]> Git Repo - linux.git/commitdiff
Merge tag 'phy-fixes-6.12' of git://git.kernel.org/pub/scm/linux/kernel/git/phy/linux-phy
authorLinus Torvalds <[email protected]>
Sun, 3 Nov 2024 20:19:34 +0000 (10:19 -1000)
committerLinus Torvalds <[email protected]>
Sun, 3 Nov 2024 20:19:34 +0000 (10:19 -1000)
Pull phy fixes from Vinod Koul:

 - Qualcomm QMP driver fixes for null deref on suspend, bogus supplies
   fix and reset entries fix

 - BCM usb driver init array fix

 - cadence array offset fix

 - starfive link configuration fix

 - config dependency fix for rockchip driver

 - freescale reset signal fix before pll lock

 - tegra driver fix for error pointer check

* tag 'phy-fixes-6.12' of git://git.kernel.org/pub/scm/linux/kernel/git/phy/linux-phy:
  phy: tegra: xusb: Add error pointer check in xusb.c
  dt-bindings: phy: qcom,sc8280xp-qmp-pcie-phy: Fix X1E80100 resets entries
  phy: freescale: imx8m-pcie: Do CMN_RST just before PHY PLL lock check
  phy: phy-rockchip-samsung-hdptx: Depend on CONFIG_COMMON_CLK
  phy: ti: phy-j721e-wiz: fix usxgmii configuration
  phy: starfive: jh7110-usb: Fix link configuration to controller
  phy: qcom: qmp-pcie: drop bogus x1e80100 qref supplies
  phy: qcom: qmp-combo: move driver data initialisation earlier
  phy: qcom: qmp-usbc: fix NULL-deref on runtime suspend
  phy: qcom: qmp-usb-legacy: fix NULL-deref on runtime suspend
  phy: qcom: qmp-usb: fix NULL-deref on runtime suspend
  dt-bindings: phy: qcom,sc8280xp-qmp-pcie-phy: add missing x1e80100 pipediv2 clocks
  phy: usb: disable COMMONONN for dual mode
  phy: cadence: Sierra: Fix offset of DEQ open eye algorithm control register
  phy: usb: Fix missing elements in BCM4908 USB init array

2430 files changed:
.mailmap
CREDITS
Documentation/admin-guide/LSM/ipe.rst
Documentation/admin-guide/pm/cpufreq.rst
Documentation/arch/arm/mem_alignment.rst
Documentation/arch/arm64/silicon-errata.rst
Documentation/core-api/folio_queue.rst [new file with mode: 0644]
Documentation/core-api/index.rst
Documentation/core-api/protection-keys.rst
Documentation/core-api/unaligned-memory-access.rst
Documentation/devicetree/bindings/display/elgin,jg10309-01.yaml [new file with mode: 0644]
Documentation/devicetree/bindings/display/mediatek/mediatek,dpi.yaml
Documentation/devicetree/bindings/display/mediatek/mediatek,split.yaml
Documentation/devicetree/bindings/iio/adc/adi,ad7380.yaml
Documentation/devicetree/bindings/iio/dac/adi,ad5686.yaml
Documentation/devicetree/bindings/iio/dac/adi,ad5696.yaml
Documentation/devicetree/bindings/interrupt-controller/fsl,ls-extirq.yaml
Documentation/devicetree/bindings/misc/fsl,qoriq-mc.yaml
Documentation/devicetree/bindings/net/brcm,unimac-mdio.yaml
Documentation/devicetree/bindings/net/xlnx,axi-ethernet.yaml
Documentation/devicetree/bindings/sound/davinci-mcasp-audio.yaml
Documentation/devicetree/bindings/sound/qcom,sm8250.yaml
Documentation/devicetree/bindings/sound/renesas,rsnd.yaml
Documentation/devicetree/bindings/sound/rockchip,rk3308-codec.yaml
Documentation/devicetree/bindings/trivial-devices.yaml
Documentation/driver-api/wmi.rst
Documentation/filesystems/caching/cachefiles.rst
Documentation/filesystems/iomap/operations.rst
Documentation/filesystems/netfs_library.rst
Documentation/gpu/drm-kms-helpers.rst
Documentation/iio/ad7380.rst
Documentation/mm/damon/maintainer-profile.rst
Documentation/networking/napi.rst
Documentation/networking/packet_mmap.rst
Documentation/networking/tcp_ao.rst
Documentation/process/maintainer-netdev.rst
Documentation/process/maintainer-soc.rst
Documentation/rust/arch-support.rst
Documentation/scheduler/sched-ext.rst
Documentation/translations/zh_CN/core-api/unaligned-memory-access.rst
Documentation/userspace-api/mseal.rst
Documentation/virt/kvm/api.rst
Documentation/virt/kvm/locking.rst
Documentation/wmi/devices/dell-wmi-ddv.rst
MAINTAINERS
Makefile
arch/Kconfig
arch/alpha/kernel/traps.c
arch/arc/include/asm/io.h
arch/arc/include/asm/mmu.h
arch/arc/include/asm/unaligned.h [deleted file]
arch/arc/kernel/traps.c
arch/arc/kernel/unaligned.c
arch/arc/kernel/unaligned.h [new file with mode: 0644]
arch/arc/kernel/unwind.c
arch/arm/boot/dts/broadcom/bcm2837-rpi-cm3-io3.dts
arch/arm/crypto/aes-ce-glue.c
arch/arm/crypto/crc32-ce-glue.c
arch/arm/crypto/ghash-ce-glue.c
arch/arm/crypto/poly1305-glue.c
arch/arm/crypto/sha2-ce-glue.c
arch/arm/include/asm/uaccess.h
arch/arm/mm/alignment.c
arch/arm64/Kconfig
arch/arm64/Makefile
arch/arm64/boot/dts/marvell/cn9130-sr-som.dtsi
arch/arm64/crypto/aes-ce-ccm-glue.c
arch/arm64/crypto/aes-ce-glue.c
arch/arm64/crypto/ghash-ce-glue.c
arch/arm64/crypto/poly1305-glue.c
arch/arm64/crypto/sha1-ce-glue.c
arch/arm64/crypto/sha2-ce-glue.c
arch/arm64/crypto/sha3-ce-glue.c
arch/arm64/crypto/sha512-ce-glue.c
arch/arm64/crypto/sm3-ce-glue.c
arch/arm64/crypto/sm3-neon-glue.c
arch/arm64/include/asm/cputype.h
arch/arm64/include/asm/kvm_asm.h
arch/arm64/include/asm/kvm_host.h
arch/arm64/include/asm/kvm_mmu.h
arch/arm64/include/asm/kvm_nested.h
arch/arm64/include/asm/uprobes.h
arch/arm64/kernel/asm-offsets.c
arch/arm64/kernel/cpu_errata.c
arch/arm64/kernel/probes/decode-insn.c
arch/arm64/kernel/probes/simulate-insn.c
arch/arm64/kernel/probes/uprobes.c
arch/arm64/kernel/process.c
arch/arm64/kernel/signal.c
arch/arm64/kvm/arm.c
arch/arm64/kvm/hyp/include/hyp/switch.h
arch/arm64/kvm/hyp/nvhe/hyp-init.S
arch/arm64/kvm/hyp/nvhe/hyp-main.c
arch/arm64/kvm/hyp/nvhe/pkvm.c
arch/arm64/kvm/hypercalls.c
arch/arm64/kvm/mmu.c
arch/arm64/kvm/nested.c
arch/arm64/kvm/sys_regs.c
arch/arm64/kvm/vgic/vgic-init.c
arch/arm64/kvm/vgic/vgic-kvm-device.c
arch/arm64/net/bpf_jit_comp.c
arch/loongarch/crypto/crc32-loongarch.c
arch/loongarch/include/asm/bootinfo.h
arch/loongarch/include/asm/kasan.h
arch/loongarch/include/asm/loongarch.h
arch/loongarch/include/asm/pgalloc.h
arch/loongarch/include/asm/pgtable.h
arch/loongarch/kernel/process.c
arch/loongarch/kernel/setup.c
arch/loongarch/kernel/traps.c
arch/loongarch/kernel/vdso.c
arch/loongarch/kvm/timer.c
arch/loongarch/kvm/vcpu.c
arch/loongarch/mm/init.c
arch/loongarch/mm/pgtable.c
arch/microblaze/include/asm/flat.h
arch/mips/boot/compressed/decompress.c
arch/mips/crypto/crc32-mips.c
arch/mips/crypto/poly1305-glue.c
arch/mips/kernel/cmpxchg.c
arch/nios2/kernel/misaligned.c
arch/parisc/boot/compressed/misc.c
arch/parisc/include/asm/unaligned.h [deleted file]
arch/parisc/kernel/traps.c
arch/parisc/kernel/unaligned.c
arch/parisc/kernel/unaligned.h [new file with mode: 0644]
arch/powerpc/crypto/aes-gcm-p10-glue.c
arch/powerpc/crypto/poly1305-p10-glue.c
arch/powerpc/kernel/head_8xx.S
arch/powerpc/kernel/vdso/Makefile
arch/powerpc/platforms/powernv/opal-irqchip.c
arch/powerpc/platforms/pseries/papr_scm.c
arch/riscv/Kconfig
arch/riscv/errata/Makefile
arch/riscv/include/asm/thread_info.h
arch/riscv/kernel/Makefile
arch/riscv/kernel/acpi.c
arch/riscv/kernel/asm-offsets.c
arch/riscv/kernel/cacheinfo.c
arch/riscv/kernel/cpu-hotplug.c
arch/riscv/kernel/efi-header.S
arch/riscv/kernel/pi/Makefile
arch/riscv/kernel/traps_misaligned.c
arch/riscv/kernel/vdso/Makefile
arch/riscv/kvm/aia_imsic.c
arch/riscv/net/bpf_jit_comp64.c
arch/s390/configs/debug_defconfig
arch/s390/configs/defconfig
arch/s390/configs/zfcpdump_defconfig
arch/s390/include/asm/io.h
arch/s390/include/asm/perf_event.h
arch/s390/kvm/diag.c
arch/s390/kvm/gaccess.c
arch/s390/kvm/gaccess.h
arch/s390/pci/pci_event.c
arch/sh/include/asm/flat.h
arch/sh/kernel/dwarf.c
arch/sh/kernel/module.c
arch/sparc/crypto/crc32c_glue.c
arch/um/drivers/virt-pci.c
arch/um/include/asm/uaccess.h
arch/x86/Kconfig
arch/x86/crypto/camellia_glue.c
arch/x86/crypto/ghash-clmulni-intel_glue.c
arch/x86/entry/entry.S
arch/x86/entry/entry_32.S
arch/x86/include/asm/amd_nb.h
arch/x86/include/asm/cpufeatures.h
arch/x86/include/asm/ftrace.h
arch/x86/include/asm/nospec-branch.h
arch/x86/include/asm/reboot.h
arch/x86/include/asm/runtime-const.h
arch/x86/include/asm/uaccess_64.h
arch/x86/kernel/amd_nb.c
arch/x86/kernel/apic/apic.c
arch/x86/kernel/cpu/amd.c
arch/x86/kernel/cpu/bugs.c
arch/x86/kernel/cpu/common.c
arch/x86/kernel/cpu/microcode/amd.c
arch/x86/kernel/cpu/resctrl/core.c
arch/x86/kernel/cpu/resctrl/ctrlmondata.c
arch/x86/kernel/kvm.c
arch/x86/kernel/reboot.c
arch/x86/kernel/traps.c
arch/x86/kernel/vmlinux.lds.S
arch/x86/kvm/Kconfig
arch/x86/kvm/Makefile
arch/x86/kvm/mmu/mmu.c
arch/x86/kvm/svm/nested.c
arch/x86/kvm/vmx/vmx.c
arch/x86/lib/getuser.S
arch/x86/lib/insn.c
arch/x86/virt/svm/sev.c
arch/x86/xen/enlighten_pv.c
arch/xtensa/include/asm/flat.h
block/blk-integrity.c
block/blk-iocost.c
block/blk-map.c
block/blk-mq.c
block/blk-rq-qos.c
block/elevator.c
block/partitions/ldm.h
block/partitions/msdos.c
block/t10-pi.c
crypto/aes_generic.c
crypto/algapi.c
crypto/blake2b_generic.c
crypto/blowfish_generic.c
crypto/camellia_generic.c
crypto/cast5_generic.c
crypto/cast6_generic.c
crypto/chacha_generic.c
crypto/crc32_generic.c
crypto/crc32c_generic.c
crypto/crc64_rocksoft_generic.c
crypto/ecc.c
crypto/michael_mic.c
crypto/nhpoly1305.c
crypto/poly1305_generic.c
crypto/polyval-generic.c
crypto/serpent_generic.c
crypto/sha256_generic.c
crypto/sha3_generic.c
crypto/sha512_generic.c
crypto/sm3.c
crypto/sm3_generic.c
crypto/sm4.c
crypto/sm4_generic.c
crypto/testmgr.c
crypto/twofish_generic.c
crypto/vmac.c
crypto/xxhash_generic.c
drivers/accel/ivpu/ivpu_debugfs.c
drivers/accel/ivpu/ivpu_hw.c
drivers/accel/ivpu/ivpu_hw.h
drivers/accel/ivpu/ivpu_hw_ip.c
drivers/accel/qaic/qaic_control.c
drivers/accel/qaic/qaic_data.c
drivers/acpi/apei/apei-base.c
drivers/acpi/apei/einj-core.c
drivers/acpi/apei/einj-cxl.c
drivers/acpi/battery.c
drivers/acpi/button.c
drivers/acpi/cppc_acpi.c
drivers/acpi/prmt.c
drivers/acpi/resource.c
drivers/acpi/video_detect.c
drivers/ata/libata-core.c
drivers/ata/libata-eh.c
drivers/ata/libata-sata.c
drivers/ata/libata-scsi.c
drivers/auxdisplay/ht16k33.c
drivers/base/core.c
drivers/base/module.c
drivers/base/power/common.c
drivers/base/regmap/regmap.c
drivers/block/aoe/aoecmd.c
drivers/block/aoe/aoenet.c
drivers/block/drbd/drbd_int.h
drivers/block/drbd/drbd_main.c
drivers/block/drbd/drbd_nl.c
drivers/block/pktcdvd.c
drivers/block/ublk_drv.c
drivers/bluetooth/ath3k.c
drivers/bluetooth/btbcm.c
drivers/bluetooth/btintel.c
drivers/bluetooth/btintel_pcie.c
drivers/bluetooth/btmrvl_sdio.c
drivers/bluetooth/btmtk.c
drivers/bluetooth/btmtksdio.c
drivers/bluetooth/btmtkuart.c
drivers/bluetooth/btnxpuart.c
drivers/bluetooth/btrsi.c
drivers/bluetooth/btrtl.c
drivers/bluetooth/btusb.c
drivers/bluetooth/h4_recv.h
drivers/bluetooth/hci_bcm4377.c
drivers/bluetooth/hci_bcsp.c
drivers/bluetooth/hci_h4.c
drivers/bluetooth/hci_nokia.c
drivers/bluetooth/hci_qca.c
drivers/bluetooth/hci_vhci.c
drivers/cdrom/cdrom.c
drivers/char/tpm/tpm-chip.c
drivers/char/tpm/tpm-dev-common.c
drivers/char/tpm/tpm-interface.c
drivers/char/tpm/tpm2-sessions.c
drivers/char/tpm/tpm2-space.c
drivers/char/virtio_console.c
drivers/clk/clk-si5341.c
drivers/clk/clk_test.c
drivers/clk/rockchip/clk.c
drivers/clk/samsung/clk-exynosautov920.c
drivers/comedi/drivers/usbduxsigma.c
drivers/counter/104-quad-8.c
drivers/counter/i8254.c
drivers/cpufreq/amd-pstate.c
drivers/cpufreq/cppc_cpufreq.c
drivers/cpufreq/intel_pstate.c
drivers/crypto/allwinner/sun4i-ss/sun4i-ss-hash.c
drivers/crypto/caam/caamalg.c
drivers/crypto/caam/caamalg_qi.c
drivers/crypto/caam/caamalg_qi2.c
drivers/crypto/inside-secure/safexcel_cipher.c
drivers/crypto/marvell/cesa/hash.c
drivers/crypto/rockchip/rk3288_crypto_ahash.c
drivers/crypto/stm32/stm32-crc32.c
drivers/cxl/Kconfig
drivers/cxl/Makefile
drivers/cxl/acpi.c
drivers/cxl/core/cdat.c
drivers/cxl/core/hdm.c
drivers/cxl/core/mbox.c
drivers/cxl/core/port.c
drivers/cxl/core/region.c
drivers/cxl/core/trace.h
drivers/cxl/cxl.h
drivers/cxl/pci.c
drivers/cxl/pmem.c
drivers/cxl/port.c
drivers/cxl/security.c
drivers/dax/device.c
drivers/dma/ep93xx_dma.c
drivers/dma/sh/rz-dmac.c
drivers/dma/ti/k3-udma.c
drivers/firewire/core-topology.c
drivers/firewire/net.c
drivers/firmware/arm_ffa/driver.c
drivers/firmware/arm_scmi/common.h
drivers/firmware/arm_scmi/driver.c
drivers/firmware/arm_scmi/protocols.h
drivers/firmware/arm_scmi/transports/Makefile
drivers/firmware/arm_scmi/transports/mailbox.c
drivers/firmware/arm_sdei.c
drivers/firmware/dmi_scan.c
drivers/firmware/efi/fdtparams.c
drivers/firmware/efi/libstub/riscv-stub.c
drivers/firmware/efi/libstub/riscv.c
drivers/firmware/efi/libstub/zboot.c
drivers/firmware/sysfb.c
drivers/fpga/microchip-spi.c
drivers/fsi/fsi-occ.c
drivers/gpio/gpio-aspeed.c
drivers/gpio/gpio-davinci.c
drivers/gpio/gpio-sloppy-logic-analyzer.c
drivers/gpio/gpiolib-swnode.c
drivers/gpio/gpiolib.c
drivers/gpu/drm/amd/amdgpu/amdgpu_acpi.c
drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c
drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c
drivers/gpu/drm/amd/amdgpu/amdgpu_mes.c
drivers/gpu/drm/amd/amdgpu/atom.c
drivers/gpu/drm/amd/amdgpu/mes_v12_0.c
drivers/gpu/drm/amd/amdgpu/sdma_v7_0.c
drivers/gpu/drm/amd/amdkfd/kfd_chardev.c
drivers/gpu/drm/amd/amdkfd/kfd_priv.h
drivers/gpu/drm/amd/amdkfd/kfd_process.c
drivers/gpu/drm/amd/amdkfd/kfd_svm.c
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.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/dc_types.h
drivers/gpu/drm/amd/display/dc/resource/dcn351/dcn351_resource.c
drivers/gpu/drm/amd/display/modules/power/power_helpers.c
drivers/gpu/drm/amd/pm/powerplay/inc/hwmgr.h
drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c
drivers/gpu/drm/amd/pm/swsmu/inc/pmfw_if/smu14_driver_if_v14_0.h
drivers/gpu/drm/amd/pm/swsmu/inc/smu_v14_0.h
drivers/gpu/drm/amd/pm/swsmu/smu11/vangogh_ppt.c
drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c
drivers/gpu/drm/amd/pm/swsmu/smu14/smu_v14_0_2_ppt.c
drivers/gpu/drm/ast/ast_sil164.c
drivers/gpu/drm/ast/ast_vga.c
drivers/gpu/drm/bridge/aux-bridge.c
drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-core.c
drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-hdcp.c
drivers/gpu/drm/bridge/samsung-dsim.c
drivers/gpu/drm/bridge/sil-sii8620.c
drivers/gpu/drm/bridge/tc358767.c
drivers/gpu/drm/bridge/tc358775.c
drivers/gpu/drm/bridge/ti-sn65dsi86.c
drivers/gpu/drm/display/drm_dp_mst_topology.c
drivers/gpu/drm/display/drm_hdmi_state_helper.c
drivers/gpu/drm/drm_atomic_uapi.c
drivers/gpu/drm/drm_debugfs.c
drivers/gpu/drm/drm_fbdev_dma.c
drivers/gpu/drm/i915/Kconfig
drivers/gpu/drm/i915/display/intel_dp_mst.c
drivers/gpu/drm/i915/display/intel_dsi_vbt.c
drivers/gpu/drm/i915/display/intel_fb.c
drivers/gpu/drm/i915/display/intel_fb.h
drivers/gpu/drm/i915/display/intel_hdcp.c
drivers/gpu/drm/i915/display/skl_universal_plane.c
drivers/gpu/drm/i915/gem/i915_gem_ttm.c
drivers/gpu/drm/mediatek/mtk_crtc.c
drivers/gpu/drm/mediatek/mtk_ddp_comp.c
drivers/gpu/drm/mediatek/mtk_ddp_comp.h
drivers/gpu/drm/mediatek/mtk_disp_drv.h
drivers/gpu/drm/mediatek/mtk_disp_ovl.c
drivers/gpu/drm/mediatek/mtk_disp_ovl_adaptor.c
drivers/gpu/drm/mediatek/mtk_dp.c
drivers/gpu/drm/mediatek/mtk_ethdr.c
drivers/gpu/drm/mediatek/mtk_ethdr.h
drivers/gpu/drm/mediatek/mtk_plane.c
drivers/gpu/drm/mediatek/mtk_plane.h
drivers/gpu/drm/mgag200/mgag200_drv.c
drivers/gpu/drm/mgag200/mgag200_drv.h
drivers/gpu/drm/mgag200/mgag200_g200.c
drivers/gpu/drm/mgag200/mgag200_g200eh.c
drivers/gpu/drm/mgag200/mgag200_g200eh3.c
drivers/gpu/drm/mgag200/mgag200_g200er.c
drivers/gpu/drm/mgag200/mgag200_g200ev.c
drivers/gpu/drm/mgag200/mgag200_g200ew3.c
drivers/gpu/drm/mgag200/mgag200_g200se.c
drivers/gpu/drm/mgag200/mgag200_g200wb.c
drivers/gpu/drm/mgag200/mgag200_mode.c
drivers/gpu/drm/msm/adreno/a6xx_gpu.c
drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_vid.c
drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_wb.c
drivers/gpu/drm/msm/disp/msm_disp_snapshot_util.c
drivers/gpu/drm/msm/dsi/dsi_host.c
drivers/gpu/drm/msm/hdmi/hdmi_phy_8998.c
drivers/gpu/drm/nouveau/include/nvif/os.h
drivers/gpu/drm/nouveau/include/nvkm/subdev/gsp.h
drivers/gpu/drm/nouveau/nouveau_dmem.c
drivers/gpu/drm/nouveau/nouveau_drm.c
drivers/gpu/drm/panel/panel-himax-hx83102.c
drivers/gpu/drm/panthor/panthor_drv.c
drivers/gpu/drm/panthor/panthor_fw.c
drivers/gpu/drm/panthor/panthor_gem.c
drivers/gpu/drm/panthor/panthor_mmu.c
drivers/gpu/drm/panthor/panthor_mmu.h
drivers/gpu/drm/panthor/panthor_sched.c
drivers/gpu/drm/radeon/atom.c
drivers/gpu/drm/radeon/atombios_dp.c
drivers/gpu/drm/radeon/radeon_connectors.c
drivers/gpu/drm/radeon/radeon_encoders.c
drivers/gpu/drm/radeon/radeon_gem.c
drivers/gpu/drm/radeon/radeon_object.c
drivers/gpu/drm/scheduler/sched_entity.c
drivers/gpu/drm/scheduler/sched_main.c
drivers/gpu/drm/tegra/drm.c
drivers/gpu/drm/tegra/gr3d.c
drivers/gpu/drm/tests/drm_connector_test.c
drivers/gpu/drm/tests/drm_hdmi_state_helper_test.c
drivers/gpu/drm/tests/drm_kunit_helpers.c
drivers/gpu/drm/udl/udl_transfer.c
drivers/gpu/drm/v3d/v3d_perfmon.c
drivers/gpu/drm/vboxvideo/hgsmi_base.c
drivers/gpu/drm/vboxvideo/vboxvideo.h
drivers/gpu/drm/vc4/vc4_perfmon.c
drivers/gpu/drm/vmwgfx/vmwgfx_blit.c
drivers/gpu/drm/vmwgfx/vmwgfx_drv.h
drivers/gpu/drm/vmwgfx/vmwgfx_kms.c
drivers/gpu/drm/vmwgfx/vmwgfx_kms.h
drivers/gpu/drm/vmwgfx/vmwgfx_stdu.c
drivers/gpu/drm/vmwgfx/vmwgfx_surface.c
drivers/gpu/drm/xe/display/xe_display.c
drivers/gpu/drm/xe/display/xe_display.h
drivers/gpu/drm/xe/regs/xe_gt_regs.h
drivers/gpu/drm/xe/xe_bo.c
drivers/gpu/drm/xe/xe_debugfs.c
drivers/gpu/drm/xe/xe_device.c
drivers/gpu/drm/xe/xe_device_types.h
drivers/gpu/drm/xe/xe_drm_client.c
drivers/gpu/drm/xe/xe_exec.c
drivers/gpu/drm/xe/xe_exec_queue.c
drivers/gpu/drm/xe/xe_force_wake.c
drivers/gpu/drm/xe/xe_ggtt.c
drivers/gpu/drm/xe/xe_gpu_scheduler.c
drivers/gpu/drm/xe/xe_gpu_scheduler.h
drivers/gpu/drm/xe/xe_gt.c
drivers/gpu/drm/xe/xe_gt_freq.c
drivers/gpu/drm/xe/xe_gt_mcr.c
drivers/gpu/drm/xe/xe_gt_pagefault.c
drivers/gpu/drm/xe/xe_gt_sysfs.c
drivers/gpu/drm/xe/xe_gt_tlb_invalidation.c
drivers/gpu/drm/xe/xe_gt_tlb_invalidation.h
drivers/gpu/drm/xe/xe_guc_ct.c
drivers/gpu/drm/xe/xe_guc_submit.c
drivers/gpu/drm/xe/xe_guc_types.h
drivers/gpu/drm/xe/xe_oa.c
drivers/gpu/drm/xe/xe_pci.c
drivers/gpu/drm/xe/xe_pm.c
drivers/gpu/drm/xe/xe_pt.c
drivers/gpu/drm/xe/xe_query.c
drivers/gpu/drm/xe/xe_sync.c
drivers/gpu/drm/xe/xe_tuning.c
drivers/gpu/drm/xe/xe_vm.c
drivers/gpu/drm/xe/xe_wa.c
drivers/gpu/drm/xe/xe_wait_user_fence.c
drivers/gpu/host1x/context.c
drivers/gpu/host1x/dev.c
drivers/greybus/es2.c
drivers/greybus/gb-beagleplay.c
drivers/hid/amd-sfh-hid/amd_sfh_client.c
drivers/hid/bpf/hid_bpf_struct_ops.c
drivers/hid/hid-alps.c
drivers/hid/hid-core.c
drivers/hid/hid-generic.c
drivers/hid/hid-goodix-spi.c
drivers/hid/hid-google-hammer.c
drivers/hid/hid-ids.h
drivers/hid/hid-kye.c
drivers/hid/hid-lenovo.c
drivers/hid/hid-letsketch.c
drivers/hid/hid-logitech-dj.c
drivers/hid/hid-logitech-hidpp.c
drivers/hid/hid-multitouch.c
drivers/hid/hid-nintendo.c
drivers/hid/hid-plantronics.c
drivers/hid/hid-playstation.c
drivers/hid/hid-sony.c
drivers/hid/hid-uclogic-params.c
drivers/hid/hid-uclogic-rdesc.c
drivers/hid/i2c-hid/i2c-hid-core.c
drivers/hid/intel-ish-hid/ishtp-fw-loader.c
drivers/hid/surface-hid/surface_hid.c
drivers/hid/surface-hid/surface_hid_core.c
drivers/hid/surface-hid/surface_kbd.c
drivers/hid/usbhid/hid-core.c
drivers/hid/wacom.h
drivers/hid/wacom_wac.c
drivers/hwmon/Kconfig
drivers/hwmon/adt7310.c
drivers/hwmon/adt7475.c
drivers/hwmon/aquacomputer_d5next.c
drivers/hwmon/asus-ec-sensors.c
drivers/hwmon/asus_rog_ryujin.c
drivers/hwmon/dell-smm-hwmon.c
drivers/hwmon/gigabyte_waterforce.c
drivers/hwmon/intel-m10-bmc-hwmon.c
drivers/hwmon/jc42.c
drivers/hwmon/nzxt-kraken2.c
drivers/hwmon/nzxt-kraken3.c
drivers/hwmon/nzxt-smart2.c
drivers/hwmon/occ/common.c
drivers/hwmon/occ/p8_i2c.c
drivers/i2c/busses/i2c-nvidia-gpu.c
drivers/i2c/busses/i2c-stm32f7.c
drivers/iio/accel/Kconfig
drivers/iio/accel/adxl355_core.c
drivers/iio/accel/adxl367.c
drivers/iio/accel/adxl380.c
drivers/iio/accel/bma400_core.c
drivers/iio/accel/bmi088-accel-core.c
drivers/iio/accel/dmard09.c
drivers/iio/accel/sca3300.c
drivers/iio/adc/Kconfig
drivers/iio/adc/ad4130.c
drivers/iio/adc/ad7124.c
drivers/iio/adc/ad7380.c
drivers/iio/adc/ad_sigma_delta.c
drivers/iio/adc/axp20x_adc.c
drivers/iio/adc/intel_mrfld_adc.c
drivers/iio/adc/ltc2497.c
drivers/iio/adc/max11100.c
drivers/iio/adc/max11410.c
drivers/iio/adc/mcp3422.c
drivers/iio/adc/mcp3911.c
drivers/iio/adc/mt6360-adc.c
drivers/iio/adc/pac1921.c
drivers/iio/adc/pac1934.c
drivers/iio/adc/qcom-spmi-rradc.c
drivers/iio/adc/ti-ads124s08.c
drivers/iio/adc/ti-ads1298.c
drivers/iio/adc/ti-ads131e08.c
drivers/iio/adc/ti-tsc2046.c
drivers/iio/addac/ad74115.c
drivers/iio/addac/ad74413r.c
drivers/iio/amplifiers/Kconfig
drivers/iio/amplifiers/ada4250.c
drivers/iio/cdc/ad7746.c
drivers/iio/chemical/Kconfig
drivers/iio/chemical/bme680_core.c
drivers/iio/chemical/pms7003.c
drivers/iio/chemical/scd30_i2c.c
drivers/iio/chemical/scd30_serial.c
drivers/iio/chemical/scd4x.c
drivers/iio/chemical/sps30_i2c.c
drivers/iio/common/hid-sensors/hid-sensor-trigger.c
drivers/iio/common/st_sensors/st_sensors_core.c
drivers/iio/dac/Kconfig
drivers/iio/dac/ad3552r.c
drivers/iio/dac/ad5064.c
drivers/iio/dac/ad5446.c
drivers/iio/dac/ad5449.c
drivers/iio/dac/ad5593r.c
drivers/iio/dac/ad5624r_spi.c
drivers/iio/dac/ad5766.c
drivers/iio/dac/ad7293.c
drivers/iio/dac/ltc2632.c
drivers/iio/dac/ltc2664.c
drivers/iio/dac/mcp4821.c
drivers/iio/frequency/Kconfig
drivers/iio/frequency/adf4377.c
drivers/iio/frequency/admv1013.c
drivers/iio/frequency/admv1014.c
drivers/iio/frequency/admv4420.c
drivers/iio/frequency/adrf6780.c
drivers/iio/gyro/adis16130.c
drivers/iio/health/afe4403.c
drivers/iio/humidity/ens210.c
drivers/iio/humidity/hdc3020.c
drivers/iio/imu/adis.c
drivers/iio/imu/bmi323/bmi323_core.c
drivers/iio/industrialio-gts-helper.c
drivers/iio/light/Kconfig
drivers/iio/light/apds9306.c
drivers/iio/light/gp2ap020a00f.c
drivers/iio/light/ltr390.c
drivers/iio/light/ltrf216a.c
drivers/iio/light/opt3001.c
drivers/iio/light/si1133.c
drivers/iio/light/tsl2591.c
drivers/iio/light/veml6030.c
drivers/iio/light/zopt2201.c
drivers/iio/magnetometer/Kconfig
drivers/iio/magnetometer/rm3100-core.c
drivers/iio/magnetometer/yamaha-yas530.c
drivers/iio/pressure/Kconfig
drivers/iio/pressure/bmp280-core.c
drivers/iio/pressure/dlhl60d.c
drivers/iio/pressure/hp206c.c
drivers/iio/pressure/hsc030pa.c
drivers/iio/pressure/mprls0025pa.c
drivers/iio/pressure/ms5611_i2c.c
drivers/iio/pressure/ms5611_spi.c
drivers/iio/pressure/sdp500.c
drivers/iio/pressure/st_pressure_core.c
drivers/iio/pressure/zpa2326.c
drivers/iio/proximity/Kconfig
drivers/iio/proximity/aw96103.c
drivers/iio/proximity/cros_ec_mkbp_proximity.c
drivers/iio/proximity/hx9023s.c
drivers/iio/proximity/irsd200.c
drivers/iio/resolver/Kconfig
drivers/iio/temperature/ltc2983.c
drivers/iio/temperature/max31856.c
drivers/iio/temperature/max31865.c
drivers/infiniband/core/addr.c
drivers/infiniband/core/nldev.c
drivers/infiniband/hw/bnxt_re/hw_counters.c
drivers/infiniband/hw/bnxt_re/ib_verbs.c
drivers/infiniband/hw/bnxt_re/main.c
drivers/infiniband/hw/bnxt_re/qplib_fp.c
drivers/infiniband/hw/bnxt_re/qplib_fp.h
drivers/infiniband/hw/bnxt_re/qplib_rcfw.c
drivers/infiniband/hw/bnxt_re/qplib_rcfw.h
drivers/infiniband/hw/bnxt_re/qplib_res.c
drivers/infiniband/hw/bnxt_re/qplib_sp.c
drivers/infiniband/hw/bnxt_re/qplib_sp.h
drivers/infiniband/hw/cxgb4/cm.c
drivers/infiniband/hw/cxgb4/provider.c
drivers/infiniband/hw/irdma/cm.c
drivers/infiniband/hw/mlx5/qp.c
drivers/infiniband/sw/siw/siw_qp_tx.c
drivers/infiniband/ulp/srpt/ib_srpt.c
drivers/input/input.c
drivers/input/joystick/adafruit-seesaw.c
drivers/input/joystick/adc-joystick.c
drivers/input/joystick/iforce/iforce-main.c
drivers/input/joystick/iforce/iforce-packets.c
drivers/input/joystick/spaceball.c
drivers/input/joystick/xpad.c
drivers/input/keyboard/adp5588-keys.c
drivers/input/keyboard/adp5589-keys.c
drivers/input/keyboard/applespi.c
drivers/input/keyboard/cros_ec_keyb.c
drivers/input/misc/ims-pcu.c
drivers/input/misc/iqs7222.c
drivers/input/mouse/Kconfig
drivers/input/mouse/Makefile
drivers/input/mouse/cyapa_gen3.c
drivers/input/mouse/cyapa_gen5.c
drivers/input/mouse/cyapa_gen6.c
drivers/input/mouse/elan_i2c_core.c
drivers/input/mouse/elan_i2c_i2c.c
drivers/input/mouse/elantech.c
drivers/input/mouse/pixart_ps2.c [deleted file]
drivers/input/mouse/pixart_ps2.h [deleted file]
drivers/input/mouse/psmouse-base.c
drivers/input/mouse/psmouse.h
drivers/input/rmi4/rmi_f01.c
drivers/input/rmi4/rmi_f34.c
drivers/input/rmi4/rmi_f34v7.c
drivers/input/tablet/aiptek.c
drivers/input/tablet/kbtab.c
drivers/input/touchscreen/ads7846.c
drivers/input/touchscreen/atmel_mxt_ts.c
drivers/input/touchscreen/chipone_icn8505.c
drivers/input/touchscreen/cy8ctma140.c
drivers/input/touchscreen/cyttsp5.c
drivers/input/touchscreen/edt-ft5x06.c
drivers/input/touchscreen/eeti_ts.c
drivers/input/touchscreen/elants_i2c.c
drivers/input/touchscreen/exc3000.c
drivers/input/touchscreen/goodix.c
drivers/input/touchscreen/goodix_berlin_core.c
drivers/input/touchscreen/goodix_berlin_spi.c
drivers/input/touchscreen/hideep.c
drivers/input/touchscreen/hycon-hy46xx.c
drivers/input/touchscreen/hynitron_cstxxx.c
drivers/input/touchscreen/ili210x.c
drivers/input/touchscreen/ilitek_ts_i2c.c
drivers/input/touchscreen/iqs5xx.c
drivers/input/touchscreen/iqs7211.c
drivers/input/touchscreen/melfas_mip4.c
drivers/input/touchscreen/novatek-nvt-ts.c
drivers/input/touchscreen/pixcir_i2c_ts.c
drivers/input/touchscreen/raydium_i2c_ts.c
drivers/input/touchscreen/s6sy761.c
drivers/input/touchscreen/silead.c
drivers/input/touchscreen/sis_i2c.c
drivers/input/touchscreen/surface3_spi.c
drivers/input/touchscreen/wacom_i2c.c
drivers/input/touchscreen/wdt87xx_i2c.c
drivers/input/touchscreen/zet6223.c
drivers/input/touchscreen/zforce_ts.c
drivers/input/touchscreen/zinitix.c
drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
drivers/iommu/arm/arm-smmu/arm-smmu-impl.c
drivers/iommu/intel/iommu.c
drivers/irqchip/Kconfig
drivers/irqchip/irq-gic-v3-its.c
drivers/irqchip/irq-mscc-ocelot.c
drivers/irqchip/irq-renesas-rzg2l.c
drivers/irqchip/irq-riscv-imsic-platform.c
drivers/irqchip/irq-riscv-intc.c
drivers/irqchip/irq-sifive-plic.c
drivers/isdn/hardware/mISDN/avmfritz.c
drivers/leds/rgb/leds-mt6370-rgb.c
drivers/macintosh/adb-iop.c
drivers/md/dm-crypt.c
drivers/md/dm-vdo/murmurhash3.c
drivers/md/dm-vdo/numeric.h
drivers/md/dm-verity-target.c
drivers/md/dm-verity.h
drivers/md/md.c
drivers/md/raid10.c
drivers/media/dvb-frontends/mxl5xx.c
drivers/media/i2c/ccs/ccs-reg-access.c
drivers/media/i2c/hi556.c
drivers/media/i2c/hi846.c
drivers/media/i2c/hi847.c
drivers/media/i2c/imx208.c
drivers/media/i2c/imx258.c
drivers/media/i2c/imx290.c
drivers/media/i2c/imx319.c
drivers/media/i2c/imx334.c
drivers/media/i2c/imx335.c
drivers/media/i2c/imx355.c
drivers/media/i2c/imx412.c
drivers/media/i2c/ir-kbd-i2c.c
drivers/media/i2c/og01a1b.c
drivers/media/i2c/ov01a10.c
drivers/media/i2c/ov08x40.c
drivers/media/i2c/ov2740.c
drivers/media/i2c/ov5670.c
drivers/media/i2c/ov5675.c
drivers/media/i2c/ov8856.c
drivers/media/i2c/ov8858.c
drivers/media/i2c/ov9282.c
drivers/media/i2c/ov9734.c
drivers/media/i2c/thp7312.c
drivers/media/i2c/vgxy61.c
drivers/media/pci/bt8xx/bttv-cards.c
drivers/media/platform/chips-media/coda/coda-jpeg.c
drivers/media/platform/renesas/rcar_jpu.c
drivers/media/platform/verisilicon/hantro_g1_mpeg2_dec.c
drivers/media/platform/verisilicon/hantro_h1_jpeg_enc.c
drivers/media/platform/verisilicon/rockchip_vpu2_hw_jpeg_enc.c
drivers/media/platform/verisilicon/rockchip_vpu2_hw_mpeg2_dec.c
drivers/media/radio/radio-raremono.c
drivers/media/radio/si470x/radio-si470x.h
drivers/media/rc/ir_toy.c
drivers/media/rc/redrat3.c
drivers/media/tuners/xc2028.c
drivers/media/tuners/xc4000.c
drivers/media/usb/dvb-usb/m920x.c
drivers/media/usb/uvc/uvc_driver.c
drivers/media/usb/uvc/uvc_video.c
drivers/media/v4l2-core/v4l2-cci.c
drivers/media/v4l2-core/v4l2-jpeg.c
drivers/memstick/host/rtsx_usb_ms.c
drivers/mfd/gateworks-gsc.c
drivers/mfd/iqs62x.c
drivers/mfd/ntxec.c
drivers/mfd/rave-sp.c
drivers/mfd/si476x-cmd.c
drivers/misc/altera-stapl/altera.c
drivers/misc/bcm-vk/bcm_vk_sg.c
drivers/misc/cardreader/Kconfig
drivers/misc/cardreader/rtsx_pcr.c
drivers/misc/lattice-ecp3-config.c
drivers/misc/mchp_pci1xxxx/mchp_pci1xxxx_otpe2p.c
drivers/misc/mei/client.c
drivers/misc/mei/platform-vsc.c
drivers/misc/mei/vsc-fw-loader.c
drivers/misc/sgi-gru/grukservices.c
drivers/misc/sgi-gru/grumain.c
drivers/misc/sgi-gru/grutlbpurge.c
drivers/mmc/core/queue.c
drivers/mmc/host/atmel-mci.c
drivers/mmc/host/mmc_spi.c
drivers/mmc/host/mvsdio.c
drivers/mmc/host/rtsx_pci_sdmmc.c
drivers/mmc/host/rtsx_usb_sdmmc.c
drivers/mmc/host/sdhci-of-dwcmshc.c
drivers/mtd/nand/raw/intel-nand-controller.c
drivers/mtd/nand/raw/marvell_nand.c
drivers/net/can/spi/mcp251xfd/mcp251xfd-core.c
drivers/net/can/spi/mcp251xfd/mcp251xfd-regmap.c
drivers/net/can/spi/mcp251xfd/mcp251xfd-ring.c
drivers/net/can/spi/mcp251xfd/mcp251xfd-tx.c
drivers/net/can/usb/etas_es58x/es581_4.c
drivers/net/can/usb/etas_es58x/es58x_core.c
drivers/net/can/usb/etas_es58x/es58x_fd.c
drivers/net/can/usb/f81604.c
drivers/net/can/usb/mcba_usb.c
drivers/net/can/usb/peak_usb/pcan_usb.c
drivers/net/dsa/b53/b53_common.c
drivers/net/dsa/b53/b53_spi.c
drivers/net/dsa/lan9303-core.c
drivers/net/dsa/microchip/ksz_common.c
drivers/net/dsa/microchip/ksz_spi.c
drivers/net/dsa/mv88e6xxx/chip.c
drivers/net/dsa/mv88e6xxx/chip.h
drivers/net/dsa/mv88e6xxx/port.c
drivers/net/dsa/mv88e6xxx/ptp.c
drivers/net/dsa/sja1105/sja1105_main.c
drivers/net/dsa/vitesse-vsc73xx-core.c
drivers/net/ethernet/adi/adin1110.c
drivers/net/ethernet/aeroflex/greth.c
drivers/net/ethernet/amd/mvme147.c
drivers/net/ethernet/broadcom/asp2/bcmasp_ethtool.c
drivers/net/ethernet/broadcom/asp2/bcmasp_intf.c
drivers/net/ethernet/broadcom/bcmsysport.c
drivers/net/ethernet/broadcom/bnxt/bnxt.c
drivers/net/ethernet/broadcom/bnxt/bnxt_ptp.c
drivers/net/ethernet/broadcom/bnxt/bnxt_ptp.h
drivers/net/ethernet/broadcom/genet/bcmgenet.c
drivers/net/ethernet/cadence/macb_main.c
drivers/net/ethernet/dec/tulip/de2104x.c
drivers/net/ethernet/dec/tulip/eeprom.c
drivers/net/ethernet/dec/tulip/tulip.h
drivers/net/ethernet/dec/tulip/tulip_core.c
drivers/net/ethernet/emulex/benet/be_main.c
drivers/net/ethernet/faraday/ftgmac100.c
drivers/net/ethernet/freescale/enetc/enetc.c
drivers/net/ethernet/freescale/enetc/enetc.h
drivers/net/ethernet/freescale/enetc/enetc_pf.c
drivers/net/ethernet/freescale/fec.h
drivers/net/ethernet/freescale/fec_main.c
drivers/net/ethernet/freescale/fec_ptp.c
drivers/net/ethernet/freescale/fman/mac.c
drivers/net/ethernet/freescale/fman/mac.h
drivers/net/ethernet/hisilicon/hns3/hns3_debugfs.c
drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
drivers/net/ethernet/hisilicon/hns3/hns3_enet.h
drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c
drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_ptp.c
drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_regs.c
drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c
drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_regs.c
drivers/net/ethernet/i825xx/sun3_82586.c
drivers/net/ethernet/ibm/emac/mal.c
drivers/net/ethernet/ibm/ibmvnic.c
drivers/net/ethernet/intel/e100.c
drivers/net/ethernet/intel/e1000e/hw.h
drivers/net/ethernet/intel/e1000e/netdev.c
drivers/net/ethernet/intel/i40e/i40e_main.c
drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c
drivers/net/ethernet/intel/ice/devlink/devlink_port.c
drivers/net/ethernet/intel/ice/ice_ddp.c
drivers/net/ethernet/intel/ice/ice_ddp.h
drivers/net/ethernet/intel/ice/ice_dpll.c
drivers/net/ethernet/intel/ice/ice_eswitch_br.c
drivers/net/ethernet/intel/ice/ice_eswitch_br.h
drivers/net/ethernet/intel/ice/ice_fw_update.c
drivers/net/ethernet/intel/ice/ice_main.c
drivers/net/ethernet/intel/ice/ice_ptp_hw.c
drivers/net/ethernet/intel/ice/ice_ptp_hw.h
drivers/net/ethernet/intel/ice/ice_sriov.c
drivers/net/ethernet/intel/ice/ice_switch.c
drivers/net/ethernet/intel/ice/ice_tc_lib.c
drivers/net/ethernet/intel/ice/ice_vf_lib.c
drivers/net/ethernet/intel/ice/ice_vf_lib_private.h
drivers/net/ethernet/intel/ice/ice_vsi_vlan_lib.c
drivers/net/ethernet/intel/ice/ice_vsi_vlan_lib.h
drivers/net/ethernet/intel/idpf/idpf_vf_dev.c
drivers/net/ethernet/intel/idpf/idpf_virtchnl.c
drivers/net/ethernet/intel/igb/igb_main.c
drivers/net/ethernet/lantiq_etop.c
drivers/net/ethernet/marvell/octeon_ep/octep_rx.c
drivers/net/ethernet/marvell/octeontx2/af/rvu_nix.c
drivers/net/ethernet/mediatek/airoha_eth.c
drivers/net/ethernet/mediatek/mtk_eth_soc.c
drivers/net/ethernet/mediatek/mtk_wed_mcu.c
drivers/net/ethernet/mediatek/mtk_wed_wo.h
drivers/net/ethernet/mellanox/mlx5/core/cmd.c
drivers/net/ethernet/mellanox/mlx5/core/en.h
drivers/net/ethernet/mellanox/mlx5/core/en/tir.c
drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec.c
drivers/net/ethernet/mellanox/mlx5/core/en_main.c
drivers/net/ethernet/mellanox/mlx5/core/en_tx.c
drivers/net/ethernet/mellanox/mlx5/core/eq.c
drivers/net/ethernet/mellanox/mlx5/core/eswitch.c
drivers/net/ethernet/mellanox/mlx5/core/lib/pci_vsc.c
drivers/net/ethernet/mellanox/mlx5/core/steering/hws/mlx5hws_bwc.c
drivers/net/ethernet/mellanox/mlx5/core/steering/hws/mlx5hws_bwc_complex.c
drivers/net/ethernet/mellanox/mlx5/core/steering/hws/mlx5hws_context.h
drivers/net/ethernet/mellanox/mlx5/core/steering/hws/mlx5hws_definer.c
drivers/net/ethernet/mellanox/mlx5/core/steering/hws/mlx5hws_matcher.c
drivers/net/ethernet/mellanox/mlx5/core/steering/hws/mlx5hws_send.c
drivers/net/ethernet/mellanox/mlxsw/pci.c
drivers/net/ethernet/mellanox/mlxsw/spectrum_ipip.c
drivers/net/ethernet/mellanox/mlxsw/spectrum_ptp.c
drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c
drivers/net/ethernet/meta/fbnic/fbnic_devlink.c
drivers/net/ethernet/microchip/fdma/Kconfig
drivers/net/ethernet/microchip/lan743x_ptp.c
drivers/net/ethernet/microchip/sparx5/sparx5_mirror.c
drivers/net/ethernet/microchip/sparx5/sparx5_packet.c
drivers/net/ethernet/microchip/vcap/vcap_api_kunit.c
drivers/net/ethernet/netronome/nfp/crypto/ipsec.c
drivers/net/ethernet/netronome/nfp/nfpcore/nfp6000_pcie.c
drivers/net/ethernet/netronome/nfp/nfpcore/nfp_cppcore.c
drivers/net/ethernet/netronome/nfp/nfpcore/nfp_cpplib.c
drivers/net/ethernet/netronome/nfp/nfpcore/nfp_hwinfo.c
drivers/net/ethernet/netronome/nfp/nfpcore/nfp_nsp.c
drivers/net/ethernet/netronome/nfp/nfpcore/nfp_rtsym.c
drivers/net/ethernet/packetengines/hamachi.c
drivers/net/ethernet/packetengines/yellowfin.c
drivers/net/ethernet/realtek/r8169_main.c
drivers/net/ethernet/renesas/ravb_main.c
drivers/net/ethernet/renesas/rtsn.c
drivers/net/ethernet/sfc/efx_channels.c
drivers/net/ethernet/sfc/siena/efx_channels.c
drivers/net/ethernet/smsc/smsc9420.c
drivers/net/ethernet/stmicro/stmmac/dwmac-tegra.c
drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c
drivers/net/ethernet/stmicro/stmmac/dwmac4_dma.c
drivers/net/ethernet/stmicro/stmmac/dwmac4_dma.h
drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
drivers/net/ethernet/ti/am65-cpsw-nuss.c
drivers/net/ethernet/ti/cpsw_ale.c
drivers/net/ethernet/ti/cpsw_ale.h
drivers/net/ethernet/ti/icssg/icssg_config.c
drivers/net/ethernet/ti/icssg/icssg_prueth.c
drivers/net/ethernet/ti/icssg/icssg_prueth.h
drivers/net/ethernet/xilinx/xilinx_axienet_main.c
drivers/net/gtp.c
drivers/net/hyperv/netvsc_drv.c
drivers/net/ieee802154/Kconfig
drivers/net/ieee802154/cc2520.c
drivers/net/ieee802154/mcr20a.c
drivers/net/macsec.c
drivers/net/mctp/mctp-i2c.c
drivers/net/mctp/mctp-i3c.c
drivers/net/mdio/mdio-bcm-unimac.c
drivers/net/netconsole.c
drivers/net/netdevsim/dev.c
drivers/net/netdevsim/fib.c
drivers/net/pcs/pcs-xpcs-wx.c
drivers/net/phy/air_en8811h.c
drivers/net/phy/aquantia/aquantia_firmware.c
drivers/net/phy/aquantia/aquantia_main.c
drivers/net/phy/bcm-phy-ptp.c
drivers/net/phy/bcm84881.c
drivers/net/phy/dp83822.c
drivers/net/phy/dp83869.c
drivers/net/phy/mscc/mscc_ptp.c
drivers/net/phy/phy_device.c
drivers/net/phy/qt2025.rs
drivers/net/phy/realtek.c
drivers/net/plip/plip.c
drivers/net/ppp/ppp_async.c
drivers/net/ppp/ppp_deflate.c
drivers/net/ppp/ppp_generic.c
drivers/net/ppp/ppp_mppe.c
drivers/net/ppp/ppp_synctty.c
drivers/net/pse-pd/pse_core.c
drivers/net/slip/slhc.c
drivers/net/usb/net1080.c
drivers/net/usb/qmi_wwan.c
drivers/net/usb/r8152.c
drivers/net/usb/sierra_net.c
drivers/net/usb/usbnet.c
drivers/net/virtio_net.c
drivers/net/vmxnet3/vmxnet3_xdp.c
drivers/net/vrf.c
drivers/net/vxlan/vxlan_core.c
drivers/net/vxlan/vxlan_private.h
drivers/net/vxlan/vxlan_vnifilter.c
drivers/net/wireless/ath/ath10k/wmi-tlv.c
drivers/net/wireless/ath/ath10k/wmi.c
drivers/net/wireless/ath/ath11k/dp_rx.c
drivers/net/wireless/ath/ath5k/base.c
drivers/net/wireless/ath/ath5k/mac80211-ops.c
drivers/net/wireless/ath/ath5k/pcu.c
drivers/net/wireless/ath/ath5k/phy.c
drivers/net/wireless/ath/ath5k/reset.c
drivers/net/wireless/ath/ath6kl/htc_mbox.c
drivers/net/wireless/ath/ath9k/ar9003_eeprom.c
drivers/net/wireless/ath/ath9k/debug.c
drivers/net/wireless/ath/ath9k/eeprom_4k.c
drivers/net/wireless/ath/ath9k/eeprom_9287.c
drivers/net/wireless/ath/ath9k/eeprom_def.c
drivers/net/wireless/ath/ath9k/hif_usb.c
drivers/net/wireless/ath/ath9k/hw.c
drivers/net/wireless/ath/carl9170/mac.c
drivers/net/wireless/ath/hw.c
drivers/net/wireless/ath/key.c
drivers/net/wireless/ath/wil6210/txrx.c
drivers/net/wireless/broadcom/b43/main.c
drivers/net/wireless/broadcom/b43legacy/main.c
drivers/net/wireless/broadcom/brcm80211/Kconfig
drivers/net/wireless/broadcom/brcm80211/brcmfmac/fweh.h
drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c
drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
drivers/net/wireless/broadcom/brcm80211/brcmfmac/xtlv.c
drivers/net/wireless/intel/ipw2x00/ipw2100.c
drivers/net/wireless/intel/ipw2x00/ipw2200.h
drivers/net/wireless/intel/iwlegacy/3945.c
drivers/net/wireless/intel/iwlegacy/4965.c
drivers/net/wireless/intel/iwlegacy/common.c
drivers/net/wireless/intel/iwlegacy/common.h
drivers/net/wireless/intel/iwlwifi/dvm/led.c
drivers/net/wireless/intel/iwlwifi/dvm/rx.c
drivers/net/wireless/intel/iwlwifi/fw/acpi.c
drivers/net/wireless/intel/iwlwifi/fw/init.c
drivers/net/wireless/intel/iwlwifi/iwl-drv.c
drivers/net/wireless/intel/iwlwifi/iwl-drv.h
drivers/net/wireless/intel/iwlwifi/mvm/d3.c
drivers/net/wireless/intel/iwlwifi/mvm/fw.c
drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c
drivers/net/wireless/intel/iwlwifi/mvm/mld-mac80211.c
drivers/net/wireless/intel/iwlwifi/mvm/rx.c
drivers/net/wireless/intel/iwlwifi/mvm/scan.c
drivers/net/wireless/marvell/libertas/cfg.c
drivers/net/wireless/marvell/libertas/cmdresp.c
drivers/net/wireless/marvell/libertas/radiotap.h
drivers/net/wireless/marvell/mwifiex/cmdevt.c
drivers/net/wireless/mediatek/mt76/mcu.c
drivers/net/wireless/mediatek/mt76/mt76x0/eeprom.c
drivers/net/wireless/mediatek/mt76/mt76x02_eeprom.c
drivers/net/wireless/mediatek/mt76/mt76x2/eeprom.c
drivers/net/wireless/mediatek/mt7601u/dma.h
drivers/net/wireless/mediatek/mt7601u/eeprom.c
drivers/net/wireless/microchip/wilc1000/mon.c
drivers/net/wireless/purelifi/plfxlc/usb.c
drivers/net/wireless/realtek/rtlwifi/rtl8192du/sw.c
drivers/net/wireless/realtek/rtw88/usb.c
drivers/net/wireless/realtek/rtw89/coex.c
drivers/net/wireless/realtek/rtw89/pci.c
drivers/net/wireless/virtual/mac80211_hwsim.c
drivers/net/wireless/zydas/zd1211rw/zd_usb.c
drivers/net/wwan/qcom_bam_dmux.c
drivers/net/wwan/wwan_core.c
drivers/nfc/nfcmrvl/fw_dnld.c
drivers/nfc/nxp-nci/firmware.c
drivers/nfc/nxp-nci/i2c.c
drivers/nfc/pn544/i2c.c
drivers/nvme/common/auth.c
drivers/nvme/host/auth.c
drivers/nvme/host/core.c
drivers/nvme/host/hwmon.c
drivers/nvme/host/ioctl.c
drivers/nvme/host/multipath.c
drivers/nvme/host/nvme.h
drivers/nvme/host/pci.c
drivers/nvme/host/pr.c
drivers/nvme/host/rdma.c
drivers/nvme/host/tcp.c
drivers/nvme/host/trace.c
drivers/nvme/target/admin-cmd.c
drivers/nvme/target/auth.c
drivers/nvme/target/loop.c
drivers/nvme/target/passthru.c
drivers/nvme/target/rdma.c
drivers/nvme/target/trace.c
drivers/of/of_kunit_helpers.c
drivers/of/of_private.h
drivers/of/of_test.c
drivers/of/overlay_test.c
drivers/opp/core.c
drivers/parport/procfs.c
drivers/pci/pci.c
drivers/pci/probe.c
drivers/pci/pwrctl/pci-pwrctl-pwrseq.c
drivers/pci/vpd.c
drivers/pcmcia/cistpl.c
drivers/peci/controller/peci-aspeed.c
drivers/peci/request.c
drivers/perf/riscv_pmu_legacy.c
drivers/perf/riscv_pmu_sbi.c
drivers/pinctrl/intel/Kconfig
drivers/pinctrl/intel/pinctrl-intel-platform.c
drivers/pinctrl/nuvoton/pinctrl-ma35.c
drivers/pinctrl/pinctrl-apple-gpio.c
drivers/pinctrl/pinctrl-aw9523.c
drivers/pinctrl/pinctrl-ocelot.c
drivers/pinctrl/sophgo/pinctrl-cv18xx.c
drivers/pinctrl/stm32/pinctrl-stm32.c
drivers/platform/arm64/acer-aspire1-ec.c
drivers/platform/chrome/cros_ec_proto.c
drivers/platform/chrome/cros_ec_proto_test.c
drivers/platform/chrome/wilco_ec/properties.c
drivers/platform/cznic/turris-omnia-mcu-gpio.c
drivers/platform/cznic/turris-omnia-mcu.h
drivers/platform/surface/aggregator/ssh_msgb.h
drivers/platform/surface/aggregator/ssh_packet_layer.c
drivers/platform/surface/aggregator/ssh_parser.c
drivers/platform/surface/aggregator/ssh_request_layer.c
drivers/platform/surface/aggregator/trace.h
drivers/platform/surface/surface3_power.c
drivers/platform/surface/surface_acpi_notify.c
drivers/platform/surface/surface_aggregator_tabletsw.c
drivers/platform/surface/surface_platform_profile.c
drivers/platform/x86/asus-tf103c-dock.c
drivers/platform/x86/asus-wmi.c
drivers/platform/x86/dell/dell-laptop.c
drivers/platform/x86/dell/dell-wmi-base.c
drivers/platform/x86/dell/dell-wmi-ddv.c
drivers/platform/x86/dell/dell-wmi-sysman/sysman.c
drivers/platform/x86/intel/pmc/adl.c
drivers/platform/x86/intel/pmc/cnp.c
drivers/platform/x86/intel/pmc/core.c
drivers/platform/x86/intel/pmc/core.h
drivers/platform/x86/intel/pmc/core_ssram.c
drivers/platform/x86/intel/pmc/icl.c
drivers/platform/x86/intel/pmc/mtl.c
drivers/platform/x86/intel/pmc/spt.c
drivers/platform/x86/intel/pmc/tgl.c
drivers/platform/x86/intel/speed_select_if/isst_if_common.c
drivers/platform/x86/intel/tpmi_power_domains.c
drivers/platform/x86/msi-wmi-platform.c
drivers/platform/x86/quickstart.c
drivers/platform/x86/x86-android-tablets/core.c
drivers/pmdomain/qcom/cpr.c
drivers/power/supply/axp288_fuel_gauge.c
drivers/power/supply/bq27xxx_battery_i2c.c
drivers/power/supply/cros_peripheral_charger.c
drivers/power/supply/max1720x_battery.c
drivers/power/supply/rk817_charger.c
drivers/power/supply/surface_battery.c
drivers/power/supply/surface_charger.c
drivers/powercap/dtpm_devfreq.c
drivers/powercap/intel_rapl_msr.c
drivers/powercap/intel_rapl_tpmi.c
drivers/ptp/ptp_clockmatrix.c
drivers/ptp/ptp_fc3.c
drivers/reset/reset-npcm.c
drivers/reset/starfive/reset-starfive-jh71x0.c
drivers/rtc/rtc-max31335.c
drivers/rtc/rtc-pm8xxx.c
drivers/s390/char/sclp.c
drivers/s390/char/sclp_vt220.c
drivers/s390/crypto/ap_bus.c
drivers/s390/crypto/ap_bus.h
drivers/s390/crypto/ap_queue.c
drivers/s390/crypto/pkey_pckmo.c
drivers/scsi/aacraid/aachba.c
drivers/scsi/csiostor/csio_lnode.c
drivers/scsi/csiostor/csio_scsi.c
drivers/scsi/cxlflash/lunmgt.c
drivers/scsi/cxlflash/main.c
drivers/scsi/cxlflash/superpipe.c
drivers/scsi/cxlflash/vlun.c
drivers/scsi/device_handler/scsi_dh_alua.c
drivers/scsi/fnic/fnic_main.c
drivers/scsi/hpsa.c
drivers/scsi/ipr.h
drivers/scsi/libfc/fc_disc.c
drivers/scsi/libfc/fc_elsct.c
drivers/scsi/libfc/fc_encode.h
drivers/scsi/libfc/fc_lport.c
drivers/scsi/libfc/fc_rport.c
drivers/scsi/libiscsi.c
drivers/scsi/libsas/sas_expander.c
drivers/scsi/lpfc/lpfc_nvme.c
drivers/scsi/lpfc/lpfc_nvmet.c
drivers/scsi/lpfc/lpfc_scsi.c
drivers/scsi/megaraid/megaraid_sas_base.c
drivers/scsi/mpi3mr/mpi3mr.h
drivers/scsi/mpi3mr/mpi3mr_transport.c
drivers/scsi/mpt3sas/mpt3sas_scsih.c
drivers/scsi/mpt3sas/mpt3sas_warpdrive.c
drivers/scsi/mvsas/mv_sas.h
drivers/scsi/myrb.c
drivers/scsi/myrs.c
drivers/scsi/qla2xxx/qla_dsd.h
drivers/scsi/qla2xxx/qla_target.c
drivers/scsi/qla2xxx/tcm_qla2xxx.c
drivers/scsi/scsi.c
drivers/scsi/scsi_common.c
drivers/scsi/scsi_debug.c
drivers/scsi/scsi_error.c
drivers/scsi/scsi_lib.c
drivers/scsi/scsi_proto_test.c
drivers/scsi/scsi_scan.c
drivers/scsi/scsi_trace.c
drivers/scsi/scsi_transport_fc.c
drivers/scsi/scsicam.c
drivers/scsi/sd.c
drivers/scsi/sd_zbc.c
drivers/scsi/ses.c
drivers/scsi/smartpqi/smartpqi_init.c
drivers/scsi/smartpqi/smartpqi_sas_transport.c
drivers/scsi/smartpqi/smartpqi_sis.c
drivers/scsi/sr.c
drivers/scsi/st.c
drivers/scsi/wd33c93.c
drivers/soc/fsl/qe/qmc.c
drivers/soc/qcom/socinfo.c
drivers/soundwire/intel_ace2x.c
drivers/spi/atmel-quadspi.c
drivers/spi/spi-airoha-snfi.c
drivers/spi/spi-cadence.c
drivers/spi/spi-dln2.c
drivers/spi/spi-fsl-dspi.c
drivers/spi/spi-geni-qcom.c
drivers/spi/spi-imx.c
drivers/spi/spi-mtk-snfi.c
drivers/spi/spi-npcm-pspi.c
drivers/spi/spi-orion.c
drivers/spi/spi-rpc-if.c
drivers/spi/spi-s3c64xx.c
drivers/spi/spi-sh-msiof.c
drivers/spi/spi-stm32.c
drivers/spi/spi-uniphier.c
drivers/spi/spi-xcomm.c
drivers/staging/iio/frequency/ad9832.c
drivers/staging/media/av7110/av7110.c
drivers/staging/rtl8192e/rtl819x_BAProc.c
drivers/staging/rtl8723bs/core/rtw_ap.c
drivers/staging/rtl8723bs/core/rtw_ieee80211.c
drivers/staging/rtl8723bs/core/rtw_mlme_ext.c
drivers/staging/rtl8723bs/core/rtw_recv.c
drivers/staging/rtl8723bs/os_dep/recv_linux.c
drivers/target/iscsi/cxgbit/cxgbit_target.c
drivers/target/iscsi/iscsi_target.c
drivers/target/iscsi/iscsi_target_tmr.c
drivers/target/sbp/sbp_target.c
drivers/target/target_core_alua.c
drivers/target/target_core_device.c
drivers/target/target_core_fabric_lib.c
drivers/target/target_core_file.c
drivers/target/target_core_iblock.c
drivers/target/target_core_pr.c
drivers/target/target_core_pscsi.c
drivers/target/target_core_sbc.c
drivers/target/target_core_spc.c
drivers/target/target_core_transport.c
drivers/target/target_core_user.c
drivers/target/target_core_xcopy.c
drivers/target/tcm_fc/tfc_cmd.c
drivers/target/tcm_fc/tfc_conf.c
drivers/target/tcm_fc/tfc_io.c
drivers/target/tcm_fc/tfc_sess.c
drivers/thermal/intel/int340x_thermal/processor_thermal_device_pci.c
drivers/thermal/intel/int340x_thermal/processor_thermal_rapl.c
drivers/thermal/qcom/qcom-spmi-adc-tm5.c
drivers/thermal/thermal_core.c
drivers/thermal/thermal_core.h
drivers/thermal/thermal_netlink.c
drivers/thunderbolt/retimer.c
drivers/thunderbolt/tb.c
drivers/tty/n_gsm.c
drivers/tty/serial/imx.c
drivers/tty/serial/max3100.c
drivers/tty/serial/qcom_geni_serial.c
drivers/tty/vt/vc_screen.c
drivers/tty/vt/vt.c
drivers/ufs/core/ufs-mcq.c
drivers/ufs/core/ufs-sysfs.c
drivers/ufs/core/ufshcd.c
drivers/ufs/host/ufs-exynos.c
drivers/usb/atm/cxacru.c
drivers/usb/atm/ueagle-atm.c
drivers/usb/class/cdc-acm.c
drivers/usb/class/cdc-wdm.c
drivers/usb/core/hcd.c
drivers/usb/core/usb-acpi.c
drivers/usb/dwc2/params.c
drivers/usb/dwc3/core.c
drivers/usb/dwc3/core.h
drivers/usb/dwc3/gadget.c
drivers/usb/fotg210/fotg210-hcd.c
drivers/usb/gadget/composite.c
drivers/usb/gadget/function/f_fs.c
drivers/usb/gadget/function/f_mass_storage.c
drivers/usb/gadget/function/f_printer.c
drivers/usb/gadget/function/f_tcm.c
drivers/usb/gadget/function/f_uac2.c
drivers/usb/gadget/function/rndis.c
drivers/usb/gadget/function/storage_common.h
drivers/usb/gadget/function/uvc_video.c
drivers/usb/gadget/legacy/tcm_usb_gadget.c
drivers/usb/gadget/u_os_desc.h
drivers/usb/gadget/udc/bdc/bdc.h
drivers/usb/gadget/udc/bdc/bdc_ep.c
drivers/usb/gadget/udc/bdc/bdc_udc.c
drivers/usb/gadget/udc/cdns2/cdns2-ep0.c
drivers/usb/gadget/udc/core.c
drivers/usb/gadget/udc/dummy_hcd.c
drivers/usb/gadget/udc/fsl_udc_core.c
drivers/usb/gadget/udc/goku_udc.c
drivers/usb/gadget/udc/mv_udc_core.c
drivers/usb/gadget/udc/net2272.c
drivers/usb/gadget/udc/net2280.c
drivers/usb/gadget/udc/omap_udc.c
drivers/usb/gadget/udc/pxa25x_udc.c
drivers/usb/gadget/udc/snps_udc_core.c
drivers/usb/host/ehci-hcd.c
drivers/usb/host/isp1362-hcd.c
drivers/usb/host/ohci-da8xx.c
drivers/usb/host/ohci-hcd.c
drivers/usb/host/oxu210hp-hcd.c
drivers/usb/host/sl811-hcd.c
drivers/usb/host/xhci-dbgcap.h
drivers/usb/host/xhci-dbgtty.c
drivers/usb/host/xhci-hub.c
drivers/usb/host/xhci-pci-renesas.c
drivers/usb/host/xhci-pci.c
drivers/usb/host/xhci-ring.c
drivers/usb/host/xhci-tegra.c
drivers/usb/host/xhci.h
drivers/usb/isp1760/isp1760-hcd.c
drivers/usb/misc/Kconfig
drivers/usb/misc/onboard_usb_dev.c
drivers/usb/misc/usb-ljca.c
drivers/usb/misc/yurex.c
drivers/usb/musb/musb_virthub.c
drivers/usb/phy/phy-fsl-usb.c
drivers/usb/phy/phy.c
drivers/usb/serial/aircable.c
drivers/usb/serial/ch341.c
drivers/usb/serial/cypress_m8.c
drivers/usb/serial/kl5kusb105.c
drivers/usb/serial/mct_u232.c
drivers/usb/serial/mxuport.c
drivers/usb/serial/option.c
drivers/usb/serial/pl2303.c
drivers/usb/serial/quatech2.c
drivers/usb/storage/unusual_devs.h
drivers/usb/typec/class.c
drivers/usb/typec/tcpm/qcom/qcom_pmic_typec.c
drivers/usb/typec/tcpm/qcom/qcom_pmic_typec_port.c
drivers/usb/typec/tcpm/tcpm.c
drivers/usb/typec/ucsi/ucsi.h
drivers/usb/typec/ucsi/ucsi_ccg.c
drivers/usb/typec/ucsi/ucsi_stm32g0.c
drivers/vdpa/octeon_ep/octep_vdpa_hw.c
drivers/vhost/scsi.c
drivers/video/fbdev/Kconfig
drivers/video/fbdev/Makefile
drivers/video/fbdev/amifb.c
drivers/video/fbdev/arcfb.c
drivers/video/fbdev/atmel_lcdfb.c
drivers/video/fbdev/aty/mach64_accel.c
drivers/video/fbdev/au1100fb.c
drivers/video/fbdev/au1200fb.c
drivers/video/fbdev/broadsheetfb.c
drivers/video/fbdev/bw2.c
drivers/video/fbdev/c2p_iplan2.c
drivers/video/fbdev/c2p_planar.c
drivers/video/fbdev/cg14.c
drivers/video/fbdev/cg3.c
drivers/video/fbdev/cg6.c
drivers/video/fbdev/clps711x-fb.c
drivers/video/fbdev/cobalt_lcdfb.c
drivers/video/fbdev/da8xx-fb.c [deleted file]
drivers/video/fbdev/ep93xx-fb.c
drivers/video/fbdev/ffb.c
drivers/video/fbdev/fsl-diu-fb.c
drivers/video/fbdev/gbefb.c
drivers/video/fbdev/goldfishfb.c
drivers/video/fbdev/grvga.c
drivers/video/fbdev/hecubafb.c
drivers/video/fbdev/hgafb.c
drivers/video/fbdev/hitfb.c
drivers/video/fbdev/imxfb.c
drivers/video/fbdev/leo.c
drivers/video/fbdev/matrox/matroxfb_base.h
drivers/video/fbdev/mb862xx/mb862xxfbdrv.c
drivers/video/fbdev/metronomefb.c
drivers/video/fbdev/nvidia/nv_hw.c
drivers/video/fbdev/ocfb.c
drivers/video/fbdev/offb.c
drivers/video/fbdev/omap/omapfb_main.c
drivers/video/fbdev/omap2/omapfb/displays/connector-analog-tv.c
drivers/video/fbdev/omap2/omapfb/displays/connector-dvi.c
drivers/video/fbdev/omap2/omapfb/displays/connector-hdmi.c
drivers/video/fbdev/omap2/omapfb/displays/encoder-opa362.c
drivers/video/fbdev/omap2/omapfb/displays/encoder-tfp410.c
drivers/video/fbdev/omap2/omapfb/displays/encoder-tpd12s015.c
drivers/video/fbdev/omap2/omapfb/displays/panel-dpi.c
drivers/video/fbdev/omap2/omapfb/displays/panel-dsi-cm.c
drivers/video/fbdev/omap2/omapfb/displays/panel-sharp-ls037v7dw01.c
drivers/video/fbdev/omap2/omapfb/dss/core.c
drivers/video/fbdev/omap2/omapfb/dss/dispc.c
drivers/video/fbdev/omap2/omapfb/dss/dpi.c
drivers/video/fbdev/omap2/omapfb/dss/dsi.c
drivers/video/fbdev/omap2/omapfb/dss/dss.c
drivers/video/fbdev/omap2/omapfb/dss/hdmi4.c
drivers/video/fbdev/omap2/omapfb/dss/hdmi5.c
drivers/video/fbdev/omap2/omapfb/dss/sdi.c
drivers/video/fbdev/omap2/omapfb/dss/venc.c
drivers/video/fbdev/omap2/omapfb/omapfb-main.c
drivers/video/fbdev/p9100.c
drivers/video/fbdev/platinumfb.c
drivers/video/fbdev/pxa168fb.c
drivers/video/fbdev/pxa3xx-gcu.c
drivers/video/fbdev/pxafb.c
drivers/video/fbdev/s1d13xxxfb.c
drivers/video/fbdev/s3c-fb.c
drivers/video/fbdev/sbuslib.c
drivers/video/fbdev/sbuslib.h
drivers/video/fbdev/sh7760fb.c
drivers/video/fbdev/sh_mobile_lcdcfb.c
drivers/video/fbdev/simplefb.c
drivers/video/fbdev/sm501fb.c
drivers/video/fbdev/sstfb.c
drivers/video/fbdev/tcx.c
drivers/video/fbdev/udlfb.c
drivers/video/fbdev/uvesafb.c
drivers/video/fbdev/vesafb.c
drivers/video/fbdev/vfb.c
drivers/video/fbdev/vga16fb.c
drivers/video/fbdev/via/via-gpio.c
drivers/video/fbdev/via/via_i2c.c
drivers/video/fbdev/vt8500lcdfb.c
drivers/video/fbdev/wm8505fb.c
drivers/video/fbdev/wmt_ge_rops.c
drivers/video/fbdev/xilinxfb.c
drivers/virtio/virtio_ring.c
drivers/watchdog/ziirave_wdt.c
drivers/xen/Kconfig
drivers/xen/acpi.c
drivers/xen/privcmd.c
drivers/xen/xen-pciback/pci_stub.c
fs/9p/fid.c
fs/9p/v9fs.h
fs/9p/v9fs_vfs.h
fs/9p/vfs_inode.c
fs/9p/vfs_inode_dotl.c
fs/9p/vfs_super.c
fs/Kconfig
fs/adfs/map.c
fs/afs/afs_vl.h
fs/afs/dir.c
fs/afs/dir_edit.c
fs/afs/file.c
fs/afs/fs_operation.c
fs/afs/fs_probe.c
fs/afs/internal.h
fs/afs/rotate.c
fs/afs/rxrpc.c
fs/autofs/dev-ioctl.c
fs/backing-file.c
fs/bcachefs/alloc_background.c
fs/bcachefs/alloc_background.h
fs/bcachefs/alloc_background_format.h
fs/bcachefs/alloc_foreground.c
fs/bcachefs/bcachefs.h
fs/bcachefs/bcachefs_format.h
fs/bcachefs/bset.c
fs/bcachefs/btree_gc.c
fs/bcachefs/btree_io.c
fs/bcachefs/btree_iter.c
fs/bcachefs/btree_iter.h
fs/bcachefs/btree_node_scan.c
fs/bcachefs/btree_trans_commit.c
fs/bcachefs/btree_update.c
fs/bcachefs/btree_update.h
fs/bcachefs/btree_update_interior.c
fs/bcachefs/buckets.c
fs/bcachefs/buckets.h
fs/bcachefs/chardev.c
fs/bcachefs/darray.c
fs/bcachefs/data_update.c
fs/bcachefs/data_update.h
fs/bcachefs/dirent.c
fs/bcachefs/dirent.h
fs/bcachefs/disk_accounting.c
fs/bcachefs/ec.c
fs/bcachefs/errcode.h
fs/bcachefs/error.c
fs/bcachefs/error.h
fs/bcachefs/extents.c
fs/bcachefs/extents.h
fs/bcachefs/fs-io-buffered.c
fs/bcachefs/fs-io-direct.c
fs/bcachefs/fs-io-pagecache.c
fs/bcachefs/fs-io.c
fs/bcachefs/fs.c
fs/bcachefs/fs.h
fs/bcachefs/fsck.c
fs/bcachefs/fsck.h
fs/bcachefs/inode.c
fs/bcachefs/inode.h
fs/bcachefs/inode_format.h
fs/bcachefs/io_misc.c
fs/bcachefs/io_read.c
fs/bcachefs/io_write.c
fs/bcachefs/journal.c
fs/bcachefs/journal.h
fs/bcachefs/logged_ops.c
fs/bcachefs/logged_ops.h
fs/bcachefs/lru.c
fs/bcachefs/move.c
fs/bcachefs/movinggc.c
fs/bcachefs/opts.c
fs/bcachefs/opts.h
fs/bcachefs/quota.c
fs/bcachefs/rebalance.c
fs/bcachefs/recovery.c
fs/bcachefs/recovery_passes_types.h
fs/bcachefs/replicas.c
fs/bcachefs/sb-downgrade.c
fs/bcachefs/sb-errors_format.h
fs/bcachefs/sb-members.c
fs/bcachefs/siphash.c
fs/bcachefs/snapshot.c
fs/bcachefs/snapshot.h
fs/bcachefs/str_hash.h
fs/bcachefs/subvolume.c
fs/bcachefs/subvolume.h
fs/bcachefs/super-io.c
fs/bcachefs/super.c
fs/bcachefs/tests.c
fs/bcachefs/util.c
fs/bcachefs/varint.c
fs/bcachefs/xattr.c
fs/binfmt_flat.c
fs/btrfs/accessors.c
fs/btrfs/accessors.h
fs/btrfs/backref.c
fs/btrfs/bio.c
fs/btrfs/bio.h
fs/btrfs/block-group.c
fs/btrfs/defrag.c
fs/btrfs/delayed-ref.c
fs/btrfs/delayed-ref.h
fs/btrfs/dir-item.c
fs/btrfs/disk-io.c
fs/btrfs/extent-tree.c
fs/btrfs/extent_io.c
fs/btrfs/extent_map.c
fs/btrfs/free-space-cache.c
fs/btrfs/free-space-cache.h
fs/btrfs/inode.c
fs/btrfs/messages.c
fs/btrfs/qgroup.c
fs/btrfs/qgroup.h
fs/btrfs/relocation.c
fs/btrfs/send.c
fs/btrfs/super.c
fs/btrfs/tree-log.c
fs/btrfs/uuid-tree.c
fs/btrfs/volumes.c
fs/btrfs/volumes.h
fs/btrfs/zoned.c
fs/cachefiles/namei.c
fs/ceph/addr.c
fs/ceph/export.c
fs/ceph/super.h
fs/crypto/keyring.c
fs/dax.c
fs/ecryptfs/crypto.c
fs/ecryptfs/inode.c
fs/ecryptfs/mmap.c
fs/erofs/super.c
fs/erofs/zdata.c
fs/erofs/zmap.c
fs/exfat/cache.c
fs/exfat/fatent.c
fs/exfat/nls.c
fs/ext4/fast_commit.c
fs/ext4/resize.c
fs/ext4/xattr.c
fs/f2fs/dir.c
fs/f2fs/file.c
fs/f2fs/recovery.c
fs/fat/inode.c
fs/fat/namei_vfat.c
fs/file.c
fs/fuse/file.c
fs/fuse/passthrough.c
fs/hfsplus/wrapper.c
fs/hpfs/hpfs_fn.h
fs/inode.c
fs/iomap/buffered-io.c
fs/isofs/isofs.h
fs/jfs/jfs_dmap.c
fs/lockd/mon.c
fs/namespace.c
fs/netfs/buffered_read.c
fs/netfs/locking.c
fs/netfs/misc.c
fs/netfs/read_collect.c
fs/netfs/write_issue.c
fs/nfs/callback_xdr.c
fs/nfs/client.c
fs/nfs/delegation.c
fs/nfs/localio.c
fs/nfs/nfs42proc.c
fs/nfs/nfs4state.c
fs/nfs_common/nfslocalio.c
fs/nfsd/filecache.c
fs/nfsd/localio.c
fs/nfsd/nfs4proc.c
fs/nfsd/nfs4state.c
fs/nfsd/nfssvc.c
fs/nfsd/state.h
fs/nfsd/trace.h
fs/nilfs2/dir.c
fs/nilfs2/namei.c
fs/nilfs2/nilfs.h
fs/nilfs2/page.c
fs/nls/nls_ucs2_utils.c
fs/notify/dnotify/dnotify.c
fs/notify/fanotify/fanotify_user.c
fs/notify/fsnotify.c
fs/notify/group.c
fs/notify/inotify/inotify_user.c
fs/notify/mark.c
fs/ntfs3/attrib.c
fs/ntfs3/attrlist.c
fs/ntfs3/file.c
fs/ntfs3/frecord.c
fs/ntfs3/fslog.c
fs/ntfs3/inode.c
fs/ntfs3/lib/decompress_common.h
fs/ntfs3/lib/lzx_decompress.c
fs/ntfs3/lznt.c
fs/ntfs3/namei.c
fs/ntfs3/ntfs_fs.h
fs/ntfs3/record.c
fs/ntfs3/run.c
fs/ntfs3/super.c
fs/ntfs3/xattr.c
fs/ocfs2/file.c
fs/open.c
fs/orangefs/orangefs-kernel.h
fs/overlayfs/file.c
fs/pidfs.c
fs/proc/fd.c
fs/proc/kcore.c
fs/proc/task_mmu.c
fs/reiserfs/inode.c
fs/reiserfs/reiserfs.h
fs/smb/client/cifs_unicode.c
fs/smb/client/cifsacl.h
fs/smb/client/cifsencrypt.c
fs/smb/client/cifsfs.c
fs/smb/client/cifsglob.h
fs/smb/client/cifspdu.h
fs/smb/client/cifsproto.h
fs/smb/client/cifssmb.c
fs/smb/client/compress.c
fs/smb/client/compress/lz77.c
fs/smb/client/connect.c
fs/smb/client/file.c
fs/smb/client/fs_context.c
fs/smb/client/fs_context.h
fs/smb/client/inode.c
fs/smb/client/misc.c
fs/smb/client/netmisc.c
fs/smb/client/readdir.c
fs/smb/client/reparse.c
fs/smb/client/sess.c
fs/smb/client/smb1ops.c
fs/smb/client/smb2inode.c
fs/smb/client/smb2misc.c
fs/smb/client/smb2ops.c
fs/smb/client/smb2pdu.c
fs/smb/client/smb2proto.h
fs/smb/client/smb2transport.c
fs/smb/client/smbdirect.c
fs/smb/client/smbdirect.h
fs/smb/common/smbfsctl.h
fs/smb/server/auth.c
fs/smb/server/ksmbd_netlink.h
fs/smb/server/mgmt/user_config.c
fs/smb/server/mgmt/user_config.h
fs/smb/server/mgmt/user_session.c
fs/smb/server/mgmt/user_session.h
fs/smb/server/server.c
fs/smb/server/smb2pdu.c
fs/smb/server/smb2pdu.h
fs/smb/server/smb_common.c
fs/smb/server/transport_ipc.c
fs/smb/server/transport_ipc.h
fs/smb/server/transport_rdma.c
fs/smb/server/unicode.c
fs/super.c
fs/udf/balloc.c
fs/udf/directory.c
fs/udf/inode.c
fs/udf/partition.c
fs/udf/super.c
fs/udf/truncate.c
fs/udf/udfdecl.h
fs/ufs/namei.c
fs/unicode/mkutf8data.c
fs/unicode/utf8data.c_shipped
fs/userfaultfd.c
fs/xfs/libxfs/xfs_ag.c
fs/xfs/libxfs/xfs_ag.h
fs/xfs/libxfs/xfs_alloc.c
fs/xfs/libxfs/xfs_alloc.h
fs/xfs/libxfs/xfs_attr.c
fs/xfs/libxfs/xfs_attr_leaf.c
fs/xfs/libxfs/xfs_attr_leaf.h
fs/xfs/libxfs/xfs_bmap.c
fs/xfs/libxfs/xfs_da_btree.c
fs/xfs/scrub/bmap_repair.c
fs/xfs/scrub/ialloc_repair.c
fs/xfs/scrub/repair.c
fs/xfs/xfs_aops.c
fs/xfs/xfs_bmap_util.c
fs/xfs/xfs_bmap_util.h
fs/xfs/xfs_buf_item_recover.c
fs/xfs/xfs_file.c
fs/xfs/xfs_filestream.c
fs/xfs/xfs_fsops.c
fs/xfs/xfs_icache.c
fs/xfs/xfs_inode.c
fs/xfs/xfs_inode.h
fs/xfs/xfs_ioctl.c
fs/xfs/xfs_iomap.c
fs/xfs/xfs_linux.h
fs/xfs/xfs_log.h
fs/xfs/xfs_log_cil.c
fs/xfs/xfs_log_recover.c
fs/xfs/xfs_mount.c
fs/xfs/xfs_reflink.c
fs/xfs/xfs_reflink.h
fs/xfs/xfs_trace.h
fs/zonefs/sysfs.c
include/acpi/cppc_acpi.h
include/asm-generic/Kbuild
include/asm-generic/uaccess.h
include/asm-generic/unaligned.h [deleted file]
include/crypto/chacha.h
include/crypto/internal/ecc.h
include/crypto/internal/poly1305.h
include/crypto/sha1_base.h
include/crypto/sha256_base.h
include/crypto/sha512_base.h
include/crypto/sm3_base.h
include/crypto/utils.h
include/drm/drm_kunit_helpers.h
include/drm/gpu_scheduler.h
include/linux/backing-file.h
include/linux/bpf.h
include/linux/bpf_mem_alloc.h
include/linux/bpf_types.h
include/linux/ceph/decode.h
include/linux/ceph/libceph.h
include/linux/closure.h
include/linux/compiler-gcc.h
include/linux/cpufreq.h
include/linux/device.h
include/linux/etherdevice.h
include/linux/fdtable.h
include/linux/folio_queue.h
include/linux/fs.h
include/linux/fs_context.h
include/linux/fsl/enetc_mdio.h
include/linux/fsnotify_backend.h
include/linux/hdmi.h
include/linux/host1x.h
include/linux/huge_mm.h
include/linux/ieee80211.h
include/linux/input.h
include/linux/iomap.h
include/linux/irqchip/arm-gic-v4.h
include/linux/ksm.h
include/linux/kvm_host.h
include/linux/mlx5/mlx5_ifc.h
include/linux/mm.h
include/linux/mtd/map.h
include/linux/netdevice.h
include/linux/nfs_fs_sb.h
include/linux/nfslocalio.h
include/linux/percpu.h
include/linux/ptp_classify.h
include/linux/sched.h
include/linux/sched/mm.h
include/linux/security.h
include/linux/soc/qcom/geni-se.h
include/linux/soundwire/sdw_intel.h
include/linux/sunrpc/xdr.h
include/linux/task_work.h
include/linux/tick.h
include/linux/tpm.h
include/linux/uaccess.h
include/linux/unaligned.h [new file with mode: 0644]
include/linux/userfaultfd_k.h
include/linux/virtio_net.h
include/net/bluetooth/bluetooth.h
include/net/bluetooth/l2cap.h
include/net/calipso.h
include/net/cfg80211.h
include/net/cipso_ipv4.h
include/net/genetlink.h
include/net/ieee80211_radiotap.h
include/net/ip_tunnels.h
include/net/mac80211.h
include/net/mac802154.h
include/net/mctp.h
include/net/netfilter/nf_tables.h
include/net/netns/xfrm.h
include/net/rtnetlink.h
include/net/sch_generic.h
include/net/sock.h
include/net/xfrm.h
include/rdma/ib_hdrs.h
include/rdma/iba.h
include/scsi/scsi_transport_fc.h
include/sound/hdaudio.h
include/target/target_core_backend.h
include/trace/events/afs.h
include/trace/events/btrfs.h
include/trace/events/dma.h
include/trace/events/huge_memory.h
include/trace/events/netfs.h
include/uapi/linux/bpf.h
include/uapi/linux/netfilter/nf_tables.h
include/uapi/linux/ublk_cmd.h
include/uapi/sound/asoc.h
include/video/da8xx-fb.h [deleted file]
include/xen/acpi.h
init/Kconfig
io_uring/io_uring.c
io_uring/io_uring.h
io_uring/net.c
io_uring/rsrc.c
io_uring/rw.c
kernel/bpf/bpf_lsm.c
kernel/bpf/btf.c
kernel/bpf/cgroup.c
kernel/bpf/core.c
kernel/bpf/devmap.c
kernel/bpf/helpers.c
kernel/bpf/inode.c
kernel/bpf/log.c
kernel/bpf/lpm_trie.c
kernel/bpf/memalloc.c
kernel/bpf/ringbuf.c
kernel/bpf/syscall.c
kernel/bpf/task_iter.c
kernel/bpf/verifier.c
kernel/cgroup/cgroup.c
kernel/debug/gdbstub.c
kernel/events/core.c
kernel/events/uprobes.c
kernel/fork.c
kernel/freezer.c
kernel/irq/msi.c
kernel/kthread.c
kernel/rcu/tasks.h
kernel/rcu/tree.c
kernel/rcu/tree_nocb.h
kernel/resource.c
kernel/resource_kunit.c
kernel/sched/core.c
kernel/sched/deadline.c
kernel/sched/ext.c
kernel/sched/ext.h
kernel/sched/fair.c
kernel/sched/psi.c
kernel/sched/sched.h
kernel/sched/stats.h
kernel/sched/syscalls.c
kernel/task_work.c
kernel/time/posix-clock.c
kernel/time/tick-sched.c
kernel/trace/bpf_trace.c
kernel/trace/fgraph.c
kernel/trace/ring_buffer.c
kernel/trace/trace.c
kernel/trace/trace_eprobe.c
kernel/trace/trace_fprobe.c
kernel/trace/trace_hwlat.c
kernel/trace/trace_kprobe.c
kernel/trace/trace_osnoise.c
kernel/trace/trace_probe.c
kernel/trace/trace_selftest.c
kernel/trace/trace_uprobe.c
lib/842/842.h
lib/Kconfig.debug
lib/buildid.c
lib/codetag.c
lib/crypto/aes.c
lib/crypto/blake2s-generic.c
lib/crypto/chacha.c
lib/crypto/chacha20poly1305-selftest.c
lib/crypto/chacha20poly1305.c
lib/crypto/curve25519-fiat32.c
lib/crypto/curve25519-hacl64.c
lib/crypto/des.c
lib/crypto/memneq.c
lib/crypto/mpi/mpi-mul.c
lib/crypto/poly1305-donna32.c
lib/crypto/poly1305-donna64.c
lib/crypto/poly1305.c
lib/crypto/sha1.c
lib/crypto/sha256.c
lib/crypto/utils.c
lib/decompress_unlz4.c
lib/decompress_unlzo.c
lib/hexdump.c
lib/iov_iter.c
lib/lz4/lz4_compress.c
lib/lz4/lz4_decompress.c
lib/lz4/lz4defs.h
lib/lzo/lzo1x_compress.c
lib/lzo/lzo1x_decompress_safe.c
lib/maple_tree.c
lib/objpool.c
lib/pldmfw/pldmfw.c
lib/random32.c
lib/siphash.c
lib/slub_kunit.c
lib/string.c
lib/vsprintf.c
lib/xxhash.c
lib/xz/xz_private.h
lib/zstd/common/mem.h
mm/Kconfig
mm/damon/tests/sysfs-kunit.h
mm/huge_memory.c
mm/kasan/init.c
mm/khugepaged.c
mm/memory.c
mm/mmap.c
mm/mremap.c
mm/numa_memblks.c
mm/page_alloc.c
mm/pagewalk.c
mm/secretmem.c
mm/shmem.c
mm/slab.h
mm/slab_common.c
mm/slub.c
mm/sparse-vmemmap.c
mm/swapfile.c
mm/vma.c
mm/vma.h
mm/vmscan.c
mm/zswap.c
net/802/garp.c
net/802/mrp.c
net/9p/Kconfig
net/9p/client.c
net/batman-adv/distributed-arp-table.c
net/bluetooth/af_bluetooth.c
net/bluetooth/bnep/core.c
net/bluetooth/coredump.c
net/bluetooth/eir.h
net/bluetooth/hci_conn.c
net/bluetooth/hci_core.c
net/bluetooth/hci_event.c
net/bluetooth/hci_sock.c
net/bluetooth/hci_sync.c
net/bluetooth/iso.c
net/bluetooth/l2cap_core.c
net/bluetooth/mgmt.c
net/bluetooth/mgmt_util.c
net/bluetooth/rfcomm/core.c
net/bluetooth/rfcomm/sock.c
net/bluetooth/sco.c
net/bpf/test_run.c
net/bridge/br_fdb.c
net/bridge/br_mdb.c
net/bridge/br_netfilter_hooks.c
net/bridge/br_netlink.c
net/bridge/br_private.h
net/bridge/br_stp_bpdu.c
net/bridge/br_vlan.c
net/caif/cfrfml.c
net/core/dev.c
net/core/drop_monitor.c
net/core/dst.c
net/core/filter.c
net/core/gro.c
net/core/net-traces.c
net/core/netpoll.c
net/core/rtnetlink.c
net/core/sock.c
net/core/sock_map.c
net/core/tso.c
net/dccp/ccids/ccid3.c
net/dccp/options.c
net/dsa/dsa.c
net/dsa/user.c
net/ipv4/cipso_ipv4.c
net/ipv4/devinet.c
net/ipv4/inet_connection_sock.c
net/ipv4/ip_gre.c
net/ipv4/ip_options.c
net/ipv4/ip_tunnel.c
net/ipv4/netfilter/nf_dup_ipv4.c
net/ipv4/netfilter/nft_fib_ipv4.c
net/ipv4/tcp_bpf.c
net/ipv4/tcp_input.c
net/ipv4/tcp_offload.c
net/ipv4/tcp_output.c
net/ipv4/udp.c
net/ipv4/udp_offload.c
net/ipv4/xfrm4_policy.c
net/ipv6/addrconf.c
net/ipv6/calipso.c
net/ipv6/netfilter/nf_dup_ipv6.c
net/ipv6/netfilter/nf_reject_ipv6.c
net/ipv6/netfilter/nft_fib_ipv6.c
net/ipv6/tcpv6_offload.c
net/ipv6/udp.c
net/ipv6/xfrm6_policy.c
net/l2tp/l2tp_netlink.c
net/mac80211/Kconfig
net/mac80211/cfg.c
net/mac80211/ieee80211_i.h
net/mac80211/key.c
net/mac80211/link.c
net/mac80211/main.c
net/mac80211/mesh.c
net/mac80211/mesh_hwmp.c
net/mac80211/michael.c
net/mac80211/mlme.c
net/mac80211/ocb.c
net/mac80211/rx.c
net/mac80211/status.c
net/mac80211/tkip.c
net/mac80211/tx.c
net/mac80211/wep.c
net/mac80211/wpa.c
net/mac802154/rx.c
net/mac802154/scan.c
net/mac802154/tx.c
net/mctp/af_mctp.c
net/mctp/device.c
net/mctp/neigh.c
net/mctp/route.c
net/mpls/af_mpls.c
net/mptcp/crypto.c
net/mptcp/mib.c
net/mptcp/mib.h
net/mptcp/pm_netlink.c
net/mptcp/protocol.c
net/mptcp/protocol.h
net/mptcp/subflow.c
net/ncsi/ncsi-manage.c
net/netfilter/ipvs/ip_vs_ftp.c
net/netfilter/ipvs/ip_vs_sync.c
net/netfilter/nf_bpf_link.c
net/netfilter/nf_conntrack_proto_tcp.c
net/netfilter/nf_synproxy_core.c
net/netfilter/nft_byteorder.c
net/netfilter/nft_exthdr.c
net/netfilter/nft_payload.c
net/netfilter/x_tables.c
net/netfilter/xt_CHECKSUM.c
net/netfilter/xt_CLASSIFY.c
net/netfilter/xt_CONNSECMARK.c
net/netfilter/xt_CT.c
net/netfilter/xt_IDLETIMER.c
net/netfilter/xt_LED.c
net/netfilter/xt_NFLOG.c
net/netfilter/xt_RATEEST.c
net/netfilter/xt_SECMARK.c
net/netfilter/xt_TRACE.c
net/netfilter/xt_addrtype.c
net/netfilter/xt_cluster.c
net/netfilter/xt_connbytes.c
net/netfilter/xt_connlimit.c
net/netfilter/xt_connmark.c
net/netfilter/xt_mark.c
net/netlink/af_netlink.c
net/netlink/genetlink.c
net/phonet/af_phonet.c
net/phonet/pn_netlink.c
net/rxrpc/ar-internal.h
net/rxrpc/io_thread.c
net/rxrpc/local_object.c
net/rxrpc/sendmsg.c
net/sched/act_api.c
net/sched/cls_api.c
net/sched/em_cmp.c
net/sched/sch_api.c
net/sched/sch_generic.c
net/sched/sch_taprio.c
net/sctp/socket.c
net/smc/smc_inet.c
net/smc/smc_pnet.c
net/smc/smc_wr.c
net/socket.c
net/sunrpc/svc.c
net/sunrpc/xprtrdma/ib_client.c
net/sunrpc/xprtrdma/svc_rdma_recvfrom.c
net/sunrpc/xprtrdma/svc_rdma_sendto.c
net/tls/trace.h
net/vmw_vsock/virtio_transport.c
net/vmw_vsock/virtio_transport_common.c
net/vmw_vsock/vsock_bpf.c
net/wireless/core.c
net/wireless/nl80211.c
net/wireless/radiotap.c
net/wireless/scan.c
net/xfrm/xfrm_device.c
net/xfrm/xfrm_policy.c
net/xfrm/xfrm_user.c
rust/bindgen_parameters
rust/helpers/mutex.c
rust/kernel/device.rs
rust/kernel/firmware.rs
rust/kernel/kunit.rs
rust/kernel/lib.rs
rust/kernel/sync/locked_by.rs
scripts/Kconfig.include
scripts/Makefile.compiler
scripts/Makefile.dtbs
scripts/Makefile.package
scripts/include/list.h
scripts/kconfig/expr.c
scripts/kconfig/menu.c
scripts/kconfig/parser.y
scripts/kconfig/qconf.cc
scripts/mod/file2alias.c
scripts/mod/sumversion.c
scripts/package/builddeb
scripts/package/install-extmod-build
scripts/package/mkdebian
scripts/rustc-llvm-version.sh [new file with mode: 0755]
security/Kconfig.hardening
security/apparmor/policy_unpack.c
security/ipe/Kconfig
security/ipe/policy.c
security/keys/trusted-keys/trusted_tpm2.c
security/security.c
security/tomoyo/Kconfig
security/tomoyo/Makefile
security/tomoyo/common.c
security/tomoyo/common.h
security/tomoyo/gc.c
security/tomoyo/hooks.h [deleted file]
security/tomoyo/init.c [deleted file]
security/tomoyo/load_policy.c
security/tomoyo/proxy.c [deleted file]
security/tomoyo/securityfs_if.c
security/tomoyo/tomoyo.c [new file with mode: 0644]
security/tomoyo/util.c
sound/Kconfig
sound/aoa/codecs/onyx.c
sound/aoa/codecs/tas.c
sound/core/compress_offload.c
sound/core/control.c
sound/core/init.c
sound/core/oss/mixer_oss.c
sound/core/oss/rate.c
sound/core/pcm_native.c
sound/core/sound.c
sound/firewire/amdtp-stream.c
sound/hda/hdac_stream.c
sound/hda/intel-dsp-config.c
sound/hda/intel-sdw-acpi.c
sound/i2c/cs8427.c
sound/isa/gus/gus_pcm.c
sound/pci/hda/Kconfig
sound/pci/hda/cs35l41_hda_i2c.c
sound/pci/hda/hda_codec.c
sound/pci/hda/hda_controller.c
sound/pci/hda/hda_controller.h
sound/pci/hda/hda_eld.c
sound/pci/hda/hda_generic.c
sound/pci/hda/hda_generic.h
sound/pci/hda/hda_intel.c
sound/pci/hda/patch_conexant.c
sound/pci/hda/patch_cs8409.c
sound/pci/hda/patch_realtek.c
sound/pci/hda/tas2781_hda_i2c.c
sound/soc/amd/acp/acp-sdw-sof-mach.c
sound/soc/amd/yc/acp6x-mach.c
sound/soc/atmel/mchp-pdmc.c
sound/soc/codecs/adau1701.c
sound/soc/codecs/adau17x1.c
sound/soc/codecs/aw88399.c
sound/soc/codecs/cs35l45-tables.c
sound/soc/codecs/cs35l45.h
sound/soc/codecs/cs42l51.c
sound/soc/codecs/lpass-rx-macro.c
sound/soc/codecs/max98388.c
sound/soc/codecs/pcm3060-i2c.c
sound/soc/codecs/pcm3060-spi.c
sound/soc/codecs/pcm3060.c
sound/soc/codecs/pcm3060.h
sound/soc/codecs/pcm6240.c
sound/soc/codecs/peb2466.c
sound/soc/codecs/rt5640.c
sound/soc/codecs/rt722-sdca-sdw.c
sound/soc/codecs/sigmadsp-i2c.c
sound/soc/codecs/tas2781-fmwlib.c
sound/soc/codecs/tas2781-i2c.c
sound/soc/codecs/tas571x.c
sound/soc/codecs/tlv320aic31xx.c
sound/soc/codecs/wcd937x.c
sound/soc/codecs/wcd937x.h
sound/soc/codecs/wm5102.c
sound/soc/codecs/wm8958-dsp2.c
sound/soc/fsl/fsl_esai.c
sound/soc/fsl/fsl_micfil.c
sound/soc/fsl/fsl_sai.c
sound/soc/fsl/fsl_sai.h
sound/soc/fsl/imx-card.c
sound/soc/intel/atom/sst/sst_acpi.c
sound/soc/intel/avs/core.c
sound/soc/intel/avs/pcm.c
sound/soc/intel/avs/pcm.h [new file with mode: 0644]
sound/soc/intel/boards/bytcr_rt5640.c
sound/soc/intel/boards/sof_sdw.c
sound/soc/intel/common/soc-acpi-intel-arl-match.c
sound/soc/intel/common/soc-acpi-intel-lnl-match.c
sound/soc/intel/common/soc-acpi-intel-rpl-match.c
sound/soc/loongson/loongson_card.c
sound/soc/qcom/Kconfig
sound/soc/qcom/lpass-cpu.c
sound/soc/qcom/sc7280.c
sound/soc/qcom/sdm845.c
sound/soc/qcom/sm8250.c
sound/soc/sh/rcar/core.c
sound/soc/soc-dapm.c
sound/soc/soc-topology.c
sound/soc/sof/amd/acp-loader.c
sound/soc/sof/amd/acp.c
sound/soc/sof/intel/hda-dai-ops.c
sound/soc/sof/intel/hda-dai.c
sound/soc/sof/intel/hda-loader.c
sound/soc/sof/iomem-utils.c
sound/soc/sof/ipc4-topology.c
sound/soc/sof/sof-utils.c
sound/usb/line6/capture.c
sound/usb/line6/capture.h
sound/usb/line6/driver.c
sound/usb/line6/driver.h
sound/usb/line6/midi.c
sound/usb/line6/midi.h
sound/usb/line6/midibuf.c
sound/usb/line6/midibuf.h
sound/usb/line6/pcm.c
sound/usb/line6/pcm.h
sound/usb/line6/playback.c
sound/usb/line6/playback.h
sound/usb/line6/pod.c
sound/usb/line6/podhd.c
sound/usb/line6/toneport.c
sound/usb/line6/variax.c
sound/usb/mixer_quirks.c
sound/usb/mixer_scarlett2.c
sound/usb/quirks.c
sound/usb/stream.c
tools/arch/arm64/include/asm/cputype.h
tools/arch/arm64/vdso [deleted symlink]
tools/arch/loongarch/vdso [deleted symlink]
tools/arch/powerpc/vdso [deleted symlink]
tools/arch/s390/vdso [deleted symlink]
tools/arch/x86/include/asm/msr-index.h
tools/arch/x86/include/uapi/asm/kvm.h
tools/arch/x86/include/uapi/asm/unistd_32.h
tools/arch/x86/include/uapi/asm/unistd_64.h
tools/arch/x86/lib/insn.c
tools/arch/x86/vdso [deleted symlink]
tools/build/feature/Makefile
tools/include/asm-generic/unaligned.h [deleted file]
tools/include/linux/bits.h
tools/include/linux/unaligned.h [new file with mode: 0644]
tools/include/uapi/linux/bits.h
tools/include/uapi/linux/bpf.h
tools/include/uapi/linux/const.h
tools/include/uapi/linux/in.h
tools/include/vdso/unaligned.h [new file with mode: 0644]
tools/perf/Makefile.config
tools/perf/builtin-trace.c
tools/perf/check-header_ignore_hunks/lib/list_sort.c [new file with mode: 0644]
tools/perf/check-headers.sh
tools/perf/tests/shell/base_probe/test_adding_blacklisted.sh
tools/perf/trace/beauty/arch/x86/include/asm/irq_vectors.h
tools/perf/trace/beauty/fs_at_flags.sh
tools/perf/trace/beauty/include/linux/socket.h
tools/perf/trace/beauty/include/uapi/linux/fcntl.h
tools/perf/trace/beauty/include/uapi/linux/sched.h
tools/perf/trace/beauty/include/uapi/sound/asound.h
tools/perf/trace/beauty/msg_flags.c
tools/perf/util/arm-spe-decoder/arm-spe-pkt-decoder.c
tools/perf/util/bpf_skel/augmented_raw_syscalls.bpf.c
tools/perf/util/cap.c
tools/perf/util/cs-etm.c
tools/perf/util/dwarf-aux.h
tools/perf/util/intel-pt-decoder/intel-pt-pkt-decoder.c
tools/perf/util/python.c
tools/perf/util/symbol.c
tools/perf/util/syscalltbl.c
tools/perf/util/vdso.c
tools/sched_ext/include/scx/common.bpf.h
tools/sched_ext/include/scx/compat.bpf.h
tools/sched_ext/include/scx/user_exit_info.h
tools/sched_ext/scx_flatcg.bpf.c
tools/sched_ext/scx_qmap.bpf.c
tools/testing/cxl/test/cxl.c
tools/testing/cxl/test/mem.c
tools/testing/radix-tree/maple.c
tools/testing/selftests/Makefile
tools/testing/selftests/alsa/Makefile
tools/testing/selftests/bpf/Makefile
tools/testing/selftests/bpf/bpf_test_modorder_x/Makefile [new file with mode: 0644]
tools/testing/selftests/bpf/bpf_test_modorder_x/bpf_test_modorder_x.c [new file with mode: 0644]
tools/testing/selftests/bpf/bpf_test_modorder_y/Makefile [new file with mode: 0644]
tools/testing/selftests/bpf/bpf_test_modorder_y/bpf_test_modorder_y.c [new file with mode: 0644]
tools/testing/selftests/bpf/map_tests/lpm_trie_map_get_next_key.c [new file with mode: 0644]
tools/testing/selftests/bpf/prog_tests/bpf_iter.c
tools/testing/selftests/bpf/prog_tests/cgroup_ancestor.c
tools/testing/selftests/bpf/prog_tests/cpumask.c
tools/testing/selftests/bpf/prog_tests/fill_link_info.c
tools/testing/selftests/bpf/prog_tests/kfunc_module_order.c [new file with mode: 0644]
tools/testing/selftests/bpf/prog_tests/netfilter_link_attach.c
tools/testing/selftests/bpf/prog_tests/verifier.c
tools/testing/selftests/bpf/prog_tests/xdp_devmap_attach.c
tools/testing/selftests/bpf/progs/cpumask_common.h
tools/testing/selftests/bpf/progs/cpumask_failure.c
tools/testing/selftests/bpf/progs/cpumask_success.c
tools/testing/selftests/bpf/progs/kfunc_module_order.c [new file with mode: 0644]
tools/testing/selftests/bpf/progs/test_tcp_custom_syncookie.h
tools/testing/selftests/bpf/progs/test_xdp_with_devmap_helpers.c
tools/testing/selftests/bpf/progs/verifier_bits_iter.c
tools/testing/selftests/bpf/progs/verifier_bpf_fastcall.c
tools/testing/selftests/bpf/progs/verifier_const.c
tools/testing/selftests/bpf/progs/verifier_linked_scalars.c [new file with mode: 0644]
tools/testing/selftests/bpf/progs/verifier_movsx.c
tools/testing/selftests/bpf/progs/verifier_mtu.c [new file with mode: 0644]
tools/testing/selftests/bpf/progs/verifier_scalar_ids.c
tools/testing/selftests/bpf/progs/verifier_search_pruning.c
tools/testing/selftests/bpf/testing_helpers.c
tools/testing/selftests/bpf/testing_helpers.h
tools/testing/selftests/bpf/veristat.cfg
tools/testing/selftests/breakpoints/step_after_suspend_test.c
tools/testing/selftests/clone3/clone3_cap_checkpoint_restore.c
tools/testing/selftests/core/.gitignore
tools/testing/selftests/devices/probe/test_discoverable_devices.py
tools/testing/selftests/exec/.gitignore
tools/testing/selftests/ftrace/test.d/ftrace/fgraph-profiler.tc [new file with mode: 0644]
tools/testing/selftests/hid/Makefile
tools/testing/selftests/intel_pstate/run.sh
tools/testing/selftests/kvm/Makefile
tools/testing/selftests/kvm/aarch64/set_id_regs.c
tools/testing/selftests/kvm/memslot_modification_stress_test.c
tools/testing/selftests/kvm/memslot_perf_test.c
tools/testing/selftests/kvm/x86_64/cpuid_test.c
tools/testing/selftests/mm/hmm-tests.c
tools/testing/selftests/mm/khugepaged.c
tools/testing/selftests/mm/uffd-unit-tests.c
tools/testing/selftests/mount_setattr/mount_setattr_test.c
tools/testing/selftests/net/.gitignore
tools/testing/selftests/net/forwarding/ip6gre_flat.sh
tools/testing/selftests/net/forwarding/ip6gre_flat_key.sh
tools/testing/selftests/net/forwarding/ip6gre_flat_keys.sh
tools/testing/selftests/net/forwarding/ip6gre_hier.sh
tools/testing/selftests/net/forwarding/ip6gre_hier_key.sh
tools/testing/selftests/net/forwarding/ip6gre_hier_keys.sh
tools/testing/selftests/net/forwarding/ip6gre_lib.sh
tools/testing/selftests/net/forwarding/no_forwarding.sh
tools/testing/selftests/net/lib/py/nsim.py
tools/testing/selftests/net/mptcp/mptcp_connect.sh
tools/testing/selftests/net/mptcp/mptcp_join.sh
tools/testing/selftests/net/netfilter/Makefile
tools/testing/selftests/net/netfilter/config
tools/testing/selftests/net/netfilter/conntrack_dump_flush.c
tools/testing/selftests/net/netfilter/conntrack_vrf.sh
tools/testing/selftests/net/netfilter/nft_audit.sh
tools/testing/selftests/net/netfilter/nft_flowtable.sh
tools/testing/selftests/net/netfilter/vxlan_mtu_frag.sh [new file with mode: 0755]
tools/testing/selftests/net/rds/.gitignore [new file with mode: 0644]
tools/testing/selftests/net/rds/Makefile
tools/testing/selftests/net/rds/test.py [changed mode: 0644->0755]
tools/testing/selftests/net/ynl.mk
tools/testing/selftests/rseq/rseq.c
tools/testing/selftests/rseq/rseq.h
tools/testing/selftests/rtc/rtctest.c
tools/testing/selftests/sched_ext/Makefile
tools/testing/selftests/sched_ext/create_dsq.bpf.c
tools/testing/selftests/sched_ext/ddsp_bogus_dsq_fail.bpf.c
tools/testing/selftests/sched_ext/ddsp_vtimelocal_fail.bpf.c
tools/testing/selftests/sched_ext/dsp_local_on.bpf.c
tools/testing/selftests/sched_ext/enq_last_no_enq_fails.bpf.c
tools/testing/selftests/sched_ext/enq_last_no_enq_fails.c
tools/testing/selftests/sched_ext/enq_select_cpu_fails.bpf.c
tools/testing/selftests/sched_ext/exit.bpf.c
tools/testing/selftests/sched_ext/hotplug.bpf.c
tools/testing/selftests/sched_ext/init_enable_count.bpf.c
tools/testing/selftests/sched_ext/maximal.bpf.c
tools/testing/selftests/sched_ext/maybe_null.bpf.c
tools/testing/selftests/sched_ext/maybe_null_fail_dsp.bpf.c
tools/testing/selftests/sched_ext/maybe_null_fail_yld.bpf.c
tools/testing/selftests/sched_ext/prog_run.bpf.c
tools/testing/selftests/sched_ext/select_cpu_dfl.bpf.c
tools/testing/selftests/sched_ext/select_cpu_dfl_nodispatch.bpf.c
tools/testing/selftests/sched_ext/select_cpu_dispatch.bpf.c
tools/testing/selftests/sched_ext/select_cpu_dispatch_bad_dsq.bpf.c
tools/testing/selftests/sched_ext/select_cpu_dispatch_dbl_dsp.bpf.c
tools/testing/selftests/sched_ext/select_cpu_vtime.bpf.c
tools/testing/selftests/timers/posix_timers.c
tools/testing/selftests/vDSO/Makefile
tools/testing/selftests/vDSO/vdso_test_chacha.c
tools/testing/selftests/vDSO/vdso_test_getrandom.c
tools/testing/selftests/vDSO/vgetrandom-chacha.S [new file with mode: 0644]
tools/testing/selftests/watchdog/watchdog-test.c
tools/testing/vma/vma.c
tools/tracing/rtla/Makefile.rtla
tools/tracing/rtla/src/osnoise_top.c
tools/tracing/rtla/src/timerlat_top.c
tools/usb/usbip/src/usbip_detach.c
virt/kvm/kvm_main.c

index 0374777cc6628e3650b67d51b7f00b3b547490a2..9a94c514e32c51c87b3915d6ccdc45dca7577774 100644 (file)
--- a/.mailmap
+++ b/.mailmap
@@ -73,6 +73,8 @@ Andrey Ryabinin <[email protected]> <[email protected]>
 Andrzej Hajda <[email protected]> <[email protected]>
 André Almeida <[email protected]> <[email protected]>
 Andy Adamson <[email protected]>
 Andy Shevchenko <[email protected]> <[email protected]>
 Andy Shevchenko <[email protected]> <[email protected]>
 Anilkumar Kolli <[email protected]> <[email protected]>
 Faith Ekstrand <[email protected]> <[email protected]>
 Faith Ekstrand <[email protected]> <[email protected]>
 Faith Ekstrand <[email protected]> <[email protected]>
 Felipe W Damasio <[email protected]>
 Felix Kuhling <[email protected]>
 Felix Moeller <[email protected]>
 Filipe Lautert <[email protected]>
+Fiona Behrens <[email protected]>
 Franck Bui-Huu <[email protected]>
 Jens Osterkamp <[email protected]>
 Jernej Skrabec <[email protected]> <[email protected]>
+Jesper Dangaard Brouer <[email protected]> <[email protected]>
+Jesper Dangaard Brouer <[email protected]> <[email protected]>
+Jesper Dangaard Brouer <[email protected]> <[email protected]>
+Jesper Dangaard Brouer <[email protected]> <[email protected]>
+Jesper Dangaard Brouer <[email protected]> <[email protected]>
 Jessica Zhang <[email protected]> <[email protected]>
diff --git a/CREDITS b/CREDITS
index d439f5a1bc00d014ad600f05971236449f4b67cc..63f53feefa0ae45b8ec434eb7f66146e803bde44 100644 (file)
--- a/CREDITS
+++ b/CREDITS
@@ -1358,10 +1358,6 @@ D: Major kbuild rework during the 2.5 cycle
 D: ISDN Maintainer
 S: USA
 
-N: Gerrit Renker
-D: DCCP protocol support.
-
 N: Philip Gladstone
 D: Kernel / timekeeping stuff
@@ -1677,11 +1673,6 @@ W: http://www.carumba.com/
 D: bug toaster (A1 sauce makes all the difference)
 D: Random linux hacker
 
-N: James Hogan
-D: Metag architecture maintainer
-D: TZ1090 SoC maintainer
-
 N: Tim Hockin
 W: http://www.hockin.org/~thockin
@@ -1697,6 +1688,11 @@ D: hwmon subsystem maintainer
 D: i2c-sis96x and i2c-stub SMBus drivers
 S: USA
 
+N: James Hogan
+D: Metag architecture maintainer
+D: TZ1090 SoC maintainer
+
 N: Dirk Hohndel
 D: The XFree86[tm] Project
@@ -1872,6 +1868,10 @@ S: K osmidomkum 723
 S: 160 00 Praha 6
 S: Czech Republic
 
+N: Seth Jennings
+D: Creation and maintenance of zswap
+
 N: Jeremy Kerr
 D: Maintainer of SPU File System
 
@@ -2188,19 +2188,6 @@ N: Mike Kravetz
 D: Maintenance and development of the hugetlb subsystem
 
-N: Seth Jennings
-D: Creation and maintenance of zswap
-
-N: Dan Streetman
-D: Maintenance and development of zswap
-D: Creation and maintenance of the zpool API
-
-N: Vitaly Wool
-D: Maintenance and development of zswap
-
 N: Andreas S. Krebs
 D: CYPRESS CY82C693 chipset IDE, Digital's PC-Alpha 164SX boards
@@ -3191,6 +3178,11 @@ N: Ken Pizzini
 D: CDROM driver "sonycd535" (Sony CDU-535/531)
 
+N: Mathieu Poirier
+D: CoreSight kernel subsystem, Maintainer 2014-2022
+D: Perf tool support for CoreSight
+
 N: Stelian Pop
 P: 1024D/EDBB6147 7B36 0E07 04BC 11DC A7A0  D3F7 7185 9E7A EDBB 6147
@@ -3300,6 +3292,10 @@ S: Schlossbergring 9
 S: 79098 Freiburg
 S: Germany
 
+N: Gerrit Renker
+D: DCCP protocol support.
+
 N: Thomas Renninger
 D: cpupowerutils
@@ -3576,11 +3572,6 @@ D: several improvements to system programs
 S: Oldenburg
 S: Germany
 
-N: Mathieu Poirier
-D: CoreSight kernel subsystem, Maintainer 2014-2022
-D: Perf tool support for CoreSight
-
 N: Robert Schwebel
 W: https://www.schwebel.de
@@ -3771,6 +3762,11 @@ S: Chr. Winthersvej 1 B, st.th.
 S: DK-1860 Frederiksberg C
 S: Denmark
 
+N: Dan Streetman
+D: Maintenance and development of zswap
+D: Creation and maintenance of the zpool API
+
 N: Drew Sullivan
 W: http://www.ss.org/
@@ -4286,6 +4282,10 @@ S: Pipers Way
 S: Swindon. SN3 1RJ
 S: England
 
+N: Vitaly Wool
+D: Maintenance and development of zswap
+
 N: Chris Wright
 D: hacking on LSM framework and security modules.
index f38e641df0e97fc45c8398125a24764209df191f..f93a467db628d6582bb9b3baa89031a6144cd1ce 100644 (file)
@@ -223,7 +223,10 @@ are signed through the PKCS#7 message format to enforce some level of
 authorization of the policies (prohibiting an attacker from gaining
 unconstrained root, and deploying an "allow all" policy). These
 policies must be signed by a certificate that chains to the
-``SYSTEM_TRUSTED_KEYRING``. With openssl, the policy can be signed by::
+``SYSTEM_TRUSTED_KEYRING``, or to the secondary and/or platform keyrings if
+``CONFIG_IPE_POLICY_SIG_SECONDARY_KEYRING`` and/or
+``CONFIG_IPE_POLICY_SIG_PLATFORM_KEYRING`` are enabled, respectively.
+With openssl, the policy can be signed by::
 
    openssl smime -sign \
       -in "$MY_POLICY" \
@@ -266,7 +269,7 @@ in the kernel. This file is write-only and accepts a PKCS#7 signed
 policy. Two checks will always be performed on this policy: First, the
 ``policy_names`` must match with the updated version and the existing
 version. Second the updated policy must have a policy version greater than
-or equal to the currently-running version. This is to prevent rollback attacks.
+the currently-running version. This is to prevent rollback attacks.
 
 The ``delete`` file is used to remove a policy that is no longer needed.
 This file is write-only and accepts a value of ``1`` to delete the policy.
index fe1be4ad88cb2a2df6da5e20ff2120fc44fb65c2..a21369eba034d57aa2448b01f8b2e7f539cf0d93 100644 (file)
@@ -425,8 +425,8 @@ This governor exposes only one tunable:
 
 ``rate_limit_us``
        Minimum time (in microseconds) that has to pass between two consecutive
-       runs of governor computations (default: 1000 times the scaling driver's
-       transition latency).
+       runs of governor computations (default: 1.5 times the scaling driver's
+       transition latency or the maximum 2ms).
 
        The purpose of this tunable is to reduce the scheduler context overhead
        of the governor which might be excessive without it.
@@ -474,17 +474,17 @@ This governor exposes the following tunables:
        This is how often the governor's worker routine should run, in
        microseconds.
 
-       Typically, it is set to values of the order of 10000 (10 ms).  Its
-       default value is equal to the value of ``cpuinfo_transition_latency``
-       for each policy this governor is attached to (but since the unit here
-       is greater by 1000, this means that the time represented by
-       ``sampling_rate`` is 1000 times greater than the transition latency by
-       default).
+       Typically, it is set to values of the order of 2000 (2 ms).  Its
+       default value is to add a 50% breathing room
+       to ``cpuinfo_transition_latency`` on each policy this governor is
+       attached to. The minimum is typically the length of two scheduler
+       ticks.
 
        If this tunable is per-policy, the following shell command sets the time
-       represented by it to be 750 times as high as the transition latency::
+       represented by it to be 1.5 times as high as the transition latency
+       (the default)::
 
-       # echo `$(($(cat cpuinfo_transition_latency) * 750 / 1000)) > ondemand/sampling_rate
+       # echo `$(($(cat cpuinfo_transition_latency) * 3 / 2)) > ondemand/sampling_rate
 
 ``up_threshold``
        If the estimated CPU load is above this value (in percent), the governor
index aa22893b62bc342eb47e9a7e8caacc3e51c09112..64bd779593003b07b7a6fa94558049a9d7f5e2b4 100644 (file)
@@ -12,7 +12,7 @@ ones.
 
 Of course this is a bad idea to rely on the alignment trap to perform
 unaligned memory access in general.  If those access are predictable, you
-are better to use the macros provided by include/asm/unaligned.h.  The
+are better to use the macros provided by include/linux/unaligned.h.  The
 alignment trap can fixup misaligned access for the exception cases, but at
 a high performance cost.  It better be rare.
 
index 9eb5e70b488840ed570e786f5d530ff88ab98609..65bfab1b1861467358d201619018b1a327de4ad8 100644 (file)
@@ -146,6 +146,8 @@ stable kernels.
 +----------------+-----------------+-----------------+-----------------------------+
 | ARM            | Cortex-A715     | #2645198        | ARM64_ERRATUM_2645198       |
 +----------------+-----------------+-----------------+-----------------------------+
+| ARM            | Cortex-A715     | #3456084        | ARM64_ERRATUM_3194386       |
++----------------+-----------------+-----------------+-----------------------------+
 | ARM            | Cortex-A720     | #3456091        | ARM64_ERRATUM_3194386       |
 +----------------+-----------------+-----------------+-----------------------------+
 | ARM            | Cortex-A725     | #3456106        | ARM64_ERRATUM_3194386       |
@@ -186,6 +188,8 @@ stable kernels.
 +----------------+-----------------+-----------------+-----------------------------+
 | ARM            | Neoverse-N2     | #3324339        | ARM64_ERRATUM_3194386       |
 +----------------+-----------------+-----------------+-----------------------------+
+| ARM            | Neoverse-N3     | #3456111        | ARM64_ERRATUM_3194386       |
++----------------+-----------------+-----------------+-----------------------------+
 | ARM            | Neoverse-V1     | #1619801        | N/A                         |
 +----------------+-----------------+-----------------+-----------------------------+
 | ARM            | Neoverse-V1     | #3324341        | ARM64_ERRATUM_3194386       |
@@ -289,3 +293,5 @@ stable kernels.
 +----------------+-----------------+-----------------+-----------------------------+
 | Microsoft      | Azure Cobalt 100| #2253138        | ARM64_ERRATUM_2253138       |
 +----------------+-----------------+-----------------+-----------------------------+
+| Microsoft      | Azure Cobalt 100| #3324339        | ARM64_ERRATUM_3194386       |
++----------------+-----------------+-----------------+-----------------------------+
diff --git a/Documentation/core-api/folio_queue.rst b/Documentation/core-api/folio_queue.rst
new file mode 100644 (file)
index 0000000..1fe7a9b
--- /dev/null
@@ -0,0 +1,212 @@
+.. SPDX-License-Identifier: GPL-2.0+
+
+===========
+Folio Queue
+===========
+
+:Author: David Howells <[email protected]>
+
+.. Contents:
+
+ * Overview
+ * Initialisation
+ * Adding and removing folios
+ * Querying information about a folio
+ * Querying information about a folio_queue
+ * Folio queue iteration
+ * Folio marks
+ * Lockless simultaneous production/consumption issues
+
+
+Overview
+========
+
+The folio_queue struct forms a single segment in a segmented list of folios
+that can be used to form an I/O buffer.  As such, the list can be iterated over
+using the ITER_FOLIOQ iov_iter type.
+
+The publicly accessible members of the structure are::
+
+       struct folio_queue {
+               struct folio_queue *next;
+               struct folio_queue *prev;
+               ...
+       };
+
+A pair of pointers are provided, ``next`` and ``prev``, that point to the
+segments on either side of the segment being accessed.  Whilst this is a
+doubly-linked list, it is intentionally not a circular list; the outward
+sibling pointers in terminal segments should be NULL.
+
+Each segment in the list also stores:
+
+ * an ordered sequence of folio pointers,
+ * the size of each folio and
+ * three 1-bit marks per folio,
+
+but hese should not be accessed directly as the underlying data structure may
+change, but rather the access functions outlined below should be used.
+
+The facility can be made accessible by::
+
+       #include <linux/folio_queue.h>
+
+and to use the iterator::
+
+       #include <linux/uio.h>
+
+
+Initialisation
+==============
+
+A segment should be initialised by calling::
+
+       void folioq_init(struct folio_queue *folioq);
+
+with a pointer to the segment to be initialised.  Note that this will not
+necessarily initialise all the folio pointers, so care must be taken to check
+the number of folios added.
+
+
+Adding and removing folios
+==========================
+
+Folios can be set in the next unused slot in a segment struct by calling one
+of::
+
+       unsigned int folioq_append(struct folio_queue *folioq,
+                                  struct folio *folio);
+
+       unsigned int folioq_append_mark(struct folio_queue *folioq,
+                                       struct folio *folio);
+
+Both functions update the stored folio count, store the folio and note its
+size.  The second function also sets the first mark for the folio added.  Both
+functions return the number of the slot used.  [!] Note that no attempt is made
+to check that the capacity wasn't overrun and the list will not be extended
+automatically.
+
+A folio can be excised by calling::
+
+       void folioq_clear(struct folio_queue *folioq, unsigned int slot);
+
+This clears the slot in the array and also clears all the marks for that folio,
+but doesn't change the folio count - so future accesses of that slot must check
+if the slot is occupied.
+
+
+Querying information about a folio
+==================================
+
+Information about the folio in a particular slot may be queried by the
+following function::
+
+       struct folio *folioq_folio(const struct folio_queue *folioq,
+                                  unsigned int slot);
+
+If a folio has not yet been set in that slot, this may yield an undefined
+pointer.  The size of the folio in a slot may be queried with either of::
+
+       unsigned int folioq_folio_order(const struct folio_queue *folioq,
+                                       unsigned int slot);
+
+       size_t folioq_folio_size(const struct folio_queue *folioq,
+                                unsigned int slot);
+
+The first function returns the size as an order and the second as a number of
+bytes.
+
+
+Querying information about a folio_queue
+========================================
+
+Information may be retrieved about a particular segment with the following
+functions::
+
+       unsigned int folioq_nr_slots(const struct folio_queue *folioq);
+
+       unsigned int folioq_count(struct folio_queue *folioq);
+
+       bool folioq_full(struct folio_queue *folioq);
+
+The first function returns the maximum capacity of a segment.  It must not be
+assumed that this won't vary between segments.  The second returns the number
+of folios added to a segments and the third is a shorthand to indicate if the
+segment has been filled to capacity.
+
+Not that the count and fullness are not affected by clearing folios from the
+segment.  These are more about indicating how many slots in the array have been
+initialised, and it assumed that slots won't get reused, but rather the segment
+will get discarded as the queue is consumed.
+
+
+Folio marks
+===========
+
+Folios within a queue can also have marks assigned to them.  These marks can be
+used to note information such as if a folio needs folio_put() calling upon it.
+There are three marks available to be set for each folio.
+
+The marks can be set by::
+
+       void folioq_mark(struct folio_queue *folioq, unsigned int slot);
+       void folioq_mark2(struct folio_queue *folioq, unsigned int slot);
+       void folioq_mark3(struct folio_queue *folioq, unsigned int slot);
+
+Cleared by::
+
+       void folioq_unmark(struct folio_queue *folioq, unsigned int slot);
+       void folioq_unmark2(struct folio_queue *folioq, unsigned int slot);
+       void folioq_unmark3(struct folio_queue *folioq, unsigned int slot);
+
+And the marks can be queried by::
+
+       bool folioq_is_marked(const struct folio_queue *folioq, unsigned int slot);
+       bool folioq_is_marked2(const struct folio_queue *folioq, unsigned int slot);
+       bool folioq_is_marked3(const struct folio_queue *folioq, unsigned int slot);
+
+The marks can be used for any purpose and are not interpreted by this API.
+
+
+Folio queue iteration
+=====================
+
+A list of segments may be iterated over using the I/O iterator facility using
+an ``iov_iter`` iterator of ``ITER_FOLIOQ`` type.  The iterator may be
+initialised with::
+
+       void iov_iter_folio_queue(struct iov_iter *i, unsigned int direction,
+                                 const struct folio_queue *folioq,
+                                 unsigned int first_slot, unsigned int offset,
+                                 size_t count);
+
+This may be told to start at a particular segment, slot and offset within a
+queue.  The iov iterator functions will follow the next pointers when advancing
+and prev pointers when reverting when needed.
+
+
+Lockless simultaneous production/consumption issues
+===================================================
+
+If properly managed, the list can be extended by the producer at the head end
+and shortened by the consumer at the tail end simultaneously without the need
+to take locks.  The ITER_FOLIOQ iterator inserts appropriate barriers to aid
+with this.
+
+Care must be taken when simultaneously producing and consuming a list.  If the
+last segment is reached and the folios it refers to are entirely consumed by
+the IOV iterators, an iov_iter struct will be left pointing to the last segment
+with a slot number equal to the capacity of that segment.  The iterator will
+try to continue on from this if there's another segment available when it is
+used again, but care must be taken lest the segment got removed and freed by
+the consumer before the iterator was advanced.
+
+It is recommended that the queue always contain at least one segment, even if
+that segment has never been filled or is entirely spent.  This prevents the
+head and tail pointers from collapsing.
+
+
+API Function Reference
+======================
+
+.. kernel-doc:: include/linux/folio_queue.h
index a331d2c814f57d65313ef42897c21204b995e816..6a875743dd4b7f1d0198c7b2bb0e7365ed3d3eaa 100644 (file)
@@ -37,6 +37,7 @@ Library functionality that is used throughout the kernel.
    kref
    cleanup
    assoc_array
+   folio_queue
    xarray
    maple_tree
    idr
index bf28ac0401f38a0c7bd5cec975c1bf5c76af34a0..7eb7c6023e0969f7598081fe1432a0a565473950 100644 (file)
@@ -12,7 +12,10 @@ Pkeys Userspace (PKU) is a feature which can be found on:
         * Intel server CPUs, Skylake and later
         * Intel client CPUs, Tiger Lake (11th Gen Core) and later
         * Future AMD CPUs
+        * arm64 CPUs implementing the Permission Overlay Extension (FEAT_S1POE)
 
+x86_64
+======
 Pkeys work by dedicating 4 previously Reserved bits in each page table entry to
 a "protection key", giving 16 possible keys.
 
@@ -28,6 +31,22 @@ register.  The feature is only available in 64-bit mode, even though there is
 theoretically space in the PAE PTEs.  These permissions are enforced on data
 access only and have no effect on instruction fetches.
 
+arm64
+=====
+
+Pkeys use 3 bits in each page table entry, to encode a "protection key index",
+giving 8 possible keys.
+
+Protections for each key are defined with a per-CPU user-writable system
+register (POR_EL0).  This is a 64-bit register encoding read, write and execute
+overlay permissions for each protection key index.
+
+Being a CPU register, POR_EL0 is inherently thread-local, potentially giving
+each thread a different set of protections from every other thread.
+
+Unlike x86_64, the protection key permissions also apply to instruction
+fetches.
+
 Syscalls
 ========
 
@@ -38,11 +57,10 @@ There are 3 system calls which directly interact with pkeys::
        int pkey_mprotect(unsigned long start, size_t len,
                          unsigned long prot, int pkey);
 
-Before a pkey can be used, it must first be allocated with
-pkey_alloc().  An application calls the WRPKRU instruction
-directly in order to change access permissions to memory covered
-with a key.  In this example WRPKRU is wrapped by a C function
-called pkey_set().
+Before a pkey can be used, it must first be allocated with pkey_alloc().  An
+application writes to the architecture specific CPU register directly in order
+to change access permissions to memory covered with a key.  In this example
+this is wrapped by a C function called pkey_set().
 ::
 
        int real_prot = PROT_READ|PROT_WRITE;
@@ -64,9 +82,9 @@ is no longer in use::
        munmap(ptr, PAGE_SIZE);
        pkey_free(pkey);
 
-.. note:: pkey_set() is a wrapper for the RDPKRU and WRPKRU instructions.
-          An example implementation can be found in
-          tools/testing/selftests/x86/protection_keys.c.
+.. note:: pkey_set() is a wrapper around writing to the CPU register.
+          Example implementations can be found in
+          tools/testing/selftests/mm/pkey-{arm64,powerpc,x86}.h
 
 Behavior
 ========
@@ -96,3 +114,7 @@ with a read()::
 The kernel will send a SIGSEGV in both cases, but si_code will be set
 to SEGV_PKERR when violating protection keys versus SEGV_ACCERR when
 the plain mprotect() permissions are violated.
+
+Note that kernel accesses from a kthread (such as io_uring) will use a default
+value for the protection key register and so will not be consistent with
+userspace's value of the register or mprotect().
index 1ee82419d8aa66929a5a52fac89a62c7f54d0644..5ceeb80eb539cf3aedf617bf75d85c4dc2af87b9 100644 (file)
@@ -203,7 +203,7 @@ Avoiding unaligned accesses
 ===========================
 
 The easiest way to avoid unaligned access is to use the get_unaligned() and
-put_unaligned() macros provided by the <asm/unaligned.h> header file.
+put_unaligned() macros provided by the <linux/unaligned.h> header file.
 
 Going back to an earlier example of code that potentially causes unaligned
 access::
diff --git a/Documentation/devicetree/bindings/display/elgin,jg10309-01.yaml b/Documentation/devicetree/bindings/display/elgin,jg10309-01.yaml
new file mode 100644 (file)
index 0000000..faca0cb
--- /dev/null
@@ -0,0 +1,54 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/elgin,jg10309-01.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Elgin JG10309-01 SPI-controlled display
+
+maintainers:
+  - Fabio Estevam <[email protected]>
+
+description: |
+  The Elgin JG10309-01 SPI-controlled display is used on the RV1108-Elgin-r1
+  board and is a custom display.
+
+allOf:
+  - $ref: /schemas/spi/spi-peripheral-props.yaml#
+
+properties:
+  compatible:
+    const: elgin,jg10309-01
+
+  reg:
+    maxItems: 1
+
+  spi-max-frequency:
+    maximum: 24000000
+
+  spi-cpha: true
+
+  spi-cpol: true
+
+required:
+  - compatible
+  - reg
+  - spi-cpha
+  - spi-cpol
+
+additionalProperties: false
+
+examples:
+  - |
+    spi {
+        #address-cells = <1>;
+        #size-cells = <0>;
+
+        display@0 {
+            compatible = "elgin,jg10309-01";
+            reg = <0>;
+            spi-max-frequency = <24000000>;
+            spi-cpha;
+            spi-cpol;
+        };
+    };
index 3a82aec9021c7c5aec74c2f961817cc7b2a24a80..497c0eb4ed0b5e2f57f60859f56a1a42fed4f40d 100644 (file)
@@ -63,6 +63,16 @@ properties:
       - const: sleep
 
   power-domains:
+    description: |
+      The MediaTek DPI module is typically associated with one of the
+      following multimedia power domains:
+        POWER_DOMAIN_DISPLAY
+        POWER_DOMAIN_VDOSYS
+        POWER_DOMAIN_MM
+      The specific power domain used varies depending on the SoC design.
+
+      It is recommended to explicitly add the appropriate power domain
+      property to the DPI node in the device tree.
     maxItems: 1
 
   port:
@@ -79,20 +89,6 @@ required:
   - clock-names
   - port
 
-allOf:
-  - if:
-      not:
-        properties:
-          compatible:
-            contains:
-              enum:
-                - mediatek,mt6795-dpi
-                - mediatek,mt8173-dpi
-                - mediatek,mt8186-dpi
-    then:
-      properties:
-        power-domains: false
-
 additionalProperties: false
 
 examples:
index e4affc854f3dd264f8e76e568ac00630fff5a8e2..4b6ff546757e62352e9415f0b8a6b178fbbf6dce 100644 (file)
@@ -38,6 +38,7 @@ properties:
     description: A phandle and PM domain specifier as defined by bindings of
       the power controller specified by phandle. See
       Documentation/devicetree/bindings/power/power-domain.yaml for details.
+    maxItems: 1
 
   mediatek,gce-client-reg:
     description:
@@ -57,6 +58,9 @@ properties:
   clocks:
     items:
       - description: SPLIT Clock
+      - description: Used for interfacing with the HDMI RX signal source.
+      - description: Paired with receiving HDMI RX metadata.
+    minItems: 1
 
 required:
   - compatible
@@ -72,9 +76,24 @@ allOf:
             const: mediatek,mt8195-mdp3-split
 
     then:
+      properties:
+        clocks:
+          minItems: 3
+
       required:
         - mediatek,gce-client-reg
 
+  - if:
+      properties:
+        compatible:
+          contains:
+            const: mediatek,mt8173-disp-split
+
+    then:
+      properties:
+        clocks:
+          maxItems: 1
+
 additionalProperties: false
 
 examples:
index bd19abb867d98d46bdd1c9e0c197e10f06979204..0065d650882489e21b952bb9fb25f1e3a070ee68 100644 (file)
@@ -67,6 +67,10 @@ properties:
       A 2.5V to 3.3V supply for the external reference voltage. When omitted,
       the internal 2.5V reference is used.
 
+  refin-supply:
+    description:
+      A 2.5V to 3.3V supply for external reference voltage, for ad7380-4 only.
+
   aina-supply:
     description:
       The common mode voltage supply for the AINA- pin on pseudo-differential
@@ -135,6 +139,23 @@ allOf:
         ainc-supply: false
         aind-supply: false
 
+  # ad7380-4 uses refin-supply as external reference.
+  # All other chips from ad738x family use refio as optional external reference.
+  # When refio-supply is omitted, internal reference is used.
+  - if:
+      properties:
+        compatible:
+          enum:
+            - adi,ad7380-4
+    then:
+      properties:
+        refio-supply: false
+      required:
+        - refin-supply
+    else:
+      properties:
+        refin-supply: false
+
 examples:
   - |
     #include <dt-bindings/interrupt-controller/irq.h>
index b4400c52bec3a1803430ac6d5fd520a890fda34e..713f535bb33aea14f916112a4a831dbf5ddba6ea 100644 (file)
@@ -4,7 +4,7 @@
 $id: http://devicetree.org/schemas/iio/dac/adi,ad5686.yaml#
 $schema: http://devicetree.org/meta-schemas/core.yaml#
 
-title: Analog Devices AD5360 and similar DACs
+title: Analog Devices AD5360 and similar SPI DACs
 
 maintainers:
   - Michael Hennerich <[email protected]>
@@ -12,41 +12,22 @@ maintainers:
 
 properties:
   compatible:
-    oneOf:
-      - description: SPI devices
-        enum:
-          - adi,ad5310r
-          - adi,ad5672r
-          - adi,ad5674r
-          - adi,ad5676
-          - adi,ad5676r
-          - adi,ad5679r
-          - adi,ad5681r
-          - adi,ad5682r
-          - adi,ad5683
-          - adi,ad5683r
-          - adi,ad5684
-          - adi,ad5684r
-          - adi,ad5685r
-          - adi,ad5686
-          - adi,ad5686r
-      - description: I2C devices
-        enum:
-          - adi,ad5311r
-          - adi,ad5337r
-          - adi,ad5338r
-          - adi,ad5671r
-          - adi,ad5675r
-          - adi,ad5691r
-          - adi,ad5692r
-          - adi,ad5693
-          - adi,ad5693r
-          - adi,ad5694
-          - adi,ad5694r
-          - adi,ad5695r
-          - adi,ad5696
-          - adi,ad5696r
-
+    enum:
+      - adi,ad5310r
+      - adi,ad5672r
+      - adi,ad5674r
+      - adi,ad5676
+      - adi,ad5676r
+      - adi,ad5679r
+      - adi,ad5681r
+      - adi,ad5682r
+      - adi,ad5683
+      - adi,ad5683r
+      - adi,ad5684
+      - adi,ad5684r
+      - adi,ad5685r
+      - adi,ad5686
+      - adi,ad5686r
 
   reg:
     maxItems: 1
index 56b0cda0f30ab88cdec6064d9c31ab6c3bb6e5db..b5a88b03dc2f0befc5e602b28e8eca305323b54b 100644 (file)
@@ -4,7 +4,7 @@
 $id: http://devicetree.org/schemas/iio/dac/adi,ad5696.yaml#
 $schema: http://devicetree.org/meta-schemas/core.yaml#
 
-title: Analog Devices AD5696 and similar multi-channel DACs
+title: Analog Devices AD5696 and similar I2C multi-channel DACs
 
 maintainers:
   - Michael Auchter <[email protected]>
@@ -16,6 +16,7 @@ properties:
   compatible:
     enum:
       - adi,ad5311r
+      - adi,ad5337r
       - adi,ad5338r
       - adi,ad5671r
       - adi,ad5675r
index 199b34fdbefc4398a937f9b9b58f2108f222f96b..7ff4efc4758ab71cc413adfe4e3d2dd3cc2f1bce 100644 (file)
@@ -82,9 +82,6 @@ allOf:
             enum:
               - fsl,ls1043a-extirq
               - fsl,ls1046a-extirq
-              - fsl,ls1088a-extirq
-              - fsl,ls2080a-extirq
-              - fsl,lx2160a-extirq
     then:
       properties:
         interrupt-map:
@@ -95,6 +92,29 @@ allOf:
             - const: 0xf
             - const: 0
 
+  - if:
+      properties:
+        compatible:
+          contains:
+            enum:
+              - fsl,ls1088a-extirq
+              - fsl,ls2080a-extirq
+              - fsl,lx2160a-extirq
+# The driver(drivers/irqchip/irq-ls-extirq.c) have not use standard DT
+# function to parser interrupt-map. So it doesn't consider '#address-size'
+# in parent interrupt controller, such as GIC.
+#
+# When dt-binding verify interrupt-map, item data matrix is spitted at
+# incorrect position. Remove interrupt-map restriction because it always
+# wrong.
+
+    then:
+      properties:
+        interrupt-map-mask:
+          items:
+            - const: 0xf
+            - const: 0
+
 additionalProperties: false
 
 examples:
index 01b00d89a992100ab22845668fcaa697d864d39e..df45ff56d4445559700b636c6ec74fb470f38079 100644 (file)
@@ -113,7 +113,7 @@ properties:
 
   msi-parent:
     deprecated: true
-    $ref: /schemas/types.yaml#/definitions/phandle
+    maxItems: 1
     description:
       Describes the MSI controller node handling message
       interrupts for the MC. When there is no translation
index 23dfe0838dca487e4fa1a983aa7b95ef4e39ede6..63bee5b542f50135479bf42891fc97408d1543ee 100644 (file)
@@ -26,6 +26,7 @@ properties:
       - brcm,asp-v2.1-mdio
       - brcm,asp-v2.2-mdio
       - brcm,unimac-mdio
+      - brcm,bcm6846-mdio
 
   reg:
     minItems: 1
index bbe89ea9590ceb53df4a0f589787c9990aec0219..e95c216282818e66e6b26bf763954b061a2d5e93 100644 (file)
@@ -34,6 +34,7 @@ properties:
       and length of the AXI DMA controller IO space, unless
       axistream-connected is specified, in which case the reg
       attribute of the node referenced by it is used.
+    minItems: 1
     maxItems: 2
 
   interrupts:
@@ -181,7 +182,7 @@ examples:
         clock-names = "s_axi_lite_clk", "axis_clk", "ref_clk", "mgt_clk";
         clocks = <&axi_clk>, <&axi_clk>, <&pl_enet_ref_clk>, <&mgt_clk>;
         phy-mode = "mii";
-        reg = <0x00 0x40000000 0x00 0x40000>;
+        reg = <0x40000000 0x40000>;
         xlnx,rxcsum = <0x2>;
         xlnx,rxmem = <0x800>;
         xlnx,txcsum = <0x2>;
index 7735e08d35ba147e3a4a815ada8d31081c6338e8..beef193aaaeba0afd4eeeab38d5a2ff03c83da4f 100644 (file)
@@ -102,21 +102,21 @@ properties:
     default: 2
 
   interrupts:
-    anyOf:
-      - minItems: 1
-        items:
-          - description: TX interrupt
-          - description: RX interrupt
-      - items:
-          - description: common/combined interrupt
+    minItems: 1
+    maxItems: 2
 
   interrupt-names:
     oneOf:
-      - minItems: 1
+      - description: TX interrupt
+        const: tx
+      - description: RX interrupt
+        const: rx
+      - description: TX and RX interrupts
         items:
           - const: tx
           - const: rx
-      - const: common
+      - description: Common/combined interrupt
+        const: common
 
   fck_parent:
     $ref: /schemas/types.yaml#/definitions/string
index 1d3acdc0c7339b54b68040de2a7e53503555a574..2e2e01493a5f4f5048aaa894a95ebfc7fd033e4f 100644 (file)
@@ -30,6 +30,7 @@ properties:
           - qcom,apq8096-sndcard
           - qcom,qcm6490-idp-sndcard
           - qcom,qcs6490-rb3gen2-sndcard
+          - qcom,qrb4210-rb2-sndcard
           - qcom,qrb5165-rb5-sndcard
           - qcom,sc7180-qdsp6-sndcard
           - qcom,sc8280xp-sndcard
index 3bc93c59535e9abeb48584917b13ab83d2ae7854..6d0d1514cd4211b90aa4ead776694fcea63562f1 100644 (file)
@@ -302,7 +302,7 @@ allOf:
         reg-names:
           items:
             enum:
-              - scu
+              - sru
               - ssi
               - adg
   # for Gen2/Gen3
index ecf3d7d968c80ba9821a90dcc93ecd218d9d9e39..2cf229a076f0f5169ca8148f73048cceca55042b 100644 (file)
@@ -48,6 +48,10 @@ properties:
       - const: mclk_rx
       - const: hclk
 
+  port:
+    $ref: audio-graph-port.yaml#
+    unevaluatedProperties: false
+
   resets:
     maxItems: 1
 
index 0108d750721519e6607094489d8017eaeab3c360..9bf0fb17a05e56c2b9351b4b46886c6982f328e7 100644 (file)
@@ -101,8 +101,6 @@ properties:
           - domintech,dmard09
             # DMARD10: 3-axis Accelerometer
           - domintech,dmard10
-            # Elgin SPI-controlled LCD
-          - elgin,jg10309-01
             # MMA7660FC: 3-Axis Orientation/Motion Detection Sensor
           - fsl,mma7660
             # MMA8450Q: Xtrinsic Low-power, 3-axis Xtrinsic Accelerometer
index 6ca58c8249e5482550c234784aa09463b708d546..4e8dbdb1fc6780090f6bd428ce02fcbfed4fde84 100644 (file)
@@ -7,12 +7,11 @@ WMI Driver API
 The WMI driver core supports a more modern bus-based interface for interacting
 with WMI devices, and an older GUID-based interface. The latter interface is
 considered to be deprecated, so new WMI drivers should generally avoid it since
-it has some issues with multiple WMI devices and events sharing the same GUIDs
-and/or notification IDs. The modern bus-based interface instead maps each
-WMI device to a :c:type:`struct wmi_device <wmi_device>`, so it supports
-WMI devices sharing GUIDs and/or notification IDs. Drivers can then register
-a :c:type:`struct wmi_driver <wmi_driver>`, which will be bound to compatible
-WMI devices by the driver core.
+it has some issues with multiple WMI devices sharing the same GUID.
+The modern bus-based interface instead maps each WMI device to a
+:c:type:`struct wmi_device <wmi_device>`, so it supports WMI devices sharing the
+same GUID. Drivers can then register a :c:type:`struct wmi_driver <wmi_driver>`
+which will be bound to compatible WMI devices by the driver core.
 
 .. kernel-doc:: include/linux/wmi.h
    :internal:
index e04a27bdbe19ce2b3dd474e069031cede57ba13f..b3ccc782cb3b2b1b91e13be08f10d41f8fd44a69 100644 (file)
@@ -115,7 +115,7 @@ set up cache ready for use.  The following script commands are available:
 
        This mask can also be set through sysfs, eg::
 
-               echo 5 >/sys/modules/cachefiles/parameters/debug
+               echo 5 > /sys/module/cachefiles/parameters/debug
 
 
 Starting the Cache
index 8e6c721d233010ea47fac5c647fb93dbbda2236d..b93115ab8748ae45ef4d40ec955232bcb9171c8b 100644 (file)
@@ -208,7 +208,7 @@ The filesystem must arrange to `cancel
 such `reservations
 <https://lore.kernel.org/linux-xfs/[email protected]/>`_
 because writeback will not consume the reservation.
-The ``iomap_file_buffered_write_punch_delalloc`` can be called from a
+The ``iomap_write_delalloc_release`` can be called from a
 ``->iomap_end`` function to find all the clean areas of the folios
 caching a fresh (``IOMAP_F_NEW``) delalloc mapping.
 It takes the ``invalidate_lock``.
index f0d2cb257bb8d98d42d63cb8c59e634f6b0bc3ab..73f0bfd7e903af92aa6450b5d912cb263ee04bfb 100644 (file)
@@ -592,4 +592,3 @@ API Function Reference
 
 .. kernel-doc:: include/linux/netfs.h
 .. kernel-doc:: fs/netfs/buffered_read.c
-.. kernel-doc:: fs/netfs/io.c
index 8435e8621cc0872b5b8e29d89f156ee28106308f..c3e58856f75b36d22c5d777fbc486b488f56bc06 100644 (file)
@@ -181,7 +181,7 @@ Bridge Operations
 Bridge Connector Helper
 -----------------------
 
-.. kernel-doc:: drivers/gpu/drm/drm_bridge_connector.c
+.. kernel-doc:: drivers/gpu/drm/display/drm_bridge_connector.c
    :doc: overview
 
 
@@ -204,7 +204,7 @@ MIPI-DSI bridge operation
 Bridge Connector Helper Reference
 ---------------------------------
 
-.. kernel-doc:: drivers/gpu/drm/drm_bridge_connector.c
+.. kernel-doc:: drivers/gpu/drm/display/drm_bridge_connector.c
    :export:
 
 Panel-Bridge Helper Reference
index 9c784c1e652e9afc116fd206a6cdb70fa6e2adf0..6f70b49b9ef27c1ac32acaefecd1146e5c8bd6cc 100644 (file)
@@ -41,13 +41,22 @@ supports only 1 SDO line.
 Reference voltage
 -----------------
 
-2 possible reference voltage sources are supported:
+ad7380-4
+~~~~~~~~
+
+ad7380-4 supports only an external reference voltage (2.5V to 3.3V). It must be
+declared in the device tree as ``refin-supply``.
+
+All other devices from ad738x family
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+All other devices from ad738x support 2 possible reference voltage sources:
 
 - Internal reference (2.5V)
 - External reference (2.5V to 3.3V)
 
 The source is determined by the device tree. If ``refio-supply`` is present,
-then the external reference is used, else the internal reference is used.
+then it is used as external reference, else the internal reference is used.
 
 Oversampling and resolution boost
 ---------------------------------
index 2365c9a3c1f08f2ee200703372b65aaf55e8e734..ce3e9845833905c8dbfd26b9f3f31f42ddb6c7b5 100644 (file)
@@ -7,26 +7,26 @@ The DAMON subsystem covers the files that are listed in 'DATA ACCESS MONITOR'
 section of 'MAINTAINERS' file.
 
 The mailing lists for the subsystem are [email protected] and
[email protected].  Patches should be made against the mm-unstable `tree
-<https://git.kernel.org/akpm/mm/h/mm-unstable>` whenever possible and posted to
-the mailing lists.
[email protected].  Patches should be made against the `mm-unstable tree
+<https://git.kernel.org/akpm/mm/h/mm-unstable>`_ whenever possible and posted
+to the mailing lists.
 
 SCM Trees
 ---------
 
 There are multiple Linux trees for DAMON development.  Patches under
 development or testing are queued in `damon/next
-<https://git.kernel.org/sj/h/damon/next>` by the DAMON maintainer.
+<https://git.kernel.org/sj/h/damon/next>`_ by the DAMON maintainer.
 Sufficiently reviewed patches will be queued in `mm-unstable
-<https://git.kernel.org/akpm/mm/h/mm-unstable>` by the memory management
+<https://git.kernel.org/akpm/mm/h/mm-unstable>`_ by the memory management
 subsystem maintainer.  After more sufficient tests, the patches will be queued
-in `mm-stable <https://git.kernel.org/akpm/mm/h/mm-stable>` , and finally
+in `mm-stable <https://git.kernel.org/akpm/mm/h/mm-stable>`_, and finally
 pull-requested to the mainline by the memory management subsystem maintainer.
 
-Note again the patches for mm-unstable `tree
-<https://git.kernel.org/akpm/mm/h/mm-unstable>` are queued by the memory
+Note again the patches for `mm-unstable tree
+<https://git.kernel.org/akpm/mm/h/mm-unstable>`_ are queued by the memory
 management subsystem maintainer.  If the patches requires some patches in
-damon/next `tree <https://git.kernel.org/sj/h/damon/next>` which not yet merged
+`damon/next tree <https://git.kernel.org/sj/h/damon/next>`_ which not yet merged
 in mm-unstable, please make sure the requirement is clearly specified.
 
 Submit checklist addendum
@@ -37,25 +37,25 @@ When making DAMON changes, you should do below.
 - Build changes related outputs including kernel and documents.
 - Ensure the builds introduce no new errors or warnings.
 - Run and ensure no new failures for DAMON `selftests
-  <https://github.com/awslabs/damon-tests/blob/master/corr/run.sh#L49>` and
+  <https://github.com/damonitor/damon-tests/blob/master/corr/run.sh#L49>`_ and
   `kunittests
-  <https://github.com/awslabs/damon-tests/blob/master/corr/tests/kunit.sh>`.
+  <https://github.com/damonitor/damon-tests/blob/master/corr/tests/kunit.sh>`_.
 
 Further doing below and putting the results will be helpful.
 
 - Run `damon-tests/corr
-  <https://github.com/awslabs/damon-tests/tree/master/corr>` for normal
+  <https://github.com/damonitor/damon-tests/tree/master/corr>`_ for normal
   changes.
 - Run `damon-tests/perf
-  <https://github.com/awslabs/damon-tests/tree/master/perf>` for performance
+  <https://github.com/damonitor/damon-tests/tree/master/perf>`_ for performance
   changes.
 
 Key cycle dates
 ---------------
 
 Patches can be sent anytime.  Key cycle dates of the `mm-unstable
-<https://git.kernel.org/akpm/mm/h/mm-unstable>` and `mm-stable
-<https://git.kernel.org/akpm/mm/h/mm-stable>` trees depend on the memory
+<https://git.kernel.org/akpm/mm/h/mm-unstable>`_ and `mm-stable
+<https://git.kernel.org/akpm/mm/h/mm-stable>`_ trees depend on the memory
 management subsystem maintainer.
 
 Review cadence
@@ -72,13 +72,13 @@ Mailing tool
 Like many other Linux kernel subsystems, DAMON uses the mailing lists
 ([email protected] and [email protected]) as the major communication
 channel.  There is a simple tool called `HacKerMaiL
-<https://github.com/damonitor/hackermail>` (``hkml``), which is for people who
+<https://github.com/damonitor/hackermail>`_ (``hkml``), which is for people who
 are not very familiar with the mailing lists based communication.  The tool
 could be particularly helpful for DAMON community members since it is developed
 and maintained by DAMON maintainer.  The tool is also officially announced to
 support DAMON and general Linux kernel development workflow.
 
-In other words, `hkml <https://github.com/damonitor/hackermail>` is a mailing
+In other words, `hkml <https://github.com/damonitor/hackermail>`_ is a mailing
 tool for DAMON community, which DAMON maintainer is committed to support.
 Please feel free to try and report issues or feature requests for the tool to
 the maintainer.
@@ -98,8 +98,8 @@ slots, and attendees should reserve one of those at least 24 hours before the
 time slot, by reaching out to the maintainer.
 
 Schedules and available reservation time slots are available at the Google `doc
-<https://docs.google.com/document/d/1v43Kcj3ly4CYqmAkMaZzLiM2GEnWfgdGbZAH3mi2vpM/edit?usp=sharing>`.
+<https://docs.google.com/document/d/1v43Kcj3ly4CYqmAkMaZzLiM2GEnWfgdGbZAH3mi2vpM/edit?usp=sharing>`_.
 There is also a public Google `calendar
-<https://calendar.google.com/calendar/u/0?cid=ZDIwOTA4YTMxNjc2MDQ3NTIyMmUzYTM5ZmQyM2U4NDA0ZGIwZjBiYmJlZGQxNDM0MmY4ZTRjOTE0NjdhZDRiY0Bncm91cC5jYWxlbmRhci5nb29nbGUuY29t>`
+<https://calendar.google.com/calendar/u/0?cid=ZDIwOTA4YTMxNjc2MDQ3NTIyMmUzYTM5ZmQyM2U4NDA0ZGIwZjBiYmJlZGQxNDM0MmY4ZTRjOTE0NjdhZDRiY0Bncm91cC5jYWxlbmRhci5nb29nbGUuY29t>`_
 that has the events.  Anyone can subscribe it.  DAMON maintainer will also
 provide periodic reminder to the mailing list ([email protected]).
index 7bf7b95c4f7af346c7291ac2ea43f29e2626142a..dfa5d549be9c03f863669f6396bf28fb6424a9a0 100644 (file)
@@ -144,9 +144,8 @@ IRQ should only be unmasked after a successful call to napi_complete_done():
 
 napi_schedule_irqoff() is a variant of napi_schedule() which takes advantage
 of guarantees given by being invoked in IRQ context (no need to
-mask interrupts). Note that PREEMPT_RT forces all interrupts
-to be threaded so the interrupt may need to be marked ``IRQF_NO_THREAD``
-to avoid issues on real-time kernel configurations.
+mask interrupts). napi_schedule_irqoff() will fall back to napi_schedule() if
+IRQs are threaded (such as if ``PREEMPT_RT`` is enabled).
 
 Instance to queue mapping
 -------------------------
index dca15d15feaf99ce44d2a73d857928c3eac56da0..02370786e77bc1219f75478cee07264ea12627b5 100644 (file)
@@ -16,7 +16,7 @@ ii) transmit network traffic, or any other that needs raw
 
 Howto can be found at:
 
-    https://sites.google.com/site/packetmmap/
+    https://web.archive.org/web/20220404160947/https://sites.google.com/site/packetmmap/
 
 Please send your comments to
     - Ulisses Alonso Camaró <[email protected]>
@@ -166,7 +166,8 @@ As capture, each frame contains two parts::
     /* bind socket to eth0 */
     bind(this->socket, (struct sockaddr *)&my_addr, sizeof(struct sockaddr_ll));
 
- A complete tutorial is available at: https://sites.google.com/site/packetmmap/
+ A complete tutorial is available at:
+ https://web.archive.org/web/20220404160947/https://sites.google.com/site/packetmmap/
 
 By default, the user should put data at::
 
index e96e62d1dab3048b0feccddea076a11c7c2d88c6..d5b6d0df63c351fe70993834756e055e85b20537 100644 (file)
@@ -9,7 +9,7 @@ segments between trusted peers. It adds a new TCP header option with
 a Message Authentication Code (MAC). MACs are produced from the content
 of a TCP segment using a hashing function with a password known to both peers.
 The intent of TCP-AO is to deprecate TCP-MD5 providing better security,
-key rotation and support for variety of hashing algorithms.
+key rotation and support for variety of hashing algorithms.
 
 1. Introduction
 ===============
@@ -164,9 +164,9 @@ A: It should not, no action needs to be performed [7.5.2.e]::
        is not available, no action is required (RNextKeyID of a received
        segment needs to match the MKT’s SendID).
 
-Q: How current_key is set and when does it change? It is a user-triggered
-change, or is it by a request from the remote peer? Is it set by the user
-explicitly, or by a matching rule?
+Q: How is current_key set, and when does it change? Is it a user-triggered
+change, or is it triggered by a request from the remote peer? Is it set by the
+user explicitly, or by a matching rule?
 
 A: current_key is set by RNextKeyID [6.1]::
 
@@ -233,8 +233,8 @@ always have one current_key [3.3]::
 
 Q: Can a non-TCP-AO connection become a TCP-AO-enabled one?
 
-A: No: for already established non-TCP-AO connection it would be impossible
-to switch using TCP-AO as the traffic key generation requires the initial
+A: No: for an already established non-TCP-AO connection it would be impossible
+to switch to using TCP-AO, as the traffic key generation requires the initial
 sequence numbers. Paraphrasing, starting using TCP-AO would require
 re-establishing the TCP connection.
 
@@ -292,7 +292,7 @@ no transparency is really needed and modern BGP daemons already have
 
 Linux provides a set of ``setsockopt()s`` and ``getsockopt()s`` that let
 userspace manage TCP-AO on a per-socket basis. In order to add/delete MKTs
-``TCP_AO_ADD_KEY`` and ``TCP_AO_DEL_KEY`` TCP socket options must be used
+``TCP_AO_ADD_KEY`` and ``TCP_AO_DEL_KEY`` TCP socket options must be used.
 It is not allowed to add a key on an established non-TCP-AO connection
 as well as to remove the last key from TCP-AO connection.
 
@@ -361,7 +361,7 @@ not implemented.
 4. ``setsockopt()`` vs ``accept()`` race
 ========================================
 
-In contrast with TCP-MD5 established connection which has just one key,
+In contrast with an established TCP-MD5 connection which has just one key,
 TCP-AO connections may have many keys, which means that accepted connections
 on a listen socket may have any amount of keys as well. As copying all those
 keys on a first properly signed SYN would make the request socket bigger, that
@@ -374,7 +374,7 @@ keys from sockets that were already established, but not yet ``accept()``'ed,
 hanging in the accept queue.
 
 The reverse is valid as well: if userspace adds a new key for a peer on
-a listener socket, the established sockets in accept queue won't
+a listener socket, the established sockets in the accept queue won't
 have the new keys.
 
 At this moment, the resolution for the two races:
@@ -382,7 +382,7 @@ At this moment, the resolution for the two races:
 and ``setsockopt(TCP_AO_DEL_KEY)`` vs ``accept()`` is delegated to userspace.
 This means that it's expected that userspace would check the MKTs on the socket
 that was returned by ``accept()`` to verify that any key rotation that
-happened on listen socket is reflected on the newly established connection.
+happened on the listen socket is reflected on the newly established connection.
 
 This is a similar "do-nothing" approach to TCP-MD5 from the kernel side and
 may be changed later by introducing new flags to ``tcp_ao_add``
index c9edf9e7362d675106d11f31df80bdea21cfe4f3..1ae71e31591cb46c59a876bec8c9379ee9e19c0f 100644 (file)
@@ -355,6 +355,8 @@ just do it. As a result, a sequence of smaller series gets merged quicker and
 with better review coverage. Re-posting large series also increases the mailing
 list traffic.
 
+.. _rcs:
+
 Local variable ordering ("reverse xmas tree", "RCS")
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
@@ -391,6 +393,21 @@ APIs and helpers, especially scoped iterators. However, direct use of
 ``__free()`` within networking core and drivers is discouraged.
 Similar guidance applies to declaring variables mid-function.
 
+Clean-up patches
+~~~~~~~~~~~~~~~~
+
+Netdev discourages patches which perform simple clean-ups, which are not in
+the context of other work. For example:
+
+* Addressing ``checkpatch.pl`` warnings
+* Addressing :ref:`Local variable ordering<rcs>` issues
+* Conversions to device-managed APIs (``devm_`` helpers)
+
+This is because it is felt that the churn that such changes produce comes
+at a greater cost than the value of such clean-ups.
+
+Conversely, spelling and grammar fixes are not discouraged.
+
 Resending after review
 ~~~~~~~~~~~~~~~~~~~~~~
 
index 12637530d68f3279cde869752cf2211f153eef1d..fe9d8bcfbd2b920583ee66327cfba4cf634b70b0 100644 (file)
@@ -30,10 +30,13 @@ tree as a dedicated branch covering multiple subsystems.
 The main SoC tree is housed on git.kernel.org:
   https://git.kernel.org/pub/scm/linux/kernel/git/soc/soc.git/
 
+Maintainers
+-----------
+
 Clearly this is quite a wide range of topics, which no one person, or even
 small group of people are capable of maintaining.  Instead, the SoC subsystem
-is comprised of many submaintainers, each taking care of individual platforms
-and driver subdirectories.
+is comprised of many submaintainers (platform maintainers), each taking care of
+individual platforms and driver subdirectories.
 In this regard, "platform" usually refers to a series of SoCs from a given
 vendor, for example, Nvidia's series of Tegra SoCs.  Many submaintainers operate
 on a vendor level, responsible for multiple product lines.  For several reasons,
@@ -43,14 +46,43 @@ MAINTAINERS file.
 
 Most of these submaintainers have their own trees where they stage patches,
 sending pull requests to the main SoC tree.  These trees are usually, but not
-always, listed in MAINTAINERS.  The main SoC maintainers can be reached via the
-alias [email protected] if there is no platform-specific maintainer, or if they
-are unresponsive.
+always, listed in MAINTAINERS.
 
 What the SoC tree is not, however, is a location for architecture-specific code
 changes.  Each architecture has its own maintainers that are responsible for
 architectural details, CPU errata and the like.
 
+Submitting Patches for Given SoC
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+All typical platform related patches should be sent via SoC submaintainers
+(platform-specific maintainers).  This includes also changes to per-platform or
+shared defconfigs (scripts/get_maintainer.pl might not provide correct
+addresses in such case).
+
+Submitting Patches to the Main SoC Maintainers
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The main SoC maintainers can be reached via the alias [email protected] only in
+following cases:
+
+1. There are no platform-specific maintainers.
+
+2. Platform-specific maintainers are unresponsive.
+
+3. Introducing a completely new SoC platform.  Such new SoC work should be sent
+   first to common mailing lists, pointed out by scripts/get_maintainer.pl, for
+   community review.  After positive community review, work should be sent to
+   [email protected] in one patchset containing new arch/foo/Kconfig entry, DTS
+   files, MAINTAINERS file entry and optionally initial drivers with their
+   Devicetree bindings.  The MAINTAINERS file entry should list new
+   platform-specific maintainers, who are going to be responsible for handling
+   patches for the platform from now on.
+
+Note that the [email protected] is usually not the place to discuss the patches,
+thus work sent to this address should be already considered as acceptable by
+the community.
+
 Information for (new) Submaintainers
 ------------------------------------
 
index 750ff371570a03b268e27d5fdb7dd09c40ef0539..54be7ddf3e57a732dbbca85541b137c62e834d7d 100644 (file)
@@ -17,7 +17,7 @@ Architecture   Level of support  Constraints
 =============  ================  ==============================================
 ``arm64``      Maintained        Little Endian only.
 ``loongarch``  Maintained        \-
-``riscv``      Maintained        ``riscv64`` only.
+``riscv``      Maintained        ``riscv64`` and LLVM/Clang only.
 ``um``         Maintained        \-
 ``x86``        Maintained        ``x86_64`` only.
 =============  ================  ==============================================
index 6c0d70e2e27df5af29dd82ff8d382ac6d0926246..7b59bbd2e56428322aec34192d7ca3ed824bb2c6 100644 (file)
@@ -66,7 +66,7 @@ BPF scheduler and reverts all tasks back to CFS.
 .. code-block:: none
 
     # make -j16 -C tools/sched_ext
-    # tools/sched_ext/scx_simple
+    # tools/sched_ext/build/bin/scx_simple
     local=0 global=3
     local=5 global=24
     local=9 global=44
index 29c33e7e0855968a757e5546dc591228c19c6068..fbe0989a8ce57fa0385587087faa484978fce025 100644 (file)
@@ -175,7 +175,7 @@ field2会导致非对齐访问,这并不是不合理的。你会期望field2
 避免非对齐访问
 ==============
 
-避免非对齐访问的最简单方法是使用<asm/unaligned.h>头文件提供的get_unaligned()和
+避免非对齐访问的最简单方法是使用<linux/unaligned.h>头文件提供的get_unaligned()和
 put_unaligned()宏。
 
 回到前面的一个可能导致非对齐访问的代码例子::
index 4132eec995a399acf53d70b013e2aaef32ff8e97..41102f74c5e208745f5d29b1d373c7a835fcbaac 100644 (file)
@@ -23,177 +23,166 @@ applications can additionally seal security critical data at runtime.
 A similar feature already exists in the XNU kernel with the
 VM_FLAGS_PERMANENT flag [1] and on OpenBSD with the mimmutable syscall [2].
 
-User API
-========
-mseal()
------------
-The mseal() syscall has the following signature:
-
-``int mseal(void addr, size_t len, unsigned long flags)``
-
-**addr/len**: virtual memory address range.
-
-The address range set by ``addr``/``len`` must meet:
-   - The start address must be in an allocated VMA.
-   - The start address must be page aligned.
-   - The end address (``addr`` + ``len``) must be in an allocated VMA.
-   - no gap (unallocated memory) between start and end address.
-
-The ``len`` will be paged aligned implicitly by the kernel.
-
-**flags**: reserved for future use.
-
-**return values**:
-
-- ``0``: Success.
-
-- ``-EINVAL``:
-    - Invalid input ``flags``.
-    - The start address (``addr``) is not page aligned.
-    - Address range (``addr`` + ``len``) overflow.
-
-- ``-ENOMEM``:
-    - The start address (``addr``) is not allocated.
-    - The end address (``addr`` + ``len``) is not allocated.
-    - A gap (unallocated memory) between start and end address.
-
-- ``-EPERM``:
-    - sealing is supported only on 64-bit CPUs, 32-bit is not supported.
-
-- For above error cases, users can expect the given memory range is
-  unmodified, i.e. no partial update.
-
-- There might be other internal errors/cases not listed here, e.g.
-  error during merging/splitting VMAs, or the process reaching the max
-  number of supported VMAs. In those cases, partial updates to the given
-  memory range could happen. However, those cases should be rare.
-
-**Blocked operations after sealing**:
-    Unmapping, moving to another location, and shrinking the size,
-    via munmap() and mremap(), can leave an empty space, therefore
-    can be replaced with a VMA with a new set of attributes.
-
-    Moving or expanding a different VMA into the current location,
-    via mremap().
-
-    Modifying a VMA via mmap(MAP_FIXED).
-
-    Size expansion, via mremap(), does not appear to pose any
-    specific risks to sealed VMAs. It is included anyway because
-    the use case is unclear. In any case, users can rely on
-    merging to expand a sealed VMA.
-
-    mprotect() and pkey_mprotect().
-
-    Some destructive madvice() behaviors (e.g. MADV_DONTNEED)
-    for anonymous memory, when users don't have write permission to the
-    memory. Those behaviors can alter region contents by discarding pages,
-    effectively a memset(0) for anonymous memory.
-
-    Kernel will return -EPERM for blocked operations.
-
-    For blocked operations, one can expect the given address is unmodified,
-    i.e. no partial update. Note, this is different from existing mm
-    system call behaviors, where partial updates are made till an error is
-    found and returned to userspace. To give an example:
-
-    Assume following code sequence:
-
-    - ptr = mmap(null, 8192, PROT_NONE);
-    - munmap(ptr + 4096, 4096);
-    - ret1 = mprotect(ptr, 8192, PROT_READ);
-    - mseal(ptr, 4096);
-    - ret2 = mprotect(ptr, 8192, PROT_NONE);
-
-    ret1 will be -ENOMEM, the page from ptr is updated to PROT_READ.
-
-    ret2 will be -EPERM, the page remains to be PROT_READ.
-
-**Note**:
-
-- mseal() only works on 64-bit CPUs, not 32-bit CPU.
-
-- users can call mseal() multiple times, mseal() on an already sealed memory
-  is a no-action (not error).
-
-- munseal() is not supported.
-
-Use cases:
-==========
+SYSCALL
+=======
+mseal syscall signature
+-----------------------
+   ``int mseal(void \* addr, size_t len, unsigned long flags)``
+
+   **addr**/**len**: virtual memory address range.
+      The address range set by **addr**/**len** must meet:
+         - The start address must be in an allocated VMA.
+         - The start address must be page aligned.
+         - The end address (**addr** + **len**) must be in an allocated VMA.
+         - no gap (unallocated memory) between start and end address.
+
+      The ``len`` will be paged aligned implicitly by the kernel.
+
+   **flags**: reserved for future use.
+
+   **Return values**:
+      - **0**: Success.
+      - **-EINVAL**:
+         * Invalid input ``flags``.
+         * The start address (``addr``) is not page aligned.
+         * Address range (``addr`` + ``len``) overflow.
+      - **-ENOMEM**:
+         * The start address (``addr``) is not allocated.
+         * The end address (``addr`` + ``len``) is not allocated.
+         * A gap (unallocated memory) between start and end address.
+      - **-EPERM**:
+         * sealing is supported only on 64-bit CPUs, 32-bit is not supported.
+
+   **Note about error return**:
+      - For above error cases, users can expect the given memory range is
+        unmodified, i.e. no partial update.
+      - There might be other internal errors/cases not listed here, e.g.
+        error during merging/splitting VMAs, or the process reaching the maximum
+        number of supported VMAs. In those cases, partial updates to the given
+        memory range could happen. However, those cases should be rare.
+
+   **Architecture support**:
+      mseal only works on 64-bit CPUs, not 32-bit CPUs.
+
+   **Idempotent**:
+      users can call mseal multiple times. mseal on an already sealed memory
+      is a no-action (not error).
+
+   **no munseal**
+      Once mapping is sealed, it can't be unsealed. The kernel should never
+      have munseal, this is consistent with other sealing feature, e.g.
+      F_SEAL_SEAL for file.
+
+Blocked mm syscall for sealed mapping
+-------------------------------------
+   It might be important to note: **once the mapping is sealed, it will
+   stay in the process's memory until the process terminates**.
+
+   Example::
+
+         *ptr = mmap(0, 4096, PROT_READ, MAP_ANONYMOUS | MAP_PRIVATE, 0, 0);
+         rc = mseal(ptr, 4096, 0);
+         /* munmap will fail */
+         rc = munmap(ptr, 4096);
+         assert(rc < 0);
+
+   Blocked mm syscall:
+      - munmap
+      - mmap
+      - mremap
+      - mprotect and pkey_mprotect
+      - some destructive madvise behaviors: MADV_DONTNEED, MADV_FREE,
+        MADV_DONTNEED_LOCKED, MADV_FREE, MADV_DONTFORK, MADV_WIPEONFORK
+
+   The first set of syscalls to block is munmap, mremap, mmap. They can
+   either leave an empty space in the address space, therefore allowing
+   replacement with a new mapping with new set of attributes, or can
+   overwrite the existing mapping with another mapping.
+
+   mprotect and pkey_mprotect are blocked because they changes the
+   protection bits (RWX) of the mapping.
+
+   Certain destructive madvise behaviors, specifically MADV_DONTNEED,
+   MADV_FREE, MADV_DONTNEED_LOCKED, and MADV_WIPEONFORK, can introduce
+   risks when applied to anonymous memory by threads lacking write
+   permissions. Consequently, these operations are prohibited under such
+   conditions. The aforementioned behaviors have the potential to modify
+   region contents by discarding pages, effectively performing a memset(0)
+   operation on the anonymous memory.
+
+   Kernel will return -EPERM for blocked syscalls.
+
+   When blocked syscall return -EPERM due to sealing, the memory regions may
+   or may not be changed, depends on the syscall being blocked:
+
+      - munmap: munmap is atomic. If one of VMAs in the given range is
+        sealed, none of VMAs are updated.
+      - mprotect, pkey_mprotect, madvise: partial update might happen, e.g.
+        when mprotect over multiple VMAs, mprotect might update the beginning
+        VMAs before reaching the sealed VMA and return -EPERM.
+      - mmap and mremap: undefined behavior.
+
+Use cases
+=========
 - glibc:
   The dynamic linker, during loading ELF executables, can apply sealing to
-  non-writable memory segments.
-
-- Chrome browser: protect some security sensitive data-structures.
+  mapping segments.
 
-Notes on which memory to seal:
-==============================
+- Chrome browser: protect some security sensitive data structures.
 
-It might be important to note that sealing changes the lifetime of a mapping,
-i.e. the sealed mapping won’t be unmapped till the process terminates or the
-exec system call is invoked. Applications can apply sealing to any virtual
-memory region from userspace, but it is crucial to thoroughly analyze the
-mapping's lifetime prior to apply the sealing.
+When not to use mseal
+=====================
+Applications can apply sealing to any virtual memory region from userspace,
+but it is *crucial to thoroughly analyze the mapping's lifetime* prior to
+apply the sealing. This is because the sealed mapping *won’t be unmapped*
+until the process terminates or the exec system call is invoked.
 
 For example:
+   - aio/shm
+     aio/shm can call mmap and  munmap on behalf of userspace, e.g.
+     ksys_shmdt() in shm.c. The lifetimes of those mapping are not tied to
+     the lifetime of the process. If those memories are sealed from userspace,
+     then munmap will fail, causing leaks in VMA address space during the
+     lifetime of the process.
+
+   - ptr allocated by malloc (heap)
+     Don't use mseal on the memory ptr return from malloc().
+     malloc() is implemented by allocator, e.g. by glibc. Heap manager might
+     allocate a ptr from brk or mapping created by mmap.
+     If an app calls mseal on a ptr returned from malloc(), this can affect
+     the heap manager's ability to manage the mappings; the outcome is
+     non-deterministic.
+
+     Example::
+
+        ptr = malloc(size);
+        /* don't call mseal on ptr return from malloc. */
+        mseal(ptr, size);
+        /* free will success, allocator can't shrink heap lower than ptr */
+        free(ptr);
+
+mseal doesn't block
+===================
+In a nutshell, mseal blocks certain mm syscall from modifying some of VMA's
+attributes, such as protection bits (RWX). Sealed mappings doesn't mean the
+memory is immutable.
 
-- aio/shm
-
-  aio/shm can call mmap()/munmap() on behalf of userspace, e.g. ksys_shmdt() in
-  shm.c. The lifetime of those mapping are not tied to the lifetime of the
-  process. If those memories are sealed from userspace, then munmap() will fail,
-  causing leaks in VMA address space during the lifetime of the process.
-
-- Brk (heap)
-
-  Currently, userspace applications can seal parts of the heap by calling
-  malloc() and mseal().
-  let's assume following calls from user space:
-
-  - ptr = malloc(size);
-  - mprotect(ptr, size, RO);
-  - mseal(ptr, size);
-  - free(ptr);
-
-  Technically, before mseal() is added, the user can change the protection of
-  the heap by calling mprotect(RO). As long as the user changes the protection
-  back to RW before free(), the memory range can be reused.
-
-  Adding mseal() into the picture, however, the heap is then sealed partially,
-  the user can still free it, but the memory remains to be RO. If the address
-  is re-used by the heap manager for another malloc, the process might crash
-  soon after. Therefore, it is important not to apply sealing to any memory
-  that might get recycled.
-
-  Furthermore, even if the application never calls the free() for the ptr,
-  the heap manager may invoke the brk system call to shrink the size of the
-  heap. In the kernel, the brk-shrink will call munmap(). Consequently,
-  depending on the location of the ptr, the outcome of brk-shrink is
-  nondeterministic.
-
-
-Additional notes:
-=================
 As Jann Horn pointed out in [3], there are still a few ways to write
-to RO memory, which is, in a way, by design. Those cases are not covered
-by mseal(). If applications want to block such cases, sandbox tools (such as
-seccomp, LSM, etc) might be considered.
+to RO memory, which is, in a way, by design. And those could be blocked
+by different security measures.
 
 Those cases are:
 
-- Write to read-only memory through /proc/self/mem interface.
-- Write to read-only memory through ptrace (such as PTRACE_POKETEXT).
-- userfaultfd.
+   - Write to read-only memory through /proc/self/mem interface (FOLL_FORCE).
+   - Write to read-only memory through ptrace (such as PTRACE_POKETEXT).
+   - userfaultfd.
 
 The idea that inspired this patch comes from Stephen Röttger’s work in V8
 CFI [4]. Chrome browser in ChromeOS will be the first user of this API.
 
-Reference:
-==========
-[1] https://github.com/apple-oss-distributions/xnu/blob/1031c584a5e37aff177559b9f69dbd3c8c3fd30a/osfmk/mach/vm_statistics.h#L274
-
-[2] https://man.openbsd.org/mimmutable.2
-
-[3] https://lore.kernel.org/lkml/CAG48ez3ShUYey+ZAFsU2i1RpQn0a5eOs2hzQ426FkcgnfUGLvA@mail.gmail.com
-
-[4] https://docs.google.com/document/d/1O2jwK4dxI3nRcOJuPYkonhTkNQfbmwdvxQMyXgeaRHo/edit#heading=h.bvaojj9fu6hc
+Reference
+=========
+- [1] https://github.com/apple-oss-distributions/xnu/blob/1031c584a5e37aff177559b9f69dbd3c8c3fd30a/osfmk/mach/vm_statistics.h#L274
+- [2] https://man.openbsd.org/mimmutable.2
+- [3] https://lore.kernel.org/lkml/CAG48ez3ShUYey+ZAFsU2i1RpQn0a5eOs2hzQ426FkcgnfUGLvA@mail.gmail.com
+- [4] https://docs.google.com/document/d/1O2jwK4dxI3nRcOJuPYkonhTkNQfbmwdvxQMyXgeaRHo/edit#heading=h.bvaojj9fu6hc
index e32471977d0a23933698952ae3d9057fa6aeea3b..edc070c6e19b210f11755d9e675a697eb5eab49c 100644 (file)
@@ -8098,13 +8098,15 @@ KVM_X86_QUIRK_MWAIT_NEVER_UD_FAULTS By default, KVM emulates MONITOR/MWAIT (if
                                     KVM_X86_QUIRK_MISC_ENABLE_NO_MWAIT is
                                     disabled.
 
-KVM_X86_QUIRK_SLOT_ZAP_ALL          By default, KVM invalidates all SPTEs in
-                                    fast way for memslot deletion when VM type
-                                    is KVM_X86_DEFAULT_VM.
-                                    When this quirk is disabled or when VM type
-                                    is other than KVM_X86_DEFAULT_VM, KVM zaps
-                                    only leaf SPTEs that are within the range of
-                                    the memslot being deleted.
+KVM_X86_QUIRK_SLOT_ZAP_ALL          By default, for KVM_X86_DEFAULT_VM VMs, KVM
+                                    invalidates all SPTEs in all memslots and
+                                    address spaces when a memslot is deleted or
+                                    moved.  When this quirk is disabled (or the
+                                    VM type isn't KVM_X86_DEFAULT_VM), KVM only
+                                    ensures the backing memory of the deleted
+                                    or moved memslot isn't reachable, i.e KVM
+                                    _may_ invalidate only SPTEs related to the
+                                    memslot.
 =================================== ============================================
 
 7.32 KVM_CAP_MAX_VCPU_ID
index 20a9a37d1cdd23d4e4dd0f60edee57912759e60e..1bedd56e2fe3ac381ccc464e29dfc31db625c0c7 100644 (file)
@@ -136,7 +136,7 @@ For direct sp, we can easily avoid it since the spte of direct sp is fixed
 to gfn.  For indirect sp, we disabled fast page fault for simplicity.
 
 A solution for indirect sp could be to pin the gfn, for example via
-kvm_vcpu_gfn_to_pfn_atomic, before the cmpxchg.  After the pinning:
+gfn_to_pfn_memslot_atomic, before the cmpxchg.  After the pinning:
 
 - We have held the refcount of pfn; that means the pfn can not be freed and
   be reused for another gfn.
index 2fcdfcf0332708264f6ce5c7165b801657915a5f..e0c20af309481a35fbc54e7c9d1c19d4c91f4633 100644 (file)
@@ -8,7 +8,7 @@ Introduction
 ============
 
 Many Dell notebooks made after ~2020 support a WMI-based interface for
-retrieving various system data like battery temperature, ePPID, diagostic data
+retrieving various system data like battery temperature, ePPID, diagnostic data
 and fan/thermal sensor data.
 
 This interface is likely used by the `Dell Data Vault` software on Windows,
@@ -277,7 +277,7 @@ Reverse-Engineering the DDV WMI interface
 4. Try to deduce the meaning of a certain WMI method by comparing the control
    flow with other ACPI methods (_BIX or _BIF for battery related methods
    for example).
-5. Use the built-in UEFI diagostics to view sensor types/values for fan/thermal
+5. Use the built-in UEFI diagnostics to view sensor types/values for fan/thermal
    related methods (sometimes overwriting static ACPI data fields can be used
    to test different sensor type values, since on some machines this data is
    not reinitialized upon a warm reset).
index c27f3190737f8b85779bde5489639c8b899f4fd8..bdae0faf000c7e293cb6c119d974dc78e82cdb5a 100644 (file)
 S:     Maintained
 F:     drivers/net/ethernet/alteon/acenic*
 
-ACER ASPIRE 1 EMBEDDED CONTROLLER DRIVER
-M:     Nikita Travkin <[email protected]>
-S:     Maintained
-F:     Documentation/devicetree/bindings/platform/acer,aspire1-ec.yaml
-F:     drivers/platform/arm64/acer-aspire1-ec.c
-
 ACER ASPIRE ONE TEMPERATURE AND FAN DRIVER
 M:     Peter Kaestle <[email protected]>
 L:     [email protected]
@@ -860,7 +854,7 @@ F:  drivers/crypto/allwinner/
 
 ALLWINNER DMIC DRIVERS
 M:     Ban Tao <[email protected]>
-L:     [email protected] (moderated for non-subscribers)
+L:     [email protected]
 S:     Maintained
 F:     Documentation/devicetree/bindings/sound/allwinner,sun50i-h6-dmic.yaml
 F:     sound/soc/sunxi/sun50i-dmic.c
@@ -888,7 +882,6 @@ F:  drivers/staging/media/sunxi/cedrus/
 
 ALPHA PORT
 M:     Richard Henderson <[email protected]>
-M:     Ivan Kokshaysky <[email protected]>
 M:     Matt Turner <[email protected]>
 L:     [email protected]
 S:     Odd Fixes
@@ -1517,7 +1510,7 @@ F:        drivers/iio/gyro/adxrs290.c
 ANALOG DEVICES INC ASOC CODEC DRIVERS
 M:     Lars-Peter Clausen <[email protected]>
 M:     Nuno Sá <[email protected]>
-L:     [email protected] (moderated for non-subscribers)
+L:     [email protected]
 S:     Supported
 W:     http://wiki.analog.com/
 W:     https://ez.analog.com/linux-software-drivers
@@ -1594,7 +1587,7 @@ F:        drivers/rtc/rtc-goldfish.c
 AOA (Apple Onboard Audio) ALSA DRIVER
 M:     Johannes Berg <[email protected]>
 L:     [email protected]
-L:     [email protected] (moderated for non-subscribers)
+L:     [email protected]
 S:     Maintained
 F:     sound/aoa/
 
@@ -1761,8 +1754,8 @@ F:        include/uapi/linux/if_arcnet.h
 ARM AND ARM64 SoC SUB-ARCHITECTURES (COMMON PARTS)
 M:     Arnd Bergmann <[email protected]>
 M:     Olof Johansson <[email protected]>
-M:     [email protected]
 L:     [email protected] (moderated for non-subscribers)
+L:     [email protected]
 S:     Maintained
 P:     Documentation/process/maintainer-soc.rst
 C:     irc://irc.libera.chat/armlinux
@@ -2091,7 +2084,7 @@ F:        drivers/crypto/amlogic/
 
 ARM/Amlogic Meson SoC Sound Drivers
 M:     Jerome Brunet <[email protected]>
-L:     [email protected] (moderated for non-subscribers)
+L:     [email protected]
 S:     Maintained
 F:     Documentation/devicetree/bindings/sound/amlogic*
 F:     sound/soc/meson/
@@ -2129,7 +2122,7 @@ F:        drivers/*/*alpine*
 ARM/APPLE MACHINE SOUND DRIVERS
 M:     Martin Povišer <[email protected]>
 L:     [email protected]
-L:     [email protected] (moderated for non-subscribers)
+L:     [email protected]
 S:     Maintained
 F:     Documentation/devicetree/bindings/sound/adi,ssm3515.yaml
 F:     Documentation/devicetree/bindings/sound/apple,*
@@ -2263,12 +2256,6 @@ L:       [email protected] (moderated for non-subscribers)
 S:     Maintained
 F:     arch/arm/mach-ep93xx/ts72xx.c
 
-ARM/CIRRUS LOGIC CLPS711X ARM ARCHITECTURE
-M:     Alexander Shiyan <[email protected]>
-L:     [email protected] (moderated for non-subscribers)
-S:     Odd Fixes
-N:     clps711x
-
 ARM/CIRRUS LOGIC EP93XX ARM ARCHITECTURE
 M:     Hartley Sweeten <[email protected]>
 M:     Alexander Sverdlin <[email protected]>
@@ -3732,7 +3719,7 @@ F:        arch/arm/boot/dts/microchip/at91-tse850-3.dts
 
 AXENTIA ASOC DRIVERS
 M:     Peter Rosin <[email protected]>
-L:     [email protected] (moderated for non-subscribers)
+L:     [email protected]
 S:     Maintained
 F:     Documentation/devicetree/bindings/sound/axentia,*
 F:     sound/soc/atmel/tse850-pcm5142.c
@@ -3815,14 +3802,6 @@ F:       drivers/video/backlight/
 F:     include/linux/backlight.h
 F:     include/linux/pwm_backlight.h
 
-BAIKAL-T1 PVT HARDWARE MONITOR DRIVER
-M:     Serge Semin <[email protected]>
-L:     [email protected]
-S:     Supported
-F:     Documentation/devicetree/bindings/hwmon/baikal,bt1-pvt.yaml
-F:     Documentation/hwmon/bt1-pvt.rst
-F:     drivers/hwmon/bt1-pvt.[ch]
-
 BARCO P50 GPIO DRIVER
 M:     Santosh Kumar Yadav <[email protected]>
 M:     Peter Korsgaard <[email protected]>
@@ -4851,7 +4830,7 @@ F:        include/uapi/linux/bsg.h
 
 BT87X AUDIO DRIVER
 M:     Clemens Ladisch <[email protected]>
-L:     [email protected] (moderated for non-subscribers)
+L:     [email protected]
 S:     Maintained
 T:     git git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound.git
 F:     Documentation/sound/cards/bt87x.rst
@@ -4913,7 +4892,7 @@ F:        drivers/net/can/bxcan.c
 
 C-MEDIA CMI8788 DRIVER
 M:     Clemens Ladisch <[email protected]>
-L:     [email protected] (moderated for non-subscribers)
+L:     [email protected]
 S:     Maintained
 T:     git git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound.git
 F:     sound/pci/oxygen/
@@ -6476,7 +6455,6 @@ F:        drivers/mtd/nand/raw/denali*
 
 DESIGNWARE EDMA CORE IP DRIVER
 M:     Manivannan Sadhasivam <[email protected]>
-R:     Serge Semin <[email protected]>
 L:     [email protected]
 S:     Maintained
 F:     drivers/dma/dw-edma/
@@ -7832,6 +7810,8 @@ F:        drivers/gpu/drm/xlnx/
 DRM GPU SCHEDULER
 M:     Luben Tuikov <[email protected]>
 M:     Matthew Brost <[email protected]>
+M:     Danilo Krummrich <[email protected]>
+M:     Philipp Stanner <[email protected]>
 L:     [email protected]
 S:     Maintained
 T:     git https://gitlab.freedesktop.org/drm/misc/kernel.git
@@ -8252,7 +8232,7 @@ F:        drivers/edac/ti_edac.c
 
 EDIROL UA-101/UA-1000 DRIVER
 M:     Clemens Ladisch <[email protected]>
-L:     [email protected] (moderated for non-subscribers)
+L:     [email protected]
 S:     Maintained
 T:     git git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound.git
 F:     sound/usb/misc/ua101.c
@@ -8814,7 +8794,7 @@ F:        drivers/net/can/usb/f81604.c
 FIREWIRE AUDIO DRIVERS and IEC 61883-1/6 PACKET STREAMING ENGINE
 M:     Clemens Ladisch <[email protected]>
 M:     Takashi Sakamoto <[email protected]>
-L:     [email protected] (moderated for non-subscribers)
+L:     [email protected]
 S:     Maintained
 T:     git git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound.git
 F:     include/uapi/sound/firewire.h
@@ -8888,7 +8868,7 @@ F:        drivers/input/joystick/fsia6b.c
 
 FOCUSRITE SCARLETT2 MIXER DRIVER (Scarlett Gen 2+ and Clarett)
 M:     Geoffrey D. Bennett <[email protected]>
-L:     [email protected] (moderated for non-subscribers)
+L:     [email protected]
 S:     Maintained
 W:     https://github.com/geoffreybennett/scarlett-gen2
 B:     https://github.com/geoffreybennett/scarlett-gen2/issues
@@ -8912,6 +8892,7 @@ F:        include/linux/fortify-string.h
 F:     lib/fortify_kunit.c
 F:     lib/memcpy_kunit.c
 F:     lib/test_fortify/*
+K:     \bunsafe_memcpy\b
 K:     \b__NO_FORTIFY\b
 
 FPGA DFL DRIVERS
@@ -9209,7 +9190,7 @@ M:        Shengjiu Wang <[email protected]>
 M:     Xiubo Li <[email protected]>
 R:     Fabio Estevam <[email protected]>
 R:     Nicolin Chen <[email protected]>
-L:     [email protected] (moderated for non-subscribers)
+L:     [email protected]
 L:     [email protected]
 S:     Maintained
 F:     sound/soc/fsl/fsl*
@@ -9219,7 +9200,7 @@ FREESCALE SOC LPC32XX SOUND DRIVERS
 M:     J.M.B. Downing <[email protected]>
 M:     Piotr Wojtaszczyk <[email protected]>
 R:     Vladimir Zapolskiy <[email protected]>
-L:     [email protected] (moderated for non-subscribers)
+L:     [email protected]
 L:     [email protected]
 S:     Maintained
 F:     Documentation/devicetree/bindings/sound/nxp,lpc3220-i2s.yaml
@@ -9227,7 +9208,7 @@ F:        sound/soc/fsl/lpc3xxx-*
 
 FREESCALE SOC SOUND QMC DRIVER
 M:     Herve Codina <[email protected]>
-L:     [email protected] (moderated for non-subscribers)
+L:     [email protected]
 L:     [email protected]
 S:     Maintained
 F:     Documentation/devicetree/bindings/sound/fsl,qmc-audio.yaml
@@ -9742,6 +9723,7 @@ F:        include/dt-bindings/gpio/
 F:     include/linux/gpio.h
 F:     include/linux/gpio/
 F:     include/linux/of_gpio.h
+K:     (devm_)?gpio_(request|free|direction|get|set)
 
 GPIO UAPI
 M:     Bartosz Golaszewski <[email protected]>
@@ -9756,14 +9738,6 @@ F:       drivers/gpio/gpiolib-cdev.c
 F:     include/uapi/linux/gpio.h
 F:     tools/gpio/
 
-GRE DEMULTIPLEXER DRIVER
-M:     Dmitry Kozlov <[email protected]>
-L:     [email protected]
-S:     Maintained
-F:     include/net/gre.h
-F:     net/ipv4/gre_demux.c
-F:     net/ipv4/gre_offload.c
-
 GRETH 10/100/1G Ethernet MAC device driver
 M:     Andreas Larsson <[email protected]>
 L:     [email protected]
@@ -10267,7 +10241,7 @@ F:      Documentation/devicetree/bindings/arm/hisilicon/low-pin-count.yaml
 F:     drivers/bus/hisi_lpc.c
 
 HISILICON NETWORK SUBSYSTEM 3 DRIVER (HNS3)
-M:     Yisen Zhuang <yisen.zhuang@huawei.com>
+M:     Jian Shen <shenjian15@huawei.com>
 M:     Salil Mehta <[email protected]>
 M:     Jijie Shao <[email protected]>
 L:     [email protected]
@@ -10276,7 +10250,7 @@ W:      http://www.hisilicon.com
 F:     drivers/net/ethernet/hisilicon/hns3/
 
 HISILICON NETWORK SUBSYSTEM DRIVER
-M:     Yisen Zhuang <yisen.zhuang@huawei.com>
+M:     Jian Shen <shenjian15@huawei.com>
 M:     Salil Mehta <[email protected]>
 L:     [email protected]
 S:     Maintained
@@ -11154,7 +11128,7 @@ F:      drivers/iio/pressure/dps310.c
 
 INFINEON PEB2466 ASoC CODEC
 M:     Herve Codina <[email protected]>
-L:     [email protected] (moderated for non-subscribers)
+L:     [email protected]
 S:     Maintained
 F:     Documentation/devicetree/bindings/sound/infineon,peb2466.yaml
 F:     sound/soc/codecs/peb2466.c
@@ -11280,10 +11254,10 @@ F:    security/integrity/
 F:     security/integrity/ima/
 
 INTEGRITY POLICY ENFORCEMENT (IPE)
-M:     Fan Wu <wufan@linux.microsoft.com>
+M:     Fan Wu <wufan@kernel.org>
 L:     [email protected]
 S:     Supported
-T:     git https://github.com/microsoft/ipe.git
+T:     git git://git.kernel.org/pub/scm/linux/kernel/git/wufan/ipe.git
 F:     Documentation/admin-guide/LSM/ipe.rst
 F:     Documentation/security/ipe.rst
 F:     scripts/ipe/
@@ -11317,7 +11291,7 @@ M:      Bard Liao <[email protected]>
 M:     Ranjani Sridharan <[email protected]>
 M:     Kai Vehmanen <[email protected]>
 R:     Pierre-Louis Bossart <[email protected]>
-L:     [email protected] (moderated for non-subscribers)
+L:     [email protected]
 S:     Supported
 F:     sound/soc/intel/
 
@@ -11496,7 +11470,7 @@ F:      include/uapi/linux/idxd.h
 
 INTEL IN FIELD SCAN (IFS) DEVICE
 M:     Jithu Joseph <[email protected]>
-R:     Ashok Raj <ashok.raj@intel.com>
+R:     Ashok Raj <ashok.raj.linux@gmail.com>
 R:     Tony Luck <[email protected]>
 S:     Maintained
 F:     drivers/platform/x86/intel/ifs
@@ -11601,6 +11575,16 @@ F:     drivers/crypto/intel/keembay/keembay-ocs-hcu-core.c
 F:     drivers/crypto/intel/keembay/ocs-hcu.c
 F:     drivers/crypto/intel/keembay/ocs-hcu.h
 
+INTEL LA JOLLA COVE ADAPTER (LJCA) USB I/O EXPANDER DRIVERS
+M:     Wentong Wu <[email protected]>
+M:     Sakari Ailus <[email protected]>
+S:     Maintained
+F:     drivers/gpio/gpio-ljca.c
+F:     drivers/i2c/busses/i2c-ljca.c
+F:     drivers/spi/spi-ljca.c
+F:     drivers/usb/misc/usb-ljca.c
+F:     include/linux/usb/ljca.h
+
 INTEL MANAGEMENT ENGINE (mei)
 M:     Tomas Winkler <[email protected]>
 L:     [email protected]
@@ -12001,7 +11985,7 @@ F:      drivers/tty/ipwireless/
 
 IRON DEVICE AUDIO CODEC DRIVERS
 M:     Kiseok Jo <[email protected]>
-L:     [email protected] (moderated for non-subscribers)
+L:     [email protected]
 S:     Maintained
 F:     Documentation/devicetree/bindings/sound/irondevice,*
 F:     sound/soc/codecs/sma*
@@ -12239,6 +12223,7 @@ R:      Dmitry Vyukov <[email protected]>
 R:     Vincenzo Frascino <[email protected]>
 L:     [email protected]
 S:     Maintained
+B:     https://bugzilla.kernel.org/buglist.cgi?component=Sanitizers&product=Memory%20Management
 F:     Documentation/dev-tools/kasan.rst
 F:     arch/*/include/asm/*kasan.h
 F:     arch/*/mm/kasan_init*
@@ -12262,6 +12247,7 @@ R:      Dmitry Vyukov <[email protected]>
 R:     Andrey Konovalov <[email protected]>
 L:     [email protected]
 S:     Maintained
+B:     https://bugzilla.kernel.org/buglist.cgi?component=Sanitizers&product=Memory%20Management
 F:     Documentation/dev-tools/kcov.rst
 F:     include/linux/kcov.h
 F:     include/uapi/linux/kcov.h
@@ -12343,6 +12329,7 @@ F:      include/linux/randomize_kstack.h
 F:     kernel/configs/hardening.config
 F:     lib/usercopy_kunit.c
 F:     mm/usercopy.c
+F:     security/Kconfig.hardening
 K:     \b(add|choose)_random_kstack_offset\b
 K:     \b__check_(object_size|heap_object)\b
 K:     \b__counted_by\b
@@ -12459,7 +12446,7 @@ F:      virt/kvm/*
 KERNEL VIRTUAL MACHINE FOR ARM64 (KVM/arm64)
 M:     Marc Zyngier <[email protected]>
 M:     Oliver Upton <[email protected]>
-R:     James Morse <james.morse@arm.com>
+R:     Joey Gouly <joey.gouly@arm.com>
 R:     Suzuki K Poulose <[email protected]>
 R:     Zenghui Yu <[email protected]>
 L:     [email protected] (moderated for non-subscribers)
@@ -12940,49 +12927,29 @@ LIBATA PATA ARASAN COMPACT FLASH CONTROLLER
 M:     Viresh Kumar <[email protected]>
 L:     [email protected]
 S:     Maintained
-T:     git git://git.kernel.org/pub/scm/linux/kernel/git/axboe/linux-block.git
 F:     drivers/ata/pata_arasan_cf.c
 F:     include/linux/pata_arasan_cf_data.h
 
-LIBATA PATA DRIVERS
-R:     Sergey Shtylyov <[email protected]>
-L:     [email protected]
-F:     drivers/ata/ata_*.c
-F:     drivers/ata/pata_*.c
-
 LIBATA PATA FARADAY FTIDE010 AND GEMINI SATA BRIDGE DRIVERS
 M:     Linus Walleij <[email protected]>
 L:     [email protected]
 S:     Maintained
-T:     git git://git.kernel.org/pub/scm/linux/kernel/git/axboe/linux-block.git
 F:     drivers/ata/pata_ftide010.c
 F:     drivers/ata/sata_gemini.c
 F:     drivers/ata/sata_gemini.h
 
 LIBATA SATA AHCI PLATFORM devices support
 M:     Hans de Goede <[email protected]>
-M:     Jens Axboe <[email protected]>
 L:     [email protected]
 S:     Maintained
-T:     git git://git.kernel.org/pub/scm/linux/kernel/git/axboe/linux-block.git
 F:     drivers/ata/ahci_platform.c
 F:     drivers/ata/libahci_platform.c
 F:     include/linux/ahci_platform.h
 
-LIBATA SATA AHCI SYNOPSYS DWC CONTROLLER DRIVER
-M:     Serge Semin <[email protected]>
-L:     [email protected]
-S:     Maintained
-T:     git git://git.kernel.org/pub/scm/linux/kernel/git/dlemoal/libata.git
-F:     Documentation/devicetree/bindings/ata/baikal,bt1-ahci.yaml
-F:     Documentation/devicetree/bindings/ata/snps,dwc-ahci.yaml
-F:     drivers/ata/ahci_dwc.c
-
 LIBATA SATA PROMISE TX2/TX4 CONTROLLER DRIVER
 M:     Mikael Pettersson <[email protected]>
 L:     [email protected]
 S:     Maintained
-T:     git git://git.kernel.org/pub/scm/linux/kernel/git/axboe/linux-block.git
 F:     drivers/ata/sata_promise.*
 
 LIBATA SUBSYSTEM (Serial and Parallel ATA drivers)
@@ -13952,7 +13919,7 @@ F:      drivers/media/i2c/max96717.c
 
 MAX9860 MONO AUDIO VOICE CODEC DRIVER
 M:     Peter Rosin <[email protected]>
-L:     [email protected] (moderated for non-subscribers)
+L:     [email protected]
 S:     Maintained
 F:     Documentation/devicetree/bindings/sound/max9860.txt
 F:     sound/soc/codecs/max9860.*
@@ -14175,8 +14142,7 @@ T:      git git://linuxtv.org/media_tree.git
 F:     drivers/media/platform/nxp/imx-pxp.[ch]
 
 MEDIA DRIVERS FOR ASCOT2E
-M:     Sergey Kozlov <[email protected]>
-M:     Abylay Ospan <[email protected]>
+M:     Abylay Ospan <[email protected]>
 L:     [email protected]
 S:     Supported
 W:     https://linuxtv.org
@@ -14193,8 +14159,7 @@ T:      git git://linuxtv.org/media_tree.git
 F:     drivers/media/dvb-frontends/cxd2099*
 
 MEDIA DRIVERS FOR CXD2841ER
-M:     Sergey Kozlov <[email protected]>
-M:     Abylay Ospan <[email protected]>
+M:     Abylay Ospan <[email protected]>
 L:     [email protected]
 S:     Supported
 W:     https://linuxtv.org
@@ -14247,7 +14212,7 @@ F:      drivers/media/platform/nxp/imx7-media-csi.c
 F:     drivers/media/platform/nxp/imx8mq-mipi-csi2.c
 
 MEDIA DRIVERS FOR HELENE
-M:     Abylay Ospan <aospan@netup.ru>
+M:     Abylay Ospan <aospan@amazon.com>
 L:     [email protected]
 S:     Supported
 W:     https://linuxtv.org
@@ -14256,8 +14221,7 @@ T:      git git://linuxtv.org/media_tree.git
 F:     drivers/media/dvb-frontends/helene*
 
 MEDIA DRIVERS FOR HORUS3A
-M:     Sergey Kozlov <[email protected]>
-M:     Abylay Ospan <[email protected]>
+M:     Abylay Ospan <[email protected]>
 L:     [email protected]
 S:     Supported
 W:     https://linuxtv.org
@@ -14266,8 +14230,7 @@ T:      git git://linuxtv.org/media_tree.git
 F:     drivers/media/dvb-frontends/horus3a*
 
 MEDIA DRIVERS FOR LNBH25
-M:     Sergey Kozlov <[email protected]>
-M:     Abylay Ospan <[email protected]>
+M:     Abylay Ospan <[email protected]>
 L:     [email protected]
 S:     Supported
 W:     https://linuxtv.org
@@ -14283,8 +14246,7 @@ T:      git git://linuxtv.org/media_tree.git
 F:     drivers/media/dvb-frontends/mxl5xx*
 
 MEDIA DRIVERS FOR NETUP PCI UNIVERSAL DVB devices
-M:     Sergey Kozlov <[email protected]>
-M:     Abylay Ospan <[email protected]>
+M:     Abylay Ospan <[email protected]>
 L:     [email protected]
 S:     Supported
 W:     https://linuxtv.org
@@ -14909,9 +14871,10 @@ N:     include/linux/page[-_]*
 
 MEMORY MAPPING
 M:     Andrew Morton <[email protected]>
-R:     Liam R. Howlett <[email protected]>
+M:     Liam R. Howlett <[email protected]>
+M:     Lorenzo Stoakes <[email protected]>
 R:     Vlastimil Babka <[email protected]>
-R:     Lorenzo Stoakes <lorenzo.stoakes@oracle.com>
+R:     Jann Horn <jannh@google.com>
 L:     [email protected]
 S:     Maintained
 W:     http://www.linux-mm.org
@@ -14934,13 +14897,6 @@ F:     drivers/mtd/
 F:     include/linux/mtd/
 F:     include/uapi/mtd/
 
-MEMSENSING MICROSYSTEMS MSA311 DRIVER
-M:     Dmitry Rokosov <[email protected]>
-L:     [email protected]
-S:     Maintained
-F:     Documentation/devicetree/bindings/iio/accel/memsensing,msa311.yaml
-F:     drivers/iio/accel/msa311.c
-
 MEN A21 WATCHDOG DRIVER
 M:     Johannes Thumshirn <[email protected]>
 L:     [email protected]
@@ -15085,7 +15041,8 @@ F:      drivers/spi/spi-at91-usart.c
 
 MICROCHIP AUDIO ASOC DRIVERS
 M:     Claudiu Beznea <[email protected]>
-L:     [email protected] (moderated for non-subscribers)
+M:     Andrei Simion <[email protected]>
+L:     [email protected]
 S:     Supported
 F:     Documentation/devicetree/bindings/sound/atmel*
 F:     Documentation/devicetree/bindings/sound/axentia,tse850-pcm5142.txt
@@ -15193,6 +15150,7 @@ F:      include/video/atmel_lcdc.h
 
 MICROCHIP MCP16502 PMIC DRIVER
 M:     Claudiu Beznea <[email protected]>
+M:     Andrei Simion <[email protected]>
 L:     [email protected] (moderated for non-subscribers)
 S:     Supported
 F:     Documentation/devicetree/bindings/regulator/microchip,mcp16502.yaml
@@ -15274,7 +15232,6 @@ F:      drivers/tty/serial/8250/8250_pci1xxxx.c
 
 MICROCHIP POLARFIRE FPGA DRIVERS
 M:     Conor Dooley <[email protected]>
-R:     Vladimir Georgiev <[email protected]>
 L:     [email protected]
 S:     Supported
 F:     Documentation/devicetree/bindings/fpga/microchip,mpf-spi-fpga-mgr.yaml
@@ -15324,6 +15281,7 @@ F:      drivers/spi/spi-atmel.*
 
 MICROCHIP SSC DRIVER
 M:     Claudiu Beznea <[email protected]>
+M:     Andrei Simion <[email protected]>
 L:     [email protected] (moderated for non-subscribers)
 S:     Supported
 F:     Documentation/devicetree/bindings/misc/atmel-ssc.txt
@@ -15529,17 +15487,6 @@ F:     arch/mips/
 F:     drivers/platform/mips/
 F:     include/dt-bindings/mips/
 
-MIPS BAIKAL-T1 PLATFORM
-M:     Serge Semin <[email protected]>
-L:     [email protected]
-S:     Supported
-F:     Documentation/devicetree/bindings/bus/baikal,bt1-*.yaml
-F:     Documentation/devicetree/bindings/clock/baikal,bt1-*.yaml
-F:     drivers/bus/bt1-*.c
-F:     drivers/clk/baikal-t1/
-F:     drivers/memory/bt1-l2-ctl.c
-F:     drivers/mtd/maps/physmap-bt1-rom.[ch]
-
 MIPS BOSTON DEVELOPMENT BOARD
 M:     Paul Burton <[email protected]>
 L:     [email protected]
@@ -15552,7 +15499,6 @@ F:      include/dt-bindings/clock/boston-clock.h
 
 MIPS CORE DRIVERS
 M:     Thomas Bogendoerfer <[email protected]>
-M:     Serge Semin <[email protected]>
 L:     [email protected]
 S:     Supported
 F:     drivers/bus/mips_cdmm.c
@@ -15957,7 +15903,7 @@ F:      include/linux/mtd/*nand*.h
 
 NATIVE INSTRUMENTS USB SOUND INTERFACE DRIVER
 M:     Daniel Mack <[email protected]>
-L:     [email protected] (moderated for non-subscribers)
+L:     [email protected]
 S:     Maintained
 W:     http://www.native-instruments.com
 F:     sound/usb/caiaq/
@@ -16088,6 +16034,7 @@ F:      include/uapi/linux/net_dropmon.h
 F:     net/core/drop_monitor.c
 
 NETWORKING DRIVERS
+M:     Andrew Lunn <[email protected]>
 M:     "David S. Miller" <[email protected]>
 M:     Eric Dumazet <[email protected]>
 M:     Jakub Kicinski <[email protected]>
@@ -16153,6 +16100,7 @@ M:      "David S. Miller" <[email protected]>
 M:     Eric Dumazet <[email protected]>
 M:     Jakub Kicinski <[email protected]>
 M:     Paolo Abeni <[email protected]>
+R:     Simon Horman <[email protected]>
 L:     [email protected]
 S:     Maintained
 P:     Documentation/process/maintainer-netdev.rst
@@ -16195,10 +16143,22 @@ F:    include/uapi/linux/rtnetlink.h
 F:     lib/net_utils.c
 F:     lib/random32.c
 F:     net/
+F:     samples/pktgen/
 F:     tools/net/
 F:     tools/testing/selftests/net/
+X:     Documentation/networking/mac80211-injection.rst
+X:     Documentation/networking/mac80211_hwsim/
+X:     Documentation/networking/regulatory.rst
+X:     include/net/cfg80211.h
+X:     include/net/ieee80211_radiotap.h
+X:     include/net/iw_handler.h
+X:     include/net/mac80211.h
+X:     include/net/wext.h
 X:     net/9p/
 X:     net/bluetooth/
+X:     net/mac80211/
+X:     net/rfkill/
+X:     net/wireless/
 
 NETWORKING [IPSEC]
 M:     Steffen Klassert <[email protected]>
@@ -16508,12 +16468,6 @@ F:     include/linux/ntb.h
 F:     include/linux/ntb_transport.h
 F:     tools/testing/selftests/ntb/
 
-NTB IDT DRIVER
-M:     Serge Semin <[email protected]>
-L:     [email protected]
-S:     Supported
-F:     drivers/ntb/hw/idt/
-
 NTB INTEL DRIVER
 M:     Dave Jiang <[email protected]>
 L:     [email protected]
@@ -16728,7 +16682,7 @@ F:      drivers/extcon/extcon-ptn5150.c
 
 NXP SGTL5000 DRIVER
 M:     Fabio Estevam <[email protected]>
-L:     [email protected] (moderated for non-subscribers)
+L:     [email protected]
 S:     Maintained
 F:     Documentation/devicetree/bindings/sound/fsl,sgtl5000.yaml
 F:     sound/soc/codecs/sgtl5000*
@@ -16752,7 +16706,7 @@ K:      "nxp,tda998x"
 
 NXP TFA9879 DRIVER
 M:     Peter Rosin <[email protected]>
-L:     [email protected] (moderated for non-subscribers)
+L:     [email protected]
 S:     Maintained
 F:     Documentation/devicetree/bindings/sound/nxp,tfa9879.yaml
 F:     sound/soc/codecs/tfa9879*
@@ -16764,7 +16718,7 @@ F:      drivers/nfc/nxp-nci
 
 NXP/Goodix TFA989X (TFA1) DRIVER
 M:     Stephan Gerhold <[email protected]>
-L:     [email protected] (moderated for non-subscribers)
+L:     [email protected]
 S:     Maintained
 F:     Documentation/devicetree/bindings/sound/nxp,tfa989x.yaml
 F:     sound/soc/codecs/tfa989x.c
@@ -16850,7 +16804,7 @@ F:      include/uapi/misc/ocxl.h
 OMAP AUDIO SUPPORT
 M:     Peter Ujfalusi <[email protected]>
 M:     Jarkko Nikula <[email protected]>
-L:     [email protected] (moderated for non-subscribers)
+L:     [email protected]
 L:     [email protected]
 S:     Maintained
 F:     sound/soc/ti/n810.c
@@ -17407,7 +17361,7 @@ F:      include/linux/pm_opp.h
 
 OPL4 DRIVER
 M:     Clemens Ladisch <[email protected]>
-L:     [email protected] (moderated for non-subscribers)
+L:     [email protected]
 S:     Maintained
 T:     git git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound.git
 F:     sound/drivers/opl4/
@@ -18534,13 +18488,6 @@ F:     drivers/pps/
 F:     include/linux/pps*.h
 F:     include/uapi/linux/pps.h
 
-PPTP DRIVER
-M:     Dmitry Kozlov <[email protected]>
-L:     [email protected]
-S:     Maintained
-W:     http://sourceforge.net/projects/accel-pptp
-F:     drivers/net/ppp/pptp.c
-
 PRESSURE STALL INFORMATION (PSI)
 M:     Johannes Weiner <[email protected]>
 M:     Suren Baghdasaryan <[email protected]>
@@ -18790,7 +18737,7 @@ F:      drivers/crypto/intel/qat/
 
 QCOM AUDIO (ASoC) DRIVERS
 M:     Srinivas Kandagatla <[email protected]>
-L:     [email protected] (moderated for non-subscribers)
+L:     [email protected]
 L:     [email protected]
 S:     Supported
 F:     Documentation/devicetree/bindings/soc/qcom/qcom,apr*
@@ -19514,6 +19461,14 @@ S:     Maintained
 F:     Documentation/tools/rtla/
 F:     tools/tracing/rtla/
 
+Real-time Linux (PREEMPT_RT)
+M:     Sebastian Andrzej Siewior <[email protected]>
+M:     Clark Williams <[email protected]>
+M:     Steven Rostedt <[email protected]>
+L:     [email protected]
+S:     Supported
+K:     PREEMPT_RT
+
 REALTEK AUDIO CODECS
 M:     Oder Chiou <[email protected]>
 S:     Maintained
@@ -19623,15 +19578,6 @@ S:     Supported
 F:     Documentation/devicetree/bindings/i2c/renesas,iic-emev2.yaml
 F:     drivers/i2c/busses/i2c-emev2.c
 
-RENESAS ETHERNET AVB DRIVER
-R:     Sergey Shtylyov <[email protected]>
-L:     [email protected]
-L:     [email protected]
-F:     Documentation/devicetree/bindings/net/renesas,etheravb.yaml
-F:     drivers/net/ethernet/renesas/Kconfig
-F:     drivers/net/ethernet/renesas/Makefile
-F:     drivers/net/ethernet/renesas/ravb*
-
 RENESAS ETHERNET SWITCH DRIVER
 R:     Yoshihiro Shimoda <[email protected]>
 L:     [email protected]
@@ -19652,7 +19598,7 @@ F:      drivers/net/ethernet/renesas/rtsn.*
 
 RENESAS IDT821034 ASoC CODEC
 M:     Herve Codina <[email protected]>
-L:     [email protected] (moderated for non-subscribers)
+L:     [email protected]
 S:     Maintained
 F:     Documentation/devicetree/bindings/sound/renesas,idt821034.yaml
 F:     sound/soc/codecs/idt821034.c
@@ -19681,14 +19627,6 @@ F:     Documentation/devicetree/bindings/i2c/renesas,rmobile-iic.yaml
 F:     drivers/i2c/busses/i2c-rcar.c
 F:     drivers/i2c/busses/i2c-sh_mobile.c
 
-RENESAS R-CAR SATA DRIVER
-R:     Sergey Shtylyov <[email protected]>
-L:     [email protected]
-L:     [email protected]
-S:     Supported
-F:     Documentation/devicetree/bindings/ata/renesas,rcar-sata.yaml
-F:     drivers/ata/sata_rcar.c
-
 RENESAS R-CAR THERMAL DRIVERS
 M:     Niklas Söderlund <[email protected]>
 L:     [email protected]
@@ -19764,16 +19702,6 @@ S:     Supported
 F:     Documentation/devicetree/bindings/i2c/renesas,rzv2m.yaml
 F:     drivers/i2c/busses/i2c-rzv2m.c
 
-RENESAS SUPERH ETHERNET DRIVER
-R:     Sergey Shtylyov <[email protected]>
-L:     [email protected]
-L:     [email protected]
-F:     Documentation/devicetree/bindings/net/renesas,ether.yaml
-F:     drivers/net/ethernet/renesas/Kconfig
-F:     drivers/net/ethernet/renesas/Makefile
-F:     drivers/net/ethernet/renesas/sh_eth*
-F:     include/linux/sh_eth.h
-
 RENESAS USB PHY DRIVER
 M:     Yoshihiro Shimoda <[email protected]>
 L:     [email protected]
@@ -20403,7 +20331,7 @@ F:      security/safesetid/
 
 SAMSUNG AUDIO (ASoC) DRIVERS
 M:     Sylwester Nawrocki <[email protected]>
-L:     [email protected] (moderated for non-subscribers)
+L:     [email protected]
 S:     Maintained
 B:     mailto:[email protected]
 F:     Documentation/devicetree/bindings/sound/samsung*
@@ -20939,7 +20867,7 @@ F:      drivers/media/rc/serial_ir.c
 
 SERIAL LOW-POWER INTER-CHIP MEDIA BUS (SLIMbus)
 M:     Srinivas Kandagatla <[email protected]>
-L:     [email protected] (moderated for non-subscribers)
+L:     [email protected]
 S:     Maintained
 F:     Documentation/devicetree/bindings/slimbus/
 F:     drivers/slimbus/
@@ -21373,7 +21301,7 @@ F:      Documentation/devicetree/bindings/i2c/socionext,synquacer-i2c.yaml
 F:     drivers/i2c/busses/i2c-synquacer.c
 
 SOCIONEXT UNIPHIER SOUND DRIVER
-L:     [email protected] (moderated for non-subscribers)
+L:     [email protected]
 S:     Orphan
 F:     sound/soc/uniphier/
 
@@ -21632,7 +21560,7 @@ F:      tools/testing/selftests/alsa
 
 SOUND - COMPRESSED AUDIO
 M:     Vinod Koul <[email protected]>
-L:     [email protected] (moderated for non-subscribers)
+L:     [email protected]
 S:     Supported
 T:     git git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound.git
 F:     Documentation/sound/designs/compress-offload.rst
@@ -21695,7 +21623,7 @@ M:      Vinod Koul <[email protected]>
 M:     Bard Liao <[email protected]>
 R:     Pierre-Louis Bossart <[email protected]>
 R:     Sanyog Kale <[email protected]>
-L:     [email protected] (moderated for non-subscribers)
+L:     [email protected]
 S:     Supported
 T:     git git://git.kernel.org/pub/scm/linux/kernel/git/vkoul/soundwire.git
 F:     Documentation/driver-api/soundwire/
@@ -21768,8 +21696,8 @@ F:      drivers/accessibility/speakup/
 SPEAR PLATFORM/CLOCK/PINCTRL SUPPORT
 M:     Viresh Kumar <[email protected]>
 M:     Shiraz Hashim <[email protected]>
-M:     [email protected]
 L:     [email protected] (moderated for non-subscribers)
+L:     [email protected]
 S:     Maintained
 W:     http://www.st.com/spear
 F:     arch/arm/boot/dts/st/spear*
@@ -22168,7 +22096,7 @@ F:      kernel/static_call.c
 
 STI AUDIO (ASoC) DRIVERS
 M:     Arnaud Pouliquen <[email protected]>
-L:     [email protected] (moderated for non-subscribers)
+L:     [email protected]
 S:     Maintained
 F:     Documentation/devicetree/bindings/sound/st,sti-asoc-card.txt
 F:     sound/soc/sti/
@@ -22189,7 +22117,7 @@ F:      drivers/media/usb/stk1160/
 STM32 AUDIO (ASoC) DRIVERS
 M:     Olivier Moysan <[email protected]>
 M:     Arnaud Pouliquen <[email protected]>
-L:     [email protected] (moderated for non-subscribers)
+L:     [email protected]
 S:     Maintained
 F:     Documentation/devicetree/bindings/iio/adc/st,stm32-dfsdm-adc.yaml
 F:     Documentation/devicetree/bindings/sound/st,stm32-*.yaml
@@ -22427,19 +22355,11 @@ F:    drivers/tty/serial/8250/8250_lpss.c
 
 SYNOPSYS DESIGNWARE APB GPIO DRIVER
 M:     Hoan Tran <[email protected]>
-M:     Serge Semin <[email protected]>
 L:     [email protected]
 S:     Maintained
 F:     Documentation/devicetree/bindings/gpio/snps,dw-apb-gpio.yaml
 F:     drivers/gpio/gpio-dwapb.c
 
-SYNOPSYS DESIGNWARE APB SSI DRIVER
-M:     Serge Semin <[email protected]>
-L:     [email protected]
-S:     Supported
-F:     Documentation/devicetree/bindings/spi/snps,dw-apb-ssi.yaml
-F:     drivers/spi/spi-dw*
-
 SYNOPSYS DESIGNWARE AXI DMAC DRIVER
 M:     Eugeniy Paltsev <[email protected]>
 S:     Maintained
@@ -22892,7 +22812,7 @@ F:      drivers/irqchip/irq-xtensa-*
 
 TEXAS INSTRUMENTS ASoC DRIVERS
 M:     Peter Ujfalusi <[email protected]>
-L:     [email protected] (moderated for non-subscribers)
+L:     [email protected]
 S:     Maintained
 F:     Documentation/devicetree/bindings/sound/davinci-mcasp-audio.yaml
 F:     sound/soc/ti/
@@ -22901,7 +22821,7 @@ TEXAS INSTRUMENTS AUDIO (ASoC/HDA) DRIVERS
 M:     Shenghao Ding <[email protected]>
 M:     Kevin Lu <[email protected]>
 M:     Baojun Xu <[email protected]>
-L:     [email protected] (moderated for non-subscribers)
+L:     [email protected]
 S:     Maintained
 F:     Documentation/devicetree/bindings/sound/tas2552.txt
 F:     Documentation/devicetree/bindings/sound/ti,tas2562.yaml
@@ -23269,7 +23189,7 @@ F:      drivers/soc/ti/*
 TI LM49xxx FAMILY ASoC CODEC DRIVERS
 M:     M R Swami Reddy <[email protected]>
 M:     Vishwas A Deshpande <[email protected]>
-L:     [email protected] (moderated for non-subscribers)
+L:     [email protected]
 S:     Maintained
 F:     sound/soc/codecs/isabelle*
 F:     sound/soc/codecs/lm49453*
@@ -23283,15 +23203,15 @@ F:    Documentation/devicetree/bindings/iio/adc/ti,lmp92064.yaml
 F:     drivers/iio/adc/ti-lmp92064.c
 
 TI PCM3060 ASoC CODEC DRIVER
-M:     Kirill Marinushkin <kmarinushkin@birdec.com>
-L:     [email protected] (moderated for non-subscribers)
+M:     Kirill Marinushkin <k.marinushkin@gmail.com>
+L:     [email protected]
 S:     Maintained
 F:     Documentation/devicetree/bindings/sound/pcm3060.txt
 F:     sound/soc/codecs/pcm3060*
 
 TI TAS571X FAMILY ASoC CODEC DRIVER
 M:     Kevin Cernekee <[email protected]>
-L:     [email protected] (moderated for non-subscribers)
+L:     [email protected]
 S:     Odd Fixes
 F:     sound/soc/codecs/tas571x*
 
@@ -23319,7 +23239,7 @@ F:      drivers/iio/adc/ti-tsc2046.c
 
 TI TWL4030 SERIES SOC CODEC DRIVER
 M:     Peter Ujfalusi <[email protected]>
-L:     [email protected] (moderated for non-subscribers)
+L:     [email protected]
 S:     Maintained
 F:     sound/soc/codecs/twl4030*
 
 S:     Maintained
 F:     drivers/hid/hid-udraw-ps3.c
 
-UFS FILESYSTEM
-M:     Evgeniy Dushistov <[email protected]>
-S:     Maintained
-F:     Documentation/admin-guide/ufs.rst
-F:     fs/ufs/
-
 UHID USERSPACE HID IO DRIVER
 M:     David Rheinsberg <[email protected]>
 L:     [email protected]
@@ -23995,7 +23909,7 @@ F:      drivers/usb/storage/
 
 USB MIDI DRIVER
 M:     Clemens Ladisch <[email protected]>
-L:     [email protected] (moderated for non-subscribers)
+L:     [email protected]
 S:     Maintained
 T:     git git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound.git
 F:     sound/usb/midi.*
@@ -24057,6 +23971,7 @@ USB RAW GADGET DRIVER
 R:     Andrey Konovalov <[email protected]>
 L:     [email protected]
 S:     Maintained
+B:     https://github.com/xairy/raw-gadget/issues
 F:     Documentation/usb/raw-gadget.rst
 F:     drivers/usb/gadget/legacy/raw_gadget.c
 F:     include/uapi/linux/usb/raw_gadget.h
@@ -24173,8 +24088,12 @@ F:     drivers/usb/host/xhci*
 
 USER DATAGRAM PROTOCOL (UDP)
 M:     Willem de Bruijn <[email protected]>
+L:     [email protected]
 S:     Maintained
 F:     include/linux/udp.h
+F:     include/net/udp.h
+F:     include/trace/events/udp.h
+F:     include/uapi/linux/udp.h
 F:     net/ipv4/udp.c
 F:     net/ipv6/udp.c
 
@@ -24655,7 +24574,7 @@ VIRTIO SOUND DRIVER
 M:     Anton Yakovlev <[email protected]>
 M:     "Michael S. Tsirkin" <[email protected]>
 L:     [email protected]
-L:     [email protected] (moderated for non-subscribers)
+L:     [email protected]
 S:     Maintained
 F:     include/uapi/linux/virtio_snd.h
 F:     sound/virtio/*
@@ -24724,9 +24643,10 @@ F:     tools/testing/vsock/
 
 VMA
 M:     Andrew Morton <[email protected]>
-R:     Liam R. Howlett <[email protected]>
+M:     Liam R. Howlett <[email protected]>
+M:     Lorenzo Stoakes <[email protected]>
 R:     Vlastimil Babka <[email protected]>
-R:     Lorenzo Stoakes <lorenzo.stoakes@oracle.com>
+R:     Jann Horn <jannh@google.com>
 L:     [email protected]
 S:     Maintained
 W:     https://www.linux-mm.org
@@ -25384,7 +25304,7 @@ F:      include/xen/interface/io/usbif.h
 XEN SOUND FRONTEND DRIVER
 M:     Oleksandr Andrushchenko <[email protected]>
 L:     [email protected] (moderated for non-subscribers)
-L:     [email protected] (moderated for non-subscribers)
+L:     [email protected]
 S:     Supported
 F:     sound/xen/*
 
@@ -25400,7 +25320,7 @@ F:      include/xen/arm/swiotlb-xen.h
 F:     include/xen/swiotlb-xen.h
 
 XFS FILESYSTEM
-M:     Chandan Babu R <[email protected]>
+M:     Carlos Maiolino <[email protected]>
 R:     Darrick J. Wong <[email protected]>
 L:     [email protected]
 S:     Supported
index 187a4ce2728e9a31d41ce86d6c7d4f037d8270a3..5e04e4abffd88f6a06cb4c07f09b94f0305d1a3e 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -2,7 +2,7 @@
 VERSION = 6
 PATCHLEVEL = 12
 SUBLEVEL = 0
-EXTRAVERSION = -rc1
+EXTRAVERSION = -rc5
 NAME = Baby Opossum Posse
 
 # *DOCUMENTATION*
@@ -1645,7 +1645,7 @@ help:
                echo '* dtbs               - Build device tree blobs for enabled boards'; \
                echo '  dtbs_install       - Install dtbs to $(INSTALL_DTBS_PATH)'; \
                echo '  dt_binding_check   - Validate device tree binding documents and examples'; \
-               echo '  dt_binding_schema  - Build processed device tree binding schemas'; \
+               echo '  dt_binding_schemas - Build processed device tree binding schemas'; \
                echo '  dtbs_check         - Validate device tree source files';\
                echo '')
 
index 98157b38f5cf85e039941e31c164a9f80bf3d3b9..bd9f095d69fa0300605b455d1d4f89da77129192 100644 (file)
@@ -838,7 +838,7 @@ config CFI_CLANG
 config CFI_ICALL_NORMALIZE_INTEGERS
        bool "Normalize CFI tags for integers"
        depends on CFI_CLANG
-       depends on $(cc-option,-fsanitize=kcfi -fsanitize-cfi-icall-experimental-normalize-integers)
+       depends on HAVE_CFI_ICALL_NORMALIZE_INTEGERS_CLANG
        help
          This option normalizes the CFI tags for integer types so that all
          integer types of the same size and signedness receive the same CFI
@@ -851,6 +851,20 @@ config CFI_ICALL_NORMALIZE_INTEGERS
 
          This option is necessary for using CFI with Rust. If unsure, say N.
 
+config HAVE_CFI_ICALL_NORMALIZE_INTEGERS_CLANG
+       def_bool y
+       depends on $(cc-option,-fsanitize=kcfi -fsanitize-cfi-icall-experimental-normalize-integers)
+       # With GCOV/KASAN we need this fix: https://github.com/llvm/llvm-project/pull/104826
+       depends on CLANG_VERSION >= 190103 || (!GCOV_KERNEL && !KASAN_GENERIC && !KASAN_SW_TAGS)
+
+config HAVE_CFI_ICALL_NORMALIZE_INTEGERS_RUSTC
+       def_bool y
+       depends on HAVE_CFI_ICALL_NORMALIZE_INTEGERS_CLANG
+       depends on RUSTC_VERSION >= 107900
+       # With GCOV/KASAN we need this fix: https://github.com/rust-lang/rust/pull/129373
+       depends on (RUSTC_LLVM_VERSION >= 190103 && RUSTC_VERSION >= 108200) || \
+               (!GCOV_KERNEL && !KASAN_GENERIC && !KASAN_SW_TAGS)
+
 config CFI_PERMISSIVE
        bool "Use CFI in permissive mode"
        depends on CFI_CLANG
index 6afae65e9a8b32c8a7da57c0f2a0a320b6ea60fa..a9a38c80c4a7af92c5504cdfa6f9110b0c34f0a9 100644 (file)
@@ -22,7 +22,7 @@
 
 #include <asm/gentrap.h>
 #include <linux/uaccess.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include <asm/sysinfo.h>
 #include <asm/hwrpb.h>
 #include <asm/mmu_context.h>
index 4fdb7350636c32720f394976deecef7e37c71901..f57cb5a6b624038cc371d18f1f228553844e6981 100644 (file)
@@ -9,7 +9,7 @@
 #include <linux/types.h>
 #include <asm/byteorder.h>
 #include <asm/page.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #ifdef CONFIG_ISA_ARCV2
 #include <asm/barrier.h>
index 9febf5bc3de6d0617b3e4b2c0a985231e908963c..4ae2db59d494cb7932f129a349aff16ca967dc3d 100644 (file)
@@ -14,6 +14,7 @@ typedef struct {
        unsigned long asid[NR_CPUS];    /* 8 bit MMU PID + Generation cycle */
 } mm_context_t;
 
+struct pt_regs;
 extern void do_tlb_overlap_fault(unsigned long, unsigned long, struct pt_regs *);
 
 #endif
diff --git a/arch/arc/include/asm/unaligned.h b/arch/arc/include/asm/unaligned.h
deleted file mode 100644 (file)
index cf5a023..0000000
+++ /dev/null
@@ -1,27 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-only */
-/*
- * Copyright (C) 2004, 2007-2010, 2011-2012 Synopsys, Inc. (www.synopsys.com)
- */
-
-#ifndef _ASM_ARC_UNALIGNED_H
-#define _ASM_ARC_UNALIGNED_H
-
-/* ARC700 can't handle unaligned Data accesses. */
-
-#include <asm-generic/unaligned.h>
-#include <asm/ptrace.h>
-
-#ifdef CONFIG_ARC_EMUL_UNALIGNED
-int misaligned_fixup(unsigned long address, struct pt_regs *regs,
-                    struct callee_regs *cregs);
-#else
-static inline int
-misaligned_fixup(unsigned long address, struct pt_regs *regs,
-                struct callee_regs *cregs)
-{
-       /* Not fixed */
-       return 1;
-}
-#endif
-
-#endif /* _ASM_ARC_UNALIGNED_H */
index a19751e824fb4c272e5cfa21ab3349210d30bfa7..8d2ea2cbd98b0f65d688e2dd150af7d2779d7176 100644 (file)
@@ -18,8 +18,9 @@
 #include <linux/kgdb.h>
 #include <asm/entry.h>
 #include <asm/setup.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include <asm/kprobes.h>
+#include "unaligned.h"
 
 void die(const char *str, struct pt_regs *regs, unsigned long address)
 {
index 99a9b92ed98d629e75783f71eef34f72d84800fd..d2f5ceaaed1b4a3c0ce4fced0aa3f59ffa97b451 100644 (file)
@@ -12,6 +12,7 @@
 #include <linux/ptrace.h>
 #include <linux/uaccess.h>
 #include <asm/disasm.h>
+#include "unaligned.h"
 
 #ifdef CONFIG_CPU_BIG_ENDIAN
 #define BE             1
diff --git a/arch/arc/kernel/unaligned.h b/arch/arc/kernel/unaligned.h
new file mode 100644 (file)
index 0000000..5244453
--- /dev/null
@@ -0,0 +1,16 @@
+struct pt_regs;
+struct callee_regs;
+
+#ifdef CONFIG_ARC_EMUL_UNALIGNED
+int misaligned_fixup(unsigned long address, struct pt_regs *regs,
+                    struct callee_regs *cregs);
+#else
+static inline int
+misaligned_fixup(unsigned long address, struct pt_regs *regs,
+                struct callee_regs *cregs)
+{
+       /* Not fixed */
+       return 1;
+}
+#endif
+
index 9270d0a713c31626e8787026472b0a0498545b47..d8969dab12d42d515a3bf53d763d268ca1a16134 100644 (file)
@@ -19,7 +19,7 @@
 #include <linux/uaccess.h>
 #include <linux/ptrace.h>
 #include <asm/sections.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include <asm/unwind.h>
 
 extern char __start_unwind[], __end_unwind[];
index 72d26d130efaa435f4255df3774d8a46a109c8cb..85f54fa595aa8fb7ae119528cc5e7fa7f8fd2d4d 100644 (file)
@@ -77,7 +77,7 @@
 };
 
 &hdmi {
-       hpd-gpios = <&expgpio 1 GPIO_ACTIVE_LOW>;
+       hpd-gpios = <&expgpio 0 GPIO_ACTIVE_LOW>;
        power-domains = <&power RPI_POWER_DOMAIN_HDMI>;
        status = "okay";
 };
index f5b66f4cf45d96eac9b2f3658ce8efced7f68008..21df5e7f51f9c96ef66c271c31cc5d1bd9192923 100644 (file)
@@ -8,7 +8,7 @@
 #include <asm/hwcap.h>
 #include <asm/neon.h>
 #include <asm/simd.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include <crypto/aes.h>
 #include <crypto/ctr.h>
 #include <crypto/internal/simd.h>
index 4ff18044af070bf7380b2d4c91b1bd8b650fa2fd..20b4dff13e3a66a6516410322361e68770fae8f5 100644 (file)
@@ -18,7 +18,7 @@
 #include <asm/hwcap.h>
 #include <asm/neon.h>
 #include <asm/simd.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #define PMULL_MIN_LEN          64L     /* minimum size of buffer
                                         * for crc32_pmull_le_16 */
index 3ddf05b4234d8e5c6540edf087906507769ac242..3af9970825340d93f9fea29e5cc5783ae7119c8d 100644 (file)
@@ -9,7 +9,7 @@
 #include <asm/hwcap.h>
 #include <asm/neon.h>
 #include <asm/simd.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include <crypto/aes.h>
 #include <crypto/gcm.h>
 #include <crypto/b128ops.h>
index 8482e302c45a441e31ed1ea8c47d8f42bd32c24d..4464ffbf8fd168428abd052b3a39f9a77c9595ba 100644 (file)
@@ -8,7 +8,7 @@
 #include <asm/hwcap.h>
 #include <asm/neon.h>
 #include <asm/simd.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include <crypto/algapi.h>
 #include <crypto/internal/hash.h>
 #include <crypto/internal/poly1305.h>
index c62ce89dd3e0d886f0aef109790502035256f346..aeac45bfbf9f1f624174dba8fd20c9f8a1b5a8e1 100644 (file)
@@ -16,7 +16,7 @@
 #include <asm/hwcap.h>
 #include <asm/simd.h>
 #include <asm/neon.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #include "sha256_glue.h"
 
index 6c9c16d767cfd5df81e5d45c2df23b1454070673..f90be312418e87b53ab99d6059617c121b85825e 100644 (file)
@@ -12,7 +12,7 @@
 #include <linux/string.h>
 #include <asm/page.h>
 #include <asm/domain.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include <asm/unified.h>
 #include <asm/pgtable.h>
 #include <asm/proc-fns.h>
index f8dd0b3cc8e040cb7cb737e10ae465c11882c913..3c6ddb1afdc463b393447969bfadb77eb99d3483 100644 (file)
@@ -22,7 +22,7 @@
 
 #include <asm/cp15.h>
 #include <asm/system_info.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include <asm/opcodes.h>
 
 #include "fault.h"
index 3e29b44d2d7bd693c6209383a67b8d0d14345406..fd9df6dcc5937208fe158ac8da9c4ede131d0fc7 100644 (file)
@@ -200,7 +200,8 @@ config ARM64
        select HAVE_DMA_CONTIGUOUS
        select HAVE_DYNAMIC_FTRACE
        select HAVE_DYNAMIC_FTRACE_WITH_ARGS \
-               if $(cc-option,-fpatchable-function-entry=2)
+               if (GCC_SUPPORTS_DYNAMIC_FTRACE_WITH_ARGS || \
+                   CLANG_SUPPORTS_DYNAMIC_FTRACE_WITH_ARGS)
        select HAVE_DYNAMIC_FTRACE_WITH_DIRECT_CALLS \
                if DYNAMIC_FTRACE_WITH_ARGS && DYNAMIC_FTRACE_WITH_CALL_OPS
        select HAVE_DYNAMIC_FTRACE_WITH_CALL_OPS \
@@ -286,12 +287,10 @@ config CLANG_SUPPORTS_DYNAMIC_FTRACE_WITH_ARGS
        def_bool CC_IS_CLANG
        # https://github.com/ClangBuiltLinux/linux/issues/1507
        depends on AS_IS_GNU || (AS_IS_LLVM && (LD_IS_LLD || LD_VERSION >= 23600))
-       select HAVE_DYNAMIC_FTRACE_WITH_ARGS
 
 config GCC_SUPPORTS_DYNAMIC_FTRACE_WITH_ARGS
        def_bool CC_IS_GCC
        depends on $(cc-option,-fpatchable-function-entry=2)
-       select HAVE_DYNAMIC_FTRACE_WITH_ARGS
 
 config 64BIT
        def_bool y
@@ -1097,6 +1096,7 @@ config ARM64_ERRATUM_3194386
          * ARM Cortex-A78C erratum 3324346
          * ARM Cortex-A78C erratum 3324347
          * ARM Cortex-A710 erratam 3324338
+         * ARM Cortex-A715 errartum 3456084
          * ARM Cortex-A720 erratum 3456091
          * ARM Cortex-A725 erratum 3456106
          * ARM Cortex-X1 erratum 3324344
@@ -1107,6 +1107,7 @@ config ARM64_ERRATUM_3194386
          * ARM Cortex-X925 erratum 3324334
          * ARM Neoverse-N1 erratum 3324349
          * ARM Neoverse N2 erratum 3324339
+         * ARM Neoverse-N3 erratum 3456111
          * ARM Neoverse-V1 erratum 3324341
          * ARM Neoverse V2 erratum 3324336
          * ARM Neoverse-V3 erratum 3312417
index b058c4803efb1c6d97d3e3ae1942abeef26cf330..9efd3f37c2fd9de155019f69cee1a0bb09e9a6dd 100644 (file)
@@ -10,7 +10,7 @@
 #
 # Copyright (C) 1995-2001 by Russell King
 
-LDFLAGS_vmlinux        :=--no-undefined -X
+LDFLAGS_vmlinux        :=--no-undefined -X --pic-veneer
 
 ifeq ($(CONFIG_RELOCATABLE), y)
 # Pass --no-apply-dynamic-relocs to restore pre-binutils-2.27 behaviour
index 4676e3488f54d53041696d877b510b8d51dcd984..cb8d54895a77753c760b58b8b5103149e21e2094 100644 (file)
                };
 
                cp0_mdio_pins: cp0-mdio-pins {
-                       marvell,pins = "mpp40", "mpp41";
+                       marvell,pins = "mpp0", "mpp1";
                        marvell,function = "ge";
                };
 
index ce9b28e3c7d63462c02827b177dc22633edb5474..a523b519700f518ef7b7887e4f94be3dcb729e07 100644 (file)
@@ -9,7 +9,7 @@
  */
 
 #include <asm/neon.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include <crypto/aes.h>
 #include <crypto/scatterwalk.h>
 #include <crypto/internal/aead.h>
index e921823ca103a4e4081282f88a68fb9dfd09b72d..00b8749013c5bf1a08985482597d5768b62eb012 100644 (file)
@@ -7,7 +7,7 @@
 
 #include <asm/neon.h>
 #include <asm/simd.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include <crypto/aes.h>
 #include <crypto/algapi.h>
 #include <crypto/internal/simd.h>
index 97331b454ea8619304d85287d2ea70b9247acc0b..da7b7ec1a664e128bd46b26589a032a32653224b 100644 (file)
@@ -7,7 +7,7 @@
 
 #include <asm/neon.h>
 #include <asm/simd.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include <crypto/aes.h>
 #include <crypto/gcm.h>
 #include <crypto/algapi.h>
index 9c4bfd62e789dc9d6e16ccf09c65e445b0244a7e..18883ea438f3c1ae66dd20dd9f2f661d52c90e54 100644 (file)
@@ -8,7 +8,7 @@
 #include <asm/hwcap.h>
 #include <asm/neon.h>
 #include <asm/simd.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include <crypto/algapi.h>
 #include <crypto/internal/hash.h>
 #include <crypto/internal/poly1305.h>
index 1dd93e1fcb39a276a7be635878986c907d63afaf..cbd14f208f8301a627b36813cace10662f5162f7 100644 (file)
@@ -7,7 +7,7 @@
 
 #include <asm/neon.h>
 #include <asm/simd.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include <crypto/internal/hash.h>
 #include <crypto/internal/simd.h>
 #include <crypto/sha1.h>
index 0a44d2e7ee1f7b1d5da894b6229a75c3a3c7bde4..6b4866a88ded1c3701882b40a5a0bf8c1e332013 100644 (file)
@@ -7,7 +7,7 @@
 
 #include <asm/neon.h>
 #include <asm/simd.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include <crypto/internal/hash.h>
 #include <crypto/internal/simd.h>
 #include <crypto/sha2.h>
index 250e1377c481b35f76b0ea092348536347af7648..5662c3ac49e91ccdbba250bc7a0835a84621c36e 100644 (file)
@@ -12,7 +12,7 @@
 #include <asm/hwcap.h>
 #include <asm/neon.h>
 #include <asm/simd.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include <crypto/internal/hash.h>
 #include <crypto/internal/simd.h>
 #include <crypto/sha3.h>
index f3431fc6231540724b82b5f0eb8441f4f53b4c61..071f6429322702581176d54bb6dd1f001eb80199 100644 (file)
@@ -11,7 +11,7 @@
 
 #include <asm/neon.h>
 #include <asm/simd.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include <crypto/internal/hash.h>
 #include <crypto/internal/simd.h>
 #include <crypto/sha2.h>
index 54bf6ebcfffb1567562af61f188c9bf6ccade166..1a71788c4cda5f35fae85c7da13d133f55912258 100644 (file)
@@ -7,7 +7,7 @@
 
 #include <asm/neon.h>
 #include <asm/simd.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include <crypto/internal/hash.h>
 #include <crypto/internal/simd.h>
 #include <crypto/sm3.h>
index 7182ee683f14ace6ea8c23ec9af0ab40fd3db97c..8dd71ce79b69bb937a096496dec66eb8b2b557ec 100644 (file)
@@ -7,7 +7,7 @@
 
 #include <asm/neon.h>
 #include <asm/simd.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include <crypto/internal/hash.h>
 #include <crypto/internal/simd.h>
 #include <crypto/sm3.h>
index 5a7dfeb8e8eb55da537605fd841cc50992009509..488f8e75134959f5263a61230dbde5192e8d4a58 100644 (file)
@@ -94,6 +94,7 @@
 #define ARM_CPU_PART_NEOVERSE_V3       0xD84
 #define ARM_CPU_PART_CORTEX_X925       0xD85
 #define ARM_CPU_PART_CORTEX_A725       0xD87
+#define ARM_CPU_PART_NEOVERSE_N3       0xD8E
 
 #define APM_CPU_PART_XGENE             0x000
 #define APM_CPU_VAR_POTENZA            0x00
 #define MIDR_NEOVERSE_V3 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_NEOVERSE_V3)
 #define MIDR_CORTEX_X925 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_X925)
 #define MIDR_CORTEX_A725 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A725)
+#define MIDR_NEOVERSE_N3 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_NEOVERSE_N3)
 #define MIDR_THUNDERX  MIDR_CPU_MODEL(ARM_CPU_IMP_CAVIUM, CAVIUM_CPU_PART_THUNDERX)
 #define MIDR_THUNDERX_81XX MIDR_CPU_MODEL(ARM_CPU_IMP_CAVIUM, CAVIUM_CPU_PART_THUNDERX_81XX)
 #define MIDR_THUNDERX_83XX MIDR_CPU_MODEL(ARM_CPU_IMP_CAVIUM, CAVIUM_CPU_PART_THUNDERX_83XX)
index b36a3b6cc01169d3e8554382da48e15cba7cbc3f..67afac659231ed648cf1042d885e1801afe91312 100644 (file)
@@ -178,6 +178,7 @@ struct kvm_nvhe_init_params {
        unsigned long hcr_el2;
        unsigned long vttbr;
        unsigned long vtcr;
+       unsigned long tmp;
 };
 
 /*
index 329619c6fa9611b474dc4823fccf01a3b9dd61a8..bf64fed9820ea0c53a315c6a6ec46a9eed71b74e 100644 (file)
@@ -51,6 +51,7 @@
 #define KVM_REQ_RELOAD_PMU     KVM_ARCH_REQ(5)
 #define KVM_REQ_SUSPEND                KVM_ARCH_REQ(6)
 #define KVM_REQ_RESYNC_PMU_EL0 KVM_ARCH_REQ(7)
+#define KVM_REQ_NESTED_S2_UNMAP        KVM_ARCH_REQ(8)
 
 #define KVM_DIRTY_LOG_MANUAL_CAPS   (KVM_DIRTY_LOG_MANUAL_PROTECT_ENABLE | \
                                     KVM_DIRTY_LOG_INITIALLY_SET)
@@ -211,6 +212,12 @@ struct kvm_s2_mmu {
         */
        bool    nested_stage2_enabled;
 
+       /*
+        * true when this MMU needs to be unmapped before being used for a new
+        * purpose.
+        */
+       bool    pending_unmap;
+
        /*
         *  0: Nobody is currently using this, check vttbr for validity
         * >0: Somebody is actively using this.
@@ -1441,11 +1448,6 @@ void kvm_set_vm_id_reg(struct kvm *kvm, u32 reg, u64 val);
                sign_extend64(__val, id##_##fld##_WIDTH - 1);           \
        })
 
-#define expand_field_sign(id, fld, val)                                        \
-       (id##_##fld##_SIGNED ?                                          \
-        __expand_field_sign_signed(id, fld, val) :                     \
-        __expand_field_sign_unsigned(id, fld, val))
-
 #define get_idreg_field_unsigned(kvm, id, fld)                         \
        ({                                                              \
                u64 __val = kvm_read_vm_id_reg((kvm), SYS_##id);        \
@@ -1461,20 +1463,26 @@ void kvm_set_vm_id_reg(struct kvm *kvm, u32 reg, u64 val);
 #define get_idreg_field_enum(kvm, id, fld)                             \
        get_idreg_field_unsigned(kvm, id, fld)
 
-#define get_idreg_field(kvm, id, fld)                                  \
+#define kvm_cmp_feat_signed(kvm, id, fld, op, limit)                   \
+       (get_idreg_field_signed((kvm), id, fld) op __expand_field_sign_signed(id, fld, limit))
+
+#define kvm_cmp_feat_unsigned(kvm, id, fld, op, limit)                 \
+       (get_idreg_field_unsigned((kvm), id, fld) op __expand_field_sign_unsigned(id, fld, limit))
+
+#define kvm_cmp_feat(kvm, id, fld, op, limit)                          \
        (id##_##fld##_SIGNED ?                                          \
-        get_idreg_field_signed(kvm, id, fld) :                         \
-        get_idreg_field_unsigned(kvm, id, fld))
+        kvm_cmp_feat_signed(kvm, id, fld, op, limit) :                 \
+        kvm_cmp_feat_unsigned(kvm, id, fld, op, limit))
 
 #define kvm_has_feat(kvm, id, fld, limit)                              \
-       (get_idreg_field((kvm), id, fld) >= expand_field_sign(id, fld, limit))
+       kvm_cmp_feat(kvm, id, fld, >=, limit)
 
 #define kvm_has_feat_enum(kvm, id, fld, val)                           \
-       (get_idreg_field_unsigned((kvm), id, fld) == __expand_field_sign_unsigned(id, fld, val))
+       kvm_cmp_feat_unsigned(kvm, id, fld, ==, val)
 
 #define kvm_has_feat_range(kvm, id, fld, min, max)                     \
-       (get_idreg_field((kvm), id, fld) >= expand_field_sign(id, fld, min) && \
-        get_idreg_field((kvm), id, fld) <= expand_field_sign(id, fld, max))
+       (kvm_cmp_feat(kvm, id, fld, >=, min) &&                         \
+       kvm_cmp_feat(kvm, id, fld, <=, max))
 
 /* Check for a given level of PAuth support */
 #define kvm_has_pauth(k, l)                                            \
index cd4087fbda9afea06d136abad7300d99d44fdeef..66d93e320ec8eec222e4fc43b99d414ef0a0eac1 100644 (file)
@@ -166,7 +166,8 @@ int create_hyp_exec_mappings(phys_addr_t phys_addr, size_t size,
 int create_hyp_stack(phys_addr_t phys_addr, unsigned long *haddr);
 void __init free_hyp_pgds(void);
 
-void kvm_stage2_unmap_range(struct kvm_s2_mmu *mmu, phys_addr_t start, u64 size);
+void kvm_stage2_unmap_range(struct kvm_s2_mmu *mmu, phys_addr_t start,
+                           u64 size, bool may_block);
 void kvm_stage2_flush_range(struct kvm_s2_mmu *mmu, phys_addr_t addr, phys_addr_t end);
 void kvm_stage2_wp_range(struct kvm_s2_mmu *mmu, phys_addr_t addr, phys_addr_t end);
 
index e8bc6d67aba2991657c628d6dd45b3e8b0769c7c..233e65522716441c95f2cf9ddbd56fc825e6bf72 100644 (file)
@@ -78,6 +78,8 @@ extern void kvm_s2_mmu_iterate_by_vmid(struct kvm *kvm, u16 vmid,
 extern void kvm_vcpu_load_hw_mmu(struct kvm_vcpu *vcpu);
 extern void kvm_vcpu_put_hw_mmu(struct kvm_vcpu *vcpu);
 
+extern void check_nested_vcpu_requests(struct kvm_vcpu *vcpu);
+
 struct kvm_s2_trans {
        phys_addr_t output;
        unsigned long block_size;
@@ -124,7 +126,7 @@ extern int kvm_s2_handle_perm_fault(struct kvm_vcpu *vcpu,
                                    struct kvm_s2_trans *trans);
 extern int kvm_inject_s2_fault(struct kvm_vcpu *vcpu, u64 esr_el2);
 extern void kvm_nested_s2_wp(struct kvm *kvm);
-extern void kvm_nested_s2_unmap(struct kvm *kvm);
+extern void kvm_nested_s2_unmap(struct kvm *kvm, bool may_block);
 extern void kvm_nested_s2_flush(struct kvm *kvm);
 
 unsigned long compute_tlb_inval_range(struct kvm_s2_mmu *mmu, u64 val);
index 2b09495499c6183a155e81b3fc33d13cb6e62012..014b02897f8e22a072fb3cfb9928d7afa655d4d6 100644 (file)
 #include <asm/insn.h>
 #include <asm/probes.h>
 
-#define MAX_UINSN_BYTES                AARCH64_INSN_SIZE
-
 #define UPROBE_SWBP_INSN       cpu_to_le32(BRK64_OPCODE_UPROBES)
 #define UPROBE_SWBP_INSN_SIZE  AARCH64_INSN_SIZE
-#define UPROBE_XOL_SLOT_BYTES  MAX_UINSN_BYTES
+#define UPROBE_XOL_SLOT_BYTES  AARCH64_INSN_SIZE
 
 typedef __le32 uprobe_opcode_t;
 
@@ -23,8 +21,8 @@ struct arch_uprobe_task {
 
 struct arch_uprobe {
        union {
-               u8 insn[MAX_UINSN_BYTES];
-               u8 ixol[MAX_UINSN_BYTES];
+               __le32 insn;
+               __le32 ixol;
        };
        struct arch_probe_insn api;
        bool simulate;
index 27de1dddb0abee1f6e9d760676a0ffdd0c9a2603..b21dd24b8efc3b07a8f05e4a4651031600e63e4b 100644 (file)
@@ -146,6 +146,7 @@ int main(void)
   DEFINE(NVHE_INIT_HCR_EL2,    offsetof(struct kvm_nvhe_init_params, hcr_el2));
   DEFINE(NVHE_INIT_VTTBR,      offsetof(struct kvm_nvhe_init_params, vttbr));
   DEFINE(NVHE_INIT_VTCR,       offsetof(struct kvm_nvhe_init_params, vtcr));
+  DEFINE(NVHE_INIT_TMP,                offsetof(struct kvm_nvhe_init_params, tmp));
 #endif
 #ifdef CONFIG_CPU_PM
   DEFINE(CPU_CTX_SP,           offsetof(struct cpu_suspend_ctx, sp));
index dfefbdf4073a6a22ced7d89e5a10f56f1bc61b89..a78f247029aec3be4e7dfdc31f9a0d3c4346f49f 100644 (file)
@@ -439,6 +439,7 @@ static const struct midr_range erratum_spec_ssbs_list[] = {
        MIDR_ALL_VERSIONS(MIDR_CORTEX_A78),
        MIDR_ALL_VERSIONS(MIDR_CORTEX_A78C),
        MIDR_ALL_VERSIONS(MIDR_CORTEX_A710),
+       MIDR_ALL_VERSIONS(MIDR_CORTEX_A715),
        MIDR_ALL_VERSIONS(MIDR_CORTEX_A720),
        MIDR_ALL_VERSIONS(MIDR_CORTEX_A725),
        MIDR_ALL_VERSIONS(MIDR_CORTEX_X1),
@@ -447,8 +448,10 @@ static const struct midr_range erratum_spec_ssbs_list[] = {
        MIDR_ALL_VERSIONS(MIDR_CORTEX_X3),
        MIDR_ALL_VERSIONS(MIDR_CORTEX_X4),
        MIDR_ALL_VERSIONS(MIDR_CORTEX_X925),
+       MIDR_ALL_VERSIONS(MIDR_MICROSOFT_AZURE_COBALT_100),
        MIDR_ALL_VERSIONS(MIDR_NEOVERSE_N1),
        MIDR_ALL_VERSIONS(MIDR_NEOVERSE_N2),
+       MIDR_ALL_VERSIONS(MIDR_NEOVERSE_N3),
        MIDR_ALL_VERSIONS(MIDR_NEOVERSE_V1),
        MIDR_ALL_VERSIONS(MIDR_NEOVERSE_V2),
        MIDR_ALL_VERSIONS(MIDR_NEOVERSE_V3),
index 968d5fffe2330202c731d5f6c022222db5b7a180..3496d6169e59b26ac89e4956f949f0b62661fad4 100644 (file)
@@ -99,10 +99,6 @@ arm_probe_decode_insn(probe_opcode_t insn, struct arch_probe_insn *api)
            aarch64_insn_is_blr(insn) ||
            aarch64_insn_is_ret(insn)) {
                api->handler = simulate_br_blr_ret;
-       } else if (aarch64_insn_is_ldr_lit(insn)) {
-               api->handler = simulate_ldr_literal;
-       } else if (aarch64_insn_is_ldrsw_lit(insn)) {
-               api->handler = simulate_ldrsw_literal;
        } else {
                /*
                 * Instruction cannot be stepped out-of-line and we don't
@@ -140,6 +136,17 @@ arm_kprobe_decode_insn(kprobe_opcode_t *addr, struct arch_specific_insn *asi)
        probe_opcode_t insn = le32_to_cpu(*addr);
        probe_opcode_t *scan_end = NULL;
        unsigned long size = 0, offset = 0;
+       struct arch_probe_insn *api = &asi->api;
+
+       if (aarch64_insn_is_ldr_lit(insn)) {
+               api->handler = simulate_ldr_literal;
+               decoded = INSN_GOOD_NO_SLOT;
+       } else if (aarch64_insn_is_ldrsw_lit(insn)) {
+               api->handler = simulate_ldrsw_literal;
+               decoded = INSN_GOOD_NO_SLOT;
+       } else {
+               decoded = arm_probe_decode_insn(insn, &asi->api);
+       }
 
        /*
         * If there's a symbol defined in front of and near enough to
@@ -157,7 +164,6 @@ arm_kprobe_decode_insn(kprobe_opcode_t *addr, struct arch_specific_insn *asi)
                else
                        scan_end = addr - MAX_ATOMIC_CONTEXT_SIZE;
        }
-       decoded = arm_probe_decode_insn(insn, &asi->api);
 
        if (decoded != INSN_REJECTED && scan_end)
                if (is_probed_address_atomic(addr - 1, scan_end))
index 22d0b32524763e11fe9ce8edee4929c9141504be..b65334ab79d2b0e9190f8349546ebe497c5e5b91 100644 (file)
@@ -171,17 +171,15 @@ simulate_tbz_tbnz(u32 opcode, long addr, struct pt_regs *regs)
 void __kprobes
 simulate_ldr_literal(u32 opcode, long addr, struct pt_regs *regs)
 {
-       u64 *load_addr;
+       unsigned long load_addr;
        int xn = opcode & 0x1f;
-       int disp;
 
-       disp = ldr_displacement(opcode);
-       load_addr = (u64 *) (addr + disp);
+       load_addr = addr + ldr_displacement(opcode);
 
        if (opcode & (1 << 30)) /* x0-x30 */
-               set_x_reg(regs, xn, *load_addr);
+               set_x_reg(regs, xn, READ_ONCE(*(u64 *)load_addr));
        else                    /* w0-w30 */
-               set_w_reg(regs, xn, *load_addr);
+               set_w_reg(regs, xn, READ_ONCE(*(u32 *)load_addr));
 
        instruction_pointer_set(regs, instruction_pointer(regs) + 4);
 }
@@ -189,14 +187,12 @@ simulate_ldr_literal(u32 opcode, long addr, struct pt_regs *regs)
 void __kprobes
 simulate_ldrsw_literal(u32 opcode, long addr, struct pt_regs *regs)
 {
-       s32 *load_addr;
+       unsigned long load_addr;
        int xn = opcode & 0x1f;
-       int disp;
 
-       disp = ldr_displacement(opcode);
-       load_addr = (s32 *) (addr + disp);
+       load_addr = addr + ldr_displacement(opcode);
 
-       set_x_reg(regs, xn, *load_addr);
+       set_x_reg(regs, xn, READ_ONCE(*(s32 *)load_addr));
 
        instruction_pointer_set(regs, instruction_pointer(regs) + 4);
 }
index d49aef2657cdf74311bbbb9f6e4415b92c114b3c..a2f137a595fc1c06b71a0965bbba441e8101d180 100644 (file)
@@ -42,7 +42,7 @@ int arch_uprobe_analyze_insn(struct arch_uprobe *auprobe, struct mm_struct *mm,
        else if (!IS_ALIGNED(addr, AARCH64_INSN_SIZE))
                return -EINVAL;
 
-       insn = *(probe_opcode_t *)(&auprobe->insn[0]);
+       insn = le32_to_cpu(auprobe->insn);
 
        switch (arm_probe_decode_insn(insn, &auprobe->api)) {
        case INSN_REJECTED:
@@ -108,7 +108,7 @@ bool arch_uprobe_skip_sstep(struct arch_uprobe *auprobe, struct pt_regs *regs)
        if (!auprobe->simulate)
                return false;
 
-       insn = *(probe_opcode_t *)(&auprobe->insn[0]);
+       insn = le32_to_cpu(auprobe->insn);
        addr = instruction_pointer(regs);
 
        if (auprobe->api.handler)
index 0540653fbf382bf8a0984a7e9f97cafbedc3251b..3e7c8c8195c3c964e51e34b72fc2b08a39c633a2 100644 (file)
@@ -412,6 +412,9 @@ int copy_thread(struct task_struct *p, const struct kernel_clone_args *args)
 
                p->thread.cpu_context.x19 = (unsigned long)args->fn;
                p->thread.cpu_context.x20 = (unsigned long)args->fn_arg;
+
+               if (system_supports_poe())
+                       p->thread.por_el0 = POR_EL0_INIT;
        }
        p->thread.cpu_context.pc = (unsigned long)ret_from_fork;
        p->thread.cpu_context.sp = (unsigned long)childregs;
index 5619869475304776fc005fe24a385bf86bfdd253..c7d311d8b92a2eeac1b0524b226a926e4fe79b46 100644 (file)
@@ -19,6 +19,7 @@
 #include <linux/ratelimit.h>
 #include <linux/rseq.h>
 #include <linux/syscalls.h>
+#include <linux/pkeys.h>
 
 #include <asm/daifflags.h>
 #include <asm/debug-monitors.h>
@@ -66,10 +67,63 @@ struct rt_sigframe_user_layout {
        unsigned long end_offset;
 };
 
+/*
+ * Holds any EL0-controlled state that influences unprivileged memory accesses.
+ * This includes both accesses done in userspace and uaccess done in the kernel.
+ *
+ * This state needs to be carefully managed to ensure that it doesn't cause
+ * uaccess to fail when setting up the signal frame, and the signal handler
+ * itself also expects a well-defined state when entered.
+ */
+struct user_access_state {
+       u64 por_el0;
+};
+
 #define BASE_SIGFRAME_SIZE round_up(sizeof(struct rt_sigframe), 16)
 #define TERMINATOR_SIZE round_up(sizeof(struct _aarch64_ctx), 16)
 #define EXTRA_CONTEXT_SIZE round_up(sizeof(struct extra_context), 16)
 
+/*
+ * Save the user access state into ua_state and reset it to disable any
+ * restrictions.
+ */
+static void save_reset_user_access_state(struct user_access_state *ua_state)
+{
+       if (system_supports_poe()) {
+               u64 por_enable_all = 0;
+
+               for (int pkey = 0; pkey < arch_max_pkey(); pkey++)
+                       por_enable_all |= POE_RXW << (pkey * POR_BITS_PER_PKEY);
+
+               ua_state->por_el0 = read_sysreg_s(SYS_POR_EL0);
+               write_sysreg_s(por_enable_all, SYS_POR_EL0);
+               /* Ensure that any subsequent uaccess observes the updated value */
+               isb();
+       }
+}
+
+/*
+ * Set the user access state for invoking the signal handler.
+ *
+ * No uaccess should be done after that function is called.
+ */
+static void set_handler_user_access_state(void)
+{
+       if (system_supports_poe())
+               write_sysreg_s(POR_EL0_INIT, SYS_POR_EL0);
+}
+
+/*
+ * Restore the user access state to the values saved in ua_state.
+ *
+ * No uaccess should be done after that function is called.
+ */
+static void restore_user_access_state(const struct user_access_state *ua_state)
+{
+       if (system_supports_poe())
+               write_sysreg_s(ua_state->por_el0, SYS_POR_EL0);
+}
+
 static void init_user_layout(struct rt_sigframe_user_layout *user)
 {
        const size_t reserved_size =
@@ -261,18 +315,20 @@ static int restore_fpmr_context(struct user_ctxs *user)
        return err;
 }
 
-static int preserve_poe_context(struct poe_context __user *ctx)
+static int preserve_poe_context(struct poe_context __user *ctx,
+                               const struct user_access_state *ua_state)
 {
        int err = 0;
 
        __put_user_error(POE_MAGIC, &ctx->head.magic, err);
        __put_user_error(sizeof(*ctx), &ctx->head.size, err);
-       __put_user_error(read_sysreg_s(SYS_POR_EL0), &ctx->por_el0, err);
+       __put_user_error(ua_state->por_el0, &ctx->por_el0, err);
 
        return err;
 }
 
-static int restore_poe_context(struct user_ctxs *user)
+static int restore_poe_context(struct user_ctxs *user,
+                              struct user_access_state *ua_state)
 {
        u64 por_el0;
        int err = 0;
@@ -282,7 +338,7 @@ static int restore_poe_context(struct user_ctxs *user)
 
        __get_user_error(por_el0, &(user->poe->por_el0), err);
        if (!err)
-               write_sysreg_s(por_el0, SYS_POR_EL0);
+               ua_state->por_el0 = por_el0;
 
        return err;
 }
@@ -850,7 +906,8 @@ invalid:
 }
 
 static int restore_sigframe(struct pt_regs *regs,
-                           struct rt_sigframe __user *sf)
+                           struct rt_sigframe __user *sf,
+                           struct user_access_state *ua_state)
 {
        sigset_t set;
        int i, err;
@@ -899,7 +956,7 @@ static int restore_sigframe(struct pt_regs *regs,
                err = restore_zt_context(&user);
 
        if (err == 0 && system_supports_poe() && user.poe)
-               err = restore_poe_context(&user);
+               err = restore_poe_context(&user, ua_state);
 
        return err;
 }
@@ -908,6 +965,7 @@ SYSCALL_DEFINE0(rt_sigreturn)
 {
        struct pt_regs *regs = current_pt_regs();
        struct rt_sigframe __user *frame;
+       struct user_access_state ua_state;
 
        /* Always make any pending restarted system calls return -EINTR */
        current->restart_block.fn = do_no_restart_syscall;
@@ -924,12 +982,14 @@ SYSCALL_DEFINE0(rt_sigreturn)
        if (!access_ok(frame, sizeof (*frame)))
                goto badframe;
 
-       if (restore_sigframe(regs, frame))
+       if (restore_sigframe(regs, frame, &ua_state))
                goto badframe;
 
        if (restore_altstack(&frame->uc.uc_stack))
                goto badframe;
 
+       restore_user_access_state(&ua_state);
+
        return regs->regs[0];
 
 badframe:
@@ -1035,7 +1095,8 @@ static int setup_sigframe_layout(struct rt_sigframe_user_layout *user,
 }
 
 static int setup_sigframe(struct rt_sigframe_user_layout *user,
-                         struct pt_regs *regs, sigset_t *set)
+                         struct pt_regs *regs, sigset_t *set,
+                         const struct user_access_state *ua_state)
 {
        int i, err = 0;
        struct rt_sigframe __user *sf = user->sigframe;
@@ -1097,10 +1158,9 @@ static int setup_sigframe(struct rt_sigframe_user_layout *user,
                struct poe_context __user *poe_ctx =
                        apply_user_offset(user, user->poe_offset);
 
-               err |= preserve_poe_context(poe_ctx);
+               err |= preserve_poe_context(poe_ctx, ua_state);
        }
 
-
        /* ZA state if present */
        if (system_supports_sme() && err == 0 && user->za_offset) {
                struct za_context __user *za_ctx =
@@ -1237,9 +1297,6 @@ static void setup_return(struct pt_regs *regs, struct k_sigaction *ka,
                sme_smstop();
        }
 
-       if (system_supports_poe())
-               write_sysreg_s(POR_EL0_INIT, SYS_POR_EL0);
-
        if (ka->sa.sa_flags & SA_RESTORER)
                sigtramp = ka->sa.sa_restorer;
        else
@@ -1253,6 +1310,7 @@ static int setup_rt_frame(int usig, struct ksignal *ksig, sigset_t *set,
 {
        struct rt_sigframe_user_layout user;
        struct rt_sigframe __user *frame;
+       struct user_access_state ua_state;
        int err = 0;
 
        fpsimd_signal_preserve_current_state();
@@ -1260,13 +1318,14 @@ static int setup_rt_frame(int usig, struct ksignal *ksig, sigset_t *set,
        if (get_sigframe(&user, ksig, regs))
                return 1;
 
+       save_reset_user_access_state(&ua_state);
        frame = user.sigframe;
 
        __put_user_error(0, &frame->uc.uc_flags, err);
        __put_user_error(NULL, &frame->uc.uc_link, err);
 
        err |= __save_altstack(&frame->uc.uc_stack, regs->sp);
-       err |= setup_sigframe(&user, regs, set);
+       err |= setup_sigframe(&user, regs, set, &ua_state);
        if (err == 0) {
                setup_return(regs, &ksig->ka, &user, usig);
                if (ksig->ka.sa.sa_flags & SA_SIGINFO) {
@@ -1276,6 +1335,11 @@ static int setup_rt_frame(int usig, struct ksignal *ksig, sigset_t *set,
                }
        }
 
+       if (err == 0)
+               set_handler_user_access_state();
+       else
+               restore_user_access_state(&ua_state);
+
        return err;
 }
 
index a0d01c46e40845b8936b82638eb8010e2b23fe68..48cafb65d6acff5610da0851633865697ba9a132 100644 (file)
@@ -997,6 +997,9 @@ static int kvm_vcpu_suspend(struct kvm_vcpu *vcpu)
 static int check_vcpu_requests(struct kvm_vcpu *vcpu)
 {
        if (kvm_request_pending(vcpu)) {
+               if (kvm_check_request(KVM_REQ_VM_DEAD, vcpu))
+                       return -EIO;
+
                if (kvm_check_request(KVM_REQ_SLEEP, vcpu))
                        kvm_vcpu_sleep(vcpu);
 
@@ -1031,6 +1034,8 @@ static int check_vcpu_requests(struct kvm_vcpu *vcpu)
 
                if (kvm_dirty_ring_check_request(vcpu))
                        return 0;
+
+               check_nested_vcpu_requests(vcpu);
        }
 
        return 1;
index 46d52e8a3df3a3917e33976e0c34f597f8936a6e..5310fe1da6165bcdedfb5ce61bce353e4c9dd58b 100644 (file)
@@ -338,7 +338,7 @@ static inline void __hyp_sve_save_host(void)
        struct cpu_sve_state *sve_state = *host_data_ptr(sve_state);
 
        sve_state->zcr_el1 = read_sysreg_el1(SYS_ZCR);
-       write_sysreg_s(ZCR_ELx_LEN_MASK, SYS_ZCR_EL2);
+       write_sysreg_s(sve_vq_from_vl(kvm_host_sve_max_vl) - 1, SYS_ZCR_EL2);
        __sve_save_state(sve_state->sve_regs + sve_ffr_offset(kvm_host_sve_max_vl),
                         &sve_state->fpsr,
                         true);
index 401af1835be6b7ae6f099ad7059d278aa3996cf4..fc18662260676712d3f75fc68f652a6cb4b6474a 100644 (file)
        .align  11
 
 SYM_CODE_START(__kvm_hyp_init)
-       ventry  __invalid               // Synchronous EL2t
-       ventry  __invalid               // IRQ EL2t
-       ventry  __invalid               // FIQ EL2t
-       ventry  __invalid               // Error EL2t
+       ventry  .                       // Synchronous EL2t
+       ventry  .                       // IRQ EL2t
+       ventry  .                       // FIQ EL2t
+       ventry  .                       // Error EL2t
 
-       ventry  __invalid               // Synchronous EL2h
-       ventry  __invalid               // IRQ EL2h
-       ventry  __invalid               // FIQ EL2h
-       ventry  __invalid               // Error EL2h
+       ventry  .                       // Synchronous EL2h
+       ventry  .                       // IRQ EL2h
+       ventry  .                       // FIQ EL2h
+       ventry  .                       // Error EL2h
 
        ventry  __do_hyp_init           // Synchronous 64-bit EL1
-       ventry  __invalid               // IRQ 64-bit EL1
-       ventry  __invalid               // FIQ 64-bit EL1
-       ventry  __invalid               // Error 64-bit EL1
+       ventry  .                       // IRQ 64-bit EL1
+       ventry  .                       // FIQ 64-bit EL1
+       ventry  .                       // Error 64-bit EL1
 
-       ventry  __invalid               // Synchronous 32-bit EL1
-       ventry  __invalid               // IRQ 32-bit EL1
-       ventry  __invalid               // FIQ 32-bit EL1
-       ventry  __invalid               // Error 32-bit EL1
-
-__invalid:
-       b       .
+       ventry  .                       // Synchronous 32-bit EL1
+       ventry  .                       // IRQ 32-bit EL1
+       ventry  .                       // FIQ 32-bit EL1
+       ventry  .                       // Error 32-bit EL1
 
        /*
         * Only uses x0..x3 so as to not clobber callee-saved SMCCC registers.
@@ -76,6 +73,13 @@ __do_hyp_init:
        eret
 SYM_CODE_END(__kvm_hyp_init)
 
+SYM_CODE_START_LOCAL(__kvm_init_el2_state)
+       /* Initialize EL2 CPU state to sane values. */
+       init_el2_state                          // Clobbers x0..x2
+       finalise_el2_state
+       ret
+SYM_CODE_END(__kvm_init_el2_state)
+
 /*
  * Initialize the hypervisor in EL2.
  *
@@ -102,9 +106,12 @@ SYM_CODE_START_LOCAL(___kvm_hyp_init)
        // TPIDR_EL2 is used to preserve x0 across the macro maze...
        isb
        msr     tpidr_el2, x0
-       init_el2_state
-       finalise_el2_state
+       str     lr, [x0, #NVHE_INIT_TMP]
+
+       bl      __kvm_init_el2_state
+
        mrs     x0, tpidr_el2
+       ldr     lr, [x0, #NVHE_INIT_TMP]
 
 1:
        ldr     x1, [x0, #NVHE_INIT_TPIDR_EL2]
@@ -199,9 +206,8 @@ SYM_CODE_START_LOCAL(__kvm_hyp_init_cpu)
 
 2:     msr     SPsel, #1                       // We want to use SP_EL{1,2}
 
-       /* Initialize EL2 CPU state to sane values. */
-       init_el2_state                          // Clobbers x0..x2
-       finalise_el2_state
+       bl      __kvm_init_el2_state
+
        __init_el2_nvhe_prepare_eret
 
        /* Enable MMU, set vectors and stack. */
index 87692b566d90d1e5bcd97b6ebb627f632df57cb7..fefc89209f9e41c95478f6770881eb314a38b4c2 100644 (file)
@@ -33,7 +33,7 @@ static void __hyp_sve_save_guest(struct kvm_vcpu *vcpu)
         */
        sve_cond_update_zcr_vq(vcpu_sve_max_vq(vcpu) - 1, SYS_ZCR_EL2);
        __sve_save_state(vcpu_sve_pffr(vcpu), &vcpu->arch.ctxt.fp_regs.fpsr, true);
-       write_sysreg_s(ZCR_ELx_LEN_MASK, SYS_ZCR_EL2);
+       write_sysreg_s(sve_vq_from_vl(kvm_host_sve_max_vl) - 1, SYS_ZCR_EL2);
 }
 
 static void __hyp_sve_restore_host(void)
@@ -45,10 +45,11 @@ static void __hyp_sve_restore_host(void)
         * the host. The layout of the data when saving the sve state depends
         * on the VL, so use a consistent (i.e., the maximum) host VL.
         *
-        * Setting ZCR_EL2 to ZCR_ELx_LEN_MASK sets the effective length
-        * supported by the system (or limited at EL3).
+        * Note that this constrains the PE to the maximum shared VL
+        * that was discovered, if we wish to use larger VLs this will
+        * need to be revisited.
         */
-       write_sysreg_s(ZCR_ELx_LEN_MASK, SYS_ZCR_EL2);
+       write_sysreg_s(sve_vq_from_vl(kvm_host_sve_max_vl) - 1, SYS_ZCR_EL2);
        __sve_restore_state(sve_state->sve_regs + sve_ffr_offset(kvm_host_sve_max_vl),
                            &sve_state->fpsr,
                            true);
@@ -488,7 +489,8 @@ void handle_trap(struct kvm_cpu_context *host_ctxt)
        case ESR_ELx_EC_SVE:
                cpacr_clear_set(0, CPACR_ELx_ZEN);
                isb();
-               sve_cond_update_zcr_vq(ZCR_ELx_LEN_MASK, SYS_ZCR_EL2);
+               sve_cond_update_zcr_vq(sve_vq_from_vl(kvm_host_sve_max_vl) - 1,
+                                      SYS_ZCR_EL2);
                break;
        case ESR_ELx_EC_IABT_LOW:
        case ESR_ELx_EC_DABT_LOW:
index 187a5f4d56c0c61c5f46afa39383c5c6a3557e07..077d4098548d2c87abdd3931285d87798d63adb3 100644 (file)
@@ -574,12 +574,14 @@ int __pkvm_init_vcpu(pkvm_handle_t handle, struct kvm_vcpu *host_vcpu,
 unlock:
        hyp_spin_unlock(&vm_table_lock);
 
-       if (ret)
+       if (ret) {
                unmap_donated_memory(hyp_vcpu, sizeof(*hyp_vcpu));
+               return ret;
+       }
 
        hyp_vcpu->vcpu.arch.cptr_el2 = kvm_get_reset_cptr_el2(&hyp_vcpu->vcpu);
 
-       return ret;
+       return 0;
 }
 
 static void
index 5763d979d8cae00ac206a6f80f10c2d36f86bdac..ee6573befb8134eb6528d3eba4180b193c1c155f 100644 (file)
@@ -317,7 +317,7 @@ int kvm_smccc_call_handler(struct kvm_vcpu *vcpu)
                                 * to the guest, and hide SSBS so that the
                                 * guest stays protected.
                                 */
-                               if (cpus_have_final_cap(ARM64_SSBS))
+                               if (kvm_has_feat(vcpu->kvm, ID_AA64PFR1_EL1, SSBS, IMP))
                                        break;
                                fallthrough;
                        case SPECTRE_UNAFFECTED:
@@ -428,7 +428,7 @@ int kvm_arm_copy_fw_reg_indices(struct kvm_vcpu *vcpu, u64 __user *uindices)
  * Convert the workaround level into an easy-to-compare number, where higher
  * values mean better protection.
  */
-static int get_kernel_wa_level(u64 regid)
+static int get_kernel_wa_level(struct kvm_vcpu *vcpu, u64 regid)
 {
        switch (regid) {
        case KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_1:
@@ -449,7 +449,7 @@ static int get_kernel_wa_level(u64 regid)
                         * don't have any FW mitigation if SSBS is there at
                         * all times.
                         */
-                       if (cpus_have_final_cap(ARM64_SSBS))
+                       if (kvm_has_feat(vcpu->kvm, ID_AA64PFR1_EL1, SSBS, IMP))
                                return KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_2_NOT_AVAIL;
                        fallthrough;
                case SPECTRE_UNAFFECTED:
@@ -486,7 +486,7 @@ int kvm_arm_get_fw_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg)
        case KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_1:
        case KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_2:
        case KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_3:
-               val = get_kernel_wa_level(reg->id) & KVM_REG_FEATURE_LEVEL_MASK;
+               val = get_kernel_wa_level(vcpu, reg->id) & KVM_REG_FEATURE_LEVEL_MASK;
                break;
        case KVM_REG_ARM_STD_BMAP:
                val = READ_ONCE(smccc_feat->std_bmap);
@@ -588,7 +588,7 @@ int kvm_arm_set_fw_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg)
                if (val & ~KVM_REG_FEATURE_LEVEL_MASK)
                        return -EINVAL;
 
-               if (get_kernel_wa_level(reg->id) < val)
+               if (get_kernel_wa_level(vcpu, reg->id) < val)
                        return -EINVAL;
 
                return 0;
@@ -624,7 +624,7 @@ int kvm_arm_set_fw_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg)
                 * We can deal with NOT_AVAIL on NOT_REQUIRED, but not the
                 * other way around.
                 */
-               if (get_kernel_wa_level(reg->id) < wa_level)
+               if (get_kernel_wa_level(vcpu, reg->id) < wa_level)
                        return -EINVAL;
 
                return 0;
index a509b63bd4dd50d462e779f5511e6b06687cf73a..0f7658aefa1a3ddb0ee5a5e6a6cc25857d80b9c6 100644 (file)
@@ -328,9 +328,10 @@ static void __unmap_stage2_range(struct kvm_s2_mmu *mmu, phys_addr_t start, u64
                                   may_block));
 }
 
-void kvm_stage2_unmap_range(struct kvm_s2_mmu *mmu, phys_addr_t start, u64 size)
+void kvm_stage2_unmap_range(struct kvm_s2_mmu *mmu, phys_addr_t start,
+                           u64 size, bool may_block)
 {
-       __unmap_stage2_range(mmu, start, size, true);
+       __unmap_stage2_range(mmu, start, size, may_block);
 }
 
 void kvm_stage2_flush_range(struct kvm_s2_mmu *mmu, phys_addr_t addr, phys_addr_t end)
@@ -1015,7 +1016,7 @@ static void stage2_unmap_memslot(struct kvm *kvm,
 
                if (!(vma->vm_flags & VM_PFNMAP)) {
                        gpa_t gpa = addr + (vm_start - memslot->userspace_addr);
-                       kvm_stage2_unmap_range(&kvm->arch.mmu, gpa, vm_end - vm_start);
+                       kvm_stage2_unmap_range(&kvm->arch.mmu, gpa, vm_end - vm_start, true);
                }
                hva = vm_end;
        } while (hva < reg_end);
@@ -1042,7 +1043,7 @@ void stage2_unmap_vm(struct kvm *kvm)
        kvm_for_each_memslot(memslot, bkt, slots)
                stage2_unmap_memslot(kvm, memslot);
 
-       kvm_nested_s2_unmap(kvm);
+       kvm_nested_s2_unmap(kvm, true);
 
        write_unlock(&kvm->mmu_lock);
        mmap_read_unlock(current->mm);
@@ -1912,7 +1913,7 @@ bool kvm_unmap_gfn_range(struct kvm *kvm, struct kvm_gfn_range *range)
                             (range->end - range->start) << PAGE_SHIFT,
                             range->may_block);
 
-       kvm_nested_s2_unmap(kvm);
+       kvm_nested_s2_unmap(kvm, range->may_block);
        return false;
 }
 
@@ -2179,8 +2180,8 @@ void kvm_arch_flush_shadow_memslot(struct kvm *kvm,
        phys_addr_t size = slot->npages << PAGE_SHIFT;
 
        write_lock(&kvm->mmu_lock);
-       kvm_stage2_unmap_range(&kvm->arch.mmu, gpa, size);
-       kvm_nested_s2_unmap(kvm);
+       kvm_stage2_unmap_range(&kvm->arch.mmu, gpa, size, true);
+       kvm_nested_s2_unmap(kvm, true);
        write_unlock(&kvm->mmu_lock);
 }
 
index f9e30dd34c7a180ada88fc7bfc4426a5a7e26472..c4b17d90fc49d6d829b2876704f8186975e9e42f 100644 (file)
@@ -632,9 +632,9 @@ static struct kvm_s2_mmu *get_s2_mmu_nested(struct kvm_vcpu *vcpu)
        /* Set the scene for the next search */
        kvm->arch.nested_mmus_next = (i + 1) % kvm->arch.nested_mmus_size;
 
-       /* Clear the old state */
+       /* Make sure we don't forget to do the laundry */
        if (kvm_s2_mmu_valid(s2_mmu))
-               kvm_stage2_unmap_range(s2_mmu, 0, kvm_phys_size(s2_mmu));
+               s2_mmu->pending_unmap = true;
 
        /*
         * The virtual VMID (modulo CnP) will be used as a key when matching
@@ -650,6 +650,16 @@ static struct kvm_s2_mmu *get_s2_mmu_nested(struct kvm_vcpu *vcpu)
 
 out:
        atomic_inc(&s2_mmu->refcnt);
+
+       /*
+        * Set the vCPU request to perform an unmap, even if the pending unmap
+        * originates from another vCPU. This guarantees that the MMU has been
+        * completely unmapped before any vCPU actually uses it, and allows
+        * multiple vCPUs to lend a hand with completing the unmap.
+        */
+       if (s2_mmu->pending_unmap)
+               kvm_make_request(KVM_REQ_NESTED_S2_UNMAP, vcpu);
+
        return s2_mmu;
 }
 
@@ -663,6 +673,13 @@ void kvm_init_nested_s2_mmu(struct kvm_s2_mmu *mmu)
 
 void kvm_vcpu_load_hw_mmu(struct kvm_vcpu *vcpu)
 {
+       /*
+        * The vCPU kept its reference on the MMU after the last put, keep
+        * rolling with it.
+        */
+       if (vcpu->arch.hw_mmu)
+               return;
+
        if (is_hyp_ctxt(vcpu)) {
                vcpu->arch.hw_mmu = &vcpu->kvm->arch.mmu;
        } else {
@@ -674,10 +691,18 @@ void kvm_vcpu_load_hw_mmu(struct kvm_vcpu *vcpu)
 
 void kvm_vcpu_put_hw_mmu(struct kvm_vcpu *vcpu)
 {
-       if (kvm_is_nested_s2_mmu(vcpu->kvm, vcpu->arch.hw_mmu)) {
+       /*
+        * Keep a reference on the associated stage-2 MMU if the vCPU is
+        * scheduling out and not in WFI emulation, suggesting it is likely to
+        * reuse the MMU sometime soon.
+        */
+       if (vcpu->scheduled_out && !vcpu_get_flag(vcpu, IN_WFI))
+               return;
+
+       if (kvm_is_nested_s2_mmu(vcpu->kvm, vcpu->arch.hw_mmu))
                atomic_dec(&vcpu->arch.hw_mmu->refcnt);
-               vcpu->arch.hw_mmu = NULL;
-       }
+
+       vcpu->arch.hw_mmu = NULL;
 }
 
 /*
@@ -730,7 +755,7 @@ void kvm_nested_s2_wp(struct kvm *kvm)
        }
 }
 
-void kvm_nested_s2_unmap(struct kvm *kvm)
+void kvm_nested_s2_unmap(struct kvm *kvm, bool may_block)
 {
        int i;
 
@@ -740,7 +765,7 @@ void kvm_nested_s2_unmap(struct kvm *kvm)
                struct kvm_s2_mmu *mmu = &kvm->arch.nested_mmus[i];
 
                if (kvm_s2_mmu_valid(mmu))
-                       kvm_stage2_unmap_range(mmu, 0, kvm_phys_size(mmu));
+                       kvm_stage2_unmap_range(mmu, 0, kvm_phys_size(mmu), may_block);
        }
 }
 
@@ -1184,3 +1209,17 @@ int kvm_init_nv_sysregs(struct kvm *kvm)
 
        return 0;
 }
+
+void check_nested_vcpu_requests(struct kvm_vcpu *vcpu)
+{
+       if (kvm_check_request(KVM_REQ_NESTED_S2_UNMAP, vcpu)) {
+               struct kvm_s2_mmu *mmu = vcpu->arch.hw_mmu;
+
+               write_lock(&vcpu->kvm->mmu_lock);
+               if (mmu->pending_unmap) {
+                       kvm_stage2_unmap_range(mmu, 0, kvm_phys_size(mmu), true);
+                       mmu->pending_unmap = false;
+               }
+               write_unlock(&vcpu->kvm->mmu_lock);
+       }
+}
index dad88e31f9537fe02e28b117d6a740f15572e0ba..ff8c4e1b847ed417c5695b8b4c292b8144b558c5 100644 (file)
@@ -1527,6 +1527,14 @@ static u64 __kvm_read_sanitised_id_reg(const struct kvm_vcpu *vcpu,
                        val &= ~ARM64_FEATURE_MASK(ID_AA64PFR1_EL1_MTE);
 
                val &= ~ARM64_FEATURE_MASK(ID_AA64PFR1_EL1_SME);
+               val &= ~ARM64_FEATURE_MASK(ID_AA64PFR1_EL1_RNDR_trap);
+               val &= ~ARM64_FEATURE_MASK(ID_AA64PFR1_EL1_NMI);
+               val &= ~ARM64_FEATURE_MASK(ID_AA64PFR1_EL1_MTE_frac);
+               val &= ~ARM64_FEATURE_MASK(ID_AA64PFR1_EL1_GCS);
+               val &= ~ARM64_FEATURE_MASK(ID_AA64PFR1_EL1_THE);
+               val &= ~ARM64_FEATURE_MASK(ID_AA64PFR1_EL1_MTEX);
+               val &= ~ARM64_FEATURE_MASK(ID_AA64PFR1_EL1_DF2);
+               val &= ~ARM64_FEATURE_MASK(ID_AA64PFR1_EL1_PFAR);
                break;
        case SYS_ID_AA64PFR2_EL1:
                /* We only expose FPMR */
@@ -1550,7 +1558,8 @@ static u64 __kvm_read_sanitised_id_reg(const struct kvm_vcpu *vcpu,
                val &= ~ID_AA64MMFR2_EL1_CCIDX_MASK;
                break;
        case SYS_ID_AA64MMFR3_EL1:
-               val &= ID_AA64MMFR3_EL1_TCRX | ID_AA64MMFR3_EL1_S1POE;
+               val &= ID_AA64MMFR3_EL1_TCRX | ID_AA64MMFR3_EL1_S1POE |
+                       ID_AA64MMFR3_EL1_S1PIE;
                break;
        case SYS_ID_MMFR4_EL1:
                val &= ~ARM64_FEATURE_MASK(ID_MMFR4_EL1_CCIDX);
@@ -1985,7 +1994,7 @@ static u64 reset_clidr(struct kvm_vcpu *vcpu, const struct sys_reg_desc *r)
         * one cache line.
         */
        if (kvm_has_mte(vcpu->kvm))
-               clidr |= 2 << CLIDR_TTYPE_SHIFT(loc);
+               clidr |= 2ULL << CLIDR_TTYPE_SHIFT(loc);
 
        __vcpu_sys_reg(vcpu, r->reg) = clidr;
 
@@ -2376,7 +2385,19 @@ static const struct sys_reg_desc sys_reg_descs[] = {
                   ID_AA64PFR0_EL1_RAS |
                   ID_AA64PFR0_EL1_AdvSIMD |
                   ID_AA64PFR0_EL1_FP), },
-       ID_SANITISED(ID_AA64PFR1_EL1),
+       ID_WRITABLE(ID_AA64PFR1_EL1, ~(ID_AA64PFR1_EL1_PFAR |
+                                      ID_AA64PFR1_EL1_DF2 |
+                                      ID_AA64PFR1_EL1_MTEX |
+                                      ID_AA64PFR1_EL1_THE |
+                                      ID_AA64PFR1_EL1_GCS |
+                                      ID_AA64PFR1_EL1_MTE_frac |
+                                      ID_AA64PFR1_EL1_NMI |
+                                      ID_AA64PFR1_EL1_RNDR_trap |
+                                      ID_AA64PFR1_EL1_SME |
+                                      ID_AA64PFR1_EL1_RES0 |
+                                      ID_AA64PFR1_EL1_MPAM_frac |
+                                      ID_AA64PFR1_EL1_RAS_frac |
+                                      ID_AA64PFR1_EL1_MTE)),
        ID_WRITABLE(ID_AA64PFR2_EL1, ID_AA64PFR2_EL1_FPMR),
        ID_UNALLOCATED(4,3),
        ID_WRITABLE(ID_AA64ZFR0_EL1, ~ID_AA64ZFR0_EL1_RES0),
@@ -2390,7 +2411,21 @@ static const struct sys_reg_desc sys_reg_descs[] = {
          .get_user = get_id_reg,
          .set_user = set_id_aa64dfr0_el1,
          .reset = read_sanitised_id_aa64dfr0_el1,
-         .val = ID_AA64DFR0_EL1_PMUVer_MASK |
+       /*
+        * Prior to FEAT_Debugv8.9, the architecture defines context-aware
+        * breakpoints (CTX_CMPs) as the highest numbered breakpoints (BRPs).
+        * KVM does not trap + emulate the breakpoint registers, and as such
+        * cannot support a layout that misaligns with the underlying hardware.
+        * While it may be possible to describe a subset that aligns with
+        * hardware, just prevent changes to BRPs and CTX_CMPs altogether for
+        * simplicity.
+        *
+        * See DDI0487K.a, section D2.8.3 Breakpoint types and linking
+        * of breakpoints for more details.
+        */
+         .val = ID_AA64DFR0_EL1_DoubleLock_MASK |
+                ID_AA64DFR0_EL1_WRPs_MASK |
+                ID_AA64DFR0_EL1_PMUVer_MASK |
                 ID_AA64DFR0_EL1_DebugVer_MASK, },
        ID_SANITISED(ID_AA64DFR1_EL1),
        ID_UNALLOCATED(5,2),
@@ -2433,6 +2468,7 @@ static const struct sys_reg_desc sys_reg_descs[] = {
                                        ID_AA64MMFR2_EL1_NV |
                                        ID_AA64MMFR2_EL1_CCIDX)),
        ID_WRITABLE(ID_AA64MMFR3_EL1, (ID_AA64MMFR3_EL1_TCRX    |
+                                      ID_AA64MMFR3_EL1_S1PIE   |
                                       ID_AA64MMFR3_EL1_S1POE)),
        ID_SANITISED(ID_AA64MMFR4_EL1),
        ID_UNALLOCATED(7,5),
@@ -2903,7 +2939,7 @@ static bool handle_alle1is(struct kvm_vcpu *vcpu, struct sys_reg_params *p,
         * Drop all shadow S2s, resulting in S1/S2 TLBIs for each of the
         * corresponding VMIDs.
         */
-       kvm_nested_s2_unmap(vcpu->kvm);
+       kvm_nested_s2_unmap(vcpu->kvm, true);
 
        write_unlock(&vcpu->kvm->mmu_lock);
 
@@ -2955,7 +2991,30 @@ union tlbi_info {
 static void s2_mmu_unmap_range(struct kvm_s2_mmu *mmu,
                               const union tlbi_info *info)
 {
-       kvm_stage2_unmap_range(mmu, info->range.start, info->range.size);
+       /*
+        * The unmap operation is allowed to drop the MMU lock and block, which
+        * means that @mmu could be used for a different context than the one
+        * currently being invalidated.
+        *
+        * This behavior is still safe, as:
+        *
+        *  1) The vCPU(s) that recycled the MMU are responsible for invalidating
+        *     the entire MMU before reusing it, which still honors the intent
+        *     of a TLBI.
+        *
+        *  2) Until the guest TLBI instruction is 'retired' (i.e. increment PC
+        *     and ERET to the guest), other vCPUs are allowed to use stale
+        *     translations.
+        *
+        *  3) Accidentally unmapping an unrelated MMU context is nonfatal, and
+        *     at worst may cause more aborts for shadow stage-2 fills.
+        *
+        * Dropping the MMU lock also implies that shadow stage-2 fills could
+        * happen behind the back of the TLBI. This is still safe, though, as
+        * the L1 needs to put its stage-2 in a consistent state before doing
+        * the TLBI.
+        */
+       kvm_stage2_unmap_range(mmu, info->range.start, info->range.size, true);
 }
 
 static bool handle_vmalls12e1is(struct kvm_vcpu *vcpu, struct sys_reg_params *p,
@@ -3050,7 +3109,11 @@ static void s2_mmu_unmap_ipa(struct kvm_s2_mmu *mmu,
        max_size = compute_tlb_inval_range(mmu, info->ipa.addr);
        base_addr &= ~(max_size - 1);
 
-       kvm_stage2_unmap_range(mmu, base_addr, max_size);
+       /*
+        * See comment in s2_mmu_unmap_range() for why this is allowed to
+        * reschedule.
+        */
+       kvm_stage2_unmap_range(mmu, base_addr, max_size, true);
 }
 
 static bool handle_ipas2e1is(struct kvm_vcpu *vcpu, struct sys_reg_params *p,
index e7c53e8af3d165379a609cbac4cc8ef2bd3be6fd..48c952563e85fd5b0aea77be946cfb0f324c5bf8 100644 (file)
@@ -417,8 +417,28 @@ static void __kvm_vgic_vcpu_destroy(struct kvm_vcpu *vcpu)
        kfree(vgic_cpu->private_irqs);
        vgic_cpu->private_irqs = NULL;
 
-       if (vcpu->kvm->arch.vgic.vgic_model == KVM_DEV_TYPE_ARM_VGIC_V3)
+       if (vcpu->kvm->arch.vgic.vgic_model == KVM_DEV_TYPE_ARM_VGIC_V3) {
+               /*
+                * If this vCPU is being destroyed because of a failed creation
+                * then unregister the redistributor to avoid leaving behind a
+                * dangling pointer to the vCPU struct.
+                *
+                * vCPUs that have been successfully created (i.e. added to
+                * kvm->vcpu_array) get unregistered in kvm_vgic_destroy(), as
+                * this function gets called while holding kvm->arch.config_lock
+                * in the VM teardown path and would otherwise introduce a lock
+                * inversion w.r.t. kvm->srcu.
+                *
+                * vCPUs that failed creation are torn down outside of the
+                * kvm->arch.config_lock and do not get unregistered in
+                * kvm_vgic_destroy(), meaning it is both safe and necessary to
+                * do so here.
+                */
+               if (kvm_get_vcpu_by_id(vcpu->kvm, vcpu->vcpu_id) != vcpu)
+                       vgic_unregister_redist_iodev(vcpu);
+
                vgic_cpu->rd_iodev.base_addr = VGIC_ADDR_UNDEF;
+       }
 }
 
 void kvm_vgic_vcpu_destroy(struct kvm_vcpu *vcpu)
@@ -524,22 +544,31 @@ int kvm_vgic_map_resources(struct kvm *kvm)
        if (ret)
                goto out;
 
-       dist->ready = true;
        dist_base = dist->vgic_dist_base;
        mutex_unlock(&kvm->arch.config_lock);
 
        ret = vgic_register_dist_iodev(kvm, dist_base, type);
-       if (ret)
+       if (ret) {
                kvm_err("Unable to register VGIC dist MMIO regions\n");
+               goto out_slots;
+       }
 
+       /*
+        * kvm_io_bus_register_dev() guarantees all readers see the new MMIO
+        * registration before returning through synchronize_srcu(), which also
+        * implies a full memory barrier. As such, marking the distributor as
+        * 'ready' here is guaranteed to be ordered after all vCPUs having seen
+        * a completely configured distributor.
+        */
+       dist->ready = true;
        goto out_slots;
 out:
        mutex_unlock(&kvm->arch.config_lock);
 out_slots:
-       mutex_unlock(&kvm->slots_lock);
-
        if (ret)
-               kvm_vgic_destroy(kvm);
+               kvm_vm_dead(kvm);
+
+       mutex_unlock(&kvm->slots_lock);
 
        return ret;
 }
index 1d26bb5b02f4b592775dee6f964938f8ce4c866c..5f4f57aaa23ecd8de1c419974d79faf9bba2b09b 100644 (file)
@@ -236,7 +236,12 @@ static int vgic_set_common_attr(struct kvm_device *dev,
 
                mutex_lock(&dev->kvm->arch.config_lock);
 
-               if (vgic_ready(dev->kvm) || dev->kvm->arch.vgic.nr_spis)
+               /*
+                * Either userspace has already configured NR_IRQS or
+                * the vgic has already been initialized and vgic_init()
+                * supplied a default amount of SPIs.
+                */
+               if (dev->kvm->arch.vgic.nr_spis)
                        ret = -EBUSY;
                else
                        dev->kvm->arch.vgic.nr_spis =
index 8bbd0b20136a87fe746592f8f3ed09cb70e89cd6..5db82bfc9dc1156c37ac4a87ce0e880e61542dd7 100644 (file)
@@ -2220,7 +2220,11 @@ static int prepare_trampoline(struct jit_ctx *ctx, struct bpf_tramp_image *im,
        emit(A64_STR64I(A64_R(20), A64_SP, regs_off + 8), ctx);
 
        if (flags & BPF_TRAMP_F_CALL_ORIG) {
-               emit_a64_mov_i64(A64_R(0), (const u64)im, ctx);
+               /* for the first pass, assume the worst case */
+               if (!ctx->image)
+                       ctx->idx += 4;
+               else
+                       emit_a64_mov_i64(A64_R(0), (const u64)im, ctx);
                emit_call((const u64)__bpf_tramp_enter, ctx);
        }
 
@@ -2264,7 +2268,11 @@ static int prepare_trampoline(struct jit_ctx *ctx, struct bpf_tramp_image *im,
 
        if (flags & BPF_TRAMP_F_CALL_ORIG) {
                im->ip_epilogue = ctx->ro_image + ctx->idx;
-               emit_a64_mov_i64(A64_R(0), (const u64)im, ctx);
+               /* for the first pass, assume the worst case */
+               if (!ctx->image)
+                       ctx->idx += 4;
+               else
+                       emit_a64_mov_i64(A64_R(0), (const u64)im, ctx);
                emit_call((const u64)__bpf_tramp_exit, ctx);
        }
 
index 3eebea3a7b478d0b2e78ac02ac5d2005a3b1a171..b7d9782827f55e543e858b18df3f73222a2f1aa9 100644 (file)
@@ -13,7 +13,7 @@
 #include <crypto/internal/hash.h>
 
 #include <asm/cpu-features.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #define _CRC32(crc, value, size, type)                 \
 do {                                                   \
index 6d5846dd075cbdde654760422fac5d9536605d4a..7657e016233fb12b04fd85f67f9a5c8ab468a629 100644 (file)
@@ -26,6 +26,10 @@ struct loongson_board_info {
 
 #define NR_WORDS DIV_ROUND_UP(NR_CPUS, BITS_PER_LONG)
 
+/*
+ * The "core" of cores_per_node and cores_per_package stands for a
+ * logical core, which means in a SMT system it stands for a thread.
+ */
 struct loongson_system_configuration {
        int nr_cpus;
        int nr_nodes;
index cd6084f4e153feef9140ba198207b4a50fe0cfc2..c6bce5fbff57b056634cd6d8038ecfa72157e498 100644 (file)
@@ -16,7 +16,7 @@
 #define XRANGE_SHIFT (48)
 
 /* Valid address length */
-#define XRANGE_SHADOW_SHIFT    (PGDIR_SHIFT + PAGE_SHIFT - 3)
+#define XRANGE_SHADOW_SHIFT    min(cpu_vabits, VA_BITS)
 /* Used for taking out the valid address */
 #define XRANGE_SHADOW_MASK     GENMASK_ULL(XRANGE_SHADOW_SHIFT - 1, 0)
 /* One segment whole address space size */
index 26542413a5b0ea4c33843faecdc25b0da4745c02..64ad277e096edd7d77af6f37e234d68e571764a4 100644 (file)
 #define  CSR_ESTAT_IS_WIDTH            15
 #define  CSR_ESTAT_IS                  (_ULCAST_(0x7fff) << CSR_ESTAT_IS_SHIFT)
 
-#define LOONGARCH_CSR_ERA              0x6     /* ERA */
+#define LOONGARCH_CSR_ERA              0x6     /* Exception return address */
 
 #define LOONGARCH_CSR_BADV             0x7     /* Bad virtual address */
 
index 4e2d6b7ca2eebf5ba14bfa46ae2699e37716d210..a7b9c9e73593d2e4a7d79134ad3b70f3415787c4 100644 (file)
@@ -10,6 +10,7 @@
 
 #define __HAVE_ARCH_PMD_ALLOC_ONE
 #define __HAVE_ARCH_PUD_ALLOC_ONE
+#define __HAVE_ARCH_PTE_ALLOC_ONE_KERNEL
 #include <asm-generic/pgalloc.h>
 
 static inline void pmd_populate_kernel(struct mm_struct *mm,
@@ -44,6 +45,16 @@ extern void pagetable_init(void);
 
 extern pgd_t *pgd_alloc(struct mm_struct *mm);
 
+static inline pte_t *pte_alloc_one_kernel(struct mm_struct *mm)
+{
+       pte_t *pte = __pte_alloc_one_kernel(mm);
+
+       if (pte)
+               kernel_pte_init(pte);
+
+       return pte;
+}
+
 #define __pte_free_tlb(tlb, pte, address)                      \
 do {                                                           \
        pagetable_pte_dtor(page_ptdesc(pte));                   \
index 9965f52ef65b6f2d24da9dbeae306c5f9ca278a6..20714b73f14c8eef9f5a3461905e02e549e22f34 100644 (file)
@@ -269,6 +269,7 @@ extern void set_pmd_at(struct mm_struct *mm, unsigned long addr, pmd_t *pmdp, pm
 extern void pgd_init(void *addr);
 extern void pud_init(void *addr);
 extern void pmd_init(void *addr);
+extern void kernel_pte_init(void *addr);
 
 /*
  * Encode/decode swap entries and swap PTEs. Swap PTEs are all PTEs that
@@ -325,39 +326,17 @@ static inline void set_pte(pte_t *ptep, pte_t pteval)
 {
        WRITE_ONCE(*ptep, pteval);
 
-       if (pte_val(pteval) & _PAGE_GLOBAL) {
-               pte_t *buddy = ptep_buddy(ptep);
-               /*
-                * Make sure the buddy is global too (if it's !none,
-                * it better already be global)
-                */
-               if (pte_none(ptep_get(buddy))) {
 #ifdef CONFIG_SMP
-                       /*
-                        * For SMP, multiple CPUs can race, so we need
-                        * to do this atomically.
-                        */
-                       __asm__ __volatile__(
-                       __AMOR "$zero, %[global], %[buddy] \n"
-                       : [buddy] "+ZB" (buddy->pte)
-                       : [global] "r" (_PAGE_GLOBAL)
-                       : "memory");
-
-                       DBAR(0b11000); /* o_wrw = 0b11000 */
-#else /* !CONFIG_SMP */
-                       WRITE_ONCE(*buddy, __pte(pte_val(ptep_get(buddy)) | _PAGE_GLOBAL));
-#endif /* CONFIG_SMP */
-               }
-       }
+       if (pte_val(pteval) & _PAGE_GLOBAL)
+               DBAR(0b11000); /* o_wrw = 0b11000 */
+#endif
 }
 
 static inline void pte_clear(struct mm_struct *mm, unsigned long addr, pte_t *ptep)
 {
-       /* Preserve global status for the pair */
-       if (pte_val(ptep_get(ptep_buddy(ptep))) & _PAGE_GLOBAL)
-               set_pte(ptep, __pte(_PAGE_GLOBAL));
-       else
-               set_pte(ptep, __pte(0));
+       pte_t pte = ptep_get(ptep);
+       pte_val(pte) &= _PAGE_GLOBAL;
+       set_pte(ptep, pte);
 }
 
 #define PGD_T_LOG2     (__builtin_ffs(sizeof(pgd_t)) - 1)
index f2ff8b5d591e4fd638109d2c98d75543c01a112c..6e58f65455c7ca3eae2e88ed852c8655a6701e5c 100644 (file)
@@ -293,13 +293,15 @@ unsigned long stack_top(void)
 {
        unsigned long top = TASK_SIZE & PAGE_MASK;
 
-       /* Space for the VDSO & data page */
-       top -= PAGE_ALIGN(current->thread.vdso->size);
-       top -= VVAR_SIZE;
-
-       /* Space to randomize the VDSO base */
-       if (current->flags & PF_RANDOMIZE)
-               top -= VDSO_RANDOMIZE_SIZE;
+       if (current->thread.vdso) {
+               /* Space for the VDSO & data page */
+               top -= PAGE_ALIGN(current->thread.vdso->size);
+               top -= VVAR_SIZE;
+
+               /* Space to randomize the VDSO base */
+               if (current->flags & PF_RANDOMIZE)
+                       top -= VDSO_RANDOMIZE_SIZE;
+       }
 
        return top;
 }
index 00e307203ddb423316b36a041efa47ce39e96559..cbd3c09a93c14c90f4089077eaff3bc0cd203585 100644 (file)
@@ -55,6 +55,7 @@
 #define SMBIOS_FREQHIGH_OFFSET         0x17
 #define SMBIOS_FREQLOW_MASK            0xFF
 #define SMBIOS_CORE_PACKAGE_OFFSET     0x23
+#define SMBIOS_THREAD_PACKAGE_OFFSET   0x25
 #define LOONGSON_EFI_ENABLE            (1 << 3)
 
 unsigned long fw_arg0, fw_arg1, fw_arg2;
@@ -125,7 +126,7 @@ static void __init parse_cpu_table(const struct dmi_header *dm)
        cpu_clock_freq = freq_temp * 1000000;
 
        loongson_sysconf.cpuname = (void *)dmi_string_parse(dm, dmi_data[16]);
-       loongson_sysconf.cores_per_package = *(dmi_data + SMBIOS_CORE_PACKAGE_OFFSET);
+       loongson_sysconf.cores_per_package = *(dmi_data + SMBIOS_THREAD_PACKAGE_OFFSET);
 
        pr_info("CpuClock = %llu\n", cpu_clock_freq);
 }
index f9f4eb00c92ef586c3350049b0b9d55ac6aac1ff..c57b4134f3e84bafbd1d5ffd4c9936adfe40f217 100644 (file)
@@ -555,6 +555,9 @@ asmlinkage void noinstr do_ale(struct pt_regs *regs)
 #else
        unsigned int *pc;
 
+       if (regs->csr_prmd & CSR_PRMD_PIE)
+               local_irq_enable();
+
        perf_sw_event(PERF_COUNT_SW_ALIGNMENT_FAULTS, 1, regs, regs->csr_badvaddr);
 
        /*
@@ -579,6 +582,8 @@ sigbus:
        die_if_kernel("Kernel ale access", regs);
        force_sig_fault(SIGBUS, BUS_ADRALN, (void __user *)regs->csr_badvaddr);
 out:
+       if (regs->csr_prmd & CSR_PRMD_PIE)
+               local_irq_disable();
 #endif
        irqentry_exit(regs, state);
 }
index f6fcc52aefae0043e307327b8e7a5872fad0822a..2c0d852ca5366b378088a492cf0942d9309dd809 100644 (file)
@@ -34,7 +34,6 @@ static union {
        struct loongarch_vdso_data vdata;
 } loongarch_vdso_data __page_aligned_data;
 
-static struct page *vdso_pages[] = { NULL };
 struct vdso_data *vdso_data = generic_vdso_data.data;
 struct vdso_pcpu_data *vdso_pdata = loongarch_vdso_data.vdata.pdata;
 struct vdso_rng_data *vdso_rng_data = &loongarch_vdso_data.vdata.rng_data;
@@ -85,10 +84,8 @@ static vm_fault_t vvar_fault(const struct vm_special_mapping *sm,
 
 struct loongarch_vdso_info vdso_info = {
        .vdso = vdso_start,
-       .size = PAGE_SIZE,
        .code_mapping = {
                .name = "[vdso]",
-               .pages = vdso_pages,
                .mremap = vdso_mremap,
        },
        .data_mapping = {
@@ -103,11 +100,14 @@ static int __init init_vdso(void)
        unsigned long i, cpu, pfn;
 
        BUG_ON(!PAGE_ALIGNED(vdso_info.vdso));
-       BUG_ON(!PAGE_ALIGNED(vdso_info.size));
 
        for_each_possible_cpu(cpu)
                vdso_pdata[cpu].node = cpu_to_node(cpu);
 
+       vdso_info.size = PAGE_ALIGN(vdso_end - vdso_start);
+       vdso_info.code_mapping.pages =
+               kcalloc(vdso_info.size / PAGE_SIZE, sizeof(struct page *), GFP_KERNEL);
+
        pfn = __phys_to_pfn(__pa_symbol(vdso_info.vdso));
        for (i = 0; i < vdso_info.size / PAGE_SIZE; i++)
                vdso_info.code_mapping.pages[i] = pfn_to_page(pfn + i);
index 74a4b5c272d60e99523e12e89d5e663d53009c2b..32dc213374beacb22b79b98163d58568489525b0 100644 (file)
@@ -161,10 +161,11 @@ static void _kvm_save_timer(struct kvm_vcpu *vcpu)
        if (kvm_vcpu_is_blocking(vcpu)) {
 
                /*
-                * HRTIMER_MODE_PINNED is suggested since vcpu may run in
-                * the same physical cpu in next time
+                * HRTIMER_MODE_PINNED_HARD is suggested since vcpu may run in
+                * the same physical cpu in next time, and the timer should run
+                * in hardirq context even in the PREEMPT_RT case.
                 */
-               hrtimer_start(&vcpu->arch.swtimer, expire, HRTIMER_MODE_ABS_PINNED);
+               hrtimer_start(&vcpu->arch.swtimer, expire, HRTIMER_MODE_ABS_PINNED_HARD);
        }
 }
 
index 0697b106425116d225e8ee655f09873c76771ef9..174734a23d0ac8221fdeea137739baae953a7353 100644 (file)
@@ -1457,7 +1457,7 @@ int kvm_arch_vcpu_create(struct kvm_vcpu *vcpu)
        vcpu->arch.vpid = 0;
        vcpu->arch.flush_gpa = INVALID_GPA;
 
-       hrtimer_init(&vcpu->arch.swtimer, CLOCK_MONOTONIC, HRTIMER_MODE_ABS_PINNED);
+       hrtimer_init(&vcpu->arch.swtimer, CLOCK_MONOTONIC, HRTIMER_MODE_ABS_PINNED_HARD);
        vcpu->arch.swtimer.function = kvm_swtimer_wakeup;
 
        vcpu->arch.handle_exit = kvm_handle_exit;
index 8a87a482c8f44bf085ae792da33342bb35b9b010..188b52bbb254273674eb931bf97e9e250fa30024 100644 (file)
@@ -201,7 +201,9 @@ pte_t * __init populate_kernel_pte(unsigned long addr)
                pte = memblock_alloc(PAGE_SIZE, PAGE_SIZE);
                if (!pte)
                        panic("%s: Failed to allocate memory\n", __func__);
+
                pmd_populate_kernel(&init_mm, pmd, pte);
+               kernel_pte_init(pte);
        }
 
        return pte_offset_kernel(pmd, addr);
index eb6a29b491a72be73f64a472d57fe3c2856bc9c1..3fa69b23ff8400198337f0073ef42b8c40e5b374 100644 (file)
@@ -116,6 +116,26 @@ void pud_init(void *addr)
 EXPORT_SYMBOL_GPL(pud_init);
 #endif
 
+void kernel_pte_init(void *addr)
+{
+       unsigned long *p, *end;
+
+       p = (unsigned long *)addr;
+       end = p + PTRS_PER_PTE;
+
+       do {
+               p[0] = _PAGE_GLOBAL;
+               p[1] = _PAGE_GLOBAL;
+               p[2] = _PAGE_GLOBAL;
+               p[3] = _PAGE_GLOBAL;
+               p[4] = _PAGE_GLOBAL;
+               p += 8;
+               p[-3] = _PAGE_GLOBAL;
+               p[-2] = _PAGE_GLOBAL;
+               p[-1] = _PAGE_GLOBAL;
+       } while (p != end);
+}
+
 pmd_t mk_pmd(struct page *page, pgprot_t prot)
 {
        pmd_t pmd;
index 79a749f4ad04ee4073b336ab0e640a7c3aea72ea..edff4306fa7093f1e0137115b92d74461860115e 100644 (file)
@@ -8,7 +8,7 @@
 #ifndef _ASM_MICROBLAZE_FLAT_H
 #define _ASM_MICROBLAZE_FLAT_H
 
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 /*
  * Microblaze works a little differently from other arches, because
index adb6d5b0e6ebc05f5cb7212d85c6e697cc757ea3..90021c6a8cab5c4c291b0f9596ab99018bbaf20b 100644 (file)
@@ -16,7 +16,7 @@
 #include <linux/libfdt.h>
 
 #include <asm/addrspace.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include <asm-generic/vmlinux.lds.h>
 
 #include "decompress.h"
index 2a59b85f88aacea20d11e6e8ddcb2b6c8006ebe4..a7a1d43a1b2ca5eb8a582681b22c7949da21ec06 100644 (file)
@@ -14,7 +14,7 @@
 #include <linux/module.h>
 #include <linux/string.h>
 #include <asm/mipsregs.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #include <crypto/internal/hash.h>
 
index 867728ee535af450ef8f260aff10049cf0f60767..c03ad0bbe69cdc5016b0ce7e07631beb048dc393 100644 (file)
@@ -5,7 +5,7 @@
  * Copyright (C) 2019 Linaro Ltd. <[email protected]>
  */
 
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include <crypto/algapi.h>
 #include <crypto/internal/hash.h>
 #include <crypto/internal/poly1305.h>
index e974a4954df8530b5bb90633b889db276860bb48..c371def2302d27080d38cc5b56caed4215d4ae39 100644 (file)
@@ -102,3 +102,4 @@ unsigned long __cmpxchg_small(volatile void *ptr, unsigned long old,
                        return old;
        }
 }
+EXPORT_SYMBOL(__cmpxchg_small);
index 23e0544e117cef65f8b771fdd2917ed8995c50e8..2f2862eab3c6d54ccf1a7c62c0d1c3e8d132bd9f 100644 (file)
@@ -23,7 +23,7 @@
 #include <linux/seq_file.h>
 
 #include <asm/traps.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 /* instructions we emulate */
 #define INST_LDHU      0x0b
index d389359e22ac6c168538b02a3c55fb04cfa59760..9c83bd06ef1542437d0ac1d416ba67c3b707433a 100644 (file)
@@ -6,7 +6,7 @@
 
 #include <linux/uaccess.h>
 #include <linux/elf.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include <asm/page.h>
 #include "sizes.h"
 
diff --git a/arch/parisc/include/asm/unaligned.h b/arch/parisc/include/asm/unaligned.h
deleted file mode 100644 (file)
index c062129..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-#ifndef _ASM_PARISC_UNALIGNED_H
-#define _ASM_PARISC_UNALIGNED_H
-
-#include <asm-generic/unaligned.h>
-
-struct pt_regs;
-void handle_unaligned(struct pt_regs *regs);
-int check_unaligned(struct pt_regs *regs);
-
-#endif /* _ASM_PARISC_UNALIGNED_H */
index 294b0e026c9a5baed1815d3ff477acb81fd64885..b9b3d527bc9065c659da306049182247f0d338ef 100644 (file)
@@ -36,7 +36,7 @@
 #include <asm/io.h>
 #include <asm/irq.h>
 #include <asm/traps.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include <linux/atomic.h>
 #include <asm/smp.h>
 #include <asm/pdc.h>
@@ -47,6 +47,8 @@
 #include <linux/kgdb.h>
 #include <linux/kprobes.h>
 
+#include "unaligned.h"
+
 #if defined(CONFIG_LIGHTWEIGHT_SPINLOCK_CHECK)
 #include <asm/spinlock.h>
 #endif
index 3e79e40e361d5246a8e9c37337c3df44f6c6c4e6..f4626943633adc33efec55ccd2ac035c9a56e988 100644 (file)
 #include <linux/ratelimit.h>
 #include <linux/uaccess.h>
 #include <linux/sysctl.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include <asm/hardirq.h>
 #include <asm/traps.h>
+#include "unaligned.h"
 
 /* #define DEBUG_UNALIGNED 1 */
 
diff --git a/arch/parisc/kernel/unaligned.h b/arch/parisc/kernel/unaligned.h
new file mode 100644 (file)
index 0000000..c1aa4b1
--- /dev/null
@@ -0,0 +1,3 @@
+struct pt_regs;
+void handle_unaligned(struct pt_regs *regs);
+int check_unaligned(struct pt_regs *regs);
index f62ee54076c06dc738f275da8690a4579d0f0fab..f66ad56e765f041be55571aecfef515c91a09d6b 100644 (file)
@@ -5,7 +5,7 @@
  * Copyright 2022- IBM Inc. All rights reserved
  */
 
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include <asm/simd.h>
 #include <asm/switch_to.h>
 #include <crypto/aes.h>
index 95dd708573ee4d97574fe3becf7bad307df2e302..369686e9370b445d109596c1d599ac7a1908ff29 100644 (file)
@@ -14,7 +14,7 @@
 #include <crypto/internal/poly1305.h>
 #include <crypto/internal/simd.h>
 #include <linux/cpufeature.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include <asm/simd.h>
 #include <asm/switch_to.h>
 
index 811a7130505cd40e37836707da6e6bdf842da4c2..56c5ebe21b99a4dfb409bd18cbda98e5769f6e82 100644 (file)
@@ -494,6 +494,7 @@ FixupDAR:/* Entry point for dcbx workaround. */
        bctr                            /* jump into table */
 152:
        mfdar   r11
+       mtdar   r10
        mtctr   r11                     /* restore ctr reg from DAR */
        mfspr   r11, SPRN_SPRG_THREAD
        stw     r10, DAR(r11)
index 56fb1633529a728799e45c3152026cab7c100f4c..31ca5a5470047e7ac0a0f8194fd59c6a3b453b4d 100644 (file)
@@ -22,7 +22,7 @@ endif
 
 ifneq ($(c-getrandom-y),)
   CFLAGS_vgetrandom-32.o += -include $(c-getrandom-y)
-  CFLAGS_vgetrandom-64.o += -include $(c-getrandom-y) $(call cc-option, -ffixed-r30)
+  CFLAGS_vgetrandom-64.o += -include $(c-getrandom-y)
 endif
 
 # Build rules
index 56a1f7ce78d2c7bb16d6709a23ab35ac1c0b8108..d92759c21fae94256a8b714260873962abfa15ab 100644 (file)
@@ -282,6 +282,7 @@ int __init opal_event_init(void)
                                 name, NULL);
                if (rc) {
                        pr_warn("Error %d requesting OPAL irq %d\n", rc, (int)r->start);
+                       kfree(name);
                        continue;
                }
        }
index d95e03b3d3e3f358a3c0c0e31b76c4694d5881d6..9e297f88adc5d97d4dc7b267b0bfebd58e5cf193 100644 (file)
@@ -19,7 +19,7 @@
 #include <uapi/linux/papr_pdsm.h>
 #include <linux/papr_scm.h>
 #include <asm/mce.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include <linux/perf_event.h>
 
 #define BIND_ANY_ADDR (~0ul)
index 22dc5ea4196ce19c7f2282c4160f92a02b69a2c7..f4c570538d55b17b33a22dd78be149fb62480706 100644 (file)
@@ -177,7 +177,7 @@ config RISCV
        select HAVE_REGS_AND_STACK_ACCESS_API
        select HAVE_RETHOOK if !XIP_KERNEL
        select HAVE_RSEQ
-       select HAVE_RUST if RUSTC_SUPPORTS_RISCV
+       select HAVE_RUST if RUSTC_SUPPORTS_RISCV && CC_IS_CLANG
        select HAVE_SAMPLE_FTRACE_DIRECT
        select HAVE_SAMPLE_FTRACE_DIRECT_MULTI
        select HAVE_STACKPROTECTOR
@@ -777,8 +777,7 @@ config IRQ_STACKS
 config THREAD_SIZE_ORDER
        int "Kernel stack size (in power-of-two numbers of page size)" if VMAP_STACK && EXPERT
        range 0 4
-       default 1 if 32BIT && !KASAN
-       default 3 if 64BIT && KASAN
+       default 1 if 32BIT
        default 2
        help
          Specify the Pages of thread stack size (from 4KB to 64KB), which also
index 8a27394851233dbda1a4f0841e1e7e918b61f8e0..f0da9d7b39c3748494d46cb9cadc530fec68acf2 100644 (file)
@@ -2,6 +2,12 @@ ifdef CONFIG_RELOCATABLE
 KBUILD_CFLAGS += -fno-pie
 endif
 
+ifdef CONFIG_RISCV_ALTERNATIVE_EARLY
+ifdef CONFIG_FORTIFY_SOURCE
+KBUILD_CFLAGS += -D__NO_FORTIFY
+endif
+endif
+
 obj-$(CONFIG_ERRATA_ANDES) += andes/
 obj-$(CONFIG_ERRATA_SIFIVE) += sifive/
 obj-$(CONFIG_ERRATA_THEAD) += thead/
index ebe52f96da348746159f3a630b82c49a8e45c5df..9c10fb180f43899042bf4b293aa72b630599df09 100644 (file)
 #include <linux/sizes.h>
 
 /* thread information allocation */
-#define THREAD_SIZE_ORDER      CONFIG_THREAD_SIZE_ORDER
+#ifdef CONFIG_KASAN
+#define KASAN_STACK_ORDER      1
+#else
+#define KASAN_STACK_ORDER      0
+#endif
+#define THREAD_SIZE_ORDER      (CONFIG_THREAD_SIZE_ORDER + KASAN_STACK_ORDER)
 #define THREAD_SIZE            (PAGE_SIZE << THREAD_SIZE_ORDER)
 
 /*
index 7f88cc4931f5c44105e827d46832a94fe81483f4..69dc8aaab3fb3afc4f501258687e8cd5f79ecfce 100644 (file)
@@ -36,6 +36,11 @@ KASAN_SANITIZE_alternative.o := n
 KASAN_SANITIZE_cpufeature.o := n
 KASAN_SANITIZE_sbi_ecall.o := n
 endif
+ifdef CONFIG_FORTIFY_SOURCE
+CFLAGS_alternative.o += -D__NO_FORTIFY
+CFLAGS_cpufeature.o += -D__NO_FORTIFY
+CFLAGS_sbi_ecall.o += -D__NO_FORTIFY
+endif
 endif
 
 extra-y += vmlinux.lds
index 6e0d333f57e556912742e4282a6dcb03674ebb2d..2fd29695a788f25fe7392be5b4e844c223a0ba68 100644 (file)
@@ -210,7 +210,7 @@ void __init __iomem *__acpi_map_table(unsigned long phys, unsigned long size)
        if (!size)
                return NULL;
 
-       return early_ioremap(phys, size);
+       return early_memremap(phys, size);
 }
 
 void __init __acpi_unmap_table(void __iomem *map, unsigned long size)
@@ -218,7 +218,7 @@ void __init __acpi_unmap_table(void __iomem *map, unsigned long size)
        if (!map || !size)
                return;
 
-       early_iounmap(map, size);
+       early_memunmap(map, size);
 }
 
 void __iomem *acpi_os_ioremap(acpi_physical_address phys, acpi_size size)
index e94180ba432f5957b4e73143e17e902be24a6b29..c2f3129a8e5cfb3d41becc5c30fb14c77cb6e0f4 100644 (file)
@@ -4,8 +4,6 @@
  * Copyright (C) 2017 SiFive
  */
 
-#define GENERATING_ASM_OFFSETS
-
 #include <linux/kbuild.h>
 #include <linux/mm.h>
 #include <linux/sched.h>
index b320b1d9aa01eff8cb41d4971f7f6dc461cce341..2d40736fc37cec788448d25c4ec5bdce802e581a 100644 (file)
@@ -80,8 +80,7 @@ int populate_cache_leaves(unsigned int cpu)
 {
        struct cpu_cacheinfo *this_cpu_ci = get_cpu_cacheinfo(cpu);
        struct cacheinfo *this_leaf = this_cpu_ci->info_list;
-       struct device_node *np = of_cpu_device_node_get(cpu);
-       struct device_node *prev = NULL;
+       struct device_node *np, *prev;
        int levels = 1, level = 1;
 
        if (!acpi_disabled) {
@@ -105,6 +104,10 @@ int populate_cache_leaves(unsigned int cpu)
                return 0;
        }
 
+       np = of_cpu_device_node_get(cpu);
+       if (!np)
+               return -ENOENT;
+
        if (of_property_read_bool(np, "cache-size"))
                ci_leaf_init(this_leaf++, CACHE_TYPE_UNIFIED, level);
        if (of_property_read_bool(np, "i-cache-size"))
index 28b58fc5ad1996112c67b7f6030f9ba81a26b388..a1e38ecfc8be21068a2af679f7a093ed630d62b2 100644 (file)
@@ -58,7 +58,7 @@ void arch_cpuhp_cleanup_dead_cpu(unsigned int cpu)
        if (cpu_ops->cpu_is_stopped)
                ret = cpu_ops->cpu_is_stopped(cpu);
        if (ret)
-               pr_warn("CPU%d may not have stopped: %d\n", cpu, ret);
+               pr_warn("CPU%u may not have stopped: %d\n", cpu, ret);
 }
 
 /*
index 515b2dfbca75ba8e76128dfb3b16b252f388c2e0..c5f17c2710b58f435929c8a2ae889ea1f8ae7c06 100644 (file)
@@ -64,7 +64,7 @@ extra_header_fields:
        .long   efi_header_end - _start                 // SizeOfHeaders
        .long   0                                       // CheckSum
        .short  IMAGE_SUBSYSTEM_EFI_APPLICATION         // Subsystem
-       .short  0                                       // DllCharacteristics
+       .short  IMAGE_DLL_CHARACTERISTICS_NX_COMPAT     // DllCharacteristics
        .quad   0                                       // SizeOfStackReserve
        .quad   0                                       // SizeOfStackCommit
        .quad   0                                       // SizeOfHeapReserve
index d5bf1bc7de62e21ef1c9d5ce1f63fc16db4c2dce..81d69d45c06c33887b4795d1f226c476005c3826 100644 (file)
@@ -16,8 +16,12 @@ KBUILD_CFLAGS        := $(filter-out $(CC_FLAGS_LTO), $(KBUILD_CFLAGS))
 KBUILD_CFLAGS  += -mcmodel=medany
 
 CFLAGS_cmdline_early.o += -D__NO_FORTIFY
-CFLAGS_lib-fdt_ro.o += -D__NO_FORTIFY
 CFLAGS_fdt_early.o += -D__NO_FORTIFY
+# lib/string.c already defines __NO_FORTIFY
+CFLAGS_ctype.o += -D__NO_FORTIFY
+CFLAGS_lib-fdt.o += -D__NO_FORTIFY
+CFLAGS_lib-fdt_ro.o += -D__NO_FORTIFY
+CFLAGS_archrandom_early.o += -D__NO_FORTIFY
 
 $(obj)/%.pi.o: OBJCOPYFLAGS := --prefix-symbols=__pi_ \
                               --remove-section=.note.gnu.property \
index d4fd8af7aaf5a937de9c3f50f0d52cd51f845645..1b9867136b61006ab3be871ddf5a9d3d1b13c8cb 100644 (file)
 #define REG_PTR(insn, pos, regs)       \
        (ulong *)((ulong)(regs) + REG_OFFSET(insn, pos))
 
-#define GET_RM(insn)                   (((insn) >> 12) & 7)
-
 #define GET_RS1(insn, regs)            (*REG_PTR(insn, SH_RS1, regs))
 #define GET_RS2(insn, regs)            (*REG_PTR(insn, SH_RS2, regs))
 #define GET_RS1S(insn, regs)           (*REG_PTR(RVC_RS1S(insn), 0, regs))
index 960feb1526caa00488726f2a5dfcd16143ba6c91..3f1c4b2d0b0642b90ce9d18994fc6fc966235c24 100644 (file)
@@ -18,6 +18,7 @@ obj-vdso = $(patsubst %, %.o, $(vdso-syms)) note.o
 
 ccflags-y := -fno-stack-protector
 ccflags-y += -DDISABLE_BRANCH_PROFILING
+ccflags-y += -fno-builtin
 
 ifneq ($(c-gettimeofday-y),)
   CFLAGS_vgettimeofday.o += -fPIC -include $(c-gettimeofday-y)
index 0a1e859323b45779feb1f1b77259aa80f868e295..a8085cd8215e352689304e9bd0db78ffd57211e9 100644 (file)
@@ -55,7 +55,7 @@ struct imsic {
        /* IMSIC SW-file */
        struct imsic_mrif *swfile;
        phys_addr_t swfile_pa;
-       spinlock_t swfile_extirq_lock;
+       raw_spinlock_t swfile_extirq_lock;
 };
 
 #define imsic_vs_csr_read(__c)                 \
@@ -622,7 +622,7 @@ static void imsic_swfile_extirq_update(struct kvm_vcpu *vcpu)
         * interruptions between reading topei and updating pending status.
         */
 
-       spin_lock_irqsave(&imsic->swfile_extirq_lock, flags);
+       raw_spin_lock_irqsave(&imsic->swfile_extirq_lock, flags);
 
        if (imsic_mrif_atomic_read(mrif, &mrif->eidelivery) &&
            imsic_mrif_topei(mrif, imsic->nr_eix, imsic->nr_msis))
@@ -630,7 +630,7 @@ static void imsic_swfile_extirq_update(struct kvm_vcpu *vcpu)
        else
                kvm_riscv_vcpu_unset_interrupt(vcpu, IRQ_VS_EXT);
 
-       spin_unlock_irqrestore(&imsic->swfile_extirq_lock, flags);
+       raw_spin_unlock_irqrestore(&imsic->swfile_extirq_lock, flags);
 }
 
 static void imsic_swfile_read(struct kvm_vcpu *vcpu, bool clear,
@@ -1051,7 +1051,7 @@ int kvm_riscv_vcpu_aia_imsic_init(struct kvm_vcpu *vcpu)
        }
        imsic->swfile = page_to_virt(swfile_page);
        imsic->swfile_pa = page_to_phys(swfile_page);
-       spin_lock_init(&imsic->swfile_extirq_lock);
+       raw_spin_lock_init(&imsic->swfile_extirq_lock);
 
        /* Setup IO device */
        kvm_iodevice_init(&imsic->iodev, &imsic_iodoev_ops);
index 99f34409fb60f48a92366c4824e6237c96f92680..4cc631fa703913377d1d109e9a0a06a7ada2cb4a 100644 (file)
@@ -18,6 +18,7 @@
 #define RV_MAX_REG_ARGS 8
 #define RV_FENTRY_NINSNS 2
 #define RV_FENTRY_NBYTES (RV_FENTRY_NINSNS * 4)
+#define RV_KCFI_NINSNS (IS_ENABLED(CONFIG_CFI_CLANG) ? 1 : 0)
 /* imm that allows emit_imm to emit max count insns */
 #define RV_MAX_COUNT_IMM 0x7FFF7FF7FF7FF7FF
 
@@ -271,7 +272,8 @@ static void __build_epilogue(bool is_tail_call, struct rv_jit_context *ctx)
        if (!is_tail_call)
                emit_addiw(RV_REG_A0, RV_REG_A5, 0, ctx);
        emit_jalr(RV_REG_ZERO, is_tail_call ? RV_REG_T3 : RV_REG_RA,
-                 is_tail_call ? (RV_FENTRY_NINSNS + 1) * 4 : 0, /* skip reserved nops and TCC init */
+                 /* kcfi, fentry and TCC init insns will be skipped on tailcall */
+                 is_tail_call ? (RV_KCFI_NINSNS + RV_FENTRY_NINSNS + 1) * 4 : 0,
                  ctx);
 }
 
@@ -548,8 +550,8 @@ static void emit_atomic(u8 rd, u8 rs, s16 off, s32 imm, bool is64,
                     rv_lr_w(r0, 0, rd, 0, 0), ctx);
                jmp_offset = ninsns_rvoff(8);
                emit(rv_bne(RV_REG_T2, r0, jmp_offset >> 1), ctx);
-               emit(is64 ? rv_sc_d(RV_REG_T3, rs, rd, 0, 0) :
-                    rv_sc_w(RV_REG_T3, rs, rd, 0, 0), ctx);
+               emit(is64 ? rv_sc_d(RV_REG_T3, rs, rd, 0, 1) :
+                    rv_sc_w(RV_REG_T3, rs, rd, 0, 1), ctx);
                jmp_offset = ninsns_rvoff(-6);
                emit(rv_bne(RV_REG_T3, 0, jmp_offset >> 1), ctx);
                emit(rv_fence(0x3, 0x3), ctx);
index 9b57add02cd5c4c4ec4fb391a8fd1915a0d3ed00..fb0e9a1d9be254f85792a0bf6a855ad3ac59516e 100644 (file)
@@ -50,7 +50,6 @@ CONFIG_NUMA=y
 CONFIG_HZ_100=y
 CONFIG_CERT_STORE=y
 CONFIG_EXPOLINE=y
-# CONFIG_EXPOLINE_EXTERN is not set
 CONFIG_EXPOLINE_AUTO=y
 CONFIG_CHSC_SCH=y
 CONFIG_VFIO_CCW=m
@@ -95,6 +94,7 @@ CONFIG_BINFMT_MISC=m
 CONFIG_ZSWAP=y
 CONFIG_ZSWAP_ZPOOL_DEFAULT_ZBUD=y
 CONFIG_ZSMALLOC_STAT=y
+CONFIG_SLAB_BUCKETS=y
 CONFIG_SLUB_STATS=y
 # CONFIG_COMPAT_BRK is not set
 CONFIG_MEMORY_HOTPLUG=y
@@ -426,6 +426,13 @@ CONFIG_DEVTMPFS_SAFE=y
 # CONFIG_FW_LOADER is not set
 CONFIG_CONNECTOR=y
 CONFIG_ZRAM=y
+CONFIG_ZRAM_BACKEND_LZ4=y
+CONFIG_ZRAM_BACKEND_LZ4HC=y
+CONFIG_ZRAM_BACKEND_ZSTD=y
+CONFIG_ZRAM_BACKEND_DEFLATE=y
+CONFIG_ZRAM_BACKEND_842=y
+CONFIG_ZRAM_BACKEND_LZO=y
+CONFIG_ZRAM_DEF_COMP_DEFLATE=y
 CONFIG_BLK_DEV_LOOP=m
 CONFIG_BLK_DEV_DRBD=m
 CONFIG_BLK_DEV_NBD=m
@@ -486,6 +493,7 @@ CONFIG_DM_UEVENT=y
 CONFIG_DM_FLAKEY=m
 CONFIG_DM_VERITY=m
 CONFIG_DM_VERITY_VERIFY_ROOTHASH_SIG=y
+CONFIG_DM_VERITY_VERIFY_ROOTHASH_SIG_PLATFORM_KEYRING=y
 CONFIG_DM_SWITCH=m
 CONFIG_DM_INTEGRITY=m
 CONFIG_DM_VDO=m
@@ -535,6 +543,7 @@ CONFIG_NLMON=m
 CONFIG_MLX4_EN=m
 CONFIG_MLX5_CORE=m
 CONFIG_MLX5_CORE_EN=y
+# CONFIG_NET_VENDOR_META is not set
 # CONFIG_NET_VENDOR_MICREL is not set
 # CONFIG_NET_VENDOR_MICROCHIP is not set
 # CONFIG_NET_VENDOR_MICROSEMI is not set
@@ -695,6 +704,7 @@ CONFIG_NFSD=m
 CONFIG_NFSD_V3_ACL=y
 CONFIG_NFSD_V4=y
 CONFIG_NFSD_V4_SECURITY_LABEL=y
+# CONFIG_NFSD_LEGACY_CLIENT_TRACKING is not set
 CONFIG_CIFS=m
 CONFIG_CIFS_UPCALL=y
 CONFIG_CIFS_XATTR=y
@@ -740,7 +750,6 @@ CONFIG_CRYPTO_DH=m
 CONFIG_CRYPTO_ECDH=m
 CONFIG_CRYPTO_ECDSA=m
 CONFIG_CRYPTO_ECRDSA=m
-CONFIG_CRYPTO_SM2=m
 CONFIG_CRYPTO_CURVE25519=m
 CONFIG_CRYPTO_AES_TI=m
 CONFIG_CRYPTO_ANUBIS=m
index df4addd1834ab23c2713ccd7f8ffe488993be5a4..88be0a734b60f670fa5b16d173ac30d7e89a2718 100644 (file)
@@ -48,7 +48,6 @@ CONFIG_NUMA=y
 CONFIG_HZ_100=y
 CONFIG_CERT_STORE=y
 CONFIG_EXPOLINE=y
-# CONFIG_EXPOLINE_EXTERN is not set
 CONFIG_EXPOLINE_AUTO=y
 CONFIG_CHSC_SCH=y
 CONFIG_VFIO_CCW=m
@@ -89,6 +88,7 @@ CONFIG_BINFMT_MISC=m
 CONFIG_ZSWAP=y
 CONFIG_ZSWAP_ZPOOL_DEFAULT_ZBUD=y
 CONFIG_ZSMALLOC_STAT=y
+CONFIG_SLAB_BUCKETS=y
 # CONFIG_COMPAT_BRK is not set
 CONFIG_MEMORY_HOTPLUG=y
 CONFIG_MEMORY_HOTREMOVE=y
@@ -416,6 +416,13 @@ CONFIG_DEVTMPFS_SAFE=y
 # CONFIG_FW_LOADER is not set
 CONFIG_CONNECTOR=y
 CONFIG_ZRAM=y
+CONFIG_ZRAM_BACKEND_LZ4=y
+CONFIG_ZRAM_BACKEND_LZ4HC=y
+CONFIG_ZRAM_BACKEND_ZSTD=y
+CONFIG_ZRAM_BACKEND_DEFLATE=y
+CONFIG_ZRAM_BACKEND_842=y
+CONFIG_ZRAM_BACKEND_LZO=y
+CONFIG_ZRAM_DEF_COMP_DEFLATE=y
 CONFIG_BLK_DEV_LOOP=m
 CONFIG_BLK_DEV_DRBD=m
 CONFIG_BLK_DEV_NBD=m
@@ -476,6 +483,7 @@ CONFIG_DM_UEVENT=y
 CONFIG_DM_FLAKEY=m
 CONFIG_DM_VERITY=m
 CONFIG_DM_VERITY_VERIFY_ROOTHASH_SIG=y
+CONFIG_DM_VERITY_VERIFY_ROOTHASH_SIG_PLATFORM_KEYRING=y
 CONFIG_DM_SWITCH=m
 CONFIG_DM_INTEGRITY=m
 CONFIG_DM_VDO=m
@@ -525,6 +533,7 @@ CONFIG_NLMON=m
 CONFIG_MLX4_EN=m
 CONFIG_MLX5_CORE=m
 CONFIG_MLX5_CORE_EN=y
+# CONFIG_NET_VENDOR_META is not set
 # CONFIG_NET_VENDOR_MICREL is not set
 # CONFIG_NET_VENDOR_MICROCHIP is not set
 # CONFIG_NET_VENDOR_MICROSEMI is not set
@@ -682,6 +691,7 @@ CONFIG_NFSD=m
 CONFIG_NFSD_V3_ACL=y
 CONFIG_NFSD_V4=y
 CONFIG_NFSD_V4_SECURITY_LABEL=y
+# CONFIG_NFSD_LEGACY_CLIENT_TRACKING is not set
 CONFIG_CIFS=m
 CONFIG_CIFS_UPCALL=y
 CONFIG_CIFS_XATTR=y
@@ -726,7 +736,6 @@ CONFIG_CRYPTO_DH=m
 CONFIG_CRYPTO_ECDH=m
 CONFIG_CRYPTO_ECDSA=m
 CONFIG_CRYPTO_ECRDSA=m
-CONFIG_CRYPTO_SM2=m
 CONFIG_CRYPTO_CURVE25519=m
 CONFIG_CRYPTO_AES_TI=m
 CONFIG_CRYPTO_ANUBIS=m
@@ -767,6 +776,7 @@ CONFIG_CRYPTO_LZ4=m
 CONFIG_CRYPTO_LZ4HC=m
 CONFIG_CRYPTO_ZSTD=m
 CONFIG_CRYPTO_ANSI_CPRNG=m
+CONFIG_CRYPTO_JITTERENTROPY_OSR=1
 CONFIG_CRYPTO_USER_API_HASH=m
 CONFIG_CRYPTO_USER_API_SKCIPHER=m
 CONFIG_CRYPTO_USER_API_RNG=m
index 8c2b61363bab91cd04e62f8b09040f4906883380..bcbaa069de96eadabedaae387df1cd0d049d5b72 100644 (file)
@@ -49,6 +49,7 @@ CONFIG_ZFCP=y
 # CONFIG_HVC_IUCV is not set
 # CONFIG_HW_RANDOM_S390 is not set
 # CONFIG_HMC_DRV is not set
+# CONFIG_S390_UV_UAPI is not set
 # CONFIG_S390_TAPE is not set
 # CONFIG_VMCP is not set
 # CONFIG_MONWRITER is not set
index 0fbc992d7a5ea7e71fddc8576218237360900fd2..fc9933a743d692196c322f77538d35b9a826a8ee 100644 (file)
 #include <asm/pci_io.h>
 
 #define xlate_dev_mem_ptr xlate_dev_mem_ptr
+#define kc_xlate_dev_mem_ptr xlate_dev_mem_ptr
 void *xlate_dev_mem_ptr(phys_addr_t phys);
 #define unxlate_dev_mem_ptr unxlate_dev_mem_ptr
+#define kc_unxlate_dev_mem_ptr unxlate_dev_mem_ptr
 void unxlate_dev_mem_ptr(phys_addr_t phys, void *addr);
 
 #define IO_SPACE_LIMIT 0
index 66200d4a21341b816147be21aae61b1ace990322..29ee289108c5622e1375166fbbdc2cc66f29cf1c 100644 (file)
@@ -49,6 +49,7 @@ struct perf_sf_sde_regs {
 };
 
 #define perf_arch_fetch_caller_regs(regs, __ip) do {                   \
+       (regs)->psw.mask = 0;                                           \
        (regs)->psw.addr = (__ip);                                      \
        (regs)->gprs[15] = (unsigned long)__builtin_frame_address(0) -  \
                offsetof(struct stack_frame, back_chain);               \
index 2a32438e09cebaa698a8935c4aec03bf1f2cbc58..74f73141f9b96b5dcebe2f6a92c55fa161aaf118 100644 (file)
@@ -77,7 +77,7 @@ static int __diag_page_ref_service(struct kvm_vcpu *vcpu)
        vcpu->stat.instruction_diagnose_258++;
        if (vcpu->run->s.regs.gprs[rx] & 7)
                return kvm_s390_inject_program_int(vcpu, PGM_SPECIFICATION);
-       rc = read_guest(vcpu, vcpu->run->s.regs.gprs[rx], rx, &parm, sizeof(parm));
+       rc = read_guest_real(vcpu, vcpu->run->s.regs.gprs[rx], &parm, sizeof(parm));
        if (rc)
                return kvm_s390_inject_prog_cond(vcpu, rc);
        if (parm.parm_version != 2 || parm.parm_len < 5 || parm.code != 0x258)
index e65f597e3044a76f2a29fc9aeff84998cc3534da..a688351f4ab5217d745444e6b8a95829c10a2f1f 100644 (file)
@@ -828,6 +828,8 @@ static int access_guest_page(struct kvm *kvm, enum gacc_mode mode, gpa_t gpa,
        const gfn_t gfn = gpa_to_gfn(gpa);
        int rc;
 
+       if (!gfn_to_memslot(kvm, gfn))
+               return PGM_ADDRESSING;
        if (mode == GACC_STORE)
                rc = kvm_write_guest_page(kvm, gfn, data, offset, len);
        else
@@ -985,6 +987,8 @@ int access_guest_real(struct kvm_vcpu *vcpu, unsigned long gra,
                gra += fragment_len;
                data += fragment_len;
        }
+       if (rc > 0)
+               vcpu->arch.pgm.code = rc;
        return rc;
 }
 
index b320d12aa04934e52caec4ad06bc9bc655a16c35..3fde45a151f22ec89f7185dff9898f69e6632a9a 100644 (file)
@@ -405,11 +405,12 @@ int read_guest_abs(struct kvm_vcpu *vcpu, unsigned long gpa, void *data,
  * @len: number of bytes to copy
  *
  * Copy @len bytes from @data (kernel space) to @gra (guest real address).
- * It is up to the caller to ensure that the entire guest memory range is
- * valid memory before calling this function.
  * Guest low address and key protection are not checked.
  *
- * Returns zero on success or -EFAULT on error.
+ * Returns zero on success, -EFAULT when copying from @data failed, or
+ * PGM_ADRESSING in case @gra is outside a memslot. In this case, pgm check info
+ * is also stored to allow injecting into the guest (if applicable) using
+ * kvm_s390_inject_prog_cond().
  *
  * If an error occurs data may have been copied partially to guest memory.
  */
@@ -428,11 +429,12 @@ int write_guest_real(struct kvm_vcpu *vcpu, unsigned long gra, void *data,
  * @len: number of bytes to copy
  *
  * Copy @len bytes from @gra (guest real address) to @data (kernel space).
- * It is up to the caller to ensure that the entire guest memory range is
- * valid memory before calling this function.
  * Guest key protection is not checked.
  *
- * Returns zero on success or -EFAULT on error.
+ * Returns zero on success, -EFAULT when copying to @data failed, or
+ * PGM_ADRESSING in case @gra is outside a memslot. In this case, pgm check info
+ * is also stored to allow injecting into the guest (if applicable) using
+ * kvm_s390_inject_prog_cond().
  *
  * If an error occurs data may have been copied partially to kernel space.
  */
index dbe95ec5917e57f79a55033a1768c8945079cf6a..d4f19d33914cbc91b6280bceabc5c6482d764d0b 100644 (file)
@@ -280,18 +280,19 @@ static void __zpci_event_error(struct zpci_ccdf_err *ccdf)
                goto no_pdev;
 
        switch (ccdf->pec) {
-       case 0x003a: /* Service Action or Error Recovery Successful */
+       case 0x002a: /* Error event concerns FMB */
+       case 0x002b:
+       case 0x002c:
+               break;
+       case 0x0040: /* Service Action or Error Recovery Failed */
+       case 0x003b:
+               zpci_event_io_failure(pdev, pci_channel_io_perm_failure);
+               break;
+       default: /* PCI function left in the error state attempt to recover */
                ers_res = zpci_event_attempt_error_recovery(pdev);
                if (ers_res != PCI_ERS_RESULT_RECOVERED)
                        zpci_event_io_failure(pdev, pci_channel_io_perm_failure);
                break;
-       default:
-               /*
-                * Mark as frozen not permanently failed because the device
-                * could be subsequently recovered by the platform.
-                */
-               zpci_event_io_failure(pdev, pci_channel_io_frozen);
-               break;
        }
        pci_dev_put(pdev);
 no_pdev:
index fee4f25555cb53e90463c7cd4e1fbf19a2e383b9..70752c7bc55f2f170562a7e0827b4b269917b945 100644 (file)
@@ -9,7 +9,7 @@
 #ifndef __ASM_SH_FLAT_H
 #define __ASM_SH_FLAT_H
 
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 static inline int flat_get_addr_from_rp(u32 __user *rp, u32 relval, u32 flags,
                                        u32 *addr)
index 45c8ae20d10957db4b35c84f27d9ecc4a216f27a..a1b54bedc92935753e624794bca9ab205d0a3402 100644 (file)
@@ -24,7 +24,7 @@
 #include <asm/dwarf.h>
 #include <asm/unwinder.h>
 #include <asm/sections.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include <asm/stacktrace.h>
 
 /* Reserve enough memory for two stack frames */
index b9cee98a754e5129eb067bb9660ea900bd0a969c..a469a80840d3deeda67d4f6c73c1f03793d9828d 100644 (file)
@@ -18,7 +18,7 @@
 #include <linux/fs.h>
 #include <linux/string.h>
 #include <linux/kernel.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include <asm/dwarf.h>
 
 int apply_relocate_add(Elf32_Shdr *sechdrs,
index 688db0dcb97d92d746c3c51c194760bb804bd493..913b9a09e885de313b6afbc68c81f8e0b17e231a 100644 (file)
@@ -20,7 +20,7 @@
 
 #include <asm/pstate.h>
 #include <asm/elf.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #include "opcodes.h"
 
index 6100819681b5cb6cbc7deb0509c7b01280035f14..744e7f31e8ef1774c8d6dd24d68e6ee39d7acd6b 100644 (file)
@@ -14,7 +14,7 @@
 #include <linux/virtio-uml.h>
 #include <linux/delay.h>
 #include <linux/msi.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include <irq_kern.h>
 
 #define MAX_DEVICES 8
index 7d9d60e41e4e3977ac87a320c22298f86ffc0a02..1d4b6bbc1b65ceb2a32154cdac20e5efc42fe42f 100644 (file)
@@ -8,7 +8,7 @@
 #define __UM_UACCESS_H
 
 #include <asm/elf.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #define __under_task_size(addr, size) \
        (((unsigned long) (addr) < TASK_SIZE) && \
index 2852fcd82cbd8c48983c92f0b6634a1c475b9404..16354dfa6d965042e46fde64092c6230cd1d9eaa 100644 (file)
@@ -2257,6 +2257,7 @@ config RANDOMIZE_MEMORY_PHYSICAL_PADDING
 config ADDRESS_MASKING
        bool "Linear Address Masking support"
        depends on X86_64
+       depends on COMPILE_TEST || !CPU_MITIGATIONS # wait for LASS
        help
          Linear Address Masking (LAM) modifies the checking that is applied
          to 64-bit linear addresses, allowing software to use of the
index d45e9c0c42acf7b072f08a8d823f194c8a4a8756..f110708c8038c78ebd5a69a4c3de4535ec35f118 100644 (file)
@@ -8,7 +8,7 @@
  *  Copyright (C) 2006 NTT (Nippon Telegraph and Telephone Corporation)
  */
 
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include <linux/crypto.h>
 #include <linux/init.h>
 #include <linux/module.h>
index 700ecaee9a08aabfdfa6a659db09a471b0f5e119..41bc02e489160cfb99eba0edc10f51794841f32a 100644 (file)
@@ -19,7 +19,7 @@
 #include <crypto/internal/simd.h>
 #include <asm/cpu_device_id.h>
 #include <asm/simd.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #define GHASH_BLOCK_SIZE       16
 #define GHASH_DIGEST_SIZE      16
index d9feadffa972dadf0e2dcf5804ac50f9827d6c07..324686bca36813a16168fda28bf0875b23457efc 100644 (file)
@@ -9,6 +9,8 @@
 #include <asm/unwind_hints.h>
 #include <asm/segment.h>
 #include <asm/cache.h>
+#include <asm/cpufeatures.h>
+#include <asm/nospec-branch.h>
 
 #include "calling.h"
 
@@ -19,6 +21,9 @@ SYM_FUNC_START(entry_ibpb)
        movl    $PRED_CMD_IBPB, %eax
        xorl    %edx, %edx
        wrmsr
+
+       /* Make sure IBPB clears return stack preductions too. */
+       FILL_RETURN_BUFFER %rax, RSB_CLEAR_LOOPS, X86_BUG_IBPB_NO_RET
        RET
 SYM_FUNC_END(entry_ibpb)
 /* For KVM */
index d3a814efbff66318b8f2f750aa1d3a0906036aca..20be5758c2d2e235484e32329068233eb8a72d85 100644 (file)
@@ -871,6 +871,8 @@ SYM_FUNC_START(entry_SYSENTER_32)
 
        /* Now ready to switch the cr3 */
        SWITCH_TO_USER_CR3 scratch_reg=%eax
+       /* Clobbers ZF */
+       CLEAR_CPU_BUFFERS
 
        /*
         * Restore all flags except IF. (We restore IF separately because
@@ -881,7 +883,6 @@ SYM_FUNC_START(entry_SYSENTER_32)
        BUG_IF_WRONG_CR3 no_user_check=1
        popfl
        popl    %eax
-       CLEAR_CPU_BUFFERS
 
        /*
         * Return back to the vDSO, which will pop ecx and edx.
@@ -1144,7 +1145,6 @@ SYM_CODE_START(asm_exc_nmi)
 
        /* Not on SYSENTER stack. */
        call    exc_nmi
-       CLEAR_CPU_BUFFERS
        jmp     .Lnmi_return
 
 .Lnmi_from_sysenter_stack:
@@ -1165,6 +1165,7 @@ SYM_CODE_START(asm_exc_nmi)
 
        CHECK_AND_APPLY_ESPFIX
        RESTORE_ALL_NMI cr3_reg=%edi pop=4
+       CLEAR_CPU_BUFFERS
        jmp     .Lirq_return
 
 #ifdef CONFIG_X86_ESPFIX32
@@ -1206,6 +1207,7 @@ SYM_CODE_START(asm_exc_nmi)
         *  1 - orig_ax
         */
        lss     (1+5+6)*4(%esp), %esp                   # back to espfix stack
+       CLEAR_CPU_BUFFERS
        jmp     .Lirq_return
 #endif
 SYM_CODE_END(asm_exc_nmi)
index 6f3b6aef47ba998736bd1b92a03d56a43afc6dd2..d0caac26533f22e78c4776b4921102df5edd423b 100644 (file)
@@ -116,7 +116,10 @@ static inline bool amd_gart_present(void)
 
 #define amd_nb_num(x)          0
 #define amd_nb_has_feature(x)  false
-#define node_to_amd_nb(x)      NULL
+static inline struct amd_northbridge *node_to_amd_nb(int node)
+{
+       return NULL;
+}
 #define amd_gart_present(x)    false
 
 #endif
index dd4682857c12083c099b1aee6c47df77287bb179..913fd3a7bac6506141de65f33b9ee61c615c7d7d 100644 (file)
 #define X86_FEATURE_SPEC_STORE_BYPASS_DISABLE  ( 7*32+23) /* Disable Speculative Store Bypass. */
 #define X86_FEATURE_LS_CFG_SSBD                ( 7*32+24)  /* AMD SSBD implementation via LS_CFG MSR */
 #define X86_FEATURE_IBRS               ( 7*32+25) /* "ibrs" Indirect Branch Restricted Speculation */
-#define X86_FEATURE_IBPB               ( 7*32+26) /* "ibpb" Indirect Branch Prediction Barrier */
+#define X86_FEATURE_IBPB               ( 7*32+26) /* "ibpb" Indirect Branch Prediction Barrier without a guaranteed RSB flush */
 #define X86_FEATURE_STIBP              ( 7*32+27) /* "stibp" Single Thread Indirect Branch Predictors */
 #define X86_FEATURE_ZEN                        ( 7*32+28) /* Generic flag for all Zen and newer */
 #define X86_FEATURE_L1TF_PTEINV                ( 7*32+29) /* L1TF workaround PTE inversion */
 #define X86_FEATURE_CPPC               (13*32+27) /* "cppc" Collaborative Processor Performance Control */
 #define X86_FEATURE_AMD_PSFD            (13*32+28) /* Predictive Store Forwarding Disable */
 #define X86_FEATURE_BTC_NO             (13*32+29) /* Not vulnerable to Branch Type Confusion */
+#define X86_FEATURE_AMD_IBPB_RET       (13*32+30) /* IBPB clears return address predictor */
 #define X86_FEATURE_BRS                        (13*32+31) /* "brs" Branch Sampling available */
 
 /* Thermal and Power Management Leaf, CPUID level 0x00000006 (EAX), word 14 */
 #define X86_BUG_DIV0                   X86_BUG(1*32 + 1) /* "div0" AMD DIV0 speculation bug */
 #define X86_BUG_RFDS                   X86_BUG(1*32 + 2) /* "rfds" CPU is vulnerable to Register File Data Sampling */
 #define X86_BUG_BHI                    X86_BUG(1*32 + 3) /* "bhi" CPU is affected by Branch History Injection */
+#define X86_BUG_IBPB_NO_RET            X86_BUG(1*32 + 4) /* "ibpb_no_ret" IBPB omits return target predictions */
 #endif /* _ASM_X86_CPUFEATURES_H */
index 0152a81d9b4a2e295fe758475aa2f1b7954a6a6c..b4d719de2c845924efc47cebe5536c2f2bbd16c6 100644 (file)
@@ -2,6 +2,8 @@
 #ifndef _ASM_X86_FTRACE_H
 #define _ASM_X86_FTRACE_H
 
+#include <asm/ptrace.h>
+
 #ifdef CONFIG_FUNCTION_TRACER
 #ifndef CC_USING_FENTRY
 # error Compiler does not support fentry?
index ff5f1ecc7d1e6512fcc34f4a6e5df5976e9087f0..96b410b1d4e841eb02f53a4691ee794ceee4ad2c 100644 (file)
  * Note: Only the memory operand variant of VERW clears the CPU buffers.
  */
 .macro CLEAR_CPU_BUFFERS
-       ALTERNATIVE "", __stringify(verw _ASM_RIP(mds_verw_sel)), X86_FEATURE_CLEAR_CPU_BUF
+#ifdef CONFIG_X86_64
+       ALTERNATIVE "", "verw mds_verw_sel(%rip)", X86_FEATURE_CLEAR_CPU_BUF
+#else
+       /*
+        * In 32bit mode, the memory operand must be a %cs reference. The data
+        * segments may not be usable (vm86 mode), and the stack segment may not
+        * be flat (ESPFIX32).
+        */
+       ALTERNATIVE "", "verw %cs:mds_verw_sel", X86_FEATURE_CLEAR_CPU_BUF
+#endif
 .endm
 
 #ifdef CONFIG_X86_64
index c02183d3cdd7e8d5c712fb2d04b3b080ea653f80..ecd58ea9a837b194b62fcba3946e7557c007c996 100644 (file)
@@ -26,7 +26,7 @@ void __noreturn machine_real_restart(unsigned int type);
 #define MRR_APM                1
 
 typedef void (cpu_emergency_virt_cb)(void);
-#if IS_ENABLED(CONFIG_KVM_INTEL) || IS_ENABLED(CONFIG_KVM_AMD)
+#if IS_ENABLED(CONFIG_KVM_X86)
 void cpu_emergency_register_virt_callback(cpu_emergency_virt_cb *callback);
 void cpu_emergency_unregister_virt_callback(cpu_emergency_virt_cb *callback);
 void cpu_emergency_disable_virtualization(void);
@@ -34,7 +34,7 @@ void cpu_emergency_disable_virtualization(void);
 static inline void cpu_emergency_register_virt_callback(cpu_emergency_virt_cb *callback) {}
 static inline void cpu_emergency_unregister_virt_callback(cpu_emergency_virt_cb *callback) {}
 static inline void cpu_emergency_disable_virtualization(void) {}
-#endif /* CONFIG_KVM_INTEL || CONFIG_KVM_AMD */
+#endif /* CONFIG_KVM_X86 */
 
 typedef void (*nmi_shootdown_cb)(int, struct pt_regs*);
 void nmi_shootdown_cpus(nmi_shootdown_cb callback);
index 24e3a53ca2551e939dec29a1cfad6d234a1c46bb..6652ebddfd02f89086de06713410039b283ad6b5 100644 (file)
@@ -6,7 +6,7 @@
        typeof(sym) __ret;                                      \
        asm_inline("mov %1,%0\n1:\n"                            \
                ".pushsection runtime_ptr_" #sym ",\"a\"\n\t"   \
-               ".long 1b - %c2 - .\n\t"                        \
+               ".long 1b - %c2 - .\n"                          \
                ".popsection"                                   \
                :"=r" (__ret)                                   \
                :"i" ((unsigned long)0x0123456789abcdefull),    \
@@ -20,7 +20,7 @@
        typeof(0u+(val)) __ret = (val);                         \
        asm_inline("shrl $12,%k0\n1:\n"                         \
                ".pushsection runtime_shift_" #sym ",\"a\"\n\t" \
-               ".long 1b - 1 - .\n\t"                          \
+               ".long 1b - 1 - .\n"                            \
                ".popsection"                                   \
                :"+r" (__ret));                                 \
        __ret; })
index afce8ee5d7b7947afd768a43c5351e123de68939..b0a887209400de33aa24e75f00af64d72600291d 100644 (file)
 #include <asm/cpufeatures.h>
 #include <asm/page.h>
 #include <asm/percpu.h>
+#include <asm/runtime-const.h>
+
+/*
+ * Virtual variable: there's no actual backing store for this,
+ * it can purely be used as 'runtime_const_ptr(USER_PTR_MAX)'
+ */
+extern unsigned long USER_PTR_MAX;
 
 #ifdef CONFIG_ADDRESS_MASKING
 /*
@@ -46,19 +53,24 @@ static inline unsigned long __untagged_addr_remote(struct mm_struct *mm,
 
 #endif
 
-/*
- * The virtual address space space is logically divided into a kernel
- * half and a user half.  When cast to a signed type, user pointers
- * are positive and kernel pointers are negative.
- */
-#define valid_user_address(x) ((__force long)(x) >= 0)
+#define valid_user_address(x) \
+       ((__force unsigned long)(x) <= runtime_const_ptr(USER_PTR_MAX))
 
 /*
  * Masking the user address is an alternative to a conditional
  * user_access_begin that can avoid the fencing. This only works
  * for dense accesses starting at the address.
  */
-#define mask_user_address(x) ((typeof(x))((long)(x)|((long)(x)>>63)))
+static inline void __user *mask_user_address(const void __user *ptr)
+{
+       unsigned long mask;
+       asm("cmp %1,%0\n\t"
+           "sbb %0,%0"
+               :"=r" (mask)
+               :"r" (ptr),
+                "0" (runtime_const_ptr(USER_PTR_MAX)));
+       return (__force void __user *)(mask | (__force unsigned long)ptr);
+}
 #define masked_user_access_begin(x) ({                         \
        __auto_type __masked_ptr = (x);                         \
        __masked_ptr = mask_user_address(__masked_ptr);         \
@@ -69,23 +81,16 @@ static inline unsigned long __untagged_addr_remote(struct mm_struct *mm,
  * arbitrary values in those bits rather then masking them off.
  *
  * Enforce two rules:
- * 1. 'ptr' must be in the user half of the address space
+ * 1. 'ptr' must be in the user part of the address space
  * 2. 'ptr+size' must not overflow into kernel addresses
  *
- * Note that addresses around the sign change are not valid addresses,
- * and will GP-fault even with LAM enabled if the sign bit is set (see
- * "CR3.LAM_SUP" that can narrow the canonicality check if we ever
- * enable it, but not remove it entirely).
- *
- * So the "overflow into kernel addresses" does not imply some sudden
- * exact boundary at the sign bit, and we can allow a lot of slop on the
- * size check.
+ * Note that we always have at least one guard page between the
+ * max user address and the non-canonical gap, allowing us to
+ * ignore small sizes entirely.
  *
  * In fact, we could probably remove the size check entirely, since
  * any kernel accesses will be in increasing address order starting
- * at 'ptr', and even if the end might be in kernel space, we'll
- * hit the GP faults for non-canonical accesses before we ever get
- * there.
+ * at 'ptr'.
  *
  * That's a separate optimization, for now just handle the small
  * constant case.
index dc5d3216af2404a8aba37bb7708a136c3f45ffc3..9fe9972d2071b90c3aa47b8ca0e8ce19c88c6aec 100644 (file)
@@ -44,6 +44,7 @@
 #define PCI_DEVICE_ID_AMD_19H_M70H_DF_F4       0x14f4
 #define PCI_DEVICE_ID_AMD_19H_M78H_DF_F4       0x12fc
 #define PCI_DEVICE_ID_AMD_1AH_M00H_DF_F4       0x12c4
+#define PCI_DEVICE_ID_AMD_1AH_M20H_DF_F4       0x16fc
 #define PCI_DEVICE_ID_AMD_1AH_M60H_DF_F4       0x124c
 #define PCI_DEVICE_ID_AMD_1AH_M70H_DF_F4       0x12bc
 #define PCI_DEVICE_ID_AMD_MI200_DF_F4          0x14d4
@@ -127,6 +128,7 @@ static const struct pci_device_id amd_nb_link_ids[] = {
        { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_19H_M78H_DF_F4) },
        { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_CNB17H_F4) },
        { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_1AH_M00H_DF_F4) },
+       { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_1AH_M20H_DF_F4) },
        { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_1AH_M60H_DF_F4) },
        { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_1AH_M70H_DF_F4) },
        { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_MI200_DF_F4) },
index 6513c53c9459eb89ea5f07389d61ae0888a86889..c5fb28e6451a3415a7af8576285b0a3ae633e6b9 100644 (file)
@@ -440,7 +440,19 @@ static int lapic_timer_shutdown(struct clock_event_device *evt)
        v = apic_read(APIC_LVTT);
        v |= (APIC_LVT_MASKED | LOCAL_TIMER_VECTOR);
        apic_write(APIC_LVTT, v);
-       apic_write(APIC_TMICT, 0);
+
+       /*
+        * Setting APIC_LVT_MASKED (above) should be enough to tell
+        * the hardware that this timer will never fire. But AMD
+        * erratum 411 and some Intel CPU behavior circa 2024 say
+        * otherwise.  Time for belt and suspenders programming: mask
+        * the timer _and_ zero the counter registers:
+        */
+       if (v & APIC_LVT_TIMER_TSCDEADLINE)
+               wrmsrl(MSR_IA32_TSC_DEADLINE, 0);
+       else
+               apic_write(APIC_TMICT, 0);
+
        return 0;
 }
 
index 015971adadfc7e3604be34f8d7e46383300a1fe4..fab5caec0b72e485e8232406e0ddf7a889a74104 100644 (file)
@@ -1202,5 +1202,6 @@ void amd_check_microcode(void)
        if (boot_cpu_data.x86_vendor != X86_VENDOR_AMD)
                return;
 
-       on_each_cpu(zenbleed_check_cpu, NULL, 1);
+       if (cpu_feature_enabled(X86_FEATURE_ZEN2))
+               on_each_cpu(zenbleed_check_cpu, NULL, 1);
 }
index d1915427b4ffcb1141452b0fe5bb8872ab2ae1da..47a01d4028f60e012d1e625e1667842b52948038 100644 (file)
@@ -1115,8 +1115,25 @@ do_cmd_auto:
 
        case RETBLEED_MITIGATION_IBPB:
                setup_force_cpu_cap(X86_FEATURE_ENTRY_IBPB);
+
+               /*
+                * IBPB on entry already obviates the need for
+                * software-based untraining so clear those in case some
+                * other mitigation like SRSO has selected them.
+                */
+               setup_clear_cpu_cap(X86_FEATURE_UNRET);
+               setup_clear_cpu_cap(X86_FEATURE_RETHUNK);
+
                setup_force_cpu_cap(X86_FEATURE_IBPB_ON_VMEXIT);
                mitigate_smt = true;
+
+               /*
+                * There is no need for RSB filling: entry_ibpb() ensures
+                * all predictions, including the RSB, are invalidated,
+                * regardless of IBPB implementation.
+                */
+               setup_clear_cpu_cap(X86_FEATURE_RSB_VMEXIT);
+
                break;
 
        case RETBLEED_MITIGATION_STUFF:
@@ -2627,6 +2644,14 @@ static void __init srso_select_mitigation(void)
                        if (has_microcode) {
                                setup_force_cpu_cap(X86_FEATURE_ENTRY_IBPB);
                                srso_mitigation = SRSO_MITIGATION_IBPB;
+
+                               /*
+                                * IBPB on entry already obviates the need for
+                                * software-based untraining so clear those in case some
+                                * other mitigation like Retbleed has selected them.
+                                */
+                               setup_clear_cpu_cap(X86_FEATURE_UNRET);
+                               setup_clear_cpu_cap(X86_FEATURE_RETHUNK);
                        }
                } else {
                        pr_err("WARNING: kernel not compiled with MITIGATION_IBPB_ENTRY.\n");
@@ -2638,6 +2663,13 @@ static void __init srso_select_mitigation(void)
                        if (!boot_cpu_has(X86_FEATURE_ENTRY_IBPB) && has_microcode) {
                                setup_force_cpu_cap(X86_FEATURE_IBPB_ON_VMEXIT);
                                srso_mitigation = SRSO_MITIGATION_IBPB_ON_VMEXIT;
+
+                               /*
+                                * There is no need for RSB filling: entry_ibpb() ensures
+                                * all predictions, including the RSB, are invalidated,
+                                * regardless of IBPB implementation.
+                                */
+                               setup_clear_cpu_cap(X86_FEATURE_RSB_VMEXIT);
                        }
                } else {
                        pr_err("WARNING: kernel not compiled with MITIGATION_SRSO.\n");
index 07a34d723505741c2308e27a6a349e0c78717580..a5f221ea5688851020e305fbbe32005b80a5e90a 100644 (file)
@@ -69,6 +69,7 @@
 #include <asm/sev.h>
 #include <asm/tdx.h>
 #include <asm/posted_intr.h>
+#include <asm/runtime-const.h>
 
 #include "cpu.h"
 
@@ -1443,6 +1444,9 @@ static void __init cpu_set_bug_bits(struct cpuinfo_x86 *c)
             boot_cpu_has(X86_FEATURE_HYPERVISOR)))
                setup_force_cpu_bug(X86_BUG_BHI);
 
+       if (cpu_has(c, X86_FEATURE_AMD_IBPB) && !cpu_has(c, X86_FEATURE_AMD_IBPB_RET))
+               setup_force_cpu_bug(X86_BUG_IBPB_NO_RET);
+
        if (cpu_matches(cpu_vuln_whitelist, NO_MELTDOWN))
                return;
 
@@ -2386,6 +2390,15 @@ void __init arch_cpu_finalize_init(void)
        alternative_instructions();
 
        if (IS_ENABLED(CONFIG_X86_64)) {
+               unsigned long USER_PTR_MAX = TASK_SIZE_MAX-1;
+
+               /*
+                * Enable this when LAM is gated on LASS support
+               if (cpu_feature_enabled(X86_FEATURE_LAM))
+                       USER_PTR_MAX = (1ul << 63) - PAGE_SIZE - 1;
+                */
+               runtime_const_init(ptr, USER_PTR_MAX);
+
                /*
                 * Make sure the first 2MB area is not mapped by huge pages
                 * There are typically fixed size MTRRs in there and overlapping
index f63b051f25a0a982747045b0921eacccc4a0fe68..31a73715d7553142ba6291078698d8fb8eb40d87 100644 (file)
@@ -584,7 +584,7 @@ void __init load_ucode_amd_bsp(struct early_load_data *ed, unsigned int cpuid_1_
                native_rdmsr(MSR_AMD64_PATCH_LEVEL, ed->new_rev, dummy);
 }
 
-static enum ucode_state load_microcode_amd(u8 family, const u8 *data, size_t size);
+static enum ucode_state _load_microcode_amd(u8 family, const u8 *data, size_t size);
 
 static int __init save_microcode_in_initrd(void)
 {
@@ -605,7 +605,7 @@ static int __init save_microcode_in_initrd(void)
        if (!desc.mc)
                return -EINVAL;
 
-       ret = load_microcode_amd(x86_family(cpuid_1_eax), desc.data, desc.size);
+       ret = _load_microcode_amd(x86_family(cpuid_1_eax), desc.data, desc.size);
        if (ret > UCODE_UPDATED)
                return -EINVAL;
 
@@ -613,16 +613,19 @@ static int __init save_microcode_in_initrd(void)
 }
 early_initcall(save_microcode_in_initrd);
 
-static inline bool patch_cpus_equivalent(struct ucode_patch *p, struct ucode_patch *n)
+static inline bool patch_cpus_equivalent(struct ucode_patch *p,
+                                        struct ucode_patch *n,
+                                        bool ignore_stepping)
 {
        /* Zen and newer hardcode the f/m/s in the patch ID */
         if (x86_family(bsp_cpuid_1_eax) >= 0x17) {
                union cpuid_1_eax p_cid = ucode_rev_to_cpuid(p->patch_id);
                union cpuid_1_eax n_cid = ucode_rev_to_cpuid(n->patch_id);
 
-               /* Zap stepping */
-               p_cid.stepping = 0;
-               n_cid.stepping = 0;
+               if (ignore_stepping) {
+                       p_cid.stepping = 0;
+                       n_cid.stepping = 0;
+               }
 
                return p_cid.full == n_cid.full;
        } else {
@@ -644,13 +647,13 @@ static struct ucode_patch *cache_find_patch(struct ucode_cpu_info *uci, u16 equi
        WARN_ON_ONCE(!n.patch_id);
 
        list_for_each_entry(p, &microcode_cache, plist)
-               if (patch_cpus_equivalent(p, &n))
+               if (patch_cpus_equivalent(p, &n, false))
                        return p;
 
        return NULL;
 }
 
-static inline bool patch_newer(struct ucode_patch *p, struct ucode_patch *n)
+static inline int patch_newer(struct ucode_patch *p, struct ucode_patch *n)
 {
        /* Zen and newer hardcode the f/m/s in the patch ID */
         if (x86_family(bsp_cpuid_1_eax) >= 0x17) {
@@ -659,6 +662,9 @@ static inline bool patch_newer(struct ucode_patch *p, struct ucode_patch *n)
                zp.ucode_rev = p->patch_id;
                zn.ucode_rev = n->patch_id;
 
+               if (zn.stepping != zp.stepping)
+                       return -1;
+
                return zn.rev > zp.rev;
        } else {
                return n->patch_id > p->patch_id;
@@ -668,10 +674,14 @@ static inline bool patch_newer(struct ucode_patch *p, struct ucode_patch *n)
 static void update_cache(struct ucode_patch *new_patch)
 {
        struct ucode_patch *p;
+       int ret;
 
        list_for_each_entry(p, &microcode_cache, plist) {
-               if (patch_cpus_equivalent(p, new_patch)) {
-                       if (!patch_newer(p, new_patch)) {
+               if (patch_cpus_equivalent(p, new_patch, true)) {
+                       ret = patch_newer(p, new_patch);
+                       if (ret < 0)
+                               continue;
+                       else if (!ret) {
                                /* we already have the latest patch */
                                kfree(new_patch->data);
                                kfree(new_patch);
@@ -944,21 +954,30 @@ static enum ucode_state __load_microcode_amd(u8 family, const u8 *data,
        return UCODE_OK;
 }
 
-static enum ucode_state load_microcode_amd(u8 family, const u8 *data, size_t size)
+static enum ucode_state _load_microcode_amd(u8 family, const u8 *data, size_t size)
 {
-       struct cpuinfo_x86 *c;
-       unsigned int nid, cpu;
-       struct ucode_patch *p;
        enum ucode_state ret;
 
        /* free old equiv table */
        free_equiv_cpu_table();
 
        ret = __load_microcode_amd(family, data, size);
-       if (ret != UCODE_OK) {
+       if (ret != UCODE_OK)
                cleanup();
+
+       return ret;
+}
+
+static enum ucode_state load_microcode_amd(u8 family, const u8 *data, size_t size)
+{
+       struct cpuinfo_x86 *c;
+       unsigned int nid, cpu;
+       struct ucode_patch *p;
+       enum ucode_state ret;
+
+       ret = _load_microcode_amd(family, data, size);
+       if (ret != UCODE_OK)
                return ret;
-       }
 
        for_each_node(nid) {
                cpu = cpumask_first(cpumask_of_node(nid));
index 8591d53c144bb17bd7f33077da05a9330e7c5e5e..b681c2e07dbf8464fa11779b4ae954f0adb8287e 100644 (file)
@@ -207,7 +207,7 @@ static inline bool rdt_get_mb_table(struct rdt_resource *r)
        return false;
 }
 
-static bool __get_mem_config_intel(struct rdt_resource *r)
+static __init bool __get_mem_config_intel(struct rdt_resource *r)
 {
        struct rdt_hw_resource *hw_res = resctrl_to_arch_res(r);
        union cpuid_0x10_3_eax eax;
@@ -241,7 +241,7 @@ static bool __get_mem_config_intel(struct rdt_resource *r)
        return true;
 }
 
-static bool __rdt_get_mem_config_amd(struct rdt_resource *r)
+static __init bool __rdt_get_mem_config_amd(struct rdt_resource *r)
 {
        struct rdt_hw_resource *hw_res = resctrl_to_arch_res(r);
        u32 eax, ebx, ecx, edx, subleaf;
index 50fa1fe9a073f5832e687d01a88c1efcc91e22c9..200d89a6402708066bf165487577e142c73b057b 100644 (file)
  * hardware. The allocated bandwidth percentage is rounded to the next
  * control step available on the hardware.
  */
-static bool bw_validate(char *buf, unsigned long *data, struct rdt_resource *r)
+static bool bw_validate(char *buf, u32 *data, struct rdt_resource *r)
 {
-       unsigned long bw;
        int ret;
+       u32 bw;
 
        /*
         * Only linear delay values is supported for current Intel SKUs.
@@ -42,16 +42,21 @@ static bool bw_validate(char *buf, unsigned long *data, struct rdt_resource *r)
                return false;
        }
 
-       ret = kstrtoul(buf, 10, &bw);
+       ret = kstrtou32(buf, 10, &bw);
        if (ret) {
-               rdt_last_cmd_printf("Non-decimal digit in MB value %s\n", buf);
+               rdt_last_cmd_printf("Invalid MB value %s\n", buf);
                return false;
        }
 
-       if ((bw < r->membw.min_bw || bw > r->default_ctrl) &&
-           !is_mba_sc(r)) {
-               rdt_last_cmd_printf("MB value %ld out of range [%d,%d]\n", bw,
-                                   r->membw.min_bw, r->default_ctrl);
+       /* Nothing else to do if software controller is enabled. */
+       if (is_mba_sc(r)) {
+               *data = bw;
+               return true;
+       }
+
+       if (bw < r->membw.min_bw || bw > r->default_ctrl) {
+               rdt_last_cmd_printf("MB value %u out of range [%d,%d]\n",
+                                   bw, r->membw.min_bw, r->default_ctrl);
                return false;
        }
 
@@ -65,7 +70,7 @@ int parse_bw(struct rdt_parse_data *data, struct resctrl_schema *s,
        struct resctrl_staged_config *cfg;
        u32 closid = data->rdtgrp->closid;
        struct rdt_resource *r = s->res;
-       unsigned long bw_val;
+       u32 bw_val;
 
        cfg = &d->staged_config[s->conf_type];
        if (cfg->have_new_ctrl) {
index 263f8aed4e2cf8b84575d21e4b4358b2924915b5..21e9e4845354159cf289eb765a63e80e69a12e25 100644 (file)
@@ -37,6 +37,7 @@
 #include <asm/apic.h>
 #include <asm/apicdef.h>
 #include <asm/hypervisor.h>
+#include <asm/mtrr.h>
 #include <asm/tlb.h>
 #include <asm/cpuidle_haltpoll.h>
 #include <asm/ptrace.h>
@@ -980,6 +981,9 @@ static void __init kvm_init_platform(void)
        }
        kvmclock_init();
        x86_platform.apic_post_init = kvm_apic_init;
+
+       /* Set WB as the default cache mode for SEV-SNP and TDX */
+       mtrr_overwrite_state(NULL, 0, MTRR_TYPE_WRBACK);
 }
 
 #if defined(CONFIG_AMD_MEM_ENCRYPT)
index 0e0a4cf6b5eb1702d61a94583e69f26a228d1940..615922838c510bdd634f50cfba5f385b18b0c587 100644 (file)
@@ -530,7 +530,7 @@ static inline void kb_wait(void)
 
 static inline void nmi_shootdown_cpus_on_restart(void);
 
-#if IS_ENABLED(CONFIG_KVM_INTEL) || IS_ENABLED(CONFIG_KVM_AMD)
+#if IS_ENABLED(CONFIG_KVM_X86)
 /* RCU-protected callback to disable virtualization prior to reboot. */
 static cpu_emergency_virt_cb __rcu *cpu_emergency_virt_callback;
 
@@ -600,7 +600,7 @@ static void emergency_reboot_disable_virtualization(void)
 }
 #else
 static void emergency_reboot_disable_virtualization(void) { }
-#endif /* CONFIG_KVM_INTEL || CONFIG_KVM_AMD */
+#endif /* CONFIG_KVM_X86 */
 
 void __attribute__((weak)) mach_reboot_fixups(void)
 {
index d05392db5d0fecbc2740f83086567c1f040fc2ea..2dbadf347b5f4f66625c4f49b76c41b412270d57 100644 (file)
@@ -261,12 +261,6 @@ static noinstr bool handle_bug(struct pt_regs *regs)
        int ud_type;
        u32 imm;
 
-       /*
-        * Normally @regs are unpoisoned by irqentry_enter(), but handle_bug()
-        * is a rare case that uses @regs without passing them to
-        * irqentry_enter().
-        */
-       kmsan_unpoison_entry_regs(regs);
        ud_type = decode_bug(regs->ip, &imm);
        if (ud_type == BUG_NONE)
                return handled;
@@ -275,6 +269,12 @@ static noinstr bool handle_bug(struct pt_regs *regs)
         * All lies, just get the WARN/BUG out.
         */
        instrumentation_begin();
+       /*
+        * Normally @regs are unpoisoned by irqentry_enter(), but handle_bug()
+        * is a rare case that uses @regs without passing them to
+        * irqentry_enter().
+        */
+       kmsan_unpoison_entry_regs(regs);
        /*
         * Since we're emulating a CALL with exceptions, restore the interrupt
         * state to what it was at the exception site.
index 6726be89b7a663a1554f8f4b297bba65b4ebdf61..b8c5741d2fb48017813060c977f4c31356168d5d 100644 (file)
@@ -358,6 +358,7 @@ SECTIONS
 #endif
 
        RUNTIME_CONST_VARIABLES
+       RUNTIME_CONST(ptr, USER_PTR_MAX)
 
        . = ALIGN(PAGE_SIZE);
 
index 730c2f34d3479676224d0268a5969002798d98d1..f09f13c01c6bbd28fa37fdf50547abf4403658c9 100644 (file)
@@ -17,8 +17,8 @@ menuconfig VIRTUALIZATION
 
 if VIRTUALIZATION
 
-config KVM
-       tristate "Kernel-based Virtual Machine (KVM) support"
+config KVM_X86
+       def_tristate KVM if KVM_INTEL || KVM_AMD
        depends on X86_LOCAL_APIC
        select KVM_COMMON
        select KVM_GENERIC_MMU_NOTIFIER
@@ -44,7 +44,11 @@ config KVM
        select HAVE_KVM_PM_NOTIFIER if PM
        select KVM_GENERIC_HARDWARE_ENABLING
        select KVM_GENERIC_PRE_FAULT_MEMORY
+       select KVM_GENERIC_PRIVATE_MEM if KVM_SW_PROTECTED_VM
        select KVM_WERROR if WERROR
+
+config KVM
+       tristate "Kernel-based Virtual Machine (KVM) support"
        help
          Support hosting fully virtualized guest machines using hardware
          virtualization extensions.  You will need a fairly recent
@@ -77,7 +81,6 @@ config KVM_SW_PROTECTED_VM
        bool "Enable support for KVM software-protected VMs"
        depends on EXPERT
        depends on KVM && X86_64
-       select KVM_GENERIC_PRIVATE_MEM
        help
          Enable support for KVM software-protected VMs.  Currently, software-
          protected VMs are purely a development and testing vehicle for
index 5494669a055a6e87c2b70b358cc3166d7fa29509..f9dddb8cb46698a15468bfb6e442803edc811021 100644 (file)
@@ -32,7 +32,7 @@ kvm-intel-y           += vmx/vmx_onhyperv.o vmx/hyperv_evmcs.o
 kvm-amd-y              += svm/svm_onhyperv.o
 endif
 
-obj-$(CONFIG_KVM)      += kvm.o
+obj-$(CONFIG_KVM_X86)  += kvm.o
 obj-$(CONFIG_KVM_INTEL)        += kvm-intel.o
 obj-$(CONFIG_KVM_AMD)  += kvm-amd.o
 
index e52f990548df6370a403ac5a19b69fa74caca090..8e853a5fc867b742321a78076d5bd81764abbc55 100644 (file)
@@ -1556,6 +1556,17 @@ bool kvm_unmap_gfn_range(struct kvm *kvm, struct kvm_gfn_range *range)
 {
        bool flush = false;
 
+       /*
+        * To prevent races with vCPUs faulting in a gfn using stale data,
+        * zapping a gfn range must be protected by mmu_invalidate_in_progress
+        * (and mmu_invalidate_seq).  The only exception is memslot deletion;
+        * in that case, SRCU synchronization ensures that SPTEs are zapped
+        * after all vCPUs have unlocked SRCU, guaranteeing that vCPUs see the
+        * invalid slot.
+        */
+       lockdep_assert_once(kvm->mmu_invalidate_in_progress ||
+                           lockdep_is_held(&kvm->slots_lock));
+
        if (kvm_memslots_have_rmaps(kvm))
                flush = __kvm_rmap_zap_gfn_range(kvm, range->slot,
                                                 range->start, range->end,
@@ -7047,14 +7058,42 @@ void kvm_arch_flush_shadow_all(struct kvm *kvm)
        kvm_mmu_zap_all(kvm);
 }
 
-/*
- * Zapping leaf SPTEs with memslot range when a memslot is moved/deleted.
- *
- * Zapping non-leaf SPTEs, a.k.a. not-last SPTEs, isn't required, worst
- * case scenario we'll have unused shadow pages lying around until they
- * are recycled due to age or when the VM is destroyed.
- */
-static void kvm_mmu_zap_memslot_leafs(struct kvm *kvm, struct kvm_memory_slot *slot)
+static void kvm_mmu_zap_memslot_pages_and_flush(struct kvm *kvm,
+                                               struct kvm_memory_slot *slot,
+                                               bool flush)
+{
+       LIST_HEAD(invalid_list);
+       unsigned long i;
+
+       if (list_empty(&kvm->arch.active_mmu_pages))
+               goto out_flush;
+
+       /*
+        * Since accounting information is stored in struct kvm_arch_memory_slot,
+        * all MMU pages that are shadowing guest PTEs must be zapped before the
+        * memslot is deleted, as freeing such pages after the memslot is freed
+        * will result in use-after-free, e.g. in unaccount_shadowed().
+        */
+       for (i = 0; i < slot->npages; i++) {
+               struct kvm_mmu_page *sp;
+               gfn_t gfn = slot->base_gfn + i;
+
+               for_each_gfn_valid_sp_with_gptes(kvm, sp, gfn)
+                       kvm_mmu_prepare_zap_page(kvm, sp, &invalid_list);
+
+               if (need_resched() || rwlock_needbreak(&kvm->mmu_lock)) {
+                       kvm_mmu_remote_flush_or_zap(kvm, &invalid_list, flush);
+                       flush = false;
+                       cond_resched_rwlock_write(&kvm->mmu_lock);
+               }
+       }
+
+out_flush:
+       kvm_mmu_remote_flush_or_zap(kvm, &invalid_list, flush);
+}
+
+static void kvm_mmu_zap_memslot(struct kvm *kvm,
+                               struct kvm_memory_slot *slot)
 {
        struct kvm_gfn_range range = {
                .slot = slot,
@@ -7062,11 +7101,11 @@ static void kvm_mmu_zap_memslot_leafs(struct kvm *kvm, struct kvm_memory_slot *s
                .end = slot->base_gfn + slot->npages,
                .may_block = true,
        };
+       bool flush;
 
        write_lock(&kvm->mmu_lock);
-       if (kvm_unmap_gfn_range(kvm, &range))
-               kvm_flush_remote_tlbs_memslot(kvm, slot);
-
+       flush = kvm_unmap_gfn_range(kvm, &range);
+       kvm_mmu_zap_memslot_pages_and_flush(kvm, slot, flush);
        write_unlock(&kvm->mmu_lock);
 }
 
@@ -7082,7 +7121,7 @@ void kvm_arch_flush_shadow_memslot(struct kvm *kvm,
        if (kvm_memslot_flush_zap_all(kvm))
                kvm_mmu_zap_all_fast(kvm);
        else
-               kvm_mmu_zap_memslot_leafs(kvm, slot);
+               kvm_mmu_zap_memslot(kvm, slot);
 }
 
 void kvm_mmu_invalidate_mmio_sptes(struct kvm *kvm, u64 gen)
index d5314cb7dff4ca2524b3dba584c94f7fad18b02b..cf84103ce38b97f2fedc28c426e11a9e31a882f3 100644 (file)
@@ -63,8 +63,12 @@ static u64 nested_svm_get_tdp_pdptr(struct kvm_vcpu *vcpu, int index)
        u64 pdpte;
        int ret;
 
+       /*
+        * Note, nCR3 is "assumed" to be 32-byte aligned, i.e. the CPU ignores
+        * nCR3[4:0] when loading PDPTEs from memory.
+        */
        ret = kvm_vcpu_read_guest_page(vcpu, gpa_to_gfn(cr3), &pdpte,
-                                      offset_in_page(cr3) + index * 8, 8);
+                                      (cr3 & GENMASK(11, 5)) + index * 8, 8);
        if (ret)
                return 0;
        return pdpte;
index 1a4438358c5e38ef09d5d306f026d887c14331cd..81ed596e4454c565b9a5ea001243cfbcf2d50bf2 100644 (file)
@@ -4888,9 +4888,6 @@ void vmx_vcpu_reset(struct kvm_vcpu *vcpu, bool init_event)
        vmx->hv_deadline_tsc = -1;
        kvm_set_cr8(vcpu, 0);
 
-       vmx_segment_cache_clear(vmx);
-       kvm_register_mark_available(vcpu, VCPU_EXREG_SEGMENTS);
-
        seg_setup(VCPU_SREG_CS);
        vmcs_write16(GUEST_CS_SELECTOR, 0xf000);
        vmcs_writel(GUEST_CS_BASE, 0xffff0000ul);
@@ -4917,6 +4914,9 @@ void vmx_vcpu_reset(struct kvm_vcpu *vcpu, bool init_event)
        vmcs_writel(GUEST_IDTR_BASE, 0);
        vmcs_write32(GUEST_IDTR_LIMIT, 0xffff);
 
+       vmx_segment_cache_clear(vmx);
+       kvm_register_mark_available(vcpu, VCPU_EXREG_SEGMENTS);
+
        vmcs_write32(GUEST_ACTIVITY_STATE, GUEST_ACTIVITY_ACTIVE);
        vmcs_write32(GUEST_INTERRUPTIBILITY_INFO, 0);
        vmcs_writel(GUEST_PENDING_DBG_EXCEPTIONS, 0);
index d066aecf8aeb22d4f6b01e8fe18a7101723e6491..4357ec2a0bfc2c887f64ba6fe6dc1d47b6956a53 100644 (file)
 
 .macro check_range size:req
 .if IS_ENABLED(CONFIG_X86_64)
-       mov %rax, %rdx
-       sar $63, %rdx
+       movq $0x0123456789abcdef,%rdx
+  1:
+  .pushsection runtime_ptr_USER_PTR_MAX,"a"
+       .long 1b - 8 - .
+  .popsection
+       cmp %rax, %rdx
+       sbb %rdx, %rdx
        or %rdx, %rax
 .else
        cmp $TASK_SIZE_MAX-\size+1, %eax
index 5952ab41c60f4def412a27f97e287c482b6d3832..6ffb931b9fb14ff87251a60bc61c9639497238c9 100644 (file)
@@ -13,7 +13,7 @@
 #endif
 #include <asm/inat.h> /*__ignore_sync_check__ */
 #include <asm/insn.h> /* __ignore_sync_check__ */
-#include <asm/unaligned.h> /* __ignore_sync_check__ */
+#include <linux/unaligned.h> /* __ignore_sync_check__ */
 
 #include <linux/errno.h>
 #include <linux/kconfig.h>
index 0ce17766c0e5230821cd77cf430a838772cfe1f6..9a6a943d8e410c0289200adb9deafe8e45d33a4b 100644 (file)
@@ -173,6 +173,8 @@ static void __init __snp_fixup_e820_tables(u64 pa)
                e820__range_update(pa, PMD_SIZE, E820_TYPE_RAM, E820_TYPE_RESERVED);
                e820__range_update_table(e820_table_kexec, pa, PMD_SIZE, E820_TYPE_RAM, E820_TYPE_RESERVED);
                e820__range_update_table(e820_table_firmware, pa, PMD_SIZE, E820_TYPE_RAM, E820_TYPE_RESERVED);
+               if (!memblock_is_region_reserved(pa, PMD_SIZE))
+                       memblock_reserve(pa, PMD_SIZE);
        }
 }
 
index 2c12ae42dc8bd991e9b8b618233e9b98ba63b611..d6818c6cafda1612bfe404235772555f14d67780 100644 (file)
@@ -1032,6 +1032,10 @@ static u64 xen_do_read_msr(unsigned int msr, int *err)
        switch (msr) {
        case MSR_IA32_APICBASE:
                val &= ~X2APIC_ENABLE;
+               if (smp_processor_id() == 0)
+                       val |= MSR_IA32_APICBASE_BSP;
+               else
+                       val &= ~MSR_IA32_APICBASE_BSP;
                break;
        }
        return val;
index ed5870c779f92d940609b811b635d457bece2219..4854419dcd861e120c8f9bec7be9cd134da77f83 100644 (file)
@@ -2,7 +2,7 @@
 #ifndef __ASM_XTENSA_FLAT_H
 #define __ASM_XTENSA_FLAT_H
 
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 static inline int flat_get_addr_from_rp(u32 __user *rp, u32 relval, u32 flags,
                                        u32 *addr)
index 0a2b1c5d0ebf1281f7ab2101b3cc64736530348c..83b696ba0cac3142878668fbde8a603c03853604 100644 (file)
@@ -56,8 +56,7 @@ new_segment:
 
 /**
  * blk_rq_map_integrity_sg - Map integrity metadata into a scatterlist
- * @q:         request queue
- * @bio:       bio with integrity metadata attached
+ * @rq:                request to map
  * @sglist:    target scatterlist
  *
  * Description: Map the integrity vectors in request into a
index 9dc9323f84ac1c1f722ef45047189d8215a50ef3..384aa15e8260bd4d83b00f1c03efb87829950327 100644 (file)
@@ -3166,7 +3166,7 @@ static u64 ioc_qos_prfill(struct seq_file *sf, struct blkg_policy_data *pd,
        if (!dname)
                return 0;
 
-       spin_lock_irq(&ioc->lock);
+       spin_lock(&ioc->lock);
        seq_printf(sf, "%s enable=%d ctrl=%s rpct=%u.%02u rlat=%u wpct=%u.%02u wlat=%u min=%u.%02u max=%u.%02u\n",
                   dname, ioc->enabled, ioc->user_qos_params ? "user" : "auto",
                   ioc->params.qos[QOS_RPPM] / 10000,
@@ -3179,7 +3179,7 @@ static u64 ioc_qos_prfill(struct seq_file *sf, struct blkg_policy_data *pd,
                   ioc->params.qos[QOS_MIN] % 10000 / 100,
                   ioc->params.qos[QOS_MAX] / 10000,
                   ioc->params.qos[QOS_MAX] % 10000 / 100);
-       spin_unlock_irq(&ioc->lock);
+       spin_unlock(&ioc->lock);
        return 0;
 }
 
@@ -3366,14 +3366,14 @@ static u64 ioc_cost_model_prfill(struct seq_file *sf,
        if (!dname)
                return 0;
 
-       spin_lock_irq(&ioc->lock);
+       spin_lock(&ioc->lock);
        seq_printf(sf, "%s ctrl=%s model=linear "
                   "rbps=%llu rseqiops=%llu rrandiops=%llu "
                   "wbps=%llu wseqiops=%llu wrandiops=%llu\n",
                   dname, ioc->user_cost_model ? "user" : "auto",
                   u[I_LCOEF_RBPS], u[I_LCOEF_RSEQIOPS], u[I_LCOEF_RRANDIOPS],
                   u[I_LCOEF_WBPS], u[I_LCOEF_WSEQIOPS], u[I_LCOEF_WRANDIOPS]);
-       spin_unlock_irq(&ioc->lock);
+       spin_unlock(&ioc->lock);
        return 0;
 }
 
index 0e1167b239342f71b76b54d8593435eb771bb83f..b5fd1d8574615e28da206b6e12a1b81009279fff 100644 (file)
@@ -561,57 +561,33 @@ EXPORT_SYMBOL(blk_rq_append_bio);
 /* Prepare bio for passthrough IO given ITER_BVEC iter */
 static int blk_rq_map_user_bvec(struct request *rq, const struct iov_iter *iter)
 {
-       struct request_queue *q = rq->q;
-       size_t nr_iter = iov_iter_count(iter);
-       size_t nr_segs = iter->nr_segs;
-       struct bio_vec *bvecs, *bvprvp = NULL;
-       const struct queue_limits *lim = &q->limits;
-       unsigned int nsegs = 0, bytes = 0;
+       const struct queue_limits *lim = &rq->q->limits;
+       unsigned int max_bytes = lim->max_hw_sectors << SECTOR_SHIFT;
+       unsigned int nsegs;
        struct bio *bio;
-       size_t i;
+       int ret;
 
-       if (!nr_iter || (nr_iter >> SECTOR_SHIFT) > queue_max_hw_sectors(q))
-               return -EINVAL;
-       if (nr_segs > queue_max_segments(q))
+       if (!iov_iter_count(iter) || iov_iter_count(iter) > max_bytes)
                return -EINVAL;
 
-       /* no iovecs to alloc, as we already have a BVEC iterator */
+       /* reuse the bvecs from the iterator instead of allocating new ones */
        bio = blk_rq_map_bio_alloc(rq, 0, GFP_KERNEL);
-       if (bio == NULL)
+       if (!bio)
                return -ENOMEM;
-
        bio_iov_bvec_set(bio, (struct iov_iter *)iter);
-       blk_rq_bio_prep(rq, bio, nr_segs);
-
-       /* loop to perform a bunch of sanity checks */
-       bvecs = (struct bio_vec *)iter->bvec;
-       for (i = 0; i < nr_segs; i++) {
-               struct bio_vec *bv = &bvecs[i];
 
-               /*
-                * If the queue doesn't support SG gaps and adding this
-                * offset would create a gap, fallback to copy.
-                */
-               if (bvprvp && bvec_gap_to_prev(lim, bvprvp, bv->bv_offset)) {
-                       blk_mq_map_bio_put(bio);
-                       return -EREMOTEIO;
-               }
-               /* check full condition */
-               if (nsegs >= nr_segs || bytes > UINT_MAX - bv->bv_len)
-                       goto put_bio;
-               if (bytes + bv->bv_len > nr_iter)
-                       goto put_bio;
-               if (bv->bv_offset + bv->bv_len > PAGE_SIZE)
-                       goto put_bio;
-
-               nsegs++;
-               bytes += bv->bv_len;
-               bvprvp = bv;
+       /* check that the data layout matches the hardware restrictions */
+       ret = bio_split_rw_at(bio, lim, &nsegs, max_bytes);
+       if (ret) {
+               /* if we would have to split the bio, copy instead */
+               if (ret > 0)
+                       ret = -EREMOTEIO;
+               blk_mq_map_bio_put(bio);
+               return ret;
        }
+
+       blk_rq_bio_prep(rq, bio, nsegs);
        return 0;
-put_bio:
-       blk_mq_map_bio_put(bio);
-       return -EINVAL;
 }
 
 /**
index 4b2c8e940f5913001956ff8a6e7f450c756e34be..cf626e061dd7747cbdebfbd5aba037ac8ef92521 100644 (file)
@@ -4310,6 +4310,12 @@ int blk_mq_init_allocated_queue(struct blk_mq_tag_set *set,
        /* mark the queue as mq asap */
        q->mq_ops = set->ops;
 
+       /*
+        * ->tag_set has to be setup before initialize hctx, which cpuphp
+        * handler needs it for checking queue mapping
+        */
+       q->tag_set = set;
+
        if (blk_mq_alloc_ctxs(q))
                goto err_exit;
 
@@ -4328,8 +4334,6 @@ int blk_mq_init_allocated_queue(struct blk_mq_tag_set *set,
        INIT_WORK(&q->timeout_work, blk_mq_timeout_work);
        blk_queue_rq_timeout(q, set->timeout ? set->timeout : 30 * HZ);
 
-       q->tag_set = set;
-
        q->queue_flags |= QUEUE_FLAG_MQ_DEFAULT;
 
        INIT_DELAYED_WORK(&q->requeue_work, blk_mq_requeue_work);
index 2cfb297d9a62766384864ba527e8f533e387c3c3..058f92c4f9d57bb955999b667610369592c51d18 100644 (file)
@@ -219,8 +219,8 @@ static int rq_qos_wake_function(struct wait_queue_entry *curr,
 
        data->got_token = true;
        smp_wmb();
-       list_del_init(&curr->entry);
        wake_up_process(data->task);
+       list_del_init_careful(&curr->entry);
        return 1;
 }
 
index 4122026b11f1a1399e76a880e699e3ef009732e8..9430cde13d1a411965a9f4ff4c33b3efb7c593ca 100644 (file)
@@ -106,8 +106,7 @@ static struct elevator_type *__elevator_find(const char *name)
        return NULL;
 }
 
-static struct elevator_type *elevator_find_get(struct request_queue *q,
-               const char *name)
+static struct elevator_type *elevator_find_get(const char *name)
 {
        struct elevator_type *e;
 
@@ -551,7 +550,7 @@ EXPORT_SYMBOL_GPL(elv_unregister);
 static inline bool elv_support_iosched(struct request_queue *q)
 {
        if (!queue_is_mq(q) ||
-           (q->tag_set && (q->tag_set->flags & BLK_MQ_F_NO_SCHED)))
+           (q->tag_set->flags & BLK_MQ_F_NO_SCHED))
                return false;
        return true;
 }
@@ -562,14 +561,14 @@ static inline bool elv_support_iosched(struct request_queue *q)
  */
 static struct elevator_type *elevator_get_default(struct request_queue *q)
 {
-       if (q->tag_set && q->tag_set->flags & BLK_MQ_F_NO_SCHED_BY_DEFAULT)
+       if (q->tag_set->flags & BLK_MQ_F_NO_SCHED_BY_DEFAULT)
                return NULL;
 
        if (q->nr_hw_queues != 1 &&
            !blk_mq_is_shared_tags(q->tag_set->flags))
                return NULL;
 
-       return elevator_find_get(q, "mq-deadline");
+       return elevator_find_get("mq-deadline");
 }
 
 /*
@@ -697,7 +696,7 @@ static int elevator_change(struct request_queue *q, const char *elevator_name)
        if (q->elevator && elevator_match(q->elevator->type, elevator_name))
                return 0;
 
-       e = elevator_find_get(q, elevator_name);
+       e = elevator_find_get(elevator_name);
        if (!e)
                return -EINVAL;
        ret = elevator_switch(q, e);
@@ -709,13 +708,21 @@ int elv_iosched_load_module(struct gendisk *disk, const char *buf,
                            size_t count)
 {
        char elevator_name[ELV_NAME_MAX];
+       struct elevator_type *found;
+       const char *name;
 
        if (!elv_support_iosched(disk->queue))
                return -EOPNOTSUPP;
 
        strscpy(elevator_name, buf, sizeof(elevator_name));
+       name = strstrip(elevator_name);
 
-       request_module("%s-iosched", strstrip(elevator_name));
+       spin_lock(&elv_list_lock);
+       found = __elevator_find(name);
+       spin_unlock(&elv_list_lock);
+
+       if (!found)
+               request_module("%s-iosched", name);
 
        return 0;
 }
index 0a747a0c782d5d03023fc72d0b7bbda209e0e11f..e259180c89148bdcd0d2ae5c901af8c1e51f8576 100644 (file)
@@ -15,7 +15,7 @@
 #include <linux/types.h>
 #include <linux/list.h>
 #include <linux/fs.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include <asm/byteorder.h>
 
 struct parsed_partitions;
index b5d5c229cc3b94cb06ab51d30798581326927e75..073be78ba0b0d74323c8b8882c2c298c0f919ea5 100644 (file)
@@ -36,7 +36,7 @@
  * the nr_sects and start_sect partition table entries are
  * at a 2 (mod 4) address.
  */
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 static inline sector_t nr_sects(struct msdos_partition *p)
 {
index e7052a728966fa58ecaa7668ddb9d2fd024d4e84..2d05421f0fa566f8b7884bec023681d086c78735 100644 (file)
@@ -9,7 +9,7 @@
 #include <linux/crc-t10dif.h>
 #include <linux/crc64.h>
 #include <net/checksum.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include "blk.h"
 
 struct blk_integrity_iter {
index 666474b81c6aa5655fd48eee511cc57203dd1410..3c66d425c97b5d197c021bdb562a0e00cbbf1694 100644 (file)
@@ -54,7 +54,7 @@
 #include <linux/types.h>
 #include <linux/errno.h>
 #include <asm/byteorder.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 static inline u8 byte(const u32 x, const unsigned n)
 {
index 74e2261c184ca96d9a3d19dcc248f7df08758be8..004d27e41315ffea3c60e4237044e41d306f47aa 100644 (file)
@@ -373,7 +373,7 @@ found:
        q->cra_flags |= CRYPTO_ALG_DEAD;
        alg = test->adult;
 
-       if (list_empty(&alg->cra_list))
+       if (crypto_is_dead(alg))
                goto complete;
 
        if (err == -ECANCELED)
index 32e380b714b6ccc1a2b0aa1074f0311e9245fe37..04a712ddfb43092afc36be73629b4e842010db0f 100644 (file)
@@ -15,7 +15,7 @@
  * More information about BLAKE2 can be found at https://blake2.net.
  */
 
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/bitops.h>
index 0e74c7242e77e409ebfa7b71d1759a5f3f10081e..0146bc762c09a4ea5f2c914f46815e2568dae694 100644 (file)
@@ -16,7 +16,7 @@
 #include <linux/init.h>
 #include <linux/module.h>
 #include <linux/mm.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include <linux/types.h>
 #include <crypto/blowfish.h>
 
index c04670cf51acfb7fe089ccb4005c442c5f8dda6a..197fcf3abc892154f831085a21d10add177e10a9 100644 (file)
@@ -15,7 +15,7 @@
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/bitops.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 static const u32 camellia_sp1110[256] = {
        0x70707000, 0x82828200, 0x2c2c2c00, 0xececec00,
index 085a1eedae03bbfed08ab4b505fb0e5d1be10d7a..f3e57775fa02ead8269e1fbd2be747057e2ef38a 100644 (file)
@@ -13,7 +13,7 @@
 */
 
 
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include <crypto/algapi.h>
 #include <linux/init.h>
 #include <linux/module.h>
index 34f1ab53e3a713ba44a8442b917e95e8f56f7edd..11b725b12f27418c196a047609b465dd46d6114b 100644 (file)
@@ -10,7 +10,7 @@
  */
 
 
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include <crypto/algapi.h>
 #include <linux/init.h>
 #include <linux/module.h>
index 8beea79ab1178298f0c72ad1df8a40a1febae2ec..ba7fcb47f9aa02e7afbd2035922aeabc2d35e7f0 100644 (file)
@@ -6,7 +6,7 @@
  * Copyright (C) 2018 Google LLC
  */
 
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include <crypto/algapi.h>
 #include <crypto/internal/chacha.h>
 #include <crypto/internal/skcipher.h>
index a989cb44fd16081c01966071ac8203108f259236..d1251663ed6683561adeeda6b5726b1b3c5485d9 100644 (file)
@@ -7,7 +7,7 @@
  * This is crypto api shash wrappers to crc32_le.
  */
 
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include <linux/crc32.h>
 #include <crypto/internal/hash.h>
 #include <linux/init.h>
index 7686147385412a42e74dac14101172c69d611b75..a8c90b3f4c6c5580e6d14f315b6130eb6398ed03 100644 (file)
@@ -30,7 +30,7 @@
  * Copyright (c) 2008 Herbert Xu <[email protected]>
  */
 
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include <crypto/internal/hash.h>
 #include <linux/init.h>
 #include <linux/module.h>
index 9e812bb26dba6420dde39aab464fc383e6d1387d..ce0f3059b9125a99d4a11c219a076b7aa02f0c40 100644 (file)
@@ -3,7 +3,7 @@
 #include <linux/crc64.h>
 #include <linux/module.h>
 #include <crypto/internal/hash.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 static int chksum_init(struct shash_desc *desc)
 {
index 420decdad7d94f40bdf4bdf60862c957c810496e..50ad2d4ed672c527ee95c78dba926ca6c7787257 100644 (file)
@@ -33,7 +33,7 @@
 #include <crypto/ecdh.h>
 #include <crypto/rng.h>
 #include <crypto/internal/ecc.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include <linux/ratelimit.h>
 
 #include "ecc_curve_defs.h"
index f4c31049601c9d91d389b627b16c6ba128ecef48..0d14e980d4d6135cdc08a411b4e4bdfca2506730 100644 (file)
@@ -7,7 +7,7 @@
  * Copyright (c) 2004 Jouni Malinen <[email protected]>
  */
 #include <crypto/internal/hash.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include <linux/init.h>
 #include <linux/module.h>
 #include <linux/string.h>
index 8a3006c3b51b9c5e3324b4591a701e28443afc76..a661d4f667cde54199fd120d196f21d64f5c1dfb 100644 (file)
@@ -30,7 +30,7 @@
  *     (https://cr.yp.to/mac/poly1305-20050329.pdf)
  */
 
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include <crypto/algapi.h>
 #include <crypto/internal/hash.h>
 #include <crypto/internal/poly1305.h>
index 94af47eb6fa699745a7cc6dffaebc10a1b2e455c..e6f29a98725a83979c48fc4493e87185ac647aef 100644 (file)
@@ -17,7 +17,7 @@
 #include <linux/crypto.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 static int crypto_poly1305_init(struct shash_desc *desc)
 {
index 16bfa6925b31eb68bd68329130fd3685786399ae..4f98910bcdb589f5c77ab2343a77a2ca8daff9c5 100644 (file)
@@ -44,7 +44,7 @@
  *
  */
 
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include <crypto/algapi.h>
 #include <crypto/gf128mul.h>
 #include <crypto/polyval.h>
index c6bca47931e21ec86a8196097f05257bb025654e..f6ef187be6fe7a715a994e2c62fb155ee836bcb1 100644 (file)
@@ -11,7 +11,7 @@
 #include <linux/init.h>
 #include <linux/module.h>
 #include <linux/errno.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include <linux/types.h>
 #include <crypto/serpent.h>
 
index bf147b01e313547fba544cf8e99248e5d988098d..b00521f1a6d4555adf5b64ac745a1390b587239c 100644 (file)
@@ -15,7 +15,7 @@
 #include <crypto/sha2.h>
 #include <crypto/sha256_base.h>
 #include <asm/byteorder.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 const u8 sha224_zero_message_hash[SHA224_DIGEST_SIZE] = {
        0xd1, 0x4a, 0x02, 0x8c, 0x2a, 0x3a, 0x2b, 0xc9, 0x47,
index 3e4069935b53ba513445e062a5dc40c27b646118..b103642b56ea12eed5f3ff8ec38a34a312ec82e3 100644 (file)
@@ -13,7 +13,7 @@
 #include <linux/module.h>
 #include <linux/types.h>
 #include <crypto/sha3.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 /*
  * On some 32-bit architectures (h8300), GCC ends up using
index be70e76d6d8623ac5ec58990b024b4c03c78859d..ed81813bd4201331ecab1c1b742f1466a65913ea 100644 (file)
@@ -16,7 +16,7 @@
 #include <crypto/sha512_base.h>
 #include <linux/percpu.h>
 #include <asm/byteorder.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 const u8 sha384_zero_message_hash[SHA384_DIGEST_SIZE] = {
        0x38, 0xb0, 0x60, 0xa7, 0x51, 0xac, 0x96, 0x38,
index d473e358a873a82cdabbb322e90ea24a193c0604..18c2fb73ba16e9b120e3375b1f0607a828974545 100644 (file)
@@ -9,7 +9,7 @@
  */
 
 #include <linux/module.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include <crypto/sm3.h>
 
 static const u32 ____cacheline_aligned K[64] = {
index a215c1c37e730a08174afe8c697b8ab6e39d3e2c..a2d23a46924eabf68f670b4a27516916e55deb0d 100644 (file)
@@ -17,7 +17,7 @@
 #include <crypto/sm3_base.h>
 #include <linux/bitops.h>
 #include <asm/byteorder.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 const u8 sm3_zero_message_hash[SM3_DIGEST_SIZE] = {
        0x1A, 0xB2, 0x1D, 0x83, 0x55, 0xCF, 0xA1, 0x7F,
index 2c44193bc27e4a0369a795ed641a6e32ca33cb6b..f4cd7edc11f0545952a8251b591e8988e59bd517 100644 (file)
@@ -8,7 +8,7 @@
  */
 
 #include <linux/module.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include <crypto/sm4.h>
 
 static const u32 ____cacheline_aligned fk[4] = {
index 560eba37dc55eae6e2f9cacb5ec339a71618c0fb..7df86369ac0091b11d0980925935b40749f2612f 100644 (file)
@@ -14,7 +14,7 @@
 #include <linux/types.h>
 #include <linux/errno.h>
 #include <asm/byteorder.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 /**
  * sm4_setkey - Set the SM4 key.
index ee8da628e9da46273dc90612c8be747736cb2772..2f5f6b52b2d4546844e86b81b5ef761f1ed2cd2c 100644 (file)
@@ -1940,7 +1940,7 @@ static int __alg_test_hash(const struct hash_testvec *vecs,
        atfm = crypto_alloc_ahash(driver, type, mask);
        if (IS_ERR(atfm)) {
                if (PTR_ERR(atfm) == -ENOENT)
-                       return -ENOENT;
+                       return 0;
                pr_err("alg: hash: failed to allocate transform for %s: %ld\n",
                       driver, PTR_ERR(atfm));
                return PTR_ERR(atfm);
@@ -2706,7 +2706,7 @@ static int alg_test_aead(const struct alg_test_desc *desc, const char *driver,
        tfm = crypto_alloc_aead(driver, type, mask);
        if (IS_ERR(tfm)) {
                if (PTR_ERR(tfm) == -ENOENT)
-                       return -ENOENT;
+                       return 0;
                pr_err("alg: aead: failed to allocate transform for %s: %ld\n",
                       driver, PTR_ERR(tfm));
                return PTR_ERR(tfm);
@@ -3285,7 +3285,7 @@ static int alg_test_skcipher(const struct alg_test_desc *desc,
        tfm = crypto_alloc_skcipher(driver, type, mask);
        if (IS_ERR(tfm)) {
                if (PTR_ERR(tfm) == -ENOENT)
-                       return -ENOENT;
+                       return 0;
                pr_err("alg: skcipher: failed to allocate transform for %s: %ld\n",
                       driver, PTR_ERR(tfm));
                return PTR_ERR(tfm);
@@ -3700,7 +3700,7 @@ static int alg_test_cipher(const struct alg_test_desc *desc,
        tfm = crypto_alloc_cipher(driver, type, mask);
        if (IS_ERR(tfm)) {
                if (PTR_ERR(tfm) == -ENOENT)
-                       return -ENOENT;
+                       return 0;
                printk(KERN_ERR "alg: cipher: Failed to load transform for "
                       "%s: %ld\n", driver, PTR_ERR(tfm));
                return PTR_ERR(tfm);
@@ -3726,7 +3726,7 @@ static int alg_test_comp(const struct alg_test_desc *desc, const char *driver,
                acomp = crypto_alloc_acomp(driver, type, mask);
                if (IS_ERR(acomp)) {
                        if (PTR_ERR(acomp) == -ENOENT)
-                               return -ENOENT;
+                               return 0;
                        pr_err("alg: acomp: Failed to load transform for %s: %ld\n",
                               driver, PTR_ERR(acomp));
                        return PTR_ERR(acomp);
@@ -3740,7 +3740,7 @@ static int alg_test_comp(const struct alg_test_desc *desc, const char *driver,
                comp = crypto_alloc_comp(driver, type, mask);
                if (IS_ERR(comp)) {
                        if (PTR_ERR(comp) == -ENOENT)
-                               return -ENOENT;
+                               return 0;
                        pr_err("alg: comp: Failed to load transform for %s: %ld\n",
                               driver, PTR_ERR(comp));
                        return PTR_ERR(comp);
@@ -3818,7 +3818,7 @@ static int alg_test_cprng(const struct alg_test_desc *desc, const char *driver,
        rng = crypto_alloc_rng(driver, type, mask);
        if (IS_ERR(rng)) {
                if (PTR_ERR(rng) == -ENOENT)
-                       return -ENOENT;
+                       return 0;
                printk(KERN_ERR "alg: cprng: Failed to load transform for %s: "
                       "%ld\n", driver, PTR_ERR(rng));
                return PTR_ERR(rng);
@@ -3846,12 +3846,11 @@ static int drbg_cavs_test(const struct drbg_testvec *test, int pr,
 
        drng = crypto_alloc_rng(driver, type, mask);
        if (IS_ERR(drng)) {
+               kfree_sensitive(buf);
                if (PTR_ERR(drng) == -ENOENT)
-                       goto out_no_rng;
+                       return 0;
                printk(KERN_ERR "alg: drbg: could not allocate DRNG handle for "
                       "%s\n", driver);
-out_no_rng:
-               kfree_sensitive(buf);
                return PTR_ERR(drng);
        }
 
@@ -4095,7 +4094,7 @@ static int alg_test_kpp(const struct alg_test_desc *desc, const char *driver,
        tfm = crypto_alloc_kpp(driver, type, mask);
        if (IS_ERR(tfm)) {
                if (PTR_ERR(tfm) == -ENOENT)
-                       return -ENOENT;
+                       return 0;
                pr_err("alg: kpp: Failed to load tfm for %s: %ld\n",
                       driver, PTR_ERR(tfm));
                return PTR_ERR(tfm);
@@ -4325,7 +4324,7 @@ static int alg_test_akcipher(const struct alg_test_desc *desc,
        tfm = crypto_alloc_akcipher(driver, type, mask);
        if (IS_ERR(tfm)) {
                if (PTR_ERR(tfm) == -ENOENT)
-                       return -ENOENT;
+                       return 0;
                pr_err("alg: akcipher: Failed to load tfm for %s: %ld\n",
                       driver, PTR_ERR(tfm));
                return PTR_ERR(tfm);
index 557915e4062d7ca55eb62859cca742a5d46d0bfb..19f2b365e140b2a4c5ab0feb75bc5f01f982f42d 100644 (file)
@@ -24,7 +24,7 @@
  * Third Edition.
  */
 
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include <crypto/algapi.h>
 #include <crypto/twofish.h>
 #include <linux/module.h>
index 0a1d8efa6c1a6f42f368342f7eadef33e1b546a5..bd9d70eac22e00388deacb889b06b69b833101f4 100644 (file)
@@ -28,7 +28,7 @@
  *     Last modified: 17 APR 08, 1700 PDT
  */
 
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include <linux/init.h>
 #include <linux/types.h>
 #include <linux/crypto.h>
index 55d1c8a761273e5d2a1a8897ee0c9971820a6957..ac206ad4184df1cd14a398a7e6f4be9639e5520c 100644 (file)
@@ -4,7 +4,7 @@
 #include <linux/init.h>
 #include <linux/module.h>
 #include <linux/xxhash.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #define XXHASH64_BLOCK_SIZE    32
 #define XXHASH64_DIGEST_SIZE   8
index 6f86f8df30db0fc263f13a7a4bc98d9e1d3d687b..8d50981594d1533fef602f51d9378db1c7e85dfc 100644 (file)
@@ -108,6 +108,14 @@ static int reset_pending_show(struct seq_file *s, void *v)
        return 0;
 }
 
+static int firewall_irq_counter_show(struct seq_file *s, void *v)
+{
+       struct ivpu_device *vdev = seq_to_ivpu(s);
+
+       seq_printf(s, "%d\n", atomic_read(&vdev->hw->firewall_irq_counter));
+       return 0;
+}
+
 static const struct drm_debugfs_info vdev_debugfs_list[] = {
        {"bo_list", bo_list_show, 0},
        {"fw_name", fw_name_show, 0},
@@ -116,6 +124,7 @@ static const struct drm_debugfs_info vdev_debugfs_list[] = {
        {"last_bootmode", last_bootmode_show, 0},
        {"reset_counter", reset_counter_show, 0},
        {"reset_pending", reset_pending_show, 0},
+       {"firewall_irq_counter", firewall_irq_counter_show, 0},
 };
 
 static ssize_t
index 27f0fe4d54e00628b524d263f817c90075844602..e69c0613513f111c08ce00b4b33be0e826d77a2b 100644 (file)
@@ -249,6 +249,7 @@ int ivpu_hw_init(struct ivpu_device *vdev)
        platform_init(vdev);
        wa_init(vdev);
        timeouts_init(vdev);
+       atomic_set(&vdev->hw->firewall_irq_counter, 0);
 
        return 0;
 }
index 1c0c98e3afb88d78fc514989cd8c7ca09d83737b..a96a05b2acda9a4f898268a74eaa2d3765742d8a 100644 (file)
@@ -52,6 +52,7 @@ struct ivpu_hw_info {
        int dma_bits;
        ktime_t d0i3_entry_host_ts;
        u64 d0i3_entry_vpu_ts;
+       atomic_t firewall_irq_counter;
 };
 
 int ivpu_hw_init(struct ivpu_device *vdev);
index dfd2f4a5b5268583165c101206e749c304e81928..60b33fc59d96e3962d47a3e5fbca4e482e3a6311 100644 (file)
@@ -1062,7 +1062,10 @@ static void irq_wdt_mss_handler(struct ivpu_device *vdev)
 
 static void irq_noc_firewall_handler(struct ivpu_device *vdev)
 {
-       ivpu_pm_trigger_recovery(vdev, "NOC Firewall IRQ");
+       atomic_inc(&vdev->hw->firewall_irq_counter);
+
+       ivpu_dbg(vdev, IRQ, "NOC Firewall interrupt detected, counter %d\n",
+                atomic_read(&vdev->hw->firewall_irq_counter));
 }
 
 /* Handler for IRQs from NPU core */
index 9e8a8cbadf6bb99f1341ac1d62fb890e7d2ea280..d8bdab69f800957ba5e431159d1372cde5107ee2 100644 (file)
@@ -496,7 +496,7 @@ static int encode_addr_size_pairs(struct dma_xfer *xfer, struct wrapper_list *wr
        nents = sgt->nents;
        nents_dma = nents;
        *size = QAIC_MANAGE_EXT_MSG_LENGTH - msg_hdr_len - sizeof(**out_trans);
-       for_each_sgtable_sg(sgt, sg, i) {
+       for_each_sgtable_dma_sg(sgt, sg, i) {
                *size -= sizeof(*asp);
                /* Save 1K for possible follow-up transactions. */
                if (*size < SZ_1K) {
index e86e71c1cdd86897926e5b6eabc028a176b23fa4..c20eb63750f517c07c88132bb79766cbbe010688 100644 (file)
@@ -184,7 +184,7 @@ static int clone_range_of_sgt_for_slice(struct qaic_device *qdev, struct sg_tabl
        nents = 0;
 
        size = size ? size : PAGE_SIZE;
-       for (sg = sgt_in->sgl; sg; sg = sg_next(sg)) {
+       for_each_sgtable_dma_sg(sgt_in, sg, j) {
                len = sg_dma_len(sg);
 
                if (!len)
@@ -221,7 +221,7 @@ static int clone_range_of_sgt_for_slice(struct qaic_device *qdev, struct sg_tabl
 
        /* copy relevant sg node and fix page and length */
        sgn = sgf;
-       for_each_sgtable_sg(sgt, sg, j) {
+       for_each_sgtable_dma_sg(sgt, sg, j) {
                memcpy(sg, sgn, sizeof(*sg));
                if (sgn == sgf) {
                        sg_dma_address(sg) += offf;
@@ -301,7 +301,7 @@ static int encode_reqs(struct qaic_device *qdev, struct bo_slice *slice,
         * fence.
         */
        dev_addr = req->dev_addr;
-       for_each_sgtable_sg(slice->sgt, sg, i) {
+       for_each_sgtable_dma_sg(slice->sgt, sg, i) {
                slice->reqs[i].cmd = cmd;
                slice->reqs[i].src_addr = cpu_to_le64(slice->dir == DMA_TO_DEVICE ?
                                                      sg_dma_address(sg) : dev_addr);
index c7c26872f4cec11a3be409204b25e54bd727b482..9c84f3da7c09004079c1e0a52988f7f29c641f08 100644 (file)
@@ -28,7 +28,7 @@
 #include <linux/interrupt.h>
 #include <linux/debugfs.h>
 #include <acpi/apei.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #include "apei-internal.h"
 
index 73903a497d73f7549e913ee00d85507398643464..5c22720f43ccb971d69505ea88f30310ce5c562b 100644 (file)
@@ -22,7 +22,7 @@
 #include <linux/delay.h>
 #include <linux/mm.h>
 #include <linux/platform_device.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #include "apei-internal.h"
 
index 4f81a119ec0896b4b93601865d783d56f24c76dc..a4e709937236f66146790c044df473b151257892 100644 (file)
@@ -63,7 +63,7 @@ static int cxl_dport_get_sbdf(struct pci_dev *dport_dev, u64 *sbdf)
                seg = bridge->domain_nr;
 
        bus = pbus->number;
-       *sbdf = (seg << 24) | (bus << 16) | dport_dev->devfn;
+       *sbdf = (seg << 24) | (bus << 16) | (dport_dev->devfn << 8);
 
        return 0;
 }
index f4599261cfc31cdbf9c371fa4de0d87f17fd862f..65fa3444367a13ac83644444076a11f08152c382 100644 (file)
@@ -21,7 +21,7 @@
 #include <linux/suspend.h>
 #include <linux/types.h>
 
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #include <linux/acpi.h>
 #include <linux/power_supply.h>
@@ -703,28 +703,35 @@ static LIST_HEAD(acpi_battery_list);
 static LIST_HEAD(battery_hook_list);
 static DEFINE_MUTEX(hook_mutex);
 
-static void __battery_hook_unregister(struct acpi_battery_hook *hook, int lock)
+static void battery_hook_unregister_unlocked(struct acpi_battery_hook *hook)
 {
        struct acpi_battery *battery;
+
        /*
         * In order to remove a hook, we first need to
         * de-register all the batteries that are registered.
         */
-       if (lock)
-               mutex_lock(&hook_mutex);
        list_for_each_entry(battery, &acpi_battery_list, list) {
                if (!hook->remove_battery(battery->bat, hook))
                        power_supply_changed(battery->bat);
        }
-       list_del(&hook->list);
-       if (lock)
-               mutex_unlock(&hook_mutex);
+       list_del_init(&hook->list);
+
        pr_info("extension unregistered: %s\n", hook->name);
 }
 
 void battery_hook_unregister(struct acpi_battery_hook *hook)
 {
-       __battery_hook_unregister(hook, 1);
+       mutex_lock(&hook_mutex);
+       /*
+        * Ignore already unregistered battery hooks. This might happen
+        * if a battery hook was previously unloaded due to an error when
+        * adding a new battery.
+        */
+       if (!list_empty(&hook->list))
+               battery_hook_unregister_unlocked(hook);
+
+       mutex_unlock(&hook_mutex);
 }
 EXPORT_SYMBOL_GPL(battery_hook_unregister);
 
@@ -733,7 +740,6 @@ void battery_hook_register(struct acpi_battery_hook *hook)
        struct acpi_battery *battery;
 
        mutex_lock(&hook_mutex);
-       INIT_LIST_HEAD(&hook->list);
        list_add(&hook->list, &battery_hook_list);
        /*
         * Now that the driver is registered, we need
@@ -750,7 +756,7 @@ void battery_hook_register(struct acpi_battery_hook *hook)
                         * hooks.
                         */
                        pr_err("extension failed to load: %s", hook->name);
-                       __battery_hook_unregister(hook, 0);
+                       battery_hook_unregister_unlocked(hook);
                        goto end;
                }
 
@@ -804,7 +810,7 @@ static void battery_hook_add_battery(struct acpi_battery *battery)
                         */
                        pr_err("error in extension, unloading: %s",
                                        hook_node->name);
-                       __battery_hook_unregister(hook_node, 0);
+                       battery_hook_unregister_unlocked(hook_node);
                }
        }
        mutex_unlock(&hook_mutex);
@@ -837,7 +843,7 @@ static void __exit battery_hook_exit(void)
         * need to remove the hooks.
         */
        list_for_each_entry_safe(hook, ptr, &battery_hook_list, list) {
-               __battery_hook_unregister(hook, 1);
+               battery_hook_unregister(hook);
        }
        mutex_destroy(&hook_mutex);
 }
index 51470208e6daed524d973027a2e5f9a2d30bc1d1..7773e6b860e73bef6231504e3aa1ee8ef30d8917 100644 (file)
@@ -130,6 +130,17 @@ static const struct dmi_system_id dmi_lid_quirks[] = {
                },
                .driver_data = (void *)(long)ACPI_BUTTON_LID_INIT_OPEN,
        },
+       {
+               /*
+                * Samsung galaxybook2 ,initial _LID device notification returns
+                * lid closed.
+                */
+               .matches = {
+                       DMI_MATCH(DMI_SYS_VENDOR, "SAMSUNG ELECTRONICS CO., LTD."),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "750XED"),
+               },
+               .driver_data = (void *)(long)ACPI_BUTTON_LID_INIT_OPEN,
+       },
        {}
 };
 
index 5b06e236aabef2bae1834a056436afa8b47e8e02..1a40f0514eaa368322b86e1be61bc7d6d56f9944 100644 (file)
@@ -41,7 +41,7 @@
 #include <linux/topology.h>
 #include <linux/dmi.h>
 #include <linux/units.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #include <acpi/cppc_acpi.h>
 
@@ -867,7 +867,7 @@ int acpi_cppc_processor_probe(struct acpi_processor *pr)
 
        /* Store CPU Logical ID */
        cpc_ptr->cpu_id = pr->id;
-       spin_lock_init(&cpc_ptr->rmw_lock);
+       raw_spin_lock_init(&cpc_ptr->rmw_lock);
 
        /* Parse PSD data for this CPU */
        ret = acpi_get_psd(cpc_ptr, handle);
@@ -1087,6 +1087,7 @@ static int cpc_write(int cpu, struct cpc_register_resource *reg_res, u64 val)
        int pcc_ss_id = per_cpu(cpu_pcc_subspace_idx, cpu);
        struct cpc_reg *reg = &reg_res->cpc_entry.reg;
        struct cpc_desc *cpc_desc;
+       unsigned long flags;
 
        size = GET_BIT_WIDTH(reg);
 
@@ -1126,7 +1127,7 @@ static int cpc_write(int cpu, struct cpc_register_resource *reg_res, u64 val)
                        return -ENODEV;
                }
 
-               spin_lock(&cpc_desc->rmw_lock);
+               raw_spin_lock_irqsave(&cpc_desc->rmw_lock, flags);
                switch (size) {
                case 8:
                        prev_val = readb_relaxed(vaddr);
@@ -1141,7 +1142,7 @@ static int cpc_write(int cpu, struct cpc_register_resource *reg_res, u64 val)
                        prev_val = readq_relaxed(vaddr);
                        break;
                default:
-                       spin_unlock(&cpc_desc->rmw_lock);
+                       raw_spin_unlock_irqrestore(&cpc_desc->rmw_lock, flags);
                        return -EFAULT;
                }
                val = MASK_VAL_WRITE(reg, prev_val, val);
@@ -1174,7 +1175,7 @@ static int cpc_write(int cpu, struct cpc_register_resource *reg_res, u64 val)
        }
 
        if (reg->space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY)
-               spin_unlock(&cpc_desc->rmw_lock);
+               raw_spin_unlock_irqrestore(&cpc_desc->rmw_lock, flags);
 
        return ret_val;
 }
@@ -1916,9 +1917,15 @@ unsigned int cppc_perf_to_khz(struct cppc_perf_caps *caps, unsigned int perf)
        u64 mul, div;
 
        if (caps->lowest_freq && caps->nominal_freq) {
-               mul = caps->nominal_freq - caps->lowest_freq;
+               /* Avoid special case when nominal_freq is equal to lowest_freq */
+               if (caps->lowest_freq == caps->nominal_freq) {
+                       mul = caps->nominal_freq;
+                       div = caps->nominal_perf;
+               } else {
+                       mul = caps->nominal_freq - caps->lowest_freq;
+                       div = caps->nominal_perf - caps->lowest_perf;
+               }
                mul *= KHZ_PER_MHZ;
-               div = caps->nominal_perf - caps->lowest_perf;
                offset = caps->nominal_freq * KHZ_PER_MHZ -
                         div64_u64(caps->nominal_perf * mul, div);
        } else {
@@ -1939,11 +1946,17 @@ unsigned int cppc_khz_to_perf(struct cppc_perf_caps *caps, unsigned int freq)
 {
        s64 retval, offset = 0;
        static u64 max_khz;
-       u64  mul, div;
+       u64 mul, div;
 
        if (caps->lowest_freq && caps->nominal_freq) {
-               mul = caps->nominal_perf - caps->lowest_perf;
-               div = caps->nominal_freq - caps->lowest_freq;
+               /* Avoid special case when nominal_freq is equal to lowest_freq */
+               if (caps->lowest_freq == caps->nominal_freq) {
+                       mul = caps->nominal_perf;
+                       div = caps->nominal_freq;
+               } else {
+                       mul = caps->nominal_perf - caps->lowest_perf;
+                       div = caps->nominal_freq - caps->lowest_freq;
+               }
                /*
                 * We don't need to convert to kHz for computing offset and can
                 * directly use nominal_freq and lowest_freq as the div64_u64
index 1cfaa5957ac4d860babeb05460a7c7d020caa659..747f83f7114d295a22079e5d3b167b4af94442b5 100644 (file)
@@ -52,7 +52,7 @@ struct prm_context_buffer {
 static LIST_HEAD(prm_module_list);
 
 struct prm_handler_info {
-       guid_t guid;
+       efi_guid_t guid;
        efi_status_t (__efiapi *handler_addr)(u64, void *);
        u64 static_data_buffer_addr;
        u64 acpi_param_buffer_addr;
@@ -72,17 +72,21 @@ struct prm_module_info {
        struct prm_handler_info handlers[] __counted_by(handler_count);
 };
 
-static u64 efi_pa_va_lookup(u64 pa)
+static u64 efi_pa_va_lookup(efi_guid_t *guid, u64 pa)
 {
        efi_memory_desc_t *md;
        u64 pa_offset = pa & ~PAGE_MASK;
        u64 page = pa & PAGE_MASK;
 
        for_each_efi_memory_desc(md) {
-               if (md->phys_addr < pa && pa < md->phys_addr + PAGE_SIZE * md->num_pages)
+               if ((md->attribute & EFI_MEMORY_RUNTIME) &&
+                   (md->phys_addr < pa && pa < md->phys_addr + PAGE_SIZE * md->num_pages)) {
                        return pa_offset + md->virt_addr + page - md->phys_addr;
+               }
        }
 
+       pr_warn("Failed to find VA for GUID: %pUL, PA: 0x%llx", guid, pa);
+
        return 0;
 }
 
@@ -148,9 +152,15 @@ acpi_parse_prmt(union acpi_subtable_headers *header, const unsigned long end)
                th = &tm->handlers[cur_handler];
 
                guid_copy(&th->guid, (guid_t *)handler_info->handler_guid);
-               th->handler_addr = (void *)efi_pa_va_lookup(handler_info->handler_address);
-               th->static_data_buffer_addr = efi_pa_va_lookup(handler_info->static_data_buffer_address);
-               th->acpi_param_buffer_addr = efi_pa_va_lookup(handler_info->acpi_param_buffer_address);
+               th->handler_addr =
+                       (void *)efi_pa_va_lookup(&th->guid, handler_info->handler_address);
+
+               th->static_data_buffer_addr =
+                       efi_pa_va_lookup(&th->guid, handler_info->static_data_buffer_address);
+
+               th->acpi_param_buffer_addr =
+                       efi_pa_va_lookup(&th->guid, handler_info->acpi_param_buffer_address);
+
        } while (++cur_handler < tm->handler_count && (handler_info = get_next_handler(handler_info)));
 
        return 0;
@@ -277,6 +287,13 @@ static acpi_status acpi_platformrt_space_handler(u32 function,
                if (!handler || !module)
                        goto invalid_guid;
 
+               if (!handler->handler_addr ||
+                   !handler->static_data_buffer_addr ||
+                   !handler->acpi_param_buffer_addr) {
+                       buffer->prm_status = PRM_HANDLER_ERROR;
+                       return AE_OK;
+               }
+
                ACPI_COPY_NAMESEG(context.signature, "PRMC");
                context.revision = 0x0;
                context.reserved = 0x0;
index 8a4726e2eb6938da0992138eb6fc0bce11597d9f..7fe842dae1ec05ce6726af2ae4fcc8eff3698dcb 100644 (file)
@@ -441,115 +441,73 @@ static const struct dmi_system_id irq1_level_low_skip_override[] = {
                },
        },
        {
-               /* Asus ExpertBook B1402CBA */
+               /* Asus Vivobook X1704VAP */
                .matches = {
                        DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
-                       DMI_MATCH(DMI_BOARD_NAME, "B1402CBA"),
+                       DMI_MATCH(DMI_BOARD_NAME, "X1704VAP"),
                },
        },
        {
-               /* Asus ExpertBook B1402CVA */
+               /* Asus ExpertBook B1402C* */
                .matches = {
                        DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
-                       DMI_MATCH(DMI_BOARD_NAME, "B1402CVA"),
+                       DMI_MATCH(DMI_BOARD_NAME, "B1402C"),
                },
        },
        {
-               /* Asus ExpertBook B1502CBA */
+               /* Asus ExpertBook B1502C* */
                .matches = {
                        DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
-                       DMI_MATCH(DMI_BOARD_NAME, "B1502CBA"),
+                       DMI_MATCH(DMI_BOARD_NAME, "B1502C"),
                },
        },
        {
-               /* Asus ExpertBook B1502CGA */
+               /* Asus ExpertBook B2402 (B2402CBA / B2402FBA / B2402CVA / B2402FVA) */
                .matches = {
                        DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
-                       DMI_MATCH(DMI_BOARD_NAME, "B1502CGA"),
+                       DMI_MATCH(DMI_BOARD_NAME, "B2402"),
                },
        },
-        {
-                /* Asus ExpertBook B1502CVA */
-                .matches = {
-                        DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
-                        DMI_MATCH(DMI_BOARD_NAME, "B1502CVA"),
-                },
-        },
        {
-               /* Asus ExpertBook B2402CBA */
+               /* Asus ExpertBook B2502 (B2502CBA / B2502FBA / B2502CVA / B2502FVA) */
                .matches = {
                        DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
-                       DMI_MATCH(DMI_BOARD_NAME, "B2402CBA"),
+                       DMI_MATCH(DMI_BOARD_NAME, "B2502"),
                },
        },
        {
-               /* Asus ExpertBook B2402FBA */
+               /* Asus Vivobook Go E1404GA* */
                .matches = {
                        DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
-                       DMI_MATCH(DMI_BOARD_NAME, "B2402FBA"),
+                       DMI_MATCH(DMI_BOARD_NAME, "E1404GA"),
                },
        },
        {
-               /* Asus ExpertBook B2502 */
-               .matches = {
-                       DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
-                       DMI_MATCH(DMI_BOARD_NAME, "B2502CBA"),
-               },
-       },
-       {
-               /* Asus ExpertBook B2502FBA */
-               .matches = {
-                       DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
-                       DMI_MATCH(DMI_BOARD_NAME, "B2502FBA"),
-               },
-       },
-       {
-               /* Asus Vivobook Go E1404GAB */
-               .matches = {
-                       DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
-                       DMI_MATCH(DMI_BOARD_NAME, "E1404GAB"),
-               },
-       },
-       {
-               /* Asus Vivobook E1504GA */
+               /* Asus Vivobook E1504GA* */
                .matches = {
                        DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
                        DMI_MATCH(DMI_BOARD_NAME, "E1504GA"),
                },
        },
        {
-               /* Asus Vivobook E1504GAB */
+               /* Asus Vivobook Pro N6506M* */
                .matches = {
                        DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
-                       DMI_MATCH(DMI_BOARD_NAME, "E1504GAB"),
+                       DMI_MATCH(DMI_BOARD_NAME, "N6506M"),
                },
        },
        {
-               /* Asus Vivobook Pro N6506MV */
-               .matches = {
-                       DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
-                       DMI_MATCH(DMI_BOARD_NAME, "N6506MV"),
-               },
-       },
-       {
-               /* Asus Vivobook Pro N6506MU */
-               .matches = {
-                       DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
-                       DMI_MATCH(DMI_BOARD_NAME, "N6506MU"),
-               },
-       },
-       {
-               /* Asus Vivobook Pro N6506MJ */
+               /* LG Electronics 17U70P */
                .matches = {
-                       DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
-                       DMI_MATCH(DMI_BOARD_NAME, "N6506MJ"),
+                       DMI_MATCH(DMI_SYS_VENDOR, "LG Electronics"),
+                       DMI_MATCH(DMI_BOARD_NAME, "17U70P"),
                },
        },
        {
-               /* LG Electronics 17U70P */
+               /* LG Electronics 16T90SP */
                .matches = {
                        DMI_MATCH(DMI_SYS_VENDOR, "LG Electronics"),
-                       DMI_MATCH(DMI_BOARD_NAME, "17U70P"),
+                       DMI_MATCH(DMI_BOARD_NAME, "16T90SP"),
                },
        },
        { }
index b70e84e8049aa79902dcaa9f18615d165ceebcbf..015bd8e66c1cf85f301b74c1184a7a760c601915 100644 (file)
@@ -844,6 +844,15 @@ static const struct dmi_system_id video_detect_dmi_table[] = {
         * controller board in their ACPI tables (and may even have one), but
         * which need native backlight control nevertheless.
         */
+       {
+        /* https://github.com/zabbly/linux/issues/26 */
+        .callback = video_detect_force_native,
+        /* Dell OptiPlex 5480 AIO */
+        .matches = {
+               DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
+               DMI_MATCH(DMI_PRODUCT_NAME, "OptiPlex 5480 AIO"),
+               },
+       },
        {
         /* https://bugzilla.redhat.com/show_bug.cgi?id=2303936 */
         .callback = video_detect_force_native,
index cdb20a700b55b8aeaa21eba31456b1e62d40718a..c085dd81ebe7f646c061cd813fdcb3f4428b16cb 100644 (file)
@@ -50,7 +50,7 @@
 #include <scsi/scsi_host.h>
 #include <linux/libata.h>
 #include <asm/byteorder.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include <linux/cdrom.h>
 #include <linux/ratelimit.h>
 #include <linux/leds.h>
index 3f0144e7dc8042531fd85054fc1f47bb7b5f0e4d..3b303d4ae37a01c55ca2ce5973aa9de256d7d5eb 100644 (file)
@@ -651,6 +651,7 @@ void ata_scsi_cmd_error_handler(struct Scsi_Host *host, struct ata_port *ap,
                        /* the scmd has an associated qc */
                        if (!(qc->flags & ATA_QCFLAG_EH)) {
                                /* which hasn't failed yet, timeout */
+                               set_host_byte(scmd, DID_TIME_OUT);
                                qc->err_mask |= AC_ERR_TIMEOUT;
                                qc->flags |= ATA_QCFLAG_EH;
                                nr_timedout++;
@@ -4099,10 +4100,20 @@ static void ata_eh_handle_port_suspend(struct ata_port *ap)
 
        WARN_ON(ap->pflags & ATA_PFLAG_SUSPENDED);
 
-       /* Set all devices attached to the port in standby mode */
-       ata_for_each_link(link, ap, HOST_FIRST) {
-               ata_for_each_dev(dev, link, ENABLED)
-                       ata_dev_power_set_standby(dev);
+       /*
+        * We will reach this point for all of the PM events:
+        * PM_EVENT_SUSPEND (if runtime pm, PM_EVENT_AUTO will also be set)
+        * PM_EVENT_FREEZE, and PM_EVENT_HIBERNATE.
+        *
+        * We do not want to perform disk spin down for PM_EVENT_FREEZE.
+        * (Spin down will be performed by the subsequent PM_EVENT_HIBERNATE.)
+        */
+       if (!(ap->pm_mesg.event & PM_EVENT_FREEZE)) {
+               /* Set all devices attached to the port in standby mode */
+               ata_for_each_link(link, ap, HOST_FIRST) {
+                       ata_for_each_dev(dev, link, ENABLED)
+                               ata_dev_power_set_standby(dev);
+               }
        }
 
        /*
index c8b119a06bb23dc1d7f4f9bd92d3b5481530dc42..9c76fb1ad2ec506879bb481509e20e1ede971f3d 100644 (file)
@@ -13,7 +13,7 @@
 #include <scsi/scsi_device.h>
 #include <scsi/scsi_eh.h>
 #include <linux/libata.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #include "libata.h"
 #include "libata-transport.h"
index a4aedf7e177580efb459af29fc540508aef82324..f915e3df57a9a0c29f5a912531c9f43a0a181e18 100644 (file)
@@ -30,7 +30,7 @@
 #include <linux/hdreg.h>
 #include <linux/uaccess.h>
 #include <linux/suspend.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include <linux/ioprio.h>
 #include <linux/of.h>
 
index 8a7034b41d50e8f0ab1228000bb4b703f277e825..a816f9e102559574c5d492501be51129faf18bce 100644 (file)
@@ -25,7 +25,7 @@
 #include <linux/map_to_7segment.h>
 #include <linux/map_to_14segment.h>
 
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #include "line-display.h"
 
index a4c853411a6b2b767cfab2169ab2125ab803ca9c..048ff98dbdfd846ae67729e46d7acc9cde546a70 100644 (file)
@@ -26,7 +26,6 @@
 #include <linux/of.h>
 #include <linux/of_device.h>
 #include <linux/pm_runtime.h>
-#include <linux/rcupdate.h>
 #include <linux/sched/mm.h>
 #include <linux/sched/signal.h>
 #include <linux/slab.h>
@@ -2634,7 +2633,6 @@ static const char *dev_uevent_name(const struct kobject *kobj)
 static int dev_uevent(const struct kobject *kobj, struct kobj_uevent_env *env)
 {
        const struct device *dev = kobj_to_dev(kobj);
-       struct device_driver *driver;
        int retval = 0;
 
        /* add device node properties if present */
@@ -2663,12 +2661,8 @@ static int dev_uevent(const struct kobject *kobj, struct kobj_uevent_env *env)
        if (dev->type && dev->type->name)
                add_uevent_var(env, "DEVTYPE=%s", dev->type->name);
 
-       /* Synchronize with module_remove_driver() */
-       rcu_read_lock();
-       driver = READ_ONCE(dev->driver);
-       if (driver)
-               add_uevent_var(env, "DRIVER=%s", driver->name);
-       rcu_read_unlock();
+       if (dev->driver)
+               add_uevent_var(env, "DRIVER=%s", dev->driver->name);
 
        /* Add common DT information about the device */
        of_device_uevent(dev, env);
@@ -2738,8 +2732,11 @@ static ssize_t uevent_show(struct device *dev, struct device_attribute *attr,
        if (!env)
                return -ENOMEM;
 
+       /* Synchronize with really_probe() */
+       device_lock(dev);
        /* let the kset specific function add its keys */
        retval = kset->uevent_ops->uevent(&dev->kobj, env);
+       device_unlock(dev);
        if (retval)
                goto out;
 
@@ -4037,6 +4034,41 @@ int device_for_each_child_reverse(struct device *parent, void *data,
 }
 EXPORT_SYMBOL_GPL(device_for_each_child_reverse);
 
+/**
+ * device_for_each_child_reverse_from - device child iterator in reversed order.
+ * @parent: parent struct device.
+ * @from: optional starting point in child list
+ * @fn: function to be called for each device.
+ * @data: data for the callback.
+ *
+ * Iterate over @parent's child devices, starting at @from, and call @fn
+ * for each, passing it @data. This helper is identical to
+ * device_for_each_child_reverse() when @from is NULL.
+ *
+ * @fn is checked each iteration. If it returns anything other than 0,
+ * iteration stop and that value is returned to the caller of
+ * device_for_each_child_reverse_from();
+ */
+int device_for_each_child_reverse_from(struct device *parent,
+                                      struct device *from, const void *data,
+                                      int (*fn)(struct device *, const void *))
+{
+       struct klist_iter i;
+       struct device *child;
+       int error = 0;
+
+       if (!parent->p)
+               return 0;
+
+       klist_iter_init_node(&parent->p->klist_children, &i,
+                            (from ? &from->p->knode_parent : NULL));
+       while ((child = prev_device(&i)) && !error)
+               error = fn(child, data);
+       klist_iter_exit(&i);
+       return error;
+}
+EXPORT_SYMBOL_GPL(device_for_each_child_reverse_from);
+
 /**
  * device_find_child - device iterator for locating a particular device.
  * @parent: parent struct device
index c4eaa1158d54ed24a83860ffe587e7bf17c68ff7..5bc71bea883a06f0b10b064a242b1a0ebee35236 100644 (file)
@@ -7,7 +7,6 @@
 #include <linux/errno.h>
 #include <linux/slab.h>
 #include <linux/string.h>
-#include <linux/rcupdate.h>
 #include "base.h"
 
 static char *make_driver_name(const struct device_driver *drv)
@@ -102,9 +101,6 @@ void module_remove_driver(const struct device_driver *drv)
        if (!drv)
                return;
 
-       /* Synchronize with dev_uevent() */
-       synchronize_rcu();
-
        sysfs_remove_link(&drv->p->kobj, "module");
 
        if (drv->owner)
index 8c34ae1cd8d554d5e9e8deb86a2d49688d82ad22..cca2fd0a1aed64b368c8c8e33ec4a8ad554b37af 100644 (file)
@@ -195,6 +195,7 @@ int dev_pm_domain_attach_list(struct device *dev,
        struct device *pd_dev = NULL;
        int ret, i, num_pds = 0;
        bool by_id = true;
+       size_t size;
        u32 pd_flags = data ? data->pd_flags : 0;
        u32 link_flags = pd_flags & PD_FLAG_NO_DEV_LINK ? 0 :
                        DL_FLAG_STATELESS | DL_FLAG_PM_RUNTIME;
@@ -217,19 +218,17 @@ int dev_pm_domain_attach_list(struct device *dev,
        if (num_pds <= 0)
                return 0;
 
-       pds = devm_kzalloc(dev, sizeof(*pds), GFP_KERNEL);
+       pds = kzalloc(sizeof(*pds), GFP_KERNEL);
        if (!pds)
                return -ENOMEM;
 
-       pds->pd_devs = devm_kcalloc(dev, num_pds, sizeof(*pds->pd_devs),
-                                   GFP_KERNEL);
-       if (!pds->pd_devs)
-               return -ENOMEM;
-
-       pds->pd_links = devm_kcalloc(dev, num_pds, sizeof(*pds->pd_links),
-                                    GFP_KERNEL);
-       if (!pds->pd_links)
-               return -ENOMEM;
+       size = sizeof(*pds->pd_devs) + sizeof(*pds->pd_links);
+       pds->pd_devs = kcalloc(num_pds, size, GFP_KERNEL);
+       if (!pds->pd_devs) {
+               ret = -ENOMEM;
+               goto free_pds;
+       }
+       pds->pd_links = (void *)(pds->pd_devs + num_pds);
 
        if (link_flags && pd_flags & PD_FLAG_DEV_LINK_ON)
                link_flags |= DL_FLAG_RPM_ACTIVE;
@@ -272,6 +271,9 @@ err_attach:
                        device_link_del(pds->pd_links[i]);
                dev_pm_domain_detach(pds->pd_devs[i], true);
        }
+       kfree(pds->pd_devs);
+free_pds:
+       kfree(pds);
        return ret;
 }
 EXPORT_SYMBOL_GPL(dev_pm_domain_attach_list);
@@ -363,6 +365,9 @@ void dev_pm_domain_detach_list(struct dev_pm_domain_list *list)
                        device_link_del(list->pd_links[i]);
                dev_pm_domain_detach(list->pd_devs[i], true);
        }
+
+       kfree(list->pd_devs);
+       kfree(list);
 }
 EXPORT_SYMBOL_GPL(dev_pm_domain_detach_list);
 
index 9ed842d17642b54b7de05676cc659e94c828e2ee..4ded93687c1f0ab3584947c61398cd6333b2e72c 100644 (file)
@@ -17,7 +17,7 @@
 #include <linux/delay.h>
 #include <linux/log2.h>
 #include <linux/hwspinlock.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #define CREATE_TRACE_POINTS
 #include "trace.h"
index cc9077b588d7e7af30401ab03c826a358b2a232c..92b06d1de4cc7b7c4ea6f5fad6aa6c4518c1001b 100644 (file)
@@ -14,7 +14,7 @@
 #include <linux/workqueue.h>
 #include <linux/kthread.h>
 #include <net/net_namespace.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include <linux/uio.h>
 #include "aoe.h"
 
@@ -361,6 +361,7 @@ ata_rw_frameinit(struct frame *f)
        }
 
        ah->cmdstat = ATA_CMD_PIO_READ | writebit | extbit;
+       dev_hold(t->ifp->nd);
        skb->dev = t->ifp->nd;
 }
 
@@ -401,6 +402,8 @@ aoecmd_ata_rw(struct aoedev *d)
                __skb_queue_head_init(&queue);
                __skb_queue_tail(&queue, skb);
                aoenet_xmit(&queue);
+       } else {
+               dev_put(f->t->ifp->nd);
        }
        return 1;
 }
@@ -483,10 +486,13 @@ resend(struct aoedev *d, struct frame *f)
        memcpy(h->dst, t->addr, sizeof h->dst);
        memcpy(h->src, t->ifp->nd->dev_addr, sizeof h->src);
 
+       dev_hold(t->ifp->nd);
        skb->dev = t->ifp->nd;
        skb = skb_clone(skb, GFP_ATOMIC);
-       if (skb == NULL)
+       if (skb == NULL) {
+               dev_put(t->ifp->nd);
                return;
+       }
        f->sent = ktime_get();
        __skb_queue_head_init(&queue);
        __skb_queue_tail(&queue, skb);
@@ -617,6 +623,8 @@ probe(struct aoetgt *t)
                __skb_queue_head_init(&queue);
                __skb_queue_tail(&queue, skb);
                aoenet_xmit(&queue);
+       } else {
+               dev_put(f->t->ifp->nd);
        }
 }
 
@@ -1395,6 +1403,7 @@ aoecmd_ata_id(struct aoedev *d)
        ah->cmdstat = ATA_CMD_ID_ATA;
        ah->lba3 = 0xa0;
 
+       dev_hold(t->ifp->nd);
        skb->dev = t->ifp->nd;
 
        d->rttavg = RTTAVG_INIT;
@@ -1404,6 +1413,8 @@ aoecmd_ata_id(struct aoedev *d)
        skb = skb_clone(skb, GFP_ATOMIC);
        if (skb)
                f->sent = ktime_get();
+       else
+               dev_put(t->ifp->nd);
 
        return skb;
 }
index 923a134fd766562fcf9d33a993739040517258c1..66e617664c143aa38da45ab08ee693f8022574f2 100644 (file)
@@ -10,7 +10,7 @@
 #include <linux/netdevice.h>
 #include <linux/moduleparam.h>
 #include <net/net_namespace.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include "aoe.h"
 
 #define NECODES 5
index 2a05d955e30b67c70bf8bb102f0951411137b308..e21492981f7dd128bec9362c41b512c5a93087b4 100644 (file)
@@ -1364,7 +1364,6 @@ extern struct bio_set drbd_io_bio_set;
 
 extern struct mutex resources_mutex;
 
-extern int conn_lowest_minor(struct drbd_connection *connection);
 extern enum drbd_ret_code drbd_create_device(struct drbd_config_context *adm_ctx, unsigned int minor);
 extern void drbd_destroy_device(struct kref *kref);
 extern void drbd_delete_device(struct drbd_device *device);
index 0d74d75260ef12e7e8030e7196d9596de4446cdb..5bbd312c3e14d0bd9252aa365f4f165e2486cb9a 100644 (file)
@@ -471,20 +471,6 @@ void _drbd_thread_stop(struct drbd_thread *thi, int restart, int wait)
                wait_for_completion(&thi->stop);
 }
 
-int conn_lowest_minor(struct drbd_connection *connection)
-{
-       struct drbd_peer_device *peer_device;
-       int vnr = 0, minor = -1;
-
-       rcu_read_lock();
-       peer_device = idr_get_next(&connection->peer_devices, &vnr);
-       if (peer_device)
-               minor = device_to_minor(peer_device->device);
-       rcu_read_unlock();
-
-       return minor;
-}
-
 #ifdef CONFIG_SMP
 /*
  * drbd_calc_cpu_mask() - Generate CPU masks, spread over all CPUs
index 5d65c9754d8377e60f59228f7abb2eac9669a439..720fc30e2ecc921d7ddc1f285e5aa509647d1f69 100644 (file)
@@ -25,7 +25,7 @@
 #include "drbd_protocol.h"
 #include "drbd_req.h"
 #include "drbd_state_change.h"
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include <linux/drbd_limits.h>
 #include <linux/kthread.h>
 
index 499c110465e34f0fc766caa8436d8719315dd90f..65b96c083b3cad28aa73868fda222a7c16d15dc6 100644 (file)
@@ -71,7 +71,7 @@
 #include <scsi/scsi_cmnd.h>
 #include <scsi/scsi_ioctl.h>
 
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #define DRIVER_NAME    "pktcdvd"
 
index a6c8e5cc6051730f23e25c6788a9a5ced7c92441..6ba2c1dd1d878a6a797b41f270a913ae84e5071e 100644 (file)
@@ -2380,10 +2380,19 @@ static int ublk_ctrl_add_dev(struct io_uring_cmd *cmd)
         * TODO: provide forward progress for RECOVERY handler, so that
         * unprivileged device can benefit from it
         */
-       if (info.flags & UBLK_F_UNPRIVILEGED_DEV)
+       if (info.flags & UBLK_F_UNPRIVILEGED_DEV) {
                info.flags &= ~(UBLK_F_USER_RECOVERY_REISSUE |
                                UBLK_F_USER_RECOVERY);
 
+               /*
+                * For USER_COPY, we depends on userspace to fill request
+                * buffer by pwrite() to ublk char device, which can't be
+                * used for unprivileged device
+                */
+               if (info.flags & UBLK_F_USER_COPY)
+                       return -EINVAL;
+       }
+
        /* the created device is always owned by current user */
        ublk_store_owner_uid_gid(&info.owner_uid, &info.owner_gid);
 
index ce97b336fbfb8aad7d3d5b6e5ab49feb022762d3..fc796f1dbda9742bedd7e2f52c073f235be3c03d 100644 (file)
@@ -11,7 +11,7 @@
 #include <linux/errno.h>
 #include <linux/firmware.h>
 #include <linux/usb.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include <net/bluetooth/bluetooth.h>
 
 #define VERSION "1.0"
index f9a7c790d7e2ec958a43c8b577a2c775d1307207..eef00467905eb3bc5e9b29a4dde6c24e541b7929 100644 (file)
@@ -12,7 +12,7 @@
 #include <linux/dmi.h>
 #include <linux/of.h>
 #include <linux/string.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #include <net/bluetooth/bluetooth.h>
 #include <net/bluetooth/hci_core.h>
index 1ccbb5157515331daaaef87b7a8eeb1370942278..438b92967bc364c63f46242630466c5c62009634 100644 (file)
@@ -11,7 +11,7 @@
 #include <linux/regmap.h>
 #include <linux/acpi.h>
 #include <acpi/acpi_bus.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include <linux/efi.h>
 
 #include <net/bluetooth/bluetooth.h>
index fda47948c35d7cf76c2d6b1044ee5c2f2b51d207..5252125b003f58fc582089b3a6133373546d97b5 100644 (file)
@@ -14,7 +14,7 @@
 #include <linux/delay.h>
 #include <linux/interrupt.h>
 
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #include <net/bluetooth/bluetooth.h>
 #include <net/bluetooth/hci_core.h>
index 85b7f2bb425982c35638b54df1c9cf56495e9f0c..07cd308f7abf6debe114452ed4e3e6de82efc1f8 100644 (file)
@@ -92,7 +92,7 @@ static int btmrvl_sdio_probe_of(struct device *dev,
                } else {
                        ret = devm_request_irq(dev, cfg->irq_bt,
                                               btmrvl_wake_irq_bt,
-                                              0, "bt_wake", card);
+                                              IRQF_NO_AUTOEN, "bt_wake", card);
                        if (ret) {
                                dev_err(dev,
                                        "Failed to request irq_bt %d (%d)\n",
@@ -101,7 +101,6 @@ static int btmrvl_sdio_probe_of(struct device *dev,
 
                        /* Configure wakeup (enabled by default) */
                        device_init_wakeup(dev, true);
-                       disable_irq(cfg->irq_bt);
                }
        }
 
index 2b7c80043aa2ebd4c525d78e77af423df142d7cc..9bbf205021634f02407fa64eea5e45f0426e0a21 100644 (file)
@@ -6,7 +6,7 @@
 #include <linux/firmware.h>
 #include <linux/usb.h>
 #include <linux/iopoll.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #include <net/bluetooth/bluetooth.h>
 #include <net/bluetooth/hci_core.h>
index 497e4c87f5be56d5919f74ba4a53b20a079e0a54..11d33cd7b08fc04fc1d5b55807c232f8c00425f4 100644 (file)
@@ -10,7 +10,7 @@
  *
  */
 
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include <linux/atomic.h>
 #include <linux/gpio/consumer.h>
 #include <linux/init.h>
index aa87c3e788718feeb7999608aeb25be41c6ce3a0..64e4d835af5211dc762358ebb2a2bfd3bf5961ba 100644 (file)
@@ -8,7 +8,7 @@
  *
  */
 
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include <linux/atomic.h>
 #include <linux/clk.h>
 #include <linux/firmware.h>
index 7c2030cec10e186db9c46109deea557102de9443..5ea0d23e88c02ba33b14b6caa0a96b890b744255 100644 (file)
@@ -10,7 +10,7 @@
 #include <linux/serdev.h>
 #include <linux/of.h>
 #include <linux/skbuff.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include <linux/firmware.h>
 #include <linux/string.h>
 #include <linux/crc8.h>
index 0c91d7635ac39e9082eabe3ece06efeabefb1588..6c1f584c8a33725b6c437cfc920bb296efee86bd 100644 (file)
@@ -17,7 +17,7 @@
 #include <linux/kernel.h>
 #include <net/bluetooth/bluetooth.h>
 #include <net/bluetooth/hci_core.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include <net/rsi_91x.h>
 
 #define RSI_DMA_ALIGN  8
index 2d95b3ea046dff1b8e02e33b6fb4971292a4a4ec..0bcb44cf7b31d7d0c2d2a17f3576806fbaf28a9b 100644 (file)
@@ -7,7 +7,7 @@
 
 #include <linux/module.h>
 #include <linux/firmware.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include <linux/usb.h>
 
 #include <net/bluetooth/bluetooth.h>
index 6c9c761d5b93a8c7505b348b5d7b3caf9f69c9cb..e9534fbc92e32f04c249c8be1703103070f82ee0 100644 (file)
@@ -17,7 +17,7 @@
 #include <linux/suspend.h>
 #include <linux/gpio/consumer.h>
 #include <linux/debugfs.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #include <net/bluetooth/bluetooth.h>
 #include <net/bluetooth/hci_core.h>
@@ -1345,10 +1345,15 @@ static int btusb_submit_intr_urb(struct hci_dev *hdev, gfp_t mem_flags)
        if (!urb)
                return -ENOMEM;
 
-       /* Use maximum HCI Event size so the USB stack handles
-        * ZPL/short-transfer automatically.
-        */
-       size = HCI_MAX_EVENT_SIZE;
+       if (le16_to_cpu(data->udev->descriptor.idVendor)  == 0x0a12 &&
+           le16_to_cpu(data->udev->descriptor.idProduct) == 0x0001)
+               /* Fake CSR devices don't seem to support sort-transter */
+               size = le16_to_cpu(data->intr_ep->wMaxPacketSize);
+       else
+               /* Use maximum HCI Event size so the USB stack handles
+                * ZPL/short-transfer automatically.
+                */
+               size = HCI_MAX_EVENT_SIZE;
 
        buf = kmalloc(size, mem_flags);
        if (!buf) {
@@ -4041,8 +4046,10 @@ static int btusb_suspend(struct usb_interface *intf, pm_message_t message)
 
        BT_DBG("intf %p", intf);
 
-       /* Don't suspend if there are connections */
-       if (hci_conn_count(data->hdev))
+       /* Don't auto-suspend if there are connections; external suspend calls
+        * shall never fail.
+        */
+       if (PMSG_IS_AUTO(message) && hci_conn_count(data->hdev))
                return -EBUSY;
 
        if (data->suspend_count++)
index 647d37ca4cdda203fdfe1fa45dd8ca266c693929..28cf2d8c2d48e93df9801738257ed173478316b4 100644 (file)
@@ -6,7 +6,7 @@
  *  Copyright (C) 2015-2018  Intel Corporation
  */
 
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 struct h4_recv_pkt {
        u8  type;       /* Packet type */
index 77a5454a8721e84877407614c989be9f627d45d5..9bce53e49cfa60c6ee9ea734e5d7a0708dc7a679 100644 (file)
@@ -17,7 +17,7 @@
 #include <linux/pci.h>
 #include <linux/printk.h>
 
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #include <net/bluetooth/bluetooth.h>
 #include <net/bluetooth/hci_core.h>
index 2a5a27d713f8a0f04d6357eb642885203648ea3b..76878119d910cf55ef7d3526fc86f25c971ff12b 100644 (file)
@@ -25,7 +25,7 @@
 #include <linux/ioctl.h>
 #include <linux/skbuff.h>
 #include <linux/bitrev.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #include <net/bluetooth/bluetooth.h>
 #include <net/bluetooth/hci_core.h>
index 1d0cdf02324373062f82e69d7acb1cd28c4271f9..9070e31a68bfd22cc31c66c53caf122a17d32f53 100644 (file)
@@ -25,7 +25,7 @@
 #include <linux/signal.h>
 #include <linux/ioctl.h>
 #include <linux/skbuff.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #include <net/bluetooth/bluetooth.h>
 #include <net/bluetooth/hci_core.h>
index 62633d9ba7c43eedefa657337b9fa2521d330a88..49bbe4975be4bc3ab24615e73683a66acabe1931 100644 (file)
@@ -20,7 +20,7 @@
 #include <linux/slab.h>
 #include <linux/string.h>
 #include <linux/types.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include <net/bluetooth/bluetooth.h>
 #include <net/bluetooth/hci_core.h>
 
index 678f150229e7796b237f5b538292100383d58407..37fddf6055bebbbd9cab493a3d366060f0f25c3d 100644 (file)
@@ -32,7 +32,7 @@
 #include <linux/regulator/consumer.h>
 #include <linux/serdev.h>
 #include <linux/mutex.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #include <net/bluetooth/bluetooth.h>
 #include <net/bluetooth/hci_core.h>
index aa6af351d02de2b73ea6090b2ef8e6a1dee9c1b4..7651321d351ccd5a96503bb555b5d9eb2c35b4ff 100644 (file)
@@ -9,7 +9,7 @@
  */
 
 #include <linux/module.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #include <linux/atomic.h>
 #include <linux/kernel.h>
index 9b0f37d4b9d49ac4843e9c851643574c9152392d..6a99a459b80b2db3aac45ae6db0f8e77369d0238 100644 (file)
@@ -2313,7 +2313,7 @@ static int cdrom_ioctl_media_changed(struct cdrom_device_info *cdi,
                return -EINVAL;
 
        /* Prevent arg from speculatively bypassing the length check */
-       barrier_nospec();
+       arg = array_index_nospec(arg, cdi->capacity);
 
        info = kmalloc(sizeof(*info), GFP_KERNEL);
        if (!info)
index 854546000c92bfb16224633dfc36993716bb5464..1ff99a7091bbbacff18aa45d76f806b951d94b28 100644 (file)
@@ -674,6 +674,16 @@ EXPORT_SYMBOL_GPL(tpm_chip_register);
  */
 void tpm_chip_unregister(struct tpm_chip *chip)
 {
+#ifdef CONFIG_TCG_TPM2_HMAC
+       int rc;
+
+       rc = tpm_try_get_ops(chip);
+       if (!rc) {
+               tpm2_end_auth_session(chip);
+               tpm_put_ops(chip);
+       }
+#endif
+
        tpm_del_legacy_sysfs(chip);
        if (tpm_is_hwrng_enabled(chip))
                hwrng_unregister(&chip->hwrng);
index c3fbbf4d3db79a9b4523611aecc6772bcddffed8..48ff87444f85194651a32ab5c59e656af71064b7 100644 (file)
@@ -27,6 +27,9 @@ static ssize_t tpm_dev_transmit(struct tpm_chip *chip, struct tpm_space *space,
        struct tpm_header *header = (void *)buf;
        ssize_t ret, len;
 
+       if (chip->flags & TPM_CHIP_FLAG_TPM2)
+               tpm2_end_auth_session(chip);
+
        ret = tpm2_prepare_space(chip, space, buf, bufsiz);
        /* If the command is not implemented by the TPM, synthesize a
         * response with a TPM2_RC_COMMAND_CODE return for user-space.
index 5da134f12c9a470fb83f85574b46b6105466111a..8134f002b121f80ba8fe3f28218a27be1497bc4b 100644 (file)
@@ -379,10 +379,12 @@ int tpm_pm_suspend(struct device *dev)
 
        rc = tpm_try_get_ops(chip);
        if (!rc) {
-               if (chip->flags & TPM_CHIP_FLAG_TPM2)
+               if (chip->flags & TPM_CHIP_FLAG_TPM2) {
+                       tpm2_end_auth_session(chip);
                        tpm2_shutdown(chip, TPM2_SU_STATE);
-               else
+               } else {
                        rc = tpm1_pm_suspend(chip, tpm_suspend_pcr);
+               }
 
                tpm_put_ops(chip);
        }
index 44f60730cff4415c94a44c26086264c15770495a..0739830904b2b3fc7aa88fbaa306b0aaf3e91d64 100644 (file)
@@ -71,7 +71,7 @@
 #include "tpm.h"
 #include <linux/random.h>
 #include <linux/scatterlist.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include <crypto/kpp.h>
 #include <crypto/ecdh.h>
 #include <crypto/hash.h>
@@ -333,6 +333,9 @@ void tpm_buf_append_hmac_session(struct tpm_chip *chip, struct tpm_buf *buf,
        }
 
 #ifdef CONFIG_TCG_TPM2_HMAC
+       /* The first write to /dev/tpm{rm0} will flush the session. */
+       attributes |= TPM2_SA_CONTINUE_SESSION;
+
        /*
         * The Architecture Guide requires us to strip trailing zeros
         * before computing the HMAC
@@ -484,7 +487,8 @@ static void tpm2_KDFe(u8 z[EC_PT_SZ], const char *str, u8 *pt_u, u8 *pt_v,
        sha256_final(&sctx, out);
 }
 
-static void tpm_buf_append_salt(struct tpm_buf *buf, struct tpm_chip *chip)
+static void tpm_buf_append_salt(struct tpm_buf *buf, struct tpm_chip *chip,
+                               struct tpm2_auth *auth)
 {
        struct crypto_kpp *kpp;
        struct kpp_request *req;
@@ -543,7 +547,7 @@ static void tpm_buf_append_salt(struct tpm_buf *buf, struct tpm_chip *chip)
        sg_set_buf(&s[0], chip->null_ec_key_x, EC_PT_SZ);
        sg_set_buf(&s[1], chip->null_ec_key_y, EC_PT_SZ);
        kpp_request_set_input(req, s, EC_PT_SZ*2);
-       sg_init_one(d, chip->auth->salt, EC_PT_SZ);
+       sg_init_one(d, auth->salt, EC_PT_SZ);
        kpp_request_set_output(req, d, EC_PT_SZ);
        crypto_kpp_compute_shared_secret(req);
        kpp_request_free(req);
@@ -554,8 +558,7 @@ static void tpm_buf_append_salt(struct tpm_buf *buf, struct tpm_chip *chip)
         * This works because KDFe fully consumes the secret before it
         * writes the salt
         */
-       tpm2_KDFe(chip->auth->salt, "SECRET", x, chip->null_ec_key_x,
-                 chip->auth->salt);
+       tpm2_KDFe(auth->salt, "SECRET", x, chip->null_ec_key_x, auth->salt);
 
  out:
        crypto_free_kpp(kpp);
@@ -853,7 +856,9 @@ int tpm_buf_check_hmac_response(struct tpm_chip *chip, struct tpm_buf *buf,
                if (rc)
                        /* manually close the session if it wasn't consumed */
                        tpm2_flush_context(chip, auth->handle);
-               memzero_explicit(auth, sizeof(*auth));
+
+               kfree_sensitive(auth);
+               chip->auth = NULL;
        } else {
                /* reset for next use  */
                auth->session = TPM_HEADER_SIZE;
@@ -881,7 +886,8 @@ void tpm2_end_auth_session(struct tpm_chip *chip)
                return;
 
        tpm2_flush_context(chip, auth->handle);
-       memzero_explicit(auth, sizeof(*auth));
+       kfree_sensitive(auth);
+       chip->auth = NULL;
 }
 EXPORT_SYMBOL(tpm2_end_auth_session);
 
@@ -915,33 +921,37 @@ static int tpm2_parse_start_auth_session(struct tpm2_auth *auth,
 
 static int tpm2_load_null(struct tpm_chip *chip, u32 *null_key)
 {
-       int rc;
        unsigned int offset = 0; /* dummy offset for null seed context */
        u8 name[SHA256_DIGEST_SIZE + 2];
+       u32 tmp_null_key;
+       int rc;
 
        rc = tpm2_load_context(chip, chip->null_key_context, &offset,
-                              null_key);
-       if (rc != -EINVAL)
-               return rc;
+                              &tmp_null_key);
+       if (rc != -EINVAL) {
+               if (!rc)
+                       *null_key = tmp_null_key;
+               goto err;
+       }
 
-       /* an integrity failure may mean the TPM has been reset */
-       dev_err(&chip->dev, "NULL key integrity failure!\n");
-       /* check the null name against what we know */
-       tpm2_create_primary(chip, TPM2_RH_NULL, NULL, name);
-       if (memcmp(name, chip->null_key_name, sizeof(name)) == 0)
-               /* name unchanged, assume transient integrity failure */
-               return rc;
-       /*
-        * Fatal TPM failure: the NULL seed has actually changed, so
-        * the TPM must have been illegally reset.  All in-kernel TPM
-        * operations will fail because the NULL primary can't be
-        * loaded to salt the sessions, but disable the TPM anyway so
-        * userspace programmes can't be compromised by it.
-        */
-       dev_err(&chip->dev, "NULL name has changed, disabling TPM due to interference\n");
+       /* Try to re-create null key, given the integrity failure: */
+       rc = tpm2_create_primary(chip, TPM2_RH_NULL, &tmp_null_key, name);
+       if (rc)
+               goto err;
+
+       /* Return null key if the name has not been changed: */
+       if (!memcmp(name, chip->null_key_name, sizeof(name))) {
+               *null_key = tmp_null_key;
+               return 0;
+       }
+
+       /* Deduce from the name change TPM interference: */
+       dev_err(&chip->dev, "null key integrity check failed\n");
+       tpm2_flush_context(chip, tmp_null_key);
        chip->flags |= TPM_CHIP_FLAG_DISABLE;
 
-       return rc;
+err:
+       return rc ? -ENODEV : 0;
 }
 
 /**
@@ -958,16 +968,20 @@ static int tpm2_load_null(struct tpm_chip *chip, u32 *null_key)
  */
 int tpm2_start_auth_session(struct tpm_chip *chip)
 {
+       struct tpm2_auth *auth;
        struct tpm_buf buf;
-       struct tpm2_auth *auth = chip->auth;
-       int rc;
        u32 null_key;
+       int rc;
 
-       if (!auth) {
-               dev_warn_once(&chip->dev, "auth session is not active\n");
+       if (chip->auth) {
+               dev_warn_once(&chip->dev, "auth session is active\n");
                return 0;
        }
 
+       auth = kzalloc(sizeof(*auth), GFP_KERNEL);
+       if (!auth)
+               return -ENOMEM;
+
        rc = tpm2_load_null(chip, &null_key);
        if (rc)
                goto out;
@@ -988,7 +1002,7 @@ int tpm2_start_auth_session(struct tpm_chip *chip)
        tpm_buf_append(&buf, auth->our_nonce, sizeof(auth->our_nonce));
 
        /* append encrypted salt and squirrel away unencrypted in auth */
-       tpm_buf_append_salt(&buf, chip);
+       tpm_buf_append_salt(&buf, chip, auth);
        /* session type (HMAC, audit or policy) */
        tpm_buf_append_u8(&buf, TPM2_SE_HMAC);
 
@@ -1010,10 +1024,13 @@ int tpm2_start_auth_session(struct tpm_chip *chip)
 
        tpm_buf_destroy(&buf);
 
-       if (rc)
-               goto out;
+       if (rc == TPM2_RC_SUCCESS) {
+               chip->auth = auth;
+               return 0;
+       }
 
- out:
+out:
+       kfree_sensitive(auth);
        return rc;
 }
 EXPORT_SYMBOL(tpm2_start_auth_session);
@@ -1347,18 +1364,21 @@ static int tpm2_create_null_primary(struct tpm_chip *chip)
  *
  * Derive and context save the null primary and allocate memory in the
  * struct tpm_chip for the authorizations.
+ *
+ * Return:
+ * * 0         - OK
+ * * -errno    - A system error
+ * * TPM_RC    - A TPM error
  */
 int tpm2_sessions_init(struct tpm_chip *chip)
 {
        int rc;
 
        rc = tpm2_create_null_primary(chip);
-       if (rc)
-               dev_err(&chip->dev, "TPM: security failed (NULL seed derivation): %d\n", rc);
-
-       chip->auth = kmalloc(sizeof(*chip->auth), GFP_KERNEL);
-       if (!chip->auth)
-               return -ENOMEM;
+       if (rc) {
+               dev_err(&chip->dev, "null key creation failed with %d\n", rc);
+               return rc;
+       }
 
        return rc;
 }
index 25a66870c165c503b58cbb45c4c6906583384bb9..60354cd53b5c121f7f5fcbfe85cc88e3b903719a 100644 (file)
@@ -12,7 +12,7 @@
  */
 
 #include <linux/gfp.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include "tpm.h"
 
 enum tpm2_handle_types {
index 99a7f2441e70fb352b4e9b6ef163e7274913a485..c62b208b42f13187dfdaf2afc8ead9407c6f36c6 100644 (file)
@@ -2006,25 +2006,27 @@ static int virtcons_probe(struct virtio_device *vdev)
                multiport = true;
        }
 
-       err = init_vqs(portdev);
-       if (err < 0) {
-               dev_err(&vdev->dev, "Error %d initializing vqs\n", err);
-               goto free_chrdev;
-       }
-
        spin_lock_init(&portdev->ports_lock);
        INIT_LIST_HEAD(&portdev->ports);
        INIT_LIST_HEAD(&portdev->list);
 
-       virtio_device_ready(portdev->vdev);
-
        INIT_WORK(&portdev->config_work, &config_work_handler);
        INIT_WORK(&portdev->control_work, &control_work_handler);
 
        if (multiport) {
                spin_lock_init(&portdev->c_ivq_lock);
                spin_lock_init(&portdev->c_ovq_lock);
+       }
 
+       err = init_vqs(portdev);
+       if (err < 0) {
+               dev_err(&vdev->dev, "Error %d initializing vqs\n", err);
+               goto free_chrdev;
+       }
+
+       virtio_device_ready(portdev->vdev);
+
+       if (multiport) {
                err = fill_queue(portdev->c_ivq, &portdev->c_ivq_lock);
                if (err < 0) {
                        dev_err(&vdev->dev,
index 6e8dd7387cfdd48e03cda92f466232c10e64239f..5004888c7eca5f85a444ec6de684b8dd79635622 100644 (file)
@@ -21,7 +21,7 @@
 #include <linux/regmap.h>
 #include <linux/regulator/consumer.h>
 #include <linux/slab.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #define SI5341_NUM_INPUTS 4
 
index 41fc8eba34184809721604b0bade46df9eeb8d7e..aa3ddcfc00eba02c3f159db1c99c36116e9fc207 100644 (file)
@@ -473,7 +473,7 @@ clk_multiple_parents_mux_test_init(struct kunit *test)
                                                            &clk_dummy_rate_ops,
                                                            0);
        ctx->parents_ctx[0].rate = DUMMY_CLOCK_RATE_1;
-       ret = clk_hw_register(NULL, &ctx->parents_ctx[0].hw);
+       ret = clk_hw_register_kunit(test, NULL, &ctx->parents_ctx[0].hw);
        if (ret)
                return ret;
 
@@ -481,7 +481,7 @@ clk_multiple_parents_mux_test_init(struct kunit *test)
                                                            &clk_dummy_rate_ops,
                                                            0);
        ctx->parents_ctx[1].rate = DUMMY_CLOCK_RATE_2;
-       ret = clk_hw_register(NULL, &ctx->parents_ctx[1].hw);
+       ret = clk_hw_register_kunit(test, NULL, &ctx->parents_ctx[1].hw);
        if (ret)
                return ret;
 
@@ -489,23 +489,13 @@ clk_multiple_parents_mux_test_init(struct kunit *test)
        ctx->hw.init = CLK_HW_INIT_PARENTS("test-mux", parents,
                                           &clk_multiple_parents_mux_ops,
                                           CLK_SET_RATE_PARENT);
-       ret = clk_hw_register(NULL, &ctx->hw);
+       ret = clk_hw_register_kunit(test, NULL, &ctx->hw);
        if (ret)
                return ret;
 
        return 0;
 }
 
-static void
-clk_multiple_parents_mux_test_exit(struct kunit *test)
-{
-       struct clk_multiple_parent_ctx *ctx = test->priv;
-
-       clk_hw_unregister(&ctx->hw);
-       clk_hw_unregister(&ctx->parents_ctx[0].hw);
-       clk_hw_unregister(&ctx->parents_ctx[1].hw);
-}
-
 /*
  * Test that for a clock with multiple parents, clk_get_parent()
  * actually returns the current one.
@@ -561,18 +551,18 @@ clk_test_multiple_parents_mux_set_range_set_parent_get_rate(struct kunit *test)
 {
        struct clk_multiple_parent_ctx *ctx = test->priv;
        struct clk_hw *hw = &ctx->hw;
-       struct clk *clk = clk_hw_get_clk(hw, NULL);
+       struct clk *clk = clk_hw_get_clk_kunit(test, hw, NULL);
        struct clk *parent1, *parent2;
        unsigned long rate;
        int ret;
 
        kunit_skip(test, "This needs to be fixed in the core.");
 
-       parent1 = clk_hw_get_clk(&ctx->parents_ctx[0].hw, NULL);
+       parent1 = clk_hw_get_clk_kunit(test, &ctx->parents_ctx[0].hw, NULL);
        KUNIT_ASSERT_NOT_ERR_OR_NULL(test, parent1);
        KUNIT_ASSERT_TRUE(test, clk_is_match(clk_get_parent(clk), parent1));
 
-       parent2 = clk_hw_get_clk(&ctx->parents_ctx[1].hw, NULL);
+       parent2 = clk_hw_get_clk_kunit(test, &ctx->parents_ctx[1].hw, NULL);
        KUNIT_ASSERT_NOT_ERR_OR_NULL(test, parent2);
 
        ret = clk_set_rate(parent1, DUMMY_CLOCK_RATE_1);
@@ -593,10 +583,6 @@ clk_test_multiple_parents_mux_set_range_set_parent_get_rate(struct kunit *test)
        KUNIT_ASSERT_GT(test, rate, 0);
        KUNIT_EXPECT_GE(test, rate, DUMMY_CLOCK_RATE_1 - 1000);
        KUNIT_EXPECT_LE(test, rate, DUMMY_CLOCK_RATE_1 + 1000);
-
-       clk_put(parent2);
-       clk_put(parent1);
-       clk_put(clk);
 }
 
 static struct kunit_case clk_multiple_parents_mux_test_cases[] = {
@@ -617,7 +603,6 @@ static struct kunit_suite
 clk_multiple_parents_mux_test_suite = {
        .name = "clk-multiple-parents-mux-test",
        .init = clk_multiple_parents_mux_test_init,
-       .exit = clk_multiple_parents_mux_test_exit,
        .test_cases = clk_multiple_parents_mux_test_cases,
 };
 
@@ -637,29 +622,20 @@ clk_orphan_transparent_multiple_parent_mux_test_init(struct kunit *test)
                                                            &clk_dummy_rate_ops,
                                                            0);
        ctx->parents_ctx[1].rate = DUMMY_CLOCK_INIT_RATE;
-       ret = clk_hw_register(NULL, &ctx->parents_ctx[1].hw);
+       ret = clk_hw_register_kunit(test, NULL, &ctx->parents_ctx[1].hw);
        if (ret)
                return ret;
 
        ctx->hw.init = CLK_HW_INIT_PARENTS("test-orphan-mux", parents,
                                           &clk_multiple_parents_mux_ops,
                                           CLK_SET_RATE_PARENT);
-       ret = clk_hw_register(NULL, &ctx->hw);
+       ret = clk_hw_register_kunit(test, NULL, &ctx->hw);
        if (ret)
                return ret;
 
        return 0;
 }
 
-static void
-clk_orphan_transparent_multiple_parent_mux_test_exit(struct kunit *test)
-{
-       struct clk_multiple_parent_ctx *ctx = test->priv;
-
-       clk_hw_unregister(&ctx->hw);
-       clk_hw_unregister(&ctx->parents_ctx[1].hw);
-}
-
 /*
  * Test that, for a mux whose current parent hasn't been registered yet and is
  * thus orphan, clk_get_parent() will return NULL.
@@ -912,7 +888,7 @@ clk_test_orphan_transparent_multiple_parent_mux_set_range_set_parent_get_rate(st
 {
        struct clk_multiple_parent_ctx *ctx = test->priv;
        struct clk_hw *hw = &ctx->hw;
-       struct clk *clk = clk_hw_get_clk(hw, NULL);
+       struct clk *clk = clk_hw_get_clk_kunit(test, hw, NULL);
        struct clk *parent;
        unsigned long rate;
        int ret;
@@ -921,7 +897,7 @@ clk_test_orphan_transparent_multiple_parent_mux_set_range_set_parent_get_rate(st
 
        clk_hw_set_rate_range(hw, DUMMY_CLOCK_RATE_1, DUMMY_CLOCK_RATE_2);
 
-       parent = clk_hw_get_clk(&ctx->parents_ctx[1].hw, NULL);
+       parent = clk_hw_get_clk_kunit(test, &ctx->parents_ctx[1].hw, NULL);
        KUNIT_ASSERT_NOT_ERR_OR_NULL(test, parent);
 
        ret = clk_set_parent(clk, parent);
@@ -931,9 +907,6 @@ clk_test_orphan_transparent_multiple_parent_mux_set_range_set_parent_get_rate(st
        KUNIT_ASSERT_GT(test, rate, 0);
        KUNIT_EXPECT_GE(test, rate, DUMMY_CLOCK_RATE_1);
        KUNIT_EXPECT_LE(test, rate, DUMMY_CLOCK_RATE_2);
-
-       clk_put(parent);
-       clk_put(clk);
 }
 
 static struct kunit_case clk_orphan_transparent_multiple_parent_mux_test_cases[] = {
@@ -961,7 +934,6 @@ static struct kunit_case clk_orphan_transparent_multiple_parent_mux_test_cases[]
 static struct kunit_suite clk_orphan_transparent_multiple_parent_mux_test_suite = {
        .name = "clk-orphan-transparent-multiple-parent-mux-test",
        .init = clk_orphan_transparent_multiple_parent_mux_test_init,
-       .exit = clk_orphan_transparent_multiple_parent_mux_test_exit,
        .test_cases = clk_orphan_transparent_multiple_parent_mux_test_cases,
 };
 
@@ -986,7 +958,7 @@ static int clk_single_parent_mux_test_init(struct kunit *test)
                                      &clk_dummy_rate_ops,
                                      0);
 
-       ret = clk_hw_register(NULL, &ctx->parent_ctx.hw);
+       ret = clk_hw_register_kunit(test, NULL, &ctx->parent_ctx.hw);
        if (ret)
                return ret;
 
@@ -994,7 +966,7 @@ static int clk_single_parent_mux_test_init(struct kunit *test)
                                   &clk_dummy_single_parent_ops,
                                   CLK_SET_RATE_PARENT);
 
-       ret = clk_hw_register(NULL, &ctx->hw);
+       ret = clk_hw_register_kunit(test, NULL, &ctx->hw);
        if (ret)
                return ret;
 
@@ -1060,7 +1032,7 @@ clk_test_single_parent_mux_set_range_disjoint_child_last(struct kunit *test)
 {
        struct clk_single_parent_ctx *ctx = test->priv;
        struct clk_hw *hw = &ctx->hw;
-       struct clk *clk = clk_hw_get_clk(hw, NULL);
+       struct clk *clk = clk_hw_get_clk_kunit(test, hw, NULL);
        struct clk *parent;
        int ret;
 
@@ -1074,8 +1046,6 @@ clk_test_single_parent_mux_set_range_disjoint_child_last(struct kunit *test)
 
        ret = clk_set_rate_range(clk, 3000, 4000);
        KUNIT_EXPECT_LT(test, ret, 0);
-
-       clk_put(clk);
 }
 
 /*
@@ -1092,7 +1062,7 @@ clk_test_single_parent_mux_set_range_disjoint_parent_last(struct kunit *test)
 {
        struct clk_single_parent_ctx *ctx = test->priv;
        struct clk_hw *hw = &ctx->hw;
-       struct clk *clk = clk_hw_get_clk(hw, NULL);
+       struct clk *clk = clk_hw_get_clk_kunit(test, hw, NULL);
        struct clk *parent;
        int ret;
 
@@ -1106,8 +1076,6 @@ clk_test_single_parent_mux_set_range_disjoint_parent_last(struct kunit *test)
 
        ret = clk_set_rate_range(parent, 3000, 4000);
        KUNIT_EXPECT_LT(test, ret, 0);
-
-       clk_put(clk);
 }
 
 /*
@@ -1238,7 +1206,6 @@ static struct kunit_suite
 clk_single_parent_mux_test_suite = {
        .name = "clk-single-parent-mux-test",
        .init = clk_single_parent_mux_test_init,
-       .exit = clk_single_parent_mux_test_exit,
        .test_cases = clk_single_parent_mux_test_cases,
 };
 
index 2fa7253c73b2cdfc5b8c9f73539eb7250be8897b..88629a9abc9c90905324c458731ee3457933c59c 100644 (file)
@@ -439,7 +439,7 @@ unsigned long rockchip_clk_find_max_clk_id(struct rockchip_clk_branch *list,
                if (list->id > max)
                        max = list->id;
                if (list->child && list->child->id > max)
-                       max = list->id;
+                       max = list->child->id;
        }
 
        return max;
index 7ba9748c0526afd0f6492a5a3d7123e4eb79d689..f60f0a0c598de596fccbfd61e19ba8b4d0ab3d0d 100644 (file)
@@ -1155,6 +1155,7 @@ static const struct of_device_id exynosautov920_cmu_of_match[] = {
                .compatible = "samsung,exynosautov920-cmu-peric0",
                .data = &peric0_cmu_info,
        },
+       { }
 };
 
 static struct platform_driver exynosautov920_cmu_driver __refdata = {
index 2aaeaf44fbe57d29db63baccce4ffa9e655c5162..3f215ae228b2d3a7a82b7881f4751a7177d0fe3f 100644 (file)
@@ -39,7 +39,7 @@
 #include <linux/input.h>
 #include <linux/fcntl.h>
 #include <linux/compiler.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include <linux/comedi/comedi_usb.h>
 
 /* timeout for the USB-transfer in ms*/
index ed1f57511955856af1bbb76fc8b3e81ce51ae7b8..4a6868b8f58bce508ce2d50b1416275f6aeb582b 100644 (file)
@@ -22,7 +22,7 @@
 #include <linux/spinlock.h>
 #include <linux/types.h>
 
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #define QUAD8_EXTENT 32
 
index c41e4fdc96011752a55b029a2a76e668cda16ce6..6d74e8ef92f009d31e5806fbfe2d37d46ee0dae6 100644 (file)
@@ -15,7 +15,7 @@
 #include <linux/mutex.h>
 #include <linux/regmap.h>
 
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #define I8254_COUNTER_REG(_counter) (_counter)
 #define I8254_CONTROL_REG 0x3
index 15e201d5e911c32289cb31e3d648730ebef42a74..b63863f77c67780b14713d4fb56b9dba7a18288d 100644 (file)
@@ -536,11 +536,16 @@ static int amd_pstate_verify(struct cpufreq_policy_data *policy)
 
 static int amd_pstate_update_min_max_limit(struct cpufreq_policy *policy)
 {
-       u32 max_limit_perf, min_limit_perf, lowest_perf;
+       u32 max_limit_perf, min_limit_perf, lowest_perf, max_perf;
        struct amd_cpudata *cpudata = policy->driver_data;
 
-       max_limit_perf = div_u64(policy->max * cpudata->highest_perf, cpudata->max_freq);
-       min_limit_perf = div_u64(policy->min * cpudata->highest_perf, cpudata->max_freq);
+       if (cpudata->boost_supported && !policy->boost_enabled)
+               max_perf = READ_ONCE(cpudata->nominal_perf);
+       else
+               max_perf = READ_ONCE(cpudata->highest_perf);
+
+       max_limit_perf = div_u64(policy->max * max_perf, policy->cpuinfo.max_freq);
+       min_limit_perf = div_u64(policy->min * max_perf, policy->cpuinfo.max_freq);
 
        lowest_perf = READ_ONCE(cpudata->lowest_perf);
        if (min_limit_perf < lowest_perf)
@@ -1201,11 +1206,21 @@ static int amd_pstate_register_driver(int mode)
                return -EINVAL;
 
        cppc_state = mode;
+
+       ret = amd_pstate_enable(true);
+       if (ret) {
+               pr_err("failed to enable cppc during amd-pstate driver registration, return %d\n",
+                      ret);
+               amd_pstate_driver_cleanup();
+               return ret;
+       }
+
        ret = cpufreq_register_driver(current_pstate_driver);
        if (ret) {
                amd_pstate_driver_cleanup();
                return ret;
        }
+
        return 0;
 }
 
@@ -1496,10 +1511,13 @@ static int amd_pstate_epp_update_limit(struct cpufreq_policy *policy)
        u64 value;
        s16 epp;
 
-       max_perf = READ_ONCE(cpudata->highest_perf);
+       if (cpudata->boost_supported && !policy->boost_enabled)
+               max_perf = READ_ONCE(cpudata->nominal_perf);
+       else
+               max_perf = READ_ONCE(cpudata->highest_perf);
        min_perf = READ_ONCE(cpudata->lowest_perf);
-       max_limit_perf = div_u64(policy->max * cpudata->highest_perf, cpudata->max_freq);
-       min_limit_perf = div_u64(policy->min * cpudata->highest_perf, cpudata->max_freq);
+       max_limit_perf = div_u64(policy->max * max_perf, policy->cpuinfo.max_freq);
+       min_limit_perf = div_u64(policy->min * max_perf, policy->cpuinfo.max_freq);
 
        if (min_limit_perf < min_perf)
                min_limit_perf = min_perf;
index 1a5ad184d28fc24e318f17e4cdad06efbb74ad90..2b8708475ac7761e18bf9a4a7be14957e0937133 100644 (file)
@@ -22,7 +22,7 @@
 #include <linux/vmalloc.h>
 #include <uapi/linux/sched/types.h>
 
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #include <acpi/cppc_acpi.h>
 
index aaea9a39ecedb4a3f4de5779fd1a26f501e18255..b0018f371ea3a5e996cc9e94dd98e4bc7ae5af02 100644 (file)
@@ -1845,7 +1845,7 @@ static void intel_pstate_notify_work(struct work_struct *work)
        wrmsrl_on_cpu(cpudata->cpu, MSR_HWP_STATUS, 0);
 }
 
-static DEFINE_SPINLOCK(hwp_notify_lock);
+static DEFINE_RAW_SPINLOCK(hwp_notify_lock);
 static cpumask_t hwp_intr_enable_mask;
 
 #define HWP_GUARANTEED_PERF_CHANGE_STATUS      BIT(0)
@@ -1868,7 +1868,7 @@ void notify_hwp_interrupt(void)
        if (!(value & status_mask))
                return;
 
-       spin_lock_irqsave(&hwp_notify_lock, flags);
+       raw_spin_lock_irqsave(&hwp_notify_lock, flags);
 
        if (!cpumask_test_cpu(this_cpu, &hwp_intr_enable_mask))
                goto ack_intr;
@@ -1876,13 +1876,13 @@ void notify_hwp_interrupt(void)
        schedule_delayed_work(&all_cpu_data[this_cpu]->hwp_notify_work,
                              msecs_to_jiffies(10));
 
-       spin_unlock_irqrestore(&hwp_notify_lock, flags);
+       raw_spin_unlock_irqrestore(&hwp_notify_lock, flags);
 
        return;
 
 ack_intr:
        wrmsrl_safe(MSR_HWP_STATUS, 0);
-       spin_unlock_irqrestore(&hwp_notify_lock, flags);
+       raw_spin_unlock_irqrestore(&hwp_notify_lock, flags);
 }
 
 static void intel_pstate_disable_hwp_interrupt(struct cpudata *cpudata)
@@ -1895,9 +1895,9 @@ static void intel_pstate_disable_hwp_interrupt(struct cpudata *cpudata)
        /* wrmsrl_on_cpu has to be outside spinlock as this can result in IPC */
        wrmsrl_on_cpu(cpudata->cpu, MSR_HWP_INTERRUPT, 0x00);
 
-       spin_lock_irq(&hwp_notify_lock);
+       raw_spin_lock_irq(&hwp_notify_lock);
        cancel_work = cpumask_test_and_clear_cpu(cpudata->cpu, &hwp_intr_enable_mask);
-       spin_unlock_irq(&hwp_notify_lock);
+       raw_spin_unlock_irq(&hwp_notify_lock);
 
        if (cancel_work)
                cancel_delayed_work_sync(&cpudata->hwp_notify_work);
@@ -1912,10 +1912,10 @@ static void intel_pstate_enable_hwp_interrupt(struct cpudata *cpudata)
        if (boot_cpu_has(X86_FEATURE_HWP_NOTIFY)) {
                u64 interrupt_mask = HWP_GUARANTEED_PERF_CHANGE_REQ;
 
-               spin_lock_irq(&hwp_notify_lock);
+               raw_spin_lock_irq(&hwp_notify_lock);
                INIT_DELAYED_WORK(&cpudata->hwp_notify_work, intel_pstate_notify_work);
                cpumask_set_cpu(cpudata->cpu, &hwp_intr_enable_mask);
-               spin_unlock_irq(&hwp_notify_lock);
+               raw_spin_unlock_irq(&hwp_notify_lock);
 
                if (cpu_feature_enabled(X86_FEATURE_HWP_HIGHEST_PERF_CHANGE))
                        interrupt_mask |= HWP_HIGHEST_PERF_CHANGE_REQ;
index f7893e4ac59dd8ceea2993d18ded40d6ee91f55a..434f2b2710120034328bae2498a21a23ff53a8bf 100644 (file)
@@ -9,7 +9,7 @@
  * You could find the datasheet in Documentation/arch/arm/sunxi.rst
  */
 #include "sun4i-ss.h"
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include <linux/scatterlist.h>
 
 /* This is a totally arbitrary value */
index 066f08a3a040d875aab98bc9f2603fbb2381a3f6..2cfb1b8d8c7cfc585f405c6f3a5c13be0aee08d0 100644 (file)
@@ -56,7 +56,7 @@
 #include "sg_sw_sec4.h"
 #include "key_gen.h"
 #include "caamalg_desc.h"
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include <crypto/internal/aead.h>
 #include <crypto/internal/engine.h>
 #include <crypto/internal/skcipher.h>
index 13347dfecf7ac0ebc4783541dc7eef6755311850..65f6adb6c673f8016533b018035b9715b6be3c64 100644 (file)
@@ -19,7 +19,7 @@
 #include "jr.h"
 #include "caamalg_desc.h"
 #include <crypto/xts.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include <linux/device.h>
 #include <linux/err.h>
 #include <linux/dma-mapping.h>
index 44e1f8f469674ba46969237c33e0ea16638c7378..e809d030ab1135ad43887a99c0e115f58ae9f7b1 100644 (file)
@@ -22,7 +22,7 @@
 #include <soc/fsl/dpaa2-io.h>
 #include <soc/fsl/dpaa2-fd.h>
 #include <crypto/xts.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #define CAAM_CRA_PRIORITY      2000
 
index 42677f7458b787e3722760efa42013834dc05e95..919e5a2cab95e3b46f2068e871e5495775620206 100644 (file)
@@ -5,7 +5,7 @@
  * Antoine Tenart <[email protected]>
  */
 
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include <linux/device.h>
 #include <linux/dma-mapping.h>
 #include <linux/dmapool.h>
index 8d84ad45571c7fba912c39cfd5e2c01cd5872795..f150861ceaf6957c12c359dbf6279948ec836f9f 100644 (file)
@@ -947,7 +947,7 @@ struct ahash_alg mv_md5_alg = {
                .base = {
                        .cra_name = "md5",
                        .cra_driver_name = "mv-md5",
-                       .cra_priority = 300,
+                       .cra_priority = 0,
                        .cra_flags = CRYPTO_ALG_ASYNC |
                                     CRYPTO_ALG_ALLOCATES_MEMORY |
                                     CRYPTO_ALG_KERN_DRIVER_ONLY,
@@ -1018,7 +1018,7 @@ struct ahash_alg mv_sha1_alg = {
                .base = {
                        .cra_name = "sha1",
                        .cra_driver_name = "mv-sha1",
-                       .cra_priority = 300,
+                       .cra_priority = 0,
                        .cra_flags = CRYPTO_ALG_ASYNC |
                                     CRYPTO_ALG_ALLOCATES_MEMORY |
                                     CRYPTO_ALG_KERN_DRIVER_ONLY,
@@ -1092,7 +1092,7 @@ struct ahash_alg mv_sha256_alg = {
                .base = {
                        .cra_name = "sha256",
                        .cra_driver_name = "mv-sha256",
-                       .cra_priority = 300,
+                       .cra_priority = 0,
                        .cra_flags = CRYPTO_ALG_ASYNC |
                                     CRYPTO_ALG_ALLOCATES_MEMORY |
                                     CRYPTO_ALG_KERN_DRIVER_ONLY,
@@ -1302,7 +1302,7 @@ struct ahash_alg mv_ahmac_md5_alg = {
                .base = {
                        .cra_name = "hmac(md5)",
                        .cra_driver_name = "mv-hmac-md5",
-                       .cra_priority = 300,
+                       .cra_priority = 0,
                        .cra_flags = CRYPTO_ALG_ASYNC |
                                     CRYPTO_ALG_ALLOCATES_MEMORY |
                                     CRYPTO_ALG_KERN_DRIVER_ONLY,
@@ -1373,7 +1373,7 @@ struct ahash_alg mv_ahmac_sha1_alg = {
                .base = {
                        .cra_name = "hmac(sha1)",
                        .cra_driver_name = "mv-hmac-sha1",
-                       .cra_priority = 300,
+                       .cra_priority = 0,
                        .cra_flags = CRYPTO_ALG_ASYNC |
                                     CRYPTO_ALG_ALLOCATES_MEMORY |
                                     CRYPTO_ALG_KERN_DRIVER_ONLY,
@@ -1444,7 +1444,7 @@ struct ahash_alg mv_ahmac_sha256_alg = {
                .base = {
                        .cra_name = "hmac(sha256)",
                        .cra_driver_name = "mv-hmac-sha256",
-                       .cra_priority = 300,
+                       .cra_priority = 0,
                        .cra_flags = CRYPTO_ALG_ASYNC |
                                     CRYPTO_ALG_ALLOCATES_MEMORY |
                                     CRYPTO_ALG_KERN_DRIVER_ONLY,
index a235e6c300f1e5419eb06945757946ced70f12e2..69d6019d8abcf0dc3d49942a65cfd0d20a53f549 100644 (file)
@@ -9,7 +9,7 @@
  * Some ideas are from marvell/cesa.c and s5p-sss.c driver.
  */
 
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include <crypto/internal/hash.h>
 #include <linux/device.h>
 #include <linux/err.h>
index b0cf6d2fd352ff6dc486f389f79d6d9848292ebb..e0faddbf8990cb334e3a7151bffc02e81835e66e 100644 (file)
@@ -17,7 +17,7 @@
 
 #include <crypto/internal/hash.h>
 
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #define DRIVER_NAME             "stm32-crc32"
 #define CHKSUM_DIGEST_SIZE      4
index 29c192f20082cb82a513a42ad8dac5c44b8ff0a4..876469e23f7a7f0d53da9f33ac81498e2754cd0a 100644 (file)
@@ -60,6 +60,7 @@ config CXL_ACPI
        default CXL_BUS
        select ACPI_TABLE_LIB
        select ACPI_HMAT
+       select CXL_PORT
        help
          Enable support for host managed device memory (HDM) resources
          published by a platform's ACPI CXL memory layout description.  See
index db321f48ba52e7894844e9a21e14c34a3804ba9e..2caa90fa4bf253ac376f857ebb689fcdc8901c5d 100644 (file)
@@ -1,13 +1,21 @@
 # SPDX-License-Identifier: GPL-2.0
+
+# Order is important here for the built-in case:
+# - 'core' first for fundamental init
+# - 'port' before platform root drivers like 'acpi' so that CXL-root ports
+#   are immediately enabled
+# - 'mem' and 'pmem' before endpoint drivers so that memdevs are
+#   immediately enabled
+# - 'pci' last, also mirrors the hardware enumeration hierarchy
 obj-y += core/
-obj-$(CONFIG_CXL_PCI) += cxl_pci.o
-obj-$(CONFIG_CXL_MEM) += cxl_mem.o
+obj-$(CONFIG_CXL_PORT) += cxl_port.o
 obj-$(CONFIG_CXL_ACPI) += cxl_acpi.o
 obj-$(CONFIG_CXL_PMEM) += cxl_pmem.o
-obj-$(CONFIG_CXL_PORT) += cxl_port.o
+obj-$(CONFIG_CXL_MEM) += cxl_mem.o
+obj-$(CONFIG_CXL_PCI) += cxl_pci.o
 
-cxl_mem-y := mem.o
-cxl_pci-y := pci.o
+cxl_port-y := port.o
 cxl_acpi-y := acpi.o
 cxl_pmem-y := pmem.o security.o
-cxl_port-y := port.o
+cxl_mem-y := mem.o
+cxl_pci-y := pci.o
index 82b78e331d8ed204ff31bd7c8fe118fd5a0382a3..432b7cfd12a8e10703f1513ba4553e8821369546 100644 (file)
@@ -924,6 +924,13 @@ static void __exit cxl_acpi_exit(void)
 
 /* load before dax_hmem sees 'Soft Reserved' CXL ranges */
 subsys_initcall(cxl_acpi_init);
+
+/*
+ * Arrange for host-bridge ports to be active synchronous with
+ * cxl_acpi_probe() exit.
+ */
+MODULE_SOFTDEP("pre: cxl_port");
+
 module_exit(cxl_acpi_exit);
 MODULE_DESCRIPTION("CXL ACPI: Platform Support");
 MODULE_LICENSE("GPL v2");
index ef1621d40f0542e85b01f243f888cd0368111885..e9cd7939c407ac10b5e3e3db4f6dac704b191d14 100644 (file)
@@ -641,6 +641,9 @@ static int cxl_endpoint_gather_bandwidth(struct cxl_region *cxlr,
        void *ptr;
        int rc;
 
+       if (!dev_is_pci(cxlds->dev))
+               return -ENODEV;
+
        if (cxlds->rcd)
                return -ENODEV;
 
index 3df10517a3278f228c7535fcbdb607d7b75bc879..223c273c0cd179eb07c50ca537acd77256426dca 100644 (file)
@@ -712,7 +712,44 @@ static int cxl_decoder_commit(struct cxl_decoder *cxld)
        return 0;
 }
 
-static int cxl_decoder_reset(struct cxl_decoder *cxld)
+static int commit_reap(struct device *dev, const void *data)
+{
+       struct cxl_port *port = to_cxl_port(dev->parent);
+       struct cxl_decoder *cxld;
+
+       if (!is_switch_decoder(dev) && !is_endpoint_decoder(dev))
+               return 0;
+
+       cxld = to_cxl_decoder(dev);
+       if (port->commit_end == cxld->id &&
+           ((cxld->flags & CXL_DECODER_F_ENABLE) == 0)) {
+               port->commit_end--;
+               dev_dbg(&port->dev, "reap: %s commit_end: %d\n",
+                       dev_name(&cxld->dev), port->commit_end);
+       }
+
+       return 0;
+}
+
+void cxl_port_commit_reap(struct cxl_decoder *cxld)
+{
+       struct cxl_port *port = to_cxl_port(cxld->dev.parent);
+
+       lockdep_assert_held_write(&cxl_region_rwsem);
+
+       /*
+        * Once the highest committed decoder is disabled, free any other
+        * decoders that were pinned allocated by out-of-order release.
+        */
+       port->commit_end--;
+       dev_dbg(&port->dev, "reap: %s commit_end: %d\n", dev_name(&cxld->dev),
+               port->commit_end);
+       device_for_each_child_reverse_from(&port->dev, &cxld->dev, NULL,
+                                          commit_reap);
+}
+EXPORT_SYMBOL_NS_GPL(cxl_port_commit_reap, CXL);
+
+static void cxl_decoder_reset(struct cxl_decoder *cxld)
 {
        struct cxl_port *port = to_cxl_port(cxld->dev.parent);
        struct cxl_hdm *cxlhdm = dev_get_drvdata(&port->dev);
@@ -721,14 +758,14 @@ static int cxl_decoder_reset(struct cxl_decoder *cxld)
        u32 ctrl;
 
        if ((cxld->flags & CXL_DECODER_F_ENABLE) == 0)
-               return 0;
+               return;
 
-       if (port->commit_end != id) {
+       if (port->commit_end == id)
+               cxl_port_commit_reap(cxld);
+       else
                dev_dbg(&port->dev,
                        "%s: out of order reset, expected decoder%d.%d\n",
                        dev_name(&cxld->dev), port->id, port->commit_end);
-               return -EBUSY;
-       }
 
        down_read(&cxl_dpa_rwsem);
        ctrl = readl(hdm + CXL_HDM_DECODER0_CTRL_OFFSET(id));
@@ -741,7 +778,6 @@ static int cxl_decoder_reset(struct cxl_decoder *cxld)
        writel(0, hdm + CXL_HDM_DECODER0_BASE_LOW_OFFSET(id));
        up_read(&cxl_dpa_rwsem);
 
-       port->commit_end--;
        cxld->flags &= ~CXL_DECODER_F_ENABLE;
 
        /* Userspace is now responsible for reconfiguring this decoder */
@@ -751,8 +787,6 @@ static int cxl_decoder_reset(struct cxl_decoder *cxld)
                cxled = to_cxl_endpoint_decoder(&cxld->dev);
                cxled->state = CXL_DECODER_STATE_MANUAL;
        }
-
-       return 0;
 }
 
 static int cxl_setup_hdm_decoder_from_dvsec(
index 946f8e44455f79c6dc945e443d35bb75f9ab7ff8..5175138c4fb7382426145640d7d04967b02b22dc 100644 (file)
@@ -4,7 +4,7 @@
 #include <linux/debugfs.h>
 #include <linux/ktime.h>
 #include <linux/mutex.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include <cxlpci.h>
 #include <cxlmem.h>
 #include <cxl.h>
index e666ec6a9085a577c92f5e73cefff894922fcb38..af92c67bc9542d0cede905d6a1f35c695c7f446b 100644 (file)
@@ -2084,11 +2084,18 @@ static void cxl_bus_remove(struct device *dev)
 
 static struct workqueue_struct *cxl_bus_wq;
 
-static void cxl_bus_rescan_queue(struct work_struct *w)
+static int cxl_rescan_attach(struct device *dev, void *data)
 {
-       int rc = bus_rescan_devices(&cxl_bus_type);
+       int rc = device_attach(dev);
+
+       dev_vdbg(dev, "rescan: %s\n", rc ? "attach" : "detached");
 
-       pr_debug("CXL bus rescan result: %d\n", rc);
+       return 0;
+}
+
+static void cxl_bus_rescan_queue(struct work_struct *w)
+{
+       bus_for_each_dev(&cxl_bus_type, NULL, NULL, cxl_rescan_attach);
 }
 
 void cxl_bus_rescan(void)
index e701e4b0403282a06bccfbca6bf212fd35e3a64c..dff618c708dc68bfdedd90309b1587169975a3fc 100644 (file)
@@ -232,8 +232,8 @@ static int cxl_region_invalidate_memregion(struct cxl_region *cxlr)
                                "Bypassing cpu_cache_invalidate_memregion() for testing!\n");
                        return 0;
                } else {
-                       dev_err(&cxlr->dev,
-                               "Failed to synchronize CPU cache state\n");
+                       dev_WARN(&cxlr->dev,
+                                "Failed to synchronize CPU cache state\n");
                        return -ENXIO;
                }
        }
@@ -242,19 +242,17 @@ static int cxl_region_invalidate_memregion(struct cxl_region *cxlr)
        return 0;
 }
 
-static int cxl_region_decode_reset(struct cxl_region *cxlr, int count)
+static void cxl_region_decode_reset(struct cxl_region *cxlr, int count)
 {
        struct cxl_region_params *p = &cxlr->params;
-       int i, rc = 0;
+       int i;
 
        /*
-        * Before region teardown attempt to flush, and if the flush
-        * fails cancel the region teardown for data consistency
-        * concerns
+        * Before region teardown attempt to flush, evict any data cached for
+        * this region, or scream loudly about missing arch / platform support
+        * for CXL teardown.
         */
-       rc = cxl_region_invalidate_memregion(cxlr);
-       if (rc)
-               return rc;
+       cxl_region_invalidate_memregion(cxlr);
 
        for (i = count - 1; i >= 0; i--) {
                struct cxl_endpoint_decoder *cxled = p->targets[i];
@@ -277,23 +275,17 @@ static int cxl_region_decode_reset(struct cxl_region *cxlr, int count)
                        cxl_rr = cxl_rr_load(iter, cxlr);
                        cxld = cxl_rr->decoder;
                        if (cxld->reset)
-                               rc = cxld->reset(cxld);
-                       if (rc)
-                               return rc;
+                               cxld->reset(cxld);
                        set_bit(CXL_REGION_F_NEEDS_RESET, &cxlr->flags);
                }
 
 endpoint_reset:
-               rc = cxled->cxld.reset(&cxled->cxld);
-               if (rc)
-                       return rc;
+               cxled->cxld.reset(&cxled->cxld);
                set_bit(CXL_REGION_F_NEEDS_RESET, &cxlr->flags);
        }
 
        /* all decoders associated with this region have been torn down */
        clear_bit(CXL_REGION_F_NEEDS_RESET, &cxlr->flags);
-
-       return 0;
 }
 
 static int commit_decoder(struct cxl_decoder *cxld)
@@ -409,16 +401,8 @@ static ssize_t commit_store(struct device *dev, struct device_attribute *attr,
                 * still pending.
                 */
                if (p->state == CXL_CONFIG_RESET_PENDING) {
-                       rc = cxl_region_decode_reset(cxlr, p->interleave_ways);
-                       /*
-                        * Revert to committed since there may still be active
-                        * decoders associated with this region, or move forward
-                        * to active to mark the reset successful
-                        */
-                       if (rc)
-                               p->state = CXL_CONFIG_COMMIT;
-                       else
-                               p->state = CXL_CONFIG_ACTIVE;
+                       cxl_region_decode_reset(cxlr, p->interleave_ways);
+                       p->state = CXL_CONFIG_ACTIVE;
                }
        }
 
@@ -794,26 +778,50 @@ out:
        return rc;
 }
 
+static int check_commit_order(struct device *dev, const void *data)
+{
+       struct cxl_decoder *cxld = to_cxl_decoder(dev);
+
+       /*
+        * if port->commit_end is not the only free decoder, then out of
+        * order shutdown has occurred, block further allocations until
+        * that is resolved
+        */
+       if (((cxld->flags & CXL_DECODER_F_ENABLE) == 0))
+               return -EBUSY;
+       return 0;
+}
+
 static int match_free_decoder(struct device *dev, void *data)
 {
+       struct cxl_port *port = to_cxl_port(dev->parent);
        struct cxl_decoder *cxld;
-       int *id = data;
+       int rc;
 
        if (!is_switch_decoder(dev))
                return 0;
 
        cxld = to_cxl_decoder(dev);
 
-       /* enforce ordered allocation */
-       if (cxld->id != *id)
+       if (cxld->id != port->commit_end + 1)
                return 0;
 
-       if (!cxld->region)
-               return 1;
-
-       (*id)++;
+       if (cxld->region) {
+               dev_dbg(dev->parent,
+                       "next decoder to commit (%s) is already reserved (%s)\n",
+                       dev_name(dev), dev_name(&cxld->region->dev));
+               return 0;
+       }
 
-       return 0;
+       rc = device_for_each_child_reverse_from(dev->parent, dev, NULL,
+                                               check_commit_order);
+       if (rc) {
+               dev_dbg(dev->parent,
+                       "unable to allocate %s due to out of order shutdown\n",
+                       dev_name(dev));
+               return 0;
+       }
+       return 1;
 }
 
 static int match_auto_decoder(struct device *dev, void *data)
@@ -840,7 +848,6 @@ cxl_region_find_decoder(struct cxl_port *port,
                        struct cxl_region *cxlr)
 {
        struct device *dev;
-       int id = 0;
 
        if (port == cxled_to_port(cxled))
                return &cxled->cxld;
@@ -849,7 +856,7 @@ cxl_region_find_decoder(struct cxl_port *port,
                dev = device_find_child(&port->dev, &cxlr->params,
                                        match_auto_decoder);
        else
-               dev = device_find_child(&port->dev, &id, match_free_decoder);
+               dev = device_find_child(&port->dev, NULL, match_free_decoder);
        if (!dev)
                return NULL;
        /*
@@ -2054,13 +2061,7 @@ static int cxl_region_detach(struct cxl_endpoint_decoder *cxled)
        get_device(&cxlr->dev);
 
        if (p->state > CXL_CONFIG_ACTIVE) {
-               /*
-                * TODO: tear down all impacted regions if a device is
-                * removed out of order
-                */
-               rc = cxl_region_decode_reset(cxlr, p->interleave_ways);
-               if (rc)
-                       goto out;
+               cxl_region_decode_reset(cxlr, p->interleave_ways);
                p->state = CXL_CONFIG_ACTIVE;
        }
 
index 9167cfba7f592cfdf2f13b87cbb4ed779eb48266..8389a94adb1a681827209db46360d3d57c6672ce 100644 (file)
@@ -8,7 +8,7 @@
 
 #include <linux/tracepoint.h>
 #include <linux/pci.h>
-#include <asm-generic/unaligned.h>
+#include <linux/unaligned.h>
 
 #include <cxl.h>
 #include <cxlmem.h>
@@ -279,7 +279,7 @@ TRACE_EVENT(cxl_generic_event,
 #define CXL_GMER_MEM_EVT_TYPE_ECC_ERROR                        0x00
 #define CXL_GMER_MEM_EVT_TYPE_INV_ADDR                 0x01
 #define CXL_GMER_MEM_EVT_TYPE_DATA_PATH_ERROR          0x02
-#define show_mem_event_type(type)      __print_symbolic(type,                  \
+#define show_gmer_mem_event_type(type) __print_symbolic(type,                  \
        { CXL_GMER_MEM_EVT_TYPE_ECC_ERROR,              "ECC Error" },          \
        { CXL_GMER_MEM_EVT_TYPE_INV_ADDR,               "Invalid Address" },    \
        { CXL_GMER_MEM_EVT_TYPE_DATA_PATH_ERROR,        "Data Path Error" }     \
@@ -373,7 +373,7 @@ TRACE_EVENT(cxl_general_media,
                "hpa=%llx region=%s region_uuid=%pUb",
                __entry->dpa, show_dpa_flags(__entry->dpa_flags),
                show_event_desc_flags(__entry->descriptor),
-               show_mem_event_type(__entry->type),
+               show_gmer_mem_event_type(__entry->type),
                show_trans_type(__entry->transaction_type),
                __entry->channel, __entry->rank, __entry->device,
                __print_hex(__entry->comp_id, CXL_EVENT_GEN_MED_COMP_ID_SIZE),
@@ -391,6 +391,17 @@ TRACE_EVENT(cxl_general_media,
  * DRAM Event Record defines many fields the same as the General Media Event
  * Record.  Reuse those definitions as appropriate.
  */
+#define CXL_DER_MEM_EVT_TYPE_ECC_ERROR                 0x00
+#define CXL_DER_MEM_EVT_TYPE_SCRUB_MEDIA_ECC_ERROR     0x01
+#define CXL_DER_MEM_EVT_TYPE_INV_ADDR                  0x02
+#define CXL_DER_MEM_EVT_TYPE_DATA_PATH_ERROR           0x03
+#define show_dram_mem_event_type(type)  __print_symbolic(type,                         \
+       { CXL_DER_MEM_EVT_TYPE_ECC_ERROR,               "ECC Error" },                  \
+       { CXL_DER_MEM_EVT_TYPE_SCRUB_MEDIA_ECC_ERROR,   "Scrub Media ECC Error" },      \
+       { CXL_DER_MEM_EVT_TYPE_INV_ADDR,                "Invalid Address" },            \
+       { CXL_DER_MEM_EVT_TYPE_DATA_PATH_ERROR,         "Data Path Error" }             \
+)
+
 #define CXL_DER_VALID_CHANNEL                          BIT(0)
 #define CXL_DER_VALID_RANK                             BIT(1)
 #define CXL_DER_VALID_NIBBLE                           BIT(2)
@@ -477,7 +488,7 @@ TRACE_EVENT(cxl_dram,
                "hpa=%llx region=%s region_uuid=%pUb",
                __entry->dpa, show_dpa_flags(__entry->dpa_flags),
                show_event_desc_flags(__entry->descriptor),
-               show_mem_event_type(__entry->type),
+               show_dram_mem_event_type(__entry->type),
                show_trans_type(__entry->transaction_type),
                __entry->channel, __entry->rank, __entry->nibble_mask,
                __entry->bank_group, __entry->bank,
index 0d8b810a51f04de299e88ee8b29136bff11ed93e..5406e3ab3d4a4550ab4eda9e28b6554f881645c9 100644 (file)
@@ -359,7 +359,7 @@ struct cxl_decoder {
        struct cxl_region *region;
        unsigned long flags;
        int (*commit)(struct cxl_decoder *cxld);
-       int (*reset)(struct cxl_decoder *cxld);
+       void (*reset)(struct cxl_decoder *cxld);
 };
 
 /*
@@ -730,6 +730,7 @@ static inline bool is_cxl_root(struct cxl_port *port)
 int cxl_num_decoders_committed(struct cxl_port *port);
 bool is_cxl_port(const struct device *dev);
 struct cxl_port *to_cxl_port(const struct device *dev);
+void cxl_port_commit_reap(struct cxl_decoder *cxld);
 struct pci_bus;
 int devm_cxl_register_pci_bus(struct device *host, struct device *uport_dev,
                              struct pci_bus *bus);
index 37164174b5fb0e50b14918331a822b3b204ce0b8..188412d45e0d266b19f7401a1cdc51ed6fb0ea0a 100644 (file)
@@ -1,6 +1,6 @@
 // SPDX-License-Identifier: GPL-2.0-only
 /* Copyright(c) 2020 Intel Corporation. All rights reserved. */
-#include <asm-generic/unaligned.h>
+#include <linux/unaligned.h>
 #include <linux/io-64-nonatomic-lo-hi.h>
 #include <linux/moduleparam.h>
 #include <linux/module.h>
index a6538a5f5c9fb10d512375d83a65a92f116ea70b..d2d43a4fc05387fdd643d5f7d73612e49b5762bc 100644 (file)
@@ -1,7 +1,7 @@
 // SPDX-License-Identifier: GPL-2.0-only
 /* Copyright(c) 2021 Intel Corporation. All rights reserved. */
 #include <linux/libnvdimm.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include <linux/device.h>
 #include <linux/module.h>
 #include <linux/ndctl.h>
index 861dde65768fe383d3ccbb49ffd31fb29aeb42e9..9dc394295e1fcd1610813837b2f515b66995eb25 100644 (file)
@@ -208,7 +208,22 @@ static struct cxl_driver cxl_port_driver = {
        },
 };
 
-module_cxl_driver(cxl_port_driver);
+static int __init cxl_port_init(void)
+{
+       return cxl_driver_register(&cxl_port_driver);
+}
+/*
+ * Be ready to immediately enable ports emitted by the platform CXL root
+ * (e.g. cxl_acpi) when CONFIG_CXL_PORT=y.
+ */
+subsys_initcall(cxl_port_init);
+
+static void __exit cxl_port_exit(void)
+{
+       cxl_driver_unregister(&cxl_port_driver);
+}
+module_exit(cxl_port_exit);
+
 MODULE_DESCRIPTION("CXL: Port enumeration and services");
 MODULE_LICENSE("GPL v2");
 MODULE_IMPORT_NS(CXL);
index 452d1a9b9148a871975025c3a43e8eb6c8a7f49a..ab793e8577c782180f673f220188394b9db16789 100644 (file)
@@ -1,7 +1,7 @@
 // SPDX-License-Identifier: GPL-2.0-only
 /* Copyright(c) 2022 Intel Corporation. All rights reserved. */
 #include <linux/libnvdimm.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include <linux/module.h>
 #include <linux/async.h>
 #include <linux/slab.h>
index 9c1a729cd77e9417995bd8396aaf174bbff280cf..6d74e62bbee0d37125ebc9decc1d342449bbb150 100644 (file)
@@ -86,7 +86,7 @@ static void dax_set_mapping(struct vm_fault *vmf, pfn_t pfn,
                nr_pages = 1;
 
        pgoff = linear_page_index(vmf->vma,
-                       ALIGN(vmf->address, fault_size));
+                       ALIGN_DOWN(vmf->address, fault_size));
 
        for (i = 0; i < nr_pages; i++) {
                struct page *page = pfn_to_page(pfn_t_to_pfn(pfn) + i);
index 995427afe0773df1bb45154148fa45d62e53a19d..6b98a23e333248861725a4d897ed083536cd0011 100644 (file)
@@ -1391,11 +1391,12 @@ static struct ep93xx_dma_engine *ep93xx_dma_of_probe(struct platform_device *pde
        INIT_LIST_HEAD(&dma_dev->channels);
        for (i = 0; i < edma->num_channels; i++) {
                struct ep93xx_dma_chan *edmac = &edma->channels[i];
+               int len;
 
                edmac->chan.device = dma_dev;
                edmac->regs = devm_platform_ioremap_resource(pdev, i);
                if (IS_ERR(edmac->regs))
-                       return edmac->regs;
+                       return ERR_CAST(edmac->regs);
 
                edmac->irq = fwnode_irq_get(dev_fwnode(dev), i);
                if (edmac->irq < 0)
@@ -1404,9 +1405,11 @@ static struct ep93xx_dma_engine *ep93xx_dma_of_probe(struct platform_device *pde
                edmac->edma = edma;
 
                if (edma->m2m)
-                       snprintf(dma_clk_name, sizeof(dma_clk_name), "m2m%u", i);
+                       len = snprintf(dma_clk_name, sizeof(dma_clk_name), "m2m%u", i);
                else
-                       snprintf(dma_clk_name, sizeof(dma_clk_name), "m2p%u", i);
+                       len = snprintf(dma_clk_name, sizeof(dma_clk_name), "m2p%u", i);
+               if (len >= sizeof(dma_clk_name))
+                       return ERR_PTR(-ENOBUFS);
 
                edmac->clk = devm_clk_get(dev, dma_clk_name);
                if (IS_ERR(edmac->clk)) {
index 65a27c5a7bce3f12806e971defb4070294279e41..811389fc9cb82358463309c7e8bc21bba2b58815 100644 (file)
@@ -601,22 +601,25 @@ static int rz_dmac_config(struct dma_chan *chan,
        struct rz_dmac_chan *channel = to_rz_dmac_chan(chan);
        u32 val;
 
-       channel->src_per_address = config->src_addr;
        channel->dst_per_address = config->dst_addr;
-
-       val = rz_dmac_ds_to_val_mapping(config->dst_addr_width);
-       if (val == CHCFG_DS_INVALID)
-               return -EINVAL;
-
        channel->chcfg &= ~CHCFG_FILL_DDS_MASK;
-       channel->chcfg |= FIELD_PREP(CHCFG_FILL_DDS_MASK, val);
+       if (channel->dst_per_address) {
+               val = rz_dmac_ds_to_val_mapping(config->dst_addr_width);
+               if (val == CHCFG_DS_INVALID)
+                       return -EINVAL;
 
-       val = rz_dmac_ds_to_val_mapping(config->src_addr_width);
-       if (val == CHCFG_DS_INVALID)
-               return -EINVAL;
+               channel->chcfg |= FIELD_PREP(CHCFG_FILL_DDS_MASK, val);
+       }
 
+       channel->src_per_address = config->src_addr;
        channel->chcfg &= ~CHCFG_FILL_SDS_MASK;
-       channel->chcfg |= FIELD_PREP(CHCFG_FILL_SDS_MASK, val);
+       if (channel->src_per_address) {
+               val = rz_dmac_ds_to_val_mapping(config->src_addr_width);
+               if (val == CHCFG_DS_INVALID)
+                       return -EINVAL;
+
+               channel->chcfg |= FIELD_PREP(CHCFG_FILL_SDS_MASK, val);
+       }
 
        return 0;
 }
index 406ee199c2ac1cffc29edb475df574cf9f0cf222..b3f27b3f92098a65afe9656ca31f9b8027294c16 100644 (file)
@@ -3185,27 +3185,40 @@ static int udma_configure_statictr(struct udma_chan *uc, struct udma_desc *d,
 
        d->static_tr.elcnt = elcnt;
 
-       /*
-        * PDMA must to close the packet when the channel is in packet mode.
-        * For TR mode when the channel is not cyclic we also need PDMA to close
-        * the packet otherwise the transfer will stall because PDMA holds on
-        * the data it has received from the peripheral.
-        */
        if (uc->config.pkt_mode || !uc->cyclic) {
+               /*
+                * PDMA must close the packet when the channel is in packet mode.
+                * For TR mode when the channel is not cyclic we also need PDMA
+                * to close the packet otherwise the transfer will stall because
+                * PDMA holds on the data it has received from the peripheral.
+                */
                unsigned int div = dev_width * elcnt;
 
                if (uc->cyclic)
                        d->static_tr.bstcnt = d->residue / d->sglen / div;
                else
                        d->static_tr.bstcnt = d->residue / div;
+       } else if (uc->ud->match_data->type == DMA_TYPE_BCDMA &&
+                  uc->config.dir == DMA_DEV_TO_MEM &&
+                  uc->cyclic) {
+               /*
+                * For cyclic mode with BCDMA we have to set EOP in each TR to
+                * prevent short packet errors seen on channel teardown. So the
+                * PDMA must close the packet after every TR transfer by setting
+                * burst count equal to the number of bytes transferred.
+                */
+               struct cppi5_tr_type1_t *tr_req = d->hwdesc[0].tr_req_base;
 
-               if (uc->config.dir == DMA_DEV_TO_MEM &&
-                   d->static_tr.bstcnt > uc->ud->match_data->statictr_z_mask)
-                       return -EINVAL;
+               d->static_tr.bstcnt =
+                       (tr_req->icnt0 * tr_req->icnt1) / dev_width;
        } else {
                d->static_tr.bstcnt = 0;
        }
 
+       if (uc->config.dir == DMA_DEV_TO_MEM &&
+           d->static_tr.bstcnt > uc->ud->match_data->statictr_z_mask)
+               return -EINVAL;
+
        return 0;
 }
 
@@ -3450,8 +3463,9 @@ udma_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl,
        /* static TR for remote PDMA */
        if (udma_configure_statictr(uc, d, dev_width, burst)) {
                dev_err(uc->ud->dev,
-                       "%s: StaticTR Z is limited to maximum 4095 (%u)\n",
-                       __func__, d->static_tr.bstcnt);
+                       "%s: StaticTR Z is limited to maximum %u (%u)\n",
+                       __func__, uc->ud->match_data->statictr_z_mask,
+                       d->static_tr.bstcnt);
 
                udma_free_hwdesc(uc, d);
                kfree(d);
@@ -3476,6 +3490,7 @@ udma_prep_dma_cyclic_tr(struct udma_chan *uc, dma_addr_t buf_addr,
        u16 tr0_cnt0, tr0_cnt1, tr1_cnt0;
        unsigned int i;
        int num_tr;
+       u32 period_csf = 0;
 
        num_tr = udma_get_tr_counters(period_len, __ffs(buf_addr), &tr0_cnt0,
                                      &tr0_cnt1, &tr1_cnt0);
@@ -3498,6 +3513,20 @@ udma_prep_dma_cyclic_tr(struct udma_chan *uc, dma_addr_t buf_addr,
                period_addr = buf_addr |
                        ((u64)uc->config.asel << K3_ADDRESS_ASEL_SHIFT);
 
+       /*
+        * For BCDMA <-> PDMA transfers, the EOP flag needs to be set on the
+        * last TR of a descriptor, to mark the packet as complete.
+        * This is required for getting the teardown completion message in case
+        * of TX, and to avoid short-packet error in case of RX.
+        *
+        * As we are in cyclic mode, we do not know which period might be the
+        * last one, so set the flag for each period.
+        */
+       if (uc->config.ep_type == PSIL_EP_PDMA_XY &&
+           uc->ud->match_data->type == DMA_TYPE_BCDMA) {
+               period_csf = CPPI5_TR_CSF_EOP;
+       }
+
        for (i = 0; i < periods; i++) {
                int tr_idx = i * num_tr;
 
@@ -3525,8 +3554,10 @@ udma_prep_dma_cyclic_tr(struct udma_chan *uc, dma_addr_t buf_addr,
                }
 
                if (!(flags & DMA_PREP_INTERRUPT))
-                       cppi5_tr_csf_set(&tr_req[tr_idx].flags,
-                                        CPPI5_TR_CSF_SUPR_EVT);
+                       period_csf |= CPPI5_TR_CSF_SUPR_EVT;
+
+               if (period_csf)
+                       cppi5_tr_csf_set(&tr_req[tr_idx].flags, period_csf);
 
                period_addr += period_len;
        }
@@ -3655,8 +3686,9 @@ udma_prep_dma_cyclic(struct dma_chan *chan, dma_addr_t buf_addr, size_t buf_len,
        /* static TR for remote PDMA */
        if (udma_configure_statictr(uc, d, dev_width, burst)) {
                dev_err(uc->ud->dev,
-                       "%s: StaticTR Z is limited to maximum 4095 (%u)\n",
-                       __func__, d->static_tr.bstcnt);
+                       "%s: StaticTR Z is limited to maximum %u (%u)\n",
+                       __func__, uc->ud->match_data->statictr_z_mask,
+                       d->static_tr.bstcnt);
 
                udma_free_hwdesc(uc, d);
                kfree(d);
index 6adadb11962e3d1935695905ebbbb93f422dd175..892b94cfd62603fdf936fbfb853ef34f30fb9b3d 100644 (file)
@@ -204,7 +204,7 @@ static struct fw_node *build_tree(struct fw_card *card, const u32 *sid, int self
                                // the node->ports array where the parent node should be.  Later,
                                // when we handle the parent node, we fix up the reference.
                                ++parent_count;
-                               node->color = i;
+                               node->color = port_index;
                                break;
 
                        case PHY_PACKET_SELF_ID_PORT_STATUS_CHILD:
index 7a4d1a478e33e2ccace6bc5b2ef184113f335ca3..1bf0e15c15408e68305306b231e6af54e591be40 100644 (file)
@@ -28,7 +28,7 @@
 #include <linux/slab.h>
 #include <linux/spinlock.h>
 
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include <net/arp.h>
 #include <net/firewire.h>
 
index 4d231bc375e03b009c0d9252478edaa8cbc0f13f..b14cbdae94e82bd2eb83b77cc347529a12cc966d 100644 (file)
@@ -481,11 +481,16 @@ static int ffa_msg_send_direct_req2(u16 src_id, u16 dst_id, const uuid_t *uuid,
                                    struct ffa_send_direct_data2 *data)
 {
        u32 src_dst_ids = PACK_TARGET_INFO(src_id, dst_id);
+       union {
+               uuid_t uuid;
+               __le64 regs[2];
+       } uuid_regs = { .uuid = *uuid };
        ffa_value_t ret, args = {
-               .a0 = FFA_MSG_SEND_DIRECT_REQ2, .a1 = src_dst_ids,
+               .a0 = FFA_MSG_SEND_DIRECT_REQ2,
+               .a1 = src_dst_ids,
+               .a2 = le64_to_cpu(uuid_regs.regs[0]),
+               .a3 = le64_to_cpu(uuid_regs.regs[1]),
        };
-
-       export_uuid((u8 *)&args.a2, uuid);
        memcpy((void *)&args + offsetof(ffa_value_t, a4), data, sizeof(*data));
 
        invoke_ffa_fn(args, &ret);
@@ -496,7 +501,7 @@ static int ffa_msg_send_direct_req2(u16 src_id, u16 dst_id, const uuid_t *uuid,
                return ffa_to_linux_errno((int)ret.a2);
 
        if (ret.a0 == FFA_MSG_SEND_DIRECT_RESP2) {
-               memcpy(data, &ret.a4, sizeof(*data));
+               memcpy(data, (void *)&ret + offsetof(ffa_value_t, a4), sizeof(*data));
                return 0;
        }
 
index 6d9227db473ff67d3ab63301eefdbdeb063a8546..c4b8e7ff88aa2357fdf5739b96185f234d475b97 100644 (file)
@@ -22,7 +22,7 @@
 #include <linux/spinlock.h>
 #include <linux/types.h>
 
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #include "protocols.h"
 #include "notify.h"
index 88c5c4ff4bb62ee313da275880a9c85bc67fb38a..a477b5ade38dcac8517beeee7ff2908da9ea1d8f 100644 (file)
@@ -2976,10 +2976,8 @@ static struct scmi_debug_info *scmi_debugfs_common_setup(struct scmi_info *info)
        dbg->top_dentry = top_dentry;
 
        if (devm_add_action_or_reset(info->dev,
-                                    scmi_debugfs_common_cleanup, dbg)) {
-               scmi_debugfs_common_cleanup(dbg);
+                                    scmi_debugfs_common_cleanup, dbg))
                return NULL;
-       }
 
        return dbg;
 }
index 8e95f53bd7b76aec08d78721e3a3b523e82cf68a..aaee57cdcd5589ee8c3f28f782ba5f84fd83d792 100644 (file)
@@ -22,7 +22,7 @@
 #include <linux/spinlock.h>
 #include <linux/types.h>
 
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #define PROTOCOL_REV_MINOR_MASK        GENMASK(15, 0)
 #define PROTOCOL_REV_MAJOR_MASK        GENMASK(31, 16)
index 362a406f08e67429312bd109cb08c07b2d2f9c2a..3ba3d3bee1513b3614ced58ba121791603f4698a 100644 (file)
@@ -1,8 +1,10 @@
 # SPDX-License-Identifier: GPL-2.0-only
-scmi_transport_mailbox-objs := mailbox.o
-obj-$(CONFIG_ARM_SCMI_TRANSPORT_MAILBOX) += scmi_transport_mailbox.o
+# Keep before scmi_transport_mailbox.o to allow precedence
+# while matching the compatible.
 scmi_transport_smc-objs := smc.o
 obj-$(CONFIG_ARM_SCMI_TRANSPORT_SMC) += scmi_transport_smc.o
+scmi_transport_mailbox-objs := mailbox.o
+obj-$(CONFIG_ARM_SCMI_TRANSPORT_MAILBOX) += scmi_transport_mailbox.o
 scmi_transport_optee-objs := optee.o
 obj-$(CONFIG_ARM_SCMI_TRANSPORT_OPTEE) += scmi_transport_optee.o
 scmi_transport_virtio-objs := virtio.o
index 1a754dee24f73026c289e446407cb9da187e55de..e3d5f75609905f74888396bb19c2088fb21d2a4c 100644 (file)
@@ -25,6 +25,7 @@
  * @chan_platform_receiver: Optional Platform Receiver mailbox unidirectional channel
  * @cinfo: SCMI channel info
  * @shmem: Transmit/Receive shared memory area
+ * @chan_lock: Lock that prevents multiple xfers from being queued
  */
 struct scmi_mailbox {
        struct mbox_client cl;
@@ -33,6 +34,7 @@ struct scmi_mailbox {
        struct mbox_chan *chan_platform_receiver;
        struct scmi_chan_info *cinfo;
        struct scmi_shared_mem __iomem *shmem;
+       struct mutex chan_lock;
 };
 
 #define client_to_scmi_mailbox(c) container_of(c, struct scmi_mailbox, cl)
@@ -238,6 +240,7 @@ static int mailbox_chan_setup(struct scmi_chan_info *cinfo, struct device *dev,
 
        cinfo->transport_info = smbox;
        smbox->cinfo = cinfo;
+       mutex_init(&smbox->chan_lock);
 
        return 0;
 }
@@ -267,13 +270,23 @@ static int mailbox_send_message(struct scmi_chan_info *cinfo,
        struct scmi_mailbox *smbox = cinfo->transport_info;
        int ret;
 
-       ret = mbox_send_message(smbox->chan, xfer);
+       /*
+        * The mailbox layer has its own queue. However the mailbox queue
+        * confuses the per message SCMI timeouts since the clock starts when
+        * the message is submitted into the mailbox queue. So when multiple
+        * messages are queued up the clock starts on all messages instead of
+        * only the one inflight.
+        */
+       mutex_lock(&smbox->chan_lock);
 
-       /* mbox_send_message returns non-negative value on success, so reset */
-       if (ret > 0)
-               ret = 0;
+       ret = mbox_send_message(smbox->chan, xfer);
+       /* mbox_send_message returns non-negative value on success */
+       if (ret < 0) {
+               mutex_unlock(&smbox->chan_lock);
+               return ret;
+       }
 
-       return ret;
+       return 0;
 }
 
 static void mailbox_mark_txdone(struct scmi_chan_info *cinfo, int ret,
@@ -281,13 +294,10 @@ static void mailbox_mark_txdone(struct scmi_chan_info *cinfo, int ret,
 {
        struct scmi_mailbox *smbox = cinfo->transport_info;
 
-       /*
-        * NOTE: we might prefer not to need the mailbox ticker to manage the
-        * transfer queueing since the protocol layer queues things by itself.
-        * Unfortunately, we have to kick the mailbox framework after we have
-        * received our message.
-        */
        mbox_client_txdone(smbox->chan, ret);
+
+       /* Release channel */
+       mutex_unlock(&smbox->chan_lock);
 }
 
 static void mailbox_fetch_response(struct scmi_chan_info *cinfo,
index 285fe7ad490d1ddd904e0dd73518350bc135ef8c..3e8051fe829657294cbb29c49c2b3848f98a990f 100644 (file)
@@ -763,7 +763,7 @@ static int sdei_device_freeze(struct device *dev)
        int err;
 
        /* unregister private events */
-       cpuhp_remove_state(sdei_entry_point);
+       cpuhp_remove_state(sdei_hp_state);
 
        err = sdei_unregister_shared();
        if (err)
index 23b002e4d4a0be5f72408ea485da93c0f6a46840..fde0656481cc9577b05b781b703a8071e8d3fc4e 100644 (file)
@@ -9,7 +9,7 @@
 #include <linux/memblock.h>
 #include <linux/random.h>
 #include <asm/dmi.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #ifndef SMBIOS_ENTRY_POINT_SCAN_START
 #define SMBIOS_ENTRY_POINT_SCAN_START 0xF0000
index 0ec83ba580972f24a19f4f4d10f609119197cfc2..b815d2a754eef33b5157830fc739ca47dd666d3f 100644 (file)
@@ -8,7 +8,7 @@
 #include <linux/libfdt.h>
 #include <linux/of_fdt.h>
 
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 enum {
        SYSTAB,
index c96d6dcee86c20656e8b6c9504734c66b26854c1..e7d9204baee3126acf0c7cbd3df3d0c257a5a30a 100644 (file)
@@ -7,7 +7,7 @@
 
 #include <asm/efi.h>
 #include <asm/sections.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #include "efistub.h"
 
index 8022b104c3e6ec22af349a10ca2c6e9b155a411c..f66f33ceb99e3028cbb3dd38598a8909c8d48c54 100644 (file)
@@ -7,7 +7,7 @@
 #include <linux/libfdt.h>
 
 #include <asm/efi.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #include "efistub.h"
 
index 1ceace956758682f592f6fe3f280b7260f7ca562..af23b3c502282f9bd644c38af445875c225cdf42 100644 (file)
@@ -3,7 +3,7 @@
 #include <linux/efi.h>
 #include <linux/pe.h>
 #include <asm/efi.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #include "efistub.h"
 
index 02a07d3d0d40a91770b5039d818bf944813800f5..a3df782fa687b0f14a2646eccaf635c3bb247b2b 100644 (file)
@@ -67,9 +67,11 @@ static bool sysfb_unregister(void)
 void sysfb_disable(struct device *dev)
 {
        struct screen_info *si = &screen_info;
+       struct device *parent;
 
        mutex_lock(&disable_lock);
-       if (!dev || dev == sysfb_parent_dev(si)) {
+       parent = sysfb_parent_dev(si);
+       if (!dev || !parent || dev == parent) {
                sysfb_unregister();
                disabled = true;
        }
index 2a82c726d6e59c9a29feb3d4271eae4b19d0b88f..6134cea86ac8560c76a53d029d143a8235d2675c 100644 (file)
@@ -3,7 +3,7 @@
  * Microchip Polarfire FPGA programming over slave SPI interface.
  */
 
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include <linux/delay.h>
 #include <linux/fpga/fpga-mgr.h>
 #include <linux/iopoll.h>
index f58b158d097ce524bb5fa2a5fa0eb2966e407b01..a6d4c8f123a5a93552eed42c35b3924828f4f213 100644 (file)
@@ -20,7 +20,7 @@
 #include <linux/sched.h>
 #include <linux/slab.h>
 #include <linux/uaccess.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #define OCC_SRAM_BYTES         4096
 #define OCC_CMD_DATA_BYTES     4090
index 04c03402db6ddf3c3971c309a2bcb68b31ed7824..ea40ad43a79baacd0fd971cebbd4a627d4e9f0a3 100644 (file)
@@ -406,6 +406,8 @@ static void __aspeed_gpio_set(struct gpio_chip *gc, unsigned int offset,
        gpio->dcache[GPIO_BANK(offset)] = reg;
 
        iowrite32(reg, addr);
+       /* Flush write */
+       ioread32(addr);
 }
 
 static void aspeed_gpio_set(struct gpio_chip *gc, unsigned int offset,
@@ -1191,7 +1193,7 @@ static int __init aspeed_gpio_probe(struct platform_device *pdev)
        if (!gpio_id)
                return -EINVAL;
 
-       gpio->clk = of_clk_get(pdev->dev.of_node, 0);
+       gpio->clk = devm_clk_get_enabled(&pdev->dev, NULL);
        if (IS_ERR(gpio->clk)) {
                dev_warn(&pdev->dev,
                                "Failed to get clock from devicetree, debouncing disabled\n");
index b54fef6b1e121f5e1a6a8bb417a02d334da3379a..76b58c70b2577f80ce7127892010d6a366f3122e 100644 (file)
@@ -253,7 +253,7 @@ static int davinci_gpio_probe(struct platform_device *pdev)
  * serve as EDMA event triggers.
  */
 
-static void gpio_irq_disable(struct irq_data *d)
+static void gpio_irq_mask(struct irq_data *d)
 {
        struct davinci_gpio_regs __iomem *g = irq2regs(d);
        uintptr_t mask = (uintptr_t)irq_data_get_irq_handler_data(d);
@@ -262,7 +262,7 @@ static void gpio_irq_disable(struct irq_data *d)
        writel_relaxed(mask, &g->clr_rising);
 }
 
-static void gpio_irq_enable(struct irq_data *d)
+static void gpio_irq_unmask(struct irq_data *d)
 {
        struct davinci_gpio_regs __iomem *g = irq2regs(d);
        uintptr_t mask = (uintptr_t)irq_data_get_irq_handler_data(d);
@@ -288,8 +288,8 @@ static int gpio_irq_type(struct irq_data *d, unsigned trigger)
 
 static struct irq_chip gpio_irqchip = {
        .name           = "GPIO",
-       .irq_enable     = gpio_irq_enable,
-       .irq_disable    = gpio_irq_disable,
+       .irq_unmask     = gpio_irq_unmask,
+       .irq_mask       = gpio_irq_mask,
        .irq_set_type   = gpio_irq_type,
        .flags          = IRQCHIP_SET_TYPE_MASKED | IRQCHIP_SKIP_SET_WAKE,
 };
@@ -472,7 +472,7 @@ static int davinci_gpio_irq_setup(struct platform_device *pdev)
                return PTR_ERR(clk);
        }
 
-       if (chips->gpio_unbanked) {
+       if (!chips->gpio_unbanked) {
                irq = devm_irq_alloc_descs(dev, -1, 0, ngpio, 0);
                if (irq < 0) {
                        dev_err(dev, "Couldn't allocate IRQ numbers\n");
index 07e0d7180579ccaec1adbd4c62139881c6438f9c..59a8f3a5c4e4849769891b8a78f2348dfdc89f5d 100644 (file)
@@ -234,7 +234,9 @@ static int gpio_la_poll_probe(struct platform_device *pdev)
        if (!priv)
                return -ENOMEM;
 
-       devm_mutex_init(dev, &priv->blob_lock);
+       ret = devm_mutex_init(dev, &priv->blob_lock);
+       if (ret)
+               return ret;
 
        fops_buf_size_set(priv, GPIO_LA_DEFAULT_BUF_SIZE);
 
index 2b2dd7e92211dcd82c168c77d832b0cb2dae5091..51d2475c05c57c7e9922dd534adf15c4bb3d2b1b 100644 (file)
@@ -64,7 +64,7 @@ struct gpio_desc *swnode_find_gpio(struct fwnode_handle *fwnode,
        struct fwnode_reference_args args;
        struct gpio_desc *desc;
        char propname[32]; /* 32 is max size of property name */
-       int ret;
+       int ret = 0;
 
        swnode = to_software_node(fwnode);
        if (!swnode)
index c6afbf434366bc5f7a5a09aedeb2ccf201c1ce58..2b02655abb56eafddfd58bfd2ccddd453307f72f 100644 (file)
@@ -114,12 +114,12 @@ const char *gpiod_get_label(struct gpio_desc *desc)
                                srcu_read_lock_held(&desc->gdev->desc_srcu));
 
        if (test_bit(FLAG_USED_AS_IRQ, &flags))
-               return label->str ?: "interrupt";
+               return label ? label->str : "interrupt";
 
        if (!test_bit(FLAG_REQUESTED, &flags))
                return NULL;
 
-       return label->str;
+       return label ? label->str : NULL;
 }
 
 static void desc_free_label(struct rcu_head *rh)
@@ -4926,6 +4926,8 @@ static void *gpiolib_seq_start(struct seq_file *s, loff_t *pos)
                return NULL;
 
        s->private = priv;
+       if (*pos > 0)
+               priv->newline = true;
        priv->idx = srcu_read_lock(&gpio_devices_srcu);
 
        list_for_each_entry_srcu(gdev, &gpio_devices, list,
@@ -4969,7 +4971,7 @@ static int gpiolib_seq_show(struct seq_file *s, void *v)
 
        gc = srcu_dereference(gdev->chip, &gdev->srcu);
        if (!gc) {
-               seq_printf(s, "%s%s: (dangling chip)",
+               seq_printf(s, "%s%s: (dangling chip)\n",
                           priv->newline ? "\n" : "",
                           dev_name(&gdev->dev));
                return 0;
index f85ace0384d21893c94171d541f382a2ae3932a7..1f5a296f5ed2f4773fe35293049a7262a0c46ecc 100644 (file)
@@ -147,6 +147,7 @@ static union acpi_object *amdgpu_atif_call(struct amdgpu_atif *atif,
                                           struct acpi_buffer *params)
 {
        acpi_status status;
+       union acpi_object *obj;
        union acpi_object atif_arg_elements[2];
        struct acpi_object_list atif_arg;
        struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
@@ -169,16 +170,24 @@ static union acpi_object *amdgpu_atif_call(struct amdgpu_atif *atif,
 
        status = acpi_evaluate_object(atif->handle, NULL, &atif_arg,
                                      &buffer);
+       obj = (union acpi_object *)buffer.pointer;
 
-       /* Fail only if calling the method fails and ATIF is supported */
+       /* Fail if calling the method fails and ATIF is supported */
        if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) {
                DRM_DEBUG_DRIVER("failed to evaluate ATIF got %s\n",
                                 acpi_format_exception(status));
-               kfree(buffer.pointer);
+               kfree(obj);
                return NULL;
        }
 
-       return buffer.pointer;
+       if (obj->type != ACPI_TYPE_BUFFER) {
+               DRM_DEBUG_DRIVER("bad object returned from ATIF: %d\n",
+                                obj->type);
+               kfree(obj);
+               return NULL;
+       }
+
+       return obj;
 }
 
 /**
index ce5ca304dba93bb417ada7965397bb71173b7ba3..fa572ba7f9fc1cc1f29f8f2371a2b707105da949 100644 (file)
@@ -1439,8 +1439,8 @@ static int init_kfd_vm(struct amdgpu_vm *vm, void **process_info,
        list_add_tail(&vm->vm_list_node,
                        &(vm->process_info->vm_list_head));
        vm->process_info->n_vms++;
-
-       *ef = dma_fence_get(&vm->process_info->eviction_fence->base);
+       if (ef)
+               *ef = dma_fence_get(&vm->process_info->eviction_fence->base);
        mutex_unlock(&vm->process_info->lock);
 
        return 0;
index 1e475eb01417ef865ba8e48a258253aa9a88644b..d891ab779ca7f5168f8fd4e80c4f100c9b643186 100644 (file)
@@ -265,7 +265,7 @@ static int amdgpu_cs_pass1(struct amdgpu_cs_parser *p,
 
                        /* Only a single BO list is allowed to simplify handling. */
                        if (p->bo_list)
-                               ret = -EINVAL;
+                               goto free_partial_kdata;
 
                        ret = amdgpu_cs_p1_bo_handles(p, p->chunks[i].kdata);
                        if (ret)
index 83e54697f0ee83faf89395600978cdd28af4e1be..f1ffab5a1eaed9d4e56845025775b13ce751e7ea 100644 (file)
@@ -1635,11 +1635,9 @@ int amdgpu_gfx_sysfs_isolation_shader_init(struct amdgpu_device *adev)
 {
        int r;
 
-       if (!amdgpu_sriov_vf(adev)) {
-               r = device_create_file(adev->dev, &dev_attr_enforce_isolation);
-               if (r)
-                       return r;
-       }
+       r = device_create_file(adev->dev, &dev_attr_enforce_isolation);
+       if (r)
+               return r;
 
        r = device_create_file(adev->dev, &dev_attr_run_cleaner_shader);
        if (r)
@@ -1650,8 +1648,7 @@ int amdgpu_gfx_sysfs_isolation_shader_init(struct amdgpu_device *adev)
 
 void amdgpu_gfx_sysfs_isolation_shader_fini(struct amdgpu_device *adev)
 {
-       if (!amdgpu_sriov_vf(adev))
-               device_remove_file(adev->dev, &dev_attr_enforce_isolation);
+       device_remove_file(adev->dev, &dev_attr_enforce_isolation);
        device_remove_file(adev->dev, &dev_attr_run_cleaner_shader);
 }
 
index 10b61ff63802cad56b7fca1b3e4c9d56183dcbee..7d4b540340e021cd9cb467ef85a51475d2d9e51e 100644 (file)
@@ -1203,8 +1203,10 @@ int amdgpu_mes_add_ring(struct amdgpu_device *adev, int gang_id,
 
        r = amdgpu_ring_init(adev, ring, 1024, NULL, 0,
                             AMDGPU_RING_PRIO_DEFAULT, NULL);
-       if (r)
+       if (r) {
+               amdgpu_mes_unlock(&adev->mes);
                goto clean_up_memory;
+       }
 
        amdgpu_mes_ring_to_queue_props(adev, ring, &qprops);
 
@@ -1237,7 +1239,6 @@ clean_up_ring:
        amdgpu_ring_fini(ring);
 clean_up_memory:
        kfree(ring);
-       amdgpu_mes_unlock(&adev->mes);
        return r;
 }
 
index 09715b506468df3779423e5bcadd25fbac35b5fa..81d195d366ceba5bcf9a89be4614de3ace65033f 100644 (file)
@@ -27,7 +27,7 @@
 #include <linux/slab.h>
 #include <linux/string_helpers.h>
 
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #include <drm/drm_util.h>
 
index 8d27421689c9d52fc3d7b7ed233d774199fbfa80..a37a6801c9ea09c4936be990c8a3a8381f090eea 100644 (file)
@@ -621,7 +621,7 @@ static int mes_v12_0_set_hw_resources(struct amdgpu_mes *mes, int pipe)
 
        if (amdgpu_mes_log_enable) {
                mes_set_hw_res_pkt.enable_mes_event_int_logging = 1;
-               mes_set_hw_res_pkt.event_intr_history_gpu_mc_ptr = mes->event_log_gpu_addr;
+               mes_set_hw_res_pkt.event_intr_history_gpu_mc_ptr = mes->event_log_gpu_addr + pipe * AMDGPU_MES_LOG_BUFFER_SIZE;
        }
 
        return mes_v12_0_submit_pkt_and_poll_completion(mes, pipe,
@@ -1336,7 +1336,7 @@ static int mes_v12_0_sw_init(void *handle)
        adev->mes.kiq_hw_fini = &mes_v12_0_kiq_hw_fini;
        adev->mes.enable_legacy_queue_map = true;
 
-       adev->mes.event_log_size = AMDGPU_MES_LOG_BUFFER_SIZE;
+       adev->mes.event_log_size = adev->enable_uni_mes ? (AMDGPU_MAX_MES_PIPES * AMDGPU_MES_LOG_BUFFER_SIZE) : AMDGPU_MES_LOG_BUFFER_SIZE;
 
        r = amdgpu_mes_init(adev);
        if (r)
index a8763496aed315b5526accadd2872f26c0d50c37..9288f37a3cc5c3f2c3aac7de076bb90e890ffabd 100644 (file)
@@ -51,6 +51,12 @@ MODULE_FIRMWARE("amdgpu/sdma_7_0_1.bin");
 #define SDMA0_HYP_DEC_REG_END 0x589a
 #define SDMA1_HYP_DEC_REG_OFFSET 0x20
 
+/*define for compression field for sdma7*/
+#define SDMA_PKT_CONSTANT_FILL_HEADER_compress_offset 0
+#define SDMA_PKT_CONSTANT_FILL_HEADER_compress_mask   0x00000001
+#define SDMA_PKT_CONSTANT_FILL_HEADER_compress_shift  16
+#define SDMA_PKT_CONSTANT_FILL_HEADER_COMPRESS(x) (((x) & SDMA_PKT_CONSTANT_FILL_HEADER_compress_mask) << SDMA_PKT_CONSTANT_FILL_HEADER_compress_shift)
+
 static const struct amdgpu_hwip_reg_entry sdma_reg_list_7_0[] = {
        SOC15_REG_ENTRY_STR(GC, 0, regSDMA0_STATUS_REG),
        SOC15_REG_ENTRY_STR(GC, 0, regSDMA0_STATUS1_REG),
@@ -1724,7 +1730,8 @@ static void sdma_v7_0_emit_fill_buffer(struct amdgpu_ib *ib,
                                       uint64_t dst_offset,
                                       uint32_t byte_count)
 {
-       ib->ptr[ib->length_dw++] = SDMA_PKT_COPY_LINEAR_HEADER_OP(SDMA_OP_CONST_FILL);
+       ib->ptr[ib->length_dw++] = SDMA_PKT_CONSTANT_FILL_HEADER_OP(SDMA_OP_CONST_FILL) |
+               SDMA_PKT_CONSTANT_FILL_HEADER_COMPRESS(1);
        ib->ptr[ib->length_dw++] = lower_32_bits(dst_offset);
        ib->ptr[ib->length_dw++] = upper_32_bits(dst_offset);
        ib->ptr[ib->length_dw++] = src_data;
index 9044bdb38cf4d59e160e9b6c8d96f2ddde0f3a42..3e6b4736a7feaa56dc5cf1648f2f5e119b0a6ef6 100644 (file)
@@ -1148,7 +1148,7 @@ static int kfd_ioctl_alloc_memory_of_gpu(struct file *filep,
 
                if (flags & KFD_IOC_ALLOC_MEM_FLAGS_AQL_QUEUE_MEM)
                        size >>= 1;
-               WRITE_ONCE(pdd->vram_usage, pdd->vram_usage + PAGE_ALIGN(size));
+               atomic64_add(PAGE_ALIGN(size), &pdd->vram_usage);
        }
 
        mutex_unlock(&p->mutex);
@@ -1219,7 +1219,7 @@ static int kfd_ioctl_free_memory_of_gpu(struct file *filep,
                kfd_process_device_remove_obj_handle(
                        pdd, GET_IDR_HANDLE(args->handle));
 
-       WRITE_ONCE(pdd->vram_usage, pdd->vram_usage - size);
+       atomic64_sub(size, &pdd->vram_usage);
 
 err_unlock:
 err_pdd:
@@ -2347,7 +2347,7 @@ static int criu_restore_memory_of_gpu(struct kfd_process_device *pdd,
        } else if (bo_bucket->alloc_flags & KFD_IOC_ALLOC_MEM_FLAGS_VRAM) {
                bo_bucket->restored_offset = offset;
                /* Update the VRAM usage count */
-               WRITE_ONCE(pdd->vram_usage, pdd->vram_usage + bo_bucket->size);
+               atomic64_add(bo_bucket->size, &pdd->vram_usage);
        }
        return 0;
 }
index d6530febabad7fa3f02e5b07f1c9a1794d73cf33..26e48fdc872896c785358020fe09fddf8ae037b2 100644 (file)
@@ -775,7 +775,7 @@ struct kfd_process_device {
        enum kfd_pdd_bound bound;
 
        /* VRAM usage */
-       uint64_t vram_usage;
+       atomic64_t vram_usage;
        struct attribute attr_vram;
        char vram_filename[MAX_SYSFS_FILENAME_LEN];
 
index d07acf1b2f93c342ac49a894ace4851bcb1e01fb..d4aa843aacfdd90634a87da4da69fc8045aeb3eb 100644 (file)
@@ -332,7 +332,7 @@ static ssize_t kfd_procfs_show(struct kobject *kobj, struct attribute *attr,
        } else if (strncmp(attr->name, "vram_", 5) == 0) {
                struct kfd_process_device *pdd = container_of(attr, struct kfd_process_device,
                                                              attr_vram);
-               return snprintf(buffer, PAGE_SIZE, "%llu\n", READ_ONCE(pdd->vram_usage));
+               return snprintf(buffer, PAGE_SIZE, "%llu\n", atomic64_read(&pdd->vram_usage));
        } else if (strncmp(attr->name, "sdma_", 5) == 0) {
                struct kfd_process_device *pdd = container_of(attr, struct kfd_process_device,
                                                              attr_sdma);
@@ -1625,7 +1625,7 @@ struct kfd_process_device *kfd_create_process_device_data(struct kfd_node *dev,
        pdd->bound = PDD_UNBOUND;
        pdd->already_dequeued = false;
        pdd->runtime_inuse = false;
-       pdd->vram_usage = 0;
+       atomic64_set(&pdd->vram_usage, 0);
        pdd->sdma_past_activity_counter = 0;
        pdd->user_gpu_id = dev->id;
        atomic64_set(&pdd->evict_duration_counter, 0);
@@ -1702,12 +1702,15 @@ int kfd_process_device_init_vm(struct kfd_process_device *pdd,
 
        ret = amdgpu_amdkfd_gpuvm_acquire_process_vm(dev->adev, avm,
                                                     &p->kgd_process_info,
-                                                    &ef);
+                                                    p->ef ? NULL : &ef);
        if (ret) {
                dev_err(dev->adev->dev, "Failed to create process VM object\n");
                return ret;
        }
-       RCU_INIT_POINTER(p->ef, ef);
+
+       if (!p->ef)
+               RCU_INIT_POINTER(p->ef, ef);
+
        pdd->drm_priv = drm_file->private_data;
 
        ret = kfd_process_device_reserve_ib_mem(pdd);
index 04e746923697459956af019b2d1bbd0ab9fdf4a8..1893c27746a52375cef63c6944b0e4e70dfeeb4a 100644 (file)
@@ -405,6 +405,27 @@ static void svm_range_bo_release(struct kref *kref)
                spin_lock(&svm_bo->list_lock);
        }
        spin_unlock(&svm_bo->list_lock);
+
+       if (mmget_not_zero(svm_bo->eviction_fence->mm)) {
+               struct kfd_process_device *pdd;
+               struct kfd_process *p;
+               struct mm_struct *mm;
+
+               mm = svm_bo->eviction_fence->mm;
+               /*
+                * The forked child process takes svm_bo device pages ref, svm_bo could be
+                * released after parent process is gone.
+                */
+               p = kfd_lookup_process_by_mm(mm);
+               if (p) {
+                       pdd = kfd_get_process_device_data(svm_bo->node, p);
+                       if (pdd)
+                               atomic64_sub(amdgpu_bo_size(svm_bo->bo), &pdd->vram_usage);
+                       kfd_unref_process(p);
+               }
+               mmput(mm);
+       }
+
        if (!dma_fence_is_signaled(&svm_bo->eviction_fence->base))
                /* We're not in the eviction worker. Signal the fence. */
                dma_fence_signal(&svm_bo->eviction_fence->base);
@@ -532,6 +553,7 @@ int
 svm_range_vram_node_new(struct kfd_node *node, struct svm_range *prange,
                        bool clear)
 {
+       struct kfd_process_device *pdd;
        struct amdgpu_bo_param bp;
        struct svm_range_bo *svm_bo;
        struct amdgpu_bo_user *ubo;
@@ -623,6 +645,10 @@ svm_range_vram_node_new(struct kfd_node *node, struct svm_range *prange,
        list_add(&prange->svm_bo_list, &svm_bo->range_list);
        spin_unlock(&svm_bo->list_lock);
 
+       pdd = svm_range_get_pdd_by_node(prange, node);
+       if (pdd)
+               atomic64_add(amdgpu_bo_size(bo), &pdd->vram_usage);
+
        return 0;
 
 reserve_bo_failed:
index 6e79028c5d7897d5636aa0bc49c790f1dd243de0..13421a58210d5acebdf9d49546003e821cbd9e64 100644 (file)
@@ -770,6 +770,12 @@ static void dmub_hpd_callback(struct amdgpu_device *adev,
                return;
        }
 
+       /* Skip DMUB HPD IRQ in suspend/resume. We will probe them later. */
+       if (notify->type == DMUB_NOTIFICATION_HPD && adev->in_suspend) {
+               DRM_INFO("Skip DMUB HPD IRQ callback in suspend/resume\n");
+               return;
+       }
+
        link_index = notify->link_index;
        link = adev->dm.dc->links[link_index];
        dev = adev->dm.ddev;
@@ -2026,7 +2032,8 @@ static int amdgpu_dm_init(struct amdgpu_device *adev)
                        DRM_ERROR("amdgpu: failed to initialize vblank_workqueue.\n");
        }
 
-       if (adev->dm.dc->caps.ips_support && adev->dm.dc->config.disable_ips == DMUB_IPS_ENABLE)
+       if (adev->dm.dc->caps.ips_support &&
+           adev->dm.dc->config.disable_ips != DMUB_IPS_DISABLE_ALL)
                adev->dm.idle_workqueue = idle_create_workqueue(adev);
 
        if (adev->dm.dc->caps.max_links > 0 && adev->family >= AMDGPU_FAMILY_RV) {
@@ -2965,10 +2972,11 @@ static int dm_suspend(void *handle)
 
        hpd_rx_irq_work_suspend(dm);
 
-       if (adev->dm.dc->caps.ips_support)
-               dc_allow_idle_optimizations(adev->dm.dc, true);
-
        dc_set_power_state(dm->dc, DC_ACPI_CM_POWER_STATE_D3);
+
+       if (dm->dc->caps.ips_support && adev->in_s0ix)
+               dc_allow_idle_optimizations(dm->dc, true);
+
        dc_dmub_srv_set_power_state(dm->dc->ctx->dmub_srv, DC_ACPI_CM_POWER_STATE_D3);
 
        return 0;
@@ -6735,12 +6743,21 @@ create_stream_for_sink(struct drm_connector *connector,
        if (stream->signal == SIGNAL_TYPE_DISPLAY_PORT ||
            stream->signal == SIGNAL_TYPE_DISPLAY_PORT_MST ||
            stream->signal == SIGNAL_TYPE_EDP) {
+               const struct dc_edid_caps *edid_caps;
+               unsigned int disable_colorimetry = 0;
+
+               if (aconnector->dc_sink) {
+                       edid_caps = &aconnector->dc_sink->edid_caps;
+                       disable_colorimetry = edid_caps->panel_patch.disable_colorimetry;
+               }
+
                //
                // should decide stream support vsc sdp colorimetry capability
                // before building vsc info packet
                //
                stream->use_vsc_sdp_for_colorimetry = stream->link->dpcd_caps.dpcd_rev.raw >= 0x14 &&
-                                                     stream->link->dpcd_caps.dprx_feature.bits.VSC_SDP_COLORIMETRY_SUPPORTED;
+                                                     stream->link->dpcd_caps.dprx_feature.bits.VSC_SDP_COLORIMETRY_SUPPORTED &&
+                                                     !disable_colorimetry;
 
                if (stream->out_transfer_func.tf == TRANSFER_FUNCTION_GAMMA22)
                        tf = TRANSFER_FUNC_GAMMA_22;
@@ -8357,7 +8374,8 @@ static void manage_dm_interrupts(struct amdgpu_device *adev,
                if (amdgpu_ip_version(adev, DCE_HWIP, 0) <
                    IP_VERSION(3, 5, 0) ||
                    acrtc_state->stream->link->psr_settings.psr_version <
-                   DC_PSR_VERSION_UNSUPPORTED) {
+                   DC_PSR_VERSION_UNSUPPORTED ||
+                   !(adev->flags & AMD_IS_APU)) {
                        timing = &acrtc_state->stream->timing;
 
                        /* at least 2 frames */
index 50109d13d9671ea2c087086b157547602c38934b..eea317dcbe8c347ec152b7ff82a73f7cd1603012 100644 (file)
@@ -44,6 +44,7 @@
 
 #include "dm_helpers.h"
 #include "ddc_service_types.h"
+#include "clk_mgr.h"
 
 static u32 edid_extract_panel_id(struct edid *edid)
 {
@@ -73,6 +74,10 @@ static void apply_edid_quirks(struct edid *edid, struct dc_edid_caps *edid_caps)
                DRM_DEBUG_DRIVER("Clearing DPCD 0x317 on monitor with panel id %X\n", panel_id);
                edid_caps->panel_patch.remove_sink_ext_caps = true;
                break;
+       case drm_edid_encode_panel_id('S', 'D', 'C', 0x4154):
+               DRM_DEBUG_DRIVER("Disabling VSC on monitor with panel id %X\n", panel_id);
+               edid_caps->panel_patch.disable_colorimetry = true;
+               break;
        default:
                return;
        }
@@ -1117,6 +1122,8 @@ bool dm_helpers_dp_handle_test_pattern_request(
        struct pipe_ctx *pipe_ctx = NULL;
        struct amdgpu_dm_connector *aconnector = link->priv;
        struct drm_device *dev = aconnector->base.dev;
+       struct dc_state *dc_state = ctx->dc->current_state;
+       struct clk_mgr *clk_mgr = ctx->dc->clk_mgr;
        int i;
 
        for (i = 0; i < MAX_PIPES; i++) {
@@ -1217,6 +1224,16 @@ bool dm_helpers_dp_handle_test_pattern_request(
        pipe_ctx->stream->test_pattern.type = test_pattern;
        pipe_ctx->stream->test_pattern.color_space = test_pattern_color_space;
 
+       /* Temp W/A for compliance test failure */
+       dc_state->bw_ctx.bw.dcn.clk.p_state_change_support = false;
+       dc_state->bw_ctx.bw.dcn.clk.dramclk_khz = clk_mgr->dc_mode_softmax_enabled ?
+               clk_mgr->bw_params->dc_mode_softmax_memclk : clk_mgr->bw_params->max_memclk_mhz;
+       dc_state->bw_ctx.bw.dcn.clk.idle_dramclk_khz = dc_state->bw_ctx.bw.dcn.clk.dramclk_khz;
+       ctx->dc->clk_mgr->funcs->update_clocks(
+                       ctx->dc->clk_mgr,
+                       dc_state,
+                       false);
+
        dc_link_dp_set_test_pattern(
                (struct dc_link *) link,
                test_pattern,
index 83a31b97e96bf6739e837a7c4251e6c10b774517..a08e8a0b696c60f65514476ab7e6994f0937fe6e 100644 (file)
@@ -1027,6 +1027,7 @@ static int try_disable_dsc(struct drm_atomic_state *state,
        int remaining_to_try = 0;
        int ret;
        uint16_t fec_overhead_multiplier_x1000 = get_fec_overhead_multiplier(dc_link);
+       int var_pbn;
 
        for (i = 0; i < count; i++) {
                if (vars[i + k].dsc_enabled
@@ -1057,13 +1058,18 @@ static int try_disable_dsc(struct drm_atomic_state *state,
                        break;
 
                DRM_DEBUG_DRIVER("MST_DSC index #%d, try no compression\n", next_index);
+               var_pbn = vars[next_index].pbn;
                vars[next_index].pbn = kbps_to_peak_pbn(params[next_index].bw_range.stream_kbps, fec_overhead_multiplier_x1000);
                ret = drm_dp_atomic_find_time_slots(state,
                                                    params[next_index].port->mgr,
                                                    params[next_index].port,
                                                    vars[next_index].pbn);
-               if (ret < 0)
+               if (ret < 0) {
+                       DRM_DEBUG_DRIVER("%s:%d MST_DSC index #%d, failed to set pbn to the state, %d\n",
+                                               __func__, __LINE__, next_index, ret);
+                       vars[next_index].pbn = var_pbn;
                        return ret;
+               }
 
                ret = drm_dp_mst_atomic_check(state);
                if (ret == 0) {
@@ -1071,14 +1077,17 @@ static int try_disable_dsc(struct drm_atomic_state *state,
                        vars[next_index].dsc_enabled = false;
                        vars[next_index].bpp_x16 = 0;
                } else {
-                       DRM_DEBUG_DRIVER("MST_DSC index #%d, restore minimum compression\n", next_index);
-                       vars[next_index].pbn = kbps_to_peak_pbn(params[next_index].bw_range.max_kbps, fec_overhead_multiplier_x1000);
+                       DRM_DEBUG_DRIVER("MST_DSC index #%d, restore optimized pbn value\n", next_index);
+                       vars[next_index].pbn = var_pbn;
                        ret = drm_dp_atomic_find_time_slots(state,
                                                            params[next_index].port->mgr,
                                                            params[next_index].port,
                                                            vars[next_index].pbn);
-                       if (ret < 0)
+                       if (ret < 0) {
+                               DRM_DEBUG_DRIVER("%s:%d MST_DSC index #%d, failed to set pbn to the state, %d\n",
+                                                       __func__, __LINE__, next_index, ret);
                                return ret;
+                       }
                }
 
                tried[next_index] = true;
index 5c39390ecbd5c1858e0a6393d910185f040299db..a88f1b6ea64cfa2a4447a47747e1fd7c652a9c6e 100644 (file)
@@ -5065,11 +5065,26 @@ static bool update_planes_and_stream_v3(struct dc *dc,
        return true;
 }
 
+static void clear_update_flags(struct dc_surface_update *srf_updates,
+       int surface_count, struct dc_stream_state *stream)
+{
+       int i;
+
+       if (stream)
+               stream->update_flags.raw = 0;
+
+       for (i = 0; i < surface_count; i++)
+               if (srf_updates[i].surface)
+                       srf_updates[i].surface->update_flags.raw = 0;
+}
+
 bool dc_update_planes_and_stream(struct dc *dc,
                struct dc_surface_update *srf_updates, int surface_count,
                struct dc_stream_state *stream,
                struct dc_stream_update *stream_update)
 {
+       bool ret = false;
+
        dc_exit_ips_for_hw_access(dc);
        /*
         * update planes and stream version 3 separates FULL and FAST updates
@@ -5086,10 +5101,16 @@ bool dc_update_planes_and_stream(struct dc *dc,
         * features as they are now transparent to the new sequence.
         */
        if (dc->ctx->dce_version >= DCN_VERSION_4_01)
-               return update_planes_and_stream_v3(dc, srf_updates,
+               ret = update_planes_and_stream_v3(dc, srf_updates,
                                surface_count, stream, stream_update);
-       return update_planes_and_stream_v2(dc, srf_updates,
+       else
+               ret = update_planes_and_stream_v2(dc, srf_updates,
                        surface_count, stream, stream_update);
+
+       if (ret)
+               clear_update_flags(srf_updates, surface_count, stream);
+
+       return ret;
 }
 
 void dc_commit_updates_for_stream(struct dc *dc,
@@ -5099,6 +5120,8 @@ void dc_commit_updates_for_stream(struct dc *dc,
                struct dc_stream_update *stream_update,
                struct dc_state *state)
 {
+       bool ret = false;
+
        dc_exit_ips_for_hw_access(dc);
        /* TODO: Since change commit sequence can have a huge impact,
         * we decided to only enable it for DCN3x. However, as soon as
@@ -5106,17 +5129,17 @@ void dc_commit_updates_for_stream(struct dc *dc,
         * the new sequence for all ASICs.
         */
        if (dc->ctx->dce_version >= DCN_VERSION_4_01) {
-               update_planes_and_stream_v3(dc, srf_updates, surface_count,
+               ret = update_planes_and_stream_v3(dc, srf_updates, surface_count,
                                stream, stream_update);
-               return;
-       }
-       if (dc->ctx->dce_version >= DCN_VERSION_3_2) {
-               update_planes_and_stream_v2(dc, srf_updates, surface_count,
+       } else if (dc->ctx->dce_version >= DCN_VERSION_3_2) {
+               ret = update_planes_and_stream_v2(dc, srf_updates, surface_count,
                                stream, stream_update);
-               return;
-       }
-       update_planes_and_stream_v1(dc, srf_updates, surface_count, stream,
-                       stream_update, state);
+       } else
+               ret = update_planes_and_stream_v1(dc, srf_updates, surface_count, stream,
+                               stream_update, state);
+
+       if (ret)
+               clear_update_flags(srf_updates, surface_count, stream);
 }
 
 uint8_t dc_get_current_stream_count(struct dc *dc)
index fd6dca73571434ca65ee38aa1bc2495ef65f4668..6d7989b751e2cecbc8f5cbe837f1ce43a20d94d4 100644 (file)
@@ -178,6 +178,7 @@ struct dc_panel_patch {
        unsigned int skip_avmute;
        unsigned int mst_start_top_delay;
        unsigned int remove_sink_ext_caps;
+       unsigned int disable_colorimetry;
 };
 
 struct dc_edid_caps {
index da9101b83e8c1ea421c90100376fdaea47435d39..70abd32ce2ad18c1475a1355437d0ef72e154b3c 100644 (file)
@@ -766,6 +766,7 @@ static const struct dc_debug_options debug_defaults_drv = {
        .disable_dmub_reallow_idle = false,
        .static_screen_wait_frames = 2,
        .notify_dpia_hr_bw = true,
+       .min_disp_clk_khz = 50000,
 };
 
 static const struct dc_panel_config panel_config_defaults = {
index 3cd52e7a9c77c289bb5f234bd0072f2beeb9b59b..95838c7ab05431277075d5788307e0ea6f3b3492 100644 (file)
@@ -841,6 +841,8 @@ bool is_psr_su_specific_panel(struct dc_link *link)
                                isPSRSUSupported = false;
                        else if (dpcd_caps->sink_dev_id_str[1] == 0x08 && dpcd_caps->sink_dev_id_str[0] == 0x03)
                                isPSRSUSupported = false;
+                       else if (dpcd_caps->sink_dev_id_str[1] == 0x08 && dpcd_caps->sink_dev_id_str[0] == 0x01)
+                               isPSRSUSupported = false;
                        else if (dpcd_caps->psr_info.force_psrsu_cap == 0x1)
                                isPSRSUSupported = true;
                }
index 9118fcddbf1167ec7ddfbb8944d467007d3ad5b2..227bf0e84a130bbe67edf27369f7b1a5575926a9 100644 (file)
@@ -60,7 +60,7 @@ struct vi_dpm_level {
 
 struct vi_dpm_table {
        uint32_t count;
-       struct vi_dpm_level dpm_level[] __counted_by(count);
+       struct vi_dpm_level dpm_level[];
 };
 
 #define PCIE_PERF_REQ_REMOVE_REGISTRY   0
@@ -91,7 +91,7 @@ struct phm_set_power_state_input {
 
 struct phm_clock_array {
        uint32_t count;
-       uint32_t values[] __counted_by(count);
+       uint32_t values[];
 };
 
 struct phm_clock_voltage_dependency_record {
@@ -123,7 +123,7 @@ struct phm_acpclock_voltage_dependency_record {
 
 struct phm_clock_voltage_dependency_table {
        uint32_t count;
-       struct phm_clock_voltage_dependency_record entries[] __counted_by(count);
+       struct phm_clock_voltage_dependency_record entries[];
 };
 
 struct phm_phase_shedding_limits_record {
@@ -140,7 +140,7 @@ struct phm_uvd_clock_voltage_dependency_record {
 
 struct phm_uvd_clock_voltage_dependency_table {
        uint8_t count;
-       struct phm_uvd_clock_voltage_dependency_record entries[] __counted_by(count);
+       struct phm_uvd_clock_voltage_dependency_record entries[];
 };
 
 struct phm_acp_clock_voltage_dependency_record {
@@ -150,7 +150,7 @@ struct phm_acp_clock_voltage_dependency_record {
 
 struct phm_acp_clock_voltage_dependency_table {
        uint32_t count;
-       struct phm_acp_clock_voltage_dependency_record entries[] __counted_by(count);
+       struct phm_acp_clock_voltage_dependency_record entries[];
 };
 
 struct phm_vce_clock_voltage_dependency_record {
@@ -161,32 +161,32 @@ struct phm_vce_clock_voltage_dependency_record {
 
 struct phm_phase_shedding_limits_table {
        uint32_t count;
-       struct phm_phase_shedding_limits_record  entries[] __counted_by(count);
+       struct phm_phase_shedding_limits_record  entries[];
 };
 
 struct phm_vceclock_voltage_dependency_table {
        uint8_t count;
-       struct phm_vceclock_voltage_dependency_record entries[] __counted_by(count);
+       struct phm_vceclock_voltage_dependency_record entries[];
 };
 
 struct phm_uvdclock_voltage_dependency_table {
        uint8_t count;
-       struct phm_uvdclock_voltage_dependency_record entries[] __counted_by(count);
+       struct phm_uvdclock_voltage_dependency_record entries[];
 };
 
 struct phm_samuclock_voltage_dependency_table {
        uint8_t count;
-       struct phm_samuclock_voltage_dependency_record entries[] __counted_by(count);
+       struct phm_samuclock_voltage_dependency_record entries[];
 };
 
 struct phm_acpclock_voltage_dependency_table {
        uint32_t count;
-       struct phm_acpclock_voltage_dependency_record entries[] __counted_by(count);
+       struct phm_acpclock_voltage_dependency_record entries[];
 };
 
 struct phm_vce_clock_voltage_dependency_table {
        uint8_t count;
-       struct phm_vce_clock_voltage_dependency_record entries[] __counted_by(count);
+       struct phm_vce_clock_voltage_dependency_record entries[];
 };
 
 
@@ -393,7 +393,7 @@ union phm_cac_leakage_record {
 
 struct phm_cac_leakage_table {
        uint32_t count;
-       union phm_cac_leakage_record entries[] __counted_by(count);
+       union phm_cac_leakage_record entries[];
 };
 
 struct phm_samu_clock_voltage_dependency_record {
@@ -404,7 +404,7 @@ struct phm_samu_clock_voltage_dependency_record {
 
 struct phm_samu_clock_voltage_dependency_table {
        uint8_t count;
-       struct phm_samu_clock_voltage_dependency_record entries[] __counted_by(count);
+       struct phm_samu_clock_voltage_dependency_record entries[];
 };
 
 struct phm_cac_tdp_table {
index bb3bc68dfc39788ac0a44f2f14aecf86256d4b6f..80e60ea2d11e3c6bbfc629edea9161627eec5f83 100644 (file)
@@ -1234,6 +1234,14 @@ static void smu_init_xgmi_plpd_mode(struct smu_context *smu)
        }
 }
 
+static bool smu_is_workload_profile_available(struct smu_context *smu,
+                                             u32 profile)
+{
+       if (profile >= PP_SMC_POWER_PROFILE_COUNT)
+               return false;
+       return smu->workload_map && smu->workload_map[profile].valid_mapping;
+}
+
 static int smu_sw_init(void *handle)
 {
        struct amdgpu_device *adev = (struct amdgpu_device *)handle;
@@ -1264,7 +1272,12 @@ static int smu_sw_init(void *handle)
        smu->workload_prority[PP_SMC_POWER_PROFILE_VR] = 4;
        smu->workload_prority[PP_SMC_POWER_PROFILE_COMPUTE] = 5;
        smu->workload_prority[PP_SMC_POWER_PROFILE_CUSTOM] = 6;
-       smu->workload_mask = 1 << smu->workload_prority[PP_SMC_POWER_PROFILE_BOOTUP_DEFAULT];
+
+       if (smu->is_apu ||
+           !smu_is_workload_profile_available(smu, PP_SMC_POWER_PROFILE_FULLSCREEN3D))
+               smu->workload_mask = 1 << smu->workload_prority[PP_SMC_POWER_PROFILE_BOOTUP_DEFAULT];
+       else
+               smu->workload_mask = 1 << smu->workload_prority[PP_SMC_POWER_PROFILE_FULLSCREEN3D];
 
        smu->workload_setting[0] = PP_SMC_POWER_PROFILE_BOOTUP_DEFAULT;
        smu->workload_setting[1] = PP_SMC_POWER_PROFILE_FULLSCREEN3D;
@@ -2226,7 +2239,7 @@ static int smu_bump_power_profile_mode(struct smu_context *smu,
 static int smu_adjust_power_state_dynamic(struct smu_context *smu,
                                          enum amd_dpm_forced_level level,
                                          bool skip_display_settings,
-                                         bool force_update)
+                                         bool init)
 {
        int ret = 0;
        int index = 0;
@@ -2255,7 +2268,7 @@ static int smu_adjust_power_state_dynamic(struct smu_context *smu,
                }
        }
 
-       if (force_update || smu_dpm_ctx->dpm_level != level) {
+       if (smu_dpm_ctx->dpm_level != level) {
                ret = smu_asic_set_performance_level(smu, level);
                if (ret) {
                        dev_err(smu->adev->dev, "Failed to set performance level!");
@@ -2272,7 +2285,7 @@ static int smu_adjust_power_state_dynamic(struct smu_context *smu,
                index = index > 0 && index <= WORKLOAD_POLICY_MAX ? index - 1 : 0;
                workload[0] = smu->workload_setting[index];
 
-               if (force_update || smu->power_profile_mode != workload[0])
+               if (init || smu->power_profile_mode != workload[0])
                        smu_bump_power_profile_mode(smu, workload, 0);
        }
 
index ee457a6f08130cdd0845f3b1e961d90f82c5869d..c2fd0a4a13e5d56f0575e8796bf1db1ed93ba1cf 100644 (file)
@@ -25,7 +25,7 @@
 #define SMU14_DRIVER_IF_V14_0_H
 
 //Increment this version if SkuTable_t or BoardTable_t change
-#define PPTABLE_VERSION 0x18
+#define PPTABLE_VERSION 0x1B
 
 #define NUM_GFXCLK_DPM_LEVELS    16
 #define NUM_SOCCLK_DPM_LEVELS    8
@@ -145,7 +145,7 @@ typedef enum {
 } FEATURE_BTC_e;
 
 // Debug Overrides Bitmask
-#define DEBUG_OVERRIDE_DISABLE_VOLT_LINK_VCN_FCLK      0x00000001
+#define DEBUG_OVERRIDE_NOT_USE                                    0x00000001
 #define DEBUG_OVERRIDE_DISABLE_VOLT_LINK_DCN_FCLK      0x00000002
 #define DEBUG_OVERRIDE_DISABLE_VOLT_LINK_MP0_FCLK      0x00000004
 #define DEBUG_OVERRIDE_DISABLE_VOLT_LINK_VCN_DCFCLK    0x00000008
@@ -161,6 +161,7 @@ typedef enum {
 #define DEBUG_OVERRIDE_ENABLE_SOC_VF_BRINGUP_MODE      0x00002000
 #define DEBUG_OVERRIDE_ENABLE_PER_WGP_RESIENCY         0x00004000
 #define DEBUG_OVERRIDE_DISABLE_MEMORY_VOLTAGE_SCALING  0x00008000
+#define DEBUG_OVERRIDE_DFLL_BTC_FCW_LOG                0x00010000
 
 // VR Mapping Bit Defines
 #define VR_MAPPING_VR_SELECT_MASK  0x01
@@ -391,6 +392,21 @@ typedef struct {
   EccInfo_t  EccInfo[24];
 } EccInfoTable_t;
 
+#define EPCS_HIGH_POWER                  600
+#define EPCS_NORMAL_POWER                450
+#define EPCS_LOW_POWER                   300
+#define EPCS_SHORTED_POWER               150
+#define EPCS_NO_BOOTUP                   0
+
+typedef enum{
+  EPCS_SHORTED_LIMIT,
+  EPCS_LOW_POWER_LIMIT,
+  EPCS_NORMAL_POWER_LIMIT,
+  EPCS_HIGH_POWER_LIMIT,
+  EPCS_NOT_CONFIGURED,
+  EPCS_STATUS_COUNT,
+} EPCS_STATUS_e;
+
 //D3HOT sequences
 typedef enum {
   BACO_SEQUENCE,
@@ -662,7 +678,7 @@ typedef enum {
 } PP_GRTAVFS_FW_SEP_FUSE_e;
 
 #define PP_NUM_RTAVFS_PWL_ZONES 5
-
+#define PP_NUM_PSM_DIDT_PWL_ZONES 3
 
 // VBIOS or PPLIB configures telemetry slope and offset. Only slope expected to be set for SVI3
 // Slope Q1.7, Offset Q1.2
@@ -746,10 +762,10 @@ typedef struct {
   uint16_t               Padding;
 
   //Frequency changes
-  int16_t                GfxclkFmin;           // MHz
-  int16_t                GfxclkFmax;           // MHz
-  uint16_t               UclkFmin;             // MHz
-  uint16_t               UclkFmax;             // MHz
+  int16_t                GfxclkFoffset;
+  uint16_t               Padding1;
+  uint16_t               UclkFmin;
+  uint16_t               UclkFmax;
   uint16_t               FclkFmin;
   uint16_t               FclkFmax;
 
@@ -770,19 +786,23 @@ typedef struct {
   uint8_t                MaxOpTemp;
 
   uint8_t                AdvancedOdModeEnabled;
-  uint8_t                Padding1[3];
+  uint8_t                Padding2[3];
 
   uint16_t               GfxVoltageFullCtrlMode;
   uint16_t               SocVoltageFullCtrlMode;
   uint16_t               GfxclkFullCtrlMode;
   uint16_t               UclkFullCtrlMode;
   uint16_t               FclkFullCtrlMode;
-  uint16_t               Padding2;
+  uint16_t               Padding3;
 
   int16_t                GfxEdc;
   int16_t                GfxPccLimitControl;
 
-  uint32_t               Spare[10];
+  uint16_t               GfxclkFmaxVmax;
+  uint8_t                GfxclkFmaxVmaxTemperature;
+  uint8_t                Padding4[1];
+
+  uint32_t               Spare[9];
   uint32_t               MmHubPadding[8]; // SMU internal use. Adding here instead of external as a workaround
 } OverDriveTable_t;
 
@@ -802,8 +822,8 @@ typedef struct {
   uint16_t               VddSocVmax;
 
   //gfxclk
-  int16_t                GfxclkFmin;           // MHz
-  int16_t                GfxclkFmax;           // MHz
+  int16_t                GfxclkFoffset;
+  uint16_t               Padding;
   //uclk
   uint16_t               UclkFmin;             // MHz
   uint16_t               UclkFmax;             // MHz
@@ -828,7 +848,7 @@ typedef struct {
   uint8_t                FanZeroRpmEnable;
   //temperature
   uint8_t                MaxOpTemp;
-  uint8_t                Padding[2];
+  uint8_t                Padding1[2];
 
   //Full Ctrl
   uint16_t               GfxVoltageFullCtrlMode;
@@ -839,7 +859,7 @@ typedef struct {
   //EDC
   int16_t                GfxEdc;
   int16_t                GfxPccLimitControl;
-  int16_t                Padding1;
+  int16_t                Padding2;
 
   uint32_t               Spare[5];
 } OverDriveLimits_t;
@@ -987,8 +1007,9 @@ typedef struct {
   uint16_t BaseClockDc;
   uint16_t GameClockDc;
   uint16_t BoostClockDc;
-
-  uint32_t Reserved[4];
+  uint16_t MaxReportedClock;
+  uint16_t Padding;
+  uint32_t Reserved[3];
 } DriverReportedClocks_t;
 
 typedef struct {
@@ -1132,7 +1153,7 @@ typedef struct {
   uint32_t      DcModeMaxFreq     [PPCLK_COUNT            ];     // In MHz
 
   uint16_t      GfxclkAibFmax;
-  uint16_t      GfxclkFreqCap;
+  uint16_t      GfxDpmPadding;
 
   //GFX Idle Power Settings
   uint16_t      GfxclkFgfxoffEntry;   // Entry in RLC stage (PLL), in Mhz
@@ -1172,8 +1193,7 @@ typedef struct {
   uint32_t        DvoFmaxLowScaler; //Unitless float
 
   // GFX DCS
-  uint16_t      DcsGfxOffVoltage;     //Voltage in mV(Q2) applied to VDDGFX when entering DCS GFXOFF phase
-  uint16_t      PaddingDcs;
+  uint32_t      PaddingDcs;
 
   uint16_t      DcsMinGfxOffTime;     //Minimum amount of time PMFW shuts GFX OFF as part of GFX DCS phase
   uint16_t      DcsMaxGfxOffTime;      //Maximum amount of time PMFW can shut GFX OFF as part of GFX DCS phase at a stretch.
@@ -1205,8 +1225,7 @@ typedef struct {
   uint16_t      DalDcModeMaxUclkFreq;
   uint8_t       PaddingsMem[2];
   //FCLK Section
-  uint16_t      FclkDpmDisallowPstateFreq;  //Frequency which FW will target when indicated that display config cannot support P-state. Set to 0 use FW calculated value
-  uint16_t      PaddingFclk;
+  uint32_t      PaddingFclk;
 
   // Link DPM Settings
   uint8_t       PcieGenSpeed[NUM_LINK_LEVELS];           ///< 0:PciE-gen1 1:PciE-gen2 2:PciE-gen3 3:PciE-gen4 4:PciE-gen5
@@ -1215,12 +1234,19 @@ typedef struct {
 
   // SECTION: VDD_GFX AVFS
   uint8_t       OverrideGfxAvfsFuses;
-  uint8_t       GfxAvfsPadding[3];
+  uint8_t       GfxAvfsPadding[1];
+  uint16_t      DroopGBStDev;
 
   uint32_t      SocHwRtAvfsFuses[PP_GRTAVFS_HW_FUSE_COUNT];   //new added for Soc domain
   uint32_t      GfxL2HwRtAvfsFuses[PP_GRTAVFS_HW_FUSE_COUNT]; //see fusedoc for encoding
   //uint32_t      GfxSeHwRtAvfsFuses[PP_GRTAVFS_HW_FUSE_COUNT];
-  uint32_t      spare_HwRtAvfsFuses[PP_GRTAVFS_HW_FUSE_COUNT];
+
+  uint16_t      PsmDidt_Vcross[PP_NUM_PSM_DIDT_PWL_ZONES-1];
+  uint32_t      PsmDidt_StaticDroop_A[PP_NUM_PSM_DIDT_PWL_ZONES];
+  uint32_t      PsmDidt_StaticDroop_B[PP_NUM_PSM_DIDT_PWL_ZONES];
+  uint32_t      PsmDidt_DynDroop_A[PP_NUM_PSM_DIDT_PWL_ZONES];
+  uint32_t      PsmDidt_DynDroop_B[PP_NUM_PSM_DIDT_PWL_ZONES];
+  uint32_t      spare_HwRtAvfsFuses[19];
 
   uint32_t      SocCommonRtAvfs[PP_GRTAVFS_FW_COMMON_FUSE_COUNT];
   uint32_t      GfxCommonRtAvfs[PP_GRTAVFS_FW_COMMON_FUSE_COUNT];
@@ -1246,11 +1272,7 @@ typedef struct {
   uint32_t      dGbV_dT_vmin;
   uint32_t      dGbV_dT_vmax;
 
-  //Unused: PMFW-9370
-  uint32_t      V2F_vmin_range_low;
-  uint32_t      V2F_vmin_range_high;
-  uint32_t      V2F_vmax_range_low;
-  uint32_t      V2F_vmax_range_high;
+  uint32_t      PaddingV2F[4];
 
   AvfsDcBtcParams_t DcBtcGfxParams;
   QuadraticInt_t    SSCurve_GFX;
@@ -1327,18 +1349,18 @@ typedef struct {
   uint16_t        PsmDidtReleaseTimer;
   uint32_t        PsmDidtStallPattern; //Will be written to both pattern 1 and didt_static_level_prog
   // CAC EDC
-  uint32_t        Leakage_C0; // in IEEE float
-  uint32_t        Leakage_C1; // in IEEE float
-  uint32_t        Leakage_C2; // in IEEE float
-  uint32_t        Leakage_C3; // in IEEE float
-  uint32_t        Leakage_C4; // in IEEE float
-  uint32_t        Leakage_C5; // in IEEE float
-  uint32_t        GFX_CLK_SCALAR; // in IEEE float
-  uint32_t        GFX_CLK_INTERCEPT; // in IEEE float
-  uint32_t        GFX_CAC_M; // in IEEE float
-  uint32_t        GFX_CAC_B; // in IEEE float
-  uint32_t        VDD_GFX_CurrentLimitGuardband; // in IEEE float
-  uint32_t        DynToTotalCacScalar; // in IEEE
+  uint32_t        CacEdcCacLeakageC0;
+  uint32_t        CacEdcCacLeakageC1;
+  uint32_t        CacEdcCacLeakageC2;
+  uint32_t        CacEdcCacLeakageC3;
+  uint32_t        CacEdcCacLeakageC4;
+  uint32_t        CacEdcCacLeakageC5;
+  uint32_t        CacEdcGfxClkScalar;
+  uint32_t        CacEdcGfxClkIntercept;
+  uint32_t        CacEdcCac_m;
+  uint32_t        CacEdcCac_b;
+  uint32_t        CacEdcCurrLimitGuardband;
+  uint32_t        CacEdcDynToTotalCacRatio;
   // GFX EDC XVMIN
   uint32_t        XVmin_Gfx_EdcThreshScalar;
   uint32_t        XVmin_Gfx_EdcEnableFreq;
@@ -1467,7 +1489,7 @@ typedef struct {
   uint8_t      VddqOffEnabled;
   uint8_t      PaddingUmcFlags[2];
 
-  uint32_t    PostVoltageSetBacoDelay; // in microseconds. Amount of time FW will wait after power good is established or PSI0 command is issued
+  uint32_t    Paddign1;
   uint32_t    BacoEntryDelay; // in milliseconds. Amount of time FW will wait to trigger BACO entry after receiving entry notification from OS
 
   uint8_t     FuseWritePowerMuxPresent;
@@ -1530,7 +1552,7 @@ typedef struct {
   int16_t     FuzzyFan_ErrorSetDelta;
   int16_t     FuzzyFan_ErrorRateSetDelta;
   int16_t     FuzzyFan_PwmSetDelta;
-  uint16_t    FuzzyFan_Reserved;
+  uint16_t    FanPadding2;
 
   uint16_t    FwCtfLimit[TEMP_COUNT];
 
@@ -1547,9 +1569,10 @@ typedef struct {
   uint16_t    FanSpare[1];
   uint8_t     FanIntakeSensorSupport;
   uint8_t     FanIntakePadding;
-  uint32_t    FanAmbientPerfBoostThreshold;
   uint32_t    FanSpare2[12];
 
+  uint32_t ODFeatureCtrlMask;
+
   uint16_t TemperatureLimit_Hynix; // In degrees Celsius. Memory temperature limit associated with Hynix
   uint16_t TemperatureLimit_Micron; // In degrees Celsius. Memory temperature limit associated with Micron
   uint16_t TemperatureFwCtfLimit_Hynix;
@@ -1637,7 +1660,7 @@ typedef struct {
   uint16_t AverageDclk0Frequency  ;
   uint16_t AverageVclk1Frequency  ;
   uint16_t AverageDclk1Frequency  ;
-  uint16_t PCIeBusy               ;
+  uint16_t AveragePCIeBusy        ;
   uint16_t dGPU_W_MAX             ;
   uint16_t padding                ;
 
@@ -1665,12 +1688,12 @@ typedef struct {
 
   uint16_t AverageGfxActivity    ;
   uint16_t AverageUclkActivity   ;
-  uint16_t Vcn0ActivityPercentage  ;
+  uint16_t AverageVcn0ActivityPercentage;
   uint16_t Vcn1ActivityPercentage  ;
 
   uint32_t EnergyAccumulator;
   uint16_t AverageSocketPower;
-  uint16_t MovingAverageTotalBoardPower;
+  uint16_t AverageTotalBoardPower;
 
   uint16_t AvgTemperature[TEMP_COUNT];
   uint16_t AvgTemperatureFanIntake;
@@ -1684,7 +1707,8 @@ typedef struct {
 
 
   uint8_t  ThrottlingPercentage[THROTTLER_COUNT];
-  uint8_t  padding1[3];
+  uint8_t  VmaxThrottlingPercentage;
+  uint8_t  padding1[2];
 
   //metrics for D3hot entry/exit and driver ARM msgs
   uint32_t D3HotEntryCountPerMode[D3HOT_SEQUENCE_COUNT];
@@ -1693,7 +1717,7 @@ typedef struct {
 
   uint16_t ApuSTAPMSmartShiftLimit;
   uint16_t ApuSTAPMLimit;
-  uint16_t MovingAvgApuSocketPower;
+  uint16_t AvgApuSocketPower;
 
   uint16_t AverageUclkActivity_MAX;
 
@@ -1823,6 +1847,17 @@ typedef struct {
 #define TABLE_TRANSFER_FAILED     0xFF
 #define TABLE_TRANSFER_PENDING    0xAB
 
+#define TABLE_PPT_FAILED                          0x100
+#define TABLE_TDC_FAILED                          0x200
+#define TABLE_TEMP_FAILED                         0x400
+#define TABLE_FAN_TARGET_TEMP_FAILED              0x800
+#define TABLE_FAN_STOP_TEMP_FAILED               0x1000
+#define TABLE_FAN_START_TEMP_FAILED              0x2000
+#define TABLE_FAN_PWM_MIN_FAILED                 0x4000
+#define TABLE_ACOUSTIC_TARGET_RPM_FAILED         0x8000
+#define TABLE_ACOUSTIC_LIMIT_RPM_FAILED         0x10000
+#define TABLE_MGPU_ACOUSTIC_TARGET_RPM_FAILED   0x20000
+
 // Table types
 #define TABLE_PPTABLE            0
 #define TABLE_COMBO_PPTABLE           1
@@ -1849,5 +1884,6 @@ typedef struct {
 #define IH_INTERRUPT_CONTEXT_ID_THERMAL_THROTTLING  0x7
 #define IH_INTERRUPT_CONTEXT_ID_FAN_ABNORMAL        0x8
 #define IH_INTERRUPT_CONTEXT_ID_FAN_RECOVERY        0x9
+#define IH_INTERRUPT_CONTEXT_ID_DYNAMIC_TABLE       0xA
 
 #endif
index 46b456590a08049b051cbfbae1d725b3e93f6925..727d5b405435d01c5d149648c6eed3e4c9c72401 100644 (file)
@@ -28,7 +28,7 @@
 #define SMU14_DRIVER_IF_VERSION_INV 0xFFFFFFFF
 #define SMU14_DRIVER_IF_VERSION_SMU_V14_0_0 0x7
 #define SMU14_DRIVER_IF_VERSION_SMU_V14_0_1 0x6
-#define SMU14_DRIVER_IF_VERSION_SMU_V14_0_2 0x26
+#define SMU14_DRIVER_IF_VERSION_SMU_V14_0_2 0x2E
 
 #define FEATURE_MASK(feature) (1ULL << feature)
 
index 22737b11b1bfb1e761d9cf259b19185344945e56..1fe020f1f4dbe25b763cf36ce8f3ea0b8bb06206 100644 (file)
@@ -242,7 +242,9 @@ static int vangogh_tables_init(struct smu_context *smu)
                goto err0_out;
        smu_table->metrics_time = 0;
 
-       smu_table->gpu_metrics_table_size = max(sizeof(struct gpu_metrics_v2_3), sizeof(struct gpu_metrics_v2_2));
+       smu_table->gpu_metrics_table_size = sizeof(struct gpu_metrics_v2_2);
+       smu_table->gpu_metrics_table_size = max(smu_table->gpu_metrics_table_size, sizeof(struct gpu_metrics_v2_3));
+       smu_table->gpu_metrics_table_size = max(smu_table->gpu_metrics_table_size, sizeof(struct gpu_metrics_v2_4));
        smu_table->gpu_metrics_table = kzalloc(smu_table->gpu_metrics_table_size, GFP_KERNEL);
        if (!smu_table->gpu_metrics_table)
                goto err1_out;
index 1d024b122b0c02a94a44b82faf248a38448a1809..d53e162dcd8de2f591fd7add9240519a3731dc09 100644 (file)
@@ -2485,7 +2485,7 @@ static int smu_v13_0_0_set_power_profile_mode(struct smu_context *smu,
        DpmActivityMonitorCoeffInt_t *activity_monitor =
                &(activity_monitor_external.DpmActivityMonitorCoeffInt);
        int workload_type, ret = 0;
-       u32 workload_mask;
+       u32 workload_mask, selected_workload_mask;
 
        smu->power_profile_mode = input[size];
 
@@ -2552,21 +2552,19 @@ static int smu_v13_0_0_set_power_profile_mode(struct smu_context *smu,
        if (workload_type < 0)
                return -EINVAL;
 
-       workload_mask = 1 << workload_type;
+       selected_workload_mask = workload_mask = 1 << workload_type;
 
        /* Add optimizations for SMU13.0.0/10.  Reuse the power saving profile */
-       if (smu->power_profile_mode == PP_SMC_POWER_PROFILE_COMPUTE) {
-               if ((amdgpu_ip_version(smu->adev, MP1_HWIP, 0) == IP_VERSION(13, 0, 0) &&
-                       ((smu->adev->pm.fw_version == 0x004e6601) ||
-                       (smu->adev->pm.fw_version >= 0x004e7300))) ||
-                       (amdgpu_ip_version(smu->adev, MP1_HWIP, 0) == IP_VERSION(13, 0, 10) &&
-                        smu->adev->pm.fw_version >= 0x00504500)) {
-                       workload_type = smu_cmn_to_asic_specific_index(smu,
-                                                               CMN2ASIC_MAPPING_WORKLOAD,
-                                                               PP_SMC_POWER_PROFILE_POWERSAVING);
-                       if (workload_type >= 0)
-                               workload_mask |= 1 << workload_type;
-               }
+       if ((amdgpu_ip_version(smu->adev, MP1_HWIP, 0) == IP_VERSION(13, 0, 0) &&
+            ((smu->adev->pm.fw_version == 0x004e6601) ||
+             (smu->adev->pm.fw_version >= 0x004e7300))) ||
+           (amdgpu_ip_version(smu->adev, MP1_HWIP, 0) == IP_VERSION(13, 0, 10) &&
+            smu->adev->pm.fw_version >= 0x00504500)) {
+               workload_type = smu_cmn_to_asic_specific_index(smu,
+                                                              CMN2ASIC_MAPPING_WORKLOAD,
+                                                              PP_SMC_POWER_PROFILE_POWERSAVING);
+               if (workload_type >= 0)
+                       workload_mask |= 1 << workload_type;
        }
 
        ret = smu_cmn_send_smc_msg_with_param(smu,
@@ -2574,7 +2572,7 @@ static int smu_v13_0_0_set_power_profile_mode(struct smu_context *smu,
                                               workload_mask,
                                               NULL);
        if (!ret)
-               smu->workload_mask = workload_mask;
+               smu->workload_mask = selected_workload_mask;
 
        return ret;
 }
index 5899d01fa73d3669335bc1e6ea81a4ea057e26e2..e83ea2bc7f9c4ecf6e0e925572f13b045eb71564 100644 (file)
@@ -1077,12 +1077,9 @@ static void smu_v14_0_2_get_od_setting_limits(struct smu_context *smu,
 
        switch (od_feature_bit) {
        case PP_OD_FEATURE_GFXCLK_FMIN:
-               od_min_setting = overdrive_lowerlimits->GfxclkFmin;
-               od_max_setting = overdrive_upperlimits->GfxclkFmin;
-               break;
        case PP_OD_FEATURE_GFXCLK_FMAX:
-               od_min_setting = overdrive_lowerlimits->GfxclkFmax;
-               od_max_setting = overdrive_upperlimits->GfxclkFmax;
+               od_min_setting = overdrive_lowerlimits->GfxclkFoffset;
+               od_max_setting = overdrive_upperlimits->GfxclkFoffset;
                break;
        case PP_OD_FEATURE_UCLK_FMIN:
                od_min_setting = overdrive_lowerlimits->UclkFmin;
@@ -1269,10 +1266,16 @@ static int smu_v14_0_2_print_clk_levels(struct smu_context *smu,
                                                         PP_OD_FEATURE_GFXCLK_BIT))
                        break;
 
-               size += sysfs_emit_at(buf, size, "OD_SCLK:\n");
-               size += sysfs_emit_at(buf, size, "0: %uMhz\n1: %uMhz\n",
-                                       od_table->OverDriveTable.GfxclkFmin,
-                                       od_table->OverDriveTable.GfxclkFmax);
+               PPTable_t *pptable = smu->smu_table.driver_pptable;
+               const OverDriveLimits_t * const overdrive_upperlimits =
+                                       &pptable->SkuTable.OverDriveLimitsBasicMax;
+               const OverDriveLimits_t * const overdrive_lowerlimits =
+                                       &pptable->SkuTable.OverDriveLimitsBasicMin;
+
+               size += sysfs_emit_at(buf, size, "OD_SCLK_OFFSET:\n");
+               size += sysfs_emit_at(buf, size, "0: %dMhz\n1: %uMhz\n",
+                                       overdrive_lowerlimits->GfxclkFoffset,
+                                       overdrive_upperlimits->GfxclkFoffset);
                break;
 
        case SMU_OD_MCLK:
@@ -1414,7 +1417,7 @@ static int smu_v14_0_2_print_clk_levels(struct smu_context *smu,
                                                          PP_OD_FEATURE_GFXCLK_FMAX,
                                                          NULL,
                                                          &max_value);
-                       size += sysfs_emit_at(buf, size, "SCLK: %7uMhz %10uMhz\n",
+                       size += sysfs_emit_at(buf, size, "SCLK_OFFSET: %7dMhz %10uMhz\n",
                                              min_value, max_value);
                }
 
@@ -1796,7 +1799,7 @@ static int smu_v14_0_2_set_power_profile_mode(struct smu_context *smu,
        DpmActivityMonitorCoeffInt_t *activity_monitor =
                &(activity_monitor_external.DpmActivityMonitorCoeffInt);
        int workload_type, ret = 0;
-
+       uint32_t current_profile_mode = smu->power_profile_mode;
        smu->power_profile_mode = input[size];
 
        if (smu->power_profile_mode >= PP_SMC_POWER_PROFILE_COUNT) {
@@ -1854,6 +1857,11 @@ static int smu_v14_0_2_set_power_profile_mode(struct smu_context *smu,
                }
        }
 
+       if (smu->power_profile_mode == PP_SMC_POWER_PROFILE_COMPUTE)
+               smu_v14_0_deep_sleep_control(smu, false);
+       else if (current_profile_mode == PP_SMC_POWER_PROFILE_COMPUTE)
+               smu_v14_0_deep_sleep_control(smu, true);
+
        /* conv PP_SMC_POWER_PROFILE* to WORKLOAD_PPLIB_*_BIT */
        workload_type = smu_cmn_to_asic_specific_index(smu,
                                                       CMN2ASIC_MAPPING_WORKLOAD,
@@ -2158,7 +2166,7 @@ static ssize_t smu_v14_0_2_get_gpu_metrics(struct smu_context *smu,
 
        gpu_metrics->average_gfx_activity = metrics->AverageGfxActivity;
        gpu_metrics->average_umc_activity = metrics->AverageUclkActivity;
-       gpu_metrics->average_mm_activity = max(metrics->Vcn0ActivityPercentage,
+       gpu_metrics->average_mm_activity = max(metrics->AverageVcn0ActivityPercentage,
                                               metrics->Vcn1ActivityPercentage);
 
        gpu_metrics->average_socket_power = metrics->AverageSocketPower;
@@ -2217,8 +2225,7 @@ static void smu_v14_0_2_dump_od_table(struct smu_context *smu,
 {
        struct amdgpu_device *adev = smu->adev;
 
-       dev_dbg(adev->dev, "OD: Gfxclk: (%d, %d)\n", od_table->OverDriveTable.GfxclkFmin,
-                                                    od_table->OverDriveTable.GfxclkFmax);
+       dev_dbg(adev->dev, "OD: Gfxclk offset: (%d)\n", od_table->OverDriveTable.GfxclkFoffset);
        dev_dbg(adev->dev, "OD: Uclk: (%d, %d)\n", od_table->OverDriveTable.UclkFmin,
                                                   od_table->OverDriveTable.UclkFmax);
 }
@@ -2309,10 +2316,8 @@ static int smu_v14_0_2_set_default_od_settings(struct smu_context *smu)
                memcpy(user_od_table,
                       boot_od_table,
                       sizeof(OverDriveTableExternal_t));
-               user_od_table->OverDriveTable.GfxclkFmin =
-                               user_od_table_bak.OverDriveTable.GfxclkFmin;
-               user_od_table->OverDriveTable.GfxclkFmax =
-                               user_od_table_bak.OverDriveTable.GfxclkFmax;
+               user_od_table->OverDriveTable.GfxclkFoffset =
+                               user_od_table_bak.OverDriveTable.GfxclkFoffset;
                user_od_table->OverDriveTable.UclkFmin =
                                user_od_table_bak.OverDriveTable.UclkFmin;
                user_od_table->OverDriveTable.UclkFmax =
@@ -2441,22 +2446,6 @@ static int smu_v14_0_2_od_edit_dpm_table(struct smu_context *smu,
                        }
 
                        switch (input[i]) {
-                       case 0:
-                               smu_v14_0_2_get_od_setting_limits(smu,
-                                                                 PP_OD_FEATURE_GFXCLK_FMIN,
-                                                                 &minimum,
-                                                                 &maximum);
-                               if (input[i + 1] < minimum ||
-                                   input[i + 1] > maximum) {
-                                       dev_info(adev->dev, "GfxclkFmin (%ld) must be within [%u, %u]!\n",
-                                               input[i + 1], minimum, maximum);
-                                       return -EINVAL;
-                               }
-
-                               od_table->OverDriveTable.GfxclkFmin = input[i + 1];
-                               od_table->OverDriveTable.FeatureCtrlMask |= 1U << PP_OD_FEATURE_GFXCLK_BIT;
-                               break;
-
                        case 1:
                                smu_v14_0_2_get_od_setting_limits(smu,
                                                                  PP_OD_FEATURE_GFXCLK_FMAX,
@@ -2469,7 +2458,7 @@ static int smu_v14_0_2_od_edit_dpm_table(struct smu_context *smu,
                                        return -EINVAL;
                                }
 
-                               od_table->OverDriveTable.GfxclkFmax = input[i + 1];
+                               od_table->OverDriveTable.GfxclkFoffset = input[i + 1];
                                od_table->OverDriveTable.FeatureCtrlMask |= 1U << PP_OD_FEATURE_GFXCLK_BIT;
                                break;
 
@@ -2480,13 +2469,6 @@ static int smu_v14_0_2_od_edit_dpm_table(struct smu_context *smu,
                        }
                }
 
-               if (od_table->OverDriveTable.GfxclkFmin > od_table->OverDriveTable.GfxclkFmax) {
-                       dev_err(adev->dev,
-                               "Invalid setting: GfxclkFmin(%u) is bigger than GfxclkFmax(%u)\n",
-                               (uint32_t)od_table->OverDriveTable.GfxclkFmin,
-                               (uint32_t)od_table->OverDriveTable.GfxclkFmax);
-                       return -EINVAL;
-               }
                break;
 
        case PP_OD_EDIT_MCLK_VDDC_TABLE:
index 496c7120e515536cae3496554e89bf7f7e8731d9..c231389936bdab181767e253b13e02e6f8a099de 100644 (file)
@@ -29,6 +29,8 @@ static int ast_sil164_connector_helper_get_modes(struct drm_connector *connector
        if (ast_connector->physical_status == connector_status_connected) {
                count = drm_connector_helper_get_modes(connector);
        } else {
+               drm_edid_connector_update(connector, NULL);
+
                /*
                 * There's no EDID data without a connected monitor. Set BMC-
                 * compatible modes in this case. The XGA default resolution
index 3e815da43fbd638067016621eadb67118a0dabb6..dd389a0a8f4a2171dc858a20e8be50b44c714e9c 100644 (file)
@@ -29,6 +29,8 @@ static int ast_vga_connector_helper_get_modes(struct drm_connector *connector)
        if (ast_connector->physical_status == connector_status_connected) {
                count = drm_connector_helper_get_modes(connector);
        } else {
+               drm_edid_connector_update(connector, NULL);
+
                /*
                 * There's no EDID data without a connected monitor. Set BMC-
                 * compatible modes in this case. The XGA default resolution
index b29980f95379ec7af873ed6e0fb79a9abb663c7b..295e9d031e2dc86cbfd2a7350718fca181c99487 100644 (file)
@@ -58,9 +58,10 @@ int drm_aux_bridge_register(struct device *parent)
        adev->id = ret;
        adev->name = "aux_bridge";
        adev->dev.parent = parent;
-       adev->dev.of_node = of_node_get(parent->of_node);
        adev->dev.release = drm_aux_bridge_release;
 
+       device_set_of_node_from_dev(&adev->dev, parent);
+
        ret = auxiliary_device_init(adev);
        if (ret) {
                ida_free(&drm_aux_bridge_ida, adev->id);
index dee640ab1d3ad5b3550fcee9caa385c3bbc75dd5..41f72d458487fb27a34f2fa475c51de55725bc23 100644 (file)
@@ -47,7 +47,7 @@
 #include <drm/drm_print.h>
 #include <drm/drm_probe_helper.h>
 
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #include "cdns-mhdp8546-core.h"
 #include "cdns-mhdp8546-hdcp.h"
index 5e3b8edcf79487a4cd9c22a7dd9ef053cf739268..31832ba4017f1a8489c7dd653aa259be02e3183d 100644 (file)
@@ -9,7 +9,7 @@
 #include <linux/io.h>
 #include <linux/iopoll.h>
 
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #include <drm/display/drm_hdcp_helper.h>
 
index e7e53a9e42afbd21be9420afefbb0fe1a33a086c..430f8adebf9c44198dfb5facd1727cfa20228e1d 100644 (file)
@@ -10,7 +10,7 @@
  * Tomasz Figa <[email protected]>
  */
 
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #include <linux/clk.h>
 #include <linux/delay.h>
index 6bb755e9f0a5397c53de2e2a0bfa618479c21c40..26b8d137bce096c7c848785da414e26dfa8d4945 100644 (file)
@@ -6,7 +6,7 @@
  * Andrzej Hajda <[email protected]>
  */
 
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #include <drm/bridge/mhl.h>
 #include <drm/drm_bridge.h>
index 290e2532fab19125aeb2cdf45b6bb013ae800af3..f3afdab55c113e046a773d3024b718eb0472d007 100644 (file)
@@ -2391,6 +2391,7 @@ static int tc_probe_bridge_endpoint(struct tc_data *tc)
                        if (tc->pre_emphasis[0] < 0 || tc->pre_emphasis[0] > 2 ||
                            tc->pre_emphasis[1] < 0 || tc->pre_emphasis[1] > 2) {
                                dev_err(dev, "Incorrect Pre-Emphasis setting, use either 0=0dB 1=3.5dB 2=6dB\n");
+                               of_node_put(node);
                                return -EINVAL;
                        }
                }
index 3b7cc3be2ccdbea1542a08580677fad13f4368f0..0b4efaca6d682320b76ce09ed41824ae7f84ca2d 100644 (file)
@@ -19,7 +19,7 @@
 #include <linux/regulator/consumer.h>
 #include <linux/slab.h>
 
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #include <drm/display/drm_dp_helper.h>
 #include <drm/drm_atomic_helper.h>
index 84698a0b27a8eec3177a43108e93d15394c9b89e..582cf4f73a74c78f43522e34ea5a67f4dff67e55 100644 (file)
@@ -21,7 +21,7 @@
 #include <linux/regmap.h>
 #include <linux/regulator/consumer.h>
 
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #include <drm/display/drm_dp_aux_bus.h>
 #include <drm/display/drm_dp_helper.h>
index a040d7dfced1793d23dc6e3ec78e1c4f7dd899e6..ac90118b9e7a81f2de9e2e0615b298cdba6e0499 100644 (file)
@@ -6083,6 +6083,7 @@ struct drm_dp_aux *drm_dp_mst_dsc_aux_for_port(struct drm_dp_mst_port *port)
        struct drm_dp_aux *immediate_upstream_aux;
        struct drm_dp_mst_port *fec_port;
        struct drm_dp_desc desc = {};
+       u8 upstream_dsc;
        u8 endpoint_fec;
        u8 endpoint_dsc;
 
@@ -6109,8 +6110,6 @@ struct drm_dp_aux *drm_dp_mst_dsc_aux_for_port(struct drm_dp_mst_port *port)
 
        /* DP-to-DP peer device */
        if (drm_dp_mst_is_virtual_dpcd(immediate_upstream_port)) {
-               u8 upstream_dsc;
-
                if (drm_dp_dpcd_read(&port->aux,
                                     DP_DSC_SUPPORT, &endpoint_dsc, 1) != 1)
                        return NULL;
@@ -6156,6 +6155,13 @@ struct drm_dp_aux *drm_dp_mst_dsc_aux_for_port(struct drm_dp_mst_port *port)
        if (drm_dp_has_quirk(&desc, DP_DPCD_QUIRK_DSC_WITHOUT_VIRTUAL_DPCD)) {
                u8 dpcd_ext[DP_RECEIVER_CAP_SIZE];
 
+               if (drm_dp_dpcd_read(immediate_upstream_aux,
+                                    DP_DSC_SUPPORT, &upstream_dsc, 1) != 1)
+                       return NULL;
+
+               if (!(upstream_dsc & DP_DSC_DECOMPRESSION_IS_SUPPORTED))
+                       return NULL;
+
                if (drm_dp_read_dpcd_caps(immediate_upstream_aux, dpcd_ext) < 0)
                        return NULL;
 
index 7854820089ec6eb9c969954d8438d5393360c898..feb7a3a759811aed70c679be8704072093e2a79b 100644 (file)
@@ -521,8 +521,6 @@ int drm_atomic_helper_connector_hdmi_check(struct drm_connector *connector,
 }
 EXPORT_SYMBOL(drm_atomic_helper_connector_hdmi_check);
 
-#define HDMI_MAX_INFOFRAME_SIZE                29
-
 static int clear_device_infoframe(struct drm_connector *connector,
                                  enum hdmi_infoframe_type type)
 {
@@ -563,7 +561,7 @@ static int write_device_infoframe(struct drm_connector *connector,
 {
        const struct drm_connector_hdmi_funcs *funcs = connector->hdmi.funcs;
        struct drm_device *dev = connector->dev;
-       u8 buffer[HDMI_MAX_INFOFRAME_SIZE];
+       u8 buffer[HDMI_INFOFRAME_SIZE(MAX)];
        int ret;
        int len;
 
index 7936c20239551817bc8236ef6c1f65606084a39d..370dc676e3aa543c9827b50df20df78f02b738c9 100644 (file)
@@ -543,7 +543,7 @@ static int drm_atomic_plane_set_property(struct drm_plane *plane,
                                        &state->fb_damage_clips,
                                        val,
                                        -1,
-                                       sizeof(struct drm_rect),
+                                       sizeof(struct drm_mode_rect),
                                        &replaced);
                return ret;
        } else if (property == plane->scaling_filter_property) {
index 6b239a24f1dff3538ea74551d412ac34862b34bf..9d3e6dd68810e32c77e708590bc5ec8383f9ee11 100644 (file)
@@ -520,8 +520,6 @@ static const struct file_operations drm_connector_fops = {
        .write = connector_write
 };
 
-#define HDMI_MAX_INFOFRAME_SIZE                29
-
 static ssize_t
 audio_infoframe_read(struct file *filp, char __user *ubuf, size_t count, loff_t *ppos)
 {
@@ -579,7 +577,7 @@ static ssize_t _f##_read_infoframe(struct file *filp, \
        struct drm_connector *connector; \
        union hdmi_infoframe *frame; \
        struct drm_device *dev; \
-       u8 buf[HDMI_MAX_INFOFRAME_SIZE]; \
+       u8 buf[HDMI_INFOFRAME_SIZE(MAX)]; \
        ssize_t len = 0; \
        \
        connector = filp->private_data; \
index b0602c4f3628305cc1261741142899446bdae44a..51c2d742d19980c98231b71df5ab3e523893942c 100644 (file)
@@ -50,7 +50,8 @@ static void drm_fbdev_dma_fb_destroy(struct fb_info *info)
        if (!fb_helper->dev)
                return;
 
-       fb_deferred_io_cleanup(info);
+       if (info->fbdefio)
+               fb_deferred_io_cleanup(info);
        drm_fb_helper_fini(fb_helper);
 
        drm_client_buffer_vunmap(fb_helper->buffer);
index faa253b2766428b16f4592f0e74e05d70a014a76..14ac351fd76dbfcd08b8e5e283fc696d8d6a3112 100644 (file)
@@ -123,9 +123,8 @@ config DRM_I915_USERPTR
 config DRM_I915_GVT_KVMGT
        tristate "Enable KVM host support Intel GVT-g graphics virtualization"
        depends on DRM_I915
-       depends on X86
+       depends on KVM_X86
        depends on 64BIT
-       depends on KVM
        depends on VFIO
        select DRM_I915_GVT
        select KVM_EXTERNAL_WRITE_TRACKING
index 15541932b809e878611b123d2eaf90481d3a7f00..eeaedd979354b82d1dd3b66530ce541ae1a1c249 100644 (file)
@@ -89,25 +89,19 @@ static int intel_dp_mst_max_dpt_bpp(const struct intel_crtc_state *crtc_state,
 
 static int intel_dp_mst_bw_overhead(const struct intel_crtc_state *crtc_state,
                                    const struct intel_connector *connector,
-                                   bool ssc, bool dsc, int bpp_x16)
+                                   bool ssc, int dsc_slice_count, int bpp_x16)
 {
        const struct drm_display_mode *adjusted_mode =
                &crtc_state->hw.adjusted_mode;
        unsigned long flags = DRM_DP_BW_OVERHEAD_MST;
-       int dsc_slice_count = 0;
        int overhead;
 
        flags |= intel_dp_is_uhbr(crtc_state) ? DRM_DP_BW_OVERHEAD_UHBR : 0;
        flags |= ssc ? DRM_DP_BW_OVERHEAD_SSC_REF_CLK : 0;
        flags |= crtc_state->fec_enable ? DRM_DP_BW_OVERHEAD_FEC : 0;
 
-       if (dsc) {
+       if (dsc_slice_count)
                flags |= DRM_DP_BW_OVERHEAD_DSC;
-               dsc_slice_count = intel_dp_dsc_get_slice_count(connector,
-                                                              adjusted_mode->clock,
-                                                              adjusted_mode->hdisplay,
-                                                              crtc_state->joiner_pipes);
-       }
 
        overhead = drm_dp_bw_overhead(crtc_state->lane_count,
                                      adjusted_mode->hdisplay,
@@ -153,6 +147,19 @@ static int intel_dp_mst_calc_pbn(int pixel_clock, int bpp_x16, int bw_overhead)
        return DIV_ROUND_UP(effective_data_rate * 64, 54 * 1000);
 }
 
+static int intel_dp_mst_dsc_get_slice_count(const struct intel_connector *connector,
+                                           const struct intel_crtc_state *crtc_state)
+{
+       const struct drm_display_mode *adjusted_mode =
+               &crtc_state->hw.adjusted_mode;
+       int num_joined_pipes = crtc_state->joiner_pipes;
+
+       return intel_dp_dsc_get_slice_count(connector,
+                                           adjusted_mode->clock,
+                                           adjusted_mode->hdisplay,
+                                           num_joined_pipes);
+}
+
 static int intel_dp_mst_find_vcpi_slots_for_bpp(struct intel_encoder *encoder,
                                                struct intel_crtc_state *crtc_state,
                                                int max_bpp,
@@ -172,6 +179,7 @@ static int intel_dp_mst_find_vcpi_slots_for_bpp(struct intel_encoder *encoder,
        const struct drm_display_mode *adjusted_mode =
                &crtc_state->hw.adjusted_mode;
        int bpp, slots = -EINVAL;
+       int dsc_slice_count = 0;
        int max_dpt_bpp;
        int ret = 0;
 
@@ -203,6 +211,15 @@ static int intel_dp_mst_find_vcpi_slots_for_bpp(struct intel_encoder *encoder,
        drm_dbg_kms(&i915->drm, "Looking for slots in range min bpp %d max bpp %d\n",
                    min_bpp, max_bpp);
 
+       if (dsc) {
+               dsc_slice_count = intel_dp_mst_dsc_get_slice_count(connector, crtc_state);
+               if (!dsc_slice_count) {
+                       drm_dbg_kms(&i915->drm, "Can't get valid DSC slice count\n");
+
+                       return -ENOSPC;
+               }
+       }
+
        for (bpp = max_bpp; bpp >= min_bpp; bpp -= step) {
                int local_bw_overhead;
                int remote_bw_overhead;
@@ -216,9 +233,9 @@ static int intel_dp_mst_find_vcpi_slots_for_bpp(struct intel_encoder *encoder,
                                               intel_dp_output_bpp(crtc_state->output_format, bpp));
 
                local_bw_overhead = intel_dp_mst_bw_overhead(crtc_state, connector,
-                                                            false, dsc, link_bpp_x16);
+                                                            false, dsc_slice_count, link_bpp_x16);
                remote_bw_overhead = intel_dp_mst_bw_overhead(crtc_state, connector,
-                                                             true, dsc, link_bpp_x16);
+                                                             true, dsc_slice_count, link_bpp_x16);
 
                intel_dp_mst_compute_m_n(crtc_state, connector,
                                         local_bw_overhead,
@@ -449,6 +466,9 @@ hblank_expansion_quirk_needs_dsc(const struct intel_connector *connector,
        if (mode_hblank_period_ns(adjusted_mode) > hblank_limit)
                return false;
 
+       if (!intel_dp_mst_dsc_get_slice_count(connector, crtc_state))
+               return false;
+
        return true;
 }
 
index d8951464bd2b56bf3d27c1bf4bcde6d85ce70030..f0e3be0fe42082a835f619c22ee62b78d7a0ec38 100644 (file)
@@ -32,7 +32,7 @@
 #include <linux/slab.h>
 #include <linux/string_helpers.h>
 
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #include <drm/drm_crtc.h>
 #include <drm/drm_edid.h>
index 5be7bb43e2e0d0ea2646df162f440d3443c67ed5..35557d98d7a700b58dfe137948a1acbf468e3136 100644 (file)
@@ -438,6 +438,19 @@ bool intel_fb_needs_64k_phys(u64 modifier)
                                      INTEL_PLANE_CAP_NEED64K_PHYS);
 }
 
+/**
+ * intel_fb_is_tile4_modifier: Check if a modifier is a tile4 modifier type
+ * @modifier: Modifier to check
+ *
+ * Returns:
+ * Returns %true if @modifier is a tile4 modifier.
+ */
+bool intel_fb_is_tile4_modifier(u64 modifier)
+{
+       return plane_caps_contain_any(lookup_modifier(modifier)->plane_caps,
+                                     INTEL_PLANE_CAP_TILING_4);
+}
+
 static bool check_modifier_display_ver_range(const struct intel_modifier_desc *md,
                                             u8 display_ver_from, u8 display_ver_until)
 {
index 10de437e8ef845eab444fb2bbcdb201ee1a9fee5..827be3f7934cb4596ef0e95b2398648e9e1a1f9b 100644 (file)
@@ -35,6 +35,7 @@ bool intel_fb_is_ccs_modifier(u64 modifier);
 bool intel_fb_is_rc_ccs_cc_modifier(u64 modifier);
 bool intel_fb_is_mc_ccs_modifier(u64 modifier);
 bool intel_fb_needs_64k_phys(u64 modifier);
+bool intel_fb_is_tile4_modifier(u64 modifier);
 
 bool intel_fb_is_ccs_aux_plane(const struct drm_framebuffer *fb, int color_plane);
 int intel_fb_rc_ccs_cc_plane(const struct drm_framebuffer *fb);
index 6980b98792c212fe0ebcf58c6c025a843ef33c2d..377939de0ff4f2e230691b62b2f363507010044c 100644 (file)
@@ -1094,7 +1094,8 @@ static void intel_hdcp_update_value(struct intel_connector *connector,
        hdcp->value = value;
        if (update_property) {
                drm_connector_get(&connector->base);
-               queue_work(i915->unordered_wq, &hdcp->prop_work);
+               if (!queue_work(i915->unordered_wq, &hdcp->prop_work))
+                       drm_connector_put(&connector->base);
        }
 }
 
@@ -2524,7 +2525,8 @@ void intel_hdcp_update_pipe(struct intel_atomic_state *state,
                mutex_lock(&hdcp->mutex);
                hdcp->value = DRM_MODE_CONTENT_PROTECTION_DESIRED;
                drm_connector_get(&connector->base);
-               queue_work(i915->unordered_wq, &hdcp->prop_work);
+               if (!queue_work(i915->unordered_wq, &hdcp->prop_work))
+                       drm_connector_put(&connector->base);
                mutex_unlock(&hdcp->mutex);
        }
 
@@ -2541,7 +2543,9 @@ void intel_hdcp_update_pipe(struct intel_atomic_state *state,
                 */
                if (!desired_and_not_enabled && !content_protection_type_changed) {
                        drm_connector_get(&connector->base);
-                       queue_work(i915->unordered_wq, &hdcp->prop_work);
+                       if (!queue_work(i915->unordered_wq, &hdcp->prop_work))
+                               drm_connector_put(&connector->base);
+
                }
        }
 
index 17d4c880ecc402a9aca80355c09bc49295c1862a..c8720d31d1013d8a1db5a2c7091cd8d06238a7d7 100644 (file)
@@ -1591,6 +1591,17 @@ static int skl_plane_check_fb(const struct intel_crtc_state *crtc_state,
                return -EINVAL;
        }
 
+       /*
+        * Display20 onward tile4 hflip is not supported
+        */
+       if (rotation & DRM_MODE_REFLECT_X &&
+           intel_fb_is_tile4_modifier(fb->modifier) &&
+           DISPLAY_VER(dev_priv) >= 20) {
+               drm_dbg_kms(&dev_priv->drm,
+                           "horizontal flip is not supported with tile4 surface formats\n");
+               return -EINVAL;
+       }
+
        if (drm_rotation_90_or_270(rotation)) {
                if (!intel_fb_supports_90_270_rotation(to_intel_framebuffer(fb))) {
                        drm_dbg_kms(&dev_priv->drm,
index 5c72462d1f57e3625f3b8271524a6e3f3f718012..b22e2019768f047bee965a4570f3b8aea712f318 100644 (file)
@@ -1131,7 +1131,7 @@ static vm_fault_t vm_fault_ttm(struct vm_fault *vmf)
                GEM_WARN_ON(!i915_ttm_cpu_maps_iomem(bo->resource));
        }
 
-       if (wakeref & CONFIG_DRM_I915_USERFAULT_AUTOSUSPEND)
+       if (wakeref && CONFIG_DRM_I915_USERFAULT_AUTOSUSPEND != 0)
                intel_wakeref_auto(&to_i915(obj->base.dev)->runtime_pm.userfault_wakeref,
                                   msecs_to_jiffies_timeout(CONFIG_DRM_I915_USERFAULT_AUTOSUSPEND));
 
index 175b00e5a25354c890d5617912a7b3af0ac96ddc..eb0e1233ad0435a372fffce25c1c365fec6f211d 100644 (file)
@@ -127,9 +127,8 @@ static void mtk_crtc_destroy(struct drm_crtc *crtc)
 
        mtk_mutex_put(mtk_crtc->mutex);
 #if IS_REACHABLE(CONFIG_MTK_CMDQ)
-       cmdq_pkt_destroy(&mtk_crtc->cmdq_client, &mtk_crtc->cmdq_handle);
-
        if (mtk_crtc->cmdq_client.chan) {
+               cmdq_pkt_destroy(&mtk_crtc->cmdq_client, &mtk_crtc->cmdq_handle);
                mbox_free_channel(mtk_crtc->cmdq_client.chan);
                mtk_crtc->cmdq_client.chan = NULL;
        }
@@ -913,6 +912,7 @@ static int mtk_crtc_init_comp_planes(struct drm_device *drm_dev,
                                BIT(pipe),
                                mtk_crtc_plane_type(mtk_crtc->layer_nr, num_planes),
                                mtk_ddp_comp_supported_rotations(comp),
+                               mtk_ddp_comp_get_blend_modes(comp),
                                mtk_ddp_comp_get_formats(comp),
                                mtk_ddp_comp_get_num_formats(comp), i);
                if (ret)
index be66d94be361394993d0d72df8799034dba1eb4c..edc6417639e64286e809cc28b4a959a895a38fb6 100644 (file)
@@ -363,6 +363,7 @@ static const struct mtk_ddp_comp_funcs ddp_ovl = {
        .layer_config = mtk_ovl_layer_config,
        .bgclr_in_on = mtk_ovl_bgclr_in_on,
        .bgclr_in_off = mtk_ovl_bgclr_in_off,
+       .get_blend_modes = mtk_ovl_get_blend_modes,
        .get_formats = mtk_ovl_get_formats,
        .get_num_formats = mtk_ovl_get_num_formats,
 };
@@ -416,6 +417,7 @@ static const struct mtk_ddp_comp_funcs ddp_ovl_adaptor = {
        .disconnect = mtk_ovl_adaptor_disconnect,
        .add = mtk_ovl_adaptor_add_comp,
        .remove = mtk_ovl_adaptor_remove_comp,
+       .get_blend_modes = mtk_ovl_adaptor_get_blend_modes,
        .get_formats = mtk_ovl_adaptor_get_formats,
        .get_num_formats = mtk_ovl_adaptor_get_num_formats,
        .mode_valid = mtk_ovl_adaptor_mode_valid,
index ecf6dc283cd7c1079582ef07dde293c2aeda017a..39720b27f4e9eda8e4f3c31020d6ec7124638017 100644 (file)
@@ -80,6 +80,7 @@ struct mtk_ddp_comp_funcs {
        void (*ctm_set)(struct device *dev,
                        struct drm_crtc_state *state);
        struct device * (*dma_dev_get)(struct device *dev);
+       u32 (*get_blend_modes)(struct device *dev);
        const u32 *(*get_formats)(struct device *dev);
        size_t (*get_num_formats)(struct device *dev);
        void (*connect)(struct device *dev, struct device *mmsys_dev, unsigned int next);
@@ -266,6 +267,15 @@ static inline struct device *mtk_ddp_comp_dma_dev_get(struct mtk_ddp_comp *comp)
        return comp->dev;
 }
 
+static inline
+u32 mtk_ddp_comp_get_blend_modes(struct mtk_ddp_comp *comp)
+{
+       if (comp->funcs && comp->funcs->get_blend_modes)
+               return comp->funcs->get_blend_modes(comp->dev);
+
+       return 0;
+}
+
 static inline
 const u32 *mtk_ddp_comp_get_formats(struct mtk_ddp_comp *comp)
 {
index 082ac18fe04aab331fcabf4e4d3877a58f9261f2..04154db9085c08a27c05c79b53346000cf8ac476 100644 (file)
@@ -103,6 +103,7 @@ void mtk_ovl_register_vblank_cb(struct device *dev,
 void mtk_ovl_unregister_vblank_cb(struct device *dev);
 void mtk_ovl_enable_vblank(struct device *dev);
 void mtk_ovl_disable_vblank(struct device *dev);
+u32 mtk_ovl_get_blend_modes(struct device *dev);
 const u32 *mtk_ovl_get_formats(struct device *dev);
 size_t mtk_ovl_get_num_formats(struct device *dev);
 
@@ -131,6 +132,7 @@ void mtk_ovl_adaptor_start(struct device *dev);
 void mtk_ovl_adaptor_stop(struct device *dev);
 unsigned int mtk_ovl_adaptor_layer_nr(struct device *dev);
 struct device *mtk_ovl_adaptor_dma_dev_get(struct device *dev);
+u32 mtk_ovl_adaptor_get_blend_modes(struct device *dev);
 const u32 *mtk_ovl_adaptor_get_formats(struct device *dev);
 size_t mtk_ovl_adaptor_get_num_formats(struct device *dev);
 enum drm_mode_status mtk_ovl_adaptor_mode_valid(struct device *dev,
index 89b439dcf3a6af9f5799487fdc0f128a9b5cbe4a..e0c0bb01f65ae006828a9a94e945dac62c56763c 100644 (file)
@@ -65,8 +65,8 @@
 #define OVL_CON_CLRFMT_RGB     (1 << 12)
 #define OVL_CON_CLRFMT_ARGB8888        (2 << 12)
 #define OVL_CON_CLRFMT_RGBA8888        (3 << 12)
-#define OVL_CON_CLRFMT_ABGR8888        (OVL_CON_CLRFMT_RGBA8888 | OVL_CON_BYTE_SWAP)
-#define OVL_CON_CLRFMT_BGRA8888        (OVL_CON_CLRFMT_ARGB8888 | OVL_CON_BYTE_SWAP)
+#define OVL_CON_CLRFMT_ABGR8888        (OVL_CON_CLRFMT_ARGB8888 | OVL_CON_BYTE_SWAP)
+#define OVL_CON_CLRFMT_BGRA8888        (OVL_CON_CLRFMT_RGBA8888 | OVL_CON_BYTE_SWAP)
 #define OVL_CON_CLRFMT_UYVY    (4 << 12)
 #define OVL_CON_CLRFMT_YUYV    (5 << 12)
 #define OVL_CON_MTX_YUV_TO_RGB (6 << 16)
@@ -146,6 +146,7 @@ struct mtk_disp_ovl_data {
        bool fmt_rgb565_is_0;
        bool smi_id_en;
        bool supports_afbc;
+       const u32 blend_modes;
        const u32 *formats;
        size_t num_formats;
        bool supports_clrfmt_ext;
@@ -214,6 +215,13 @@ void mtk_ovl_disable_vblank(struct device *dev)
        writel_relaxed(0x0, ovl->regs + DISP_REG_OVL_INTEN);
 }
 
+u32 mtk_ovl_get_blend_modes(struct device *dev)
+{
+       struct mtk_disp_ovl *ovl = dev_get_drvdata(dev);
+
+       return ovl->data->blend_modes;
+}
+
 const u32 *mtk_ovl_get_formats(struct device *dev)
 {
        struct mtk_disp_ovl *ovl = dev_get_drvdata(dev);
@@ -386,14 +394,27 @@ void mtk_ovl_layer_off(struct device *dev, unsigned int idx,
                      DISP_REG_OVL_RDMA_CTRL(idx));
 }
 
-static unsigned int ovl_fmt_convert(struct mtk_disp_ovl *ovl, unsigned int fmt,
-                                   unsigned int blend_mode)
+static unsigned int mtk_ovl_fmt_convert(struct mtk_disp_ovl *ovl,
+                                       struct mtk_plane_state *state)
 {
-       /* The return value in switch "MEM_MODE_INPUT_FORMAT_XXX"
-        * is defined in mediatek HW data sheet.
-        * The alphabet order in XXX is no relation to data
-        * arrangement in memory.
+       unsigned int fmt = state->pending.format;
+       unsigned int blend_mode = DRM_MODE_BLEND_COVERAGE;
+
+       /*
+        * For the platforms where OVL_CON_CLRFMT_MAN is defined in the hardware data sheet
+        * and supports premultiplied color formats, such as OVL_CON_CLRFMT_PARGB8888.
+        *
+        * Check blend_modes in the driver data to see if premultiplied mode is supported.
+        * If not, use coverage mode instead to set it to the supported color formats.
+        *
+        * Current DRM assumption is that alpha is default premultiplied, so the bitmask of
+        * blend_modes must include BIT(DRM_MODE_BLEND_PREMULTI). Otherwise, mtk_plane_init()
+        * will get an error return from drm_plane_create_blend_mode_property() and
+        * state->base.pixel_blend_mode should not be used.
         */
+       if (ovl->data->blend_modes & BIT(DRM_MODE_BLEND_PREMULTI))
+               blend_mode = state->base.pixel_blend_mode;
+
        switch (fmt) {
        default:
        case DRM_FORMAT_RGB565:
@@ -471,20 +492,26 @@ void mtk_ovl_layer_config(struct device *dev, unsigned int idx,
                return;
        }
 
-       con = ovl_fmt_convert(ovl, fmt, blend_mode);
+       con = mtk_ovl_fmt_convert(ovl, state);
        if (state->base.fb) {
-               con |= OVL_CON_AEN;
                con |= state->base.alpha & OVL_CON_ALPHA;
-       }
 
-       /* CONST_BLD must be enabled for XRGB formats although the alpha channel
-        * can be ignored, or OVL will still read the value from memory.
-        * For RGB888 related formats, whether CONST_BLD is enabled or not won't
-        * affect the result. Therefore we use !has_alpha as the condition.
-        */
-       if ((state->base.fb && !state->base.fb->format->has_alpha) ||
-           blend_mode == DRM_MODE_BLEND_PIXEL_NONE)
-               ignore_pixel_alpha = OVL_CONST_BLEND;
+               /*
+                * For blend_modes supported SoCs, always enable alpha blending.
+                * For blend_modes unsupported SoCs, enable alpha blending when has_alpha is set.
+                */
+               if (blend_mode || state->base.fb->format->has_alpha)
+                       con |= OVL_CON_AEN;
+
+               /*
+                * Although the alpha channel can be ignored, CONST_BLD must be enabled
+                * for XRGB format, otherwise OVL will still read the value from memory.
+                * For RGB888 related formats, whether CONST_BLD is enabled or not won't
+                * affect the result. Therefore we use !has_alpha as the condition.
+                */
+               if (blend_mode == DRM_MODE_BLEND_PIXEL_NONE || !state->base.fb->format->has_alpha)
+                       ignore_pixel_alpha = OVL_CONST_BLEND;
+       }
 
        if (pending->rotation & DRM_MODE_REFLECT_Y) {
                con |= OVL_CON_VIRT_FLIP;
@@ -663,6 +690,9 @@ static const struct mtk_disp_ovl_data mt8192_ovl_driver_data = {
        .layer_nr = 4,
        .fmt_rgb565_is_0 = true,
        .smi_id_en = true,
+       .blend_modes = BIT(DRM_MODE_BLEND_PREMULTI) |
+                      BIT(DRM_MODE_BLEND_COVERAGE) |
+                      BIT(DRM_MODE_BLEND_PIXEL_NONE),
        .formats = mt8173_formats,
        .num_formats = ARRAY_SIZE(mt8173_formats),
 };
@@ -673,6 +703,9 @@ static const struct mtk_disp_ovl_data mt8192_ovl_2l_driver_data = {
        .layer_nr = 2,
        .fmt_rgb565_is_0 = true,
        .smi_id_en = true,
+       .blend_modes = BIT(DRM_MODE_BLEND_PREMULTI) |
+                      BIT(DRM_MODE_BLEND_COVERAGE) |
+                      BIT(DRM_MODE_BLEND_PIXEL_NONE),
        .formats = mt8173_formats,
        .num_formats = ARRAY_SIZE(mt8173_formats),
 };
@@ -684,6 +717,9 @@ static const struct mtk_disp_ovl_data mt8195_ovl_driver_data = {
        .fmt_rgb565_is_0 = true,
        .smi_id_en = true,
        .supports_afbc = true,
+       .blend_modes = BIT(DRM_MODE_BLEND_PREMULTI) |
+                      BIT(DRM_MODE_BLEND_COVERAGE) |
+                      BIT(DRM_MODE_BLEND_PIXEL_NONE),
        .formats = mt8195_formats,
        .num_formats = ARRAY_SIZE(mt8195_formats),
        .supports_clrfmt_ext = true,
index c6768210b08b87414c9ab270af0f0a5837e7a783..bf2546c4681a15a20d85bd6a01323cea80aa53ef 100644 (file)
@@ -400,6 +400,13 @@ void mtk_ovl_adaptor_disable_vblank(struct device *dev)
        mtk_ethdr_disable_vblank(ovl_adaptor->ovl_adaptor_comp[OVL_ADAPTOR_ETHDR0]);
 }
 
+u32 mtk_ovl_adaptor_get_blend_modes(struct device *dev)
+{
+       struct mtk_disp_ovl_adaptor *ovl_adaptor = dev_get_drvdata(dev);
+
+       return mtk_ethdr_get_blend_modes(ovl_adaptor->ovl_adaptor_comp[OVL_ADAPTOR_ETHDR0]);
+}
+
 const u32 *mtk_ovl_adaptor_get_formats(struct device *dev)
 {
        struct mtk_disp_ovl_adaptor *ovl_adaptor = dev_get_drvdata(dev);
index d8796a904eca4ddff5a98bf7fa368ec4018808e9..f2bee617f063a7b5839b9e5102a133234d77457a 100644 (file)
@@ -145,6 +145,89 @@ struct mtk_dp_data {
        u16 audio_m_div2_bit;
 };
 
+static const struct mtk_dp_efuse_fmt mt8188_dp_efuse_fmt[MTK_DP_CAL_MAX] = {
+       [MTK_DP_CAL_GLB_BIAS_TRIM] = {
+               .idx = 0,
+               .shift = 10,
+               .mask = 0x1f,
+               .min_val = 1,
+               .max_val = 0x1e,
+               .default_val = 0xf,
+       },
+       [MTK_DP_CAL_CLKTX_IMPSE] = {
+               .idx = 0,
+               .shift = 15,
+               .mask = 0xf,
+               .min_val = 1,
+               .max_val = 0xe,
+               .default_val = 0x8,
+       },
+       [MTK_DP_CAL_LN_TX_IMPSEL_PMOS_0] = {
+               .idx = 1,
+               .shift = 0,
+               .mask = 0xf,
+               .min_val = 1,
+               .max_val = 0xe,
+               .default_val = 0x8,
+       },
+       [MTK_DP_CAL_LN_TX_IMPSEL_PMOS_1] = {
+               .idx = 1,
+               .shift = 8,
+               .mask = 0xf,
+               .min_val = 1,
+               .max_val = 0xe,
+               .default_val = 0x8,
+       },
+       [MTK_DP_CAL_LN_TX_IMPSEL_PMOS_2] = {
+               .idx = 1,
+               .shift = 16,
+               .mask = 0xf,
+               .min_val = 1,
+               .max_val = 0xe,
+               .default_val = 0x8,
+       },
+       [MTK_DP_CAL_LN_TX_IMPSEL_PMOS_3] = {
+               .idx = 1,
+               .shift = 24,
+               .mask = 0xf,
+               .min_val = 1,
+               .max_val = 0xe,
+               .default_val = 0x8,
+       },
+       [MTK_DP_CAL_LN_TX_IMPSEL_NMOS_0] = {
+               .idx = 1,
+               .shift = 4,
+               .mask = 0xf,
+               .min_val = 1,
+               .max_val = 0xe,
+               .default_val = 0x8,
+       },
+       [MTK_DP_CAL_LN_TX_IMPSEL_NMOS_1] = {
+               .idx = 1,
+               .shift = 12,
+               .mask = 0xf,
+               .min_val = 1,
+               .max_val = 0xe,
+               .default_val = 0x8,
+       },
+       [MTK_DP_CAL_LN_TX_IMPSEL_NMOS_2] = {
+               .idx = 1,
+               .shift = 20,
+               .mask = 0xf,
+               .min_val = 1,
+               .max_val = 0xe,
+               .default_val = 0x8,
+       },
+       [MTK_DP_CAL_LN_TX_IMPSEL_NMOS_3] = {
+               .idx = 1,
+               .shift = 28,
+               .mask = 0xf,
+               .min_val = 1,
+               .max_val = 0xe,
+               .default_val = 0x8,
+       },
+};
+
 static const struct mtk_dp_efuse_fmt mt8195_edp_efuse_fmt[MTK_DP_CAL_MAX] = {
        [MTK_DP_CAL_GLB_BIAS_TRIM] = {
                .idx = 3,
@@ -2771,7 +2854,7 @@ static SIMPLE_DEV_PM_OPS(mtk_dp_pm_ops, mtk_dp_suspend, mtk_dp_resume);
 static const struct mtk_dp_data mt8188_dp_data = {
        .bridge_type = DRM_MODE_CONNECTOR_DisplayPort,
        .smc_cmd = MTK_DP_SIP_ATF_VIDEO_UNMUTE,
-       .efuse_fmt = mt8195_dp_efuse_fmt,
+       .efuse_fmt = mt8188_dp_efuse_fmt,
        .audio_supported = true,
        .audio_pkt_in_hblank_area = true,
        .audio_m_div2_bit = MT8188_AUDIO_M_CODE_MULT_DIV_SEL_DP_ENC0_P0_DIV_2,
index d1d9cf8b10e16d0b4db8a9e7e79592128735863e..0f22e7d337cb6779939a12c14e4dd31e5a4f2769 100644 (file)
@@ -145,6 +145,13 @@ static irqreturn_t mtk_ethdr_irq_handler(int irq, void *dev_id)
        return IRQ_HANDLED;
 }
 
+u32 mtk_ethdr_get_blend_modes(struct device *dev)
+{
+       return BIT(DRM_MODE_BLEND_PREMULTI) |
+              BIT(DRM_MODE_BLEND_COVERAGE) |
+              BIT(DRM_MODE_BLEND_PIXEL_NONE);
+}
+
 void mtk_ethdr_layer_config(struct device *dev, unsigned int idx,
                            struct mtk_plane_state *state,
                            struct cmdq_pkt *cmdq_pkt)
index 81af9edea3f7400b15ef7107ba8ec12bb12bd0a5..a72aeee46829ad1ce9ad93a2f5f785848efccd2d 100644 (file)
@@ -13,6 +13,7 @@ void mtk_ethdr_clk_disable(struct device *dev);
 void mtk_ethdr_config(struct device *dev, unsigned int w,
                      unsigned int h, unsigned int vrefresh,
                      unsigned int bpc, struct cmdq_pkt *cmdq_pkt);
+u32 mtk_ethdr_get_blend_modes(struct device *dev);
 void mtk_ethdr_layer_config(struct device *dev, unsigned int idx,
                            struct mtk_plane_state *state,
                            struct cmdq_pkt *cmdq_pkt);
index 7d2cb4e0fafad1e4f31933cbbf83f7de9b954907..8a48b3b0a95676c9823daa2052aefb7f86f629ff 100644 (file)
@@ -320,8 +320,8 @@ static const struct drm_plane_helper_funcs mtk_plane_helper_funcs = {
 
 int mtk_plane_init(struct drm_device *dev, struct drm_plane *plane,
                   unsigned long possible_crtcs, enum drm_plane_type type,
-                  unsigned int supported_rotations, const u32 *formats,
-                  size_t num_formats, unsigned int plane_idx)
+                  unsigned int supported_rotations, const u32 blend_modes,
+                  const u32 *formats, size_t num_formats, unsigned int plane_idx)
 {
        int err;
 
@@ -366,12 +366,11 @@ int mtk_plane_init(struct drm_device *dev, struct drm_plane *plane,
        if (err)
                DRM_ERROR("failed to create property: alpha\n");
 
-       err = drm_plane_create_blend_mode_property(plane,
-                                                  BIT(DRM_MODE_BLEND_PREMULTI) |
-                                                  BIT(DRM_MODE_BLEND_COVERAGE) |
-                                                  BIT(DRM_MODE_BLEND_PIXEL_NONE));
-       if (err)
-               DRM_ERROR("failed to create property: blend_mode\n");
+       if (blend_modes) {
+               err = drm_plane_create_blend_mode_property(plane, blend_modes);
+               if (err)
+                       DRM_ERROR("failed to create property: blend_mode\n");
+       }
 
        drm_plane_helper_add(plane, &mtk_plane_helper_funcs);
 
index 5b177eac67b7aa874229963d02ec3841bea6843d..3b13b89989c7e46449cc37b20283417642ae774d 100644 (file)
@@ -48,6 +48,6 @@ to_mtk_plane_state(struct drm_plane_state *state)
 
 int mtk_plane_init(struct drm_device *dev, struct drm_plane *plane,
                   unsigned long possible_crtcs, enum drm_plane_type type,
-                  unsigned int supported_rotations, const u32 *formats,
-                  size_t num_formats, unsigned int plane_idx);
+                  unsigned int supported_rotations, const u32 blend_modes,
+                  const u32 *formats, size_t num_formats, unsigned int plane_idx);
 #endif
index 6623ee4e3277dfecefdc1fb94f0713aa50192e5c..9f59256936864c0f9997a408f1b6788889576b8e 100644 (file)
@@ -18,7 +18,6 @@
 #include <drm/drm_managed.h>
 #include <drm/drm_module.h>
 #include <drm/drm_pciids.h>
-#include <drm/drm_vblank.h>
 
 #include "mgag200_drv.h"
 
@@ -85,34 +84,6 @@ resource_size_t mgag200_probe_vram(void __iomem *mem, resource_size_t size)
        return offset - 65536;
 }
 
-static irqreturn_t mgag200_irq_handler(int irq, void *arg)
-{
-       struct drm_device *dev = arg;
-       struct mga_device *mdev = to_mga_device(dev);
-       struct drm_crtc *crtc;
-       u32 status, ien;
-
-       status = RREG32(MGAREG_STATUS);
-
-       if (status & MGAREG_STATUS_VLINEPEN) {
-               ien = RREG32(MGAREG_IEN);
-               if (!(ien & MGAREG_IEN_VLINEIEN))
-                       goto out;
-
-               crtc = drm_crtc_from_index(dev, 0);
-               if (WARN_ON_ONCE(!crtc))
-                       goto out;
-               drm_crtc_handle_vblank(crtc);
-
-               WREG32(MGAREG_ICLEAR, MGAREG_ICLEAR_VLINEICLR);
-
-               return IRQ_HANDLED;
-       }
-
-out:
-       return IRQ_NONE;
-}
-
 /*
  * DRM driver
  */
@@ -196,7 +167,6 @@ int mgag200_device_init(struct mga_device *mdev,
                        const struct mgag200_device_funcs *funcs)
 {
        struct drm_device *dev = &mdev->base;
-       struct pci_dev *pdev = to_pci_dev(dev->dev);
        u8 crtcext3, misc;
        int ret;
 
@@ -223,14 +193,6 @@ int mgag200_device_init(struct mga_device *mdev,
        mutex_unlock(&mdev->rmmio_lock);
 
        WREG32(MGAREG_IEN, 0);
-       WREG32(MGAREG_ICLEAR, MGAREG_ICLEAR_VLINEICLR);
-
-       ret = devm_request_irq(&pdev->dev, pdev->irq, mgag200_irq_handler, IRQF_SHARED,
-                              dev->driver->name, dev);
-       if (ret) {
-               drm_err(dev, "Failed to acquire interrupt, error %d\n", ret);
-               return ret;
-       }
 
        return 0;
 }
index 4760ba92871bb129c386411f327d611372771404..988967eafbf24e35a3c9206105279bea17c8de4f 100644 (file)
@@ -391,24 +391,17 @@ int mgag200_crtc_helper_atomic_check(struct drm_crtc *crtc, struct drm_atomic_st
 void mgag200_crtc_helper_atomic_flush(struct drm_crtc *crtc, struct drm_atomic_state *old_state);
 void mgag200_crtc_helper_atomic_enable(struct drm_crtc *crtc, struct drm_atomic_state *old_state);
 void mgag200_crtc_helper_atomic_disable(struct drm_crtc *crtc, struct drm_atomic_state *old_state);
-bool mgag200_crtc_helper_get_scanout_position(struct drm_crtc *crtc, bool in_vblank_irq,
-                                             int *vpos, int *hpos,
-                                             ktime_t *stime, ktime_t *etime,
-                                             const struct drm_display_mode *mode);
 
 #define MGAG200_CRTC_HELPER_FUNCS \
        .mode_valid = mgag200_crtc_helper_mode_valid, \
        .atomic_check = mgag200_crtc_helper_atomic_check, \
        .atomic_flush = mgag200_crtc_helper_atomic_flush, \
        .atomic_enable = mgag200_crtc_helper_atomic_enable, \
-       .atomic_disable = mgag200_crtc_helper_atomic_disable, \
-       .get_scanout_position = mgag200_crtc_helper_get_scanout_position
+       .atomic_disable = mgag200_crtc_helper_atomic_disable
 
 void mgag200_crtc_reset(struct drm_crtc *crtc);
 struct drm_crtc_state *mgag200_crtc_atomic_duplicate_state(struct drm_crtc *crtc);
 void mgag200_crtc_atomic_destroy_state(struct drm_crtc *crtc, struct drm_crtc_state *crtc_state);
-int mgag200_crtc_enable_vblank(struct drm_crtc *crtc);
-void mgag200_crtc_disable_vblank(struct drm_crtc *crtc);
 
 #define MGAG200_CRTC_FUNCS \
        .reset = mgag200_crtc_reset, \
@@ -416,10 +409,7 @@ void mgag200_crtc_disable_vblank(struct drm_crtc *crtc);
        .set_config = drm_atomic_helper_set_config, \
        .page_flip = drm_atomic_helper_page_flip, \
        .atomic_duplicate_state = mgag200_crtc_atomic_duplicate_state, \
-       .atomic_destroy_state = mgag200_crtc_atomic_destroy_state, \
-       .enable_vblank = mgag200_crtc_enable_vblank, \
-       .disable_vblank = mgag200_crtc_disable_vblank, \
-       .get_vblank_timestamp = drm_crtc_vblank_helper_get_vblank_timestamp
+       .atomic_destroy_state = mgag200_crtc_atomic_destroy_state
 
 void mgag200_set_mode_regs(struct mga_device *mdev, const struct drm_display_mode *mode,
                           bool set_vidrst);
index 77ce8d36cef05488985d337adcdb608329247774..f874e2949840994cb5f9a545e2e4ff4e749e3e35 100644 (file)
@@ -8,7 +8,6 @@
 #include <drm/drm_drv.h>
 #include <drm/drm_gem_atomic_helper.h>
 #include <drm/drm_probe_helper.h>
-#include <drm/drm_vblank.h>
 
 #include "mgag200_drv.h"
 
@@ -404,9 +403,5 @@ struct mga_device *mgag200_g200_device_create(struct pci_dev *pdev, const struct
        drm_mode_config_reset(dev);
        drm_kms_helper_poll_init(dev);
 
-       ret = drm_vblank_init(dev, 1);
-       if (ret)
-               return ERR_PTR(ret);
-
        return mdev;
 }
index 09ced65c1d2fbb32febed5096aa892a1c756fe13..e2305f8e00f8de8af8912b2286673c3dc428849d 100644 (file)
@@ -8,7 +8,6 @@
 #include <drm/drm_drv.h>
 #include <drm/drm_gem_atomic_helper.h>
 #include <drm/drm_probe_helper.h>
-#include <drm/drm_vblank.h>
 
 #include "mgag200_drv.h"
 
@@ -276,9 +275,5 @@ struct mga_device *mgag200_g200eh_device_create(struct pci_dev *pdev, const stru
        drm_mode_config_reset(dev);
        drm_kms_helper_poll_init(dev);
 
-       ret = drm_vblank_init(dev, 1);
-       if (ret)
-               return ERR_PTR(ret);
-
        return mdev;
 }
index 5daa469137bd30add967f790bd66dccc65e5fdd3..11ae76eb081daa3fcbc7fb604dd7d94b346c84a7 100644 (file)
@@ -7,7 +7,6 @@
 #include <drm/drm_drv.h>
 #include <drm/drm_gem_atomic_helper.h>
 #include <drm/drm_probe_helper.h>
-#include <drm/drm_vblank.h>
 
 #include "mgag200_drv.h"
 
@@ -181,9 +180,5 @@ struct mga_device *mgag200_g200eh3_device_create(struct pci_dev *pdev,
        drm_mode_config_reset(dev);
        drm_kms_helper_poll_init(dev);
 
-       ret = drm_vblank_init(dev, 1);
-       if (ret)
-               return ERR_PTR(ret);
-
        return mdev;
 }
index 09cfffafe1306cb5ce5932b89742ca742fbef129..c20ed0ab50ec1f293b1647c1b43ff96d0d61323d 100644 (file)
@@ -8,7 +8,6 @@
 #include <drm/drm_drv.h>
 #include <drm/drm_gem_atomic_helper.h>
 #include <drm/drm_probe_helper.h>
-#include <drm/drm_vblank.h>
 
 #include "mgag200_drv.h"
 
@@ -206,8 +205,6 @@ static void mgag200_g200er_crtc_helper_atomic_enable(struct drm_crtc *crtc,
                mgag200_crtc_set_gamma_linear(mdev, format);
 
        mgag200_enable_display(mdev);
-
-       drm_crtc_vblank_on(crtc);
 }
 
 static const struct drm_crtc_helper_funcs mgag200_g200er_crtc_helper_funcs = {
@@ -215,8 +212,7 @@ static const struct drm_crtc_helper_funcs mgag200_g200er_crtc_helper_funcs = {
        .atomic_check = mgag200_crtc_helper_atomic_check,
        .atomic_flush = mgag200_crtc_helper_atomic_flush,
        .atomic_enable = mgag200_g200er_crtc_helper_atomic_enable,
-       .atomic_disable = mgag200_crtc_helper_atomic_disable,
-       .get_scanout_position = mgag200_crtc_helper_get_scanout_position,
+       .atomic_disable = mgag200_crtc_helper_atomic_disable
 };
 
 static const struct drm_crtc_funcs mgag200_g200er_crtc_funcs = {
@@ -312,9 +308,5 @@ struct mga_device *mgag200_g200er_device_create(struct pci_dev *pdev, const stru
        drm_mode_config_reset(dev);
        drm_kms_helper_poll_init(dev);
 
-       ret = drm_vblank_init(dev, 1);
-       if (ret)
-               return ERR_PTR(ret);
-
        return mdev;
 }
index 3d48baa91d8b73ded496bd97abbabad147c222a6..78be964eb97c6af6b4a5dfefa2ffedce79fb85e4 100644 (file)
@@ -8,7 +8,6 @@
 #include <drm/drm_drv.h>
 #include <drm/drm_gem_atomic_helper.h>
 #include <drm/drm_probe_helper.h>
-#include <drm/drm_vblank.h>
 
 #include "mgag200_drv.h"
 
@@ -207,8 +206,6 @@ static void mgag200_g200ev_crtc_helper_atomic_enable(struct drm_crtc *crtc,
                mgag200_crtc_set_gamma_linear(mdev, format);
 
        mgag200_enable_display(mdev);
-
-       drm_crtc_vblank_on(crtc);
 }
 
 static const struct drm_crtc_helper_funcs mgag200_g200ev_crtc_helper_funcs = {
@@ -216,8 +213,7 @@ static const struct drm_crtc_helper_funcs mgag200_g200ev_crtc_helper_funcs = {
        .atomic_check = mgag200_crtc_helper_atomic_check,
        .atomic_flush = mgag200_crtc_helper_atomic_flush,
        .atomic_enable = mgag200_g200ev_crtc_helper_atomic_enable,
-       .atomic_disable = mgag200_crtc_helper_atomic_disable,
-       .get_scanout_position = mgag200_crtc_helper_get_scanout_position,
+       .atomic_disable = mgag200_crtc_helper_atomic_disable
 };
 
 static const struct drm_crtc_funcs mgag200_g200ev_crtc_funcs = {
@@ -317,9 +313,5 @@ struct mga_device *mgag200_g200ev_device_create(struct pci_dev *pdev, const stru
        drm_mode_config_reset(dev);
        drm_kms_helper_poll_init(dev);
 
-       ret = drm_vblank_init(dev, 1);
-       if (ret)
-               return ERR_PTR(ret);
-
        return mdev;
 }
index dabc778e64e8e5a9eb1bcc314e427948345c8d66..31624c9ab7b7e2d0c6cb5cc7ea6c59645f55856b 100644 (file)
@@ -7,7 +7,6 @@
 #include <drm/drm_drv.h>
 #include <drm/drm_gem_atomic_helper.h>
 #include <drm/drm_probe_helper.h>
-#include <drm/drm_vblank.h>
 
 #include "mgag200_drv.h"
 
@@ -199,9 +198,5 @@ struct mga_device *mgag200_g200ew3_device_create(struct pci_dev *pdev,
        drm_mode_config_reset(dev);
        drm_kms_helper_poll_init(dev);
 
-       ret = drm_vblank_init(dev, 1);
-       if (ret)
-               return ERR_PTR(ret);
-
        return mdev;
 }
index 9dcbe830427180076ad5ae76ac6837f4dade0722..7a32d3b1d2260eaae3fa6e30774bbafea6671823 100644 (file)
@@ -8,7 +8,6 @@
 #include <drm/drm_drv.h>
 #include <drm/drm_gem_atomic_helper.h>
 #include <drm/drm_probe_helper.h>
-#include <drm/drm_vblank.h>
 
 #include "mgag200_drv.h"
 
@@ -338,8 +337,6 @@ static void mgag200_g200se_crtc_helper_atomic_enable(struct drm_crtc *crtc,
                mgag200_crtc_set_gamma_linear(mdev, format);
 
        mgag200_enable_display(mdev);
-
-       drm_crtc_vblank_on(crtc);
 }
 
 static const struct drm_crtc_helper_funcs mgag200_g200se_crtc_helper_funcs = {
@@ -347,8 +344,7 @@ static const struct drm_crtc_helper_funcs mgag200_g200se_crtc_helper_funcs = {
        .atomic_check = mgag200_crtc_helper_atomic_check,
        .atomic_flush = mgag200_crtc_helper_atomic_flush,
        .atomic_enable = mgag200_g200se_crtc_helper_atomic_enable,
-       .atomic_disable = mgag200_crtc_helper_atomic_disable,
-       .get_scanout_position = mgag200_crtc_helper_get_scanout_position,
+       .atomic_disable = mgag200_crtc_helper_atomic_disable
 };
 
 static const struct drm_crtc_funcs mgag200_g200se_crtc_funcs = {
@@ -517,9 +513,5 @@ struct mga_device *mgag200_g200se_device_create(struct pci_dev *pdev, const stru
        drm_mode_config_reset(dev);
        drm_kms_helper_poll_init(dev);
 
-       ret = drm_vblank_init(dev, 1);
-       if (ret)
-               return ERR_PTR(ret);
-
        return mdev;
 }
index 83a24aedbf2f3bd477dc6e81dce5e0f341f6b1c3..a0e7b9ad46cd4120e6559e2a3983c7f61bc1db63 100644 (file)
@@ -8,7 +8,6 @@
 #include <drm/drm_drv.h>
 #include <drm/drm_gem_atomic_helper.h>
 #include <drm/drm_probe_helper.h>
-#include <drm/drm_vblank.h>
 
 #include "mgag200_drv.h"
 
@@ -323,9 +322,5 @@ struct mga_device *mgag200_g200wb_device_create(struct pci_dev *pdev, const stru
        drm_mode_config_reset(dev);
        drm_kms_helper_poll_init(dev);
 
-       ret = drm_vblank_init(dev, 1);
-       if (ret)
-               return ERR_PTR(ret);
-
        return mdev;
 }
index 7159909aca1eb6581daa621b0829d7c51c040e13..fb71658c3117b25311f19276d6f4ffdee157ac17 100644 (file)
@@ -22,7 +22,6 @@
 #include <drm/drm_gem_framebuffer_helper.h>
 #include <drm/drm_panic.h>
 #include <drm/drm_print.h>
-#include <drm/drm_vblank.h>
 
 #include "mgag200_ddc.h"
 #include "mgag200_drv.h"
@@ -227,14 +226,7 @@ void mgag200_set_mode_regs(struct mga_device *mdev, const struct drm_display_mod
        vblkstr = mode->crtc_vblank_start;
        vblkend = vtotal + 1;
 
-       /*
-        * There's no VBLANK interrupt on Matrox chipsets, so we use
-        * the VLINE interrupt instead. It triggers when the current
-        * <linecomp> has been reached. For VBLANK, this is the first
-        * non-visible line at the bottom of the screen. Therefore,
-        * keep <linecomp> in sync with <vblkstr>.
-        */
-       linecomp = vblkstr;
+       linecomp = vdispend;
 
        misc = RREG8(MGA_MISC_IN);
 
@@ -645,8 +637,6 @@ void mgag200_crtc_helper_atomic_flush(struct drm_crtc *crtc, struct drm_atomic_s
        struct mgag200_crtc_state *mgag200_crtc_state = to_mgag200_crtc_state(crtc_state);
        struct drm_device *dev = crtc->dev;
        struct mga_device *mdev = to_mga_device(dev);
-       struct drm_pending_vblank_event *event;
-       unsigned long flags;
 
        if (crtc_state->enable && crtc_state->color_mgmt_changed) {
                const struct drm_format_info *format = mgag200_crtc_state->format;
@@ -656,18 +646,6 @@ void mgag200_crtc_helper_atomic_flush(struct drm_crtc *crtc, struct drm_atomic_s
                else
                        mgag200_crtc_set_gamma_linear(mdev, format);
        }
-
-       event = crtc->state->event;
-       if (event) {
-               crtc->state->event = NULL;
-
-               spin_lock_irqsave(&dev->event_lock, flags);
-               if (drm_crtc_vblank_get(crtc) != 0)
-                       drm_crtc_send_vblank_event(crtc, event);
-               else
-                       drm_crtc_arm_vblank_event(crtc, event);
-               spin_unlock_irqrestore(&dev->event_lock, flags);
-       }
 }
 
 void mgag200_crtc_helper_atomic_enable(struct drm_crtc *crtc, struct drm_atomic_state *old_state)
@@ -692,44 +670,15 @@ void mgag200_crtc_helper_atomic_enable(struct drm_crtc *crtc, struct drm_atomic_
                mgag200_crtc_set_gamma_linear(mdev, format);
 
        mgag200_enable_display(mdev);
-
-       drm_crtc_vblank_on(crtc);
 }
 
 void mgag200_crtc_helper_atomic_disable(struct drm_crtc *crtc, struct drm_atomic_state *old_state)
 {
        struct mga_device *mdev = to_mga_device(crtc->dev);
 
-       drm_crtc_vblank_off(crtc);
-
        mgag200_disable_display(mdev);
 }
 
-bool mgag200_crtc_helper_get_scanout_position(struct drm_crtc *crtc, bool in_vblank_irq,
-                                             int *vpos, int *hpos,
-                                             ktime_t *stime, ktime_t *etime,
-                                             const struct drm_display_mode *mode)
-{
-       struct mga_device *mdev = to_mga_device(crtc->dev);
-       u32 vcount;
-
-       if (stime)
-               *stime = ktime_get();
-
-       if (vpos) {
-               vcount = RREG32(MGAREG_VCOUNT);
-               *vpos = vcount & GENMASK(11, 0);
-       }
-
-       if (hpos)
-               *hpos = mode->htotal >> 1; // near middle of scanline on average
-
-       if (etime)
-               *etime = ktime_get();
-
-       return true;
-}
-
 void mgag200_crtc_reset(struct drm_crtc *crtc)
 {
        struct mgag200_crtc_state *mgag200_crtc_state;
@@ -774,30 +723,6 @@ void mgag200_crtc_atomic_destroy_state(struct drm_crtc *crtc, struct drm_crtc_st
        kfree(mgag200_crtc_state);
 }
 
-int mgag200_crtc_enable_vblank(struct drm_crtc *crtc)
-{
-       struct mga_device *mdev = to_mga_device(crtc->dev);
-       u32 ien;
-
-       WREG32(MGAREG_ICLEAR, MGAREG_ICLEAR_VLINEICLR);
-
-       ien = RREG32(MGAREG_IEN);
-       ien |= MGAREG_IEN_VLINEIEN;
-       WREG32(MGAREG_IEN, ien);
-
-       return 0;
-}
-
-void mgag200_crtc_disable_vblank(struct drm_crtc *crtc)
-{
-       struct mga_device *mdev = to_mga_device(crtc->dev);
-       u32 ien;
-
-       ien = RREG32(MGAREG_IEN);
-       ien &= ~(MGAREG_IEN_VLINEIEN);
-       WREG32(MGAREG_IEN, ien);
-}
-
 /*
  * Mode config
  */
index 06cab2c6fd663b81d7f2c2bf4faf57104d2d574e..702b8d4b3497237e38ff6258a160defc1da81119 100644 (file)
@@ -101,9 +101,10 @@ static void get_stats_counter(struct msm_ringbuffer *ring, u32 counter,
 }
 
 static void a6xx_set_pagetable(struct a6xx_gpu *a6xx_gpu,
-               struct msm_ringbuffer *ring, struct msm_file_private *ctx)
+               struct msm_ringbuffer *ring, struct msm_gem_submit *submit)
 {
        bool sysprof = refcount_read(&a6xx_gpu->base.base.sysprof_active) > 1;
+       struct msm_file_private *ctx = submit->queue->ctx;
        struct adreno_gpu *adreno_gpu = &a6xx_gpu->base;
        phys_addr_t ttbr;
        u32 asid;
@@ -115,6 +116,15 @@ static void a6xx_set_pagetable(struct a6xx_gpu *a6xx_gpu,
        if (msm_iommu_pagetable_params(ctx->aspace->mmu, &ttbr, &asid))
                return;
 
+       if (adreno_gpu->info->family >= ADRENO_7XX_GEN1) {
+               /* Wait for previous submit to complete before continuing: */
+               OUT_PKT7(ring, CP_WAIT_TIMESTAMP, 4);
+               OUT_RING(ring, 0);
+               OUT_RING(ring, lower_32_bits(rbmemptr(ring, fence)));
+               OUT_RING(ring, upper_32_bits(rbmemptr(ring, fence)));
+               OUT_RING(ring, submit->seqno - 1);
+       }
+
        if (!sysprof) {
                if (!adreno_is_a7xx(adreno_gpu)) {
                        /* Turn off protected mode to write to special registers */
@@ -193,7 +203,7 @@ static void a6xx_submit(struct msm_gpu *gpu, struct msm_gem_submit *submit)
        struct msm_ringbuffer *ring = submit->ring;
        unsigned int i, ibs = 0;
 
-       a6xx_set_pagetable(a6xx_gpu, ring, submit->queue->ctx);
+       a6xx_set_pagetable(a6xx_gpu, ring, submit);
 
        get_stats_counter(ring, REG_A6XX_RBBM_PERFCTR_CP(0),
                rbmemptr_stats(ring, index, cpcycles_start));
@@ -283,7 +293,7 @@ static void a7xx_submit(struct msm_gpu *gpu, struct msm_gem_submit *submit)
        OUT_PKT7(ring, CP_THREAD_CONTROL, 1);
        OUT_RING(ring, CP_THREAD_CONTROL_0_SYNC_THREADS | CP_SET_THREAD_BR);
 
-       a6xx_set_pagetable(a6xx_gpu, ring, submit->queue->ctx);
+       a6xx_set_pagetable(a6xx_gpu, ring, submit);
 
        get_stats_counter(ring, REG_A7XX_RBBM_PERFCTR_CP(0),
                rbmemptr_stats(ring, index, cpcycles_start));
index 4c1be2f0555f7ea57191b9c1718a9e041069ed86..db6c57900781d94de7c5ceb956c1664e3cd40c66 100644 (file)
@@ -711,12 +711,13 @@ void dpu_crtc_complete_commit(struct drm_crtc *crtc)
        _dpu_crtc_complete_flip(crtc);
 }
 
-static void _dpu_crtc_setup_lm_bounds(struct drm_crtc *crtc,
+static int _dpu_crtc_check_and_setup_lm_bounds(struct drm_crtc *crtc,
                struct drm_crtc_state *state)
 {
        struct dpu_crtc_state *cstate = to_dpu_crtc_state(state);
        struct drm_display_mode *adj_mode = &state->adjusted_mode;
        u32 crtc_split_width = adj_mode->hdisplay / cstate->num_mixers;
+       struct dpu_kms *dpu_kms = _dpu_crtc_get_kms(crtc);
        int i;
 
        for (i = 0; i < cstate->num_mixers; i++) {
@@ -727,7 +728,12 @@ static void _dpu_crtc_setup_lm_bounds(struct drm_crtc *crtc,
                r->y2 = adj_mode->vdisplay;
 
                trace_dpu_crtc_setup_lm_bounds(DRMID(crtc), i, r);
+
+               if (drm_rect_width(r) > dpu_kms->catalog->caps->max_mixer_width)
+                       return -E2BIG;
        }
+
+       return 0;
 }
 
 static void _dpu_crtc_get_pcc_coeff(struct drm_crtc_state *state,
@@ -803,7 +809,7 @@ static void dpu_crtc_atomic_begin(struct drm_crtc *crtc,
 
        DRM_DEBUG_ATOMIC("crtc%d\n", crtc->base.id);
 
-       _dpu_crtc_setup_lm_bounds(crtc, crtc->state);
+       _dpu_crtc_check_and_setup_lm_bounds(crtc, crtc->state);
 
        /* encoder will trigger pending mask now */
        drm_for_each_encoder_mask(encoder, crtc->dev, crtc->state->encoder_mask)
@@ -1091,9 +1097,6 @@ static void dpu_crtc_disable(struct drm_crtc *crtc,
 
        dpu_core_perf_crtc_update(crtc, 0);
 
-       memset(cstate->mixers, 0, sizeof(cstate->mixers));
-       cstate->num_mixers = 0;
-
        /* disable clk & bw control until clk & bw properties are set */
        cstate->bw_control = false;
        cstate->bw_split_vote = false;
@@ -1192,8 +1195,11 @@ static int dpu_crtc_atomic_check(struct drm_crtc *crtc,
        if (crtc_state->active_changed)
                crtc_state->mode_changed = true;
 
-       if (cstate->num_mixers)
-               _dpu_crtc_setup_lm_bounds(crtc, crtc_state);
+       if (cstate->num_mixers) {
+               rc = _dpu_crtc_check_and_setup_lm_bounds(crtc, crtc_state);
+               if (rc)
+                       return rc;
+       }
 
        /* FIXME: move this to dpu_plane_atomic_check? */
        drm_atomic_crtc_state_for_each_plane_state(plane, pstate, crtc_state) {
index 3b171bf227d16f301545eefeac1e2bf61085b218..bd3698bf0cf7403235da8315d53a4dbe077f5779 100644 (file)
@@ -624,6 +624,40 @@ static struct msm_display_topology dpu_encoder_get_topology(
        return topology;
 }
 
+static void dpu_encoder_assign_crtc_resources(struct dpu_kms *dpu_kms,
+                                             struct drm_encoder *drm_enc,
+                                             struct dpu_global_state *global_state,
+                                             struct drm_crtc_state *crtc_state)
+{
+       struct dpu_crtc_state *cstate;
+       struct dpu_hw_blk *hw_ctl[MAX_CHANNELS_PER_ENC];
+       struct dpu_hw_blk *hw_lm[MAX_CHANNELS_PER_ENC];
+       struct dpu_hw_blk *hw_dspp[MAX_CHANNELS_PER_ENC];
+       int num_lm, num_ctl, num_dspp, i;
+
+       cstate = to_dpu_crtc_state(crtc_state);
+
+       memset(cstate->mixers, 0, sizeof(cstate->mixers));
+
+       num_ctl = dpu_rm_get_assigned_resources(&dpu_kms->rm, global_state,
+               drm_enc->base.id, DPU_HW_BLK_CTL, hw_ctl, ARRAY_SIZE(hw_ctl));
+       num_lm = dpu_rm_get_assigned_resources(&dpu_kms->rm, global_state,
+               drm_enc->base.id, DPU_HW_BLK_LM, hw_lm, ARRAY_SIZE(hw_lm));
+       num_dspp = dpu_rm_get_assigned_resources(&dpu_kms->rm, global_state,
+               drm_enc->base.id, DPU_HW_BLK_DSPP, hw_dspp,
+               ARRAY_SIZE(hw_dspp));
+
+       for (i = 0; i < num_lm; i++) {
+               int ctl_idx = (i < num_ctl) ? i : (num_ctl-1);
+
+               cstate->mixers[i].hw_lm = to_dpu_hw_mixer(hw_lm[i]);
+               cstate->mixers[i].lm_ctl = to_dpu_hw_ctl(hw_ctl[ctl_idx]);
+               cstate->mixers[i].hw_dspp = i < num_dspp ? to_dpu_hw_dspp(hw_dspp[i]) : NULL;
+       }
+
+       cstate->num_mixers = num_lm;
+}
+
 static int dpu_encoder_virt_atomic_check(
                struct drm_encoder *drm_enc,
                struct drm_crtc_state *crtc_state,
@@ -692,6 +726,9 @@ static int dpu_encoder_virt_atomic_check(
                if (!crtc_state->active_changed || crtc_state->enable)
                        ret = dpu_rm_reserve(&dpu_kms->rm, global_state,
                                        drm_enc, crtc_state, topology);
+               if (!ret)
+                       dpu_encoder_assign_crtc_resources(dpu_kms, drm_enc,
+                                                         global_state, crtc_state);
        }
 
        trace_dpu_enc_atomic_check_flags(DRMID(drm_enc), adj_mode->flags);
@@ -1093,14 +1130,11 @@ static void dpu_encoder_virt_atomic_mode_set(struct drm_encoder *drm_enc,
        struct dpu_encoder_virt *dpu_enc;
        struct msm_drm_private *priv;
        struct dpu_kms *dpu_kms;
-       struct dpu_crtc_state *cstate;
        struct dpu_global_state *global_state;
        struct dpu_hw_blk *hw_pp[MAX_CHANNELS_PER_ENC];
        struct dpu_hw_blk *hw_ctl[MAX_CHANNELS_PER_ENC];
-       struct dpu_hw_blk *hw_lm[MAX_CHANNELS_PER_ENC];
-       struct dpu_hw_blk *hw_dspp[MAX_CHANNELS_PER_ENC] = { NULL };
        struct dpu_hw_blk *hw_dsc[MAX_CHANNELS_PER_ENC];
-       int num_lm, num_ctl, num_pp, num_dsc;
+       int num_ctl, num_pp, num_dsc;
        unsigned int dsc_mask = 0;
        int i;
 
@@ -1129,11 +1163,6 @@ static void dpu_encoder_virt_atomic_mode_set(struct drm_encoder *drm_enc,
                ARRAY_SIZE(hw_pp));
        num_ctl = dpu_rm_get_assigned_resources(&dpu_kms->rm, global_state,
                drm_enc->base.id, DPU_HW_BLK_CTL, hw_ctl, ARRAY_SIZE(hw_ctl));
-       num_lm = dpu_rm_get_assigned_resources(&dpu_kms->rm, global_state,
-               drm_enc->base.id, DPU_HW_BLK_LM, hw_lm, ARRAY_SIZE(hw_lm));
-       dpu_rm_get_assigned_resources(&dpu_kms->rm, global_state,
-               drm_enc->base.id, DPU_HW_BLK_DSPP, hw_dspp,
-               ARRAY_SIZE(hw_dspp));
 
        for (i = 0; i < MAX_CHANNELS_PER_ENC; i++)
                dpu_enc->hw_pp[i] = i < num_pp ? to_dpu_hw_pingpong(hw_pp[i])
@@ -1159,36 +1188,23 @@ static void dpu_encoder_virt_atomic_mode_set(struct drm_encoder *drm_enc,
                dpu_enc->cur_master->hw_cdm = hw_cdm ? to_dpu_hw_cdm(hw_cdm) : NULL;
        }
 
-       cstate = to_dpu_crtc_state(crtc_state);
-
-       for (i = 0; i < num_lm; i++) {
-               int ctl_idx = (i < num_ctl) ? i : (num_ctl-1);
-
-               cstate->mixers[i].hw_lm = to_dpu_hw_mixer(hw_lm[i]);
-               cstate->mixers[i].lm_ctl = to_dpu_hw_ctl(hw_ctl[ctl_idx]);
-               cstate->mixers[i].hw_dspp = to_dpu_hw_dspp(hw_dspp[i]);
-       }
-
-       cstate->num_mixers = num_lm;
-
        for (i = 0; i < dpu_enc->num_phys_encs; i++) {
                struct dpu_encoder_phys *phys = dpu_enc->phys_encs[i];
 
-               if (!dpu_enc->hw_pp[i]) {
+               phys->hw_pp = dpu_enc->hw_pp[i];
+               if (!phys->hw_pp) {
                        DPU_ERROR_ENC(dpu_enc,
                                "no pp block assigned at idx: %d\n", i);
                        return;
                }
 
-               if (!hw_ctl[i]) {
+               phys->hw_ctl = i < num_ctl ? to_dpu_hw_ctl(hw_ctl[i]) : NULL;
+               if (!phys->hw_ctl) {
                        DPU_ERROR_ENC(dpu_enc,
                                "no ctl block assigned at idx: %d\n", i);
                        return;
                }
 
-               phys->hw_pp = dpu_enc->hw_pp[i];
-               phys->hw_ctl = to_dpu_hw_ctl(hw_ctl[i]);
-
                phys->cached_mode = crtc_state->adjusted_mode;
                if (phys->ops.atomic_mode_set)
                        phys->ops.atomic_mode_set(phys, crtc_state, conn_state);
index ba8878d21cf0e1945a393cca806cb64f03b16640..d8a2edebfe8c3c6fb97255f196263f83b0427d94 100644 (file)
@@ -302,7 +302,7 @@ static void dpu_encoder_phys_vid_setup_timing_engine(
        intf_cfg.stream_sel = 0; /* Don't care value for video mode */
        intf_cfg.mode_3d = dpu_encoder_helper_get_3d_blend_mode(phys_enc);
        intf_cfg.dsc = dpu_encoder_helper_get_dsc(phys_enc);
-       if (phys_enc->hw_pp->merge_3d)
+       if (intf_cfg.mode_3d && phys_enc->hw_pp->merge_3d)
                intf_cfg.merge_3d = phys_enc->hw_pp->merge_3d->idx;
 
        spin_lock_irqsave(phys_enc->enc_spinlock, lock_flags);
@@ -440,10 +440,12 @@ static void dpu_encoder_phys_vid_enable(struct dpu_encoder_phys *phys_enc)
        struct dpu_hw_ctl *ctl;
        const struct msm_format *fmt;
        u32 fmt_fourcc;
+       u32 mode_3d;
 
        ctl = phys_enc->hw_ctl;
        fmt_fourcc = dpu_encoder_get_drm_fmt(phys_enc);
        fmt = mdp_get_format(&phys_enc->dpu_kms->base, fmt_fourcc, 0);
+       mode_3d = dpu_encoder_helper_get_3d_blend_mode(phys_enc);
 
        DPU_DEBUG_VIDENC(phys_enc, "\n");
 
@@ -466,7 +468,8 @@ static void dpu_encoder_phys_vid_enable(struct dpu_encoder_phys *phys_enc)
                goto skip_flush;
 
        ctl->ops.update_pending_flush_intf(ctl, phys_enc->hw_intf->idx);
-       if (ctl->ops.update_pending_flush_merge_3d && phys_enc->hw_pp->merge_3d)
+       if (mode_3d && ctl->ops.update_pending_flush_merge_3d &&
+           phys_enc->hw_pp->merge_3d)
                ctl->ops.update_pending_flush_merge_3d(ctl, phys_enc->hw_pp->merge_3d->idx);
 
        if (ctl->ops.update_pending_flush_cdm && phys_enc->hw_cdm)
index 882c717859cec6dfc4b646200e68a748a5294ac9..07035ab77b792e76c08eb3e18c12a4afddeac902 100644 (file)
@@ -275,6 +275,7 @@ static void _dpu_encoder_phys_wb_update_flush(struct dpu_encoder_phys *phys_enc)
        struct dpu_hw_pingpong *hw_pp;
        struct dpu_hw_cdm *hw_cdm;
        u32 pending_flush = 0;
+       u32 mode_3d;
 
        if (!phys_enc)
                return;
@@ -283,6 +284,7 @@ static void _dpu_encoder_phys_wb_update_flush(struct dpu_encoder_phys *phys_enc)
        hw_pp = phys_enc->hw_pp;
        hw_ctl = phys_enc->hw_ctl;
        hw_cdm = phys_enc->hw_cdm;
+       mode_3d = dpu_encoder_helper_get_3d_blend_mode(phys_enc);
 
        DPU_DEBUG("[wb:%d]\n", hw_wb->idx - WB_0);
 
@@ -294,7 +296,8 @@ static void _dpu_encoder_phys_wb_update_flush(struct dpu_encoder_phys *phys_enc)
        if (hw_ctl->ops.update_pending_flush_wb)
                hw_ctl->ops.update_pending_flush_wb(hw_ctl, hw_wb->idx);
 
-       if (hw_ctl->ops.update_pending_flush_merge_3d && hw_pp && hw_pp->merge_3d)
+       if (mode_3d && hw_ctl->ops.update_pending_flush_merge_3d &&
+           hw_pp && hw_pp->merge_3d)
                hw_ctl->ops.update_pending_flush_merge_3d(hw_ctl,
                                hw_pp->merge_3d->idx);
 
index add72bbc28b1764772a874931ec09ab4f010740a..4d55e3cf570f0b818b9387f3e7763294e1f8e0f4 100644 (file)
@@ -26,7 +26,7 @@ static void msm_disp_state_dump_regs(u32 **reg, u32 aligned_len, void __iomem *b
        end_addr = base_addr + aligned_len;
 
        if (!(*reg))
-               *reg = kzalloc(len_padded, GFP_KERNEL);
+               *reg = kvzalloc(len_padded, GFP_KERNEL);
 
        if (*reg)
                dump_addr = *reg;
@@ -48,20 +48,21 @@ static void msm_disp_state_dump_regs(u32 **reg, u32 aligned_len, void __iomem *b
        }
 }
 
-static void msm_disp_state_print_regs(u32 **reg, u32 len, void __iomem *base_addr,
-               struct drm_printer *p)
+static void msm_disp_state_print_regs(const u32 *dump_addr, u32 len,
+               void __iomem *base_addr, struct drm_printer *p)
 {
        int i;
-       u32 *dump_addr = NULL;
        void __iomem *addr;
        u32 num_rows;
 
+       if (!dump_addr) {
+               drm_printf(p, "Registers not stored\n");
+               return;
+       }
+
        addr = base_addr;
        num_rows = len / REG_DUMP_ALIGN;
 
-       if (*reg)
-               dump_addr = *reg;
-
        for (i = 0; i < num_rows; i++) {
                drm_printf(p, "0x%lx : %08x %08x %08x %08x\n",
                                (unsigned long)(addr - base_addr),
@@ -89,7 +90,7 @@ void msm_disp_state_print(struct msm_disp_state *state, struct drm_printer *p)
 
        list_for_each_entry_safe(block, tmp, &state->blocks, node) {
                drm_printf(p, "====================%s================\n", block->name);
-               msm_disp_state_print_regs(&block->state, block->size, block->base_addr, p);
+               msm_disp_state_print_regs(block->state, block->size, block->base_addr, p);
        }
 
        drm_printf(p, "===================dpu drm state================\n");
@@ -161,7 +162,7 @@ void msm_disp_state_free(void *data)
 
        list_for_each_entry_safe(block, tmp, &disp_state->blocks, node) {
                list_del(&block->node);
-               kfree(block->state);
+               kvfree(block->state);
                kfree(block);
        }
 
index 185d7de0bf376622bc6c33192e84e5254ba81337..a98d24b7cb00b41d3bb371a965a80ceaa93775a6 100644 (file)
@@ -542,7 +542,7 @@ static unsigned long dsi_adjust_pclk_for_compression(const struct drm_display_mo
 
        int new_htotal = mode->htotal - mode->hdisplay + new_hdisplay;
 
-       return new_htotal * mode->vtotal * drm_mode_vrefresh(mode);
+       return mult_frac(mode->clock * 1000u, new_htotal, mode->htotal);
 }
 
 static unsigned long dsi_get_pclk_rate(const struct drm_display_mode *mode,
@@ -550,7 +550,7 @@ static unsigned long dsi_get_pclk_rate(const struct drm_display_mode *mode,
 {
        unsigned long pclk_rate;
 
-       pclk_rate = mode->clock * 1000;
+       pclk_rate = mode->clock * 1000u;
 
        if (dsc)
                pclk_rate = dsi_adjust_pclk_for_compression(mode, dsc);
index 0e3a2b16a2ce82eda15463e98251463efd0f9fc3..e6ffaf92d26d3230bb1d90064f1b4f1a3b426170 100644 (file)
@@ -153,15 +153,6 @@ static inline u32 pll_get_pll_cmp(u64 fdata, unsigned long ref_clk)
        return dividend - 1;
 }
 
-static inline u64 pll_cmp_to_fdata(u32 pll_cmp, unsigned long ref_clk)
-{
-       u64 fdata = ((u64)pll_cmp) * ref_clk * 10;
-
-       do_div(fdata, HDMI_PLL_CMP_CNT);
-
-       return fdata;
-}
-
 #define HDMI_REF_CLOCK_HZ ((u64)19200000)
 #define HDMI_MHZ_TO_HZ ((u64)1000000)
 static int pll_get_post_div(struct hdmi_8998_post_divider *pd, u64 bclk)
index a2eaf3929ac306e132188b16df4c3065754497f3..4a1123b81feef21506f3927f2833ff0dabfbed8f 100644 (file)
@@ -30,7 +30,7 @@
 #include <linux/iommu.h>
 #include <linux/of_device.h>
 
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #include <soc/tegra/fuse.h>
 #include <soc/tegra/pmc.h>
index 9e6f3991236813c33342aef00df83a5134aa34b4..a2055f2a014a82bdf55e355a965763e764c3f580 100644 (file)
@@ -210,7 +210,7 @@ struct nvkm_gsp {
        } *rm;
 
        struct {
-               struct mutex mutex;;
+               struct mutex mutex;
                struct idr idr;
        } client_id;
 
index 1f2d649f4b96fd75c8ee65b5ee420ad3b0488de1..1a072568cef6816d08f99b130bc0bb3111b16ada 100644 (file)
@@ -193,7 +193,7 @@ static vm_fault_t nouveau_dmem_migrate_to_ram(struct vm_fault *vmf)
        if (!spage || !(src & MIGRATE_PFN_MIGRATE))
                goto done;
 
-       dpage = alloc_page_vma(GFP_HIGHUSER, vmf->vma, vmf->address);
+       dpage = alloc_page_vma(GFP_HIGHUSER | __GFP_ZERO, vmf->vma, vmf->address);
        if (!dpage)
                goto done;
 
index f6e78dba594f5cf53d2584c3d1eb40d6fb8d1ab8..34985771b2a28581cc6a0dc821a49184158e7609 100644 (file)
@@ -331,7 +331,7 @@ nouveau_accel_ce_init(struct nouveau_drm *drm)
                return;
        }
 
-       ret = nouveau_channel_new(&drm->client, false, runm, NvDmaFB, NvDmaTT, &drm->cechan);
+       ret = nouveau_channel_new(&drm->client, true, runm, NvDmaFB, NvDmaTT, &drm->cechan);
        if (ret)
                NV_ERROR(drm, "failed to create ce channel, %d\n", ret);
 }
index 6e4b7e4644ce06d198a67b36f7146235e64d63c0..8b48bba181316c6da3978823cee9f589d1ffac5c 100644 (file)
@@ -298,7 +298,7 @@ static int ivo_t109nw41_init(struct hx83102 *ctx)
        msleep(60);
 
        hx83102_enable_extended_cmds(&dsi_ctx, true);
-       mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83102_SETPOWER, 0x2c, 0xed, 0xed, 0x0f, 0xcf, 0x42,
+       mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83102_SETPOWER, 0x2c, 0xed, 0xed, 0x27, 0xe7, 0x52,
                                     0xf5, 0x39, 0x36, 0x36, 0x36, 0x36, 0x32, 0x8b, 0x11, 0x65, 0x00, 0x88,
                                     0xfa, 0xff, 0xff, 0x8f, 0xff, 0x08, 0xd6, 0x33);
        mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83102_SETDISP, 0x00, 0x47, 0xb0, 0x80, 0x00, 0x12,
@@ -343,11 +343,11 @@ static int ivo_t109nw41_init(struct hx83102 *ctx)
                                     0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xa0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                                     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                                     0x00, 0x00, 0x00, 0x00, 0x00, 0x00);
-       mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83102_SETGMA, 0x04, 0x04, 0x06, 0x0a, 0x0a, 0x05,
-                                    0x12, 0x14, 0x17, 0x13, 0x2c, 0x33, 0x39, 0x4b, 0x4c, 0x56, 0x61, 0x78,
-                                    0x7a, 0x41, 0x50, 0x68, 0x73, 0x04, 0x04, 0x06, 0x0a, 0x0a, 0x05, 0x12,
-                                    0x14, 0x17, 0x13, 0x2c, 0x33, 0x39, 0x4b, 0x4c, 0x56, 0x61, 0x78, 0x7a,
-                                    0x41, 0x50, 0x68, 0x73);
+       mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83102_SETGMA, 0x00, 0x07, 0x10, 0x17, 0x1c, 0x33,
+                                    0x48, 0x50, 0x57, 0x50, 0x68, 0x6e, 0x71, 0x7f, 0x81, 0x8a, 0x8e, 0x9b,
+                                    0x9c, 0x4d, 0x56, 0x5d, 0x73, 0x00, 0x07, 0x10, 0x17, 0x1c, 0x33, 0x48,
+                                    0x50, 0x57, 0x50, 0x68, 0x6e, 0x71, 0x7f, 0x81, 0x8a, 0x8e, 0x9b, 0x9c,
+                                    0x4d, 0x56, 0x5d, 0x73);
        mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83102_SETTP1, 0x07, 0x10, 0x10, 0x1a, 0x26, 0x9e,
                                     0x00, 0x4f, 0xa0, 0x14, 0x14, 0x00, 0x00, 0x00, 0x00, 0x12, 0x0a, 0x02,
                                     0x02, 0x00, 0x33, 0x02, 0x04, 0x18, 0x01);
index 34182f67136c175b0c2f8bd36eed0e74b20257ac..c520f156e2d73f7e735f8bf2d6d8e8efacec9362 100644 (file)
@@ -1383,6 +1383,7 @@ static const struct file_operations panthor_drm_driver_fops = {
        .read = drm_read,
        .llseek = noop_llseek,
        .mmap = panthor_mmap,
+       .fop_flags = FOP_UNSIGNED_OFFSET,
 };
 
 #ifdef CONFIG_DEBUG_FS
index ef232c0c204932c9b3e5f25841131c48dd566a98..4e2d3a02ea06894fc4c05892c5b9a63af5de2e38 100644 (file)
@@ -487,6 +487,7 @@ static int panthor_fw_load_section_entry(struct panthor_device *ptdev,
                                         struct panthor_fw_binary_iter *iter,
                                         u32 ehdr)
 {
+       ssize_t vm_pgsz = panthor_vm_page_size(ptdev->fw->vm);
        struct panthor_fw_binary_section_entry_hdr hdr;
        struct panthor_fw_section *section;
        u32 section_size;
@@ -515,8 +516,7 @@ static int panthor_fw_load_section_entry(struct panthor_device *ptdev,
                return -EINVAL;
        }
 
-       if ((hdr.va.start & ~PAGE_MASK) != 0 ||
-           (hdr.va.end & ~PAGE_MASK) != 0) {
+       if (!IS_ALIGNED(hdr.va.start, vm_pgsz) || !IS_ALIGNED(hdr.va.end, vm_pgsz)) {
                drm_err(&ptdev->base, "Firmware corrupted, virtual addresses not page aligned: 0x%x-0x%x\n",
                        hdr.va.start, hdr.va.end);
                return -EINVAL;
index 38f560864879c5f2bcd57df32daed0cf88dbd0a9..be97d56bc011d29e6237c8eb2df1912fd67ec423 100644 (file)
@@ -44,8 +44,7 @@ void panthor_kernel_bo_destroy(struct panthor_kernel_bo *bo)
                        to_panthor_bo(bo->obj)->exclusive_vm_root_gem != panthor_vm_root_gem(vm)))
                goto out_free_bo;
 
-       ret = panthor_vm_unmap_range(vm, bo->va_node.start,
-                                    panthor_kernel_bo_size(bo));
+       ret = panthor_vm_unmap_range(vm, bo->va_node.start, bo->va_node.size);
        if (ret)
                goto out_free_bo;
 
@@ -95,10 +94,16 @@ panthor_kernel_bo_create(struct panthor_device *ptdev, struct panthor_vm *vm,
        }
 
        bo = to_panthor_bo(&obj->base);
-       size = obj->base.size;
        kbo->obj = &obj->base;
        bo->flags = bo_flags;
 
+       /* The system and GPU MMU page size might differ, which becomes a
+        * problem for FW sections that need to be mapped at explicit address
+        * since our PAGE_SIZE alignment might cover a VA range that's
+        * expected to be used for another section.
+        * Make sure we never map more than we need.
+        */
+       size = ALIGN(size, panthor_vm_page_size(vm));
        ret = panthor_vm_alloc_va(vm, gpu_va, size, &kbo->va_node);
        if (ret)
                goto err_put_obj;
index bbc12728437f1365472b7f572f3d21fefcdd337e..5d5e25b1be95cb618460b18f41710855a475f51e 100644 (file)
@@ -826,6 +826,14 @@ void panthor_vm_idle(struct panthor_vm *vm)
        mutex_unlock(&ptdev->mmu->as.slots_lock);
 }
 
+u32 panthor_vm_page_size(struct panthor_vm *vm)
+{
+       const struct io_pgtable *pgt = io_pgtable_ops_to_pgtable(vm->pgtbl_ops);
+       u32 pg_shift = ffs(pgt->cfg.pgsize_bitmap) - 1;
+
+       return 1u << pg_shift;
+}
+
 static void panthor_vm_stop(struct panthor_vm *vm)
 {
        drm_sched_stop(&vm->sched, NULL);
@@ -1025,12 +1033,13 @@ int
 panthor_vm_alloc_va(struct panthor_vm *vm, u64 va, u64 size,
                    struct drm_mm_node *va_node)
 {
+       ssize_t vm_pgsz = panthor_vm_page_size(vm);
        int ret;
 
-       if (!size || (size & ~PAGE_MASK))
+       if (!size || !IS_ALIGNED(size, vm_pgsz))
                return -EINVAL;
 
-       if (va != PANTHOR_VM_KERNEL_AUTO_VA && (va & ~PAGE_MASK))
+       if (va != PANTHOR_VM_KERNEL_AUTO_VA && !IS_ALIGNED(va, vm_pgsz))
                return -EINVAL;
 
        mutex_lock(&vm->mm_lock);
@@ -1251,9 +1260,17 @@ static int panthor_vm_prepare_map_op_ctx(struct panthor_vm_op_ctx *op_ctx,
                goto err_cleanup;
        }
 
+       /* drm_gpuvm_bo_obtain_prealloc() will call drm_gpuvm_bo_put() on our
+        * pre-allocated BO if the <BO,VM> association exists. Given we
+        * only have one ref on preallocated_vm_bo, drm_gpuvm_bo_destroy() will
+        * be called immediately, and we have to hold the VM resv lock when
+        * calling this function.
+        */
+       dma_resv_lock(panthor_vm_resv(vm), NULL);
        mutex_lock(&bo->gpuva_list_lock);
        op_ctx->map.vm_bo = drm_gpuvm_bo_obtain_prealloc(preallocated_vm_bo);
        mutex_unlock(&bo->gpuva_list_lock);
+       dma_resv_unlock(panthor_vm_resv(vm));
 
        /* If the a vm_bo for this <VM,BO> combination exists, it already
         * retains a pin ref, and we can release the one we took earlier.
@@ -2358,11 +2375,12 @@ panthor_vm_bind_prepare_op_ctx(struct drm_file *file,
                               const struct drm_panthor_vm_bind_op *op,
                               struct panthor_vm_op_ctx *op_ctx)
 {
+       ssize_t vm_pgsz = panthor_vm_page_size(vm);
        struct drm_gem_object *gem;
        int ret;
 
        /* Aligned on page size. */
-       if ((op->va | op->size) & ~PAGE_MASK)
+       if (!IS_ALIGNED(op->va | op->size, vm_pgsz))
                return -EINVAL;
 
        switch (op->flags & DRM_PANTHOR_VM_BIND_OP_TYPE_MASK) {
index 6788771071e35557ccde471301bf4aa2ef32ec8f..8d21e83d8aba1e203df11883122a9e9356787803 100644 (file)
@@ -30,6 +30,7 @@ panthor_vm_get_bo_for_va(struct panthor_vm *vm, u64 va, u64 *bo_offset);
 
 int panthor_vm_active(struct panthor_vm *vm);
 void panthor_vm_idle(struct panthor_vm *vm);
+u32 panthor_vm_page_size(struct panthor_vm *vm);
 int panthor_vm_as(struct panthor_vm *vm);
 int panthor_vm_flush_all(struct panthor_vm *vm);
 
index 91a31b70c03752499101f43bdc04a942e1720968..9929e22f4d8d2e146e4ed6cbdd53a87d546334fc 100644 (file)
@@ -589,10 +589,11 @@ struct panthor_group {
         * @timedout: True when a timeout occurred on any of the queues owned by
         * this group.
         *
-        * Timeouts can be reported by drm_sched or by the FW. In any case, any
-        * timeout situation is unrecoverable, and the group becomes useless.
-        * We simply wait for all references to be dropped so we can release the
-        * group object.
+        * Timeouts can be reported by drm_sched or by the FW. If a reset is required,
+        * and the group can't be suspended, this also leads to a timeout. In any case,
+        * any timeout situation is unrecoverable, and the group becomes useless. We
+        * simply wait for all references to be dropped so we can release the group
+        * object.
         */
        bool timedout;
 
@@ -1103,7 +1104,13 @@ cs_slot_sync_queue_state_locked(struct panthor_device *ptdev, u32 csg_id, u32 cs
                        list_move_tail(&group->wait_node,
                                       &group->ptdev->scheduler->groups.waiting);
                }
-               group->blocked_queues |= BIT(cs_id);
+
+               /* The queue is only blocked if there's no deferred operation
+                * pending, which can be checked through the scoreboard status.
+                */
+               if (!cs_iface->output->status_scoreboards)
+                       group->blocked_queues |= BIT(cs_id);
+
                queue->syncwait.gpu_va = cs_iface->output->status_wait_sync_ptr;
                queue->syncwait.ref = cs_iface->output->status_wait_sync_value;
                status_wait_cond = cs_iface->output->status_wait & CS_STATUS_WAIT_SYNC_COND_MASK;
@@ -2046,6 +2053,7 @@ static void
 tick_ctx_cleanup(struct panthor_scheduler *sched,
                 struct panthor_sched_tick_ctx *ctx)
 {
+       struct panthor_device *ptdev = sched->ptdev;
        struct panthor_group *group, *tmp;
        u32 i;
 
@@ -2054,7 +2062,7 @@ tick_ctx_cleanup(struct panthor_scheduler *sched,
                        /* If everything went fine, we should only have groups
                         * to be terminated in the old_groups lists.
                         */
-                       drm_WARN_ON(&group->ptdev->base, !ctx->csg_upd_failed_mask &&
+                       drm_WARN_ON(&ptdev->base, !ctx->csg_upd_failed_mask &&
                                    group_can_run(group));
 
                        if (!group_can_run(group)) {
@@ -2077,7 +2085,7 @@ tick_ctx_cleanup(struct panthor_scheduler *sched,
                /* If everything went fine, the groups to schedule lists should
                 * be empty.
                 */
-               drm_WARN_ON(&group->ptdev->base,
+               drm_WARN_ON(&ptdev->base,
                            !ctx->csg_upd_failed_mask && !list_empty(&ctx->groups[i]));
 
                list_for_each_entry_safe(group, tmp, &ctx->groups[i], run_node) {
@@ -2633,6 +2641,12 @@ void panthor_sched_suspend(struct panthor_device *ptdev)
                csgs_upd_ctx_init(&upd_ctx);
                while (slot_mask) {
                        u32 csg_id = ffs(slot_mask) - 1;
+                       struct panthor_csg_slot *csg_slot = &sched->csg_slots[csg_id];
+
+                       /* We consider group suspension failures as fatal and flag the
+                        * group as unusable by setting timedout=true.
+                        */
+                       csg_slot->group->timedout = true;
 
                        csgs_upd_ctx_queue_reqs(ptdev, &upd_ctx, csg_id,
                                                CSG_STATE_TERMINATE,
@@ -3242,6 +3256,18 @@ int panthor_group_destroy(struct panthor_file *pfile, u32 group_handle)
        return 0;
 }
 
+static struct panthor_group *group_from_handle(struct panthor_group_pool *pool,
+                                              u32 group_handle)
+{
+       struct panthor_group *group;
+
+       xa_lock(&pool->xa);
+       group = group_get(xa_load(&pool->xa, group_handle));
+       xa_unlock(&pool->xa);
+
+       return group;
+}
+
 int panthor_group_get_state(struct panthor_file *pfile,
                            struct drm_panthor_group_get_state *get_state)
 {
@@ -3253,7 +3279,7 @@ int panthor_group_get_state(struct panthor_file *pfile,
        if (get_state->pad)
                return -EINVAL;
 
-       group = group_get(xa_load(&gpool->xa, get_state->group_handle));
+       group = group_from_handle(gpool, get_state->group_handle);
        if (!group)
                return -EINVAL;
 
@@ -3384,12 +3410,17 @@ panthor_job_create(struct panthor_file *pfile,
        job->call_info.latest_flush = qsubmit->latest_flush;
        INIT_LIST_HEAD(&job->node);
 
-       job->group = group_get(xa_load(&gpool->xa, group_handle));
+       job->group = group_from_handle(gpool, group_handle);
        if (!job->group) {
                ret = -EINVAL;
                goto err_put_job;
        }
 
+       if (!group_can_run(job->group)) {
+               ret = -EINVAL;
+               goto err_put_job;
+       }
+
        if (job->queue_idx >= job->group->queue_count ||
            !job->group->queues[job->queue_idx]) {
                ret = -EINVAL;
@@ -3424,13 +3455,8 @@ void panthor_job_update_resvs(struct drm_exec *exec, struct drm_sched_job *sched
 {
        struct panthor_job *job = container_of(sched_job, struct panthor_job, base);
 
-       /* Still not sure why we want USAGE_WRITE for external objects, since I
-        * was assuming this would be handled through explicit syncs being imported
-        * to external BOs with DMA_BUF_IOCTL_IMPORT_SYNC_FILE, but other drivers
-        * seem to pass DMA_RESV_USAGE_WRITE, so there must be a good reason.
-        */
        panthor_vm_update_resvs(job->group->vm, exec, &sched_job->s_fence->finished,
-                               DMA_RESV_USAGE_BOOKKEEP, DMA_RESV_USAGE_WRITE);
+                               DMA_RESV_USAGE_BOOKKEEP, DMA_RESV_USAGE_BOOKKEEP);
 }
 
 void panthor_sched_unplug(struct panthor_device *ptdev)
index 5bc3e6b41c34e2c42a2e5d152ee7eedbd94e8263..b31125eb9a6595c417de1a25ee178f0081268c37 100644 (file)
@@ -27,7 +27,7 @@
 #include <linux/slab.h>
 #include <linux/string_helpers.h>
 
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #include <drm/drm_device.h>
 #include <drm/drm_util.h>
index fca8b08535a5443c8e20c40453280e0ae5ca8d4d..6328627b7c342cefb2f0b2c3aafcb688f2db4482 100644 (file)
@@ -228,10 +228,8 @@ void radeon_dp_aux_init(struct radeon_connector *radeon_connector)
 {
        struct drm_device *dev = radeon_connector->base.dev;
        struct radeon_device *rdev = dev->dev_private;
-       int ret;
 
        radeon_connector->ddc_bus->rec.hpd = radeon_connector->hpd.hpd;
-       radeon_connector->ddc_bus->aux.dev = radeon_connector->base.kdev;
        radeon_connector->ddc_bus->aux.drm_dev = radeon_connector->base.dev;
        if (ASIC_IS_DCE5(rdev)) {
                if (radeon_auxch)
@@ -242,11 +240,8 @@ void radeon_dp_aux_init(struct radeon_connector *radeon_connector)
                radeon_connector->ddc_bus->aux.transfer = radeon_dp_aux_transfer_atom;
        }
 
-       ret = drm_dp_aux_register(&radeon_connector->ddc_bus->aux);
-       if (!ret)
-               radeon_connector->ddc_bus->has_aux = true;
-
-       WARN(ret, "drm_dp_aux_register() failed with error %d\n", ret);
+       drm_dp_aux_init(&radeon_connector->ddc_bus->aux);
+       radeon_connector->ddc_bus->has_aux = true;
 }
 
 /***** general DP utility functions *****/
index 528a8f3677c295c5cfb40bc888214d1f461b7020..f9c73c55f04f76ed5c78e9169004f8a7dea6004e 100644 (file)
@@ -1786,6 +1786,20 @@ static enum drm_mode_status radeon_dp_mode_valid(struct drm_connector *connector
        return MODE_OK;
 }
 
+static int
+radeon_connector_late_register(struct drm_connector *connector)
+{
+       struct radeon_connector *radeon_connector = to_radeon_connector(connector);
+       int r = 0;
+
+       if (radeon_connector->ddc_bus->has_aux) {
+               radeon_connector->ddc_bus->aux.dev = radeon_connector->base.kdev;
+               r = drm_dp_aux_register(&radeon_connector->ddc_bus->aux);
+       }
+
+       return r;
+}
+
 static const struct drm_connector_helper_funcs radeon_dp_connector_helper_funcs = {
        .get_modes = radeon_dp_get_modes,
        .mode_valid = radeon_dp_mode_valid,
@@ -1800,6 +1814,7 @@ static const struct drm_connector_funcs radeon_dp_connector_funcs = {
        .early_unregister = radeon_connector_unregister,
        .destroy = radeon_connector_destroy,
        .force = radeon_dvi_force,
+       .late_register = radeon_connector_late_register,
 };
 
 static const struct drm_connector_funcs radeon_edp_connector_funcs = {
@@ -1810,6 +1825,7 @@ static const struct drm_connector_funcs radeon_edp_connector_funcs = {
        .early_unregister = radeon_connector_unregister,
        .destroy = radeon_connector_destroy,
        .force = radeon_dvi_force,
+       .late_register = radeon_connector_late_register,
 };
 
 static const struct drm_connector_funcs radeon_lvds_bridge_connector_funcs = {
@@ -1820,6 +1836,7 @@ static const struct drm_connector_funcs radeon_lvds_bridge_connector_funcs = {
        .early_unregister = radeon_connector_unregister,
        .destroy = radeon_connector_destroy,
        .force = radeon_dvi_force,
+       .late_register = radeon_connector_late_register,
 };
 
 void
index 0f723292409e5a38ba7d0dbeaabdbd9917178403..fafed331e0a03eb3d8b939f654d2ef5fab04aace 100644 (file)
@@ -43,7 +43,7 @@ static uint32_t radeon_encoder_clones(struct drm_encoder *encoder)
        struct radeon_device *rdev = dev->dev_private;
        struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
        struct drm_encoder *clone_encoder;
-       uint32_t index_mask = 0;
+       uint32_t index_mask = drm_encoder_mask(encoder);
        int count;
 
        /* DIG routing gets problematic */
index 9735f4968b86e6d6f9b09fbec98eef482ce90aad..bf2d4b16dc2a7ff0bb7dec7806947365a65e3e56 100644 (file)
@@ -44,8 +44,6 @@ struct sg_table *radeon_gem_prime_get_sg_table(struct drm_gem_object *obj);
 int radeon_gem_prime_pin(struct drm_gem_object *obj);
 void radeon_gem_prime_unpin(struct drm_gem_object *obj);
 
-const struct drm_gem_object_funcs radeon_gem_object_funcs;
-
 static vm_fault_t radeon_gem_fault(struct vm_fault *vmf)
 {
        struct ttm_buffer_object *bo = vmf->vma->vm_private_data;
@@ -132,7 +130,6 @@ retry:
                return r;
        }
        *obj = &robj->tbo.base;
-       (*obj)->funcs = &radeon_gem_object_funcs;
        robj->pid = task_pid_nr(current);
 
        mutex_lock(&rdev->gem.mutex);
index d0e4b43d155c69ad625672ab0f1c3a66ef672e5b..7672404fdb29b563d4b7106c10edb1aaeb51f7a8 100644 (file)
@@ -151,6 +151,7 @@ int radeon_bo_create(struct radeon_device *rdev,
        if (bo == NULL)
                return -ENOMEM;
        drm_gem_private_object_init(rdev_to_drm(rdev), &bo->tbo.base, size);
+       bo->tbo.base.funcs = &radeon_gem_object_funcs;
        bo->rdev = rdev;
        bo->surface_reg = -1;
        INIT_LIST_HEAD(&bo->list);
index 58c8161289fea9dfdb07c5b65a5b3ec682d918a7..a75eede8bf8dabd235b1fe1905c860ebaa78f384 100644 (file)
@@ -133,8 +133,10 @@ void drm_sched_entity_modify_sched(struct drm_sched_entity *entity,
 {
        WARN_ON(!num_sched_list || !sched_list);
 
+       spin_lock(&entity->rq_lock);
        entity->sched_list = sched_list;
        entity->num_sched_list = num_sched_list;
+       spin_unlock(&entity->rq_lock);
 }
 EXPORT_SYMBOL(drm_sched_entity_modify_sched);
 
@@ -380,7 +382,7 @@ static void drm_sched_entity_wakeup(struct dma_fence *f,
                container_of(cb, struct drm_sched_entity, cb);
 
        drm_sched_entity_clear_dep(f, cb);
-       drm_sched_wakeup(entity->rq->sched, entity);
+       drm_sched_wakeup(entity->rq->sched);
 }
 
 /**
@@ -597,6 +599,9 @@ void drm_sched_entity_push_job(struct drm_sched_job *sched_job)
 
        /* first job wakes up scheduler */
        if (first) {
+               struct drm_gpu_scheduler *sched;
+               struct drm_sched_rq *rq;
+
                /* Add the entity to the run queue */
                spin_lock(&entity->rq_lock);
                if (entity->stopped) {
@@ -606,13 +611,16 @@ void drm_sched_entity_push_job(struct drm_sched_job *sched_job)
                        return;
                }
 
-               drm_sched_rq_add_entity(entity->rq, entity);
+               rq = entity->rq;
+               sched = rq->sched;
+
+               drm_sched_rq_add_entity(rq, entity);
                spin_unlock(&entity->rq_lock);
 
                if (drm_sched_policy == DRM_SCHED_POLICY_FIFO)
                        drm_sched_rq_update_fifo(entity, submit_ts);
 
-               drm_sched_wakeup(entity->rq->sched, entity);
+               drm_sched_wakeup(sched);
        }
 }
 EXPORT_SYMBOL(drm_sched_entity_push_job);
index ab53ab486fe69daca7e9537afd8bd0445dd4498e..e97c6c60bc96efc452b3045b3e0d359fd2d51ac0 100644 (file)
 #define CREATE_TRACE_POINTS
 #include "gpu_scheduler_trace.h"
 
+#ifdef CONFIG_LOCKDEP
+static struct lockdep_map drm_sched_lockdep_map = {
+       .name = "drm_sched_lockdep_map"
+};
+#endif
+
 #define to_drm_sched_job(sched_job)            \
                container_of((sched_job), struct drm_sched_job, queue_node)
 
@@ -1013,15 +1019,12 @@ EXPORT_SYMBOL(drm_sched_job_cleanup);
 /**
  * drm_sched_wakeup - Wake up the scheduler if it is ready to queue
  * @sched: scheduler instance
- * @entity: the scheduler entity
  *
  * Wake up the scheduler if we can queue jobs.
  */
-void drm_sched_wakeup(struct drm_gpu_scheduler *sched,
-                     struct drm_sched_entity *entity)
+void drm_sched_wakeup(struct drm_gpu_scheduler *sched)
 {
-       if (drm_sched_can_queue(sched, entity))
-               drm_sched_run_job_queue(sched);
+       drm_sched_run_job_queue(sched);
 }
 
 /**
@@ -1272,7 +1275,13 @@ int drm_sched_init(struct drm_gpu_scheduler *sched,
                sched->submit_wq = submit_wq;
                sched->own_submit_wq = false;
        } else {
-               sched->submit_wq = alloc_ordered_workqueue(name, 0);
+#ifdef CONFIG_LOCKDEP
+               sched->submit_wq = alloc_ordered_workqueue_lockdep_map(name,
+                                                                      WQ_MEM_RECLAIM,
+                                                                      &drm_sched_lockdep_map);
+#else
+               sched->submit_wq = alloc_ordered_workqueue(name, WQ_MEM_RECLAIM);
+#endif
                if (!sched->submit_wq)
                        return -ENOMEM;
 
index c9eb329665ec54b9634633e19ee1b9ba0eb89b93..34d22ba210b0b46651a2911baf6e0ce4452f78ba 100644 (file)
@@ -1153,8 +1153,8 @@ static int host1x_drm_probe(struct host1x_device *dev)
 
        if (host1x_drm_wants_iommu(dev) && device_iommu_mapped(dma_dev)) {
                tegra->domain = iommu_paging_domain_alloc(dma_dev);
-               if (!tegra->domain) {
-                       err = -ENOMEM;
+               if (IS_ERR(tegra->domain)) {
+                       err = PTR_ERR(tegra->domain);
                        goto free;
                }
 
index 4de1ea0fc7c0bb970a73005caae96594ca05cd5e..00c8564520e70818c2814b9c30261f928a4755b6 100644 (file)
@@ -46,7 +46,6 @@ struct gr3d {
        unsigned int nclocks;
        struct reset_control_bulk_data resets[RST_GR3D_MAX];
        unsigned int nresets;
-       struct dev_pm_domain_list *pd_list;
 
        DECLARE_BITMAP(addr_regs, GR3D_NUM_REGS);
 };
@@ -370,12 +369,18 @@ static int gr3d_power_up_legacy_domain(struct device *dev, const char *name,
        return 0;
 }
 
+static void gr3d_del_link(void *link)
+{
+       device_link_del(link);
+}
+
 static int gr3d_init_power(struct device *dev, struct gr3d *gr3d)
 {
-       struct dev_pm_domain_attach_data pd_data = {
-               .pd_names = (const char *[]) { "3d0", "3d1" },
-               .num_pd_names = 2,
-       };
+       static const char * const opp_genpd_names[] = { "3d0", "3d1", NULL };
+       const u32 link_flags = DL_FLAG_STATELESS | DL_FLAG_PM_RUNTIME;
+       struct device **opp_virt_devs, *pd_dev;
+       struct device_link *link;
+       unsigned int i;
        int err;
 
        err = of_count_phandle_with_args(dev->of_node, "power-domains",
@@ -409,10 +414,29 @@ static int gr3d_init_power(struct device *dev, struct gr3d *gr3d)
        if (dev->pm_domain)
                return 0;
 
-       err = dev_pm_domain_attach_list(dev, &pd_data, &gr3d->pd_list);
-       if (err < 0)
+       err = devm_pm_opp_attach_genpd(dev, opp_genpd_names, &opp_virt_devs);
+       if (err)
                return err;
 
+       for (i = 0; opp_genpd_names[i]; i++) {
+               pd_dev = opp_virt_devs[i];
+               if (!pd_dev) {
+                       dev_err(dev, "failed to get %s power domain\n",
+                               opp_genpd_names[i]);
+                       return -EINVAL;
+               }
+
+               link = device_link_add(dev, pd_dev, link_flags);
+               if (!link) {
+                       dev_err(dev, "failed to link to %s\n", dev_name(pd_dev));
+                       return -EINVAL;
+               }
+
+               err = devm_add_action_or_reset(dev, gr3d_del_link, link);
+               if (err)
+                       return err;
+       }
+
        return 0;
 }
 
@@ -503,13 +527,13 @@ static int gr3d_probe(struct platform_device *pdev)
 
        err = devm_tegra_core_dev_init_opp_table_common(&pdev->dev);
        if (err)
-               goto err;
+               return err;
 
        err = host1x_client_register(&gr3d->client.base);
        if (err < 0) {
                dev_err(&pdev->dev, "failed to register host1x client: %d\n",
                        err);
-               goto err;
+               return err;
        }
 
        /* initialize address register map */
@@ -517,9 +541,6 @@ static int gr3d_probe(struct platform_device *pdev)
                set_bit(gr3d_addr_regs[i], gr3d->addr_regs);
 
        return 0;
-err:
-       dev_pm_domain_detach_list(gr3d->pd_list);
-       return err;
 }
 
 static void gr3d_remove(struct platform_device *pdev)
@@ -528,7 +549,6 @@ static void gr3d_remove(struct platform_device *pdev)
 
        pm_runtime_disable(&pdev->dev);
        host1x_client_unregister(&gr3d->client.base);
-       dev_pm_domain_detach_list(gr3d->pd_list);
 }
 
 static int __maybe_unused gr3d_runtime_suspend(struct device *dev)
index 15e36a8db6858a48a612c13682e24c56a24d3bc1..6bba97d0be88ef34f01c8786175cf2b06c414ef5 100644 (file)
@@ -996,7 +996,7 @@ static void drm_test_drm_hdmi_compute_mode_clock_rgb(struct kunit *test)
        unsigned long long rate;
        struct drm_device *drm = &priv->drm;
 
-       mode = drm_display_mode_from_cea_vic(drm, 16);
+       mode = drm_kunit_display_mode_from_cea_vic(test, drm, 16);
        KUNIT_ASSERT_NOT_NULL(test, mode);
 
        KUNIT_ASSERT_FALSE(test, mode->flags & DRM_MODE_FLAG_DBLCLK);
@@ -1017,7 +1017,7 @@ static void drm_test_drm_hdmi_compute_mode_clock_rgb_10bpc(struct kunit *test)
        unsigned long long rate;
        struct drm_device *drm = &priv->drm;
 
-       mode = drm_display_mode_from_cea_vic(drm, 16);
+       mode = drm_kunit_display_mode_from_cea_vic(test, drm, 16);
        KUNIT_ASSERT_NOT_NULL(test, mode);
 
        KUNIT_ASSERT_FALSE(test, mode->flags & DRM_MODE_FLAG_DBLCLK);
@@ -1038,7 +1038,7 @@ static void drm_test_drm_hdmi_compute_mode_clock_rgb_10bpc_vic_1(struct kunit *t
        unsigned long long rate;
        struct drm_device *drm = &priv->drm;
 
-       mode = drm_display_mode_from_cea_vic(drm, 1);
+       mode = drm_kunit_display_mode_from_cea_vic(test, drm, 1);
        KUNIT_ASSERT_NOT_NULL(test, mode);
 
        rate = drm_hdmi_compute_mode_clock(mode, 10, HDMI_COLORSPACE_RGB);
@@ -1056,7 +1056,7 @@ static void drm_test_drm_hdmi_compute_mode_clock_rgb_12bpc(struct kunit *test)
        unsigned long long rate;
        struct drm_device *drm = &priv->drm;
 
-       mode = drm_display_mode_from_cea_vic(drm, 16);
+       mode = drm_kunit_display_mode_from_cea_vic(test, drm, 16);
        KUNIT_ASSERT_NOT_NULL(test, mode);
 
        KUNIT_ASSERT_FALSE(test, mode->flags & DRM_MODE_FLAG_DBLCLK);
@@ -1077,7 +1077,7 @@ static void drm_test_drm_hdmi_compute_mode_clock_rgb_12bpc_vic_1(struct kunit *t
        unsigned long long rate;
        struct drm_device *drm = &priv->drm;
 
-       mode = drm_display_mode_from_cea_vic(drm, 1);
+       mode = drm_kunit_display_mode_from_cea_vic(test, drm, 1);
        KUNIT_ASSERT_NOT_NULL(test, mode);
 
        rate = drm_hdmi_compute_mode_clock(mode, 12, HDMI_COLORSPACE_RGB);
@@ -1095,7 +1095,7 @@ static void drm_test_drm_hdmi_compute_mode_clock_rgb_double(struct kunit *test)
        unsigned long long rate;
        struct drm_device *drm = &priv->drm;
 
-       mode = drm_display_mode_from_cea_vic(drm, 6);
+       mode = drm_kunit_display_mode_from_cea_vic(test, drm, 6);
        KUNIT_ASSERT_NOT_NULL(test, mode);
 
        KUNIT_ASSERT_TRUE(test, mode->flags & DRM_MODE_FLAG_DBLCLK);
@@ -1118,7 +1118,7 @@ static void drm_test_connector_hdmi_compute_mode_clock_yuv420_valid(struct kunit
        unsigned long long rate;
        unsigned int vic = *(unsigned int *)test->param_value;
 
-       mode = drm_display_mode_from_cea_vic(drm, vic);
+       mode = drm_kunit_display_mode_from_cea_vic(test, drm, vic);
        KUNIT_ASSERT_NOT_NULL(test, mode);
 
        KUNIT_ASSERT_FALSE(test, mode->flags & DRM_MODE_FLAG_DBLCLK);
@@ -1155,7 +1155,7 @@ static void drm_test_connector_hdmi_compute_mode_clock_yuv420_10_bpc(struct kuni
                drm_hdmi_compute_mode_clock_yuv420_vic_valid_tests[0];
        unsigned long long rate;
 
-       mode = drm_display_mode_from_cea_vic(drm, vic);
+       mode = drm_kunit_display_mode_from_cea_vic(test, drm, vic);
        KUNIT_ASSERT_NOT_NULL(test, mode);
 
        KUNIT_ASSERT_FALSE(test, mode->flags & DRM_MODE_FLAG_DBLCLK);
@@ -1180,7 +1180,7 @@ static void drm_test_connector_hdmi_compute_mode_clock_yuv420_12_bpc(struct kuni
                drm_hdmi_compute_mode_clock_yuv420_vic_valid_tests[0];
        unsigned long long rate;
 
-       mode = drm_display_mode_from_cea_vic(drm, vic);
+       mode = drm_kunit_display_mode_from_cea_vic(test, drm, vic);
        KUNIT_ASSERT_NOT_NULL(test, mode);
 
        KUNIT_ASSERT_FALSE(test, mode->flags & DRM_MODE_FLAG_DBLCLK);
@@ -1203,7 +1203,7 @@ static void drm_test_connector_hdmi_compute_mode_clock_yuv422_8_bpc(struct kunit
        struct drm_device *drm = &priv->drm;
        unsigned long long rate;
 
-       mode = drm_display_mode_from_cea_vic(drm, 16);
+       mode = drm_kunit_display_mode_from_cea_vic(test, drm, 16);
        KUNIT_ASSERT_NOT_NULL(test, mode);
 
        KUNIT_ASSERT_FALSE(test, mode->flags & DRM_MODE_FLAG_DBLCLK);
@@ -1225,7 +1225,7 @@ static void drm_test_connector_hdmi_compute_mode_clock_yuv422_10_bpc(struct kuni
        struct drm_device *drm = &priv->drm;
        unsigned long long rate;
 
-       mode = drm_display_mode_from_cea_vic(drm, 16);
+       mode = drm_kunit_display_mode_from_cea_vic(test, drm, 16);
        KUNIT_ASSERT_NOT_NULL(test, mode);
 
        KUNIT_ASSERT_FALSE(test, mode->flags & DRM_MODE_FLAG_DBLCLK);
@@ -1247,7 +1247,7 @@ static void drm_test_connector_hdmi_compute_mode_clock_yuv422_12_bpc(struct kuni
        struct drm_device *drm = &priv->drm;
        unsigned long long rate;
 
-       mode = drm_display_mode_from_cea_vic(drm, 16);
+       mode = drm_kunit_display_mode_from_cea_vic(test, drm, 16);
        KUNIT_ASSERT_NOT_NULL(test, mode);
 
        KUNIT_ASSERT_FALSE(test, mode->flags & DRM_MODE_FLAG_DBLCLK);
index 34ee95d41f2966ab23a60deb37d689430f6b0985..294773342e710dc56772f839c2db9c2e487bbc1e 100644 (file)
@@ -441,7 +441,7 @@ static void drm_test_check_broadcast_rgb_auto_cea_mode_vic_1(struct kunit *test)
        ctx = drm_kunit_helper_acquire_ctx_alloc(test);
        KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctx);
 
-       mode = drm_display_mode_from_cea_vic(drm, 1);
+       mode = drm_kunit_display_mode_from_cea_vic(test, drm, 1);
        KUNIT_ASSERT_NOT_NULL(test, mode);
 
        drm = &priv->drm;
@@ -555,7 +555,7 @@ static void drm_test_check_broadcast_rgb_full_cea_mode_vic_1(struct kunit *test)
        ctx = drm_kunit_helper_acquire_ctx_alloc(test);
        KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctx);
 
-       mode = drm_display_mode_from_cea_vic(drm, 1);
+       mode = drm_kunit_display_mode_from_cea_vic(test, drm, 1);
        KUNIT_ASSERT_NOT_NULL(test, mode);
 
        drm = &priv->drm;
@@ -671,7 +671,7 @@ static void drm_test_check_broadcast_rgb_limited_cea_mode_vic_1(struct kunit *te
        ctx = drm_kunit_helper_acquire_ctx_alloc(test);
        KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctx);
 
-       mode = drm_display_mode_from_cea_vic(drm, 1);
+       mode = drm_kunit_display_mode_from_cea_vic(test, drm, 1);
        KUNIT_ASSERT_NOT_NULL(test, mode);
 
        drm = &priv->drm;
@@ -1263,7 +1263,7 @@ static void drm_test_check_output_bpc_format_vic_1(struct kunit *test)
        ctx = drm_kunit_helper_acquire_ctx_alloc(test);
        KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctx);
 
-       mode = drm_display_mode_from_cea_vic(drm, 1);
+       mode = drm_kunit_display_mode_from_cea_vic(test, drm, 1);
        KUNIT_ASSERT_NOT_NULL(test, mode);
 
        /*
index aa62719dab0e4753e5fb374c2a3c36b614326dc2..04a6b8cc62ac673564bead59cf906344acfd0d94 100644 (file)
@@ -3,6 +3,7 @@
 #include <drm/drm_atomic.h>
 #include <drm/drm_atomic_helper.h>
 #include <drm/drm_drv.h>
+#include <drm/drm_edid.h>
 #include <drm/drm_fourcc.h>
 #include <drm/drm_kunit_helpers.h>
 #include <drm/drm_managed.h>
@@ -311,6 +312,47 @@ drm_kunit_helper_create_crtc(struct kunit *test,
 }
 EXPORT_SYMBOL_GPL(drm_kunit_helper_create_crtc);
 
+static void kunit_action_drm_mode_destroy(void *ptr)
+{
+       struct drm_display_mode *mode = ptr;
+
+       drm_mode_destroy(NULL, mode);
+}
+
+/**
+ * drm_kunit_display_mode_from_cea_vic() - return a mode for CEA VIC
+                                          for a KUnit test
+ * @test: The test context object
+ * @dev: DRM device
+ * @video_code: CEA VIC of the mode
+ *
+ * Creates a new mode matching the specified CEA VIC for a KUnit test.
+ *
+ * Resources will be cleaned up automatically.
+ *
+ * Returns: A new drm_display_mode on success or NULL on failure
+ */
+struct drm_display_mode *
+drm_kunit_display_mode_from_cea_vic(struct kunit *test, struct drm_device *dev,
+                                   u8 video_code)
+{
+       struct drm_display_mode *mode;
+       int ret;
+
+       mode = drm_display_mode_from_cea_vic(dev, video_code);
+       if (!mode)
+               return NULL;
+
+       ret = kunit_add_action_or_reset(test,
+                                       kunit_action_drm_mode_destroy,
+                                       mode);
+       if (ret)
+               return NULL;
+
+       return mode;
+}
+EXPORT_SYMBOL_GPL(drm_kunit_display_mode_from_cea_vic);
+
 MODULE_AUTHOR("Maxime Ripard <[email protected]>");
 MODULE_DESCRIPTION("KUnit test suite helper functions");
 MODULE_LICENSE("GPL");
index 5ff1037a34536d0de6380a2b31c3d5549312dbc1..62224992988f283e9c896bf7bf440cbf366ac282 100644 (file)
@@ -7,7 +7,7 @@
  * Copyright (C) 2009 Bernie Thompson <[email protected]>
  */
 
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #include "udl_drv.h"
 #include "udl_proto.h"
index cd7f1eedf17fe0cddd83a7f96cf15f29588f9bce..00cd081d7873271cdd64476ab0167fcfb019ea4a 100644 (file)
@@ -306,6 +306,11 @@ void v3d_perfmon_open_file(struct v3d_file_priv *v3d_priv)
 static int v3d_perfmon_idr_del(int id, void *elem, void *data)
 {
        struct v3d_perfmon *perfmon = elem;
+       struct v3d_dev *v3d = (struct v3d_dev *)data;
+
+       /* If the active perfmon is being destroyed, stop it first */
+       if (perfmon == v3d->active_perfmon)
+               v3d_perfmon_stop(v3d, perfmon, false);
 
        v3d_perfmon_put(perfmon);
 
@@ -314,8 +319,10 @@ static int v3d_perfmon_idr_del(int id, void *elem, void *data)
 
 void v3d_perfmon_close_file(struct v3d_file_priv *v3d_priv)
 {
+       struct v3d_dev *v3d = v3d_priv->v3d;
+
        mutex_lock(&v3d_priv->perfmon.lock);
-       idr_for_each(&v3d_priv->perfmon.idr, v3d_perfmon_idr_del, NULL);
+       idr_for_each(&v3d_priv->perfmon.idr, v3d_perfmon_idr_del, v3d);
        idr_destroy(&v3d_priv->perfmon.idr);
        mutex_unlock(&v3d_priv->perfmon.lock);
        mutex_destroy(&v3d_priv->perfmon.lock);
index 8c041d7ce4f1bd7df3a948420328fa3f043f3f20..87dccaecc3e57d1c4c6c1bcc4988fbd590f1d8c5 100644 (file)
@@ -139,7 +139,15 @@ int hgsmi_update_pointer_shape(struct gen_pool *ctx, u32 flags,
                flags |= VBOX_MOUSE_POINTER_VISIBLE;
        }
 
-       p = hgsmi_buffer_alloc(ctx, sizeof(*p) + pixel_len, HGSMI_CH_VBVA,
+       /*
+        * The 4 extra bytes come from switching struct vbva_mouse_pointer_shape
+        * from having a 4 bytes fixed array at the end to using a proper VLA
+        * at the end. These 4 extra bytes were not subtracted from sizeof(*p)
+        * before the switch to the VLA, so this way the behavior is unchanged.
+        * Chances are these 4 extra bytes are not necessary but they are kept
+        * to avoid regressions.
+        */
+       p = hgsmi_buffer_alloc(ctx, sizeof(*p) + pixel_len + 4, HGSMI_CH_VBVA,
                               VBVA_MOUSE_POINTER_SHAPE);
        if (!p)
                return -ENOMEM;
index f60d82504da02c8e70bce2ed914b6cb00d02f425..79ec8481de0e48417dd9c71e8416bb7d31411679 100644 (file)
@@ -351,10 +351,8 @@ struct vbva_mouse_pointer_shape {
         * Bytes in the gap between the AND and the XOR mask are undefined.
         * XOR mask scanlines have no gap between them and size of XOR mask is:
         * xor_len = width * 4 * height.
-        *
-        * Preallocate 4 bytes for accessing actual data as p->data.
         */
-       u8 data[4];
+       u8 data[];
 } __packed;
 
 /* pointer is visible */
index c4ac2c946238150f9897f9eb81cfbab3764ee630..c00a5cc2316d20e04c2fff21f861b26cd05d668f 100644 (file)
@@ -116,6 +116,11 @@ void vc4_perfmon_open_file(struct vc4_file *vc4file)
 static int vc4_perfmon_idr_del(int id, void *elem, void *data)
 {
        struct vc4_perfmon *perfmon = elem;
+       struct vc4_dev *vc4 = (struct vc4_dev *)data;
+
+       /* If the active perfmon is being destroyed, stop it first */
+       if (perfmon == vc4->active_perfmon)
+               vc4_perfmon_stop(vc4, perfmon, false);
 
        vc4_perfmon_put(perfmon);
 
@@ -130,7 +135,7 @@ void vc4_perfmon_close_file(struct vc4_file *vc4file)
                return;
 
        mutex_lock(&vc4file->perfmon.lock);
-       idr_for_each(&vc4file->perfmon.idr, vc4_perfmon_idr_del, NULL);
+       idr_for_each(&vc4file->perfmon.idr, vc4_perfmon_idr_del, vc4);
        idr_destroy(&vc4file->perfmon.idr);
        mutex_unlock(&vc4file->perfmon.lock);
        mutex_destroy(&vc4file->perfmon.lock);
index 890a66a2361f4e19826a27096e0a88ffd01447cb..64bd7d74854e1a079cf282c9e063ca5f02110fcc 100644 (file)
@@ -635,10 +635,8 @@ out:
                kunmap_atomic(d.src_addr);
        if (d.dst_addr)
                kunmap_atomic(d.dst_addr);
-       if (src_pages)
-               kvfree(src_pages);
-       if (dst_pages)
-               kvfree(dst_pages);
+       kvfree(src_pages);
+       kvfree(dst_pages);
 
        return ret;
 }
index 3f4719b3c26818202c87583ca08c25703c8622a7..4e2807f5f94cf374b0f6e51f9d03235b859f7776 100644 (file)
@@ -62,7 +62,7 @@
 #define VMWGFX_DRIVER_MINOR 20
 #define VMWGFX_DRIVER_PATCHLEVEL 0
 #define VMWGFX_FIFO_STATIC_SIZE (1024*1024)
-#define VMWGFX_MAX_DISPLAYS 16
+#define VMWGFX_NUM_DISPLAY_UNITS 8
 #define VMWGFX_CMD_BOUNCE_INIT_SIZE 32768
 
 #define VMWGFX_MIN_INITIAL_WIDTH 1280
@@ -82,7 +82,7 @@
 #define VMWGFX_NUM_GB_CONTEXT 256
 #define VMWGFX_NUM_GB_SHADER 20000
 #define VMWGFX_NUM_GB_SURFACE 32768
-#define VMWGFX_NUM_GB_SCREEN_TARGET VMWGFX_MAX_DISPLAYS
+#define VMWGFX_NUM_GB_SCREEN_TARGET VMWGFX_NUM_DISPLAY_UNITS
 #define VMWGFX_NUM_DXCONTEXT 256
 #define VMWGFX_NUM_DXQUERY 512
 #define VMWGFX_NUM_MOB (VMWGFX_NUM_GB_CONTEXT +\
index 288ed0bb75cb986c94086323202f18dad3bdb3ee..63b8d7591253cdada79ea8e34153930011bd4b8f 100644 (file)
@@ -1283,7 +1283,6 @@ static int vmw_kms_new_framebuffer_surface(struct vmw_private *dev_priv,
 {
        struct drm_device *dev = &dev_priv->drm;
        struct vmw_framebuffer_surface *vfbs;
-       enum SVGA3dSurfaceFormat format;
        struct vmw_surface *surface;
        int ret;
 
@@ -1320,34 +1319,6 @@ static int vmw_kms_new_framebuffer_surface(struct vmw_private *dev_priv,
                return -EINVAL;
        }
 
-       switch (mode_cmd->pixel_format) {
-       case DRM_FORMAT_ARGB8888:
-               format = SVGA3D_A8R8G8B8;
-               break;
-       case DRM_FORMAT_XRGB8888:
-               format = SVGA3D_X8R8G8B8;
-               break;
-       case DRM_FORMAT_RGB565:
-               format = SVGA3D_R5G6B5;
-               break;
-       case DRM_FORMAT_XRGB1555:
-               format = SVGA3D_A1R5G5B5;
-               break;
-       default:
-               DRM_ERROR("Invalid pixel format: %p4cc\n",
-                         &mode_cmd->pixel_format);
-               return -EINVAL;
-       }
-
-       /*
-        * For DX, surface format validation is done when surface->scanout
-        * is set.
-        */
-       if (!has_sm4_context(dev_priv) && format != surface->metadata.format) {
-               DRM_ERROR("Invalid surface format for requested mode.\n");
-               return -EINVAL;
-       }
-
        vfbs = kzalloc(sizeof(*vfbs), GFP_KERNEL);
        if (!vfbs) {
                ret = -ENOMEM;
@@ -1539,6 +1510,7 @@ static struct drm_framebuffer *vmw_kms_fb_create(struct drm_device *dev,
                DRM_ERROR("Surface size cannot exceed %dx%d\n",
                        dev_priv->texture_max_width,
                        dev_priv->texture_max_height);
+               ret = -EINVAL;
                goto err_out;
        }
 
@@ -2225,7 +2197,7 @@ int vmw_kms_update_layout_ioctl(struct drm_device *dev, void *data,
        struct drm_mode_config *mode_config = &dev->mode_config;
        struct drm_vmw_update_layout_arg *arg =
                (struct drm_vmw_update_layout_arg *)data;
-       void __user *user_rects;
+       const void __user *user_rects;
        struct drm_vmw_rect *rects;
        struct drm_rect *drm_rects;
        unsigned rects_size;
@@ -2237,6 +2209,8 @@ int vmw_kms_update_layout_ioctl(struct drm_device *dev, void *data,
                                            VMWGFX_MIN_INITIAL_HEIGHT};
                vmw_du_update_layout(dev_priv, 1, &def_rect);
                return 0;
+       } else if (arg->num_outputs > VMWGFX_NUM_DISPLAY_UNITS) {
+               return -E2BIG;
        }
 
        rects_size = arg->num_outputs * sizeof(struct drm_vmw_rect);
index 6141fadf81efeb2cda7d91274dce16def626e46d..2a6c6d6581e02bb51c9d70cef3ddce1a0f9ecd1a 100644 (file)
@@ -199,9 +199,6 @@ struct vmw_kms_dirty {
        s32 unit_y2;
 };
 
-#define VMWGFX_NUM_DISPLAY_UNITS 8
-
-
 #define vmw_framebuffer_to_vfb(x) \
        container_of(x, struct vmw_framebuffer, base)
 #define vmw_framebuffer_to_vfbs(x) \
index fab155a68054a71b9840c7b8a6356be815be6505..82d18b88f4a7e7aaff2d7123fce1af05754e34d9 100644 (file)
@@ -886,6 +886,10 @@ static int vmw_stdu_connector_atomic_check(struct drm_connector *conn,
        struct drm_crtc_state *new_crtc_state;
 
        conn_state = drm_atomic_get_connector_state(state, conn);
+
+       if (IS_ERR(conn_state))
+               return PTR_ERR(conn_state);
+
        du = vmw_connector_to_stdu(conn);
 
        if (!conn_state->crtc)
index 1625b30d9970046607c31074cba85e592dbfa4b4..5721c74da3e0b94535518ed86b302e5db2ced728 100644 (file)
@@ -2276,9 +2276,12 @@ int vmw_dumb_create(struct drm_file *file_priv,
        const struct SVGA3dSurfaceDesc *desc = vmw_surface_get_desc(format);
        SVGA3dSurfaceAllFlags flags = SVGA3D_SURFACE_HINT_TEXTURE |
                                      SVGA3D_SURFACE_HINT_RENDERTARGET |
-                                     SVGA3D_SURFACE_SCREENTARGET |
-                                     SVGA3D_SURFACE_BIND_SHADER_RESOURCE |
-                                     SVGA3D_SURFACE_BIND_RENDER_TARGET;
+                                     SVGA3D_SURFACE_SCREENTARGET;
+
+       if (vmw_surface_is_dx_screen_target_format(format)) {
+               flags |= SVGA3D_SURFACE_BIND_SHADER_RESOURCE |
+                        SVGA3D_SURFACE_BIND_RENDER_TARGET;
+       }
 
        /*
         * Without mob support we're just going to use raw memory buffer
index 75736faf2a8028cc822eff2d75ef83dcc9276784..c6e0c8d77a70f7657b0fe7066599c81bfd08c596 100644 (file)
@@ -309,18 +309,7 @@ static void xe_display_flush_cleanup_work(struct xe_device *xe)
 }
 
 /* TODO: System and runtime suspend/resume sequences will be sanitized as a follow-up. */
-void xe_display_pm_runtime_suspend(struct xe_device *xe)
-{
-       if (!xe->info.probe_display)
-               return;
-
-       if (xe->d3cold.allowed)
-               xe_display_pm_suspend(xe, true);
-
-       intel_hpd_poll_enable(xe);
-}
-
-void xe_display_pm_suspend(struct xe_device *xe, bool runtime)
+static void __xe_display_pm_suspend(struct xe_device *xe, bool runtime)
 {
        struct intel_display *display = &xe->display;
        bool s2idle = suspend_to_idle();
@@ -353,28 +342,38 @@ void xe_display_pm_suspend(struct xe_device *xe, bool runtime)
        intel_opregion_suspend(display, s2idle ? PCI_D1 : PCI_D3cold);
 
        intel_dmc_suspend(xe);
+
+       if (runtime && has_display(xe))
+               intel_hpd_poll_enable(xe);
 }
 
-void xe_display_pm_suspend_late(struct xe_device *xe)
+void xe_display_pm_suspend(struct xe_device *xe)
+{
+       __xe_display_pm_suspend(xe, false);
+}
+
+void xe_display_pm_runtime_suspend(struct xe_device *xe)
 {
-       bool s2idle = suspend_to_idle();
        if (!xe->info.probe_display)
                return;
 
-       intel_power_domains_suspend(xe, s2idle);
+       if (xe->d3cold.allowed) {
+               __xe_display_pm_suspend(xe, true);
+               return;
+       }
 
-       intel_display_power_suspend_late(xe);
+       intel_hpd_poll_enable(xe);
 }
 
-void xe_display_pm_runtime_resume(struct xe_device *xe)
+void xe_display_pm_suspend_late(struct xe_device *xe)
 {
+       bool s2idle = suspend_to_idle();
        if (!xe->info.probe_display)
                return;
 
-       intel_hpd_poll_disable(xe);
+       intel_power_domains_suspend(xe, s2idle);
 
-       if (xe->d3cold.allowed)
-               xe_display_pm_resume(xe, true);
+       intel_display_power_suspend_late(xe);
 }
 
 void xe_display_pm_resume_early(struct xe_device *xe)
@@ -387,7 +386,7 @@ void xe_display_pm_resume_early(struct xe_device *xe)
        intel_power_domains_resume(xe);
 }
 
-void xe_display_pm_resume(struct xe_device *xe, bool runtime)
+static void __xe_display_pm_resume(struct xe_device *xe, bool runtime)
 {
        struct intel_display *display = &xe->display;
 
@@ -411,9 +410,11 @@ void xe_display_pm_resume(struct xe_device *xe, bool runtime)
                intel_display_driver_resume(xe);
                drm_kms_helper_poll_enable(&xe->drm);
                intel_display_driver_enable_user_access(xe);
-               intel_hpd_poll_disable(xe);
        }
 
+       if (has_display(xe))
+               intel_hpd_poll_disable(xe);
+
        intel_opregion_resume(display);
 
        intel_fbdev_set_suspend(&xe->drm, FBINFO_STATE_RUNNING, false);
@@ -421,6 +422,26 @@ void xe_display_pm_resume(struct xe_device *xe, bool runtime)
        intel_power_domains_enable(xe);
 }
 
+void xe_display_pm_resume(struct xe_device *xe)
+{
+       __xe_display_pm_resume(xe, false);
+}
+
+void xe_display_pm_runtime_resume(struct xe_device *xe)
+{
+       if (!xe->info.probe_display)
+               return;
+
+       if (xe->d3cold.allowed) {
+               __xe_display_pm_resume(xe, true);
+               return;
+       }
+
+       intel_hpd_init(xe);
+       intel_hpd_poll_disable(xe);
+}
+
+
 static void display_device_remove(struct drm_device *dev, void *arg)
 {
        struct xe_device *xe = arg;
index 53d727fd792b4bfd369340b1a93f6afe26af27ce..bed55fd26f30444517a85efb921c786edc6429d0 100644 (file)
@@ -34,10 +34,10 @@ void xe_display_irq_enable(struct xe_device *xe, u32 gu_misc_iir);
 void xe_display_irq_reset(struct xe_device *xe);
 void xe_display_irq_postinstall(struct xe_device *xe, struct xe_gt *gt);
 
-void xe_display_pm_suspend(struct xe_device *xe, bool runtime);
+void xe_display_pm_suspend(struct xe_device *xe);
 void xe_display_pm_suspend_late(struct xe_device *xe);
 void xe_display_pm_resume_early(struct xe_device *xe);
-void xe_display_pm_resume(struct xe_device *xe, bool runtime);
+void xe_display_pm_resume(struct xe_device *xe);
 void xe_display_pm_runtime_suspend(struct xe_device *xe);
 void xe_display_pm_runtime_resume(struct xe_device *xe);
 
@@ -65,10 +65,10 @@ static inline void xe_display_irq_enable(struct xe_device *xe, u32 gu_misc_iir)
 static inline void xe_display_irq_reset(struct xe_device *xe) {}
 static inline void xe_display_irq_postinstall(struct xe_device *xe, struct xe_gt *gt) {}
 
-static inline void xe_display_pm_suspend(struct xe_device *xe, bool runtime) {}
+static inline void xe_display_pm_suspend(struct xe_device *xe) {}
 static inline void xe_display_pm_suspend_late(struct xe_device *xe) {}
 static inline void xe_display_pm_resume_early(struct xe_device *xe) {}
-static inline void xe_display_pm_resume(struct xe_device *xe, bool runtime) {}
+static inline void xe_display_pm_resume(struct xe_device *xe) {}
 static inline void xe_display_pm_runtime_suspend(struct xe_device *xe) {}
 static inline void xe_display_pm_runtime_resume(struct xe_device *xe) {}
 
index 660ff42e45a6f44097419d3c769d5f156583fb8b..00ad34ed73a5fc7af997b40eaaefcdb363c0fde0 100644 (file)
 #define XEHP_SLICE_COMMON_ECO_CHICKEN1         XE_REG_MCR(0x731c, XE_REG_OPTION_MASKED)
 #define   MSC_MSAA_REODER_BUF_BYPASS_DISABLE   REG_BIT(14)
 
+#define XE2LPM_CCCHKNREG1                      XE_REG(0x82a8)
+
 #define VF_PREEMPTION                          XE_REG(0x83a4, XE_REG_OPTION_MASKED)
 #define   PREEMPTION_VERTEX_COUNT              REG_GENMASK(15, 0)
 
 #define L3SQCREG3                              XE_REG_MCR(0xb108)
 #define   COMPPWOVERFETCHEN                    REG_BIT(28)
 
+#define SCRATCH3_LBCF                          XE_REG_MCR(0xb154)
+#define   RWFLUSHALLEN                         REG_BIT(17)
+
 #define XEHP_L3SQCREG5                         XE_REG_MCR(0xb158)
 #define   L3_PWM_TIMER_INIT_VAL_MASK           REG_GENMASK(9, 0)
 
 
 #define XE2_GLOBAL_INVAL                       XE_REG(0xb404)
 
-#define SCRATCH1LPFC                           XE_REG(0xb474)
-#define   EN_L3_RW_CCS_CACHE_FLUSH             REG_BIT(0)
+#define XE2LPM_L3SQCREG2                       XE_REG_MCR(0xb604)
+
+#define XE2LPM_L3SQCREG3                       XE_REG_MCR(0xb608)
+
+#define XE2LPM_SCRATCH3_LBCF                   XE_REG_MCR(0xb654)
 
 #define XE2LPM_L3SQCREG5                       XE_REG_MCR(0xb658)
 
index f379df3a12bfa0c29e189c905bce39cf52ac0e67..e5f51fd23c65470e546405f00ee6001c166779bd 100644 (file)
@@ -680,8 +680,8 @@ static int xe_bo_move(struct ttm_buffer_object *ttm_bo, bool evict,
        tt_has_data = ttm && (ttm_tt_is_populated(ttm) ||
                              (ttm->page_flags & TTM_TT_FLAG_SWAPPED));
 
-       move_lacks_source = handle_system_ccs ? (!bo->ccs_cleared)  :
-                                               (!mem_type_is_vram(old_mem_type) && !tt_has_data);
+       move_lacks_source = !old_mem || (handle_system_ccs ? (!bo->ccs_cleared) :
+                                        (!mem_type_is_vram(old_mem_type) && !tt_has_data));
 
        needs_clear = (ttm && ttm->page_flags & TTM_TT_FLAG_ZERO_ALLOC) ||
                (!ttm && ttm_bo->type == ttm_bo_type_device);
index 668615c6b1725a54c0dcf2e59a9f8a479aa0c508..fe4319eb13fdfb3cf6a10d5029fcbe0a8971006b 100644 (file)
@@ -187,7 +187,7 @@ void xe_debugfs_register(struct xe_device *xe)
        debugfs_create_file("forcewake_all", 0400, root, xe,
                            &forcewake_all_fops);
 
-       debugfs_create_file("wedged_mode", 0400, root, xe,
+       debugfs_create_file("wedged_mode", 0600, root, xe,
                            &wedged_mode_fops);
 
        for (mem_type = XE_PL_VRAM0; mem_type <= XE_PL_VRAM1; ++mem_type) {
index 70d4e4d46c3c86592f0e984d725778090af99222..10fd4601b9f2a4ed546717e939dc37c87fb6ca8a 100644 (file)
@@ -171,10 +171,8 @@ static void xe_file_close(struct drm_device *dev, struct drm_file *file)
                xe_exec_queue_kill(q);
                xe_exec_queue_put(q);
        }
-       mutex_lock(&xef->vm.lock);
        xa_for_each(&xef->vm.xa, idx, vm)
                xe_vm_close_and_put(vm);
-       mutex_unlock(&xef->vm.lock);
 
        xe_file_put(xef);
 
@@ -298,6 +296,9 @@ static void xe_device_destroy(struct drm_device *dev, void *dummy)
        if (xe->unordered_wq)
                destroy_workqueue(xe->unordered_wq);
 
+       if (xe->destroy_wq)
+               destroy_workqueue(xe->destroy_wq);
+
        ttm_device_fini(&xe->ttm);
 }
 
@@ -336,9 +337,7 @@ struct xe_device *xe_device_create(struct pci_dev *pdev,
 
        init_waitqueue_head(&xe->ufence_wq);
 
-       err = drmm_mutex_init(&xe->drm, &xe->usm.lock);
-       if (err)
-               goto err;
+       init_rwsem(&xe->usm.lock);
 
        xa_init_flags(&xe->usm.asid_to_vm, XA_FLAGS_ALLOC);
 
@@ -363,8 +362,9 @@ struct xe_device *xe_device_create(struct pci_dev *pdev,
        xe->preempt_fence_wq = alloc_ordered_workqueue("xe-preempt-fence-wq", 0);
        xe->ordered_wq = alloc_ordered_workqueue("xe-ordered-wq", 0);
        xe->unordered_wq = alloc_workqueue("xe-unordered-wq", 0, 0);
+       xe->destroy_wq = alloc_workqueue("xe-destroy-wq", 0, 0);
        if (!xe->ordered_wq || !xe->unordered_wq ||
-           !xe->preempt_fence_wq) {
+           !xe->preempt_fence_wq || !xe->destroy_wq) {
                /*
                 * Cleanup done in xe_device_destroy via
                 * drmm_add_action_or_reset register above
@@ -890,7 +890,7 @@ void xe_device_l2_flush(struct xe_device *xe)
        spin_lock(&gt->global_invl_lock);
        xe_mmio_write32(gt, XE2_GLOBAL_INVAL, 0x1);
 
-       if (xe_mmio_wait32(gt, XE2_GLOBAL_INVAL, 0x1, 0x0, 150, NULL, true))
+       if (xe_mmio_wait32(gt, XE2_GLOBAL_INVAL, 0x1, 0x0, 500, NULL, true))
                xe_gt_err_once(gt, "Global invalidation timeout\n");
        spin_unlock(&gt->global_invl_lock);
 
@@ -980,13 +980,13 @@ void xe_device_declare_wedged(struct xe_device *xe)
                return;
        }
 
+       xe_pm_runtime_get_noresume(xe);
+
        if (drmm_add_action_or_reset(&xe->drm, xe_device_wedged_fini, xe)) {
                drm_err(&xe->drm, "Failed to register xe_device_wedged_fini clean-up. Although device is wedged.\n");
                return;
        }
 
-       xe_pm_runtime_get_noresume(xe);
-
        if (!atomic_xchg(&xe->wedged.flag, 1)) {
                xe->needs_flr_on_fini = true;
                drm_err(&xe->drm,
index ec7eb781112649b87dcc4541741c34faf8c5d2b5..09d731a9125cecfa6577eb5f406572f74777806a 100644 (file)
@@ -369,7 +369,7 @@ struct xe_device {
                /** @usm.next_asid: next ASID, used to cyclical alloc asids */
                u32 next_asid;
                /** @usm.lock: protects UM state */
-               struct mutex lock;
+               struct rw_semaphore lock;
        } usm;
 
        /** @pinned: pinned BO state */
@@ -396,6 +396,9 @@ struct xe_device {
        /** @unordered_wq: used to serialize unordered work, mostly display */
        struct workqueue_struct *unordered_wq;
 
+       /** @destroy_wq: used to serialize user destroy work, like queue */
+       struct workqueue_struct *destroy_wq;
+
        /** @tiles: device tiles */
        struct xe_tile tiles[XE_MAX_TILES_PER_DEVICE];
 
@@ -567,15 +570,23 @@ struct xe_file {
        struct {
                /** @vm.xe: xarray to store VMs */
                struct xarray xa;
-               /** @vm.lock: protects file VM state */
+               /**
+                * @vm.lock: Protects VM lookup + reference and removal a from
+                * file xarray. Not an intended to be an outer lock which does
+                * thing while being held.
+                */
                struct mutex lock;
        } vm;
 
        /** @exec_queue: Submission exec queue state for file */
        struct {
-               /** @exec_queue.xe: xarray to store engines */
+               /** @exec_queue.xa: xarray to store exece queues */
                struct xarray xa;
-               /** @exec_queue.lock: protects file engine state */
+               /**
+                * @exec_queue.lock: Protects exec queue lookup + reference and
+                * removal a frommfile xarray. Not an intended to be an outer
+                * lock which does thing while being held.
+                */
                struct mutex lock;
        } exec_queue;
 
index c4add8b38bbd29ad53867d70aad5c0f3784b5127..fb52a23e28f84ef8b4d2a99a0a41164759158762 100644 (file)
@@ -283,8 +283,15 @@ static void show_run_ticks(struct drm_printer *p, struct drm_file *file)
 
        /* Accumulate all the exec queues from this client */
        mutex_lock(&xef->exec_queue.lock);
-       xa_for_each(&xef->exec_queue.xa, i, q)
+       xa_for_each(&xef->exec_queue.xa, i, q) {
+               xe_exec_queue_get(q);
+               mutex_unlock(&xef->exec_queue.lock);
+
                xe_exec_queue_update_run_ticks(q);
+
+               mutex_lock(&xef->exec_queue.lock);
+               xe_exec_queue_put(q);
+       }
        mutex_unlock(&xef->exec_queue.lock);
 
        /* Get the total GPU cycles */
index 7b38485817dcb44913bb46a389d8e464986cf242..f23ac1e2ed88c4026aced9c737ebd9dbd8165924 100644 (file)
  * user knows an exec writes to a BO and reads from the BO in the next exec, it
  * is the user's responsibility to pass in / out fence between the two execs).
  *
- * Implicit dependencies for external BOs are handled by using the dma-buf
- * implicit dependency uAPI (TODO: add link). To make this works each exec must
- * install the job's fence into the DMA_RESV_USAGE_WRITE slot of every external
- * BO mapped in the VM.
- *
  * We do not allow a user to trigger a bind at exec time rather we have a VM
  * bind IOCTL which uses the same in / out fence interface as exec. In that
  * sense, a VM bind is basically the same operation as an exec from the user
@@ -59,8 +54,8 @@
  * behind any pending kernel operations on any external BOs in VM or any BOs
  * private to the VM. This is accomplished by the rebinds waiting on BOs
  * DMA_RESV_USAGE_KERNEL slot (kernel ops) and kernel ops waiting on all BOs
- * slots (inflight execs are in the DMA_RESV_USAGE_BOOKING for private BOs and
- * in DMA_RESV_USAGE_WRITE for external BOs).
+ * slots (inflight execs are in the DMA_RESV_USAGE_BOOKKEEP for private BOs and
+ * for external BOs).
  *
  * Rebinds / dma-resv usage applies to non-compute mode VMs only as for compute
  * mode VMs we use preempt fences and a rebind worker (TODO: add link).
@@ -304,7 +299,8 @@ retry:
        xe_sched_job_arm(job);
        if (!xe_vm_in_lr_mode(vm))
                drm_gpuvm_resv_add_fence(&vm->gpuvm, exec, &job->drm.s_fence->finished,
-                                        DMA_RESV_USAGE_BOOKKEEP, DMA_RESV_USAGE_WRITE);
+                                        DMA_RESV_USAGE_BOOKKEEP,
+                                        DMA_RESV_USAGE_BOOKKEEP);
 
        for (i = 0; i < num_syncs; i++) {
                xe_sync_entry_signal(&syncs[i], &job->drm.s_fence->finished);
index 7f28b7fc68d58d1a57f21a708450cf26ebd2972f..d098d2dd1b2d8059c27882c1ff7e08f17f0a22cd 100644 (file)
@@ -635,14 +635,14 @@ int xe_exec_queue_create_ioctl(struct drm_device *dev, void *data,
                }
        }
 
-       mutex_lock(&xef->exec_queue.lock);
+       q->xef = xe_file_get(xef);
+
+       /* user id alloc must always be last in ioctl to prevent UAF */
        err = xa_alloc(&xef->exec_queue.xa, &id, q, xa_limit_32b, GFP_KERNEL);
-       mutex_unlock(&xef->exec_queue.lock);
        if (err)
                goto kill_exec_queue;
 
        args->exec_queue_id = id;
-       q->xef = xe_file_get(xef);
 
        return 0;
 
index b263fff1527377836380e316a60e8513bd35704e..7d9fc489dcb81e978513feeccaf78bff32f0bf40 100644 (file)
@@ -115,9 +115,15 @@ static int __domain_wait(struct xe_gt *gt, struct xe_force_wake_domain *domain,
                             XE_FORCE_WAKE_ACK_TIMEOUT_MS * USEC_PER_MSEC,
                             &value, true);
        if (ret)
-               xe_gt_notice(gt, "Force wake domain %d failed to ack %s (%pe) reg[%#x] = %#x\n",
-                            domain->id, str_wake_sleep(wake), ERR_PTR(ret),
-                            domain->reg_ack.addr, value);
+               xe_gt_err(gt, "Force wake domain %d failed to ack %s (%pe) reg[%#x] = %#x\n",
+                         domain->id, str_wake_sleep(wake), ERR_PTR(ret),
+                         domain->reg_ack.addr, value);
+       if (value == ~0) {
+               xe_gt_err(gt,
+                         "Force wake domain %d: %s. MMIO unreliable (forcewake register returns 0xFFFFFFFF)!\n",
+                         domain->id, str_wake_sleep(wake));
+               ret = -EIO;
+       }
 
        return ret;
 }
index 2895f154654cac6338460eae5384057029e615ff..ff19eca5d358b325a4ed07e7ef812c4ff3d88a0c 100644 (file)
@@ -397,6 +397,16 @@ static void ggtt_invalidate_gt_tlb(struct xe_gt *gt)
 
 static void xe_ggtt_invalidate(struct xe_ggtt *ggtt)
 {
+       struct xe_device *xe = tile_to_xe(ggtt->tile);
+
+       /*
+        * XXX: Barrier for GGTT pages. Unsure exactly why this required but
+        * without this LNL is having issues with the GuC reading scratch page
+        * vs. correct GGTT page. Not particularly a hot code path so blindly
+        * do a mmio read here which results in GuC reading correct GGTT page.
+        */
+       xe_mmio_read32(xe_root_mmio_gt(xe), VF_CAP_REG);
+
        /* Each GT in a tile has its own TLB to cache GGTT lookups */
        ggtt_invalidate_gt_tlb(ggtt->tile->primary_gt);
        ggtt_invalidate_gt_tlb(ggtt->tile->media_gt);
index c518d1d16d828595802828bcdd1bcddb78b04433..50361b4638f96a81f171743db024ec9938bc1a75 100644 (file)
@@ -90,6 +90,11 @@ void xe_sched_submission_stop(struct xe_gpu_scheduler *sched)
        cancel_work_sync(&sched->work_process_msg);
 }
 
+void xe_sched_submission_resume_tdr(struct xe_gpu_scheduler *sched)
+{
+       drm_sched_resume_timeout(&sched->base, sched->base.timeout);
+}
+
 void xe_sched_add_msg(struct xe_gpu_scheduler *sched,
                      struct xe_sched_msg *msg)
 {
index cee9c6809fc0df5997379ff62cb23d07b9ad278a..64b2ae6839db26f2c72c311744649cc21fb9878a 100644 (file)
@@ -22,6 +22,8 @@ void xe_sched_fini(struct xe_gpu_scheduler *sched);
 void xe_sched_submission_start(struct xe_gpu_scheduler *sched);
 void xe_sched_submission_stop(struct xe_gpu_scheduler *sched);
 
+void xe_sched_submission_resume_tdr(struct xe_gpu_scheduler *sched);
+
 void xe_sched_add_msg(struct xe_gpu_scheduler *sched,
                      struct xe_sched_msg *msg);
 void xe_sched_add_msg_locked(struct xe_gpu_scheduler *sched,
@@ -61,7 +63,9 @@ xe_sched_invalidate_job(struct xe_sched_job *job, int threshold)
 static inline void xe_sched_add_pending_job(struct xe_gpu_scheduler *sched,
                                            struct xe_sched_job *job)
 {
+       spin_lock(&sched->base.job_list_lock);
        list_add(&job->drm.list, &sched->base.pending_list);
+       spin_unlock(&sched->base.job_list_lock);
 }
 
 static inline
index f0dc2bf24c7b172057e83e86c8b8aae718cb5014..d5fd6a089b7ccc1d82bb50532433810227c5d26c 100644 (file)
@@ -108,7 +108,6 @@ static void xe_gt_enable_host_l2_vram(struct xe_gt *gt)
                return;
 
        if (!xe_gt_is_media_type(gt)) {
-               xe_mmio_write32(gt, SCRATCH1LPFC, EN_L3_RW_CCS_CACHE_FLUSH);
                reg = xe_gt_mcr_unicast_read_any(gt, XE2_GAMREQSTRM_CTRL);
                reg |= CG_DIS_CNTLBUS;
                xe_gt_mcr_multicast_write(gt, XE2_GAMREQSTRM_CTRL, reg);
@@ -874,7 +873,9 @@ int xe_gt_sanitize_freq(struct xe_gt *gt)
        int ret = 0;
 
        if ((!xe_uc_fw_is_available(&gt->uc.gsc.fw) ||
-            xe_uc_fw_is_loaded(&gt->uc.gsc.fw)) && XE_WA(gt, 22019338487))
+            xe_uc_fw_is_loaded(&gt->uc.gsc.fw) ||
+            xe_uc_fw_is_in_error_state(&gt->uc.gsc.fw)) &&
+           XE_WA(gt, 22019338487))
                ret = xe_guc_pc_restore_stashed_freq(&gt->uc.guc.pc);
 
        return ret;
index 68a5778b4319fde12cb1b520c95b64f2a89c1792..ab76973f3e1e6fe19057711c65a42dd668066ba8 100644 (file)
@@ -237,11 +237,11 @@ int xe_gt_freq_init(struct xe_gt *gt)
        if (!gt->freq)
                return -ENOMEM;
 
-       err = devm_add_action(xe->drm.dev, freq_fini, gt->freq);
+       err = sysfs_create_files(gt->freq, freq_attrs);
        if (err)
                return err;
 
-       err = sysfs_create_files(gt->freq, freq_attrs);
+       err = devm_add_action_or_reset(xe->drm.dev, freq_fini, gt->freq);
        if (err)
                return err;
 
index 7d7bd0be6233efaa7b33621d96909e259630dee3..c834f64b0178b3829073bbe4d0c99c7cd6d1ca09 100644 (file)
@@ -439,7 +439,7 @@ void xe_gt_mcr_init(struct xe_gt *gt)
        if (gt->info.type == XE_GT_TYPE_MEDIA) {
                drm_WARN_ON(&xe->drm, MEDIA_VER(xe) < 13);
 
-               if (MEDIA_VER(xe) >= 20) {
+               if (MEDIA_VERx100(xe) >= 1301) {
                        gt->steering[OADDRM].ranges = xe2lpm_gpmxmt_steering_table;
                        gt->steering[INSTANCE0].ranges = xe2lpm_instance0_steering_table;
                } else {
index 00af059a8971a8e54f082633383aa763819bc0f1..79c426dc2505971d9f127051f088489ef4f5e668 100644 (file)
@@ -185,6 +185,21 @@ unlock_dma_resv:
        return err;
 }
 
+static struct xe_vm *asid_to_vm(struct xe_device *xe, u32 asid)
+{
+       struct xe_vm *vm;
+
+       down_read(&xe->usm.lock);
+       vm = xa_load(&xe->usm.asid_to_vm, asid);
+       if (vm && xe_vm_in_fault_mode(vm))
+               xe_vm_get(vm);
+       else
+               vm = ERR_PTR(-EINVAL);
+       up_read(&xe->usm.lock);
+
+       return vm;
+}
+
 static int handle_pagefault(struct xe_gt *gt, struct pagefault *pf)
 {
        struct xe_device *xe = gt_to_xe(gt);
@@ -197,16 +212,9 @@ static int handle_pagefault(struct xe_gt *gt, struct pagefault *pf)
        if (pf->trva_fault)
                return -EFAULT;
 
-       /* ASID to VM */
-       mutex_lock(&xe->usm.lock);
-       vm = xa_load(&xe->usm.asid_to_vm, pf->asid);
-       if (vm && xe_vm_in_fault_mode(vm))
-               xe_vm_get(vm);
-       else
-               vm = NULL;
-       mutex_unlock(&xe->usm.lock);
-       if (!vm)
-               return -EINVAL;
+       vm = asid_to_vm(xe, pf->asid);
+       if (IS_ERR(vm))
+               return PTR_ERR(vm);
 
        /*
         * TODO: Change to read lock? Using write lock for simplicity.
@@ -548,14 +556,9 @@ static int handle_acc(struct xe_gt *gt, struct acc *acc)
        if (acc->access_type != ACC_TRIGGER)
                return -EINVAL;
 
-       /* ASID to VM */
-       mutex_lock(&xe->usm.lock);
-       vm = xa_load(&xe->usm.asid_to_vm, acc->asid);
-       if (vm)
-               xe_vm_get(vm);
-       mutex_unlock(&xe->usm.lock);
-       if (!vm || !xe_vm_in_fault_mode(vm))
-               return -EINVAL;
+       vm = asid_to_vm(xe, acc->asid);
+       if (IS_ERR(vm))
+               return PTR_ERR(vm);
 
        down_read(&vm->lock);
 
index a05c3699e8b9149d9caa8683d832c8f8cb1244ac..ec2b8246204b88ec9d1b818f54b4f93ab93058f6 100644 (file)
@@ -51,5 +51,5 @@ int xe_gt_sysfs_init(struct xe_gt *gt)
 
        gt->sysfs = &kg->base;
 
-       return devm_add_action(xe->drm.dev, gt_sysfs_fini, gt);
+       return devm_add_action_or_reset(xe->drm.dev, gt_sysfs_fini, gt);
 }
index cca9cf536f769326e2993d9c66236a36f3fe9ba6..bbb9e411d21f64522698a3fc573d1862f45acabe 100644 (file)
@@ -37,6 +37,15 @@ static long tlb_timeout_jiffies(struct xe_gt *gt)
        return hw_tlb_timeout + 2 * delay;
 }
 
+static void xe_gt_tlb_invalidation_fence_fini(struct xe_gt_tlb_invalidation_fence *fence)
+{
+       if (WARN_ON_ONCE(!fence->gt))
+               return;
+
+       xe_pm_runtime_put(gt_to_xe(fence->gt));
+       fence->gt = NULL; /* fini() should be called once */
+}
+
 static void
 __invalidation_fence_signal(struct xe_device *xe, struct xe_gt_tlb_invalidation_fence *fence)
 {
@@ -204,7 +213,7 @@ static int send_tlb_invalidation(struct xe_guc *guc,
                                                   tlb_timeout_jiffies(gt));
                }
                spin_unlock_irq(&gt->tlb_invalidation.pending_lock);
-       } else if (ret < 0) {
+       } else {
                __invalidation_fence_signal(xe, fence);
        }
        if (!ret) {
@@ -267,10 +276,8 @@ int xe_gt_tlb_invalidation_ggtt(struct xe_gt *gt)
 
                xe_gt_tlb_invalidation_fence_init(gt, &fence, true);
                ret = xe_gt_tlb_invalidation_guc(gt, &fence);
-               if (ret < 0) {
-                       xe_gt_tlb_invalidation_fence_fini(&fence);
+               if (ret)
                        return ret;
-               }
 
                xe_gt_tlb_invalidation_fence_wait(&fence);
        } else if (xe_device_uc_enabled(xe) && !xe_device_wedged(xe)) {
@@ -496,7 +503,8 @@ static const struct dma_fence_ops invalidation_fence_ops = {
  * @stack: fence is stack variable
  *
  * Initialize TLB invalidation fence for use. xe_gt_tlb_invalidation_fence_fini
- * must be called if fence is not signaled.
+ * will be automatically called when fence is signalled (all fences must signal),
+ * even on error.
  */
 void xe_gt_tlb_invalidation_fence_init(struct xe_gt *gt,
                                       struct xe_gt_tlb_invalidation_fence *fence,
@@ -516,14 +524,3 @@ void xe_gt_tlb_invalidation_fence_init(struct xe_gt *gt,
                dma_fence_get(&fence->base);
        fence->gt = gt;
 }
-
-/**
- * xe_gt_tlb_invalidation_fence_fini - Finalize TLB invalidation fence
- * @fence: TLB invalidation fence to finalize
- *
- * Drop PM ref which fence took durinig init.
- */
-void xe_gt_tlb_invalidation_fence_fini(struct xe_gt_tlb_invalidation_fence *fence)
-{
-       xe_pm_runtime_put(gt_to_xe(fence->gt));
-}
index a84065fa324c766ad5c81889333bb738c409684b..f430d5797af701cd500f8b890169ffbeef9403fd 100644 (file)
@@ -28,7 +28,6 @@ int xe_guc_tlb_invalidation_done_handler(struct xe_guc *guc, u32 *msg, u32 len);
 void xe_gt_tlb_invalidation_fence_init(struct xe_gt *gt,
                                       struct xe_gt_tlb_invalidation_fence *fence,
                                       bool stack);
-void xe_gt_tlb_invalidation_fence_fini(struct xe_gt_tlb_invalidation_fence *fence);
 
 static inline void
 xe_gt_tlb_invalidation_fence_wait(struct xe_gt_tlb_invalidation_fence *fence)
index f24dd52239268c169443cedaf0b04d88b14775c1..17986bfd881876275e9222a85e597a6a9f7ea6b5 100644 (file)
@@ -667,16 +667,12 @@ static int __guc_ct_send_locked(struct xe_guc_ct *ct, const u32 *action,
                num_g2h = 1;
 
                if (g2h_fence_needs_alloc(g2h_fence)) {
-                       void *ptr;
-
                        g2h_fence->seqno = next_ct_seqno(ct, true);
-                       ptr = xa_store(&ct->fence_lookup,
-                                      g2h_fence->seqno,
-                                      g2h_fence, GFP_ATOMIC);
-                       if (IS_ERR(ptr)) {
-                               ret = PTR_ERR(ptr);
+                       ret = xa_err(xa_store(&ct->fence_lookup,
+                                             g2h_fence->seqno, g2h_fence,
+                                             GFP_ATOMIC));
+                       if (ret)
                                goto out;
-                       }
                }
 
                seqno = g2h_fence->seqno;
@@ -879,14 +875,11 @@ retry:
 retry_same_fence:
        ret = guc_ct_send(ct, action, len, 0, 0, &g2h_fence);
        if (unlikely(ret == -ENOMEM)) {
-               void *ptr;
-
                /* Retry allocation /w GFP_KERNEL */
-               ptr = xa_store(&ct->fence_lookup,
-                              g2h_fence.seqno,
-                              &g2h_fence, GFP_KERNEL);
-               if (IS_ERR(ptr))
-                       return PTR_ERR(ptr);
+               ret = xa_err(xa_store(&ct->fence_lookup, g2h_fence.seqno,
+                                     &g2h_fence, GFP_KERNEL));
+               if (ret)
+                       return ret;
 
                goto retry_same_fence;
        } else if (unlikely(ret)) {
@@ -903,16 +896,44 @@ retry_same_fence:
        }
 
        ret = wait_event_timeout(ct->g2h_fence_wq, g2h_fence.done, HZ);
+
+       /*
+        * Occasionally it is seen that the G2H worker starts running after a delay of more than
+        * a second even after being queued and activated by the Linux workqueue subsystem. This
+        * leads to G2H timeout error. The root cause of issue lies with scheduling latency of
+        * Lunarlake Hybrid CPU. Issue dissappears if we disable Lunarlake atom cores from BIOS
+        * and this is beyond xe kmd.
+        *
+        * TODO: Drop this change once workqueue scheduling delay issue is fixed on LNL Hybrid CPU.
+        */
+       if (!ret) {
+               flush_work(&ct->g2h_worker);
+               if (g2h_fence.done) {
+                       xe_gt_warn(gt, "G2H fence %u, action %04x, done\n",
+                                  g2h_fence.seqno, action[0]);
+                       ret = 1;
+               }
+       }
+
+       /*
+        * Ensure we serialize with completion side to prevent UAF with fence going out of scope on
+        * the stack, since we have no clue if it will fire after the timeout before we can erase
+        * from the xa. Also we have some dependent loads and stores below for which we need the
+        * correct ordering, and we lack the needed barriers.
+        */
+       mutex_lock(&ct->lock);
        if (!ret) {
-               xe_gt_err(gt, "Timed out wait for G2H, fence %u, action %04x",
-                         g2h_fence.seqno, action[0]);
+               xe_gt_err(gt, "Timed out wait for G2H, fence %u, action %04x, done %s",
+                         g2h_fence.seqno, action[0], str_yes_no(g2h_fence.done));
                xa_erase_irq(&ct->fence_lookup, g2h_fence.seqno);
+               mutex_unlock(&ct->lock);
                return -ETIME;
        }
 
        if (g2h_fence.retry) {
                xe_gt_dbg(gt, "H2G action %#x retrying: reason %#x\n",
                          action[0], g2h_fence.reason);
+               mutex_unlock(&ct->lock);
                goto retry;
        }
        if (g2h_fence.fail) {
@@ -921,7 +942,12 @@ retry_same_fence:
                ret = -EIO;
        }
 
-       return ret > 0 ? response_buffer ? g2h_fence.response_len : g2h_fence.response_data : ret;
+       if (ret > 0)
+               ret = response_buffer ? g2h_fence.response_len : g2h_fence.response_data;
+
+       mutex_unlock(&ct->lock);
+
+       return ret;
 }
 
 /**
index fbbe6a487bbb3bc7c5a14c82ead291c370990618..f903b077272259e475226da053db75b4efec61c3 100644 (file)
@@ -224,64 +224,11 @@ static bool exec_queue_killed_or_banned_or_wedged(struct xe_exec_queue *q)
                 EXEC_QUEUE_STATE_BANNED));
 }
 
-#ifdef CONFIG_PROVE_LOCKING
-static int alloc_submit_wq(struct xe_guc *guc)
-{
-       int i;
-
-       for (i = 0; i < NUM_SUBMIT_WQ; ++i) {
-               guc->submission_state.submit_wq_pool[i] =
-                       alloc_ordered_workqueue("submit_wq", 0);
-               if (!guc->submission_state.submit_wq_pool[i])
-                       goto err_free;
-       }
-
-       return 0;
-
-err_free:
-       while (i)
-               destroy_workqueue(guc->submission_state.submit_wq_pool[--i]);
-
-       return -ENOMEM;
-}
-
-static void free_submit_wq(struct xe_guc *guc)
-{
-       int i;
-
-       for (i = 0; i < NUM_SUBMIT_WQ; ++i)
-               destroy_workqueue(guc->submission_state.submit_wq_pool[i]);
-}
-
-static struct workqueue_struct *get_submit_wq(struct xe_guc *guc)
-{
-       int idx = guc->submission_state.submit_wq_idx++ % NUM_SUBMIT_WQ;
-
-       return guc->submission_state.submit_wq_pool[idx];
-}
-#else
-static int alloc_submit_wq(struct xe_guc *guc)
-{
-       return 0;
-}
-
-static void free_submit_wq(struct xe_guc *guc)
-{
-
-}
-
-static struct workqueue_struct *get_submit_wq(struct xe_guc *guc)
-{
-       return NULL;
-}
-#endif
-
 static void guc_submit_fini(struct drm_device *drm, void *arg)
 {
        struct xe_guc *guc = arg;
 
        xa_destroy(&guc->submission_state.exec_queue_lookup);
-       free_submit_wq(guc);
 }
 
 static void guc_submit_wedged_fini(void *arg)
@@ -290,9 +237,15 @@ static void guc_submit_wedged_fini(void *arg)
        struct xe_exec_queue *q;
        unsigned long index;
 
-       xa_for_each(&guc->submission_state.exec_queue_lookup, index, q)
-               if (exec_queue_wedged(q))
+       mutex_lock(&guc->submission_state.lock);
+       xa_for_each(&guc->submission_state.exec_queue_lookup, index, q) {
+               if (exec_queue_wedged(q)) {
+                       mutex_unlock(&guc->submission_state.lock);
                        xe_exec_queue_put(q);
+                       mutex_lock(&guc->submission_state.lock);
+               }
+       }
+       mutex_unlock(&guc->submission_state.lock);
 }
 
 static const struct xe_exec_queue_ops guc_exec_queue_ops;
@@ -337,14 +290,12 @@ int xe_guc_submit_init(struct xe_guc *guc, unsigned int num_ids)
        if (err)
                return err;
 
-       err = alloc_submit_wq(guc);
-       if (err)
-               return err;
-
        gt->exec_queue_ops = &guc_exec_queue_ops;
 
        xa_init(&guc->submission_state.exec_queue_lookup);
 
+       init_waitqueue_head(&guc->submission_state.fini_wq);
+
        primelockdep(guc);
 
        return drmm_add_action_or_reset(&xe->drm, guc_submit_fini, guc);
@@ -361,12 +312,14 @@ static void __release_guc_id(struct xe_guc *guc, struct xe_exec_queue *q, u32 xa
 
        xe_guc_id_mgr_release_locked(&guc->submission_state.idm,
                                     q->guc->id, q->width);
+
+       if (xa_empty(&guc->submission_state.exec_queue_lookup))
+               wake_up(&guc->submission_state.fini_wq);
 }
 
 static int alloc_guc_id(struct xe_guc *guc, struct xe_exec_queue *q)
 {
        int ret;
-       void *ptr;
        int i;
 
        /*
@@ -386,12 +339,10 @@ static int alloc_guc_id(struct xe_guc *guc, struct xe_exec_queue *q)
        q->guc->id = ret;
 
        for (i = 0; i < q->width; ++i) {
-               ptr = xa_store(&guc->submission_state.exec_queue_lookup,
-                              q->guc->id + i, q, GFP_NOWAIT);
-               if (IS_ERR(ptr)) {
-                       ret = PTR_ERR(ptr);
+               ret = xa_err(xa_store(&guc->submission_state.exec_queue_lookup,
+                                     q->guc->id + i, q, GFP_NOWAIT));
+               if (ret)
                        goto err_release;
-               }
        }
 
        return 0;
@@ -965,12 +916,22 @@ static void xe_guc_exec_queue_lr_cleanup(struct work_struct *w)
 static bool check_timeout(struct xe_exec_queue *q, struct xe_sched_job *job)
 {
        struct xe_gt *gt = guc_to_gt(exec_queue_to_guc(q));
-       u32 ctx_timestamp = xe_lrc_ctx_timestamp(q->lrc[0]);
-       u32 ctx_job_timestamp = xe_lrc_ctx_job_timestamp(q->lrc[0]);
+       u32 ctx_timestamp, ctx_job_timestamp;
        u32 timeout_ms = q->sched_props.job_timeout_ms;
        u32 diff;
        u64 running_time_ms;
 
+       if (!xe_sched_job_started(job)) {
+               xe_gt_warn(gt, "Check job timeout: seqno=%u, lrc_seqno=%u, guc_id=%d, not started",
+                          xe_sched_job_seqno(job), xe_sched_job_lrc_seqno(job),
+                          q->guc->id);
+
+               return xe_sched_invalidate_job(job, 2);
+       }
+
+       ctx_timestamp = xe_lrc_ctx_timestamp(q->lrc[0]);
+       ctx_job_timestamp = xe_lrc_ctx_job_timestamp(q->lrc[0]);
+
        /*
         * Counter wraps at ~223s at the usual 19.2MHz, be paranoid catch
         * possible overflows with a high timeout.
@@ -1079,10 +1040,13 @@ guc_exec_queue_timedout_job(struct drm_sched_job *drm_job)
 
        /*
         * TDR has fired before free job worker. Common if exec queue
-        * immediately closed after last fence signaled.
+        * immediately closed after last fence signaled. Add back to pending
+        * list so job can be freed and kick scheduler ensuring free job is not
+        * lost.
         */
        if (test_bit(DMA_FENCE_FLAG_SIGNALED_BIT, &job->fence->flags)) {
-               guc_exec_queue_free_job(drm_job);
+               xe_sched_add_pending_job(sched, job);
+               xe_sched_submission_start(sched);
 
                return DRM_GPU_SCHED_STAT_NOMINAL;
        }
@@ -1095,10 +1059,6 @@ guc_exec_queue_timedout_job(struct drm_sched_job *drm_job)
                exec_queue_killed_or_banned_or_wedged(q) ||
                exec_queue_destroyed(q);
 
-       /* Job hasn't started, can't be timed out */
-       if (!skip_timeout_check && !xe_sched_job_started(job))
-               goto rearm;
-
        /*
         * XXX: Sampling timeout doesn't work in wedged mode as we have to
         * modify scheduling state to read timestamp. We could read the
@@ -1268,13 +1228,16 @@ static void __guc_exec_queue_fini_async(struct work_struct *w)
 
 static void guc_exec_queue_fini_async(struct xe_exec_queue *q)
 {
+       struct xe_guc *guc = exec_queue_to_guc(q);
+       struct xe_device *xe = guc_to_xe(guc);
+
        INIT_WORK(&q->guc->fini_async, __guc_exec_queue_fini_async);
 
        /* We must block on kernel engines so slabs are empty on driver unload */
        if (q->flags & EXEC_QUEUE_FLAG_PERMANENT || exec_queue_wedged(q))
                __guc_exec_queue_fini_async(&q->guc->fini_async);
        else
-               queue_work(system_wq, &q->guc->fini_async);
+               queue_work(xe->destroy_wq, &q->guc->fini_async);
 }
 
 static void __guc_exec_queue_fini(struct xe_guc *guc, struct xe_exec_queue *q)
@@ -1452,8 +1415,7 @@ static int guc_exec_queue_init(struct xe_exec_queue *q)
        timeout = (q->vm && xe_vm_in_lr_mode(q->vm)) ? MAX_SCHEDULE_TIMEOUT :
                  msecs_to_jiffies(q->sched_props.job_timeout_ms);
        err = xe_sched_init(&ge->sched, &drm_sched_ops, &xe_sched_ops,
-                           get_submit_wq(guc),
-                           q->lrc[0]->ring.size / MAX_JOB_SIZE_BYTES, 64,
+                           NULL, q->lrc[0]->ring.size / MAX_JOB_SIZE_BYTES, 64,
                            timeout, guc_to_gt(guc)->ordered_wq, NULL,
                            q->name, gt_to_xe(q->gt)->drm.dev);
        if (err)
@@ -1770,8 +1732,13 @@ void xe_guc_submit_stop(struct xe_guc *guc)
 
        mutex_lock(&guc->submission_state.lock);
 
-       xa_for_each(&guc->submission_state.exec_queue_lookup, index, q)
+       xa_for_each(&guc->submission_state.exec_queue_lookup, index, q) {
+               /* Prevent redundant attempts to stop parallel queues */
+               if (q->guc->id != index)
+                       continue;
+
                guc_exec_queue_stop(guc, q);
+       }
 
        mutex_unlock(&guc->submission_state.lock);
 
@@ -1796,6 +1763,7 @@ static void guc_exec_queue_start(struct xe_exec_queue *q)
        }
 
        xe_sched_submission_start(sched);
+       xe_sched_submission_resume_tdr(sched);
 }
 
 int xe_guc_submit_start(struct xe_guc *guc)
@@ -1808,8 +1776,13 @@ int xe_guc_submit_start(struct xe_guc *guc)
 
        mutex_lock(&guc->submission_state.lock);
        atomic_dec(&guc->submission_state.stopped);
-       xa_for_each(&guc->submission_state.exec_queue_lookup, index, q)
+       xa_for_each(&guc->submission_state.exec_queue_lookup, index, q) {
+               /* Prevent redundant attempts to start parallel queues */
+               if (q->guc->id != index)
+                       continue;
+
                guc_exec_queue_start(q);
+       }
        mutex_unlock(&guc->submission_state.lock);
 
        wake_up_all(&guc->ct.wq);
index 546ac6350a31ffce73680cd217b9b8500aebeeb0..ed150fc09ad04f4f3c1e44969fc8e179a1056907 100644 (file)
@@ -72,15 +72,10 @@ struct xe_guc {
                atomic_t stopped;
                /** @submission_state.lock: protects submission state */
                struct mutex lock;
-#ifdef CONFIG_PROVE_LOCKING
-#define NUM_SUBMIT_WQ  256
-               /** @submission_state.submit_wq_pool: submission ordered workqueues pool */
-               struct workqueue_struct *submit_wq_pool[NUM_SUBMIT_WQ];
-               /** @submission_state.submit_wq_idx: submission ordered workqueue index */
-               int submit_wq_idx;
-#endif
                /** @submission_state.enabled: submission is enabled */
                bool enabled;
+               /** @submission_state.fini_wq: submit fini wait queue */
+               wait_queue_head_t fini_wq;
        } submission_state;
        /** @hwconfig: Hardware config state */
        struct {
index eae38a49ee8e592d48b8f00fb9c3eeb1b6ccdcf2..2804f14f8f2979d9b6ec0309a2a6a5ad86d2c9f0 100644 (file)
@@ -709,8 +709,7 @@ static int xe_oa_configure_oar_context(struct xe_oa_stream *stream, bool enable)
                {
                        RING_CONTEXT_CONTROL(stream->hwe->mmio_base),
                        regs_offset + CTX_CONTEXT_CONTROL,
-                       _MASKED_FIELD(CTX_CTRL_OAC_CONTEXT_ENABLE,
-                                     enable ? CTX_CTRL_OAC_CONTEXT_ENABLE : 0)
+                       _MASKED_BIT_ENABLE(CTX_CTRL_OAC_CONTEXT_ENABLE),
                },
        };
        struct xe_oa_reg reg_lri = { OAR_OACONTROL, oacontrol };
@@ -742,10 +741,8 @@ static int xe_oa_configure_oac_context(struct xe_oa_stream *stream, bool enable)
                {
                        RING_CONTEXT_CONTROL(stream->hwe->mmio_base),
                        regs_offset + CTX_CONTEXT_CONTROL,
-                       _MASKED_FIELD(CTX_CTRL_OAC_CONTEXT_ENABLE,
-                                     enable ? CTX_CTRL_OAC_CONTEXT_ENABLE : 0) |
-                       _MASKED_FIELD(CTX_CTRL_RUN_ALONE,
-                                     enable ? CTX_CTRL_RUN_ALONE : 0),
+                       _MASKED_BIT_ENABLE(CTX_CTRL_OAC_CONTEXT_ENABLE) |
+                       _MASKED_FIELD(CTX_CTRL_RUN_ALONE, enable ? CTX_CTRL_RUN_ALONE : 0),
                },
        };
        struct xe_oa_reg reg_lri = { OAC_OACONTROL, oacontrol };
index 937c3e064f0df31aea0c2c75be3c928fbf887484..5e962e72c97ea6cfec4511e96dfdf0b484b4f7e3 100644 (file)
@@ -924,6 +924,8 @@ static int xe_pci_resume(struct device *dev)
        if (err)
                return err;
 
+       pci_restore_state(pdev);
+
        err = pci_enable_device(pdev);
        if (err)
                return err;
index 7cf2160fe0408d2001e3ea810ab44dcdeff99200..33eb039053e4f5e71b82944b11237aedc338e664 100644 (file)
@@ -123,7 +123,7 @@ int xe_pm_suspend(struct xe_device *xe)
        for_each_gt(gt, xe, id)
                xe_gt_suspend_prepare(gt);
 
-       xe_display_pm_suspend(xe, false);
+       xe_display_pm_suspend(xe);
 
        /* FIXME: Super racey... */
        err = xe_bo_evict_all(xe);
@@ -133,7 +133,7 @@ int xe_pm_suspend(struct xe_device *xe)
        for_each_gt(gt, xe, id) {
                err = xe_gt_suspend(gt);
                if (err) {
-                       xe_display_pm_resume(xe, false);
+                       xe_display_pm_resume(xe);
                        goto err;
                }
        }
@@ -187,7 +187,7 @@ int xe_pm_resume(struct xe_device *xe)
        for_each_gt(gt, xe, id)
                xe_gt_resume(gt);
 
-       xe_display_pm_resume(xe, false);
+       xe_display_pm_resume(xe);
 
        err = xe_bo_restore_user(xe);
        if (err)
index d6353e8969f032a50e0c184fb73bdfb32b189a37..f27f579f4d85aacc6511bb77c2523db40e3abb51 100644 (file)
@@ -2188,5 +2188,5 @@ void xe_pt_update_ops_abort(struct xe_tile *tile, struct xe_vma_ops *vops)
                                           pt_op->num_entries);
        }
 
-       xe_bo_put_commit(&vops->pt_update_ops[tile->id].deferred);
+       xe_pt_update_ops_fini(tile, vops);
 }
index 28d9bb3b825de9f9b692e29125038874fb20155d..848da8e68c7a8378c65d818f9dff26c8b87186a6 100644 (file)
@@ -161,7 +161,11 @@ query_engine_cycles(struct xe_device *xe,
                          cpu_clock);
 
        xe_force_wake_put(gt_to_fw(gt), XE_FORCEWAKE_ALL);
-       resp.width = 36;
+
+       if (GRAPHICS_VER(xe) >= 20)
+               resp.width = 64;
+       else
+               resp.width = 36;
 
        /* Only write to the output fields of user query */
        if (put_user(resp.cpu_timestamp, &query_ptr->cpu_timestamp))
index bb3c2a8303623792d4631a8d5d16f08cdf1d8cfb..2e72c06fd40d07c63ba5876f1663acefb97dea5c 100644 (file)
@@ -54,11 +54,12 @@ static struct xe_user_fence *user_fence_create(struct xe_device *xe, u64 addr,
 {
        struct xe_user_fence *ufence;
        u64 __user *ptr = u64_to_user_ptr(addr);
+       u64 __maybe_unused prefetch_val;
 
-       if (!access_ok(ptr, sizeof(*ptr)))
+       if (get_user(prefetch_val, ptr))
                return ERR_PTR(-EFAULT);
 
-       ufence = kmalloc(sizeof(*ufence), GFP_KERNEL);
+       ufence = kzalloc(sizeof(*ufence), GFP_KERNEL);
        if (!ufence)
                return ERR_PTR(-ENOMEM);
 
index faa1bf42e50edf7011060ae21a3d827ed02cd6b3..0d5e04158917be78b48c06f5eafc96b10ce1c59f 100644 (file)
@@ -42,20 +42,48 @@ static const struct xe_rtp_entry_sr gt_tunings[] = {
          XE_RTP_ACTIONS(CLR(CCCHKNREG1, ENCOMPPERFFIX),
                         SET(CCCHKNREG1, L3CMPCTRL))
        },
+       { XE_RTP_NAME("Tuning: Compression Overfetch - media"),
+         XE_RTP_RULES(MEDIA_VERSION(2000)),
+         XE_RTP_ACTIONS(CLR(XE2LPM_CCCHKNREG1, ENCOMPPERFFIX),
+                        SET(XE2LPM_CCCHKNREG1, L3CMPCTRL))
+       },
        { XE_RTP_NAME("Tuning: Enable compressible partial write overfetch in L3"),
          XE_RTP_RULES(GRAPHICS_VERSION_RANGE(2001, XE_RTP_END_VERSION_UNDEFINED)),
          XE_RTP_ACTIONS(SET(L3SQCREG3, COMPPWOVERFETCHEN))
        },
+       { XE_RTP_NAME("Tuning: Enable compressible partial write overfetch in L3 - media"),
+         XE_RTP_RULES(MEDIA_VERSION(2000)),
+         XE_RTP_ACTIONS(SET(XE2LPM_L3SQCREG3, COMPPWOVERFETCHEN))
+       },
        { XE_RTP_NAME("Tuning: L2 Overfetch Compressible Only"),
          XE_RTP_RULES(GRAPHICS_VERSION_RANGE(2001, XE_RTP_END_VERSION_UNDEFINED)),
          XE_RTP_ACTIONS(SET(L3SQCREG2,
                             COMPMEMRD256BOVRFETCHEN))
        },
+       { XE_RTP_NAME("Tuning: L2 Overfetch Compressible Only - media"),
+         XE_RTP_RULES(MEDIA_VERSION(2000)),
+         XE_RTP_ACTIONS(SET(XE2LPM_L3SQCREG2,
+                            COMPMEMRD256BOVRFETCHEN))
+       },
        { XE_RTP_NAME("Tuning: Stateless compression control"),
          XE_RTP_RULES(GRAPHICS_VERSION_RANGE(2001, XE_RTP_END_VERSION_UNDEFINED)),
          XE_RTP_ACTIONS(FIELD_SET(STATELESS_COMPRESSION_CTRL, UNIFIED_COMPRESSION_FORMAT,
                                   REG_FIELD_PREP(UNIFIED_COMPRESSION_FORMAT, 0)))
        },
+       { XE_RTP_NAME("Tuning: Stateless compression control - media"),
+         XE_RTP_RULES(MEDIA_VERSION_RANGE(1301, 2000)),
+         XE_RTP_ACTIONS(FIELD_SET(STATELESS_COMPRESSION_CTRL, UNIFIED_COMPRESSION_FORMAT,
+                                  REG_FIELD_PREP(UNIFIED_COMPRESSION_FORMAT, 0)))
+       },
+       { XE_RTP_NAME("Tuning: L3 RW flush all Cache"),
+         XE_RTP_RULES(GRAPHICS_VERSION(2004)),
+         XE_RTP_ACTIONS(SET(SCRATCH3_LBCF, RWFLUSHALLEN))
+       },
+       { XE_RTP_NAME("Tuning: L3 RW flush all cache - media"),
+         XE_RTP_RULES(MEDIA_VERSION(2000)),
+         XE_RTP_ACTIONS(SET(XE2LPM_SCRATCH3_LBCF, RWFLUSHALLEN))
+       },
+
        {}
 };
 
index 7acd5fc9d032bd25ef9a14c6f8471e07a819bde6..c99380271de62f8659fdd909a5bd9980d09de4d9 100644 (file)
@@ -1613,7 +1613,7 @@ void xe_vm_close_and_put(struct xe_vm *vm)
 
        up_write(&vm->lock);
 
-       mutex_lock(&xe->usm.lock);
+       down_write(&xe->usm.lock);
        if (vm->usm.asid) {
                void *lookup;
 
@@ -1623,7 +1623,7 @@ void xe_vm_close_and_put(struct xe_vm *vm)
                lookup = xa_erase(&xe->usm.asid_to_vm, vm->usm.asid);
                xe_assert(xe, lookup == vm);
        }
-       mutex_unlock(&xe->usm.lock);
+       up_write(&xe->usm.lock);
 
        for_each_tile(tile, xe, id)
                xe_range_fence_tree_fini(&vm->rftree[id]);
@@ -1765,25 +1765,18 @@ int xe_vm_create_ioctl(struct drm_device *dev, void *data,
        if (IS_ERR(vm))
                return PTR_ERR(vm);
 
-       mutex_lock(&xef->vm.lock);
-       err = xa_alloc(&xef->vm.xa, &id, vm, xa_limit_32b, GFP_KERNEL);
-       mutex_unlock(&xef->vm.lock);
-       if (err)
-               goto err_close_and_put;
-
        if (xe->info.has_asid) {
-               mutex_lock(&xe->usm.lock);
+               down_write(&xe->usm.lock);
                err = xa_alloc_cyclic(&xe->usm.asid_to_vm, &asid, vm,
                                      XA_LIMIT(1, XE_MAX_ASID - 1),
                                      &xe->usm.next_asid, GFP_KERNEL);
-               mutex_unlock(&xe->usm.lock);
+               up_write(&xe->usm.lock);
                if (err < 0)
-                       goto err_free_id;
+                       goto err_close_and_put;
 
                vm->usm.asid = asid;
        }
 
-       args->vm_id = id;
        vm->xef = xe_file_get(xef);
 
        /* Record BO memory for VM pagetable created against client */
@@ -1796,12 +1789,15 @@ int xe_vm_create_ioctl(struct drm_device *dev, void *data,
        args->reserved[0] = xe_bo_main_addr(vm->pt_root[0]->bo, XE_PAGE_SIZE);
 #endif
 
+       /* user id alloc must always be last in ioctl to prevent UAF */
+       err = xa_alloc(&xef->vm.xa, &id, vm, xa_limit_32b, GFP_KERNEL);
+       if (err)
+               goto err_close_and_put;
+
+       args->vm_id = id;
+
        return 0;
 
-err_free_id:
-       mutex_lock(&xef->vm.lock);
-       xa_erase(&xef->vm.xa, id);
-       mutex_unlock(&xef->vm.lock);
 err_close_and_put:
        xe_vm_close_and_put(vm);
 
@@ -3203,10 +3199,8 @@ int xe_vm_invalidate_vma(struct xe_vma *vma)
 
                        ret = xe_gt_tlb_invalidation_vma(tile->primary_gt,
                                                         &fence[fence_id], vma);
-                       if (ret < 0) {
-                               xe_gt_tlb_invalidation_fence_fini(&fence[fence_id]);
+                       if (ret)
                                goto wait;
-                       }
                        ++fence_id;
 
                        if (!tile->media_gt)
@@ -3218,10 +3212,8 @@ int xe_vm_invalidate_vma(struct xe_vma *vma)
 
                        ret = xe_gt_tlb_invalidation_vma(tile->media_gt,
                                                         &fence[fence_id], vma);
-                       if (ret < 0) {
-                               xe_gt_tlb_invalidation_fence_fini(&fence[fence_id]);
+                       if (ret)
                                goto wait;
-                       }
                        ++fence_id;
                }
        }
index d424992514a4dcabd1960128dbc1847146a1ce6a..353936a0f877dec72e413e504941b82bc03a8055 100644 (file)
@@ -710,6 +710,10 @@ static const struct xe_rtp_entry_sr lrc_was[] = {
                             DIS_PARTIAL_AUTOSTRIP |
                             DIS_AUTOSTRIP))
        },
+       { XE_RTP_NAME("15016589081"),
+         XE_RTP_RULES(GRAPHICS_VERSION(2004), ENGINE_CLASS(RENDER)),
+         XE_RTP_ACTIONS(SET(CHICKEN_RASTER_1, DIS_CLIP_NEGATIVE_BOUNDING_BOX))
+       },
 
        /* Xe2_HPG */
        { XE_RTP_NAME("15010599737"),
index d46fa8374980cdb8bd65e0b7555780909a8c605f..f5deb81eba01eeab3ca86a3f1edb03115d0b64aa 100644 (file)
@@ -169,9 +169,6 @@ int xe_wait_user_fence_ioctl(struct drm_device *dev, void *data,
                        args->timeout = 0;
        }
 
-       if (!timeout && !(err < 0))
-               err = -ETIME;
-
        if (q)
                xe_exec_queue_put(q);
 
index 955c971c528d429c7452cc8b15b0f932da51185c..a6f6779662a36bd8dd3292137e2dbbcf1c0e8854 100644 (file)
@@ -58,6 +58,7 @@ int host1x_memory_context_list_init(struct host1x *host1x)
                ctx->dev.parent = host1x->dev;
                ctx->dev.release = host1x_memory_context_release;
 
+               ctx->dev.dma_parms = &ctx->dma_parms;
                dma_set_max_seg_size(&ctx->dev, UINT_MAX);
 
                err = device_add(&ctx->dev);
index b62e4f0e8130fb8276ffcf4b20eebc2ae7223028..e98528777faaec48faca72dc1a728f1150fb3c17 100644 (file)
@@ -625,12 +625,6 @@ static int host1x_probe(struct platform_device *pdev)
                goto free_contexts;
        }
 
-       err = host1x_intr_init(host);
-       if (err) {
-               dev_err(&pdev->dev, "failed to initialize interrupts\n");
-               goto deinit_syncpt;
-       }
-
        pm_runtime_enable(&pdev->dev);
 
        err = devm_tegra_core_dev_init_opp_table_common(&pdev->dev);
@@ -642,6 +636,12 @@ static int host1x_probe(struct platform_device *pdev)
        if (err)
                goto pm_disable;
 
+       err = host1x_intr_init(host);
+       if (err) {
+               dev_err(&pdev->dev, "failed to initialize interrupts\n");
+               goto pm_put;
+       }
+
        host1x_debug_init(host);
 
        err = host1x_register(host);
@@ -658,13 +658,11 @@ unregister:
        host1x_unregister(host);
 deinit_debugfs:
        host1x_debug_deinit(host);
-
+       host1x_intr_deinit(host);
+pm_put:
        pm_runtime_put_sync_suspend(&pdev->dev);
 pm_disable:
        pm_runtime_disable(&pdev->dev);
-
-       host1x_intr_deinit(host);
-deinit_syncpt:
        host1x_syncpt_deinit(host);
 free_contexts:
        host1x_memory_context_list_free(&host->context_list);
index 69e46b1dff1fd5741b60a3c6fa2ed409a1ec7de9..7630a36ecf812669cb6943e054c8cdfdc048acaf 100644 (file)
@@ -12,7 +12,7 @@
 #include <linux/debugfs.h>
 #include <linux/list.h>
 #include <linux/greybus.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #include "arpc.h"
 #include "greybus_trace.h"
index 3a1ade84737cb2e82723e64a907c29e99ba94e92..473ac3f2d382191b380557154b241a09f8eeebfe 100644 (file)
@@ -6,7 +6,7 @@
  * Copyright (c) 2023 BeagleBoard.org Foundation
  */
 
-#include <asm-generic/unaligned.h>
+#include <linux/unaligned.h>
 #include <linux/crc32.h>
 #include <linux/gpio/consumer.h>
 #include <linux/firmware.h>
index 4b59687ff5d821ebb3791e1288592b6c9f6f159d..3438d392920fada9b7288a2687f5b9472b35cf45 100644 (file)
@@ -236,9 +236,9 @@ int amd_sfh_hid_client_init(struct amd_mp2_dev *privdata)
        cl_data->in_data = in_data;
 
        for (i = 0; i < cl_data->num_hid_devices; i++) {
-               in_data->sensor_virt_addr[i] = dma_alloc_coherent(dev, sizeof(int) * 8,
-                                                                 &cl_data->sensor_dma_addr[i],
-                                                                 GFP_KERNEL);
+               in_data->sensor_virt_addr[i] = dmam_alloc_coherent(dev, sizeof(int) * 8,
+                                                                  &cl_data->sensor_dma_addr[i],
+                                                                  GFP_KERNEL);
                if (!in_data->sensor_virt_addr[i]) {
                        rc = -ENOMEM;
                        goto cleanup;
@@ -331,7 +331,6 @@ cleanup:
 int amd_sfh_hid_client_deinit(struct amd_mp2_dev *privdata)
 {
        struct amdtp_cl_data *cl_data = privdata->cl_data;
-       struct amd_input_data *in_data = cl_data->in_data;
        int i, status;
 
        for (i = 0; i < cl_data->num_hid_devices; i++) {
@@ -351,12 +350,5 @@ int amd_sfh_hid_client_deinit(struct amd_mp2_dev *privdata)
        cancel_delayed_work_sync(&cl_data->work_buffer);
        amdtp_hid_remove(cl_data);
 
-       for (i = 0; i < cl_data->num_hid_devices; i++) {
-               if (in_data->sensor_virt_addr[i]) {
-                       dma_free_coherent(&privdata->pdev->dev, 8 * sizeof(int),
-                                         in_data->sensor_virt_addr[i],
-                                         cl_data->sensor_dma_addr[i]);
-               }
-       }
        return 0;
 }
index cd696c59ba0f4faec12234cb3154ca09dced5384..702c22fae136aa4e9a7dd95f7ee9d63eec73d7cb 100644 (file)
@@ -276,9 +276,23 @@ static int __hid_bpf_rdesc_fixup(struct hid_bpf_ctx *ctx)
        return 0;
 }
 
+static int __hid_bpf_hw_request(struct hid_bpf_ctx *ctx, unsigned char reportnum,
+                               enum hid_report_type rtype, enum hid_class_request reqtype,
+                               u64 source)
+{
+       return 0;
+}
+
+static int __hid_bpf_hw_output_report(struct hid_bpf_ctx *ctx, u64 source)
+{
+       return 0;
+}
+
 static struct hid_bpf_ops __bpf_hid_bpf_ops = {
        .hid_device_event = __hid_bpf_device_event,
        .hid_rdesc_fixup = __hid_bpf_rdesc_fixup,
+       .hid_hw_request = __hid_bpf_hw_request,
+       .hid_hw_output_report = __hid_bpf_hw_output_report,
 };
 
 static struct bpf_struct_ops bpf_hid_bpf_ops = {
index 669d769ea1dcd12505e08e09fec3117f0295081a..ba00f6e6324b093b65910d4f2f8d15c8e47d106d 100644 (file)
@@ -8,7 +8,7 @@
 #include <linux/input.h>
 #include <linux/input/mt.h>
 #include <linux/module.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include "hid-ids.h"
 
 /* ALPS Device Product ID */
index 30de92d0bf0f2f932edab57c1e81da2874a34f9c..612ee6ddfc8db01228f9a4b960c709713864ac23 100644 (file)
@@ -20,7 +20,7 @@
 #include <linux/list.h>
 #include <linux/mm.h>
 #include <linux/spinlock.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include <asm/byteorder.h>
 #include <linux/input.h>
 #include <linux/wait.h>
index f9db991d3c5a2c734698ac85af36ae15eb505f71..d2439399fb357a84c0bc20788f04ac26f932225b 100644 (file)
@@ -16,7 +16,7 @@
 #include <linux/module.h>
 #include <linux/slab.h>
 #include <linux/kernel.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include <asm/byteorder.h>
 
 #include <linux/hid.h>
index 0e59663814dde20068bf76beb3db2e25a1f17bc7..0f87bf9c67cfb68f10d4bc55649346d20817c73b 100644 (file)
@@ -4,7 +4,7 @@
  *
  * Copyright (C) 2024 Godix, Inc.
  */
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include <linux/delay.h>
 #include <linux/hid.h>
 #include <linux/interrupt.h>
index 4e79fafeeafa8966a67067c9c214fbee590b2b72..22683ec819aacae22844f22017473dd7fd83e06b 100644 (file)
@@ -23,7 +23,7 @@
 #include <linux/platform_data/cros_ec_proto.h>
 #include <linux/platform_device.h>
 #include <linux/pm_wakeup.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #include "hid-ids.h"
 #include "hid-vivaldi-common.h"
index 86820a3d9766d33d31504f60ee8536bedcd85eba..92cff3f2658cf5049d663a162952206a41f3c133 100644 (file)
 #define I2C_DEVICE_ID_GOODIX_01E8      0x01e8
 #define I2C_DEVICE_ID_GOODIX_01E9      0x01e9
 #define I2C_DEVICE_ID_GOODIX_01F0      0x01f0
+#define I2C_DEVICE_ID_GOODIX_0D42      0x0d42
 
 #define USB_VENDOR_ID_GOODTOUCH                0x1aad
 #define USB_DEVICE_ID_GOODTOUCH_000f   0x000f
 #define USB_DEVICE_ID_LOGITECH_NANO_RECEIVER_LIGHTSPEED_1      0xc539
 #define USB_DEVICE_ID_LOGITECH_NANO_RECEIVER_LIGHTSPEED_1_1    0xc53f
 #define USB_DEVICE_ID_LOGITECH_NANO_RECEIVER_POWERPLAY 0xc53a
+#define USB_DEVICE_ID_LOGITECH_BOLT_RECEIVER   0xc548
 #define USB_DEVICE_ID_SPACETRAVELLER   0xc623
 #define USB_DEVICE_ID_SPACENAVIGATOR   0xc626
 #define USB_DEVICE_ID_DINOVO_DESKTOP   0xc704
 #define USB_DEVICE_ID_PLANTRONICS_BLACKWIRE_3220_SERIES        0xc056
 #define USB_DEVICE_ID_PLANTRONICS_BLACKWIRE_3215_SERIES        0xc057
 #define USB_DEVICE_ID_PLANTRONICS_BLACKWIRE_3225_SERIES        0xc058
+#define USB_DEVICE_ID_PLANTRONICS_BLACKWIRE_3325_SERIES        0x430c
+#define USB_DEVICE_ID_PLANTRONICS_ENCOREPRO_500_SERIES         0x431e
 
 #define USB_VENDOR_ID_PANASONIC                0x04da
 #define USB_DEVICE_ID_PANABOARD_UBT780 0x1044
index 32344331282f928d3b092d1a973c60b216d7a2e1..bd96bfa7af709748383fe3d889a98f5902aa0952 100644 (file)
@@ -8,7 +8,7 @@
  *  Copyright (c) 2023 David Yang
  */
 
-#include <asm-generic/unaligned.h>
+#include <linux/unaligned.h>
 #include <linux/device.h>
 #include <linux/hid.h>
 #include <linux/module.h>
index 3b0c779ce8f712c85177b9c85e37e9c16b064a18..f66194fde8912ac1b223e0092d5589e2a351269b 100644 (file)
@@ -473,6 +473,7 @@ static int lenovo_input_mapping(struct hid_device *hdev,
                return lenovo_input_mapping_tp10_ultrabook_kbd(hdev, hi, field,
                                                               usage, bit, max);
        case USB_DEVICE_ID_LENOVO_X1_TAB:
+       case USB_DEVICE_ID_LENOVO_X1_TAB3:
                return lenovo_input_mapping_x1_tab_kbd(hdev, hi, field, usage, bit, max);
        default:
                return 0;
@@ -583,6 +584,7 @@ static ssize_t attr_fn_lock_store(struct device *dev,
                break;
        case USB_DEVICE_ID_LENOVO_TP10UBKBD:
        case USB_DEVICE_ID_LENOVO_X1_TAB:
+       case USB_DEVICE_ID_LENOVO_X1_TAB3:
                ret = lenovo_led_set_tp10ubkbd(hdev, TP10UBKBD_FN_LOCK_LED, value);
                if (ret)
                        return ret;
@@ -776,6 +778,7 @@ static int lenovo_event(struct hid_device *hdev, struct hid_field *field,
                return lenovo_event_cptkbd(hdev, field, usage, value);
        case USB_DEVICE_ID_LENOVO_TP10UBKBD:
        case USB_DEVICE_ID_LENOVO_X1_TAB:
+       case USB_DEVICE_ID_LENOVO_X1_TAB3:
                return lenovo_event_tp10ubkbd(hdev, field, usage, value);
        default:
                return 0;
@@ -1056,6 +1059,7 @@ static int lenovo_led_brightness_set(struct led_classdev *led_cdev,
                break;
        case USB_DEVICE_ID_LENOVO_TP10UBKBD:
        case USB_DEVICE_ID_LENOVO_X1_TAB:
+       case USB_DEVICE_ID_LENOVO_X1_TAB3:
                ret = lenovo_led_set_tp10ubkbd(hdev, tp10ubkbd_led[led_nr], value);
                break;
        }
@@ -1286,6 +1290,7 @@ static int lenovo_probe(struct hid_device *hdev,
                break;
        case USB_DEVICE_ID_LENOVO_TP10UBKBD:
        case USB_DEVICE_ID_LENOVO_X1_TAB:
+       case USB_DEVICE_ID_LENOVO_X1_TAB3:
                ret = lenovo_probe_tp10ubkbd(hdev);
                break;
        default:
@@ -1372,6 +1377,7 @@ static void lenovo_remove(struct hid_device *hdev)
                break;
        case USB_DEVICE_ID_LENOVO_TP10UBKBD:
        case USB_DEVICE_ID_LENOVO_X1_TAB:
+       case USB_DEVICE_ID_LENOVO_X1_TAB3:
                lenovo_remove_tp10ubkbd(hdev);
                break;
        }
@@ -1421,6 +1427,8 @@ static const struct hid_device_id lenovo_devices[] = {
         */
        { HID_DEVICE(BUS_USB, HID_GROUP_GENERIC,
                     USB_VENDOR_ID_LENOVO, USB_DEVICE_ID_LENOVO_X1_TAB) },
+       { HID_DEVICE(BUS_USB, HID_GROUP_GENERIC,
+                    USB_VENDOR_ID_LENOVO, USB_DEVICE_ID_LENOVO_X1_TAB3) },
        { }
 };
 
index 229820fda9602ebbe2fa69e66279519cbd23482b..8602c63ed9c6ce4e3bba36edb55811f8e9b44a2f 100644 (file)
@@ -41,7 +41,7 @@
 #include <linux/timer.h>
 #include <linux/usb.h>
 
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #include "hid-ids.h"
 
index d9580bc3e19a14e339548d6fce62351ed112d6b2..34fa71ceec2b2037cba5219127a6ac494a47eead 100644 (file)
@@ -13,7 +13,7 @@
 #include <linux/kfifo.h>
 #include <linux/delay.h>
 #include <linux/usb.h> /* For to_usb_interface for kvm extra intf check */
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include "hid-ids.h"
 
 #define DJ_MAX_PAIRED_DEVICES                  7
index 0e33fa0eb8db6d0e351fa98538de6c1b726d1744..cf7a6986cf20133127e6ad9df1b4441cf407a176 100644 (file)
@@ -23,7 +23,7 @@
 #include <linux/workqueue.h>
 #include <linux/atomic.h>
 #include <linux/fixp-arith.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include "usbhid/usbhid.h"
 #include "hid-ids.h"
 
index 638e36c6d0f1030c62ec821c827e03bff56f0b24..e936019d21fecfc73b078ca8e93c9b839d9c9050 100644 (file)
@@ -2026,6 +2026,10 @@ static const struct hid_device_id mt_devices[] = {
                HID_DEVICE(BUS_I2C, HID_GROUP_MULTITOUCH_WIN_8,
                        USB_VENDOR_ID_ELAN, 0x3148) },
 
+       { .driver_data = MT_CLS_WIN_8_FORCE_MULTI_INPUT_NSMU,
+               HID_DEVICE(BUS_I2C, HID_GROUP_MULTITOUCH_WIN_8,
+                       USB_VENDOR_ID_ELAN, 0x32ae) },
+
        /* Elitegroup panel */
        { .driver_data = MT_CLS_SERIAL,
                MT_USB_DEVICE(USB_VENDOR_ID_ELITEGROUP,
@@ -2095,6 +2099,11 @@ static const struct hid_device_id mt_devices[] = {
                HID_DEVICE(BUS_I2C, HID_GROUP_MULTITOUCH_WIN_8,
                        0x347d, 0x7853) },
 
+       /* HONOR MagicBook Art 14 touchpad */
+       { .driver_data = MT_CLS_VTL,
+               HID_DEVICE(BUS_I2C, HID_GROUP_MULTITOUCH_WIN_8,
+                       0x35cc, 0x0104) },
+
        /* Ilitek dual touch panel */
        {  .driver_data = MT_CLS_NSMU,
                MT_USB_DEVICE(USB_VENDOR_ID_ILITEK,
@@ -2137,6 +2146,10 @@ static const struct hid_device_id mt_devices[] = {
                HID_DEVICE(BUS_BLUETOOTH, HID_GROUP_MULTITOUCH_WIN_8,
                        USB_VENDOR_ID_LOGITECH,
                        USB_DEVICE_ID_LOGITECH_CASA_TOUCHPAD) },
+       { .driver_data = MT_CLS_WIN_8_FORCE_MULTI_INPUT_NSMU,
+               HID_DEVICE(BUS_USB, HID_GROUP_MULTITOUCH_WIN_8,
+                       USB_VENDOR_ID_LOGITECH,
+                       USB_DEVICE_ID_LOGITECH_BOLT_RECEIVER) },
 
        /* MosArt panels */
        { .driver_data = MT_CLS_CONFIDENCE_MINUS_ONE,
index 58cd0506e431bc4da7cbc34bafc2b0c2f1263099..55153a2f79886b6b9bf8094f7d69d756ecf53185 100644 (file)
@@ -29,7 +29,7 @@
  */
 
 #include "hid-ids.h"
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include <linux/delay.h>
 #include <linux/device.h>
 #include <linux/kernel.h>
index 3d414ae194acbdaf7f6e6087ea91c7cb3e70fe85..25cfd964dc25d9d0d8acfa00f04bfffcad8aa2a5 100644 (file)
                            (usage->hid & HID_USAGE_PAGE) == HID_UP_CONSUMER)
 
 #define PLT_QUIRK_DOUBLE_VOLUME_KEYS BIT(0)
+#define PLT_QUIRK_FOLLOWED_OPPOSITE_VOLUME_KEYS BIT(1)
 
 #define PLT_DOUBLE_KEY_TIMEOUT 5 /* ms */
+#define PLT_FOLLOWED_OPPOSITE_KEY_TIMEOUT 220 /* ms */
 
 struct plt_drv_data {
        unsigned long device_type;
@@ -137,6 +139,21 @@ static int plantronics_event(struct hid_device *hdev, struct hid_field *field,
 
                drv_data->last_volume_key_ts = cur_ts;
        }
+       if (drv_data->quirks & PLT_QUIRK_FOLLOWED_OPPOSITE_VOLUME_KEYS) {
+               unsigned long prev_ts, cur_ts;
+
+               /* Usages are filtered in plantronics_usages. */
+
+               if (!value) /* Handle key presses only. */
+                       return 0;
+
+               prev_ts = drv_data->last_volume_key_ts;
+               cur_ts = jiffies;
+               if (jiffies_to_msecs(cur_ts - prev_ts) <= PLT_FOLLOWED_OPPOSITE_KEY_TIMEOUT)
+                       return 1; /* Ignore the followed opposite volume key. */
+
+               drv_data->last_volume_key_ts = cur_ts;
+       }
 
        return 0;
 }
@@ -210,6 +227,12 @@ static const struct hid_device_id plantronics_devices[] = {
        { HID_USB_DEVICE(USB_VENDOR_ID_PLANTRONICS,
                                         USB_DEVICE_ID_PLANTRONICS_BLACKWIRE_3225_SERIES),
                .driver_data = PLT_QUIRK_DOUBLE_VOLUME_KEYS },
+       { HID_USB_DEVICE(USB_VENDOR_ID_PLANTRONICS,
+                                        USB_DEVICE_ID_PLANTRONICS_BLACKWIRE_3325_SERIES),
+               .driver_data = PLT_QUIRK_FOLLOWED_OPPOSITE_VOLUME_KEYS },
+       { HID_USB_DEVICE(USB_VENDOR_ID_PLANTRONICS,
+                                        USB_DEVICE_ID_PLANTRONICS_ENCOREPRO_500_SERIES),
+               .driver_data = PLT_QUIRK_FOLLOWED_OPPOSITE_VOLUME_KEYS },
        { HID_USB_DEVICE(USB_VENDOR_ID_PLANTRONICS, HID_ANY_ID) },
        { }
 };
index 0d90d7ee693c1dae55682b547b798c551f9aa294..1468fb11e39dffc883181663a4ad44252e0a7ebb 100644 (file)
@@ -15,7 +15,7 @@
 #include <linux/led-class-multicolor.h>
 #include <linux/module.h>
 
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #include "hid-ids.h"
 
index df29c614e490d4a1f6eecc39011af21c415e5580..d2486f3734f0028bed8634b60f98654f643b6c37 100644 (file)
@@ -40,7 +40,7 @@
 #include <linux/crc32.h>
 #include <linux/usb.h>
 #include <linux/timer.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #include "hid-ids.h"
 
index 87fd4eb76c70b779ef376cb44194ba2c82ec1f8b..ef26c7defcf61ced86b07100002e572780f23305 100644 (file)
@@ -19,7 +19,7 @@
 #include "hid-ids.h"
 #include <linux/ctype.h>
 #include <linux/string.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 /**
  * uclogic_params_pen_inrange_to_str() - Convert a pen in-range reporting type
index 964d17e08f269ba908194b7d5631db67dd1d3da7..9b9cbc2aae368e0ecb4e3272219811d02c309eb0 100644 (file)
@@ -16,7 +16,7 @@
 
 #include "hid-uclogic-rdesc.h"
 #include <linux/slab.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include <kunit/visibility.h>
 
 /* Fixed WP4030U report descriptor */
index 2f8a9d3f1e861e6b3988ef790e5a7f9521e7c733..43664a24176fca008977b860537817b4941b950e 100644 (file)
@@ -36,7 +36,7 @@
 #include <linux/kernel.h>
 #include <linux/hid.h>
 #include <linux/mutex.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #include <drm/drm_panel.h>
 
@@ -50,6 +50,7 @@
 #define I2C_HID_QUIRK_BAD_INPUT_SIZE           BIT(3)
 #define I2C_HID_QUIRK_NO_WAKEUP_AFTER_RESET    BIT(4)
 #define I2C_HID_QUIRK_NO_SLEEP_ON_SUSPEND      BIT(5)
+#define I2C_HID_QUIRK_DELAY_WAKEUP_AFTER_RESUME BIT(6)
 
 /* Command opcodes */
 #define I2C_HID_OPCODE_RESET                   0x01
@@ -140,6 +141,8 @@ static const struct i2c_hid_quirks {
        { USB_VENDOR_ID_ELAN, HID_ANY_ID,
                 I2C_HID_QUIRK_NO_WAKEUP_AFTER_RESET |
                 I2C_HID_QUIRK_BOGUS_IRQ },
+       { I2C_VENDOR_ID_GOODIX, I2C_DEVICE_ID_GOODIX_0D42,
+                I2C_HID_QUIRK_DELAY_WAKEUP_AFTER_RESUME },
        { 0, 0 }
 };
 
@@ -981,6 +984,13 @@ static int i2c_hid_core_resume(struct i2c_hid *ihid)
                return -ENXIO;
        }
 
+       /* On Goodix 27c6:0d42 wait extra time before device wakeup.
+        * It's not clear why but if we send wakeup too early, the device will
+        * never trigger input interrupts.
+        */
+       if (ihid->quirks & I2C_HID_QUIRK_DELAY_WAKEUP_AFTER_RESUME)
+               msleep(1500);
+
        /* Instead of resetting device, simply powers the device on. This
         * solves "incomplete reports" on Raydium devices 2386:3118 and
         * 2386:4B33 and fixes various SIS touchscreens no longer sending
index e157863a8b250b406014fa0f6364ce27164ed5d7..b3c3cfcd97fc54280269da6255d10987caa3acfe 100644 (file)
@@ -635,7 +635,7 @@ static int ish_fw_xfer_direct_dma(struct ishtp_cl_data *client_data,
                                  const struct firmware *fw,
                                  const struct shim_fw_info fw_info)
 {
-       int rv;
+       int rv = 0;
        void *dma_buf;
        dma_addr_t dma_buf_phy;
        u32 fragment_offset, fragment_size, payload_max_size;
index 61e5814b0ad7d4993ebad9fba54a6e903c6a2d1a..eae47e0d95ed69d227865a90333be81214fd77b4 100644 (file)
@@ -8,7 +8,7 @@
  *                         Maximilian Luz <[email protected]>
  */
 
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include <linux/hid.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
index a3e9cceddfacf36c6db5dd3106b22d65dfe625c6..6690c24f28f0cbce61ba4676e3f5bc8b7e50fe2d 100644 (file)
@@ -7,7 +7,7 @@
  * Copyright (C) 2019-2021 Maximilian Luz <[email protected]>
  */
 
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include <linux/hid.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
index 8c0cbb2deb11a9ab86293b2245579390a0d02a1f..383200d9121ae8be1bc347d427d3b0220e72e818 100644 (file)
@@ -7,7 +7,7 @@
  * Copyright (C) 2019-2021 Maximilian Luz <[email protected]>
  */
 
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include <linux/hid.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
index cb687ea7325c19b59e49e596703c39bc47896184..a9e85bdd4cc6560ec9e050e2e30ea752d93a200d 100644 (file)
@@ -21,7 +21,7 @@
 #include <linux/mutex.h>
 #include <linux/property.h>
 #include <linux/spinlock.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include <asm/byteorder.h>
 #include <linux/input.h>
 #include <linux/wait.h>
index 77c5fb26cd14c29bde5aec10a275e2402a5de99b..6f1443999d1d9b26da2b02af1008de0f47c0453f 100644 (file)
@@ -89,7 +89,7 @@
 #include <linux/usb/input.h>
 #include <linux/power_supply.h>
 #include <linux/timer.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 /*
  * Version Information
index 59a13ad9371cd74da0c8bb7d501e5a8c73bb7409..413606bdf476df96ae6b4d6380fd8c4cad262858 100644 (file)
@@ -2567,6 +2567,8 @@ static void wacom_wac_pen_report(struct hid_device *hdev,
                /* Going into range select tool */
                if (wacom_wac->hid_data.invert_state)
                        wacom_wac->tool[0] = BTN_TOOL_RUBBER;
+               else if (wacom_wac->features.quirks & WACOM_QUIRK_AESPEN)
+                       wacom_wac->tool[0] = BTN_TOOL_PEN;
                else if (wacom_wac->id[0])
                        wacom_wac->tool[0] = wacom_intuos_get_tool_type(wacom_wac->id[0]);
                else
index 65ea92529406d67d30de7c1d98d688189d35e9ba..08a3c863f80a27f3758acfa090a7275dfd97be4f 100644 (file)
@@ -162,6 +162,7 @@ config SENSORS_ADM9240
        tristate "Analog Devices ADM9240 and compatibles"
        depends on I2C
        select HWMON_VID
+       select REGMAP_I2C
        help
          If you say yes here you get support for Analog Devices ADM9240,
          Dallas DS1780, National Semiconductor LM81 sensor chips.
@@ -223,6 +224,7 @@ config SENSORS_ADT7462
 config SENSORS_ADT7470
        tristate "Analog Devices ADT7470"
        depends on I2C
+       select REGMAP_I2C
        help
          If you say yes here you get support for the Analog Devices
          ADT7470 temperature monitoring chips.
@@ -999,6 +1001,7 @@ config SENSORS_LTC2990
 config SENSORS_LTC2991
        tristate "Analog Devices LTC2991"
        depends on I2C
+       select REGMAP_I2C
        help
          If you say yes here you get support for Analog Devices LTC2991
          Octal I2C Voltage, Current, and Temperature Monitor. The LTC2991
@@ -1146,6 +1149,7 @@ config SENSORS_MAX1619
 config SENSORS_MAX1668
        tristate "Maxim MAX1668 and compatibles"
        depends on I2C
+       select REGMAP_I2C
        help
          If you say yes here you get support for MAX1668, MAX1989 and
          MAX1805 chips.
@@ -1275,6 +1279,7 @@ config SENSORS_MAX31790
 config SENSORS_MC34VR500
        tristate "NXP MC34VR500 hardware monitoring driver"
        depends on I2C
+       select REGMAP_I2C
        help
          If you say yes here you get support for the temperature and input
          voltage sensors of the NXP MC34VR500.
@@ -2312,6 +2317,7 @@ config SENSORS_TMP464
 config SENSORS_TMP513
        tristate "Texas Instruments TMP513 and compatibles"
        depends on I2C
+       select REGMAP_I2C
        help
          If you say yes here you get support for Texas Instruments TMP512,
          and TMP513 temperature and power supply sensor chips.
index 25281739aa3b1697301c97bd9f8fe446b7a4925d..6a834a37bc65d7ba49f6251c1c2e232d1ec9df85 100644 (file)
@@ -10,7 +10,7 @@
 #include <linux/init.h>
 #include <linux/regmap.h>
 #include <linux/spi/spi.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #include "adt7x10.h"
 
index ca466d12475a1e4a9122da2c295b779a09f047e3..5f2541c11fe9ba25cc97aa9046e65fb6ab0293b4 100644 (file)
@@ -1735,11 +1735,10 @@ static int adt7475_pwm_properties_parse_args(struct fwnode_handle *fwnode,
 static int adt7475_fan_pwm_config(struct i2c_client *client)
 {
        struct adt7475_data *data = i2c_get_clientdata(client);
-       struct fwnode_handle *child;
        struct adt7475_pwm_config cfg = {};
        int ret;
 
-       device_for_each_child_node(&client->dev, child) {
+       device_for_each_child_node_scoped(&client->dev, child) {
                if (!fwnode_property_present(child, "pwms"))
                        continue;
 
index 8e55cd2f46f53ed5f88258edc9239b842a8bbc4d..34cac27e4ddec3a0def97c922c2afae11b347c74 100644 (file)
@@ -22,7 +22,7 @@
 #include <linux/module.h>
 #include <linux/mutex.h>
 #include <linux/seq_file.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #define USB_VENDOR_ID_AQUACOMPUTER     0x0c70
 #define USB_PRODUCT_ID_AQUAERO         0xf001
index ee396f21fac5e907f166922f2d3103eab67f1cc5..9555366aeaf0d3c6a37a00764f7f8920a8044877 100644 (file)
@@ -34,7 +34,7 @@
 #include <linux/sort.h>
 #include <linux/units.h>
 
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 static char *mutex_path_override;
 
index f8b20346a9956fabcfbd531c6a616a6d53906e45..e5e93a20723c41ca563fdeef5ea853986627af2a 100644 (file)
@@ -11,7 +11,7 @@
 #include <linux/jiffies.h>
 #include <linux/module.h>
 #include <linux/spinlock.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #define DRIVER_NAME    "asus_rog_ryujin"
 
index f9b3a3030f133e7a7236d2f83a6057f44bc92199..f5bdf842040e6c4bde367e72339edd18a09e78f7 100644 (file)
@@ -38,7 +38,7 @@
 #include <linux/wmi.h>
 
 #include <linux/i8k.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #define I8K_SMM_FN_STATUS      0x0025
 #define I8K_SMM_POWER_STATUS   0x0069
index 8129d7b3ceaf9ae2e851f39af2db7aa6eaca9ce0..27487e215bddff5a4110464868346910a7768b55 100644 (file)
@@ -11,7 +11,7 @@
 #include <linux/jiffies.h>
 #include <linux/module.h>
 #include <linux/spinlock.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #define DRIVER_NAME    "gigabyte_waterforce"
 
index ca2dff158925153032b4e0f50086b0cb08f3c971..96397ae6ff18fc60ab2790ad526187f4b97eaa57 100644 (file)
@@ -358,7 +358,7 @@ static const struct m10bmc_sdata n6000bmc_temp_tbl[] = {
        { 0x4f0, 0x4f4, 0x4f8, 0x52c, 0x0, 500, "Board Top Near FPGA Temperature" },
        { 0x4fc, 0x500, 0x504, 0x52c, 0x0, 500, "Board Bottom Near CVL Temperature" },
        { 0x508, 0x50c, 0x510, 0x52c, 0x0, 500, "Board Top East Near VRs Temperature" },
-       { 0x514, 0x518, 0x51c, 0x52c, 0x0, 500, "Columbiaville Die Temperature" },
+       { 0x514, 0x518, 0x51c, 0x52c, 0x0, 500, "CVL Die Temperature" },
        { 0x520, 0x524, 0x528, 0x52c, 0x0, 500, "Board Rear Side Temperature" },
        { 0x530, 0x534, 0x538, 0x52c, 0x0, 500, "Board Front Side Temperature" },
        { 0x53c, 0x540, 0x544, 0x0, 0x0, 500, "QSFP1 Case Temperature" },
index a260cff750a5842a289f7aeb36c2c6cd7b86cab9..c459dce496a6edd75c63468553b31f250df732af 100644 (file)
@@ -417,7 +417,7 @@ static int jc42_detect(struct i2c_client *client, struct i2c_board_info *info)
                return -ENODEV;
 
        if ((devid & TSE2004_DEVID_MASK) == TSE2004_DEVID &&
-           (cap & 0x00e7) != 0x00e7)
+           (cap & 0x0062) != 0x0062)
                return -ENODEV;
 
        for (i = 0; i < ARRAY_SIZE(jc42_chips); i++) {
index 7caf387eb1449fd2148256d3711475a2b858c951..ed38645a1dc272083be9a063b495ec6d4bc5e436 100644 (file)
@@ -9,7 +9,7 @@
  * Copyright 2019-2021  Jonas Malaco <[email protected]>
  */
 
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include <linux/hid.h>
 #include <linux/hwmon.h>
 #include <linux/jiffies.h>
index 00f3ac90a290117365d3d81bced8416597ac97e0..d00409bcab93ad5d0e3d7889e47684420f739772 100644 (file)
@@ -17,7 +17,7 @@
 #include <linux/mutex.h>
 #include <linux/spinlock.h>
 #include <linux/wait.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #define USB_VENDOR_ID_NZXT             0x1e71
 #define USB_PRODUCT_ID_X53             0x2007
index df6fa72a6b5907cae9e6d26f3611128a513275b8..c2d1173f42fefb3ac4b276099debe6ad957478ab 100644 (file)
@@ -14,7 +14,7 @@
 #include <linux/wait.h>
 
 #include <asm/byteorder.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 /*
  * The device has only 3 fan channels/connectors. But all HID reports have
index dd690f700d4990e5f11785f8777b936061f9215a..9486db249c64fba1a35c2c92dee2c03473a8673e 100644 (file)
@@ -12,7 +12,7 @@
 #include <linux/mutex.h>
 #include <linux/property.h>
 #include <linux/sysfs.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #include "common.h"
 
index 31159606cec7b41244067383cf6fb33861a9cc9e..5817a099c622a89d1e98d26ae2092b70873a2bab 100644 (file)
@@ -8,7 +8,7 @@
 #include <linux/jiffies.h>
 #include <linux/module.h>
 #include <linux/sched.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #include "common.h"
 
index 9bcaa29a71913daddce3d983d5de291a32f5f144..541d808d62d0d51d889d82e132f2cd41890273a1 100644 (file)
@@ -16,7 +16,7 @@
 #include <linux/pm_runtime.h>
 #include <linux/power_supply.h>
 
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #include "i2c-ccgx-ucsi.h"
 
index cfee2d9c09de36829f9e1f2dcea9f0b0f4d28e51..0174ead99de6c1bd55b0cb0e3ccf74eec96bad9f 100644 (file)
@@ -2395,7 +2395,7 @@ static int __maybe_unused stm32f7_i2c_runtime_suspend(struct device *dev)
        struct stm32f7_i2c_dev *i2c_dev = dev_get_drvdata(dev);
 
        if (!stm32f7_i2c_is_slave_registered(i2c_dev))
-               clk_disable_unprepare(i2c_dev->clk);
+               clk_disable(i2c_dev->clk);
 
        return 0;
 }
@@ -2406,9 +2406,9 @@ static int __maybe_unused stm32f7_i2c_runtime_resume(struct device *dev)
        int ret;
 
        if (!stm32f7_i2c_is_slave_registered(i2c_dev)) {
-               ret = clk_prepare_enable(i2c_dev->clk);
+               ret = clk_enable(i2c_dev->clk);
                if (ret) {
-                       dev_err(dev, "failed to prepare_enable clock\n");
+                       dev_err(dev, "failed to enable clock\n");
                        return ret;
                }
        }
index 516c1a8e4d566fa93251834ef31f903b1842935a..8c3f7cf55d5fa432a4d4662b184a46cd59c3ebca 100644 (file)
@@ -447,6 +447,8 @@ config IIO_ST_ACCEL_SPI_3AXIS
 
 config IIO_KX022A
        tristate
+       select IIO_BUFFER
+       select IIO_TRIGGERED_BUFFER
 
 config IIO_KX022A_SPI
        tristate "Kionix KX022A tri-axis digital accelerometer SPI interface"
index 0c9225d18fb29bf176e3a100a1684850c9462a78..eabaefa92f19d1fce587204e0992a9d2a9e61dd8 100644 (file)
@@ -22,7 +22,7 @@
 #include <linux/regmap.h>
 #include <linux/units.h>
 
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #include "adxl355.h"
 
index 1c046e96aef9378df56cb5958c3ba410f8ed7985..e790a66d86c79f7de9650ea47f11c8990825fd42 100644 (file)
@@ -16,7 +16,7 @@
 #include <linux/mod_devicetable.h>
 #include <linux/regmap.h>
 #include <linux/regulator/consumer.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #include "adxl367.h"
 
index 98863e22bb6bf46e341bf583077d76234fecf233..f80527d899be4d99310d4d1a950749ce29c9b7ed 100644 (file)
@@ -13,7 +13,7 @@
 #include <linux/regmap.h>
 #include <linux/units.h>
 
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #include <linux/iio/buffer.h>
 #include <linux/iio/events.h>
index 89db242f06e0bed46a54f24390073addda63a7ce..e4fe36768216dab5af1721c4e31ce18828c231e5 100644 (file)
@@ -22,7 +22,7 @@
 #include <linux/regulator/consumer.h>
 #include <linux/slab.h>
 
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #include <linux/iio/iio.h>
 #include <linux/iio/buffer.h>
@@ -1218,7 +1218,8 @@ static int bma400_activity_event_en(struct bma400_data *data,
 static int bma400_tap_event_en(struct bma400_data *data,
                               enum iio_event_direction dir, int state)
 {
-       unsigned int mask, field_value;
+       unsigned int mask;
+       unsigned int field_value = 0;
        int ret;
 
        /*
index 469a1255d93cf02d9d084666465ffd556dd08299..fc1c1613d673b5b53a57e0b5065eb97a5edb61d8 100644 (file)
@@ -18,7 +18,7 @@
 #include <linux/pm_runtime.h>
 #include <linux/regmap.h>
 #include <linux/slab.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #include "bmi088-accel.h"
 
index 6644c1fec3e69116b96dc662a5f3e0ed08705547..4ec70ca6910d5eb7a05766c6460bf38254ac8baf 100644 (file)
@@ -5,7 +5,7 @@
  * Copyright (c) 2016, Jelle van der Waa <[email protected]>
  */
 
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include <linux/module.h>
 #include <linux/i2c.h>
 #include <linux/iio/iio.h>
index fca77d66062566cc84ff21e11d81ccfc71cf49de..ca0ce83e42b2cec52219b91f3c5d513c9f80d55e 100644 (file)
@@ -12,7 +12,7 @@
 #include <linux/module.h>
 #include <linux/spi/spi.h>
 
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #include <linux/iio/buffer.h>
 #include <linux/iio/iio.h>
index 97ece1a4b7e39958fabf0980f2fb8d9f58357e9c..6c4e74420fd25b9c9624b4a393bd436444d335d5 100644 (file)
@@ -52,6 +52,8 @@ config AD4695
        tristate "Analog Device AD4695 ADC Driver"
        depends on SPI
        select REGMAP_SPI
+       select IIO_BUFFER
+       select IIO_TRIGGERED_BUFFER
        help
          Say yes here to build support for Analog Devices AD4695 and similar
          analog to digital converters (ADC).
@@ -328,6 +330,8 @@ config AD7923
 config AD7944
        tristate "Analog Devices AD7944 and similar ADCs driver"
        depends on SPI
+       select IIO_BUFFER
+       select IIO_TRIGGERED_BUFFER
        help
          Say yes here to build support for Analog Devices
          AD7944, AD7985, AD7986 ADCs.
@@ -1481,6 +1485,8 @@ config TI_ADS8344
 config TI_ADS8688
        tristate "Texas Instruments ADS8688"
        depends on SPI
+       select IIO_BUFFER
+       select IIO_TRIGGERED_BUFFER
        help
          If you say yes here you get support for Texas Instruments ADS8684 and
          and ADS8688 ADC chips
@@ -1491,6 +1497,8 @@ config TI_ADS8688
 config TI_ADS124S08
        tristate "Texas Instruments ADS124S08"
        depends on SPI
+       select IIO_BUFFER
+       select IIO_TRIGGERED_BUFFER
        help
          If you say yes here you get support for Texas Instruments ADS124S08
          and ADS124S06 ADC chips
@@ -1525,6 +1533,9 @@ config TI_AM335X_ADC
 config TI_LMP92064
        tristate "Texas Instruments LMP92064 ADC driver"
        depends on SPI
+       select REGMAP_SPI
+       select IIO_BUFFER
+       select IIO_TRIGGERED_BUFFER
        help
          Say yes here to build support for the LMP92064 Precision Current and Voltage
          sensor.
index e134d6497827a07acb2dc329c1609bf9f3c5889b..de32cc9d18c5efa542d5cbf1b9635ae5918ac094 100644 (file)
@@ -23,7 +23,7 @@
 #include <linux/units.h>
 
 #include <asm/div64.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #include <linux/iio/buffer.h>
 #include <linux/iio/iio.h>
index a5d91933f505b38c5c708c2da0f4ef8cf4143e60..b79c48d46cccf88c63d9866999263a65ff545d4a 100644 (file)
@@ -637,7 +637,7 @@ static int ad7124_write_raw(struct iio_dev *indio_dev,
 
        switch (info) {
        case IIO_CHAN_INFO_SAMP_FREQ:
-               if (val2 != 0) {
+               if (val2 != 0 || val == 0) {
                        ret = -EINVAL;
                        break;
                }
index e8bddfb0d07dbcf3e2a43344a4e0516f4d617548..fb728570debe6432d5f991595cb35e9e7af8b740 100644 (file)
@@ -75,6 +75,7 @@
 #define T_CONVERT_NS 190               /* conversion time */
 #define T_CONVERT_0_NS 10              /* 1st conversion start time (oversampling) */
 #define T_CONVERT_X_NS 500             /* xth conversion start time (oversampling) */
+#define T_POWERUP_US 5000              /* Power up */
 
 struct ad7380_timing_specs {
        const unsigned int t_csh_ns;    /* CS minimum high time */
@@ -86,6 +87,9 @@ struct ad7380_chip_info {
        unsigned int num_channels;
        unsigned int num_simult_channels;
        bool has_mux;
+       const char * const *supplies;
+       unsigned int num_supplies;
+       bool external_ref_only;
        const char * const *vcm_supplies;
        unsigned int num_vcm_supplies;
        const unsigned long *available_scan_masks;
@@ -243,6 +247,10 @@ DEFINE_AD7380_8_CHANNEL(ad7386_4_channels, 16, 0, u);
 DEFINE_AD7380_8_CHANNEL(ad7387_4_channels, 14, 0, u);
 DEFINE_AD7380_8_CHANNEL(ad7388_4_channels, 12, 0, u);
 
+static const char * const ad7380_supplies[] = {
+       "vcc", "vlogic",
+};
+
 static const char * const ad7380_2_channel_vcm_supplies[] = {
        "aina", "ainb",
 };
@@ -338,6 +346,8 @@ static const struct ad7380_chip_info ad7380_chip_info = {
        .channels = ad7380_channels,
        .num_channels = ARRAY_SIZE(ad7380_channels),
        .num_simult_channels = 2,
+       .supplies = ad7380_supplies,
+       .num_supplies = ARRAY_SIZE(ad7380_supplies),
        .available_scan_masks = ad7380_2_channel_scan_masks,
        .timing_specs = &ad7380_timing,
 };
@@ -347,6 +357,8 @@ static const struct ad7380_chip_info ad7381_chip_info = {
        .channels = ad7381_channels,
        .num_channels = ARRAY_SIZE(ad7381_channels),
        .num_simult_channels = 2,
+       .supplies = ad7380_supplies,
+       .num_supplies = ARRAY_SIZE(ad7380_supplies),
        .available_scan_masks = ad7380_2_channel_scan_masks,
        .timing_specs = &ad7380_timing,
 };
@@ -356,6 +368,8 @@ static const struct ad7380_chip_info ad7383_chip_info = {
        .channels = ad7383_channels,
        .num_channels = ARRAY_SIZE(ad7383_channels),
        .num_simult_channels = 2,
+       .supplies = ad7380_supplies,
+       .num_supplies = ARRAY_SIZE(ad7380_supplies),
        .vcm_supplies = ad7380_2_channel_vcm_supplies,
        .num_vcm_supplies = ARRAY_SIZE(ad7380_2_channel_vcm_supplies),
        .available_scan_masks = ad7380_2_channel_scan_masks,
@@ -367,6 +381,8 @@ static const struct ad7380_chip_info ad7384_chip_info = {
        .channels = ad7384_channels,
        .num_channels = ARRAY_SIZE(ad7384_channels),
        .num_simult_channels = 2,
+       .supplies = ad7380_supplies,
+       .num_supplies = ARRAY_SIZE(ad7380_supplies),
        .vcm_supplies = ad7380_2_channel_vcm_supplies,
        .num_vcm_supplies = ARRAY_SIZE(ad7380_2_channel_vcm_supplies),
        .available_scan_masks = ad7380_2_channel_scan_masks,
@@ -378,6 +394,8 @@ static const struct ad7380_chip_info ad7386_chip_info = {
        .channels = ad7386_channels,
        .num_channels = ARRAY_SIZE(ad7386_channels),
        .num_simult_channels = 2,
+       .supplies = ad7380_supplies,
+       .num_supplies = ARRAY_SIZE(ad7380_supplies),
        .has_mux = true,
        .available_scan_masks = ad7380_2x2_channel_scan_masks,
        .timing_specs = &ad7380_timing,
@@ -388,6 +406,8 @@ static const struct ad7380_chip_info ad7387_chip_info = {
        .channels = ad7387_channels,
        .num_channels = ARRAY_SIZE(ad7387_channels),
        .num_simult_channels = 2,
+       .supplies = ad7380_supplies,
+       .num_supplies = ARRAY_SIZE(ad7380_supplies),
        .has_mux = true,
        .available_scan_masks = ad7380_2x2_channel_scan_masks,
        .timing_specs = &ad7380_timing,
@@ -398,6 +418,8 @@ static const struct ad7380_chip_info ad7388_chip_info = {
        .channels = ad7388_channels,
        .num_channels = ARRAY_SIZE(ad7388_channels),
        .num_simult_channels = 2,
+       .supplies = ad7380_supplies,
+       .num_supplies = ARRAY_SIZE(ad7380_supplies),
        .has_mux = true,
        .available_scan_masks = ad7380_2x2_channel_scan_masks,
        .timing_specs = &ad7380_timing,
@@ -408,6 +430,9 @@ static const struct ad7380_chip_info ad7380_4_chip_info = {
        .channels = ad7380_4_channels,
        .num_channels = ARRAY_SIZE(ad7380_4_channels),
        .num_simult_channels = 4,
+       .supplies = ad7380_supplies,
+       .num_supplies = ARRAY_SIZE(ad7380_supplies),
+       .external_ref_only = true,
        .available_scan_masks = ad7380_4_channel_scan_masks,
        .timing_specs = &ad7380_4_timing,
 };
@@ -417,6 +442,8 @@ static const struct ad7380_chip_info ad7381_4_chip_info = {
        .channels = ad7381_4_channels,
        .num_channels = ARRAY_SIZE(ad7381_4_channels),
        .num_simult_channels = 4,
+       .supplies = ad7380_supplies,
+       .num_supplies = ARRAY_SIZE(ad7380_supplies),
        .available_scan_masks = ad7380_4_channel_scan_masks,
        .timing_specs = &ad7380_4_timing,
 };
@@ -426,6 +453,8 @@ static const struct ad7380_chip_info ad7383_4_chip_info = {
        .channels = ad7383_4_channels,
        .num_channels = ARRAY_SIZE(ad7383_4_channels),
        .num_simult_channels = 4,
+       .supplies = ad7380_supplies,
+       .num_supplies = ARRAY_SIZE(ad7380_supplies),
        .vcm_supplies = ad7380_4_channel_vcm_supplies,
        .num_vcm_supplies = ARRAY_SIZE(ad7380_4_channel_vcm_supplies),
        .available_scan_masks = ad7380_4_channel_scan_masks,
@@ -437,6 +466,8 @@ static const struct ad7380_chip_info ad7384_4_chip_info = {
        .channels = ad7384_4_channels,
        .num_channels = ARRAY_SIZE(ad7384_4_channels),
        .num_simult_channels = 4,
+       .supplies = ad7380_supplies,
+       .num_supplies = ARRAY_SIZE(ad7380_supplies),
        .vcm_supplies = ad7380_4_channel_vcm_supplies,
        .num_vcm_supplies = ARRAY_SIZE(ad7380_4_channel_vcm_supplies),
        .available_scan_masks = ad7380_4_channel_scan_masks,
@@ -448,6 +479,8 @@ static const struct ad7380_chip_info ad7386_4_chip_info = {
        .channels = ad7386_4_channels,
        .num_channels = ARRAY_SIZE(ad7386_4_channels),
        .num_simult_channels = 4,
+       .supplies = ad7380_supplies,
+       .num_supplies = ARRAY_SIZE(ad7380_supplies),
        .has_mux = true,
        .available_scan_masks = ad7380_2x4_channel_scan_masks,
        .timing_specs = &ad7380_4_timing,
@@ -458,6 +491,8 @@ static const struct ad7380_chip_info ad7387_4_chip_info = {
        .channels = ad7387_4_channels,
        .num_channels = ARRAY_SIZE(ad7387_4_channels),
        .num_simult_channels = 4,
+       .supplies = ad7380_supplies,
+       .num_supplies = ARRAY_SIZE(ad7380_supplies),
        .has_mux = true,
        .available_scan_masks = ad7380_2x4_channel_scan_masks,
        .timing_specs = &ad7380_4_timing,
@@ -468,6 +503,8 @@ static const struct ad7380_chip_info ad7388_4_chip_info = {
        .channels = ad7388_4_channels,
        .num_channels = ARRAY_SIZE(ad7388_4_channels),
        .num_simult_channels = 4,
+       .supplies = ad7380_supplies,
+       .num_supplies = ARRAY_SIZE(ad7380_supplies),
        .has_mux = true,
        .available_scan_masks = ad7380_2x4_channel_scan_masks,
        .timing_specs = &ad7380_4_timing,
@@ -956,7 +993,7 @@ static const struct iio_info ad7380_info = {
        .debugfs_reg_access = &ad7380_debugfs_reg_access,
 };
 
-static int ad7380_init(struct ad7380_state *st, struct regulator *vref)
+static int ad7380_init(struct ad7380_state *st, bool external_ref_en)
 {
        int ret;
 
@@ -968,13 +1005,13 @@ static int ad7380_init(struct ad7380_state *st, struct regulator *vref)
        if (ret < 0)
                return ret;
 
-       /* select internal or external reference voltage */
-       ret = regmap_update_bits(st->regmap, AD7380_REG_ADDR_CONFIG1,
-                                AD7380_CONFIG1_REFSEL,
-                                FIELD_PREP(AD7380_CONFIG1_REFSEL,
-                                           vref ? 1 : 0));
-       if (ret < 0)
-               return ret;
+       if (external_ref_en) {
+               /* select external reference voltage */
+               ret = regmap_set_bits(st->regmap, AD7380_REG_ADDR_CONFIG1,
+                                     AD7380_CONFIG1_REFSEL);
+               if (ret < 0)
+                       return ret;
+       }
 
        /* This is the default value after reset. */
        st->oversampling_ratio = 1;
@@ -987,16 +1024,11 @@ static int ad7380_init(struct ad7380_state *st, struct regulator *vref)
                                  FIELD_PREP(AD7380_CONFIG2_SDO, 1));
 }
 
-static void ad7380_regulator_disable(void *p)
-{
-       regulator_disable(p);
-}
-
 static int ad7380_probe(struct spi_device *spi)
 {
        struct iio_dev *indio_dev;
        struct ad7380_state *st;
-       struct regulator *vref;
+       bool external_ref_en;
        int ret, i;
 
        indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st));
@@ -1009,36 +1041,38 @@ static int ad7380_probe(struct spi_device *spi)
        if (!st->chip_info)
                return dev_err_probe(&spi->dev, -EINVAL, "missing match data\n");
 
-       vref = devm_regulator_get_optional(&spi->dev, "refio");
-       if (IS_ERR(vref)) {
-               if (PTR_ERR(vref) != -ENODEV)
-                       return dev_err_probe(&spi->dev, PTR_ERR(vref),
-                                            "Failed to get refio regulator\n");
-
-               vref = NULL;
-       }
+       ret = devm_regulator_bulk_get_enable(&spi->dev, st->chip_info->num_supplies,
+                                            st->chip_info->supplies);
 
-       /*
-        * If there is no REFIO supply, then it means that we are using
-        * the internal 2.5V reference, otherwise REFIO is reference voltage.
-        */
-       if (vref) {
-               ret = regulator_enable(vref);
-               if (ret)
-                       return ret;
-
-               ret = devm_add_action_or_reset(&spi->dev,
-                                              ad7380_regulator_disable, vref);
-               if (ret)
-                       return ret;
+       if (ret)
+               return dev_err_probe(&spi->dev, ret,
+                                    "Failed to enable power supplies\n");
+       fsleep(T_POWERUP_US);
 
-               ret = regulator_get_voltage(vref);
+       if (st->chip_info->external_ref_only) {
+               ret = devm_regulator_get_enable_read_voltage(&spi->dev,
+                                                            "refin");
                if (ret < 0)
-                       return ret;
+                       return dev_err_probe(&spi->dev, ret,
+                                            "Failed to get refin regulator\n");
 
                st->vref_mv = ret / 1000;
+
+               /* these chips don't have a register bit for this */
+               external_ref_en = false;
        } else {
-               st->vref_mv = AD7380_INTERNAL_REF_MV;
+               /*
+                * If there is no REFIO supply, then it means that we are using
+                * the internal reference, otherwise REFIO is reference voltage.
+                */
+               ret = devm_regulator_get_enable_read_voltage(&spi->dev,
+                                                            "refio");
+               if (ret < 0 && ret != -ENODEV)
+                       return dev_err_probe(&spi->dev, ret,
+                                            "Failed to get refio regulator\n");
+
+               external_ref_en = ret != -ENODEV;
+               st->vref_mv = external_ref_en ? ret / 1000 : AD7380_INTERNAL_REF_MV;
        }
 
        if (st->chip_info->num_vcm_supplies > ARRAY_SIZE(st->vcm_mv))
@@ -1050,27 +1084,13 @@ static int ad7380_probe(struct spi_device *spi)
         * input pin.
         */
        for (i = 0; i < st->chip_info->num_vcm_supplies; i++) {
-               struct regulator *vcm;
-
-               vcm = devm_regulator_get(&spi->dev,
-                                        st->chip_info->vcm_supplies[i]);
-               if (IS_ERR(vcm))
-                       return dev_err_probe(&spi->dev, PTR_ERR(vcm),
-                                            "Failed to get %s regulator\n",
-                                            st->chip_info->vcm_supplies[i]);
+               const char *vcm = st->chip_info->vcm_supplies[i];
 
-               ret = regulator_enable(vcm);
-               if (ret)
-                       return ret;
-
-               ret = devm_add_action_or_reset(&spi->dev,
-                                              ad7380_regulator_disable, vcm);
-               if (ret)
-                       return ret;
-
-               ret = regulator_get_voltage(vcm);
+               ret = devm_regulator_get_enable_read_voltage(&spi->dev, vcm);
                if (ret < 0)
-                       return ret;
+                       return dev_err_probe(&spi->dev, ret,
+                                            "Failed to get %s regulator\n",
+                                            vcm);
 
                st->vcm_mv[i] = ret / 1000;
        }
@@ -1135,7 +1155,7 @@ static int ad7380_probe(struct spi_device *spi)
        if (ret)
                return ret;
 
-       ret = ad7380_init(st, vref);
+       ret = ad7380_init(st, external_ref_en);
        if (ret)
                return ret;
 
index e2bed2d648f22bcb6d1527d2867dc960e6807c9b..ea4aabd3960a086db8562e99a1f9a8e71750e8d2 100644 (file)
@@ -23,7 +23,7 @@
 #include <linux/iio/triggered_buffer.h>
 #include <linux/iio/adc/ad_sigma_delta.h>
 
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 
 #define AD_SD_COMM_CHAN_MASK   0x3
index d43c8d124a0c7d01b0de89251315b6f35a5e8352..6c1a5d1b0a83d4f52b0387b3f3cd156e92b07b56 100644 (file)
@@ -5,7 +5,7 @@
  *     Quentin Schulz <[email protected]>
  */
 
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include <linux/bitfield.h>
 #include <linux/completion.h>
 #include <linux/interrupt.h>
index 0590a126f3218a9302b2bdfb8f965c0310562595..30733252aa56f83a8c4e47459853e81d22270b18 100644 (file)
@@ -25,7 +25,7 @@
 #include <linux/iio/iio.h>
 #include <linux/iio/machine.h>
 
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #define BCOVE_GPADCREQ                 0xDC
 #define BCOVE_GPADCREQ_BUSY            BIT(0)
index f010b2fd12029a71f62ce577e9e834433bbd99d1..eb9d521e86e54def0493ea0e81f63b37900c56a5 100644 (file)
@@ -14,7 +14,7 @@
 #include <linux/mod_devicetable.h>
 #include <linux/property.h>
 
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #include "ltc2497.h"
 
index 2f07437caec34d076e8666359f3ce08d05119c86..520e37f75aac4cd4e75c0d1001ad0f2cfb866b1b 100644 (file)
@@ -12,7 +12,7 @@
 #include <linux/module.h>
 #include <linux/regulator/consumer.h>
 #include <linux/spi/spi.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #include <linux/iio/iio.h>
 #include <linux/iio/driver.h>
index 45368850b2201fdbd892f5ddca9b4c6375bb2092..f0dc4b460903163b2037cc3c49f740d8463e1cea 100644 (file)
@@ -15,7 +15,7 @@
 #include <linux/regulator/consumer.h>
 #include <linux/spi/spi.h>
 
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #include <linux/iio/buffer.h>
 #include <linux/iio/sysfs.h>
index 0778a8fb68665c3e47d8a41fccc057e84c35599a..50834fdcf7388f91ee0058d6c645cf20dac84225 100644 (file)
@@ -19,7 +19,7 @@
 #include <linux/mod_devicetable.h>
 #include <linux/delay.h>
 #include <linux/sysfs.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #include <linux/iio/iio.h>
 #include <linux/iio/sysfs.h>
index d0e77971c5d357aa18bfba797e1bf4172267700a..b097f04172c80b1d5d4e1dcbd785df45b36db2e7 100644 (file)
@@ -23,7 +23,7 @@
 #include <linux/iio/trigger_consumer.h>
 #include <linux/iio/trigger.h>
 
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #define MCP3911_REG_CHANNEL0           0x00
 #define MCP3911_REG_CHANNEL1           0x03
index e2ec805e834fe96fff6156bdb2e38a1a331926f2..83161e6d29b901eda4cfc21dfd3d10ec21b1d2ce 100644 (file)
@@ -16,7 +16,7 @@
 #include <linux/iio/trigger_consumer.h>
 #include <linux/iio/triggered_buffer.h>
 
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #define MT6360_REG_PMUCHGCTRL3 0x313
 #define MT6360_REG_PMUADCCFG   0x356
index 4c2a1c07bc399028f0334885fc9cd4552d5892b1..36e813d9c73f1c25afe114466ec716a440cf7069 100644 (file)
@@ -5,7 +5,7 @@
  * Copyright (C) 2024 Matteo Martelli <[email protected]>
  */
 
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include <linux/bitfield.h>
 #include <linux/i2c.h>
 #include <linux/iio/events.h>
index 8210728034d0a626396742e99d23f4e752fe3498..7ef249d8328661072c17542a5c7142d96c0d2834 100644 (file)
@@ -19,7 +19,7 @@
 #include <linux/i2c.h>
 #include <linux/iio/iio.h>
 #include <linux/iio/sysfs.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 /*
  * maximum accumulation time should be (17 * 60 * 1000) around 17 minutes@1024 sps
index 6aa70b4629a7cc52ada2866b89d438121afa698c..63ebaf13ef19e59816a9f55df450b38fa8f224b2 100644 (file)
@@ -20,7 +20,7 @@
 #include <linux/types.h>
 #include <linux/units.h>
 
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #include <linux/iio/iio.h>
 #include <linux/iio/types.h>
index 14941f384dadddeb07a5f7cee51f5ae5c6353466..425b48d8986f5249b721d1f4322a0a8d4400386c 100644 (file)
@@ -21,7 +21,7 @@
 #include <linux/iio/triggered_buffer.h>
 #include <linux/iio/sysfs.h>
 
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 /* Commands */
 #define ADS124S08_CMD_NOP      0x00
index 13cb32125eef96b9b1b8ec979b1bb12b3397cc5e..0f9f75baaebbf7b6bb099a5c08496bddc06a01bc 100644 (file)
@@ -23,7 +23,7 @@
 #include <linux/iio/buffer.h>
 #include <linux/iio/kfifo_buf.h>
 
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 /* Commands */
 #define ADS1298_CMD_WAKEUP     0x02
index 91a427eb0882e0de78343c37da14695c8eb44867..31f1f229d97a78ad9b3a7457ccfe42f34cdff94a 100644 (file)
@@ -23,7 +23,7 @@
 #include <linux/regulator/consumer.h>
 #include <linux/spi/spi.h>
 
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 /* Commands */
 #define ADS131E08_CMD_RESET            0x06
index 311d97001249b3b678660d9bb980aa702a51109c..b56f2503f14ceb603192ef5eb34077482e84f858 100644 (file)
@@ -13,7 +13,7 @@
 #include <linux/spi/spi.h>
 #include <linux/units.h>
 
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #include <linux/iio/buffer.h>
 #include <linux/iio/trigger_consumer.h>
index 12dc43d487b4baea331edf862f20543984dbb4cc..3ee0dd5537c168724d6fc143411abacc8d830f16 100644 (file)
@@ -16,7 +16,7 @@
 #include <linux/spi/spi.h>
 #include <linux/units.h>
 
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #include <linux/iio/buffer.h>
 #include <linux/iio/iio.h>
index 2410d72da49baa2d8f0c2e10350c3402a3b67462..69c586525d2158e918d2feb6308eabd57c6bf689 100644 (file)
@@ -4,7 +4,7 @@
  * Author: Cosmin Tanislav <[email protected]>
  */
 
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include <linux/bitfield.h>
 #include <linux/crc8.h>
 #include <linux/device.h>
index b54fe01734b0d7e91198bcc22e5cf764dfe537a4..55eb16b32f6c9a71fb95be8c00379efa8d28a5d8 100644 (file)
@@ -27,6 +27,7 @@ config AD8366
 config ADA4250
        tristate "Analog Devices ADA4250 Instrumentation Amplifier"
        depends on SPI
+       select REGMAP_SPI
        help
          Say yes here to build support for Analog Devices ADA4250
          SPI Amplifier's support. The driver provides direct access via
index 4b32d350dc5dc08f512f038478fc987c2d87b338..566f0e1c98a5728f083c42380ee160045f7e2dba 100644 (file)
@@ -14,7 +14,7 @@
 #include <linux/regulator/consumer.h>
 #include <linux/spi/spi.h>
 
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 /* ADA4250 Register Map */
 #define ADA4250_REG_GAIN_MUX        0x00
index d11bc3496dda29bbe46974f3207be2e6ade6717d..ba18dbbe0940ab1ea501e76b57409d6ccb30550d 100644 (file)
@@ -16,7 +16,7 @@
 #include <linux/stat.h>
 #include <linux/sysfs.h>
 
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #include <linux/iio/iio.h>
 #include <linux/iio/sysfs.h>
index 678a6adb9a7583ceeed5612aa69d6afb3292f746..6c87223f58d9031c8c6f660d6f6a72c93534b4b5 100644 (file)
@@ -80,6 +80,8 @@ config ENS160
        tristate "ScioSense ENS160 sensor driver"
        depends on (I2C || SPI)
        select REGMAP
+       select IIO_BUFFER
+       select IIO_TRIGGERED_BUFFER
        select ENS160_I2C if I2C
        select ENS160_SPI if SPI
        help
index 5d2e750ca2b9c739d760e25688933ecf54a98ded..0b96534c6867a67096329e63ea13a6822646aaf0 100644 (file)
@@ -19,7 +19,7 @@
 #include <linux/iio/iio.h>
 #include <linux/iio/sysfs.h>
 
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #include "bme680.h"
 
index 43025866d5b791c1418898272d2cb2fa53bd125a..d0bd94912e0a3492641acd955adbc2184f4a11b3 100644 (file)
@@ -5,7 +5,7 @@
  * Copyright (c) Tomasz Duszynski <[email protected]>
  */
 
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include <linux/completion.h>
 #include <linux/device.h>
 #include <linux/errno.h>
index bd3b01ded246e0b9f5a0cafcbe8c030b38e58b19..b31dfaf52df9c5cb5476efd19c0563d9daa39422 100644 (file)
@@ -13,7 +13,7 @@
 #include <linux/mod_devicetable.h>
 #include <linux/module.h>
 #include <linux/types.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #include "scd30.h"
 
index 2adb76dbb0209edc24c5f20c3c2c01bf609afe41..55044f07d5a37137cbe4c011bcebc1d35e4428bf 100644 (file)
@@ -15,7 +15,7 @@
 #include <linux/serdev.h>
 #include <linux/string.h>
 #include <linux/types.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #include "scd30.h"
 
index ca6b20270711a6875d1a663f30c6cb2f8769ff08..52cad54e85724fb9c64d05eb1c1856d3f50c0732 100644 (file)
@@ -11,7 +11,7 @@
  * https://www.sensirion.com/file/datasheet_scd4x
  */
 
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include <linux/crc8.h>
 #include <linux/delay.h>
 #include <linux/device.h>
index 5c31299813ecf92a8b9f498fa44b9366aa4d195f..1b21b6bcd0e7a4e3c8741a3e9d7f93073274a66c 100644 (file)
@@ -6,7 +6,7 @@
  *
  * I2C slave address: 0x69
  */
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include <linux/crc8.h>
 #include <linux/delay.h>
 #include <linux/device.h>
index ad8910e6ad59df1e7c306efc72586fd285670363..abb09fefc792c54e8e0cd53ab34c05aaf253bbd8 100644 (file)
@@ -32,7 +32,7 @@ static ssize_t _hid_sensor_set_report_latency(struct device *dev,
        latency = integer * 1000 + fract / 1000;
        ret = hid_sensor_set_report_latency(attrb, latency);
        if (ret < 0)
-               return len;
+               return ret;
 
        attrb->latency_ms = hid_sensor_get_report_latency(attrb);
 
index c69399ac66572f4269bdf72ea4d0acbd5c304af8..1b4287991d00ae71785b472936af1d574f343242 100644 (file)
@@ -16,7 +16,7 @@
 #include <linux/property.h>
 #include <linux/regulator/consumer.h>
 #include <linux/regmap.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include <linux/iio/common/st_sensors.h>
 
 #include "st_sensors_core.h"
index 1cfd7e2a622f67178cc02cff5c0089f3de67e900..9f5d5ebb8653743292632a449064f884df80f5e3 100644 (file)
@@ -9,6 +9,8 @@ menu "Digital to analog converters"
 config AD3552R
        tristate "Analog Devices AD3552R DAC driver"
        depends on SPI_MASTER
+       select IIO_BUFFER
+       select IIO_TRIGGERED_BUFFER
        help
          Say yes here to build support for Analog Devices AD3552R
          Digital to Analog Converter.
@@ -252,6 +254,8 @@ config AD5764
 config AD5766
        tristate "Analog Devices AD5766/AD5767 DAC driver"
        depends on SPI_MASTER
+       select IIO_BUFFER
+       select IIO_TRIGGERED_BUFFER
        help
          Say yes here to build support for Analog Devices AD5766, AD5767
          Digital to Analog Converter.
@@ -262,6 +266,7 @@ config AD5766
 config AD5770R
        tristate "Analog Devices AD5770R IDAC driver"
        depends on SPI_MASTER
+       select REGMAP_SPI
        help
          Say yes here to build support for Analog Devices AD5770R Digital to
          Analog Converter.
@@ -353,6 +358,7 @@ config LPC18XX_DAC
 config LTC1660
        tristate "Linear Technology LTC1660/LTC1665 DAC SPI driver"
        depends on SPI
+       select REGMAP_SPI
        help
          Say yes here to build support for Linear Technology
          LTC1660 and LTC1665 Digital to Analog Converters.
@@ -374,7 +380,7 @@ config LTC2632
 config LTC2664
        tristate "Analog Devices LTC2664 and LTC2672 DAC SPI driver"
        depends on SPI
-       select REGMAP
+       select REGMAP_SPI
        help
          Say yes here to build support for Analog Devices
          LTC2664 and LTC2672 converters (DAC).
@@ -483,6 +489,7 @@ config STM32_DAC
 
 config STM32_DAC_CORE
        tristate
+       select REGMAP_MMIO
 
 config TI_DAC082S085
        tristate "Texas Instruments 8/10/12-bit 2/4-channel DAC driver"
index bd37d304ca70ac82c323d56ed7edbb7702d1179f..7d61b2fe66243641119fb43e1b89f5e635dc7c0e 100644 (file)
@@ -5,7 +5,7 @@
  *
  * Copyright 2021 Analog Devices Inc.
  */
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include <linux/device.h>
 #include <linux/iio/triggered_buffer.h>
 #include <linux/iio/trigger_consumer.h>
index 7712dc6be608f3f07bfc47487e952d2a7ef585fc..905988724f2731f164f99be11d6a7a70d13d61a7 100644 (file)
@@ -18,7 +18,7 @@
 #include <linux/slab.h>
 #include <linux/sysfs.h>
 #include <linux/regulator/consumer.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #include <linux/iio/iio.h>
 #include <linux/iio/sysfs.h>
index 8103d2cd13f66f3415d666436458fd1d1d1a0079..708629efc15734deb51d9aa330e845b2e0d3bfa4 100644 (file)
@@ -22,7 +22,7 @@
 #include <linux/iio/iio.h>
 #include <linux/iio/sysfs.h>
 
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #define MODE_PWRDWN_1k         0x1
 #define MODE_PWRDWN_100k       0x2
index 953fcfa2110bb0f20c93083e46f43fe929fb0744..1c996016756a8bdfde2375a4b044997433b514fb 100644 (file)
@@ -15,7 +15,7 @@
 #include <linux/slab.h>
 #include <linux/sysfs.h>
 #include <linux/regulator/consumer.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #include <linux/iio/iio.h>
 #include <linux/iio/sysfs.h>
index fae5e5a0e72fca1a6cc5de37b4581d36c5c7e0d3..62e1fbb9e9101eaa46fd7a24ae10e6617120fbfe 100644 (file)
@@ -13,7 +13,7 @@
 #include <linux/module.h>
 #include <linux/mod_devicetable.h>
 
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #define AD5593R_MODE_CONF              (0 << 4)
 #define AD5593R_MODE_DAC_WRITE         (1 << 4)
index 7e6f824de299380127bc9c72860028afaf7442af..9304d0499bae821e5b123e4663511098a0632af2 100644 (file)
@@ -18,7 +18,7 @@
 #include <linux/iio/iio.h>
 #include <linux/iio/sysfs.h>
 
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #include "ad5624r.h"
 
index 899894523752f032f655e8c7eb9720ffbbf91e46..f658ac8086aaa488540855c849daf46abc21275f 100644 (file)
@@ -14,7 +14,7 @@
 #include <linux/iio/trigger_consumer.h>
 #include <linux/module.h>
 #include <linux/spi/spi.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #define AD5766_UPPER_WORD_SPI_MASK             GENMASK(31, 16)
 #define AD5766_LOWER_WORD_SPI_MASK             GENMASK(15, 0)
index 06f05750d9216cf8c85ab5cf9f0fa59deb4d77d3..1d403267048240be1bf3d8b2a59685409b9087fd 100644 (file)
@@ -16,7 +16,7 @@
 #include <linux/regulator/consumer.h>
 #include <linux/spi/spi.h>
 
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #define AD7293_R1B                             BIT(16)
 #define AD7293_R2B                             BIT(17)
index 3a3c4f4874e4013dd11b746c290ade9123ea74e6..a4fb2509c950a15d5bfbb410d7f0656b3aafedfb 100644 (file)
@@ -13,7 +13,7 @@
 #include <linux/property.h>
 #include <linux/regulator/consumer.h>
 
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #define LTC2632_CMD_WRITE_INPUT_N               0x0
 #define LTC2632_CMD_UPDATE_DAC_N                0x1
index 5be5345ac5c85448050ba219c13c3b258eb03b77..67f14046cf77356b4513c6ef360f847298deb4cf 100644 (file)
@@ -516,7 +516,7 @@ static int ltc2664_channel_config(struct ltc2664_state *st)
        const struct ltc2664_chip_info *chip_info = st->chip_info;
        struct device *dev = &st->spi->dev;
        u32 reg, tmp[2], mspan;
-       int ret, span = 0;
+       int ret;
 
        mspan = LTC2664_MSPAN_SOFTSPAN;
        ret = device_property_read_u32(dev, "adi,manual-span-operation-config",
@@ -579,20 +579,21 @@ static int ltc2664_channel_config(struct ltc2664_state *st)
                ret = fwnode_property_read_u32_array(child, "output-range-microvolt",
                                                     tmp, ARRAY_SIZE(tmp));
                if (!ret && mspan == LTC2664_MSPAN_SOFTSPAN) {
-                       chan->span = ltc2664_set_span(st, tmp[0] / 1000,
-                                                     tmp[1] / 1000, reg);
-                       if (span < 0)
-                               return dev_err_probe(dev, span,
+                       ret = ltc2664_set_span(st, tmp[0] / 1000, tmp[1] / 1000, reg);
+                       if (ret < 0)
+                               return dev_err_probe(dev, ret,
                                                     "Failed to set span\n");
+                       chan->span = ret;
                }
 
                ret = fwnode_property_read_u32_array(child, "output-range-microamp",
                                                     tmp, ARRAY_SIZE(tmp));
                if (!ret) {
-                       chan->span = ltc2664_set_span(st, 0, tmp[1] / 1000, reg);
-                       if (span < 0)
-                               return dev_err_probe(dev, span,
+                       ret = ltc2664_set_span(st, 0, tmp[1] / 1000, reg);
+                       if (ret < 0)
+                               return dev_err_probe(dev, ret,
                                                     "Failed to set span\n");
+                       chan->span = ret;
                }
        }
 
index 782e8f6b77829bf8041bed92f32c1aafc0c47e0a..c1a59bbbba3cc1634f5c70be07dea9b6a1a282ed 100644 (file)
@@ -23,7 +23,7 @@
 #include <linux/iio/iio.h>
 #include <linux/iio/types.h>
 
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #define MCP4821_ACTIVE_MODE BIT(12)
 #define MCP4802_SECOND_CHAN BIT(15)
index c455be7d4a1c888ff1ec215c1e361830addc0639..583cbdf4e8cdabd20d6462cb05b76e6dee749705 100644 (file)
@@ -53,6 +53,7 @@ config ADF4371
 config ADF4377
        tristate "Analog Devices ADF4377 Microwave Wideband Synthesizer"
        depends on SPI && COMMON_CLK
+       select REGMAP_SPI
        help
          Say yes here to build support for Analog Devices ADF4377 Microwave
          Wideband Synthesizer.
@@ -91,25 +92,26 @@ config ADMV1014
          module will be called admv1014.
 
 config ADMV4420
-       tristate "Analog Devices ADMV4420 K Band Downconverter"
-       depends on SPI
-       help
-         Say yes here to build support for Analog Devices K Band
-         Downconverter with integrated Fractional-N PLL and VCO.
+       tristate "Analog Devices ADMV4420 K Band Downconverter"
+       depends on SPI
+       select REGMAP_SPI
+       help
+         Say yes here to build support for Analog Devices K Band
+         Downconverter with integrated Fractional-N PLL and VCO.
 
-         To compile this driver as a module, choose M here: the
-         module will be called admv4420.
+         To compile this driver as a module, choose M here: the
+         module will be called admv4420.
 
 config ADRF6780
-        tristate "Analog Devices ADRF6780 Microwave Upconverter"
-        depends on SPI
-        depends on COMMON_CLK
-        help
-          Say yes here to build support for Analog Devices ADRF6780
-          5.9 GHz to 23.6 GHz, Wideband, Microwave Upconverter.
-
-          To compile this driver as a module, choose M here: the
-          module will be called adrf6780.
+       tristate "Analog Devices ADRF6780 Microwave Upconverter"
+       depends on SPI
+       depends on COMMON_CLK
+       help
+         Say yes here to build support for Analog Devices ADRF6780
+         5.9 GHz to 23.6 GHz, Wideband, Microwave Upconverter.
+
+         To compile this driver as a module, choose M here: the
+         module will be called adrf6780.
 
 endmenu
 endmenu
index 25fbc2cef1f715695f550050d6f6be49530a21b8..45ceeb828d6b683d8e28cf6df74be25854e2cbec 100644 (file)
@@ -20,7 +20,7 @@
 #include <linux/regmap.h>
 #include <linux/units.h>
 
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 /* ADF4377 REG0000 Map */
 #define ADF4377_0000_SOFT_RESET_R_MSK          BIT(7)
index c0cd5d9844fe9d1c28f217e8f94348cc8425f03b..8ef583680ad0b18959225a8129ca1fcd7f4b0db0 100644 (file)
@@ -18,7 +18,7 @@
 #include <linux/spi/spi.h>
 #include <linux/units.h>
 
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 /* ADMV1013 Register Map */
 #define ADMV1013_REG_SPI_CONTROL               0x00
index b46b73b89eb715de9472e15a87af7cdd5607294c..986b87a72577e596645448a4969b4e1fa5842a28 100644 (file)
@@ -19,7 +19,7 @@
 #include <linux/spi/spi.h>
 #include <linux/units.h>
 
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 /* ADMV1014 Register Map */
 #define ADMV1014_REG_SPI_CONTROL               0x00
index 863ba8e98c95e5fa7e992c706b7c075daae29dbc..3ae462b4f5c9f924dcd6a385a2502c6816852ec5 100644 (file)
@@ -13,7 +13,7 @@
 #include <linux/spi/spi.h>
 #include <linux/units.h>
 
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 /* ADMV4420 Register Map */
 #define ADMV4420_SPI_CONFIG_1                  0x00
index 3f46032c9275277eaf36e8bc30aee78f9f26e7c3..57ee908fc747e153347ced3d87af515716d90efc 100644 (file)
@@ -16,7 +16,7 @@
 #include <linux/mod_devicetable.h>
 #include <linux/spi/spi.h>
 
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 /* ADRF6780 Register Map */
 #define ADRF6780_REG_CONTROL                   0x00
index 33cde9e6fca59cd87037aeac3d259c29173fc87f..2535e3c9403731b49953a4278370d8883ea26e20 100644 (file)
@@ -12,7 +12,7 @@
 
 #include <linux/iio/iio.h>
 
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #define ADIS16130_CON         0x0
 #define ADIS16130_CON_RD      (1 << 6)
index 85637e8ac45f86ee79fb77fb08689ebb7a0b76f3..13e1dd4dd62cad0023ed0b4268a4b0deda5a207a 100644 (file)
@@ -23,7 +23,7 @@
 #include <linux/iio/triggered_buffer.h>
 #include <linux/iio/trigger_consumer.h>
 
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #include "afe440x.h"
 
index e9167574203ad84d2f91f858ddb91892573ea07c..77418d97f30de0a1eb7f2ade239400de7507f257 100644 (file)
@@ -22,7 +22,7 @@
 #include <linux/module.h>
 #include <linux/types.h>
 
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 /* register definitions */
 #define ENS210_REG_PART_ID             0x00
index a82dcc3da4216f84c68096e779cb8df58fe37971..ffb25596d3a8bad01d1f84a9a972561266f65d76 100644 (file)
@@ -26,7 +26,7 @@
 #include <linux/regulator/consumer.h>
 #include <linux/units.h>
 
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #include <linux/iio/events.h>
 #include <linux/iio/iio.h>
index 876848b42f69bd5d2b3d62919d2d61e37de9830c..99410733c1ca7455abca1e3fc00a952b4ddc675c 100644 (file)
@@ -13,7 +13,7 @@
 #include <linux/kernel.h>
 #include <linux/spi/spi.h>
 #include <linux/module.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #include <linux/iio/iio.h>
 #include <linux/iio/imu/adis.h>
index 671401ce80dcf947b7b64ea3af112d2a42ca5501..e1f3b0d778be03013042e606a160f40689acf22e 100644 (file)
@@ -19,7 +19,7 @@
 #include <linux/regulator/consumer.h>
 #include <linux/units.h>
 
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #include <linux/iio/buffer.h>
 #include <linux/iio/events.h>
@@ -2172,7 +2172,6 @@ int bmi323_core_probe(struct device *dev)
 }
 EXPORT_SYMBOL_NS_GPL(bmi323_core_probe, IIO_BMI323);
 
-#if defined(CONFIG_PM)
 static int bmi323_core_runtime_suspend(struct device *dev)
 {
        struct iio_dev *indio_dev = dev_get_drvdata(dev);
@@ -2199,12 +2198,12 @@ static int bmi323_core_runtime_suspend(struct device *dev)
        }
 
        for (unsigned int i = 0; i < ARRAY_SIZE(bmi323_ext_reg_savestate); i++) {
-               ret = bmi323_read_ext_reg(data, bmi323_reg_savestate[i],
-                                         &savestate->reg_settings[i]);
+               ret = bmi323_read_ext_reg(data, bmi323_ext_reg_savestate[i],
+                                         &savestate->ext_reg_settings[i]);
                if (ret) {
                        dev_err(data->dev,
                                "Error reading bmi323 external reg 0x%x: %d\n",
-                               bmi323_reg_savestate[i], ret);
+                               bmi323_ext_reg_savestate[i], ret);
                        return ret;
                }
        }
@@ -2232,8 +2231,10 @@ static int bmi323_core_runtime_resume(struct device *dev)
         * after being reset in the lower power state by runtime-pm.
         */
        ret = bmi323_init(data);
-       if (!ret)
+       if (ret) {
+               dev_err(data->dev, "Device power-on and init failed: %d", ret);
                return ret;
+       }
 
        /* Register must be cleared before changing an active config */
        ret = regmap_write(data->regmap, BMI323_FEAT_IO0_REG, 0);
@@ -2243,12 +2244,12 @@ static int bmi323_core_runtime_resume(struct device *dev)
        }
 
        for (unsigned int i = 0; i < ARRAY_SIZE(bmi323_ext_reg_savestate); i++) {
-               ret = bmi323_write_ext_reg(data, bmi323_reg_savestate[i],
-                                          savestate->reg_settings[i]);
+               ret = bmi323_write_ext_reg(data, bmi323_ext_reg_savestate[i],
+                                          savestate->ext_reg_settings[i]);
                if (ret) {
                        dev_err(data->dev,
                                "Error writing bmi323 external reg 0x%x: %d\n",
-                               bmi323_reg_savestate[i], ret);
+                               bmi323_ext_reg_savestate[i], ret);
                        return ret;
                }
        }
@@ -2293,11 +2294,9 @@ static int bmi323_core_runtime_resume(struct device *dev)
        return iio_device_resume_triggering(indio_dev);
 }
 
-#endif
-
 const struct dev_pm_ops bmi323_core_pm_ops = {
-       SET_RUNTIME_PM_OPS(bmi323_core_runtime_suspend,
-                          bmi323_core_runtime_resume, NULL)
+       RUNTIME_PM_OPS(bmi323_core_runtime_suspend,
+                      bmi323_core_runtime_resume, NULL)
 };
 EXPORT_SYMBOL_NS_GPL(bmi323_core_pm_ops, IIO_BMI323);
 
index 59d7615c0f565c50bb979961e3a42e5f38ebb759..5f131bc1a01e97100fa58174c379bb921753918a 100644 (file)
@@ -307,13 +307,15 @@ static int iio_gts_build_avail_scale_table(struct iio_gts *gts)
        if (ret)
                goto err_free_out;
 
+       for (i = 0; i < gts->num_itime; i++)
+               kfree(per_time_gains[i]);
        kfree(per_time_gains);
        gts->per_time_avail_scale_tables = per_time_scales;
 
        return 0;
 
 err_free_out:
-       for (i--; i; i--) {
+       for (i--; i >= 0; i--) {
                kfree(per_time_scales[i]);
                kfree(per_time_gains[i]);
        }
index 515ff46b5b8212da7cc0649ea030c5305f5f327c..f2f3e414849ab12a7c0ea2b08e9a3310eb18ebb7 100644 (file)
@@ -335,6 +335,8 @@ config ROHM_BU27008
        depends on I2C
        select REGMAP_I2C
        select IIO_GTS_HELPER
+       select IIO_BUFFER
+       select IIO_TRIGGERED_BUFFER
        help
          Enable support for the ROHM BU27008 color sensor.
          The ROHM BU27008 is a sensor with 5 photodiodes (red, green,
index 66a063ea3db445b899ebfdd25b3948ed6bef737a..079e02be1005210ddd30b384ffa1ff7feeb098d7 100644 (file)
@@ -28,7 +28,7 @@
 #include <linux/iio/events.h>
 #include <linux/iio/sysfs.h>
 
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #define APDS9306_MAIN_CTRL_REG         0x00
 #define APDS9306_ALS_MEAS_RATE_REG     0x04
index b3f87dded040d6297a3b9243bb2ebe7929705146..81e718cdeae32d60581cb490148f4f1c0bd695c7 100644 (file)
@@ -43,7 +43,7 @@
 #include <linux/regmap.h>
 #include <linux/regulator/consumer.h>
 #include <linux/slab.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include <linux/iio/buffer.h>
 #include <linux/iio/events.h>
 #include <linux/iio/iio.h>
index 7e58b50f3660332366a787a1fc8f4d1508cf627a..4f6975e63a8fe152c1eed53a661593760611555a 100644 (file)
@@ -27,7 +27,7 @@
 
 #include <linux/iio/iio.h>
 
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #define LTR390_MAIN_CTRL               0x00
 #define LTR390_ALS_UVS_MEAS_RATE       0x04
index bc8444516689e03a90af5b274469319807994da0..37eecff571b96b858545dd04d9648888026d797e 100644 (file)
@@ -26,7 +26,7 @@
 
 #include <linux/iio/iio.h>
 
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #define LTRF216A_ALS_RESET_MASK                BIT(4)
 #define LTRF216A_ALS_DATA_STATUS       BIT(3)
index 887c4b776a8696f7429eaceeefcac3d9d661efac..176e54bb48c33b2445ecfd80351b3953fd610ee9 100644 (file)
@@ -138,6 +138,10 @@ static const struct opt3001_scale opt3001_scales[] = {
                .val = 20966,
                .val2 = 400000,
        },
+       {
+               .val = 41932,
+               .val2 = 800000,
+       },
        {
                .val = 83865,
                .val2 = 600000,
index eeff6cc792f222df07316b5ec6f0d61f7057eb21..44fa152dbd24c26c97cc778cbe641d92ecd56afa 100644 (file)
@@ -17,7 +17,7 @@
 
 #include <linux/util_macros.h>
 
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #define SI1133_REG_PART_ID             0x00
 #define SI1133_REG_REV_ID              0x01
index 7bdbfe72f0f0413625c9c2ee5b3aac05ac974e4f..850c2465992fa0d83430236825ce94051a104272 100644 (file)
@@ -21,7 +21,7 @@
 #include <linux/pm_runtime.h>
 #include <linux/sysfs.h>
 
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #include <linux/iio/events.h>
 #include <linux/iio/iio.h>
index 2e86d310952ede41925431d838e70c1ba4fae386..621428885455c0591b93411fe146d7b5ec92357b 100644 (file)
@@ -99,9 +99,8 @@ static const char * const period_values[] = {
 static ssize_t in_illuminance_period_available_show(struct device *dev,
                                struct device_attribute *attr, char *buf)
 {
+       struct veml6030_data *data = iio_priv(dev_to_iio_dev(dev));
        int ret, reg, x;
-       struct iio_dev *indio_dev = i2c_get_clientdata(to_i2c_client(dev));
-       struct veml6030_data *data = iio_priv(indio_dev);
 
        ret = regmap_read(data->regmap, VEML6030_REG_ALS_CONF, &reg);
        if (ret) {
@@ -523,7 +522,7 @@ static int veml6030_read_raw(struct iio_dev *indio_dev,
                        }
                        if (mask == IIO_CHAN_INFO_PROCESSED) {
                                *val = (reg * data->cur_resolution) / 10000;
-                               *val2 = (reg * data->cur_resolution) % 10000;
+                               *val2 = (reg * data->cur_resolution) % 10000 * 100;
                                return IIO_VAL_INT_PLUS_MICRO;
                        }
                        *val = reg;
@@ -780,7 +779,7 @@ static int veml6030_hw_init(struct iio_dev *indio_dev)
 
        /* Cache currently active measurement parameters */
        data->cur_gain = 3;
-       data->cur_resolution = 4608;
+       data->cur_resolution = 5376;
        data->cur_integration_time = 3;
 
        return ret;
index 327f94e447af4961b91a60679c694cd6e29562c7..604be60e92acae020acdbd274a599726e31983f8 100644 (file)
@@ -19,7 +19,7 @@
 #include <linux/iio/iio.h>
 #include <linux/iio/sysfs.h>
 
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #define ZOPT2201_DRV_NAME "zopt2201"
 
index 8eb718f5e50f3591082d33618b680ea22608fde8..f69ac75500f99422dec300fdc612294353bcd2bf 100644 (file)
@@ -11,6 +11,8 @@ config AF8133J
        depends on I2C
        depends on OF
        select REGMAP_I2C
+       select IIO_BUFFER
+       select IIO_TRIGGERED_BUFFER
        help
          Say yes here to build support for Voltafield AF8133J I2C-based
          3-axis magnetometer chip.
index 0e03a772fa43d290140c58c89055029cca2644ad..baab918b38254ba3e8f5f0f1b7b7f544c16544fb 100644 (file)
@@ -22,7 +22,7 @@
 #include <linux/iio/triggered_buffer.h>
 #include <linux/iio/trigger_consumer.h>
 
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #include "rm3100.h"
 
index 7b041bb386931cd09e98c877b4a57c4f1037ca3e..65011a8598d33292c07463ecfe218698cb40c456 100644 (file)
@@ -43,7 +43,7 @@
 #include <linux/iio/trigger_consumer.h>
 #include <linux/iio/triggered_buffer.h>
 
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 /* Commonly used registers */
 #define YAS5XX_DEVICE_ID               0x80
index ce369dbb17fc1551f2e139db340c7822dfeab030..d2cb8c871f6ac0b614bfb110852629a980a6fb98 100644 (file)
@@ -19,6 +19,9 @@ config ABP060MG
 config ROHM_BM1390
        tristate "ROHM BM1390GLV-Z pressure sensor driver"
        depends on I2C
+       select REGMAP_I2C
+       select IIO_BUFFER
+       select IIO_TRIGGERED_BUFFER
        help
          Support for the ROHM BM1390 pressure sensor. The BM1390GLV-Z
          can measure pressures ranging from 300 hPa to 1300 hPa with
@@ -253,6 +256,7 @@ config MS5637
 config SDP500
        tristate "Sensirion SDP500 differential pressure sensor I2C driver"
        depends on I2C
+       select CRC8
        help
          Say Y here to build support for Sensirion SDP500 differential pressure
          sensor I2C driver.
index da379230c83700384e300d84ad673af8eb11c28e..a8b97b9b0461823aba119c485a9fa56ea373229a 100644 (file)
@@ -46,7 +46,7 @@
 #include <linux/iio/trigger_consumer.h>
 #include <linux/iio/triggered_buffer.h>
 
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #include "bmp280.h"
 
index c1cea9d40424ecbc0a1bbe224ea5cea61fa12ccb..e99e97ea630051fcc026634957c86a47c2cbb021 100644 (file)
@@ -15,7 +15,7 @@
 #include <linux/iio/buffer.h>
 #include <linux/iio/trigger_consumer.h>
 #include <linux/iio/triggered_buffer.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 /* Commands */
 #define DLH_START_SINGLE    0xAA
index 261af1562827c8ef7c0d86a29b8b180596dedb11..44274094193379bdad8647d79aaf7e599484bca0 100644 (file)
@@ -18,7 +18,7 @@
 #include <linux/delay.h>
 #include <linux/util_macros.h>
 
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 /* I2C commands: */
 #define HP206C_CMD_SOFT_RST    0x06
index 1682b90d4557c2b394544074d439d908ba882c4b..4e6f10eeabc301c33764ec3aee64621e0c692996 100644 (file)
@@ -28,7 +28,7 @@
 #include <linux/iio/trigger_consumer.h>
 #include <linux/iio/triggered_buffer.h>
 
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #include "hsc030pa.h"
 
index 33a15d4c642c0a6b3ee9c7238e3d1a90e09a2c2c..3b6145348c2e3b46ae4d98450fe3944fcccdd1f8 100644 (file)
@@ -26,7 +26,7 @@
 
 #include <linux/regulator/consumer.h>
 
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #include "mprls0025pa.h"
 
index 9a0f52321fcb9d9bbf08acb4b5e527aea7caa8ba..7e2cb8b6afa223c65f0d6f5b172ab219e2eea3b1 100644 (file)
@@ -16,7 +16,7 @@
 #include <linux/module.h>
 #include <linux/mod_devicetable.h>
 
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #include "ms5611.h"
 
index cc9d1f68c53cc1b298c2ce45b26cbb0bfb516c6d..87181963a3e3db36c8ecdceb1a9dc2742eacb297 100644 (file)
@@ -11,7 +11,7 @@
 #include <linux/spi/spi.h>
 #include <linux/mod_devicetable.h>
 
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #include "ms5611.h"
 
index 6ff32e3fa637286c35e704a9dcd0e848da22d7d0..9828c73c48559c51b3fd38bb76ac8f7b0fda1e5d 100644 (file)
@@ -10,7 +10,7 @@
 #include <linux/iio/iio.h>
 #include <linux/mod_devicetable.h>
 #include <linux/regulator/consumer.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #define SDP500_CRC8_POLYNOMIAL  0x31   /* x8+x5+x4+1 (normalized to 0x31) */
 #define SDP500_READ_SIZE        3
index 80176e3083afbbbc70d2dffe1ad7a675064db422..597bf268ea5172e10d1fba4bbb92d8982816bf15 100644 (file)
@@ -14,7 +14,7 @@
 #include <linux/iio/iio.h>
 #include <linux/iio/sysfs.h>
 #include <linux/iio/trigger.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #include <linux/iio/common/st_sensors.h>
 #include "st_pressure.h"
index dcc87a9015e8be0d3e6e88ff52e76ce7008c8e10..950f8dee2b26b771e418733d433593259d9d9305 100644 (file)
@@ -64,7 +64,7 @@
 #include <linux/iio/trigger.h>
 #include <linux/iio/trigger_consumer.h>
 #include <linux/iio/triggered_buffer.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include "zpa2326.h"
 
 /* 200 ms should be enough for the longest conversion time in one-shot mode. */
index 31c679074b250ea01e43ced97ace231a76a3bee1..a562a78b7d0d1a8086388f4fe1ad3612e0eba378 100644 (file)
@@ -86,6 +86,8 @@ config LIDAR_LITE_V2
 config MB1232
        tristate "MaxSonar I2CXL family ultrasonic sensors"
        depends on I2C
+       select IIO_BUFFER
+       select IIO_TRIGGERED_BUFFER
        help
          Say Y to build a driver for the ultrasonic sensors I2CXL of
          MaxBotix which have an i2c interface. It can be used to measure
index db9d78e961fd8004dae24f63273b19bbbda0b413..707ba0a510aa5f2a30d3fa70ae81fa58b8dfbc33 100644 (file)
@@ -17,7 +17,7 @@
 #include <linux/regulator/consumer.h>
 #include <linux/regmap.h>
 #include <linux/slab.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #define AW_DATA_PROCESS_FACTOR                 1024
 #define AW96103_CHIP_ID                                0xa961
index cff57d851762ea23d47a3105c50e1396f30874a6..c25472b14d4be0f2c2fdf34aae868d7bd5748057 100644 (file)
@@ -21,7 +21,7 @@
 #include <linux/iio/iio.h>
 #include <linux/iio/sysfs.h>
 
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 struct cros_ec_mkbp_proximity_data {
        struct cros_ec_device *ec;
index 8b9f84400e004c9921fd68dba042afc543c9feab..d8fb34060d3db88a3ba5ecdc209b14be8e42e8b9 100644 (file)
@@ -29,7 +29,7 @@
 #include <linux/units.h>
 
 #include <asm/byteorder.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #include <linux/iio/buffer.h>
 #include <linux/iio/events.h>
index 323ac6dac90e1b5918549c61009db6398b84261d..6e96b764fed8b577d71c3146210679b0b61d4c38 100644 (file)
@@ -5,7 +5,7 @@
  * Copyright (C) 2023 Axis Communications AB
  */
 
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include <linux/bitfield.h>
 #include <linux/i2c.h>
 #include <linux/module.h>
index 424529d36080e899468480b7278c6050132d2971..de2dee3832a1a314ade26b3d2f2db57cefc5eebb 100644 (file)
@@ -31,6 +31,9 @@ config AD2S1210
        depends on SPI
        depends on COMMON_CLK
        depends on GPIOLIB || COMPILE_TEST
+       select REGMAP
+       select IIO_BUFFER
+       select IIO_TRIGGERED_BUFFER
        help
          Say yes here to build support for Analog Devices spi resolver
          to digital converters, ad2s1210, provides direct access via sysfs.
index 21f2cfc55bf8d8013aac6a09e58d62dfa31894de..f8ea2219ab48b31c18d2ff22dcf103fb4d114f09 100644 (file)
@@ -22,7 +22,7 @@
 #include <linux/spi/spi.h>
 
 #include <asm/byteorder.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 /* register map */
 #define LTC2983_STATUS_REG                     0x0000
index 8307aae2cb457ac708e8298031710b5fc9315658..7ddec5cbe558e7884b3770e722777f0303cafc57 100644 (file)
@@ -16,7 +16,7 @@
 #include <linux/iio/iio.h>
 #include <linux/iio/sysfs.h>
 #include <linux/util_macros.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include <dt-bindings/iio/temperature/thermocouple.h>
 /*
  * The MSB of the register value determines whether the following byte will
index 29e23652ba5a112a42537c1c0d4a2f567f01a1dd..5a6fbe3c80e5f607ea122e98d1a71e83bd77e4b1 100644 (file)
@@ -18,7 +18,7 @@
 #include <linux/iio/sysfs.h>
 #include <linux/property.h>
 #include <linux/spi/spi.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 /*
  * The MSB of the register value determines whether the following byte will
index be0743dac3fff337b3aa59b417068b5edb0e395b..c4cf26f1d1496add9200f7997a3f43e0d07809ed 100644 (file)
@@ -269,6 +269,8 @@ rdma_find_ndev_for_src_ip_rcu(struct net *net, const struct sockaddr *src_in)
                break;
 #endif
        }
+       if (!ret && dev && is_vlan_dev(dev))
+               dev = vlan_dev_real_dev(dev);
        return ret ? ERR_PTR(ret) : dev;
 }
 
index 39f89a4b86498220ec30bcb16bcc804f2b049752..7dc8e2ec62cc8bd5d86690ebdcff6dec8765f0a3 100644 (file)
@@ -2816,6 +2816,8 @@ int rdma_nl_notify_event(struct ib_device *device, u32 port_num,
        nlh = nlmsg_put(skb, 0, 0,
                        RDMA_NL_GET_TYPE(RDMA_NL_NLDEV, RDMA_NLDEV_CMD_MONITOR),
                        0, 0);
+       if (!nlh)
+               goto err_free;
 
        switch (type) {
        case RDMA_REGISTER_EVENT:
index 128651c015956c7d416751f6f3fb497246a3d928..1e63f8091748370add8106a438158e03c47a20a6 100644 (file)
@@ -366,7 +366,7 @@ int bnxt_re_ib_get_hw_stats(struct ib_device *ibdev,
                                goto done;
                        }
                }
-               if (rdev->pacing.dbr_pacing)
+               if (rdev->pacing.dbr_pacing && bnxt_qplib_is_chip_gen_p5_p7(rdev->chip_ctx))
                        bnxt_re_copy_db_pacing_stats(rdev, stats);
        }
 
index 460f33914825c6865cd8e4b4b559f94cacb71653..e66ae9f22c710c1caf38d452b4d165add35d1f60 100644 (file)
@@ -1307,7 +1307,11 @@ static int bnxt_re_init_sq_attr(struct bnxt_re_qp *qp,
                        0 : BNXT_QPLIB_RESERVED_QP_WRS;
                entries = bnxt_re_init_depth(entries + diff + 1, uctx);
                sq->max_wqe = min_t(u32, entries, dev_attr->max_qp_wqes + diff + 1);
-               sq->max_sw_wqe = bnxt_qplib_get_depth(sq, qplqp->wqe_mode, true);
+               if (qplqp->wqe_mode == BNXT_QPLIB_WQE_MODE_VARIABLE)
+                       sq->max_sw_wqe = bnxt_qplib_get_depth(sq, qplqp->wqe_mode, true);
+               else
+                       sq->max_sw_wqe = sq->max_wqe;
+
        }
        sq->q_full_delta = diff + 1;
        /*
index 777068de4bbc170de47d214d05112c14901805d2..6715c96a3eeef4369d03be9bf3ad2de378ae1643 100644 (file)
@@ -188,8 +188,11 @@ static int bnxt_re_setup_chip_ctx(struct bnxt_re_dev *rdev)
 
        bnxt_re_set_db_offset(rdev);
        rc = bnxt_qplib_map_db_bar(&rdev->qplib_res);
-       if (rc)
+       if (rc) {
+               kfree(rdev->chip_ctx);
+               rdev->chip_ctx = NULL;
                return rc;
+       }
 
        if (bnxt_qplib_determine_atomics(en_dev->pdev))
                ibdev_info(&rdev->ibdev,
@@ -531,6 +534,7 @@ static bool is_dbr_fifo_full(struct bnxt_re_dev *rdev)
 static void __wait_for_fifo_occupancy_below_th(struct bnxt_re_dev *rdev)
 {
        struct bnxt_qplib_db_pacing_data *pacing_data = rdev->qplib_res.pacing_data;
+       u32 retry_fifo_check = 1000;
        u32 fifo_occup;
 
        /* loop shouldn't run infintely as the occupancy usually goes
@@ -544,6 +548,14 @@ static void __wait_for_fifo_occupancy_below_th(struct bnxt_re_dev *rdev)
 
                if (fifo_occup < pacing_data->pacing_th)
                        break;
+               if (!retry_fifo_check--) {
+                       dev_info_once(rdev_to_dev(rdev),
+                                     "%s: fifo_occup = 0x%xfifo_max_depth = 0x%x pacing_th = 0x%x\n",
+                                     __func__, fifo_occup, pacing_data->fifo_max_depth,
+                                       pacing_data->pacing_th);
+                       break;
+               }
+
        }
 }
 
@@ -957,7 +969,7 @@ static int bnxt_re_register_ib(struct bnxt_re_dev *rdev)
        return ib_register_device(ibdev, "bnxt_re%d", &rdev->en_dev->pdev->dev);
 }
 
-static struct bnxt_re_dev *bnxt_re_dev_add(struct bnxt_aux_priv *aux_priv,
+static struct bnxt_re_dev *bnxt_re_dev_add(struct auxiliary_device *adev,
                                           struct bnxt_en_dev *en_dev)
 {
        struct bnxt_re_dev *rdev;
@@ -973,6 +985,7 @@ static struct bnxt_re_dev *bnxt_re_dev_add(struct bnxt_aux_priv *aux_priv,
        rdev->nb.notifier_call = NULL;
        rdev->netdev = en_dev->net;
        rdev->en_dev = en_dev;
+       rdev->adev = adev;
        rdev->id = rdev->en_dev->pdev->devfn;
        INIT_LIST_HEAD(&rdev->qp_list);
        mutex_init(&rdev->qp_lock);
@@ -1025,12 +1038,15 @@ static int bnxt_re_handle_unaffi_async_event(struct creq_func_event
 static int bnxt_re_handle_qp_async_event(struct creq_qp_event *qp_event,
                                         struct bnxt_re_qp *qp)
 {
-       struct bnxt_re_srq *srq = container_of(qp->qplib_qp.srq, struct bnxt_re_srq,
-                                              qplib_srq);
        struct creq_qp_error_notification *err_event;
+       struct bnxt_re_srq *srq = NULL;
        struct ib_event event = {};
        unsigned int flags;
 
+       if (qp->qplib_qp.srq)
+               srq =  container_of(qp->qplib_qp.srq, struct bnxt_re_srq,
+                                   qplib_srq);
+
        if (qp->qplib_qp.state == CMDQ_MODIFY_QP_NEW_STATE_ERR &&
            rdma_is_kernel_res(&qp->ib_qp.res)) {
                flags = bnxt_re_lock_cqs(qp);
@@ -1258,15 +1274,9 @@ static int bnxt_re_cqn_handler(struct bnxt_qplib_nq *nq,
 {
        struct bnxt_re_cq *cq = container_of(handle, struct bnxt_re_cq,
                                             qplib_cq);
-       u32 *cq_ptr;
 
-       if (cq->ib_cq.comp_handler) {
-               if (cq->uctx_cq_page) {
-                       cq_ptr = (u32 *)cq->uctx_cq_page;
-                       *cq_ptr = cq->qplib_cq.toggle;
-               }
+       if (cq->ib_cq.comp_handler)
                (*cq->ib_cq.comp_handler)(&cq->ib_cq, cq->ib_cq.cq_context);
-       }
 
        return 0;
 }
@@ -1823,7 +1833,6 @@ static void bnxt_re_update_en_info_rdev(struct bnxt_re_dev *rdev,
         */
        rtnl_lock();
        en_info->rdev = rdev;
-       rdev->adev = adev;
        rtnl_unlock();
 }
 
@@ -1840,7 +1849,7 @@ static int bnxt_re_add_device(struct auxiliary_device *adev, u8 op_type)
        en_dev = en_info->en_dev;
 
 
-       rdev = bnxt_re_dev_add(aux_priv, en_dev);
+       rdev = bnxt_re_dev_add(adev, en_dev);
        if (!rdev || !rdev_to_dev(rdev)) {
                rc = -ENOMEM;
                goto exit;
@@ -1865,12 +1874,14 @@ static int bnxt_re_add_device(struct auxiliary_device *adev, u8 op_type)
                rdev->nb.notifier_call = NULL;
                pr_err("%s: Cannot register to netdevice_notifier",
                       ROCE_DRV_MODULE_NAME);
-               return rc;
+               goto re_dev_unreg;
        }
        bnxt_re_setup_cc(rdev, true);
 
        return 0;
 
+re_dev_unreg:
+       ib_unregister_device(&rdev->ibdev);
 re_dev_uninit:
        bnxt_re_update_en_info_rdev(NULL, en_info, adev);
        bnxt_re_dev_uninit(rdev, BNXT_RE_COMPLETE_REMOVE);
@@ -2014,15 +2025,7 @@ static int bnxt_re_probe(struct auxiliary_device *adev,
        auxiliary_set_drvdata(adev, en_info);
 
        rc = bnxt_re_add_device(adev, BNXT_RE_COMPLETE_INIT);
-       if (rc)
-               goto err;
        mutex_unlock(&bnxt_re_mutex);
-       return 0;
-
-err:
-       mutex_unlock(&bnxt_re_mutex);
-       bnxt_re_remove(adev);
-
        return rc;
 }
 
index 42e98e5f94cb1a0755bc6fe96f7fe75c66b8e69d..7ad83566ab0f41dbb7d64f99e14dcf8531e5fd78 100644 (file)
@@ -327,6 +327,7 @@ static void bnxt_qplib_service_nq(struct tasklet_struct *t)
                case NQ_BASE_TYPE_CQ_NOTIFICATION:
                {
                        struct nq_cn *nqcne = (struct nq_cn *)nqe;
+                       struct bnxt_re_cq *cq_p;
 
                        q_handle = le32_to_cpu(nqcne->cq_handle_low);
                        q_handle |= (u64)le32_to_cpu(nqcne->cq_handle_high)
@@ -337,6 +338,10 @@ static void bnxt_qplib_service_nq(struct tasklet_struct *t)
                        cq->toggle = (le16_to_cpu(nqe->info10_type) &
                                        NQ_CN_TOGGLE_MASK) >> NQ_CN_TOGGLE_SFT;
                        cq->dbinfo.toggle = cq->toggle;
+                       cq_p = container_of(cq, struct bnxt_re_cq, qplib_cq);
+                       if (cq_p->uctx_cq_page)
+                               *((u32 *)cq_p->uctx_cq_page) = cq->toggle;
+
                        bnxt_qplib_armen_db(&cq->dbinfo,
                                            DBC_DBC_TYPE_CQ_ARMENA);
                        spin_lock_bh(&cq->compl_lock);
@@ -1527,9 +1532,11 @@ int bnxt_qplib_destroy_qp(struct bnxt_qplib_res *res,
        u32 tbl_indx;
        int rc;
 
+       spin_lock_bh(&rcfw->tbl_lock);
        tbl_indx = map_qp_id_to_tbl_indx(qp->id, rcfw);
        rcfw->qp_tbl[tbl_indx].qp_id = BNXT_QPLIB_QP_ID_INVALID;
        rcfw->qp_tbl[tbl_indx].qp_handle = NULL;
+       spin_unlock_bh(&rcfw->tbl_lock);
 
        bnxt_qplib_rcfw_cmd_prep((struct cmdq_base *)&req,
                                 CMDQ_BASE_OPCODE_DESTROY_QP,
@@ -1540,8 +1547,10 @@ int bnxt_qplib_destroy_qp(struct bnxt_qplib_res *res,
                                sizeof(resp), 0);
        rc = bnxt_qplib_rcfw_send_message(rcfw, &msg);
        if (rc) {
+               spin_lock_bh(&rcfw->tbl_lock);
                rcfw->qp_tbl[tbl_indx].qp_id = qp->id;
                rcfw->qp_tbl[tbl_indx].qp_handle = qp;
+               spin_unlock_bh(&rcfw->tbl_lock);
                return rc;
        }
 
index b62df8701950ff622309fb5840ab16189cebf1b9..820611a239433a5c085ad70198c181ed14273490 100644 (file)
@@ -170,7 +170,7 @@ struct bnxt_qplib_swqe {
                        };
                        u32             q_key;
                        u32             dst_qp;
-                       u16             avid;
+                       u32             avid;
                } send;
 
                /* Send Raw Ethernet and QP1 */
index 3ffaef0c26519424c35e1c690faad3ca9e73fcf9..e82bd37158ad6ce0e7866a13b7cda99c34f0e1c6 100644 (file)
@@ -290,7 +290,6 @@ static int __send_message(struct bnxt_qplib_rcfw *rcfw,
        struct bnxt_qplib_hwq *hwq;
        u32 sw_prod, cmdq_prod;
        struct pci_dev *pdev;
-       unsigned long flags;
        u16 cookie;
        u8 *preq;
 
@@ -301,7 +300,7 @@ static int __send_message(struct bnxt_qplib_rcfw *rcfw,
        /* Cmdq are in 16-byte units, each request can consume 1 or more
         * cmdqe
         */
-       spin_lock_irqsave(&hwq->lock, flags);
+       spin_lock_bh(&hwq->lock);
        required_slots = bnxt_qplib_get_cmd_slots(msg->req);
        free_slots = HWQ_FREE_SLOTS(hwq);
        cookie = cmdq->seq_num & RCFW_MAX_COOKIE_VALUE;
@@ -311,7 +310,7 @@ static int __send_message(struct bnxt_qplib_rcfw *rcfw,
                dev_info_ratelimited(&pdev->dev,
                                     "CMDQ is full req/free %d/%d!",
                                     required_slots, free_slots);
-               spin_unlock_irqrestore(&hwq->lock, flags);
+               spin_unlock_bh(&hwq->lock);
                return -EAGAIN;
        }
        if (msg->block)
@@ -367,7 +366,7 @@ static int __send_message(struct bnxt_qplib_rcfw *rcfw,
        wmb();
        writel(cmdq_prod, cmdq->cmdq_mbox.prod);
        writel(RCFW_CMDQ_TRIG_VAL, cmdq->cmdq_mbox.db);
-       spin_unlock_irqrestore(&hwq->lock, flags);
+       spin_unlock_bh(&hwq->lock);
        /* Return the CREQ response pointer */
        return 0;
 }
@@ -486,7 +485,6 @@ static int __bnxt_qplib_rcfw_send_message(struct bnxt_qplib_rcfw *rcfw,
 {
        struct creq_qp_event *evnt = (struct creq_qp_event *)msg->resp;
        struct bnxt_qplib_crsqe *crsqe;
-       unsigned long flags;
        u16 cookie;
        int rc;
        u8 opcode;
@@ -512,12 +510,12 @@ static int __bnxt_qplib_rcfw_send_message(struct bnxt_qplib_rcfw *rcfw,
                rc = __poll_for_resp(rcfw, cookie);
 
        if (rc) {
-               spin_lock_irqsave(&rcfw->cmdq.hwq.lock, flags);
+               spin_lock_bh(&rcfw->cmdq.hwq.lock);
                crsqe = &rcfw->crsqe_tbl[cookie];
                crsqe->is_waiter_alive = false;
                if (rc == -ENODEV)
                        set_bit(FIRMWARE_STALL_DETECTED, &rcfw->cmdq.flags);
-               spin_unlock_irqrestore(&rcfw->cmdq.hwq.lock, flags);
+               spin_unlock_bh(&rcfw->cmdq.hwq.lock);
                return -ETIMEDOUT;
        }
 
@@ -525,7 +523,7 @@ static int __bnxt_qplib_rcfw_send_message(struct bnxt_qplib_rcfw *rcfw,
                /* failed with status */
                dev_err(&rcfw->pdev->dev, "cmdq[%#x]=%#x status %#x\n",
                        cookie, opcode, evnt->status);
-               rc = -EFAULT;
+               rc = -EIO;
        }
 
        return rc;
@@ -628,7 +626,6 @@ static int bnxt_qplib_process_qp_event(struct bnxt_qplib_rcfw *rcfw,
        u16 cookie, blocked = 0;
        bool is_waiter_alive;
        struct pci_dev *pdev;
-       unsigned long flags;
        u32 wait_cmds = 0;
        int rc = 0;
 
@@ -637,17 +634,21 @@ static int bnxt_qplib_process_qp_event(struct bnxt_qplib_rcfw *rcfw,
        case CREQ_QP_EVENT_EVENT_QP_ERROR_NOTIFICATION:
                err_event = (struct creq_qp_error_notification *)qp_event;
                qp_id = le32_to_cpu(err_event->xid);
+               spin_lock(&rcfw->tbl_lock);
                tbl_indx = map_qp_id_to_tbl_indx(qp_id, rcfw);
                qp = rcfw->qp_tbl[tbl_indx].qp_handle;
+               if (!qp) {
+                       spin_unlock(&rcfw->tbl_lock);
+                       break;
+               }
+               bnxt_qplib_mark_qp_error(qp);
+               rc = rcfw->creq.aeq_handler(rcfw, qp_event, qp);
+               spin_unlock(&rcfw->tbl_lock);
                dev_dbg(&pdev->dev, "Received QP error notification\n");
                dev_dbg(&pdev->dev,
                        "qpid 0x%x, req_err=0x%x, resp_err=0x%x\n",
                        qp_id, err_event->req_err_state_reason,
                        err_event->res_err_state_reason);
-               if (!qp)
-                       break;
-               bnxt_qplib_mark_qp_error(qp);
-               rc = rcfw->creq.aeq_handler(rcfw, qp_event, qp);
                break;
        default:
                /*
@@ -659,8 +660,7 @@ static int bnxt_qplib_process_qp_event(struct bnxt_qplib_rcfw *rcfw,
                 *
                 */
 
-               spin_lock_irqsave_nested(&hwq->lock, flags,
-                                        SINGLE_DEPTH_NESTING);
+               spin_lock_nested(&hwq->lock, SINGLE_DEPTH_NESTING);
                cookie = le16_to_cpu(qp_event->cookie);
                blocked = cookie & RCFW_CMD_IS_BLOCKING;
                cookie &= RCFW_MAX_COOKIE_VALUE;
@@ -672,7 +672,7 @@ static int bnxt_qplib_process_qp_event(struct bnxt_qplib_rcfw *rcfw,
                        dev_info(&pdev->dev,
                                 "rcfw timedout: cookie = %#x, free_slots = %d",
                                 cookie, crsqe->free_slots);
-                       spin_unlock_irqrestore(&hwq->lock, flags);
+                       spin_unlock(&hwq->lock);
                        return rc;
                }
 
@@ -720,7 +720,7 @@ static int bnxt_qplib_process_qp_event(struct bnxt_qplib_rcfw *rcfw,
                        __destroy_timedout_ah(rcfw,
                                              (struct creq_create_ah_resp *)
                                              qp_event);
-               spin_unlock_irqrestore(&hwq->lock, flags);
+               spin_unlock(&hwq->lock);
        }
        *num_wait += wait_cmds;
        return rc;
@@ -734,12 +734,11 @@ static void bnxt_qplib_service_creq(struct tasklet_struct *t)
        u32 type, budget = CREQ_ENTRY_POLL_BUDGET;
        struct bnxt_qplib_hwq *hwq = &creq->hwq;
        struct creq_base *creqe;
-       unsigned long flags;
        u32 num_wakeup = 0;
        u32 hw_polled = 0;
 
        /* Service the CREQ until budget is over */
-       spin_lock_irqsave(&hwq->lock, flags);
+       spin_lock_bh(&hwq->lock);
        while (budget > 0) {
                creqe = bnxt_qplib_get_qe(hwq, hwq->cons, NULL);
                if (!CREQ_CMP_VALID(creqe, creq->creq_db.dbinfo.flags))
@@ -782,7 +781,7 @@ static void bnxt_qplib_service_creq(struct tasklet_struct *t)
        if (hw_polled)
                bnxt_qplib_ring_nq_db(&creq->creq_db.dbinfo,
                                      rcfw->res->cctx, true);
-       spin_unlock_irqrestore(&hwq->lock, flags);
+       spin_unlock_bh(&hwq->lock);
        if (num_wakeup)
                wake_up_nr(&rcfw->cmdq.waitq, num_wakeup);
 }
@@ -978,6 +977,7 @@ int bnxt_qplib_alloc_rcfw_channel(struct bnxt_qplib_res *res,
                               GFP_KERNEL);
        if (!rcfw->qp_tbl)
                goto fail;
+       spin_lock_init(&rcfw->tbl_lock);
 
        rcfw->max_timeout = res->cctx->hwrm_cmd_max_timeout;
 
index 45996e60a0d03e39c72cefeeff645aca910c3989..07779aeb75759df4a28779a412e7e35395f03fdb 100644 (file)
@@ -224,6 +224,8 @@ struct bnxt_qplib_rcfw {
        struct bnxt_qplib_crsqe         *crsqe_tbl;
        int qp_tbl_size;
        struct bnxt_qplib_qp_node *qp_tbl;
+       /* To synchronize the qp-handle hash table */
+       spinlock_t                      tbl_lock;
        u64 oos_prev;
        u32 init_oos_stats;
        u32 cmdq_depth;
index dfc943fab87b4ff39b1cb9d46886faa64e47d0c5..96ceec1e8199a6ba52792e60ffc9b55cb7fb3624 100644 (file)
@@ -244,6 +244,8 @@ int bnxt_qplib_alloc_init_hwq(struct bnxt_qplib_hwq *hwq,
                        sginfo.pgsize = npde * pg_size;
                        sginfo.npages = 1;
                        rc = __alloc_pbl(res, &hwq->pbl[PBL_LVL_0], &sginfo);
+                       if (rc)
+                               goto fail;
 
                        /* Alloc PBL pages */
                        sginfo.npages = npbl;
@@ -255,22 +257,9 @@ int bnxt_qplib_alloc_init_hwq(struct bnxt_qplib_hwq *hwq,
                        dst_virt_ptr =
                                (dma_addr_t **)hwq->pbl[PBL_LVL_0].pg_arr;
                        src_phys_ptr = hwq->pbl[PBL_LVL_1].pg_map_arr;
-                       if (hwq_attr->type == HWQ_TYPE_MR) {
-                       /* For MR it is expected that we supply only 1 contigous
-                        * page i.e only 1 entry in the PDL that will contain
-                        * all the PBLs for the user supplied memory region
-                        */
-                               for (i = 0; i < hwq->pbl[PBL_LVL_1].pg_count;
-                                    i++)
-                                       dst_virt_ptr[0][i] = src_phys_ptr[i] |
-                                               flag;
-                       } else {
-                               for (i = 0; i < hwq->pbl[PBL_LVL_1].pg_count;
-                                    i++)
-                                       dst_virt_ptr[PTR_PG(i)][PTR_IDX(i)] =
-                                               src_phys_ptr[i] |
-                                               PTU_PDE_VALID;
-                       }
+                       for (i = 0; i < hwq->pbl[PBL_LVL_1].pg_count; i++)
+                               dst_virt_ptr[0][i] = src_phys_ptr[i] | flag;
+
                        /* Alloc or init PTEs */
                        rc = __alloc_pbl(res, &hwq->pbl[PBL_LVL_2],
                                         hwq_attr->sginfo);
index 4f75e7e5bcf72fb5e7684c85d2331a52e631bebc..e29fbbdab9fd683931c8258471f803979ec9212a 100644 (file)
@@ -140,6 +140,8 @@ int bnxt_qplib_get_dev_attr(struct bnxt_qplib_rcfw *rcfw,
                            min_t(u32, sb->max_sge_var_wqe, BNXT_VAR_MAX_SGE) : 6;
        attr->max_cq = le32_to_cpu(sb->max_cq);
        attr->max_cq_wqes = le32_to_cpu(sb->max_cqe);
+       if (!bnxt_qplib_is_chip_gen_p7(rcfw->res->cctx))
+               attr->max_cq_wqes = min_t(u32, BNXT_QPLIB_MAX_CQ_WQES, attr->max_cq_wqes);
        attr->max_cq_sges = attr->max_qp_sges;
        attr->max_mr = le32_to_cpu(sb->max_mr);
        attr->max_mw = le32_to_cpu(sb->max_mw);
@@ -157,7 +159,14 @@ int bnxt_qplib_get_dev_attr(struct bnxt_qplib_rcfw *rcfw,
        if (!bnxt_qplib_is_chip_gen_p7(rcfw->res->cctx))
                attr->l2_db_size = (sb->l2_db_space_size + 1) *
                                    (0x01 << RCFW_DBR_BASE_PAGE_SHIFT);
-       attr->max_sgid = BNXT_QPLIB_NUM_GIDS_SUPPORTED;
+       /*
+        * Read the max gid supported by HW.
+        * For each entry in HW  GID in HW table, we consume 2
+        * GID entries in the kernel GID table.  So max_gid reported
+        * to stack can be up to twice the value reported by the HW, up to 256 gids.
+        */
+       attr->max_sgid = le32_to_cpu(sb->max_gid);
+       attr->max_sgid = min_t(u32, BNXT_QPLIB_NUM_GIDS_SUPPORTED, 2 * attr->max_sgid);
        attr->dev_cap_flags = le16_to_cpu(sb->dev_cap_flags);
        attr->dev_cap_flags2 = le16_to_cpu(sb->dev_cap_ext_flags_2);
 
index acd9c14a31c4ba9966ecf263857428fa6a393b0a..ecf3f45fea74febb20e449fad47de39fe775b8c3 100644 (file)
@@ -56,6 +56,7 @@ struct bnxt_qplib_dev_attr {
        u32                             max_qp_wqes;
        u32                             max_qp_sges;
        u32                             max_cq;
+#define BNXT_QPLIB_MAX_CQ_WQES          0xfffff
        u32                             max_cq_wqes;
        u32                             max_cq_sges;
        u32                             max_mr;
index b3757c6a0457a1bc016711f799c91a298d3ece34..8d753e6e0c71903c1742ef3f7628688bf915c2cc 100644 (file)
@@ -2086,7 +2086,7 @@ static int import_ep(struct c4iw_ep *ep, int iptype, __u8 *peer_ip,
        err = -ENOMEM;
        if (n->dev->flags & IFF_LOOPBACK) {
                if (iptype == 4)
-                       pdev = ip_dev_find(&init_net, *(__be32 *)peer_ip);
+                       pdev = __ip_dev_find(&init_net, *(__be32 *)peer_ip, false);
                else if (IS_ENABLED(CONFIG_IPV6))
                        for_each_netdev(&init_net, pdev) {
                                if (ipv6_chk_addr(&init_net,
@@ -2101,12 +2101,12 @@ static int import_ep(struct c4iw_ep *ep, int iptype, __u8 *peer_ip,
                        err = -ENODEV;
                        goto out;
                }
+               if (is_vlan_dev(pdev))
+                       pdev = vlan_dev_real_dev(pdev);
                ep->l2t = cxgb4_l2t_get(cdev->rdev.lldi.l2t,
                                        n, pdev, rt_tos2priority(tos));
-               if (!ep->l2t) {
-                       dev_put(pdev);
+               if (!ep->l2t)
                        goto out;
-               }
                ep->mtu = pdev->mtu;
                ep->tx_chan = cxgb4_port_chan(pdev);
                ep->smac_idx = ((struct port_info *)netdev_priv(pdev))->smt_idx;
@@ -2119,7 +2119,6 @@ static int import_ep(struct c4iw_ep *ep, int iptype, __u8 *peer_ip,
                ep->rss_qid = cdev->rdev.lldi.rxq_ids[
                        cxgb4_port_idx(pdev) * step];
                set_tcp_window(ep, (struct port_info *)netdev_priv(pdev));
-               dev_put(pdev);
        } else {
                pdev = get_real_dev(n->dev);
                ep->l2t = cxgb4_l2t_get(cdev->rdev.lldi.l2t,
index 10a4c738b59f9d012774cfe841c95a91116bb436..e059f92d90fd4812287c417d918d3b91eab36482 100644 (file)
@@ -473,6 +473,7 @@ static const struct ib_device_ops c4iw_dev_ops = {
        .fill_res_cq_entry = c4iw_fill_res_cq_entry,
        .fill_res_cm_id_entry = c4iw_fill_res_cm_id_entry,
        .fill_res_mr_entry = c4iw_fill_res_mr_entry,
+       .fill_res_qp_entry = c4iw_fill_res_qp_entry,
        .get_dev_fw_str = get_dev_fw_str,
        .get_dma_mr = c4iw_get_dma_mr,
        .get_hw_stats = c4iw_get_mib,
index 36bb7e5ce63829c06634a33a840f9a31ff91fab8..ce8d821bdad8476e7d0b61e2ac7eddbafcde5e50 100644 (file)
@@ -3631,7 +3631,7 @@ void irdma_free_lsmm_rsrc(struct irdma_qp *iwqp)
 /**
  * irdma_accept - registered call for connection to be accepted
  * @cm_id: cm information for passive connection
- * @conn_param: accpet parameters
+ * @conn_param: accept parameters
  */
 int irdma_accept(struct iw_cm_id *cm_id, struct iw_cm_conn_param *conn_param)
 {
index e39b1a101e9721b92b84b8e1135dbf8f1158ed41..10ce3b44f645f4e54a24c4197fb9d70d7bb00dc6 100644 (file)
@@ -4268,14 +4268,14 @@ static int __mlx5_ib_modify_qp(struct ib_qp *ibqp,
                MLX5_SET(qpc, qpc, retry_count, attr->retry_cnt);
 
        if (attr_mask & IB_QP_MAX_QP_RD_ATOMIC && attr->max_rd_atomic)
-               MLX5_SET(qpc, qpc, log_sra_max, ilog2(attr->max_rd_atomic));
+               MLX5_SET(qpc, qpc, log_sra_max, fls(attr->max_rd_atomic - 1));
 
        if (attr_mask & IB_QP_SQ_PSN)
                MLX5_SET(qpc, qpc, next_send_psn, attr->sq_psn);
 
        if (attr_mask & IB_QP_MAX_DEST_RD_ATOMIC && attr->max_dest_rd_atomic)
                MLX5_SET(qpc, qpc, log_rra_max,
-                        ilog2(attr->max_dest_rd_atomic));
+                        fls(attr->max_dest_rd_atomic - 1));
 
        if (attr_mask & (IB_QP_ACCESS_FLAGS | IB_QP_MAX_DEST_RD_ATOMIC)) {
                err = set_qpc_atomic_flags(qp, attr, attr_mask, qpc);
index 64ad9e0895bd0fece658cde06e558ce9f39b3807..a034264c566986f751366aeee4c60f2c43bafa09 100644 (file)
@@ -331,6 +331,8 @@ static int siw_tcp_sendpages(struct socket *s, struct page **page, int offset,
                        msg.msg_flags &= ~MSG_MORE;
 
                tcp_rate_check_app_limited(sk);
+               if (!sendpage_ok(page[i]))
+                       msg.msg_flags &= ~MSG_SPLICE_PAGES;
                bvec_set_page(&bvec, page[i], bytes, offset);
                iov_iter_bvec(&msg.msg_iter, ITER_SOURCE, &bvec, 1, size);
 
index 9632afbd727b64b0ddf0072ab8ce692588ad9803..5dfb4644446ba83f52dcafbc32a0fda1c886be8f 100644 (file)
@@ -68,6 +68,8 @@ MODULE_LICENSE("Dual BSD/GPL");
 static u64 srpt_service_guid;
 static DEFINE_SPINLOCK(srpt_dev_lock); /* Protects srpt_dev_list. */
 static LIST_HEAD(srpt_dev_list);       /* List of srpt_device structures. */
+static DEFINE_MUTEX(srpt_mc_mutex);    /* Protects srpt_memory_caches. */
+static DEFINE_XARRAY(srpt_memory_caches); /* See also srpt_memory_cache_entry */
 
 static unsigned srp_max_req_size = DEFAULT_MAX_REQ_SIZE;
 module_param(srp_max_req_size, int, 0444);
@@ -105,6 +107,63 @@ static void srpt_recv_done(struct ib_cq *cq, struct ib_wc *wc);
 static void srpt_send_done(struct ib_cq *cq, struct ib_wc *wc);
 static void srpt_process_wait_list(struct srpt_rdma_ch *ch);
 
+/* Type of the entries in srpt_memory_caches. */
+struct srpt_memory_cache_entry {
+       refcount_t ref;
+       struct kmem_cache *c;
+};
+
+static struct kmem_cache *srpt_cache_get(unsigned int object_size)
+{
+       struct srpt_memory_cache_entry *e;
+       char name[32];
+       void *res;
+
+       guard(mutex)(&srpt_mc_mutex);
+       e = xa_load(&srpt_memory_caches, object_size);
+       if (e) {
+               refcount_inc(&e->ref);
+               return e->c;
+       }
+       snprintf(name, sizeof(name), "srpt-%u", object_size);
+       e = kmalloc(sizeof(*e), GFP_KERNEL);
+       if (!e)
+               return NULL;
+       refcount_set(&e->ref, 1);
+       e->c = kmem_cache_create(name, object_size, /*align=*/512, 0, NULL);
+       if (!e->c)
+               goto free_entry;
+       res = xa_store(&srpt_memory_caches, object_size, e, GFP_KERNEL);
+       if (xa_is_err(res))
+               goto destroy_cache;
+       return e->c;
+
+destroy_cache:
+       kmem_cache_destroy(e->c);
+
+free_entry:
+       kfree(e);
+       return NULL;
+}
+
+static void srpt_cache_put(struct kmem_cache *c)
+{
+       struct srpt_memory_cache_entry *e = NULL;
+       unsigned long object_size;
+
+       guard(mutex)(&srpt_mc_mutex);
+       xa_for_each(&srpt_memory_caches, object_size, e)
+               if (e->c == c)
+                       break;
+       if (WARN_ON_ONCE(!e))
+               return;
+       if (!refcount_dec_and_test(&e->ref))
+               return;
+       WARN_ON_ONCE(xa_erase(&srpt_memory_caches, object_size) != e);
+       kmem_cache_destroy(e->c);
+       kfree(e);
+}
+
 /*
  * The only allowed channel state changes are those that change the channel
  * state into a state with a higher numerical value. Hence the new > prev test.
@@ -2119,13 +2178,13 @@ static void srpt_release_channel_work(struct work_struct *w)
                             ch->sport->sdev, ch->rq_size,
                             ch->rsp_buf_cache, DMA_TO_DEVICE);
 
-       kmem_cache_destroy(ch->rsp_buf_cache);
+       srpt_cache_put(ch->rsp_buf_cache);
 
        srpt_free_ioctx_ring((struct srpt_ioctx **)ch->ioctx_recv_ring,
                             sdev, ch->rq_size,
                             ch->req_buf_cache, DMA_FROM_DEVICE);
 
-       kmem_cache_destroy(ch->req_buf_cache);
+       srpt_cache_put(ch->req_buf_cache);
 
        kref_put(&ch->kref, srpt_free_ch);
 }
@@ -2245,8 +2304,7 @@ static int srpt_cm_req_recv(struct srpt_device *const sdev,
        INIT_LIST_HEAD(&ch->cmd_wait_list);
        ch->max_rsp_size = ch->sport->port_attrib.srp_max_rsp_size;
 
-       ch->rsp_buf_cache = kmem_cache_create("srpt-rsp-buf", ch->max_rsp_size,
-                                             512, 0, NULL);
+       ch->rsp_buf_cache = srpt_cache_get(ch->max_rsp_size);
        if (!ch->rsp_buf_cache)
                goto free_ch;
 
@@ -2280,8 +2338,7 @@ static int srpt_cm_req_recv(struct srpt_device *const sdev,
                alignment_offset = round_up(imm_data_offset, 512) -
                        imm_data_offset;
                req_sz = alignment_offset + imm_data_offset + srp_max_req_size;
-               ch->req_buf_cache = kmem_cache_create("srpt-req-buf", req_sz,
-                                                     512, 0, NULL);
+               ch->req_buf_cache = srpt_cache_get(req_sz);
                if (!ch->req_buf_cache)
                        goto free_rsp_ring;
 
@@ -2478,7 +2535,7 @@ free_recv_ring:
                             ch->req_buf_cache, DMA_FROM_DEVICE);
 
 free_recv_cache:
-       kmem_cache_destroy(ch->req_buf_cache);
+       srpt_cache_put(ch->req_buf_cache);
 
 free_rsp_ring:
        srpt_free_ioctx_ring((struct srpt_ioctx **)ch->ioctx_ring,
@@ -2486,7 +2543,7 @@ free_rsp_ring:
                             ch->rsp_buf_cache, DMA_TO_DEVICE);
 
 free_rsp_cache:
-       kmem_cache_destroy(ch->rsp_buf_cache);
+       srpt_cache_put(ch->rsp_buf_cache);
 
 free_ch:
        if (rdma_cm_id)
@@ -3055,7 +3112,7 @@ static void srpt_free_srq(struct srpt_device *sdev)
        srpt_free_ioctx_ring((struct srpt_ioctx **)sdev->ioctx_ring, sdev,
                             sdev->srq_size, sdev->req_buf_cache,
                             DMA_FROM_DEVICE);
-       kmem_cache_destroy(sdev->req_buf_cache);
+       srpt_cache_put(sdev->req_buf_cache);
        sdev->srq = NULL;
 }
 
@@ -3082,8 +3139,7 @@ static int srpt_alloc_srq(struct srpt_device *sdev)
        pr_debug("create SRQ #wr= %d max_allow=%d dev= %s\n", sdev->srq_size,
                 sdev->device->attrs.max_srq_wr, dev_name(&device->dev));
 
-       sdev->req_buf_cache = kmem_cache_create("srpt-srq-req-buf",
-                                               srp_max_req_size, 0, 0, NULL);
+       sdev->req_buf_cache = srpt_cache_get(srp_max_req_size);
        if (!sdev->req_buf_cache)
                goto free_srq;
 
@@ -3105,7 +3161,7 @@ static int srpt_alloc_srq(struct srpt_device *sdev)
        return 0;
 
 free_cache:
-       kmem_cache_destroy(sdev->req_buf_cache);
+       srpt_cache_put(sdev->req_buf_cache);
 
 free_srq:
        ib_destroy_srq(srq);
index 47fac29cf7c3b3d2a1da40c7f5672c73aa3c84d5..c51858f1cdc556939c2ee1bd21669c71c169d84e 100644 (file)
@@ -119,12 +119,12 @@ static void input_pass_values(struct input_dev *dev,
 
        handle = rcu_dereference(dev->grab);
        if (handle) {
-               count = handle->handler->events(handle, vals, count);
+               count = handle->handle_events(handle, vals, count);
        } else {
                list_for_each_entry_rcu(handle, &dev->h_list, d_node)
                        if (handle->open) {
-                               count = handle->handler->events(handle, vals,
-                                                               count);
+                               count = handle->handle_events(handle, vals,
+                                                             count);
                                if (!count)
                                        break;
                        }
@@ -2534,57 +2534,6 @@ static int input_handler_check_methods(const struct input_handler *handler)
        return 0;
 }
 
-/*
- * An implementation of input_handler's events() method that simply
- * invokes handler->event() method for each event one by one.
- */
-static unsigned int input_handler_events_default(struct input_handle *handle,
-                                                struct input_value *vals,
-                                                unsigned int count)
-{
-       struct input_handler *handler = handle->handler;
-       struct input_value *v;
-
-       for (v = vals; v != vals + count; v++)
-               handler->event(handle, v->type, v->code, v->value);
-
-       return count;
-}
-
-/*
- * An implementation of input_handler's events() method that invokes
- * handler->filter() method for each event one by one and removes events
- * that were filtered out from the "vals" array.
- */
-static unsigned int input_handler_events_filter(struct input_handle *handle,
-                                               struct input_value *vals,
-                                               unsigned int count)
-{
-       struct input_handler *handler = handle->handler;
-       struct input_value *end = vals;
-       struct input_value *v;
-
-       for (v = vals; v != vals + count; v++) {
-               if (handler->filter(handle, v->type, v->code, v->value))
-                       continue;
-               if (end != v)
-                       *end = *v;
-               end++;
-       }
-
-       return end - vals;
-}
-
-/*
- * An implementation of input_handler's events() method that does nothing.
- */
-static unsigned int input_handler_events_null(struct input_handle *handle,
-                                             struct input_value *vals,
-                                             unsigned int count)
-{
-       return count;
-}
-
 /**
  * input_register_handler - register a new input handler
  * @handler: handler to be registered
@@ -2604,13 +2553,6 @@ int input_register_handler(struct input_handler *handler)
 
        INIT_LIST_HEAD(&handler->h_list);
 
-       if (handler->filter)
-               handler->events = input_handler_events_filter;
-       else if (handler->event)
-               handler->events = input_handler_events_default;
-       else if (!handler->events)
-               handler->events = input_handler_events_null;
-
        error = mutex_lock_interruptible(&input_mutex);
        if (error)
                return error;
@@ -2684,6 +2626,75 @@ int input_handler_for_each_handle(struct input_handler *handler, void *data,
 }
 EXPORT_SYMBOL(input_handler_for_each_handle);
 
+/*
+ * An implementation of input_handle's handle_events() method that simply
+ * invokes handler->event() method for each event one by one.
+ */
+static unsigned int input_handle_events_default(struct input_handle *handle,
+                                               struct input_value *vals,
+                                               unsigned int count)
+{
+       struct input_handler *handler = handle->handler;
+       struct input_value *v;
+
+       for (v = vals; v != vals + count; v++)
+               handler->event(handle, v->type, v->code, v->value);
+
+       return count;
+}
+
+/*
+ * An implementation of input_handle's handle_events() method that invokes
+ * handler->filter() method for each event one by one and removes events
+ * that were filtered out from the "vals" array.
+ */
+static unsigned int input_handle_events_filter(struct input_handle *handle,
+                                              struct input_value *vals,
+                                              unsigned int count)
+{
+       struct input_handler *handler = handle->handler;
+       struct input_value *end = vals;
+       struct input_value *v;
+
+       for (v = vals; v != vals + count; v++) {
+               if (handler->filter(handle, v->type, v->code, v->value))
+                       continue;
+               if (end != v)
+                       *end = *v;
+               end++;
+       }
+
+       return end - vals;
+}
+
+/*
+ * An implementation of input_handle's handle_events() method that does nothing.
+ */
+static unsigned int input_handle_events_null(struct input_handle *handle,
+                                            struct input_value *vals,
+                                            unsigned int count)
+{
+       return count;
+}
+
+/*
+ * Sets up appropriate handle->event_handler based on the input_handler
+ * associated with the handle.
+ */
+static void input_handle_setup_event_handler(struct input_handle *handle)
+{
+       struct input_handler *handler = handle->handler;
+
+       if (handler->filter)
+               handle->handle_events = input_handle_events_filter;
+       else if (handler->event)
+               handle->handle_events = input_handle_events_default;
+       else if (handler->events)
+               handle->handle_events = handler->events;
+       else
+               handle->handle_events = input_handle_events_null;
+}
+
 /**
  * input_register_handle - register a new input handle
  * @handle: handle to register
@@ -2701,6 +2712,7 @@ int input_register_handle(struct input_handle *handle)
        struct input_dev *dev = handle->dev;
        int error;
 
+       input_handle_setup_event_handler(handle);
        /*
         * We take dev->mutex here to prevent race with
         * input_release_device().
index 5c775ca886a581ef1a5a0c82b5ea1d46353d5df8..c248c15b849d08255f4fe30ce9dca7f61d7a40f4 100644 (file)
@@ -15,7 +15,7 @@
  *     - Add interrupt support
  */
 
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include <linux/bits.h>
 #include <linux/delay.h>
 #include <linux/i2c.h>
index 02713e624df1cfe72a1171daecc19cb1bf105c8a..ff44f9978b719ede474049229c4183bc995a316b 100644 (file)
@@ -11,7 +11,7 @@
 #include <linux/platform_device.h>
 #include <linux/property.h>
 
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 struct adc_joystick_axis {
        u32 code;
index 84b87526b7ba319d98494c53a06364e5369f4d23..55e6321adab9d6911867cc292066177bf4b74792 100644 (file)
@@ -6,7 +6,7 @@
  *  USB/RS232 I-Force joysticks and wheels.
  */
 
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include "iforce.h"
 
 MODULE_AUTHOR("Vojtech Pavlik <[email protected]>, Johann Deneux <[email protected]>");
index 763642c8cee9f538415524e48411c7da33a91f65..08c889a72f6c6711c80c18839d3647ee3bf6ac8c 100644 (file)
@@ -6,7 +6,7 @@
  *  USB/RS232 I-Force joysticks and wheels.
  */
 
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include "iforce.h"
 
 static struct {
index 49101f1c858b4d47c589f12ee64f39e3e2f787cf..4f2221001a95ab768795ced34dfabd06e26be643 100644 (file)
@@ -16,7 +16,7 @@
 #include <linux/module.h>
 #include <linux/input.h>
 #include <linux/serio.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #define DRIVER_DESC    "SpaceTec SpaceBall 2003/3003/4000 FLX driver"
 
index 4eda18f4f46e39e9279254179cf0754329f6a7ce..22ea58bf76cb5ca82eaa55f179f2c5501f5a84d6 100644 (file)
@@ -218,6 +218,7 @@ static const struct xpad_device {
        { 0x0c12, 0x8810, "Zeroplus Xbox Controller", 0, XTYPE_XBOX },
        { 0x0c12, 0x9902, "HAMA VibraX - *FAULTY HARDWARE*", 0, XTYPE_XBOX },
        { 0x0d2f, 0x0002, "Andamiro Pump It Up pad", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX },
+       { 0x0db0, 0x1901, "Micro Star International Xbox360 Controller for Windows", 0, XTYPE_XBOX360 },
        { 0x0e4c, 0x1097, "Radica Gamester Controller", 0, XTYPE_XBOX },
        { 0x0e4c, 0x1103, "Radica Gamester Reflex", MAP_TRIGGERS_TO_BUTTONS, XTYPE_XBOX },
        { 0x0e4c, 0x2390, "Radica Games Jtech Controller", 0, XTYPE_XBOX },
@@ -373,6 +374,7 @@ static const struct xpad_device {
        { 0x294b, 0x3404, "Snakebyte GAMEPAD RGB X", 0, XTYPE_XBOXONE },
        { 0x2dc8, 0x2000, "8BitDo Pro 2 Wired Controller fox Xbox", 0, XTYPE_XBOXONE },
        { 0x2dc8, 0x3106, "8BitDo Pro 2 Wired Controller", 0, XTYPE_XBOX360 },
+       { 0x2dc8, 0x310a, "8BitDo Ultimate 2C Wireless Controller", 0, XTYPE_XBOX360 },
        { 0x2e24, 0x0652, "Hyperkin Duke X-Box One pad", 0, XTYPE_XBOXONE },
        { 0x31e3, 0x1100, "Wooting One", 0, XTYPE_XBOX360 },
        { 0x31e3, 0x1200, "Wooting Two", 0, XTYPE_XBOX360 },
@@ -492,6 +494,7 @@ static const struct usb_device_id xpad_table[] = {
        XPAD_XBOX360_VENDOR(0x07ff),            /* Mad Catz Gamepad */
        XPAD_XBOXONE_VENDOR(0x0b05),            /* ASUS controllers */
        XPAD_XBOX360_VENDOR(0x0c12),            /* Zeroplus X-Box 360 controllers */
+       XPAD_XBOX360_VENDOR(0x0db0),            /* Micro Star International X-Box 360 controllers */
        XPAD_XBOX360_VENDOR(0x0e6f),            /* 0x0e6f Xbox 360 controllers */
        XPAD_XBOXONE_VENDOR(0x0e6f),            /* 0x0e6f Xbox One controllers */
        XPAD_XBOX360_VENDOR(0x0f0d),            /* Hori controllers */
index d25d63a807f230a6b783a9364fc37dd0d71c8204..dc734974ce0687a6e850242b531979be8395b394 100644 (file)
@@ -822,7 +822,8 @@ static int adp5588_suspend(struct device *dev)
 {
        struct i2c_client *client = to_i2c_client(dev);
 
-       disable_irq(client->irq);
+       if (client->irq)
+               disable_irq(client->irq);
 
        return 0;
 }
@@ -831,7 +832,8 @@ static int adp5588_resume(struct device *dev)
 {
        struct i2c_client *client = to_i2c_client(dev);
 
-       enable_irq(client->irq);
+       if (client->irq)
+               enable_irq(client->irq);
 
        return 0;
 }
index 8996e00cd63a8203ec53d46ccb922c21ddb47355..922d3ab998f3a5dfbaf277f10eb19e5cd1b35415 100644 (file)
@@ -391,10 +391,17 @@ static int adp5589_gpio_get_value(struct gpio_chip *chip, unsigned off)
        struct adp5589_kpad *kpad = gpiochip_get_data(chip);
        unsigned int bank = kpad->var->bank(kpad->gpiomap[off]);
        unsigned int bit = kpad->var->bit(kpad->gpiomap[off]);
+       int val;
 
-       return !!(adp5589_read(kpad->client,
-                              kpad->var->reg(ADP5589_GPI_STATUS_A) + bank) &
-                              bit);
+       mutex_lock(&kpad->gpio_lock);
+       if (kpad->dir[bank] & bit)
+               val = kpad->dat_out[bank];
+       else
+               val = adp5589_read(kpad->client,
+                                  kpad->var->reg(ADP5589_GPI_STATUS_A) + bank);
+       mutex_unlock(&kpad->gpio_lock);
+
+       return !!(val & bit);
 }
 
 static void adp5589_gpio_set_value(struct gpio_chip *chip,
@@ -936,10 +943,9 @@ static int adp5589_keypad_add(struct adp5589_kpad *kpad, unsigned int revid)
 
 static void adp5589_clear_config(void *data)
 {
-       struct i2c_client *client = data;
-       struct adp5589_kpad *kpad = i2c_get_clientdata(client);
+       struct adp5589_kpad *kpad = data;
 
-       adp5589_write(client, kpad->var->reg(ADP5589_GENERAL_CFG), 0);
+       adp5589_write(kpad->client, kpad->var->reg(ADP5589_GENERAL_CFG), 0);
 }
 
 static int adp5589_probe(struct i2c_client *client)
@@ -983,7 +989,7 @@ static int adp5589_probe(struct i2c_client *client)
        }
 
        error = devm_add_action_or_reset(&client->dev, adp5589_clear_config,
-                                        client);
+                                        kpad);
        if (error)
                return error;
 
@@ -1010,8 +1016,6 @@ static int adp5589_probe(struct i2c_client *client)
        if (error)
                return error;
 
-       i2c_set_clientdata(client, kpad);
-
        dev_info(&client->dev, "Rev.%d keypad, irq %d\n", revid, client->irq);
        return 0;
 }
index 707c5a8ae7367610bf829de99cbbe3ac88059894..2c993fa8306a080490b658a95bed6427da294a53 100644 (file)
@@ -57,7 +57,7 @@
 #include <linux/workqueue.h>
 
 #include <asm/barrier.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #define CREATE_TRACE_POINTS
 #include "applespi.h"
index 12eb9df180ee4adcf78e48422ca2ad040fb4e0a2..4c81b20ff6af94bdd2edab1cd476ac5bcf10f3a5 100644 (file)
@@ -27,7 +27,7 @@
 #include <linux/platform_data/cros_ec_commands.h>
 #include <linux/platform_data/cros_ec_proto.h>
 
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 /**
  * struct cros_ec_keyb - Structure representing EC keyboard device
index 058f3470b7ae2b7d6cdb71065910bd9ffad84fdc..4215f9b9c2b07a85fb2ce6c374afdccbca52d768 100644 (file)
@@ -17,7 +17,7 @@
 #include <linux/types.h>
 #include <linux/usb/input.h>
 #include <linux/usb/cdc.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #define IMS_PCU_KEYMAP_LEN             32
 
index 9ca5a743f19feb1cd3f466299af1b8861a3f9374..be80a31de9f8f43929d29b9f59e6d7b166a45aa1 100644 (file)
@@ -20,7 +20,7 @@
 #include <linux/module.h>
 #include <linux/property.h>
 #include <linux/slab.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #define IQS7222_PROD_NUM                       0x00
 #define IQS7222_PROD_NUM_A                     840
index 8a27a20d04b01a9599cc14098b2f3084af22e0d9..833b643f06164920eda67705356e7c9321ac512b 100644 (file)
@@ -69,18 +69,6 @@ config MOUSE_PS2_LOGIPS2PP
 
          If unsure, say Y.
 
-config MOUSE_PS2_PIXART
-       bool "PixArt PS/2 touchpad protocol extension" if EXPERT
-       default y
-       depends on MOUSE_PS2
-       help
-         This driver supports the PixArt PS/2 touchpad found in some
-         laptops.
-         Say Y here if you have a PixArt PS/2 TouchPad connected to
-         your system.
-
-         If unsure, say Y.
-
 config MOUSE_PS2_SYNAPTICS
        bool "Synaptics PS/2 mouse protocol extension" if EXPERT
        default y
index 56302955152915e4cf9edfe96236fd811b3e2269..a1336d5bee6f33dd1733b66e77d6229134f14fdb 100644 (file)
@@ -32,7 +32,6 @@ psmouse-$(CONFIG_MOUSE_PS2_ELANTECH)  += elantech.o
 psmouse-$(CONFIG_MOUSE_PS2_OLPC)       += hgpk.o
 psmouse-$(CONFIG_MOUSE_PS2_LOGIPS2PP)  += logips2pp.o
 psmouse-$(CONFIG_MOUSE_PS2_LIFEBOOK)   += lifebook.o
-psmouse-$(CONFIG_MOUSE_PS2_PIXART)     += pixart_ps2.o
 psmouse-$(CONFIG_MOUSE_PS2_SENTELIC)   += sentelic.o
 psmouse-$(CONFIG_MOUSE_PS2_TRACKPOINT) += trackpoint.o
 psmouse-$(CONFIG_MOUSE_PS2_TOUCHKIT)   += touchkit_ps2.o
index 60c83bc71d84e662d15af2654c54ba2cb39e4147..fc3fb954523b7c75e66ee72a6d7d68d0977a21d4 100644 (file)
@@ -20,7 +20,7 @@
 #include <linux/input/mt.h>
 #include <linux/module.h>
 #include <linux/slab.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include "cyapa.h"
 
 
index 2e6bcb07257ed7374ac69e288d21fc4133cddb85..3b4439f106356377fe8f4c532ace0aedc0074574 100644 (file)
@@ -17,7 +17,7 @@
 #include <linux/mutex.h>
 #include <linux/completion.h>
 #include <linux/slab.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include <linux/crc-itu-t.h>
 #include <linux/pm_runtime.h>
 #include "cyapa.h"
index 4ffe08fee10c8a465cb3e4042de08b335ffa6f0b..570c06dcef7898f98e7e2dcb728e80c5f0c6a7a6 100644 (file)
@@ -17,7 +17,7 @@
 #include <linux/mutex.h>
 #include <linux/completion.h>
 #include <linux/slab.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include <linux/crc-itu-t.h>
 #include "cyapa.h"
 
index ce96513b34f64f2865abcc5549b4aaac40f55d7f..7521981274bd8ce5a0c1e91d1ec3ed12a1c01df3 100644 (file)
@@ -36,7 +36,7 @@
 #include <linux/pm_wakeirq.h>
 #include <linux/property.h>
 #include <linux/regulator/consumer.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #include "elan_i2c.h"
 
index 13dc097eb6c652983399c1fbefea7475a4ea0ff2..15cf4463b64ea430ff4a4a1aceac59544510cbc8 100644 (file)
@@ -21,7 +21,7 @@
 #include <linux/kernel.h>
 #include <linux/slab.h>
 #include <linux/sched.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #include "elan_i2c.h"
 
index b4723ea395eb9f40e7d272bd97704f6bf7db6652..79ad98cc1e799c5acf7212c2d952d766f6a0a1a2 100644 (file)
@@ -17,7 +17,7 @@
 #include <linux/platform_device.h>
 #include <linux/serio.h>
 #include <linux/libps2.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include "psmouse.h"
 #include "elantech.h"
 #include "elan_i2c.h"
diff --git a/drivers/input/mouse/pixart_ps2.c b/drivers/input/mouse/pixart_ps2.c
deleted file mode 100644 (file)
index 1993fc7..0000000
+++ /dev/null
@@ -1,300 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-or-later
-/*
- * Pixart Touchpad Controller 1336U PS2 driver
- *
- * Author: Jon Xie <[email protected]>
- *         Jay Lee <[email protected]>
- * Further cleanup and restructuring by:
- *         Binbin Zhou <[email protected]>
- *
- * Copyright (C) 2021-2024 Pixart Imaging.
- * Copyright (C) 2024 Loongson Technology Corporation Limited.
- *
- */
-
-#include <linux/bitfield.h>
-#include <linux/delay.h>
-#include <linux/device.h>
-#include <linux/input.h>
-#include <linux/input/mt.h>
-#include <linux/libps2.h>
-#include <linux/serio.h>
-#include <linux/slab.h>
-
-#include "pixart_ps2.h"
-
-static int pixart_read_tp_mode(struct ps2dev *ps2dev, u8 *mode)
-{
-       int error;
-       u8 param[1] = { 0 };
-
-       error = ps2_command(ps2dev, param, PIXART_CMD_REPORT_FORMAT);
-       if (error)
-               return error;
-
-       *mode = param[0] == 1 ? PIXART_MODE_ABS : PIXART_MODE_REL;
-
-       return 0;
-}
-
-static int pixart_read_tp_type(struct ps2dev *ps2dev, u8 *type)
-{
-       int error;
-       u8 param[3] = { 0 };
-
-       param[0] = 0x0a;
-       error = ps2_command(ps2dev, param, PSMOUSE_CMD_SETRATE);
-       if (error)
-               return error;
-
-       param[0] = 0x0;
-       error = ps2_command(ps2dev, param, PSMOUSE_CMD_SETRES);
-       if (error)
-               return error;
-
-       error = ps2_command(ps2dev, param, PSMOUSE_CMD_SETRES);
-       if (error)
-               return error;
-
-       error = ps2_command(ps2dev, param, PSMOUSE_CMD_SETRES);
-       if (error)
-               return error;
-
-       param[0] = 0x03;
-       error = ps2_command(ps2dev, param, PSMOUSE_CMD_SETRES);
-       if (error)
-               return error;
-
-       error = ps2_command(ps2dev, param, PSMOUSE_CMD_GETINFO);
-       if (error)
-               return error;
-
-       *type = param[0] == 0x0e ? PIXART_TYPE_TOUCHPAD : PIXART_TYPE_CLICKPAD;
-
-       return 0;
-}
-
-static void pixart_reset(struct psmouse *psmouse)
-{
-       ps2_command(&psmouse->ps2dev, NULL, PSMOUSE_CMD_RESET_DIS);
-
-       /* according to PixArt, 100ms is required for the upcoming reset */
-       msleep(100);
-       psmouse_reset(psmouse);
-}
-
-static void pixart_process_packet(struct psmouse *psmouse)
-{
-       struct pixart_data *priv = psmouse->private;
-       struct input_dev *dev = psmouse->dev;
-       const u8 *pkt = psmouse->packet;
-       unsigned int contact_cnt = FIELD_GET(CONTACT_CNT_MASK, pkt[0]);
-       unsigned int i, id, abs_x, abs_y;
-       bool tip;
-
-       for (i = 0; i < contact_cnt; i++) {
-               const u8 *p = &pkt[i * 3];
-
-               id = FIELD_GET(SLOT_ID_MASK, p[3]);
-               abs_y = FIELD_GET(ABS_Y_MASK, p[3]) << 8 | p[1];
-               abs_x = FIELD_GET(ABS_X_MASK, p[3]) << 8 | p[2];
-
-               if (i == PIXART_MAX_FINGERS - 1)
-                       tip = pkt[14] & BIT(1);
-               else
-                       tip = pkt[3 * contact_cnt + 1] & BIT(2 * i + 1);
-
-               input_mt_slot(dev, id);
-               if (input_mt_report_slot_state(dev, MT_TOOL_FINGER, tip)) {
-                       input_report_abs(dev, ABS_MT_POSITION_Y, abs_y);
-                       input_report_abs(dev, ABS_MT_POSITION_X, abs_x);
-               }
-       }
-
-       input_mt_sync_frame(dev);
-
-       if (priv->type == PIXART_TYPE_CLICKPAD) {
-               input_report_key(dev, BTN_LEFT, pkt[0] & 0x03);
-       } else {
-               input_report_key(dev, BTN_LEFT, pkt[0] & BIT(0));
-               input_report_key(dev, BTN_RIGHT, pkt[0] & BIT(1));
-       }
-
-       input_sync(dev);
-}
-
-static psmouse_ret_t pixart_protocol_handler(struct psmouse *psmouse)
-{
-       u8 *pkt = psmouse->packet;
-       u8 contact_cnt;
-
-       if ((pkt[0] & 0x8c) != 0x80)
-               return PSMOUSE_BAD_DATA;
-
-       contact_cnt = FIELD_GET(CONTACT_CNT_MASK, pkt[0]);
-       if (contact_cnt > PIXART_MAX_FINGERS)
-               return PSMOUSE_BAD_DATA;
-
-       if (contact_cnt == PIXART_MAX_FINGERS &&
-           psmouse->pktcnt < psmouse->pktsize) {
-               return PSMOUSE_GOOD_DATA;
-       }
-
-       if (contact_cnt == 0 && psmouse->pktcnt < 5)
-               return PSMOUSE_GOOD_DATA;
-
-       if (psmouse->pktcnt < 3 * contact_cnt + 2)
-               return PSMOUSE_GOOD_DATA;
-
-       pixart_process_packet(psmouse);
-
-       return PSMOUSE_FULL_PACKET;
-}
-
-static void pixart_disconnect(struct psmouse *psmouse)
-{
-       pixart_reset(psmouse);
-       kfree(psmouse->private);
-       psmouse->private = NULL;
-}
-
-static int pixart_reconnect(struct psmouse *psmouse)
-{
-       struct ps2dev *ps2dev = &psmouse->ps2dev;
-       u8 mode;
-       int error;
-
-       pixart_reset(psmouse);
-
-       error = pixart_read_tp_mode(ps2dev, &mode);
-       if (error)
-               return error;
-
-       if (mode != PIXART_MODE_ABS)
-               return -EIO;
-
-       error = ps2_command(ps2dev, NULL, PIXART_CMD_SWITCH_PROTO);
-       if (error)
-               return error;
-
-       return 0;
-}
-
-static int pixart_set_input_params(struct input_dev *dev,
-                                  struct pixart_data *priv)
-{
-       /* No relative support */
-       __clear_bit(EV_REL, dev->evbit);
-       __clear_bit(REL_X, dev->relbit);
-       __clear_bit(REL_Y, dev->relbit);
-       __clear_bit(BTN_MIDDLE, dev->keybit);
-
-       /* Buttons */
-       __set_bit(EV_KEY, dev->evbit);
-       __set_bit(BTN_LEFT, dev->keybit);
-       if (priv->type == PIXART_TYPE_CLICKPAD)
-               __set_bit(INPUT_PROP_BUTTONPAD, dev->propbit);
-       else
-               __set_bit(BTN_RIGHT, dev->keybit);
-
-       /* Absolute position */
-       input_set_abs_params(dev, ABS_X, 0, PIXART_PAD_WIDTH, 0, 0);
-       input_set_abs_params(dev, ABS_Y, 0, PIXART_PAD_HEIGHT, 0, 0);
-
-       input_set_abs_params(dev, ABS_MT_POSITION_X,
-                            0, PIXART_PAD_WIDTH, 0, 0);
-       input_set_abs_params(dev, ABS_MT_POSITION_Y,
-                            0, PIXART_PAD_HEIGHT, 0, 0);
-
-       return input_mt_init_slots(dev, PIXART_MAX_FINGERS, INPUT_MT_POINTER);
-}
-
-static int pixart_query_hardware(struct ps2dev *ps2dev, u8 *mode, u8 *type)
-{
-       int error;
-
-       error = pixart_read_tp_type(ps2dev, type);
-       if (error)
-               return error;
-
-       error = pixart_read_tp_mode(ps2dev, mode);
-       if (error)
-               return error;
-
-       return 0;
-}
-
-int pixart_detect(struct psmouse *psmouse, bool set_properties)
-{
-       u8 type;
-       int error;
-
-       pixart_reset(psmouse);
-
-       error = pixart_read_tp_type(&psmouse->ps2dev, &type);
-       if (error)
-               return error;
-
-       if (set_properties) {
-               psmouse->vendor = "PixArt";
-               psmouse->name = (type == PIXART_TYPE_TOUCHPAD) ?
-                               "touchpad" : "clickpad";
-       }
-
-       return 0;
-}
-
-int pixart_init(struct psmouse *psmouse)
-{
-       int error;
-       struct pixart_data *priv;
-
-       priv = kzalloc(sizeof(*priv), GFP_KERNEL);
-       if (!priv)
-               return -ENOMEM;
-
-       psmouse->private = priv;
-       pixart_reset(psmouse);
-
-       error = pixart_query_hardware(&psmouse->ps2dev,
-                                     &priv->mode, &priv->type);
-       if (error) {
-               psmouse_err(psmouse, "init: Unable to query PixArt touchpad hardware.\n");
-               goto err_exit;
-       }
-
-       /* Relative mode follows standard PS/2 mouse protocol */
-       if (priv->mode != PIXART_MODE_ABS) {
-               error = -EIO;
-               goto err_exit;
-       }
-
-       /* Set absolute mode */
-       error = ps2_command(&psmouse->ps2dev, NULL, PIXART_CMD_SWITCH_PROTO);
-       if (error) {
-               psmouse_err(psmouse, "init: Unable to initialize PixArt absolute mode.\n");
-               goto err_exit;
-       }
-
-       error = pixart_set_input_params(psmouse->dev, priv);
-       if (error) {
-               psmouse_err(psmouse, "init: Unable to set input params.\n");
-               goto err_exit;
-       }
-
-       psmouse->pktsize = 15;
-       psmouse->protocol_handler = pixart_protocol_handler;
-       psmouse->disconnect = pixart_disconnect;
-       psmouse->reconnect = pixart_reconnect;
-       psmouse->cleanup = pixart_reset;
-       /* resync is not supported yet */
-       psmouse->resync_time = 0;
-
-       return 0;
-
-err_exit:
-       pixart_reset(psmouse);
-       kfree(priv);
-       psmouse->private = NULL;
-       return error;
-}
diff --git a/drivers/input/mouse/pixart_ps2.h b/drivers/input/mouse/pixart_ps2.h
deleted file mode 100644 (file)
index 47a1d04..0000000
+++ /dev/null
@@ -1,36 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-or-later */
-#ifndef _PIXART_PS2_H
-#define _PIXART_PS2_H
-
-#include "psmouse.h"
-
-#define PIXART_PAD_WIDTH               1023
-#define PIXART_PAD_HEIGHT              579
-#define PIXART_MAX_FINGERS             4
-
-#define PIXART_CMD_REPORT_FORMAT       0x01d8
-#define PIXART_CMD_SWITCH_PROTO                0x00de
-
-#define PIXART_MODE_REL                        0
-#define PIXART_MODE_ABS                        1
-
-#define PIXART_TYPE_CLICKPAD           0
-#define PIXART_TYPE_TOUCHPAD           1
-
-#define CONTACT_CNT_MASK               GENMASK(6, 4)
-
-#define SLOT_ID_MASK                   GENMASK(2, 0)
-#define ABS_Y_MASK                     GENMASK(5, 4)
-#define ABS_X_MASK                     GENMASK(7, 6)
-
-struct pixart_data {
-       u8 mode;
-       u8 type;
-       int x_max;
-       int y_max;
-};
-
-int pixart_detect(struct psmouse *psmouse, bool set_properties);
-int pixart_init(struct psmouse *psmouse);
-
-#endif  /* _PIXART_PS2_H */
index 5a4defe9cf325c0f32ba3adb2129475c373cc518..a2c9f7144864e4725e377c1ad904e7dc6f873e9b 100644 (file)
@@ -36,7 +36,6 @@
 #include "focaltech.h"
 #include "vmmouse.h"
 #include "byd.h"
-#include "pixart_ps2.h"
 
 #define DRIVER_DESC    "PS/2 mouse driver"
 
@@ -906,15 +905,6 @@ static const struct psmouse_protocol psmouse_protocols[] = {
                .detect         = byd_detect,
                .init           = byd_init,
        },
-#endif
-#ifdef CONFIG_MOUSE_PS2_PIXART
-       {
-               .type           = PSMOUSE_PIXART,
-               .name           = "PixArtPS/2",
-               .alias          = "pixart",
-               .detect         = pixart_detect,
-               .init           = pixart_init,
-       },
 #endif
        {
                .type           = PSMOUSE_AUTO,
@@ -1182,13 +1172,6 @@ static int psmouse_extensions(struct psmouse *psmouse,
                        return ret;
        }
 
-       /* Try PixArt touchpad */
-       if (max_proto > PSMOUSE_IMEX &&
-           psmouse_try_protocol(psmouse, PSMOUSE_PIXART, &max_proto,
-                                set_properties, true)) {
-               return PSMOUSE_PIXART;
-       }
-
        if (max_proto > PSMOUSE_IMEX) {
                if (psmouse_try_protocol(psmouse, PSMOUSE_GENPS,
                                         &max_proto, set_properties, true))
index 23f7fa7243cb599b52dd9494769a2b5dedfc81cb..4d8acfe0d82aa3017413628d5a8ba8f917ec080f 100644 (file)
@@ -69,7 +69,6 @@ enum psmouse_type {
        PSMOUSE_BYD,
        PSMOUSE_SYNAPTICS_SMBUS,
        PSMOUSE_ELANTECH_SMBUS,
-       PSMOUSE_PIXART,
        PSMOUSE_AUTO            /* This one should always be last */
 };
 
@@ -95,7 +94,7 @@ struct psmouse {
        const char *vendor;
        const char *name;
        const struct psmouse_protocol *protocol;
-       unsigned char packet[16];
+       unsigned char packet[8];
        unsigned char badbyte;
        unsigned char pktcnt;
        unsigned char pktsize;
index cc1d4b424640ea3902cf726329b69c01aa23c4ba..47be64284b25ede8103ada86d6b58fd3a26976bb 100644 (file)
@@ -9,7 +9,7 @@
 #include <linux/slab.h>
 #include <linux/uaccess.h>
 #include <linux/of.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include "rmi_driver.h"
 
 #define RMI_PRODUCT_ID_LENGTH    10
index 3b3ac71e53dc589e5c547ff4eec7cccd54564b8a..e2468bc04a5cb3cdb85cce2fe61a6208c10c31a7 100644 (file)
@@ -7,7 +7,7 @@
 #include <linux/kernel.h>
 #include <linux/rmi.h>
 #include <linux/firmware.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include <linux/bitops.h>
 
 #include "rmi_driver.h"
index 886557b01ebabf7fcb1a2e8e29050ea043d87074..fd49acc02071056b1c48a22c537afac55c2b12b2 100644 (file)
@@ -13,7 +13,7 @@
 #include <linux/delay.h>
 #include <linux/slab.h>
 #include <linux/jiffies.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #include "rmi_driver.h"
 #include "rmi_f34.h"
index 2d176fbab25119f887b449f54aa98aad3fa39293..2b3fbb0455d5cbcca0e97ce9a99b8e350bc778b3 100644 (file)
@@ -63,7 +63,7 @@
 #include <linux/module.h>
 #include <linux/usb/input.h>
 #include <linux/uaccess.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 /*
  * Aiptek status packet:
index 38d36d25f6f4656d4b72211a2982014827a62e68..794caa102909cb9c93b88bb0128ee81e59954ad7 100644 (file)
@@ -3,7 +3,7 @@
 #include <linux/slab.h>
 #include <linux/module.h>
 #include <linux/usb/input.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 /*
  * Pressure-threshold modules param code from Alex Perry <[email protected]>
index f89c0dd15d8b91a426e967f62122fb025fafa21c..607f18af70104dec7490fd76dcbbbcfd04297d71 100644 (file)
@@ -30,7 +30,7 @@
 #include <linux/spi/ads7846.h>
 #include <linux/regulator/consumer.h>
 #include <linux/module.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 /*
  * This code has been heavily tested on a Nokia 770, and lightly
index cfc92157701fe1ce7026c6d9ef3a1f975387c30e..3ddabc5a2c999b2ed14353fb391552248e86b8ad 100644 (file)
@@ -26,7 +26,7 @@
 #include <linux/slab.h>
 #include <linux/regulator/consumer.h>
 #include <linux/gpio/consumer.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include <media/v4l2-device.h>
 #include <media/v4l2-ioctl.h>
 #include <media/videobuf2-v4l2.h>
index c1b4fc28fa8d42e14173d2b64e41820169cff0a7..cde0e478950362c44baddbb90de286d077e23e3f 100644 (file)
@@ -8,7 +8,7 @@
  * Hans de Goede <[email protected]>
  */
 
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include <linux/acpi.h>
 #include <linux/crc32.h>
 #include <linux/delay.h>
index 567c9dcaac91eede1ada2326169f437b8735f5a7..2d4b6e34320303ce98591f5ce6a2554793b46898 100644 (file)
@@ -16,7 +16,7 @@
  * same.
  */
 
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/input.h>
index 3ca246ab192e403ab3f75116ebf559cc9788d8e1..eafe5a9b89648475ff7435566eb38c094d66a473 100644 (file)
@@ -21,7 +21,7 @@
 #include <linux/mod_devicetable.h>
 #include <linux/module.h>
 #include <linux/regmap.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #define CYTTSP5_NAME                           "cyttsp5"
 #define CY_I2C_DATA_SIZE                       (2 * 256)
index e70415f189a5566191717ac585dac2fbaa95afbf..85c6d8ce003f3a2b131c33ecaae47c23dc7b3313 100644 (file)
@@ -32,7 +32,7 @@
 #include <linux/slab.h>
 #include <linux/uaccess.h>
 
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #define WORK_REGISTER_THRESHOLD                0x00
 #define WORK_REGISTER_REPORT_RATE      0x08
@@ -1121,6 +1121,14 @@ static void edt_ft5x06_ts_set_regs(struct edt_ft5x06_ts_data *tsdata)
        }
 }
 
+static void edt_ft5x06_exit_regmap(void *arg)
+{
+       struct edt_ft5x06_ts_data *data = arg;
+
+       if (!IS_ERR_OR_NULL(data->regmap))
+               regmap_exit(data->regmap);
+}
+
 static void edt_ft5x06_disable_regulators(void *arg)
 {
        struct edt_ft5x06_ts_data *data = arg;
@@ -1154,6 +1162,16 @@ static int edt_ft5x06_ts_probe(struct i2c_client *client)
                return PTR_ERR(tsdata->regmap);
        }
 
+       /*
+        * We are not using devm_regmap_init_i2c() and instead install a
+        * custom action because we may replace regmap with M06-specific one
+        * and we need to make sure that it will not be released too early.
+        */
+       error = devm_add_action_or_reset(&client->dev, edt_ft5x06_exit_regmap,
+                                        tsdata);
+       if (error)
+               return error;
+
        chip_data = device_get_match_data(&client->dev);
        if (!chip_data)
                chip_data = (const struct edt_i2c_chip_data *)id->driver_data;
@@ -1347,7 +1365,6 @@ static void edt_ft5x06_ts_remove(struct i2c_client *client)
        struct edt_ft5x06_ts_data *tsdata = i2c_get_clientdata(client);
 
        edt_ft5x06_ts_teardown_debugfs(tsdata);
-       regmap_exit(tsdata->regmap);
 }
 
 static int edt_ft5x06_ts_suspend(struct device *dev)
index 48c69788b84af6b42652b4817ecec3284aec326d..87eb18977b71a0b0d6b66652e6fc010f84667ab0 100644 (file)
@@ -21,7 +21,7 @@
 #include <linux/gpio/consumer.h>
 #include <linux/of.h>
 #include <linux/slab.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 struct eeti_ts {
        struct i2c_client *client;
index 365765d40e627880df9753cc27771345ff31a790..3fd170f75b4a652c723eb000ca79e70c070dbe46 100644 (file)
@@ -40,7 +40,7 @@
 #include <linux/gpio/consumer.h>
 #include <linux/regulator/consumer.h>
 #include <linux/uuid.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 /* Device, Driver information */
 #define DEVICE_NAME    "elants_i2c"
index 2e77cfb63f32a1a6194510a04600ddbf6f21d740..fdda8412b1644369b90df0a620f6beb4f15bb49d 100644 (file)
@@ -22,7 +22,7 @@
 #include <linux/regulator/consumer.h>
 #include <linux/sizes.h>
 #include <linux/timer.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #define EXC3000_NUM_SLOTS              10
 #define EXC3000_SLOTS_PER_FRAME                5
index 435714f18c23a61ca8cf2fcedaf6d6889b1f76a5..a3e8a51c91449533b4d5185746df6b98676053dd 100644 (file)
@@ -22,7 +22,7 @@
 #include <linux/slab.h>
 #include <linux/acpi.h>
 #include <linux/of.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include "goodix.h"
 
 #define GOODIX_GPIO_INT_NAME           "irq"
index 0bfca897ce5af16c8b834ba6e3ce99959e5c9950..3fc03cf0ca23fdbe36028a6228030d3ffb8d3a09 100644 (file)
@@ -31,7 +31,7 @@
 #include <linux/regmap.h>
 #include <linux/regulator/consumer.h>
 #include <linux/sizes.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #include "goodix_berlin.h"
 
index a2d80e84391ba63cd2703de41ed8a0053763edd6..0662e87b86929ad9f06f0b865d55c8640bcfe9d5 100644 (file)
@@ -7,7 +7,7 @@
  *
  * Based on goodix_ts_berlin driver.
  */
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/regmap.h>
index 682abbbe5bd6337f13b8d96a40bee322f6b5fc07..a73369e15dda0b8ed900751c1662c1e8aa5a396a 100644 (file)
@@ -17,7 +17,7 @@
 #include <linux/input/mt.h>
 #include <linux/input/touchscreen.h>
 #include <linux/regulator/consumer.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #define HIDEEP_TS_NAME                 "HiDeep Touchscreen"
 #define HIDEEP_I2C_NAME                        "hideep_ts"
index 2e01d87977c168ff618220aceaa02da0a132e59a..b2ff7a45b908539b930e0ff62c95e7952763d501 100644 (file)
@@ -15,7 +15,7 @@
 #include <linux/regulator/consumer.h>
 #include <linux/regmap.h>
 
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #define HY46XX_CHKSUM_CODE             0x1
 #define HY46XX_FINGER_NUM              0x2
index f728348592827883ea05a1232c0b93ac650bb127..1d8ca90dcda695bc7bbd6f486db974ab7fb49530 100644 (file)
@@ -22,7 +22,7 @@
 #include <linux/mod_devicetable.h>
 #include <linux/module.h>
 #include <linux/property.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 /* Per chip data */
 struct hynitron_ts_chip_data {
index 4573844c3395a3815273364a8bff40a2be8bda7d..260c83dc23a2e293db560d859d92504dd1433d67 100644 (file)
@@ -12,7 +12,7 @@
 #include <linux/module.h>
 #include <linux/sizes.h>
 #include <linux/slab.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #define ILI2XXX_POLL_PERIOD    15
 
index 5569641f05f61b53ba645e55490b5b0154d39dd4..0dd632724a003f75eacce758bf84946a727c5861 100644 (file)
@@ -19,7 +19,7 @@
 #include <linux/errno.h>
 #include <linux/acpi.h>
 #include <linux/input/touchscreen.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 
 #define ILITEK_TS_NAME                                 "ilitek_ts"
index 4d226118f3cc2986efd2a8efce6484733c7dc206..4ebd7565ae6e8d21fb8720f0231323fea51ce71f 100644 (file)
@@ -26,7 +26,7 @@
 #include <linux/mod_devicetable.h>
 #include <linux/module.h>
 #include <linux/slab.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #define IQS5XX_FW_FILE_LEN     64
 #define IQS5XX_NUM_RETRIES     10
index f0a56cde899e48054d5aaf6ec3daef02104fa6c5..c5d447ee6f537355f68d76edffdd61b38fe5ad6b 100644 (file)
@@ -22,7 +22,7 @@
 #include <linux/of_device.h>
 #include <linux/property.h>
 #include <linux/slab.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #define IQS7211_PROD_NUM                       0x00
 
index b99a0e3c4084350900c3d2f05eb080d91599924b..a6946e3d8376d7e9b4c26f4194409e0ba78bb075 100644 (file)
@@ -18,7 +18,7 @@
 #include <linux/module.h>
 #include <linux/of.h>
 #include <linux/slab.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #define MIP4_DEVICE_NAME       "mip4_ts"
 
index 1a797e410a3faeb324869a1620946627fc7335ef..0afee41ac9de0e8806268a0a7b25be363213ee53 100644 (file)
@@ -15,7 +15,7 @@
 #include <linux/input/touchscreen.h>
 #include <linux/module.h>
 
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #define NVT_TS_TOUCH_START             0x00
 #define NVT_TS_TOUCH_SIZE              6
index 4ede0687beb096565a88bd60fe3e36b55e258f43..83bf27085ebc09e813515420c46c6dee2d616581 100644 (file)
@@ -5,7 +5,7 @@
  * Copyright (C) 2010-2011 Pixcir, Inc.
  */
 
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include <linux/delay.h>
 #include <linux/gpio/consumer.h>
 #include <linux/i2c.h>
index 92d75057de2d0c62db262f5424e4f9828ccd0846..f975b53e88252d8911b2bae1aa03bb15e951e5de 100644 (file)
@@ -24,7 +24,7 @@
 #include <linux/pm_wakeirq.h>
 #include <linux/regulator/consumer.h>
 #include <linux/slab.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 /* Slave I2C mode */
 #define RM_BOOT_BLDR           0x02
index a529217e748fbbdf59ab0ad9233679e6ea0b94d6..e1518a75a51b6a2f69eee245f396ff36f9ab3364 100644 (file)
@@ -4,7 +4,7 @@
 // Copyright (c) 2017 Samsung Electronics Co., Ltd.
 // Copyright (c) 2017 Andi Shyti <[email protected]>
 
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include <linux/delay.h>
 #include <linux/i2c.h>
 #include <linux/input/mt.h>
index 6a42b27c459901255de37acef43097607e686d65..5ccc96764742f33ede7b99935d8f092cba6741db 100644 (file)
@@ -24,7 +24,7 @@
 #include <linux/irq.h>
 #include <linux/regulator/consumer.h>
 
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #define SILEAD_TS_NAME         "silead_ts"
 
index 2023c6df416f293c1546d3e2219cefca93e41d8e..a625f2ad809d3bb9e7958f197fc79b15ada75bfc 100644 (file)
@@ -15,7 +15,7 @@
 #include <linux/gpio/consumer.h>
 #include <linux/module.h>
 #include <linux/slab.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #define SIS_I2C_NAME           "sis_i2c_ts"
 
index 7efbcd0fde4fc32021cefc9b3557e7c8ded25866..6074b7730e86211793c2555dff427205aef6d4d7 100644 (file)
@@ -18,7 +18,7 @@
 #include <linux/spi/spi.h>
 #include <linux/acpi.h>
 
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #define SURFACE3_PACKET_SIZE   264
 
index 486230985bf084e92308da9105a3a05968cde627..fd97a83f56649ee57a7cf5f9c2a83424b39c3447 100644 (file)
@@ -13,7 +13,7 @@
 #include <linux/slab.h>
 #include <linux/irq.h>
 #include <linux/interrupt.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 /* Bitmasks (for data[3]) */
 #define WACOM_TIP_SWITCH       BIT(0)
index 698fc7e0ee7f865a57418dad7fa27f3db8d055af..27941245e962f60d1039240d808ec9882f9e5718 100644 (file)
@@ -20,7 +20,7 @@
 #include <linux/firmware.h>
 #include <linux/input/mt.h>
 #include <linux/acpi.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #define WDT87XX_NAME           "wdt87xx_i2c"
 #define WDT87XX_FW_NAME                "wdt87xx_fw.bin"
index 27333fded9a957395fea573242f119c65fa99871..943634ba9cd972d00af463a2a7281c26ab5ca5ba 100644 (file)
@@ -11,7 +11,7 @@
 #include <linux/interrupt.h>
 #include <linux/module.h>
 #include <linux/regulator/consumer.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #define ZET6223_MAX_FINGERS            16
 #define ZET6223_MAX_PKT_SIZE           (3 + 4 * ZET6223_MAX_FINGERS)
index 4b8c4ebfff96d15257a958b99486b9b407b2c82c..df42fdf36ae3b0402dd9fd22a245036e5bd11380 100644 (file)
@@ -22,7 +22,7 @@
 #include <linux/property.h>
 #include <linux/regulator/consumer.h>
 #include <linux/slab.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #define WAIT_TIMEOUT           msecs_to_jiffies(1000)
 
index 52b3950460e21b74abfe0161e9198dc237271b18..716d6fa60f86440e3d0ee996523fad0dacb14bc8 100644 (file)
@@ -645,19 +645,29 @@ static int zinitix_ts_probe(struct i2c_client *client)
                return error;
        }
 
-       bt541->num_keycodes = device_property_count_u32(&client->dev, "linux,keycodes");
-       if (bt541->num_keycodes > ARRAY_SIZE(bt541->keycodes)) {
-               dev_err(&client->dev, "too many keys defined (%d)\n", bt541->num_keycodes);
-               return -EINVAL;
-       }
+       if (device_property_present(&client->dev, "linux,keycodes")) {
+               bt541->num_keycodes = device_property_count_u32(&client->dev,
+                                                               "linux,keycodes");
+               if (bt541->num_keycodes < 0) {
+                       dev_err(&client->dev, "Failed to count keys (%d)\n",
+                               bt541->num_keycodes);
+                       return bt541->num_keycodes;
+               } else if (bt541->num_keycodes > ARRAY_SIZE(bt541->keycodes)) {
+                       dev_err(&client->dev, "Too many keys defined (%d)\n",
+                               bt541->num_keycodes);
+                       return -EINVAL;
+               }
 
-       error = device_property_read_u32_array(&client->dev, "linux,keycodes",
-                                              bt541->keycodes,
-                                              bt541->num_keycodes);
-       if (error) {
-               dev_err(&client->dev,
-                       "Unable to parse \"linux,keycodes\" property: %d\n", error);
-               return error;
+               error = device_property_read_u32_array(&client->dev,
+                                                      "linux,keycodes",
+                                                      bt541->keycodes,
+                                                      bt541->num_keycodes);
+               if (error) {
+                       dev_err(&client->dev,
+                               "Unable to parse \"linux,keycodes\" property: %d\n",
+                               error);
+                       return error;
+               }
        }
 
        error = zinitix_init_input_dev(bt541);
index 737c5b88235510e3ddb91a28cecbdcdc14854b32..353fea58cd318a93250fc31e56119d271edbfe60 100644 (file)
@@ -1420,7 +1420,7 @@ static int arm_smmu_alloc_cd_tables(struct arm_smmu_master *master)
                cd_table->s1fmt = STRTAB_STE_0_S1FMT_LINEAR;
                cd_table->linear.num_ents = max_contexts;
 
-               l1size = max_contexts * sizeof(struct arm_smmu_cd),
+               l1size = max_contexts * sizeof(struct arm_smmu_cd);
                cd_table->linear.table = dma_alloc_coherent(smmu->dev, l1size,
                                                            &cd_table->cdtab_dma,
                                                            GFP_KERNEL);
@@ -3625,7 +3625,7 @@ static int arm_smmu_init_strtab_2lvl(struct arm_smmu_device *smmu)
        u32 l1size;
        struct arm_smmu_strtab_cfg *cfg = &smmu->strtab_cfg;
        unsigned int last_sid_idx =
-               arm_smmu_strtab_l1_idx((1 << smmu->sid_bits) - 1);
+               arm_smmu_strtab_l1_idx((1ULL << smmu->sid_bits) - 1);
 
        /* Calculate the L1 size, capped to the SIDSIZE. */
        cfg->l2.num_l1_ents = min(last_sid_idx + 1, STRTAB_MAX_L1_ENTRIES);
index 9dc772f2cbb27c414fe1d83e91eb950fc5dcc82f..99030e6b16e7aaf752b19fb0bc5cf3d01ac75248 100644 (file)
@@ -130,7 +130,7 @@ int arm_mmu500_reset(struct arm_smmu_device *smmu)
 
        /*
         * Disable MMU-500's not-particularly-beneficial next-page
-        * prefetcher for the sake of errata #841119 and #826419.
+        * prefetcher for the sake of at least 5 known errata.
         */
        for (i = 0; i < smmu->num_context_banks; ++i) {
                reg = arm_smmu_cb_read(smmu, i, ARM_SMMU_CB_ACTLR);
@@ -138,7 +138,7 @@ int arm_mmu500_reset(struct arm_smmu_device *smmu)
                arm_smmu_cb_write(smmu, i, ARM_SMMU_CB_ACTLR, reg);
                reg = arm_smmu_cb_read(smmu, i, ARM_SMMU_CB_ACTLR);
                if (reg & ARM_MMU500_ACTLR_CPRE)
-                       dev_warn_once(smmu->dev, "Failed to disable prefetcher [errata #841119 and #826419], check ACR.CACHE_LOCK\n");
+                       dev_warn_once(smmu->dev, "Failed to disable prefetcher for errata workarounds, check SACR.CACHE_LOCK\n");
        }
 
        return 0;
index 9f6b0780f2ef5e7347d702b5337d99edbcc92292..e860bc9439a28358b04d11682c6a877af3b71d85 100644 (file)
@@ -3340,8 +3340,10 @@ static int domain_context_clear_one_cb(struct pci_dev *pdev, u16 alias, void *op
  */
 static void domain_context_clear(struct device_domain_info *info)
 {
-       if (!dev_is_pci(info->dev))
+       if (!dev_is_pci(info->dev)) {
                domain_context_clear_one(info, info->bus, info->devfn);
+               return;
+       }
 
        pci_for_each_dma_alias(to_pci_dev(info->dev),
                               &domain_context_clear_one_cb, info);
index 341cd9ca5a05e456d47d303671e4394acd166a36..d82bcab233a1b000b06944ae03c4f4c143260978 100644 (file)
@@ -45,13 +45,6 @@ config ARM_GIC_V3_ITS
        select IRQ_MSI_LIB
        default ARM_GIC_V3
 
-config ARM_GIC_V3_ITS_PCI
-       bool
-       depends on ARM_GIC_V3_ITS
-       depends on PCI
-       depends on PCI_MSI
-       default ARM_GIC_V3_ITS
-
 config ARM_GIC_V3_ITS_FSL_MC
        bool
        depends on ARM_GIC_V3_ITS
index fdec478ba5e70a772daee24c332d5bb1167fda00..52f625e07658cbc72d973b795a865c83130f8c88 100644 (file)
@@ -797,8 +797,8 @@ static struct its_vpe *its_build_vmapp_cmd(struct its_node *its,
        its_encode_valid(cmd, desc->its_vmapp_cmd.valid);
 
        if (!desc->its_vmapp_cmd.valid) {
+               alloc = !atomic_dec_return(&desc->its_vmapp_cmd.vpe->vmapp_count);
                if (is_v4_1(its)) {
-                       alloc = !atomic_dec_return(&desc->its_vmapp_cmd.vpe->vmapp_count);
                        its_encode_alloc(cmd, alloc);
                        /*
                         * Unmapping a VPE is self-synchronizing on GICv4.1,
@@ -817,13 +817,13 @@ static struct its_vpe *its_build_vmapp_cmd(struct its_node *its,
        its_encode_vpt_addr(cmd, vpt_addr);
        its_encode_vpt_size(cmd, LPI_NRBITS - 1);
 
+       alloc = !atomic_fetch_inc(&desc->its_vmapp_cmd.vpe->vmapp_count);
+
        if (!is_v4_1(its))
                goto out;
 
        vconf_addr = virt_to_phys(page_address(desc->its_vmapp_cmd.vpe->its_vm->vprop_page));
 
-       alloc = !atomic_fetch_inc(&desc->its_vmapp_cmd.vpe->vmapp_count);
-
        its_encode_alloc(cmd, alloc);
 
        /*
@@ -3806,6 +3806,23 @@ static int its_vpe_set_affinity(struct irq_data *d,
        struct cpumask *table_mask;
        unsigned long flags;
 
+       /*
+        * Check if we're racing against a VPE being destroyed, for
+        * which we don't want to allow a VMOVP.
+        */
+       if (!atomic_read(&vpe->vmapp_count)) {
+               if (gic_requires_eager_mapping())
+                       return -EINVAL;
+
+               /*
+                * If we lazily map the VPEs, this isn't an error and
+                * we can exit cleanly.
+                */
+               cpu = cpumask_first(mask_val);
+               irq_data_update_effective_affinity(d, cpumask_of(cpu));
+               return IRQ_SET_MASK_OK_DONE;
+       }
+
        /*
         * Changing affinity is mega expensive, so let's be as lazy as
         * we can and only do it if we really have to. Also, if mapped
@@ -4463,9 +4480,8 @@ static int its_vpe_init(struct its_vpe *vpe)
        raw_spin_lock_init(&vpe->vpe_lock);
        vpe->vpe_id = vpe_id;
        vpe->vpt_page = vpt_page;
-       if (gic_rdists->has_rvpeid)
-               atomic_set(&vpe->vmapp_count, 0);
-       else
+       atomic_set(&vpe->vmapp_count, 0);
+       if (!gic_rdists->has_rvpeid)
                vpe->vpe_proxy_event = -1;
 
        return 0;
index 4d0c3532dbe735239d971aece0444baa9eba55e8..3dc745b14cafaceaf40b44d6aef61a995c7637aa 100644 (file)
@@ -37,7 +37,7 @@ static struct chip_props ocelot_props = {
        .reg_off_ena_clr        = 0x1c,
        .reg_off_ena_set        = 0x20,
        .reg_off_ident          = 0x38,
-       .reg_off_trigger        = 0x5c,
+       .reg_off_trigger        = 0x4,
        .n_irq                  = 24,
 };
 
@@ -70,7 +70,7 @@ static struct chip_props jaguar2_props = {
        .reg_off_ena_clr        = 0x1c,
        .reg_off_ena_set        = 0x20,
        .reg_off_ident          = 0x38,
-       .reg_off_trigger        = 0x5c,
+       .reg_off_trigger        = 0x4,
        .n_irq                  = 29,
 };
 
@@ -84,6 +84,12 @@ static void ocelot_irq_unmask(struct irq_data *data)
        u32 val;
 
        irq_gc_lock(gc);
+       /*
+        * Clear sticky bits for edge mode interrupts.
+        * Serval has only one trigger register replication, but the adjacent
+        * register is always read as zero, so there's no need to handle this
+        * case separately.
+        */
        val = irq_reg_readl(gc, ICPU_CFG_INTR_INTR_TRIGGER(p, 0)) |
                irq_reg_readl(gc, ICPU_CFG_INTR_INTR_TRIGGER(p, 1));
        if (!(val & mask))
index 693ff285ca2c676da51b9d4a6de7decc34701fb7..99e27e01b0b19ff2a1526c958e2db2bd505be76a 100644 (file)
@@ -8,6 +8,7 @@
  */
 
 #include <linux/bitfield.h>
+#include <linux/cleanup.h>
 #include <linux/clk.h>
 #include <linux/err.h>
 #include <linux/io.h>
@@ -530,12 +531,12 @@ static int rzg2l_irqc_parse_interrupts(struct rzg2l_irqc_priv *priv,
 static int rzg2l_irqc_common_init(struct device_node *node, struct device_node *parent,
                                  const struct irq_chip *irq_chip)
 {
+       struct platform_device *pdev = of_find_device_by_node(node);
+       struct device *dev __free(put_device) = pdev ? &pdev->dev : NULL;
        struct irq_domain *irq_domain, *parent_domain;
-       struct platform_device *pdev;
        struct reset_control *resetn;
        int ret;
 
-       pdev = of_find_device_by_node(node);
        if (!pdev)
                return -ENODEV;
 
@@ -591,6 +592,17 @@ static int rzg2l_irqc_common_init(struct device_node *node, struct device_node *
 
        register_syscore_ops(&rzg2l_irqc_syscore_ops);
 
+       /*
+        * Prevent the cleanup function from invoking put_device by assigning
+        * NULL to dev.
+        *
+        * make coccicheck will complain about missing put_device calls, but
+        * those are false positives, as dev will be automatically "put" via
+        * __free_put_device on the failing path.
+        * On the successful path we don't actually want to "put" dev.
+        */
+       dev = NULL;
+
        return 0;
 
 pm_put:
index 64905e6f52d789fec2c9d5ca49854da7740dc4fd..c708780e8760f3445c89530ab8cb134adc874d2d 100644 (file)
@@ -341,7 +341,7 @@ int imsic_irqdomain_init(void)
                imsic->fwnode, global->hart_index_bits, global->guest_index_bits);
        pr_info("%pfwP: group-index-bits: %d, group-index-shift: %d\n",
                imsic->fwnode, global->group_index_bits, global->group_index_shift);
-       pr_info("%pfwP: per-CPU IDs %d at base PPN %pa\n",
+       pr_info("%pfwP: per-CPU IDs %d at base address %pa\n",
                imsic->fwnode, global->nr_ids, &global->base_addr);
        pr_info("%pfwP: total %d interrupts available\n",
                imsic->fwnode, num_possible_cpus() * (global->nr_ids - 1));
index 8c54113862205b4e50ed8a87da2e9ecd90107c10..f653c13de62b57acdae822fdbed41c881a72ceaa 100644 (file)
@@ -265,7 +265,7 @@ struct rintc_data {
 };
 
 static u32 nr_rintc;
-static struct rintc_data *rintc_acpi_data[NR_CPUS];
+static struct rintc_data **rintc_acpi_data;
 
 #define for_each_matching_plic(_plic_id)                               \
        unsigned int _plic;                                             \
@@ -329,13 +329,30 @@ int acpi_rintc_get_imsic_mmio_info(u32 index, struct resource *res)
        return 0;
 }
 
+static int __init riscv_intc_acpi_match(union acpi_subtable_headers *header,
+                                       const unsigned long end)
+{
+       return 0;
+}
+
 static int __init riscv_intc_acpi_init(union acpi_subtable_headers *header,
                                       const unsigned long end)
 {
        struct acpi_madt_rintc *rintc;
        struct fwnode_handle *fn;
+       int count;
        int rc;
 
+       if (!rintc_acpi_data) {
+               count = acpi_table_parse_madt(ACPI_MADT_TYPE_RINTC, riscv_intc_acpi_match, 0);
+               if (count <= 0)
+                       return -EINVAL;
+
+               rintc_acpi_data = kcalloc(count, sizeof(*rintc_acpi_data), GFP_KERNEL);
+               if (!rintc_acpi_data)
+                       return -ENOMEM;
+       }
+
        rintc = (struct acpi_madt_rintc *)header;
        rintc_acpi_data[nr_rintc] = kzalloc(sizeof(*rintc_acpi_data[0]), GFP_KERNEL);
        if (!rintc_acpi_data[nr_rintc])
index 2f6ef5c495bdaa4c34a76e1f9575c54a8eade95a..36dbcf2d728a546096f61dfe8e97fa2414b59db4 100644 (file)
@@ -126,16 +126,6 @@ static inline void plic_irq_toggle(const struct cpumask *mask,
        }
 }
 
-static void plic_irq_enable(struct irq_data *d)
-{
-       plic_irq_toggle(irq_data_get_effective_affinity_mask(d), d, 1);
-}
-
-static void plic_irq_disable(struct irq_data *d)
-{
-       plic_irq_toggle(irq_data_get_effective_affinity_mask(d), d, 0);
-}
-
 static void plic_irq_unmask(struct irq_data *d)
 {
        struct plic_priv *priv = irq_data_get_irq_chip_data(d);
@@ -150,6 +140,17 @@ static void plic_irq_mask(struct irq_data *d)
        writel(0, priv->regs + PRIORITY_BASE + d->hwirq * PRIORITY_PER_ID);
 }
 
+static void plic_irq_enable(struct irq_data *d)
+{
+       plic_irq_toggle(irq_data_get_effective_affinity_mask(d), d, 1);
+       plic_irq_unmask(d);
+}
+
+static void plic_irq_disable(struct irq_data *d)
+{
+       plic_irq_toggle(irq_data_get_effective_affinity_mask(d), d, 0);
+}
+
 static void plic_irq_eoi(struct irq_data *d)
 {
        struct plic_handler *handler = this_cpu_ptr(&plic_handlers);
@@ -626,8 +627,10 @@ static int plic_probe(struct fwnode_handle *fwnode)
 
                handler->enable_save = kcalloc(DIV_ROUND_UP(nr_irqs, 32),
                                               sizeof(*handler->enable_save), GFP_KERNEL);
-               if (!handler->enable_save)
+               if (!handler->enable_save) {
+                       error = -ENOMEM;
                        goto fail_cleanup_contexts;
+               }
 done:
                for (hwirq = 1; hwirq <= nr_irqs; hwirq++) {
                        plic_toggle(handler, hwirq, 0);
@@ -639,8 +642,10 @@ done:
 
        priv->irqdomain = irq_domain_create_linear(fwnode, nr_irqs + 1,
                                                   &plic_irqdomain_ops, priv);
-       if (WARN_ON(!priv->irqdomain))
+       if (WARN_ON(!priv->irqdomain)) {
+               error = -ENOMEM;
                goto fail_cleanup_contexts;
+       }
 
        /*
         * We can have multiple PLIC instances so setup global state
index 509b362d6465d3d0ddd61e93e7a46f804bdd35a6..044e4961376c6fbcb886f836f4616d62d5004448 100644 (file)
@@ -13,7 +13,7 @@
 #include <linux/delay.h>
 #include <linux/mISDNhw.h>
 #include <linux/slab.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include "ipac.h"
 
 
index 359ef00498b43a637b402354884db53285f68de8..10a0b5b45227ba715f5cb2d28d71943fe285c76d 100644 (file)
@@ -21,7 +21,7 @@
 #include <linux/regmap.h>
 #include <linux/util_macros.h>
 
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 enum {
        MT6370_LED_ISNK1 = 0,
index 2633bc254935cc49110c97f5e8a7eed223ee4292..126dd1cfba8efeaa600dd50bbdf48a2ac1529228 100644 (file)
@@ -19,7 +19,7 @@
 #include <asm/macints.h>
 #include <asm/mac_iop.h>
 #include <asm/adb_iop.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #include <linux/adb.h>
 
index 5228b03b6fe07006d07de7526d4190c3501a5be9..1ae2c71bb383b7724559b7304cf9b9b24bf6e23f 100644 (file)
@@ -28,7 +28,7 @@
 #include <linux/rbtree.h>
 #include <linux/ctype.h>
 #include <asm/page.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include <crypto/hash.h>
 #include <crypto/md5.h>
 #include <crypto/skcipher.h>
index 3a989efae1420a0f2e5b965b55555fe8a85a4037..13008b0892062e3aa95473e473ba2216b18af51b 100644 (file)
@@ -8,7 +8,7 @@
 
 #include "murmurhash3.h"
 
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 static inline u64 rotl64(u64 x, s8 r)
 {
index dc8c400b21d2601b61bcb194fff74f9ab2ae7b0e..f568dc59e6f18c9692b1401ced66ee43bc5577a0 100644 (file)
@@ -6,7 +6,7 @@
 #ifndef UDS_NUMERIC_H
 #define UDS_NUMERIC_H
 
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include <linux/kernel.h>
 #include <linux/types.h>
 
index 36e4ddfe2d158167b8cc50af1405762ed0b120ca..7d4d90b4395aee9d48d4a58af9efe94e5de30480 100644 (file)
 #define DM_VERITY_OPT_LOGGING          "ignore_corruption"
 #define DM_VERITY_OPT_RESTART          "restart_on_corruption"
 #define DM_VERITY_OPT_PANIC            "panic_on_corruption"
+#define DM_VERITY_OPT_ERROR_RESTART    "restart_on_error"
+#define DM_VERITY_OPT_ERROR_PANIC      "panic_on_error"
 #define DM_VERITY_OPT_IGN_ZEROES       "ignore_zero_blocks"
 #define DM_VERITY_OPT_AT_MOST_ONCE     "check_at_most_once"
 #define DM_VERITY_OPT_TASKLET_VERIFY   "try_verify_in_tasklet"
 
-#define DM_VERITY_OPTS_MAX             (4 + DM_VERITY_OPTS_FEC + \
+#define DM_VERITY_OPTS_MAX             (5 + DM_VERITY_OPTS_FEC + \
                                         DM_VERITY_ROOT_HASH_VERIFICATION_OPTS)
 
 static unsigned int dm_verity_prefetch_cluster = DM_VERITY_DEFAULT_PREFETCH_SIZE;
@@ -273,10 +275,8 @@ out:
        if (v->mode == DM_VERITY_MODE_LOGGING)
                return 0;
 
-       if (v->mode == DM_VERITY_MODE_RESTART) {
-               pr_emerg("dm-verity device corrupted\n");
-               emergency_restart();
-       }
+       if (v->mode == DM_VERITY_MODE_RESTART)
+               kernel_restart("dm-verity device corrupted");
 
        if (v->mode == DM_VERITY_MODE_PANIC)
                panic("dm-verity device corrupted");
@@ -585,6 +585,11 @@ static inline bool verity_is_system_shutting_down(void)
                || system_state == SYSTEM_RESTART;
 }
 
+static void restart_io_error(struct work_struct *w)
+{
+       kernel_restart("dm-verity device has I/O error");
+}
+
 /*
  * End one "io" structure with a given error.
  */
@@ -602,18 +607,18 @@ static void verity_finish_io(struct dm_verity_io *io, blk_status_t status)
        if (unlikely(status != BLK_STS_OK) &&
            unlikely(!(bio->bi_opf & REQ_RAHEAD)) &&
            !verity_is_system_shutting_down()) {
-               if (v->mode == DM_VERITY_MODE_RESTART ||
-                   v->mode == DM_VERITY_MODE_PANIC)
-                       DMERR_LIMIT("%s has error: %s", v->data_dev->name,
-                                       blk_status_to_str(status));
-
-               if (v->mode == DM_VERITY_MODE_RESTART) {
-                       pr_emerg("dm-verity device corrupted\n");
-                       emergency_restart();
+               if (v->error_mode == DM_VERITY_MODE_PANIC) {
+                       panic("dm-verity device has I/O error");
+               }
+               if (v->error_mode == DM_VERITY_MODE_RESTART) {
+                       static DECLARE_WORK(restart_work, restart_io_error);
+                       queue_work(v->verify_wq, &restart_work);
+                       /*
+                        * We deliberately don't call bio_endio here, because
+                        * the machine will be restarted anyway.
+                        */
+                       return;
                }
-
-               if (v->mode == DM_VERITY_MODE_PANIC)
-                       panic("dm-verity device corrupted");
        }
 
        bio_endio(bio);
@@ -824,6 +829,8 @@ static void verity_status(struct dm_target *ti, status_type_t type,
                                DMEMIT("%02x", v->salt[x]);
                if (v->mode != DM_VERITY_MODE_EIO)
                        args++;
+               if (v->error_mode != DM_VERITY_MODE_EIO)
+                       args++;
                if (verity_fec_is_enabled(v))
                        args += DM_VERITY_OPTS_FEC;
                if (v->zero_digest)
@@ -853,6 +860,19 @@ static void verity_status(struct dm_target *ti, status_type_t type,
                                BUG();
                        }
                }
+               if (v->error_mode != DM_VERITY_MODE_EIO) {
+                       DMEMIT(" ");
+                       switch (v->error_mode) {
+                       case DM_VERITY_MODE_RESTART:
+                               DMEMIT(DM_VERITY_OPT_ERROR_RESTART);
+                               break;
+                       case DM_VERITY_MODE_PANIC:
+                               DMEMIT(DM_VERITY_OPT_ERROR_PANIC);
+                               break;
+                       default:
+                               BUG();
+                       }
+               }
                if (v->zero_digest)
                        DMEMIT(" " DM_VERITY_OPT_IGN_ZEROES);
                if (v->validated_blocks)
@@ -905,6 +925,19 @@ static void verity_status(struct dm_target *ti, status_type_t type,
                                DMEMIT("invalid");
                        }
                }
+               if (v->error_mode != DM_VERITY_MODE_EIO) {
+                       DMEMIT(",verity_error_mode=");
+                       switch (v->error_mode) {
+                       case DM_VERITY_MODE_RESTART:
+                               DMEMIT(DM_VERITY_OPT_ERROR_RESTART);
+                               break;
+                       case DM_VERITY_MODE_PANIC:
+                               DMEMIT(DM_VERITY_OPT_ERROR_PANIC);
+                               break;
+                       default:
+                               DMEMIT("invalid");
+                       }
+               }
                DMEMIT(";");
                break;
        }
@@ -1107,6 +1140,25 @@ static int verity_parse_verity_mode(struct dm_verity *v, const char *arg_name)
        return 0;
 }
 
+static inline bool verity_is_verity_error_mode(const char *arg_name)
+{
+       return (!strcasecmp(arg_name, DM_VERITY_OPT_ERROR_RESTART) ||
+               !strcasecmp(arg_name, DM_VERITY_OPT_ERROR_PANIC));
+}
+
+static int verity_parse_verity_error_mode(struct dm_verity *v, const char *arg_name)
+{
+       if (v->error_mode)
+               return -EINVAL;
+
+       if (!strcasecmp(arg_name, DM_VERITY_OPT_ERROR_RESTART))
+               v->error_mode = DM_VERITY_MODE_RESTART;
+       else if (!strcasecmp(arg_name, DM_VERITY_OPT_ERROR_PANIC))
+               v->error_mode = DM_VERITY_MODE_PANIC;
+
+       return 0;
+}
+
 static int verity_parse_opt_args(struct dm_arg_set *as, struct dm_verity *v,
                                 struct dm_verity_sig_opts *verify_args,
                                 bool only_modifier_opts)
@@ -1141,6 +1193,16 @@ static int verity_parse_opt_args(struct dm_arg_set *as, struct dm_verity *v,
                        }
                        continue;
 
+               } else if (verity_is_verity_error_mode(arg_name)) {
+                       if (only_modifier_opts)
+                               continue;
+                       r = verity_parse_verity_error_mode(v, arg_name);
+                       if (r) {
+                               ti->error = "Conflicting error handling parameters";
+                               return r;
+                       }
+                       continue;
+
                } else if (!strcasecmp(arg_name, DM_VERITY_OPT_IGN_ZEROES)) {
                        if (only_modifier_opts)
                                continue;
index 754e70bb5fe09074a6ed75621046bde4c5dacc33..6b75159bf835acebb8e2c7c116a3dda0c0b430b7 100644 (file)
@@ -64,6 +64,7 @@ struct dm_verity {
        unsigned int digest_size;       /* digest size for the current hash algorithm */
        unsigned int hash_reqsize; /* the size of temporary space for crypto */
        enum verity_mode mode;  /* mode for handling verification errors */
+       enum verity_mode error_mode;/* mode for handling I/O errors */
        unsigned int corrupted_errs;/* Number of errors for corrupted blocks */
 
        struct workqueue_struct *verify_wq;
index 179ee4afe9376610db586d253982892be0512252..67108c397c5a8600fdfca6c89de76752c4e72fcb 100644 (file)
@@ -546,6 +546,26 @@ static int mddev_set_closing_and_sync_blockdev(struct mddev *mddev, int opener_n
        return 0;
 }
 
+/*
+ * The only difference from bio_chain_endio() is that the current
+ * bi_status of bio does not affect the bi_status of parent.
+ */
+static void md_end_flush(struct bio *bio)
+{
+       struct bio *parent = bio->bi_private;
+
+       /*
+        * If any flush io error before the power failure,
+        * disk data may be lost.
+        */
+       if (bio->bi_status)
+               pr_err("md: %pg flush io error %d\n", bio->bi_bdev,
+                       blk_status_to_errno(bio->bi_status));
+
+       bio_put(bio);
+       bio_endio(parent);
+}
+
 bool md_flush_request(struct mddev *mddev, struct bio *bio)
 {
        struct md_rdev *rdev;
@@ -565,7 +585,9 @@ bool md_flush_request(struct mddev *mddev, struct bio *bio)
                new = bio_alloc_bioset(rdev->bdev, 0,
                                       REQ_OP_WRITE | REQ_PREFLUSH, GFP_NOIO,
                                       &mddev->bio_set);
-               bio_chain(new, bio);
+               new->bi_private = bio;
+               new->bi_end_io = md_end_flush;
+               bio_inc_remaining(bio);
                submit_bio(new);
        }
 
index f3bf1116794a4e069377fc6d5965101c98fd3ed8..862b1fb71d864b8ab2b532be288bd380ba75cb6b 100644 (file)
@@ -4061,9 +4061,12 @@ static int raid10_run(struct mddev *mddev)
        }
 
        if (!mddev_is_dm(conf->mddev)) {
-               ret = raid10_set_queue_limits(mddev);
-               if (ret)
+               int err = raid10_set_queue_limits(mddev);
+
+               if (err) {
+                       ret = err;
                        goto out_free_conf;
+               }
        }
 
        /* need to check that every block has at least one working mirror */
index 91e9c378397c819f18eb37f013644566c94a0b2a..930da176e5bfb43ae875a2dceb480b206b2cc473 100644 (file)
@@ -21,7 +21,7 @@
 #include <linux/mutex.h>
 #include <linux/vmalloc.h>
 #include <asm/div64.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #include <media/dvb_frontend.h>
 #include "mxl5xx.h"
index ed79075505e6f99b01ac8de27c96799eaa760dfb..a696a0ec8ff5c7d0c1fbda580da5b61e04a4750f 100644 (file)
@@ -9,7 +9,7 @@
  * Contact: Sakari Ailus <[email protected]>
  */
 
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #include <linux/delay.h>
 #include <linux/i2c.h>
index b440f386f0622ef777b2d4685ed817c15127d2bb..f31f9886c924e499c65e90fd2572a2eb176d4363 100644 (file)
@@ -1,7 +1,7 @@
 // SPDX-License-Identifier: GPL-2.0
 // Copyright (c) 2019 Intel Corporation.
 
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include <linux/acpi.h>
 #include <linux/clk.h>
 #include <linux/delay.h>
index 52d9ca68a86c8cf7c6fce14bd9dcd2b280ce2212..172772decd3db14d88510f527bcffd5bc3a554e7 100644 (file)
@@ -1,7 +1,7 @@
 // SPDX-License-Identifier: GPL-2.0
 // Copyright (c) 2021 Purism SPC
 
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include <linux/clk.h>
 #include <linux/delay.h>
 #include <linux/gpio/consumer.h>
index 72c60747a83991f5df18301d91b801e33c0bbee0..546833f5b5f5987666b2948cd109192edd4f6bcd 100644 (file)
@@ -1,7 +1,7 @@
 // SPDX-License-Identifier: GPL-2.0
 // Copyright (c) 2022 Intel Corporation.
 
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include <linux/acpi.h>
 #include <linux/delay.h>
 #include <linux/i2c.h>
index 639e05340dbb5c571a60a8b7fb5a1288780f70f3..2184c90f7864d4f69855e57cdcdd87396b77df87 100644 (file)
@@ -8,7 +8,7 @@
 #include <linux/pm_runtime.h>
 #include <media/v4l2-ctrls.h>
 #include <media/v4l2-device.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #define IMX208_REG_MODE_SELECT         0x0100
 #define IMX208_MODE_STANDBY            0x00
index 1a99eaaff21a00820f085d918cc5c55c4f22c0ea..9e30fce1f22367b48938da8131317a07c7b2fced 100644 (file)
@@ -12,7 +12,7 @@
 #include <media/v4l2-ctrls.h>
 #include <media/v4l2-device.h>
 #include <media/v4l2-fwnode.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #define IMX258_REG_MODE_SELECT         CCI_REG8(0x0100)
 #define IMX258_MODE_STANDBY            0x00
index 4150e6e4b9a6358be79950d1865427ef194ba44c..458905dfb3e110587cc97db24a99c255fdc3b203 100644 (file)
@@ -18,7 +18,7 @@
 #include <linux/regmap.h>
 #include <linux/regulator/consumer.h>
 
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #include <media/media-entity.h>
 #include <media/v4l2-cci.h>
index 8fe3933f31467cb67ccd10abaa6a02dae03c1cd9..dd1b4ff983dcb1755adde2da1f92db7a2edf91e9 100644 (file)
@@ -1,7 +1,7 @@
 // SPDX-License-Identifier: GPL-2.0
 // Copyright (C) 2018 Intel Corporation
 
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include <linux/acpi.h>
 #include <linux/i2c.h>
 #include <linux/module.h>
index 40863d87d3413a5ce3527e94e1ca51d02e994321..a544fc3df39c2853e8ad0757747cb3f74e3fdfb6 100644 (file)
@@ -4,7 +4,7 @@
  *
  * Copyright (C) 2021 Intel Corporation
  */
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #include <linux/clk.h>
 #include <linux/delay.h>
index 54a1de53d49730764bcefee1767f0f1f0f25e2f6..fcfd1d851bd4aac1c71df2d6eead3f5901e27c29 100644 (file)
@@ -4,7 +4,7 @@
  *
  * Copyright (C) 2021 Intel Corporation
  */
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #include <linux/clk.h>
 #include <linux/delay.h>
index 0dd25eeea60b617574e16d94264afa413c0f827d..b2dce67c0b6bca2955b5d5d2eee8fd3c71dc056b 100644 (file)
@@ -1,7 +1,7 @@
 // SPDX-License-Identifier: GPL-2.0
 // Copyright (C) 2018 Intel Corporation
 
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include <linux/acpi.h>
 #include <linux/i2c.h>
 #include <linux/module.h>
index 7d1f7af0a9dff30c426ecf2830622f66fa3f4639..0bfe3046fcc8726ef4e484d0fbf980422343fccc 100644 (file)
@@ -4,7 +4,7 @@
  *
  * Copyright (C) 2021 Intel Corporation
  */
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #include <linux/clk.h>
 #include <linux/delay.h>
index b37a2aaf8ac0478ba76503386ad3fc3b038f2a33..c84e1e0e6109afccc29c72ee2ac762eaddb0b0ad 100644 (file)
@@ -35,7 +35,7 @@
  *     Copyright (C) 2011 Andy Walls <[email protected]>
  */
 
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/kernel.h>
index e906435fc49a16983a14cd83e17ab419dab85bb4..78d5d406e4b72a36d40977b388fd95d31daf8ed4 100644 (file)
@@ -1,7 +1,7 @@
 // SPDX-License-Identifier: GPL-2.0
 // Copyright (c) 2022 Intel Corporation.
 
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include <linux/acpi.h>
 #include <linux/clk.h>
 #include <linux/delay.h>
index 5606437f37d0ece8632c7307487fc30d4906cb80..0b9fb1ddbe5970593fe3ccae909d6ec3670413da 100644 (file)
@@ -3,7 +3,7 @@
  * Copyright (c) 2023 Intel Corporation.
  */
 
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #include <linux/acpi.h>
 #include <linux/bitfield.h>
index 48df077522ad0bb2b5f64a6def8844c02af6a193..7ead3c720e0e11af8f9ab28000ce5dbbe6dfb773 100644 (file)
@@ -1,7 +1,7 @@
 // SPDX-License-Identifier: GPL-2.0
 // Copyright (c) 2022 Intel Corporation.
 
-#include <asm-generic/unaligned.h>
+#include <linux/unaligned.h>
 #include <linux/acpi.h>
 #include <linux/i2c.h>
 #include <linux/module.h>
index c48dbcde98770d43f9f1dd53725d15127c457d2f..bd0b2f0f0d45b96f8a2bfadac9462e0b75333344 100644 (file)
@@ -1,7 +1,7 @@
 // SPDX-License-Identifier: GPL-2.0
 // Copyright (c) 2020 Intel Corporation.
 
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include <linux/acpi.h>
 #include <linux/clk.h>
 #include <linux/delay.h>
index 2aee85965cf73a382a7f90ee9482fce694cb5a71..f051045d340f239edcec22fd2d596d22ad7eae1b 100644 (file)
@@ -1,7 +1,7 @@
 // SPDX-License-Identifier: GPL-2.0
 // Copyright (c) 2017 Intel Corporation.
 
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include <linux/acpi.h>
 #include <linux/clk.h>
 #include <linux/delay.h>
index 5b5127f8953ff4182704b32b2f6c9194cf4b6e13..2833b14ee139dc5167f9a7598f6aac4b7b4d998c 100644 (file)
@@ -1,7 +1,7 @@
 // SPDX-License-Identifier: GPL-2.0
 // Copyright (c) 2019 Intel Corporation.
 
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include <linux/acpi.h>
 #include <linux/clk.h>
 #include <linux/delay.h>
index 6ffe10e57b5b14a1c582623779d151fe6d0e0339..3b94338f55ed39fc1ea3dbb21840cf580b4cee97 100644 (file)
@@ -1,7 +1,7 @@
 // SPDX-License-Identifier: GPL-2.0
 // Copyright (c) 2019 Intel Corporation.
 
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include <linux/acpi.h>
 #include <linux/clk.h>
 #include <linux/delay.h>
index 174c65f768860e1503f2bc258a09107449bca5c6..326f50a5ab51ffbb4aaf5123aa893cd30ec95c58 100644 (file)
@@ -5,7 +5,7 @@
  * Copyright (C) 2017 Fuzhou Rockchip Electronics Co., Ltd.
  */
 
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #include <linux/clk.h>
 #include <linux/delay.h>
index 251a4b53491438fa0c532d76f43d649117e442e4..9f52af6f047f3c283eb0cdf8b90662cc37003255 100644 (file)
@@ -4,7 +4,7 @@
  *
  * Copyright (C) 2021 Intel Corporation
  */
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #include <linux/clk.h>
 #include <linux/delay.h>
index d997285974318f1332043a19b5e660d4a058db00..bf9e2adbff3473d6c17c9e4cd961862494b632b3 100644 (file)
@@ -1,7 +1,7 @@
 // SPDX-License-Identifier: GPL-2.0
 // Copyright (c) 2020 Intel Corporation.
 
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include <linux/acpi.h>
 #include <linux/delay.h>
 #include <linux/i2c.h>
index 75225ff5eff6f846e155e9f9b56ee7100926d861..c77440ff098cde14d31a54f61b1acdfdc3e78087 100644 (file)
@@ -4,7 +4,7 @@
  * Copyright (C) 2023 Ideas on Board Oy
  */
 
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #include <linux/clk.h>
 #include <linux/delay.h>
index 30378e9620166d08f664c77eb79009926c5ac962..409d2d4ffb4bb2189fab1f38733ddffdc7923345 100644 (file)
@@ -16,7 +16,7 @@
 #include <linux/regulator/consumer.h>
 #include <linux/units.h>
 
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #include <media/mipi-csi2.h>
 #include <media/v4l2-async.h>
index 867c1308de235679b18cb259eae826d51086a78f..365b04e5ae4d27e7f7b092ce69575d938381570c 100644 (file)
@@ -24,7 +24,7 @@
 #include <linux/firmware.h>
 #include <net/checksum.h>
 
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include <asm/io.h>
 
 #include "bttvp.h"
index ba8f410029172de9d5955d77e93a617c33815a29..5746892658b12a9f7b88085cff8bd16aa48dc50b 100644 (file)
@@ -5,7 +5,7 @@
  * Copyright (C) 2014 Philipp Zabel, Pengutronix
  */
 
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include <linux/irqreturn.h>
 #include <linux/kernel.h>
 #include <linux/ktime.h>
index fff349e45067edf006fbe806c410249a416ba6cc..e50fe7525a732b66952f8bf5437b9d9c691db954 100644 (file)
@@ -14,7 +14,7 @@
  *      3) V4L2_CID_JPEG_ACTIVE_MARKER
  */
 
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include <linux/clk.h>
 #include <linux/err.h>
 #include <linux/interrupt.h>
index 9aea331e1a3c92600c875b9ba83a56e9d34b5b75..e0d6bd0a6e44f5c825a66c27bd4951e9c86f6255 100644 (file)
@@ -5,7 +5,7 @@
  * Copyright (C) 2018 Rockchip Electronics Co., Ltd.
  */
 
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include <linux/bitfield.h>
 #include <media/v4l2-mem2mem.h>
 #include "hantro.h"
index 12d69503d6baa5202ae0c54473fef791e245560e..86cc1a07026f0d34e06478f350eac4d1a0a0cbad 100644 (file)
@@ -5,7 +5,7 @@
  * Copyright (C) 2018 Rockchip Electronics Co., Ltd.
  */
 
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include <media/v4l2-mem2mem.h>
 #include "hantro_jpeg.h"
 #include "hantro.h"
index 8395c4d48dd0bc253fe7daed506e1818ae78fb02..61621b1be8a2f867f8508871f1a50401a7ba1c87 100644 (file)
@@ -22,7 +22,7 @@
  * zigzag, nor linear.
  */
 
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include <media/v4l2-mem2mem.h>
 #include "hantro_jpeg.h"
 #include "hantro.h"
index b66737fab46b4b790b29d6054696ba5bec9275d1..50a3a3eeaa00d6b012b748a50c1a2bb66c8baac2 100644 (file)
@@ -5,7 +5,7 @@
  * Copyright (C) 2018 Rockchip Electronics Co., Ltd.
  */
 
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include <linux/bitfield.h>
 #include <media/v4l2-mem2mem.h>
 #include "hantro.h"
index c3180d53c2824c789dc4a977052c38e68daec341..64c7452c05b57b208ea283cc1812152552f9ce9d 100644 (file)
@@ -12,7 +12,7 @@
 #include <linux/hid.h>
 #include <linux/mutex.h>
 #include <linux/videodev2.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include <media/v4l2-device.h>
 #include <media/v4l2-ioctl.h>
 #include <media/v4l2-ctrls.h>
index e57ab54a27fcac72634fd0d5288cdf290f51b300..2915c0023fcd6cc7e248e1a04450634a97526f6f 100644 (file)
@@ -26,7 +26,7 @@
 #include <media/v4l2-ctrls.h>
 #include <media/v4l2-event.h>
 #include <media/v4l2-device.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 
 
index 69e630d85262f65f413ee8c9d092ea85cee01c91..533faa117517449af8be3edd7d7ef3c8ae7391da 100644 (file)
@@ -12,7 +12,7 @@
  * Copyright (C) 2011 Peter Kooiman <[email protected]>
  */
 
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include <linux/completion.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
index 9f2947af33aa7c57265a4da2d1cd41a746fa95fa..d89a4cfe3c89592826d15ca10e44510d8e6e19f5 100644 (file)
@@ -31,7 +31,7 @@
  * --
  */
 
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include <linux/device.h>
 #include <linux/leds.h>
 #include <linux/module.h>
index 352b8a3679b72197b704bbc8587ce9f319cd48c6..8e6638e5f6889ab4b244abfb0cff087f5ad37eb9 100644 (file)
@@ -14,7 +14,7 @@
 #include <media/tuner.h>
 #include <linux/mutex.h>
 #include <linux/slab.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include "tuner-i2c.h"
 #include "xc2028.h"
 #include "xc2028-types.h"
index 29bc63021c5aae978b7937b31b9eb81fc03a4fde..3cf54d776d36c826f8db2002e3976119803fa43e 100644 (file)
@@ -16,7 +16,7 @@
 #include <linux/dvb/frontend.h>
 #include <linux/i2c.h>
 #include <linux/mutex.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #include <media/dvb_frontend.h>
 
index c88a202daf5fc168be592b2a52461cc60853eea8..a2054b1b100fe4dedfc8e9a8a67a0bca4b93635e 100644 (file)
@@ -17,7 +17,7 @@
 
 #include <media/tuner.h>
 #include "tuner-simple.h"
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 /* debug */
 static int dvb_usb_m920x_debug;
index f0febdc08c2d65208fca266c5d8d6b7c73394e77..0fac689c6350b29f3f591cf29a5724ff2818cd09 100644 (file)
@@ -19,7 +19,7 @@
 #include <linux/videodev2.h>
 #include <linux/vmalloc.h>
 #include <linux/wait.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #include <media/v4l2-common.h>
 #include <media/v4l2-ioctl.h>
index cd9c29532fb031bd1e19c2946767a9bc05f711d1..e00f38dd07d93554f1e98eab43991ded05c09d9d 100644 (file)
@@ -18,7 +18,7 @@
 #include <linux/vmalloc.h>
 #include <linux/wait.h>
 #include <linux/atomic.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #include <media/v4l2-common.h>
 
index 1ff94affbaf3a362730f6b4632f3afd55360eae0..e9ecf47859465dd18950d261e4940481a505cb10 100644 (file)
@@ -12,7 +12,7 @@
 #include <linux/regmap.h>
 #include <linux/types.h>
 
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #include <media/v4l2-cci.h>
 
index b8bece739d07a930f2d81a5a9cdc16eb9260b70f..6e264732352262bd1cdd789285014c6b1db2e12a 100644 (file)
@@ -9,7 +9,7 @@
  * [1] https://www.w3.org/Graphics/JPEG/itu-t81.pdf
  */
 
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include <linux/errno.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
index 246876ac713c25818a2e3eb632476004ccac885a..ffdd8de9ec5d79ba90689834530b67b33c7a16ed 100644 (file)
@@ -19,7 +19,7 @@
 #include <linux/mutex.h>
 #include <linux/sched.h>
 #include <linux/completion.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 struct rtsx_usb_ms {
        struct platform_device  *pdev;
index 6ca867b8f5f1207723df9b98f18ee04aec7d5529..a3301502ce6a5b4779f4211e0a3e9e657617fc55 100644 (file)
@@ -20,7 +20,7 @@
 #include <linux/platform_device.h>
 #include <linux/regmap.h>
 
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 /*
  * The GSC suffers from an errata where occasionally during
index 1b465590567cf4d80b820b4a7d679011a7d8b1cc..ee017617d1d1bbfef6593c6a39ca8c8c11fe8700 100644 (file)
@@ -31,7 +31,7 @@
 #include <linux/property.h>
 #include <linux/regmap.h>
 #include <linux/slab.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #define IQS62X_PROD_NUM                                0x00
 
index 4416cd37e539bf8be80ed47954491020de09728c..08c68de0f01bcec8496cba6bf81f194d77f255c9 100644 (file)
@@ -21,7 +21,7 @@
 #include <linux/reboot.h>
 #include <linux/regmap.h>
 #include <linux/types.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #define NTXEC_REG_VERSION      0x00
 #define NTXEC_REG_POWEROFF     0x50
index ef326d6d566e691603cd20604b863c6de091a246..c1b78d127a261e88ab0bfaa50716560c47f8d285 100644 (file)
@@ -21,7 +21,7 @@
 #include <linux/of_platform.h>
 #include <linux/sched.h>
 #include <linux/serdev.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 /*
  * UART protocol using following entities:
index c9a0ec084aa85a8a52e93f9f32db78928c1520ef..3bb2decfebd31a5ff0f804c55c927801f7bbe720 100644 (file)
@@ -20,7 +20,7 @@
 
 #include <linux/mfd/si476x-core.h>
 
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #define msb(x)                  ((u8)((u16) x >> 8))
 #define lsb(x)                  ((u8)((u16) x &  0x00FF))
index 587427b73914c5da285958b5b5753edbaeccc2b1..bbe3967c3a4c7955349c5d0a62304c5c06c75efb 100644 (file)
@@ -9,7 +9,7 @@
  * Copyright (C) 2010,2011 Igor M. Liplianin <[email protected]>
  */
 
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include <linux/ctype.h>
 #include <linux/string.h>
 #include <linux/firmware.h>
index 2e9daaf3e492bb27c67ed641618ca3be060c5624..d309216ee181925fba05f4d9fcfce6836c8866f4 100644 (file)
@@ -9,7 +9,7 @@
 #include <linux/vmalloc.h>
 
 #include <asm/page.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #include <uapi/linux/misc/bcm_vk.h>
 
index 022322dfb36efbe77353f899910750e0b28084a7..a70700f0e592db652f31d4afc1dab740ac7257dc 100644 (file)
@@ -16,7 +16,8 @@ config MISC_RTSX_PCI
        select MFD_CORE
        help
          This supports for Realtek PCI-Express card reader including rts5209,
-         rts5227, rts522A, rts5229, rts5249, rts524A, rts525A, rtl8411, rts5260.
+         rts5227, rts5228, rts522A, rts5229, rts5249, rts524A, rts525A, rtl8411,
+         rts5260, rts5261, rts5264.
          Realtek card readers support access to many types of memory cards,
          such as Memory Stick, Memory Stick Pro, Secure Digital and
          MultiMediaCard.
index 117b3c24f910c9a8e6d01083fb725100cc804d32..be3d4e0e50ccd60cae77f983776fccc8e2a566a3 100644 (file)
@@ -19,7 +19,7 @@
 #include <linux/mfd/core.h>
 #include <linux/rtsx_pci.h>
 #include <linux/mmc/card.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include <linux/pm.h>
 #include <linux/pm_runtime.h>
 
index bac4df2e5231475df76317997366a9b12813c2e1..93949df3bcff1a30a8c83cf6faceea822ca04d5e 100644 (file)
@@ -11,7 +11,7 @@
 #include <linux/spi/spi.h>
 #include <linux/platform_device.h>
 #include <linux/delay.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #define FIRMWARE_NAME  "lattice-ecp3.bit"
 
index 7c3d8bedf90ba254f6d3b40f2eaa0b1765d01a03..a2ed477e0370bc08ebf71085cb083720e7bbcf5f 100644 (file)
@@ -364,6 +364,7 @@ static int pci1xxxx_otp_eeprom_probe(struct auxiliary_device *aux_dev,
        if (is_eeprom_responsive(priv)) {
                priv->nvmem_config_eeprom.type = NVMEM_TYPE_EEPROM;
                priv->nvmem_config_eeprom.name = EEPROM_NAME;
+               priv->nvmem_config_eeprom.id = NVMEM_DEVID_AUTO;
                priv->nvmem_config_eeprom.dev = &aux_dev->dev;
                priv->nvmem_config_eeprom.owner = THIS_MODULE;
                priv->nvmem_config_eeprom.reg_read = pci1xxxx_eeprom_read;
@@ -383,6 +384,7 @@ static int pci1xxxx_otp_eeprom_probe(struct auxiliary_device *aux_dev,
 
        priv->nvmem_config_otp.type = NVMEM_TYPE_OTP;
        priv->nvmem_config_otp.name = OTP_NAME;
+       priv->nvmem_config_otp.id = NVMEM_DEVID_AUTO;
        priv->nvmem_config_otp.dev = &aux_dev->dev;
        priv->nvmem_config_otp.owner = THIS_MODULE;
        priv->nvmem_config_otp.reg_read = pci1xxxx_otp_read;
index 9d090fa07516f06a567c0308c995393e57239010..be011cef12e5d529f27962fa1aad4e0143f1061e 100644 (file)
@@ -321,7 +321,7 @@ void mei_io_cb_free(struct mei_cl_cb *cb)
                return;
 
        list_del(&cb->list);
-       kfree(cb->buf.data);
+       kvfree(cb->buf.data);
        kfree(cb->ext_hdr);
        kfree(cb);
 }
@@ -497,7 +497,7 @@ struct mei_cl_cb *mei_cl_alloc_cb(struct mei_cl *cl, size_t length,
        if (length == 0)
                return cb;
 
-       cb->buf.data = kmalloc(roundup(length, MEI_SLOT_SIZE), GFP_KERNEL);
+       cb->buf.data = kvmalloc(roundup(length, MEI_SLOT_SIZE), GFP_KERNEL);
        if (!cb->buf.data) {
                mei_io_cb_free(cb);
                return NULL;
index d02f6e881139f1289e712275f64417d294d74498..20a11b299bcd0088f33c792f50cb3cc695925646 100644 (file)
@@ -19,7 +19,7 @@
 #include <linux/types.h>
 
 #include <asm-generic/bug.h>
-#include <asm-generic/unaligned.h>
+#include <linux/unaligned.h>
 
 #include "mei_dev.h"
 #include "vsc-tp.h"
index 084d0205f97d6dd03c334102f377c343f2b4360f..9f129bc641f6993ff6814957da2cacbd82265ecc 100644 (file)
@@ -15,7 +15,7 @@
 #include <linux/string_helpers.h>
 #include <linux/types.h>
 
-#include <asm-generic/unaligned.h>
+#include <linux/unaligned.h>
 
 #include "vsc-tp.h"
 
index 37e804bbb1f281c046c7d70cefb444d8097712bb..205945ce9e86a6b3d2349574f0fd798993a64724 100644 (file)
@@ -258,7 +258,6 @@ static int gru_get_cpu_resources(int dsr_bytes, void **cb, void **dsr)
        int lcpu;
 
        BUG_ON(dsr_bytes > GRU_NUM_KERNEL_DSR_BYTES);
-       preempt_disable();
        bs = gru_lock_kernel_context(-1);
        lcpu = uv_blade_processor_id();
        *cb = bs->kernel_cb + lcpu * GRU_HANDLE_STRIDE;
@@ -272,7 +271,6 @@ static int gru_get_cpu_resources(int dsr_bytes, void **cb, void **dsr)
 static void gru_free_cpu_resources(void *cb, void *dsr)
 {
        gru_unlock_kernel_context(uv_numa_blade_id());
-       preempt_enable();
 }
 
 /*
index 0f5b09e290c899818ef83a866ac2e64201d10429..3036c15f3689259345a1bdf34fff89c9aab84297 100644 (file)
@@ -937,10 +937,8 @@ vm_fault_t gru_fault(struct vm_fault *vmf)
 
 again:
        mutex_lock(&gts->ts_ctxlock);
-       preempt_disable();
 
        if (gru_check_context_placement(gts)) {
-               preempt_enable();
                mutex_unlock(&gts->ts_ctxlock);
                gru_unload_context(gts, 1);
                return VM_FAULT_NOPAGE;
@@ -949,7 +947,6 @@ again:
        if (!gts->ts_gru) {
                STAT(load_user_context);
                if (!gru_assign_gru_context(gts)) {
-                       preempt_enable();
                        mutex_unlock(&gts->ts_ctxlock);
                        set_current_state(TASK_INTERRUPTIBLE);
                        schedule_timeout(GRU_ASSIGN_DELAY);  /* true hack ZZZ */
@@ -965,7 +962,6 @@ again:
                                vma->vm_page_prot);
        }
 
-       preempt_enable();
        mutex_unlock(&gts->ts_ctxlock);
 
        return VM_FAULT_NOPAGE;
index 10921cd2608dfa3bfabe58d49630f43cd034bbb1..1107dd3e2e9fa43b867cee20253284b697d53643 100644 (file)
@@ -65,7 +65,6 @@ static struct gru_tlb_global_handle *get_lock_tgh_handle(struct gru_state
        struct gru_tlb_global_handle *tgh;
        int n;
 
-       preempt_disable();
        if (uv_numa_blade_id() == gru->gs_blade_id)
                n = get_on_blade_tgh(gru);
        else
@@ -79,7 +78,6 @@ static struct gru_tlb_global_handle *get_lock_tgh_handle(struct gru_state
 static void get_unlock_tgh_handle(struct gru_tlb_global_handle *tgh)
 {
        unlock_tgh_handle(tgh);
-       preempt_enable();
 }
 
 /*
index d0b3ca8a11f07172041e4ae634e560f96071b486..4d6844261912047b6bc407ecf4ce16b3854ee415 100644 (file)
@@ -388,7 +388,8 @@ static struct gendisk *mmc_alloc_disk(struct mmc_queue *mq,
 
        blk_queue_rq_timeout(mq->queue, 60 * HZ);
 
-       dma_set_max_seg_size(mmc_dev(host), queue_max_segment_size(mq->queue));
+       if (mmc_dev(host)->dma_parms)
+               dma_set_max_seg_size(mmc_dev(host), queue_max_segment_size(mq->queue));
 
        INIT_WORK(&mq->recovery_work, mmc_mq_recovery_handler);
        INIT_WORK(&mq->complete_work, mmc_blk_mq_complete_work);
index 6490df54a6f55b17abf361f250082df5212d8d77..cdbd2edf4b2e7c2bfe76c54b533072a11289182b 100644 (file)
@@ -37,7 +37,7 @@
 
 #include <asm/cacheflush.h>
 #include <asm/io.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #define ATMCI_MAX_NR_SLOTS     2
 
index c9caa1ece7ef91ec94b97a6879315542f3264d05..8fee7052f2ef4f43ab2dc96b859a8a73bfd69339 100644 (file)
@@ -26,7 +26,7 @@
 #include <linux/spi/spi.h>
 #include <linux/spi/mmc_spi.h>
 
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 
 /* NOTES:
index af7f21888e273bf0bfe5b98292751d0f4d6a1e4e..12df4ff9eeee5319dcc9ed1dffd02001023c8dae 100644 (file)
@@ -22,7 +22,7 @@
 #include <linux/mmc/slot-gpio.h>
 
 #include <linux/sizes.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #include "mvsdio.h"
 
@@ -38,9 +38,8 @@ struct mvsd_host {
        unsigned int xfer_mode;
        unsigned int intr_en;
        unsigned int ctrl;
-       bool use_pio;
-       struct sg_mapping_iter sg_miter;
        unsigned int pio_size;
+       void *pio_ptr;
        unsigned int sg_frags;
        unsigned int ns_per_clk;
        unsigned int clock;
@@ -115,18 +114,11 @@ static int mvsd_setup_data(struct mvsd_host *host, struct mmc_data *data)
                 * data when the buffer is not aligned on a 64 byte
                 * boundary.
                 */
-               unsigned int miter_flags = SG_MITER_ATOMIC; /* Used from IRQ */
-
-               if (data->flags & MMC_DATA_READ)
-                       miter_flags |= SG_MITER_TO_SG;
-               else
-                       miter_flags |= SG_MITER_FROM_SG;
-
                host->pio_size = data->blocks * data->blksz;
-               sg_miter_start(&host->sg_miter, data->sg, data->sg_len, miter_flags);
+               host->pio_ptr = sg_virt(data->sg);
                if (!nodma)
-                       dev_dbg(host->dev, "fallback to PIO for data\n");
-               host->use_pio = true;
+                       dev_dbg(host->dev, "fallback to PIO for data at 0x%p size %d\n",
+                               host->pio_ptr, host->pio_size);
                return 1;
        } else {
                dma_addr_t phys_addr;
@@ -137,7 +129,6 @@ static int mvsd_setup_data(struct mvsd_host *host, struct mmc_data *data)
                phys_addr = sg_dma_address(data->sg);
                mvsd_write(MVSD_SYS_ADDR_LOW, (u32)phys_addr & 0xffff);
                mvsd_write(MVSD_SYS_ADDR_HI,  (u32)phys_addr >> 16);
-               host->use_pio = false;
                return 0;
        }
 }
@@ -297,8 +288,8 @@ static u32 mvsd_finish_data(struct mvsd_host *host, struct mmc_data *data,
 {
        void __iomem *iobase = host->base;
 
-       if (host->use_pio) {
-               sg_miter_stop(&host->sg_miter);
+       if (host->pio_ptr) {
+               host->pio_ptr = NULL;
                host->pio_size = 0;
        } else {
                dma_unmap_sg(mmc_dev(host->mmc), data->sg, host->sg_frags,
@@ -353,12 +344,9 @@ static u32 mvsd_finish_data(struct mvsd_host *host, struct mmc_data *data,
 static irqreturn_t mvsd_irq(int irq, void *dev)
 {
        struct mvsd_host *host = dev;
-       struct sg_mapping_iter *sgm = &host->sg_miter;
        void __iomem *iobase = host->base;
        u32 intr_status, intr_done_mask;
        int irq_handled = 0;
-       u16 *p;
-       int s;
 
        intr_status = mvsd_read(MVSD_NOR_INTR_STATUS);
        dev_dbg(host->dev, "intr 0x%04x intr_en 0x%04x hw_state 0x%04x\n",
@@ -382,36 +370,15 @@ static irqreturn_t mvsd_irq(int irq, void *dev)
        spin_lock(&host->lock);
 
        /* PIO handling, if needed. Messy business... */
-       if (host->use_pio) {
-               /*
-                * As we set sgm->consumed this always gives a valid buffer
-                * position.
-                */
-               if (!sg_miter_next(sgm)) {
-                       /* This should not happen */
-                       dev_err(host->dev, "ran out of scatter segments\n");
-                       spin_unlock(&host->lock);
-                       host->intr_en &=
-                               ~(MVSD_NOR_RX_READY | MVSD_NOR_RX_FIFO_8W |
-                                 MVSD_NOR_TX_AVAIL | MVSD_NOR_TX_FIFO_8W);
-                       mvsd_write(MVSD_NOR_INTR_EN, host->intr_en);
-                       return IRQ_HANDLED;
-               }
-               p = sgm->addr;
-               s = sgm->length;
-               if (s > host->pio_size)
-                       s = host->pio_size;
-       }
-
-       if (host->use_pio &&
+       if (host->pio_size &&
            (intr_status & host->intr_en &
             (MVSD_NOR_RX_READY | MVSD_NOR_RX_FIFO_8W))) {
-
+               u16 *p = host->pio_ptr;
+               int s = host->pio_size;
                while (s >= 32 && (intr_status & MVSD_NOR_RX_FIFO_8W)) {
                        readsw(iobase + MVSD_FIFO, p, 16);
                        p += 16;
                        s -= 32;
-                       sgm->consumed += 32;
                        intr_status = mvsd_read(MVSD_NOR_INTR_STATUS);
                }
                /*
@@ -424,7 +391,6 @@ static irqreturn_t mvsd_irq(int irq, void *dev)
                                put_unaligned(mvsd_read(MVSD_FIFO), p++);
                                put_unaligned(mvsd_read(MVSD_FIFO), p++);
                                s -= 4;
-                               sgm->consumed += 4;
                                intr_status = mvsd_read(MVSD_NOR_INTR_STATUS);
                        }
                        if (s && s < 4 && (intr_status & MVSD_NOR_RX_READY)) {
@@ -432,13 +398,10 @@ static irqreturn_t mvsd_irq(int irq, void *dev)
                                val[0] = mvsd_read(MVSD_FIFO);
                                val[1] = mvsd_read(MVSD_FIFO);
                                memcpy(p, ((void *)&val) + 4 - s, s);
-                               sgm->consumed += s;
                                s = 0;
                                intr_status = mvsd_read(MVSD_NOR_INTR_STATUS);
                        }
-                       /* PIO transfer done */
-                       host->pio_size -= sgm->consumed;
-                       if (host->pio_size == 0) {
+                       if (s == 0) {
                                host->intr_en &=
                                     ~(MVSD_NOR_RX_READY | MVSD_NOR_RX_FIFO_8W);
                                mvsd_write(MVSD_NOR_INTR_EN, host->intr_en);
@@ -450,10 +413,14 @@ static irqreturn_t mvsd_irq(int irq, void *dev)
                }
                dev_dbg(host->dev, "pio %d intr 0x%04x hw_state 0x%04x\n",
                        s, intr_status, mvsd_read(MVSD_HW_STATE));
+               host->pio_ptr = p;
+               host->pio_size = s;
                irq_handled = 1;
-       } else if (host->use_pio &&
+       } else if (host->pio_size &&
                   (intr_status & host->intr_en &
                    (MVSD_NOR_TX_AVAIL | MVSD_NOR_TX_FIFO_8W))) {
+               u16 *p = host->pio_ptr;
+               int s = host->pio_size;
                /*
                 * The TX_FIFO_8W bit is unreliable. When set, bursting
                 * 16 halfwords all at once in the FIFO drops data. Actually
@@ -464,7 +431,6 @@ static irqreturn_t mvsd_irq(int irq, void *dev)
                        mvsd_write(MVSD_FIFO, get_unaligned(p++));
                        mvsd_write(MVSD_FIFO, get_unaligned(p++));
                        s -= 4;
-                       sgm->consumed += 4;
                        intr_status = mvsd_read(MVSD_NOR_INTR_STATUS);
                }
                if (s < 4) {
@@ -473,13 +439,10 @@ static irqreturn_t mvsd_irq(int irq, void *dev)
                                memcpy(((void *)&val) + 4 - s, p, s);
                                mvsd_write(MVSD_FIFO, val[0]);
                                mvsd_write(MVSD_FIFO, val[1]);
-                               sgm->consumed += s;
                                s = 0;
                                intr_status = mvsd_read(MVSD_NOR_INTR_STATUS);
                        }
-                       /* PIO transfer done */
-                       host->pio_size -= sgm->consumed;
-                       if (host->pio_size == 0) {
+                       if (s == 0) {
                                host->intr_en &=
                                     ~(MVSD_NOR_TX_AVAIL | MVSD_NOR_TX_FIFO_8W);
                                mvsd_write(MVSD_NOR_INTR_EN, host->intr_en);
@@ -487,6 +450,8 @@ static irqreturn_t mvsd_irq(int irq, void *dev)
                }
                dev_dbg(host->dev, "pio %d intr 0x%04x hw_state 0x%04x\n",
                        s, intr_status, mvsd_read(MVSD_HW_STATE));
+               host->pio_ptr = p;
+               host->pio_size = s;
                irq_handled = 1;
        }
 
index 7dfe7c4e00770412e642aabb2d70cbd38f698b52..20e79109be16d6a3e71e2afdae2bb76b1109466c 100644 (file)
@@ -20,7 +20,7 @@
 #include <linux/mmc/sdio.h>
 #include <linux/mmc/card.h>
 #include <linux/rtsx_pci.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include <linux/pm_runtime.h>
 
 struct realtek_pci_sdmmc {
index ded9b6849e35e92eabc7aca89947c2b3da41652c..4e86f0a705b60a984f2b314c8316146a13642705 100644 (file)
@@ -21,7 +21,7 @@
 #include <linux/pm_runtime.h>
 
 #include <linux/rtsx_usb.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #if defined(CONFIG_LEDS_CLASS) || (defined(CONFIG_LEDS_CLASS_MODULE) && \
                defined(CONFIG_MMC_REALTEK_USB_MODULE))
index 8999b97263af99a523b327f4726ffe25da0e6309..8fd80dac11bfdf4da44ff7bf5b3eb549b1caebd7 100644 (file)
@@ -852,6 +852,14 @@ static void th1520_sdhci_reset(struct sdhci_host *host, u8 mask)
 
        sdhci_reset(host, mask);
 
+       /* The T-Head 1520 SoC does not comply with the SDHCI specification
+        * regarding the "Software Reset for CMD line should clear 'Command
+        * Complete' in the Normal Interrupt Status Register." Clear the bit
+        * here to compensate for this quirk.
+        */
+       if (mask & SDHCI_RESET_CMD)
+               sdhci_writel(host, SDHCI_INT_RESPONSE, SDHCI_INT_STATUS);
+
        if (priv->flags & FLAG_IO_FIXED_1V8) {
                ctrl_2 = sdhci_readw(host, SDHCI_HOST_CONTROL2);
                if (!(ctrl_2 & SDHCI_CTRL_VDD_180)) {
index 78174c463b368652b28836ed75dcb05372ff6f4e..f0f0522b2fa254e8903c2c6443e8b2d6c277b3d1 100644 (file)
@@ -22,7 +22,7 @@
 #include <linux/slab.h>
 #include <linux/types.h>
 #include <linux/units.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #define EBU_CLC                        0x000
 #define EBU_CLC_RST            0x00000000u
index 26648b72e691f407caca33d9a78e23b586c46a74..aa113a5d88c89e1fc445b4bff816108be00020ec 100644 (file)
@@ -84,7 +84,7 @@
 #include <linux/slab.h>
 #include <linux/mfd/syscon.h>
 #include <linux/regmap.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #include <linux/dmaengine.h>
 #include <linux/dma-mapping.h>
index 3e7526274e34bb5b03c9134b710189dababc4c5d..3bc56517fe7a99d96dd43750a8ddd21961138e41 100644 (file)
@@ -12,7 +12,7 @@
 // Copyright (c) 2019 Martin Sperl <[email protected]>
 //
 
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include <linux/bitfield.h>
 #include <linux/clk.h>
 #include <linux/device.h>
index 65150e762007201e522449bbb3c1a273dbd14bd9..8c5be8d1c51965e0e0daac51aa86ba3b5be2b1cf 100644 (file)
@@ -8,7 +8,7 @@
 
 #include "mcp251xfd.h"
 
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 static const struct regmap_config mcp251xfd_regmap_crc;
 
index 83c18035b2a24dc30695c4aa3d18c7a3b32af3db..e684991fa3917d4f6b6ebda8329f72971237574e 100644 (file)
@@ -12,7 +12,7 @@
 // Copyright (c) 2019 Martin Sperl <[email protected]>
 //
 
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #include "mcp251xfd.h"
 #include "mcp251xfd-ram.h"
index b1de8052a45ccb41a3feaa0550704ab8c112fc89..747ae3e8a768592f45972738d9af9692226829ac 100644 (file)
@@ -12,7 +12,7 @@
 // Copyright (c) 2019 Martin Sperl <[email protected]>
 //
 
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include <linux/bitfield.h>
 
 #include "mcp251xfd.h"
index 4151b18fd045daf816ac95550977ad5ac3b4f9bc..1888ca1de7b6a875b3b2f7a351901e857d2aa3d0 100644 (file)
@@ -9,7 +9,7 @@
  * Copyright (c) 2020-2022 Vincent Mailhol <[email protected]>
  */
 
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include <linux/kernel.h>
 #include <linux/units.h>
 
index 5e3a72b7c46919dc69d454e6004575c104bfe937..71f24dc0a927118af04ab345aae5ee3da5a3d34d 100644 (file)
@@ -10,7 +10,7 @@
  * Copyright (c) 2020-2022 Vincent Mailhol <[email protected]>
  */
 
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include <linux/crc16.h>
 #include <linux/ethtool.h>
 #include <linux/kernel.h>
index fa87b0b78e3eb5f39d5dd17151f47ccb4da32f3d..84ffa1839bac1136688c65806cba39ed7086eb3b 100644 (file)
@@ -11,7 +11,7 @@
  * Copyright (c) 2020-2022 Vincent Mailhol <[email protected]>
  */
 
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include <linux/kernel.h>
 #include <linux/units.h>
 
index ec8cef7fd2d535b39fe914ecd0ca161cf96ba573..bc0c8903fe77946e252660118d15e015da6e6cdd 100644 (file)
@@ -13,7 +13,7 @@
 #include <linux/can/error.h>
 #include <linux/can/platform/sja1000.h>
 
-#include <asm-generic/unaligned.h>
+#include <linux/unaligned.h>
 
 /* vendor and product id */
 #define F81604_VENDOR_ID 0x2c42
index 47619e9cb0055b8abcddcc5bc07758cda3266aa9..41c0a1c399bf36104fbf8991b537acdb01e7e950 100644 (file)
@@ -6,7 +6,7 @@
  * This driver is inspired by the 4.6.2 version of net/can/usb/usb_8dev.c
  */
 
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include <linux/can.h>
 #include <linux/can/dev.h>
 #include <linux/can/error.h>
index b211b6e283a2c0dfb104a22f0a057404b326cfc7..c75df1755b3b9529c9231e107ad58778a5e734a9 100644 (file)
@@ -8,7 +8,7 @@
  *
  * Many thanks to Klaus Hitschler <[email protected]>
  */
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #include <linux/ethtool.h>
 #include <linux/module.h>
index 0783fc121bbbf979abe6c9985b10cf4379bf2a9b..c39cb119e760db5fcbfaaf44abe033f6977e7005 100644 (file)
@@ -27,6 +27,7 @@
 #include <linux/phylink.h>
 #include <linux/etherdevice.h>
 #include <linux/if_bridge.h>
+#include <linux/if_vlan.h>
 #include <net/dsa.h>
 
 #include "b53_regs.h"
@@ -224,6 +225,9 @@ static const struct b53_mib_desc b53_mibs_58xx[] = {
 
 #define B53_MIBS_58XX_SIZE     ARRAY_SIZE(b53_mibs_58xx)
 
+#define B53_MAX_MTU_25         (1536 - ETH_HLEN - VLAN_HLEN - ETH_FCS_LEN)
+#define B53_MAX_MTU            (9720 - ETH_HLEN - VLAN_HLEN - ETH_FCS_LEN)
+
 static int b53_do_vlan_op(struct b53_device *dev, u8 op)
 {
        unsigned int i;
@@ -2254,20 +2258,25 @@ static int b53_change_mtu(struct dsa_switch *ds, int port, int mtu)
        bool allow_10_100;
 
        if (is5325(dev) || is5365(dev))
-               return -EOPNOTSUPP;
+               return 0;
 
        if (!dsa_is_cpu_port(ds, port))
                return 0;
 
-       enable_jumbo = (mtu >= JMS_MIN_SIZE);
-       allow_10_100 = (dev->chip_id == BCM583XX_DEVICE_ID);
+       enable_jumbo = (mtu > ETH_DATA_LEN);
+       allow_10_100 = !is63xx(dev);
 
        return b53_set_jumbo(dev, enable_jumbo, allow_10_100);
 }
 
 static int b53_get_max_mtu(struct dsa_switch *ds, int port)
 {
-       return JMS_MAX_SIZE;
+       struct b53_device *dev = ds->priv;
+
+       if (is5325(dev) || is5365(dev))
+               return B53_MAX_MTU_25;
+
+       return B53_MAX_MTU;
 }
 
 static const struct phylink_mac_ops b53_phylink_mac_ops = {
index 308f15d3832e8aca0c349c7c94222b8ca14bd737..467da057579e5b88f3332663627e746100be4c49 100644 (file)
@@ -16,7 +16,7 @@
  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  */
 
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #include <linux/delay.h>
 #include <linux/kernel.h>
index 268949939636a0e406554647fef0854129142e8d..d246f95d57ecf8ef648e9cfa259fca1d174b033c 100644 (file)
@@ -6,6 +6,7 @@
 #include <linux/module.h>
 #include <linux/gpio/consumer.h>
 #include <linux/regmap.h>
+#include <linux/iopoll.h>
 #include <linux/mutex.h>
 #include <linux/mii.h>
 #include <linux/of.h>
@@ -839,6 +840,8 @@ static void lan9303_handle_reset(struct lan9303 *chip)
        if (!chip->reset_gpio)
                return;
 
+       gpiod_set_value_cansleep(chip->reset_gpio, 1);
+
        if (chip->reset_duration != 0)
                msleep(chip->reset_duration);
 
@@ -864,8 +867,34 @@ static int lan9303_disable_processing(struct lan9303 *chip)
 static int lan9303_check_device(struct lan9303 *chip)
 {
        int ret;
+       int err;
        u32 reg;
 
+       /* In I2C-managed configurations this polling loop will clash with
+        * switch's reading of EEPROM right after reset and this behaviour is
+        * not configurable. While lan9303_read() already has quite long retry
+        * timeout, seems not all cases are being detected as arbitration error.
+        *
+        * According to datasheet, EEPROM loader has 30ms timeout (in case of
+        * missing EEPROM).
+        *
+        * Loading of the largest supported EEPROM is expected to take at least
+        * 5.9s.
+        */
+       err = read_poll_timeout(lan9303_read, ret,
+                               !ret && reg & LAN9303_HW_CFG_READY,
+                               20000, 6000000, false,
+                               chip->regmap, LAN9303_HW_CFG, &reg);
+       if (ret) {
+               dev_err(chip->dev, "failed to read HW_CFG reg: %pe\n",
+                       ERR_PTR(ret));
+               return ret;
+       }
+       if (err) {
+               dev_err(chip->dev, "HW_CFG not ready: 0x%08x\n", reg);
+               return err;
+       }
+
        ret = lan9303_read(chip->regmap, LAN9303_CHIP_REV, &reg);
        if (ret) {
                dev_err(chip->dev, "failed to read chip revision register: %d\n",
index 4e8710c7cb7bb2c1b19104009d7cfb0a91fc0a31..5290f5ad98f39236d2359ff3572ff583b2249884 100644 (file)
@@ -2733,26 +2733,27 @@ static u32 ksz_get_phy_flags(struct dsa_switch *ds, int port)
                        return MICREL_KSZ8_P1_ERRATA;
                break;
        case KSZ8567_CHIP_ID:
+               /* KSZ8567R Errata DS80000752C Module 4 */
+       case KSZ8765_CHIP_ID:
+       case KSZ8794_CHIP_ID:
+       case KSZ8795_CHIP_ID:
+               /* KSZ879x/KSZ877x/KSZ876x Errata DS80000687C Module 2 */
        case KSZ9477_CHIP_ID:
+               /* KSZ9477S Errata DS80000754A Module 4 */
        case KSZ9567_CHIP_ID:
+               /* KSZ9567S Errata DS80000756A Module 4 */
        case KSZ9896_CHIP_ID:
+               /* KSZ9896C Errata DS80000757A Module 3 */
        case KSZ9897_CHIP_ID:
-               /* KSZ9477 Errata DS80000754C
-                *
-                * Module 4: Energy Efficient Ethernet (EEE) feature select must
-                * be manually disabled
+               /* KSZ9897R Errata DS80000758C Module 4 */
+               /* Energy Efficient Ethernet (EEE) feature select must be manually disabled
                 *   The EEE feature is enabled by default, but it is not fully
                 *   operational. It must be manually disabled through register
                 *   controls. If not disabled, the PHY ports can auto-negotiate
                 *   to enable EEE, and this feature can cause link drops when
                 *   linked to another device supporting EEE.
                 *
-                * The same item appears in the errata for the KSZ9567, KSZ9896,
-                * and KSZ9897.
-                *
-                * A similar item appears in the errata for the KSZ8567, but
-                * provides an alternative workaround. For now, use the simple
-                * workaround of disabling the EEE feature for this device too.
+                * The same item appears in the errata for all switches above.
                 */
                return MICREL_NO_EEE;
        }
index e3e341431f095459d4a8f665379a5ab3c2cf0720..1c6652f2b9fee0ee7117a60fb412c998601ae443 100644 (file)
@@ -6,7 +6,7 @@
  *     Tristram Ha <[email protected]>
  */
 
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #include <linux/delay.h>
 #include <linux/kernel.h>
index 5b4e2ce5470d9bc05603b6f4961957d2798c6653..284270a4ade1c188679d83995126cf99345af0ec 100644 (file)
@@ -6347,7 +6347,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {
                .invalid_port_mask = BIT(1) | BIT(2) | BIT(8),
                .num_internal_phys = 5,
                .internal_phys_offset = 3,
-               .max_vid = 4095,
+               .max_vid = 8191,
                .max_sid = 63,
                .port_base_addr = 0x0,
                .phy_base_addr = 0x0,
index c34caf9815c5cb12a889adc2645765ad1b3c1199..a54682240839627979007a597df376054f6c26a3 100644 (file)
@@ -206,6 +206,7 @@ struct mv88e6xxx_gpio_ops;
 struct mv88e6xxx_avb_ops;
 struct mv88e6xxx_ptp_ops;
 struct mv88e6xxx_pcs_ops;
+struct mv88e6xxx_cc_coeffs;
 
 struct mv88e6xxx_irq {
        u16 masked;
@@ -408,6 +409,7 @@ struct mv88e6xxx_chip {
        struct cyclecounter     tstamp_cc;
        struct timecounter      tstamp_tc;
        struct delayed_work     overflow_work;
+       const struct mv88e6xxx_cc_coeffs *cc_coeffs;
 
        struct ptp_clock        *ptp_clock;
        struct ptp_clock_info   ptp_clock_info;
@@ -731,10 +733,6 @@ struct mv88e6xxx_ptp_ops {
        int arr1_sts_reg;
        int dep_sts_reg;
        u32 rx_filters;
-       u32 cc_shift;
-       u32 cc_mult;
-       u32 cc_mult_num;
-       u32 cc_mult_dem;
 };
 
 struct mv88e6xxx_pcs_ops {
index 5394a8cf7bf1d470ef39af472434936e7057fda3..04053fdc6489af2b6c5c7e83ba85d3c280d5104f 100644 (file)
@@ -1713,6 +1713,7 @@ int mv88e6393x_port_set_policy(struct mv88e6xxx_chip *chip, int port,
        ptr = shift / 8;
        shift %= 8;
        mask >>= ptr * 8;
+       ptr <<= 8;
 
        err = mv88e6393x_port_policy_read(chip, port, ptr, &reg);
        if (err)
index 56391e09b3257eefe51d88282fe11ef82bf30dbc..aed4a4b07f34b1643a8bf51c2501d1f61ef0cf0b 100644 (file)
 
 #define MV88E6XXX_MAX_ADJ_PPB  1000000
 
+struct mv88e6xxx_cc_coeffs {
+       u32 cc_shift;
+       u32 cc_mult;
+       u32 cc_mult_num;
+       u32 cc_mult_dem;
+};
+
 /* Family MV88E6250:
  * Raw timestamps are in units of 10-ns clock periods.
  *
  * simplifies to
  * clkadj = scaled_ppm * 2^7 / 5^5
  */
-#define MV88E6250_CC_SHIFT     28
-#define MV88E6250_CC_MULT      (10 << MV88E6250_CC_SHIFT)
-#define MV88E6250_CC_MULT_NUM  (1 << 7)
-#define MV88E6250_CC_MULT_DEM  3125ULL
+#define MV88E6XXX_CC_10NS_SHIFT 28
+static const struct mv88e6xxx_cc_coeffs mv88e6xxx_cc_10ns_coeffs = {
+       .cc_shift = MV88E6XXX_CC_10NS_SHIFT,
+       .cc_mult = 10 << MV88E6XXX_CC_10NS_SHIFT,
+       .cc_mult_num = 1 << 7,
+       .cc_mult_dem = 3125ULL,
+};
 
-/* Other families:
+/* Other families except MV88E6393X in internal clock mode:
  * Raw timestamps are in units of 8-ns clock periods.
  *
  * clkadj = scaled_ppm * 8*2^28 / (10^6 * 2^16)
  * simplifies to
  * clkadj = scaled_ppm * 2^9 / 5^6
  */
-#define MV88E6XXX_CC_SHIFT     28
-#define MV88E6XXX_CC_MULT      (8 << MV88E6XXX_CC_SHIFT)
-#define MV88E6XXX_CC_MULT_NUM  (1 << 9)
-#define MV88E6XXX_CC_MULT_DEM  15625ULL
+#define MV88E6XXX_CC_8NS_SHIFT 28
+static const struct mv88e6xxx_cc_coeffs mv88e6xxx_cc_8ns_coeffs = {
+       .cc_shift = MV88E6XXX_CC_8NS_SHIFT,
+       .cc_mult = 8 << MV88E6XXX_CC_8NS_SHIFT,
+       .cc_mult_num = 1 << 9,
+       .cc_mult_dem = 15625ULL
+};
+
+/* Family MV88E6393X using internal clock:
+ * Raw timestamps are in units of 4-ns clock periods.
+ *
+ * clkadj = scaled_ppm * 4*2^28 / (10^6 * 2^16)
+ * simplifies to
+ * clkadj = scaled_ppm * 2^8 / 5^6
+ */
+#define MV88E6XXX_CC_4NS_SHIFT 28
+static const struct mv88e6xxx_cc_coeffs mv88e6xxx_cc_4ns_coeffs = {
+       .cc_shift = MV88E6XXX_CC_4NS_SHIFT,
+       .cc_mult = 4 << MV88E6XXX_CC_4NS_SHIFT,
+       .cc_mult_num = 1 << 8,
+       .cc_mult_dem = 15625ULL
+};
 
 #define TAI_EVENT_WORK_INTERVAL msecs_to_jiffies(100)
 
@@ -83,6 +111,33 @@ static int mv88e6352_set_gpio_func(struct mv88e6xxx_chip *chip, int pin,
        return chip->info->ops->gpio_ops->set_pctl(chip, pin, func);
 }
 
+static const struct mv88e6xxx_cc_coeffs *
+mv88e6xxx_cc_coeff_get(struct mv88e6xxx_chip *chip)
+{
+       u16 period_ps;
+       int err;
+
+       err = mv88e6xxx_tai_read(chip, MV88E6XXX_TAI_CLOCK_PERIOD, &period_ps, 1);
+       if (err) {
+               dev_err(chip->dev, "failed to read cycle counter period: %d\n",
+                       err);
+               return ERR_PTR(err);
+       }
+
+       switch (period_ps) {
+       case 4000:
+               return &mv88e6xxx_cc_4ns_coeffs;
+       case 8000:
+               return &mv88e6xxx_cc_8ns_coeffs;
+       case 10000:
+               return &mv88e6xxx_cc_10ns_coeffs;
+       default:
+               dev_err(chip->dev, "unexpected cycle counter period of %u ps\n",
+                       period_ps);
+               return ERR_PTR(-ENODEV);
+       }
+}
+
 static u64 mv88e6352_ptp_clock_read(const struct cyclecounter *cc)
 {
        struct mv88e6xxx_chip *chip = cc_to_chip(cc);
@@ -204,7 +259,6 @@ out:
 static int mv88e6xxx_ptp_adjfine(struct ptp_clock_info *ptp, long scaled_ppm)
 {
        struct mv88e6xxx_chip *chip = ptp_to_chip(ptp);
-       const struct mv88e6xxx_ptp_ops *ptp_ops = chip->info->ops->ptp_ops;
        int neg_adj = 0;
        u32 diff, mult;
        u64 adj;
@@ -214,10 +268,10 @@ static int mv88e6xxx_ptp_adjfine(struct ptp_clock_info *ptp, long scaled_ppm)
                scaled_ppm = -scaled_ppm;
        }
 
-       mult = ptp_ops->cc_mult;
-       adj = ptp_ops->cc_mult_num;
+       mult = chip->cc_coeffs->cc_mult;
+       adj = chip->cc_coeffs->cc_mult_num;
        adj *= scaled_ppm;
-       diff = div_u64(adj, ptp_ops->cc_mult_dem);
+       diff = div_u64(adj, chip->cc_coeffs->cc_mult_dem);
 
        mv88e6xxx_reg_lock(chip);
 
@@ -364,10 +418,6 @@ const struct mv88e6xxx_ptp_ops mv88e6165_ptp_ops = {
                (1 << HWTSTAMP_FILTER_PTP_V2_EVENT) |
                (1 << HWTSTAMP_FILTER_PTP_V2_SYNC) |
                (1 << HWTSTAMP_FILTER_PTP_V2_DELAY_REQ),
-       .cc_shift = MV88E6XXX_CC_SHIFT,
-       .cc_mult = MV88E6XXX_CC_MULT,
-       .cc_mult_num = MV88E6XXX_CC_MULT_NUM,
-       .cc_mult_dem = MV88E6XXX_CC_MULT_DEM,
 };
 
 const struct mv88e6xxx_ptp_ops mv88e6250_ptp_ops = {
@@ -391,10 +441,6 @@ const struct mv88e6xxx_ptp_ops mv88e6250_ptp_ops = {
                (1 << HWTSTAMP_FILTER_PTP_V2_EVENT) |
                (1 << HWTSTAMP_FILTER_PTP_V2_SYNC) |
                (1 << HWTSTAMP_FILTER_PTP_V2_DELAY_REQ),
-       .cc_shift = MV88E6250_CC_SHIFT,
-       .cc_mult = MV88E6250_CC_MULT,
-       .cc_mult_num = MV88E6250_CC_MULT_NUM,
-       .cc_mult_dem = MV88E6250_CC_MULT_DEM,
 };
 
 const struct mv88e6xxx_ptp_ops mv88e6352_ptp_ops = {
@@ -418,10 +464,6 @@ const struct mv88e6xxx_ptp_ops mv88e6352_ptp_ops = {
                (1 << HWTSTAMP_FILTER_PTP_V2_EVENT) |
                (1 << HWTSTAMP_FILTER_PTP_V2_SYNC) |
                (1 << HWTSTAMP_FILTER_PTP_V2_DELAY_REQ),
-       .cc_shift = MV88E6XXX_CC_SHIFT,
-       .cc_mult = MV88E6XXX_CC_MULT,
-       .cc_mult_num = MV88E6XXX_CC_MULT_NUM,
-       .cc_mult_dem = MV88E6XXX_CC_MULT_DEM,
 };
 
 const struct mv88e6xxx_ptp_ops mv88e6390_ptp_ops = {
@@ -446,10 +488,6 @@ const struct mv88e6xxx_ptp_ops mv88e6390_ptp_ops = {
                (1 << HWTSTAMP_FILTER_PTP_V2_EVENT) |
                (1 << HWTSTAMP_FILTER_PTP_V2_SYNC) |
                (1 << HWTSTAMP_FILTER_PTP_V2_DELAY_REQ),
-       .cc_shift = MV88E6XXX_CC_SHIFT,
-       .cc_mult = MV88E6XXX_CC_MULT,
-       .cc_mult_num = MV88E6XXX_CC_MULT_NUM,
-       .cc_mult_dem = MV88E6XXX_CC_MULT_DEM,
 };
 
 static u64 mv88e6xxx_ptp_clock_read(const struct cyclecounter *cc)
@@ -462,10 +500,10 @@ static u64 mv88e6xxx_ptp_clock_read(const struct cyclecounter *cc)
        return 0;
 }
 
-/* With a 125MHz input clock, the 32-bit timestamp counter overflows in ~34.3
+/* With a 250MHz input clock, the 32-bit timestamp counter overflows in ~17.2
  * seconds; this task forces periodic reads so that we don't miss any.
  */
-#define MV88E6XXX_TAI_OVERFLOW_PERIOD (HZ * 16)
+#define MV88E6XXX_TAI_OVERFLOW_PERIOD (HZ * 8)
 static void mv88e6xxx_ptp_overflow_check(struct work_struct *work)
 {
        struct delayed_work *dw = to_delayed_work(work);
@@ -484,11 +522,15 @@ int mv88e6xxx_ptp_setup(struct mv88e6xxx_chip *chip)
        int i;
 
        /* Set up the cycle counter */
+       chip->cc_coeffs = mv88e6xxx_cc_coeff_get(chip);
+       if (IS_ERR(chip->cc_coeffs))
+               return PTR_ERR(chip->cc_coeffs);
+
        memset(&chip->tstamp_cc, 0, sizeof(chip->tstamp_cc));
        chip->tstamp_cc.read    = mv88e6xxx_ptp_clock_read;
        chip->tstamp_cc.mask    = CYCLECOUNTER_MASK(32);
-       chip->tstamp_cc.mult    = ptp_ops->cc_mult;
-       chip->tstamp_cc.shift   = ptp_ops->cc_shift;
+       chip->tstamp_cc.mult    = chip->cc_coeffs->cc_mult;
+       chip->tstamp_cc.shift   = chip->cc_coeffs->cc_shift;
 
        timecounter_init(&chip->tstamp_tc, &chip->tstamp_cc,
                         ktime_to_ns(ktime_get_real()));
index bc7e50dcb57c774588863f363804ed6f3a013deb..d0563ef59acf649952e7c6001b05c849ee948671 100644 (file)
@@ -3158,7 +3158,6 @@ static int sja1105_setup(struct dsa_switch *ds)
         * TPID is ETH_P_SJA1105, and the VLAN ID is the port pvid.
         */
        ds->vlan_filtering_is_global = true;
-       ds->untag_bridge_pvid = true;
        ds->fdb_isolation = true;
        ds->max_num_bridges = DSA_TAG_8021Q_MAX_NUM_BRIDGES;
 
index e4b98fd51643211e0dd58334a529f647c1f088a1..f18aa321053d75f34544267528d68ade37264e89 100644 (file)
@@ -851,7 +851,6 @@ static int vsc73xx_setup(struct dsa_switch *ds)
 
        dev_info(vsc->dev, "set up the switch\n");
 
-       ds->untag_bridge_pvid = true;
        ds->max_num_bridges = DSA_TAG_8021Q_MAX_NUM_BRIDGES;
        ds->fdb_isolation = true;
 
index 3431a7e62b0d2b3341be59a5e687b5ee9ff3354c..68fad5575fd4f836d4bb985590cd2188306c5be6 100644 (file)
@@ -26,7 +26,7 @@
 
 #include <net/switchdev.h>
 
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #define ADIN1110_PHY_ID                                0x1
 
@@ -318,11 +318,11 @@ static int adin1110_read_fifo(struct adin1110_port_priv *port_priv)
         * from the  ADIN1110 frame header.
         */
        if (frame_size < ADIN1110_FRAME_HEADER_LEN + ADIN1110_FEC_LEN)
-               return ret;
+               return -EINVAL;
 
        round_len = adin1110_round_len(frame_size);
        if (round_len < 0)
-               return ret;
+               return -EINVAL;
 
        frame_size_no_fcs = frame_size - ADIN1110_FRAME_HEADER_LEN - ADIN1110_FEC_LEN;
        memset(priv->data, 0, ADIN1110_RD_HEADER_LEN);
index 27af7746d645b81305ca79597f5bf4d1262a7a9f..adf6f67c5fcbade6d2acac1a7ea5b6a54d82f9d4 100644 (file)
@@ -484,7 +484,7 @@ greth_start_xmit_gbit(struct sk_buff *skb, struct net_device *dev)
 
        if (unlikely(skb->len > MAX_FRAME_SIZE)) {
                dev->stats.tx_errors++;
-               goto out;
+               goto len_error;
        }
 
        /* Save skb pointer. */
@@ -575,6 +575,7 @@ frag_map_error:
 map_error:
        if (net_ratelimit())
                dev_warn(greth->dev, "Could not create TX DMA mapping\n");
+len_error:
        dev_kfree_skb(skb);
 out:
        return err;
index c156566c09064c4904643e566a99a4cf5c218ef1..f19b04b92fa9f3870dd56dc0868206e45c709286 100644 (file)
@@ -105,10 +105,6 @@ static struct net_device * __init mvme147lance_probe(void)
        macaddr[3] = address&0xff;
        eth_hw_addr_set(dev, macaddr);
 
-       printk("%s: MVME147 at 0x%08lx, irq %d, Hardware Address %pM\n",
-              dev->name, dev->base_addr, MVME147_LANCE_IRQ,
-              dev->dev_addr);
-
        lp = netdev_priv(dev);
        lp->ram = __get_dma_pages(GFP_ATOMIC, 3);       /* 32K */
        if (!lp->ram) {
@@ -138,6 +134,9 @@ static struct net_device * __init mvme147lance_probe(void)
                return ERR_PTR(err);
        }
 
+       netdev_info(dev, "MVME147 at 0x%08lx, irq %d, Hardware Address %pM\n",
+                   dev->base_addr, MVME147_LANCE_IRQ, dev->dev_addr);
+
        return dev;
 }
 
index 484fc2b5626fe26f7ddf108874eb6e1ec817d8b3..ca163c8e372972bf567d864e770e4640086b761f 100644 (file)
@@ -1,7 +1,7 @@
 // SPDX-License-Identifier: GPL-2.0
 #define pr_fmt(fmt)                            "bcmasp_ethtool: " fmt
 
-#include <asm-generic/unaligned.h>
+#include <linux/unaligned.h>
 #include <linux/ethtool.h>
 #include <linux/netdevice.h>
 #include <linux/platform_device.h>
index 82768b0e90262b80b949b959b40151a0ddd0b6a9..9ea16ef4139d358002073ee1704ed45676523a79 100644 (file)
@@ -322,6 +322,7 @@ static netdev_tx_t bcmasp_xmit(struct sk_buff *skb, struct net_device *dev)
                        }
                        /* Rewind so we do not have a hole */
                        spb_index = intf->tx_spb_index;
+                       dev_kfree_skb(skb);
                        return NETDEV_TX_OK;
                }
 
index c9faa85408593b58d1022c01e4162af33b8ffab8..0a68b526e4a8213fd8f3536d6af46ff8d6a8ffc4 100644 (file)
@@ -1359,6 +1359,7 @@ static netdev_tx_t bcm_sysport_xmit(struct sk_buff *skb,
                netif_err(priv, tx_err, dev, "DMA map failed at %p (len=%d)\n",
                          skb->data, skb_len);
                ret = NETDEV_TX_OK;
+               dev_kfree_skb_any(skb);
                goto out;
        }
 
index 6e422e24750a281b9337ef3cc443b2dbe7af5abb..99d025b69079a8e69ba0fba05da63c7c31b4bc47 100644 (file)
@@ -2254,10 +2254,11 @@ static int bnxt_rx_pkt(struct bnxt *bp, struct bnxt_cp_ring_info *cpr,
 
                        if (!bnxt_get_rx_ts_p5(bp, &ts, cmpl_ts)) {
                                struct bnxt_ptp_cfg *ptp = bp->ptp_cfg;
+                               unsigned long flags;
 
-                               spin_lock_bh(&ptp->ptp_lock);
+                               spin_lock_irqsave(&ptp->ptp_lock, flags);
                                ns = timecounter_cyc2time(&ptp->tc, ts);
-                               spin_unlock_bh(&ptp->ptp_lock);
+                               spin_unlock_irqrestore(&ptp->ptp_lock, flags);
                                memset(skb_hwtstamps(skb), 0,
                                       sizeof(*skb_hwtstamps(skb)));
                                skb_hwtstamps(skb)->hwtstamp = ns_to_ktime(ns);
@@ -2757,17 +2758,18 @@ static int bnxt_async_event_process(struct bnxt *bp,
                case ASYNC_EVENT_CMPL_PHC_UPDATE_EVENT_DATA1_FLAGS_PHC_RTC_UPDATE:
                        if (BNXT_PTP_USE_RTC(bp)) {
                                struct bnxt_ptp_cfg *ptp = bp->ptp_cfg;
+                               unsigned long flags;
                                u64 ns;
 
                                if (!ptp)
                                        goto async_event_process_exit;
 
-                               spin_lock_bh(&ptp->ptp_lock);
+                               spin_lock_irqsave(&ptp->ptp_lock, flags);
                                bnxt_ptp_update_current_time(bp);
                                ns = (((u64)BNXT_EVENT_PHC_RTC_UPDATE(data1) <<
                                       BNXT_PHC_BITS) | ptp->current_time);
                                bnxt_ptp_rtc_timecounter_init(ptp, ns);
-                               spin_unlock_bh(&ptp->ptp_lock);
+                               spin_unlock_irqrestore(&ptp->ptp_lock, flags);
                        }
                        break;
                }
@@ -13494,9 +13496,11 @@ static void bnxt_force_fw_reset(struct bnxt *bp)
                return;
 
        if (ptp) {
-               spin_lock_bh(&ptp->ptp_lock);
+               unsigned long flags;
+
+               spin_lock_irqsave(&ptp->ptp_lock, flags);
                set_bit(BNXT_STATE_IN_FW_RESET, &bp->state);
-               spin_unlock_bh(&ptp->ptp_lock);
+               spin_unlock_irqrestore(&ptp->ptp_lock, flags);
        } else {
                set_bit(BNXT_STATE_IN_FW_RESET, &bp->state);
        }
@@ -13561,9 +13565,11 @@ void bnxt_fw_reset(struct bnxt *bp)
                int n = 0, tmo;
 
                if (ptp) {
-                       spin_lock_bh(&ptp->ptp_lock);
+                       unsigned long flags;
+
+                       spin_lock_irqsave(&ptp->ptp_lock, flags);
                        set_bit(BNXT_STATE_IN_FW_RESET, &bp->state);
-                       spin_unlock_bh(&ptp->ptp_lock);
+                       spin_unlock_irqrestore(&ptp->ptp_lock, flags);
                } else {
                        set_bit(BNXT_STATE_IN_FW_RESET, &bp->state);
                }
index 37d42423459c8eb1e35df763b4dd1a09bceed80a..fa514be87650286b181aa1c2a0acaca216333d4f 100644 (file)
@@ -62,13 +62,14 @@ static int bnxt_ptp_settime(struct ptp_clock_info *ptp_info,
        struct bnxt_ptp_cfg *ptp = container_of(ptp_info, struct bnxt_ptp_cfg,
                                                ptp_info);
        u64 ns = timespec64_to_ns(ts);
+       unsigned long flags;
 
        if (BNXT_PTP_USE_RTC(ptp->bp))
                return bnxt_ptp_cfg_settime(ptp->bp, ns);
 
-       spin_lock_bh(&ptp->ptp_lock);
+       spin_lock_irqsave(&ptp->ptp_lock, flags);
        timecounter_init(&ptp->tc, &ptp->cc, ns);
-       spin_unlock_bh(&ptp->ptp_lock);
+       spin_unlock_irqrestore(&ptp->ptp_lock, flags);
        return 0;
 }
 
@@ -100,13 +101,14 @@ static int bnxt_refclk_read(struct bnxt *bp, struct ptp_system_timestamp *sts,
 static void bnxt_ptp_get_current_time(struct bnxt *bp)
 {
        struct bnxt_ptp_cfg *ptp = bp->ptp_cfg;
+       unsigned long flags;
 
        if (!ptp)
                return;
-       spin_lock_bh(&ptp->ptp_lock);
+       spin_lock_irqsave(&ptp->ptp_lock, flags);
        WRITE_ONCE(ptp->old_time, ptp->current_time);
        bnxt_refclk_read(bp, NULL, &ptp->current_time);
-       spin_unlock_bh(&ptp->ptp_lock);
+       spin_unlock_irqrestore(&ptp->ptp_lock, flags);
 }
 
 static int bnxt_hwrm_port_ts_query(struct bnxt *bp, u32 flags, u64 *ts,
@@ -149,17 +151,18 @@ static int bnxt_ptp_gettimex(struct ptp_clock_info *ptp_info,
 {
        struct bnxt_ptp_cfg *ptp = container_of(ptp_info, struct bnxt_ptp_cfg,
                                                ptp_info);
+       unsigned long flags;
        u64 ns, cycles;
        int rc;
 
-       spin_lock_bh(&ptp->ptp_lock);
+       spin_lock_irqsave(&ptp->ptp_lock, flags);
        rc = bnxt_refclk_read(ptp->bp, sts, &cycles);
        if (rc) {
-               spin_unlock_bh(&ptp->ptp_lock);
+               spin_unlock_irqrestore(&ptp->ptp_lock, flags);
                return rc;
        }
        ns = timecounter_cyc2time(&ptp->tc, cycles);
-       spin_unlock_bh(&ptp->ptp_lock);
+       spin_unlock_irqrestore(&ptp->ptp_lock, flags);
        *ts = ns_to_timespec64(ns);
 
        return 0;
@@ -177,6 +180,7 @@ void bnxt_ptp_update_current_time(struct bnxt *bp)
 static int bnxt_ptp_adjphc(struct bnxt_ptp_cfg *ptp, s64 delta)
 {
        struct hwrm_port_mac_cfg_input *req;
+       unsigned long flags;
        int rc;
 
        rc = hwrm_req_init(ptp->bp, req, HWRM_PORT_MAC_CFG);
@@ -190,9 +194,9 @@ static int bnxt_ptp_adjphc(struct bnxt_ptp_cfg *ptp, s64 delta)
        if (rc) {
                netdev_err(ptp->bp->dev, "ptp adjphc failed. rc = %x\n", rc);
        } else {
-               spin_lock_bh(&ptp->ptp_lock);
+               spin_lock_irqsave(&ptp->ptp_lock, flags);
                bnxt_ptp_update_current_time(ptp->bp);
-               spin_unlock_bh(&ptp->ptp_lock);
+               spin_unlock_irqrestore(&ptp->ptp_lock, flags);
        }
 
        return rc;
@@ -202,13 +206,14 @@ static int bnxt_ptp_adjtime(struct ptp_clock_info *ptp_info, s64 delta)
 {
        struct bnxt_ptp_cfg *ptp = container_of(ptp_info, struct bnxt_ptp_cfg,
                                                ptp_info);
+       unsigned long flags;
 
        if (BNXT_PTP_USE_RTC(ptp->bp))
                return bnxt_ptp_adjphc(ptp, delta);
 
-       spin_lock_bh(&ptp->ptp_lock);
+       spin_lock_irqsave(&ptp->ptp_lock, flags);
        timecounter_adjtime(&ptp->tc, delta);
-       spin_unlock_bh(&ptp->ptp_lock);
+       spin_unlock_irqrestore(&ptp->ptp_lock, flags);
        return 0;
 }
 
@@ -236,14 +241,15 @@ static int bnxt_ptp_adjfine(struct ptp_clock_info *ptp_info, long scaled_ppm)
        struct bnxt_ptp_cfg *ptp = container_of(ptp_info, struct bnxt_ptp_cfg,
                                                ptp_info);
        struct bnxt *bp = ptp->bp;
+       unsigned long flags;
 
        if (!BNXT_MH(bp))
                return bnxt_ptp_adjfine_rtc(bp, scaled_ppm);
 
-       spin_lock_bh(&ptp->ptp_lock);
+       spin_lock_irqsave(&ptp->ptp_lock, flags);
        timecounter_read(&ptp->tc);
        ptp->cc.mult = adjust_by_scaled_ppm(ptp->cmult, scaled_ppm);
-       spin_unlock_bh(&ptp->ptp_lock);
+       spin_unlock_irqrestore(&ptp->ptp_lock, flags);
        return 0;
 }
 
@@ -251,12 +257,13 @@ void bnxt_ptp_pps_event(struct bnxt *bp, u32 data1, u32 data2)
 {
        struct bnxt_ptp_cfg *ptp = bp->ptp_cfg;
        struct ptp_clock_event event;
+       unsigned long flags;
        u64 ns, pps_ts;
 
        pps_ts = EVENT_PPS_TS(data2, data1);
-       spin_lock_bh(&ptp->ptp_lock);
+       spin_lock_irqsave(&ptp->ptp_lock, flags);
        ns = timecounter_cyc2time(&ptp->tc, pps_ts);
-       spin_unlock_bh(&ptp->ptp_lock);
+       spin_unlock_irqrestore(&ptp->ptp_lock, flags);
 
        switch (EVENT_DATA2_PPS_EVENT_TYPE(data2)) {
        case ASYNC_EVENT_CMPL_PPS_TIMESTAMP_EVENT_DATA2_EVENT_TYPE_INTERNAL:
@@ -393,16 +400,17 @@ static int bnxt_get_target_cycles(struct bnxt_ptp_cfg *ptp, u64 target_ns,
 {
        u64 cycles_now;
        u64 nsec_now, nsec_delta;
+       unsigned long flags;
        int rc;
 
-       spin_lock_bh(&ptp->ptp_lock);
+       spin_lock_irqsave(&ptp->ptp_lock, flags);
        rc = bnxt_refclk_read(ptp->bp, NULL, &cycles_now);
        if (rc) {
-               spin_unlock_bh(&ptp->ptp_lock);
+               spin_unlock_irqrestore(&ptp->ptp_lock, flags);
                return rc;
        }
        nsec_now = timecounter_cyc2time(&ptp->tc, cycles_now);
-       spin_unlock_bh(&ptp->ptp_lock);
+       spin_unlock_irqrestore(&ptp->ptp_lock, flags);
 
        nsec_delta = target_ns - nsec_now;
        *cycles_delta = div64_u64(nsec_delta << ptp->cc.shift, ptp->cc.mult);
@@ -689,6 +697,7 @@ static int bnxt_stamp_tx_skb(struct bnxt *bp, int slot)
        struct skb_shared_hwtstamps timestamp;
        struct bnxt_ptp_tx_req *txts_req;
        unsigned long now = jiffies;
+       unsigned long flags;
        u64 ts = 0, ns = 0;
        u32 tmo = 0;
        int rc;
@@ -702,9 +711,9 @@ static int bnxt_stamp_tx_skb(struct bnxt *bp, int slot)
                                     tmo, slot);
        if (!rc) {
                memset(&timestamp, 0, sizeof(timestamp));
-               spin_lock_bh(&ptp->ptp_lock);
+               spin_lock_irqsave(&ptp->ptp_lock, flags);
                ns = timecounter_cyc2time(&ptp->tc, ts);
-               spin_unlock_bh(&ptp->ptp_lock);
+               spin_unlock_irqrestore(&ptp->ptp_lock, flags);
                timestamp.hwtstamp = ns_to_ktime(ns);
                skb_tstamp_tx(txts_req->tx_skb, &timestamp);
                ptp->stats.ts_pkts++;
@@ -730,6 +739,7 @@ static long bnxt_ptp_ts_aux_work(struct ptp_clock_info *ptp_info)
        unsigned long now = jiffies;
        struct bnxt *bp = ptp->bp;
        u16 cons = ptp->txts_cons;
+       unsigned long flags;
        u32 num_requests;
        int rc = 0;
 
@@ -757,9 +767,9 @@ next_slot:
        bnxt_ptp_get_current_time(bp);
        ptp->next_period = now + HZ;
        if (time_after_eq(now, ptp->next_overflow_check)) {
-               spin_lock_bh(&ptp->ptp_lock);
+               spin_lock_irqsave(&ptp->ptp_lock, flags);
                timecounter_read(&ptp->tc);
-               spin_unlock_bh(&ptp->ptp_lock);
+               spin_unlock_irqrestore(&ptp->ptp_lock, flags);
                ptp->next_overflow_check = now + BNXT_PHC_OVERFLOW_PERIOD;
        }
        if (rc == -EAGAIN)
@@ -819,6 +829,7 @@ void bnxt_tx_ts_cmp(struct bnxt *bp, struct bnxt_napi *bnapi,
        u32 opaque = tscmp->tx_ts_cmp_opaque;
        struct bnxt_tx_ring_info *txr;
        struct bnxt_sw_tx_bd *tx_buf;
+       unsigned long flags;
        u64 ts, ns;
        u16 cons;
 
@@ -833,9 +844,9 @@ void bnxt_tx_ts_cmp(struct bnxt *bp, struct bnxt_napi *bnapi,
                                   le32_to_cpu(tscmp->tx_ts_cmp_flags_type),
                                   le32_to_cpu(tscmp->tx_ts_cmp_errors_v));
                } else {
-                       spin_lock_bh(&ptp->ptp_lock);
+                       spin_lock_irqsave(&ptp->ptp_lock, flags);
                        ns = timecounter_cyc2time(&ptp->tc, ts);
-                       spin_unlock_bh(&ptp->ptp_lock);
+                       spin_unlock_irqrestore(&ptp->ptp_lock, flags);
                        timestamp.hwtstamp = ns_to_ktime(ns);
                        skb_tstamp_tx(tx_buf->skb, &timestamp);
                }
@@ -975,6 +986,7 @@ void bnxt_ptp_rtc_timecounter_init(struct bnxt_ptp_cfg *ptp, u64 ns)
 int bnxt_ptp_init_rtc(struct bnxt *bp, bool phc_cfg)
 {
        struct timespec64 tsp;
+       unsigned long flags;
        u64 ns;
        int rc;
 
@@ -993,9 +1005,9 @@ int bnxt_ptp_init_rtc(struct bnxt *bp, bool phc_cfg)
                if (rc)
                        return rc;
        }
-       spin_lock_bh(&bp->ptp_cfg->ptp_lock);
+       spin_lock_irqsave(&bp->ptp_cfg->ptp_lock, flags);
        bnxt_ptp_rtc_timecounter_init(bp->ptp_cfg, ns);
-       spin_unlock_bh(&bp->ptp_cfg->ptp_lock);
+       spin_unlock_irqrestore(&bp->ptp_cfg->ptp_lock, flags);
 
        return 0;
 }
@@ -1063,10 +1075,12 @@ int bnxt_ptp_init(struct bnxt *bp, bool phc_cfg)
        atomic64_set(&ptp->stats.ts_err, 0);
 
        if (bp->flags & BNXT_FLAG_CHIP_P5_PLUS) {
-               spin_lock_bh(&ptp->ptp_lock);
+               unsigned long flags;
+
+               spin_lock_irqsave(&ptp->ptp_lock, flags);
                bnxt_refclk_read(bp, NULL, &ptp->current_time);
                WRITE_ONCE(ptp->old_time, ptp->current_time);
-               spin_unlock_bh(&ptp->ptp_lock);
+               spin_unlock_irqrestore(&ptp->ptp_lock, flags);
                ptp_schedule_worker(ptp->ptp_clock, 0);
        }
        ptp->txts_tmo = BNXT_PTP_DFLT_TX_TMO;
index a9a2f9a18c9ca120258d1d79aa49e3a0deaaca18..f322466ecad350da1bf213007370e29a261a2a0c 100644 (file)
@@ -146,11 +146,13 @@ struct bnxt_ptp_cfg {
 };
 
 #if BITS_PER_LONG == 32
-#define BNXT_READ_TIME64(ptp, dst, src)                \
-do {                                           \
-       spin_lock_bh(&(ptp)->ptp_lock);         \
-       (dst) = (src);                          \
-       spin_unlock_bh(&(ptp)->ptp_lock);       \
+#define BNXT_READ_TIME64(ptp, dst, src)                                \
+do {                                                           \
+       unsigned long flags;                                    \
+                                                               \
+       spin_lock_irqsave(&(ptp)->ptp_lock, flags);             \
+       (dst) = (src);                                          \
+       spin_unlock_irqrestore(&(ptp)->ptp_lock, flags);        \
 } while (0)
 #else
 #define BNXT_READ_TIME64(ptp, dst, src)                \
index c7e7dac057a336d086bdf9569286fadec7e1d3be..f7be886570d8875decf9682c98b162c5ff8a60b5 100644 (file)
@@ -37,7 +37,7 @@
 #include <linux/phy.h>
 #include <linux/platform_data/bcmgenet.h>
 
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #include "bcmgenet.h"
 
index f06babec04a0bf0a1095dd9e95ff60aa3ce07bef..56901280ba047290f91e809a5e31d96f737acd34 100644 (file)
@@ -930,9 +930,6 @@ static int macb_mdiobus_register(struct macb *bp)
                return ret;
        }
 
-       if (of_phy_is_fixed_link(np))
-               return mdiobus_register(bp->mii_bus);
-
        /* Only create the PHY from the device tree if at least one PHY is
         * described. Otherwise scan the entire MDIO bus. We do this to support
         * old device tree that did not follow the best practices and did not
@@ -953,8 +950,19 @@ static int macb_mdiobus_register(struct macb *bp)
 
 static int macb_mii_init(struct macb *bp)
 {
+       struct device_node *child, *np = bp->pdev->dev.of_node;
        int err = -ENXIO;
 
+       /* With fixed-link, we don't need to register the MDIO bus,
+        * except if we have a child named "mdio" in the device tree.
+        * In that case, some devices may be attached to the MACB's MDIO bus.
+        */
+       child = of_get_child_by_name(np, "mdio");
+       if (child)
+               of_node_put(child);
+       else if (of_phy_is_fixed_link(np))
+               return macb_mii_probe(bp->dev);
+
        /* Enable management port */
        macb_writel(bp, NCR, MACB_BIT(MPE));
 
index cd3dc4b89518f0849819da8c8b233d1638eb7e08..0a161a4db2426a66256f96b021b85b90d5dca471 100644 (file)
@@ -49,7 +49,7 @@
 #include <asm/io.h>
 #include <asm/irq.h>
 #include <linux/uaccess.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 MODULE_AUTHOR("Jeff Garzik <[email protected]>");
 MODULE_DESCRIPTION("Intel/Digital 21040/1 series PCI Ethernet driver");
index d5657ff15e3c4a027e24a6b869d35619acea1c20..71ff9e6db209a8097eb2756cf6239fa89507afcb 100644 (file)
@@ -13,7 +13,7 @@
 #include <linux/pci.h>
 #include <linux/slab.h>
 #include "tulip.h"
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 
 
index bd786dfbc066a407d23963fa373986f47232ef4c..5e010e1fa6f79c409538d0cbf8178cd0bdc3c5c8 100644 (file)
@@ -23,7 +23,7 @@
 #include <linux/pci.h>
 #include <asm/io.h>
 #include <asm/irq.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 
 
index ecfad43df45a7c9872386fe70b009b786b3571bd..27e01d780cd02eaf9c8a3488ca0f9df5b36159ce 100644 (file)
@@ -23,7 +23,7 @@
 #include <linux/delay.h>
 #include <linux/mii.h>
 #include <linux/crc32.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include <linux/uaccess.h>
 
 #ifdef CONFIG_SPARC
index a8596ebcdfd60e8d7418b63a3dedf8ed1af29d9b..875fe379eea213abcb69de189602bcacbcaa6f56 100644 (file)
@@ -1381,10 +1381,8 @@ static netdev_tx_t be_xmit(struct sk_buff *skb, struct net_device *netdev)
        be_get_wrb_params_from_skb(adapter, skb, &wrb_params);
 
        wrb_cnt = be_xmit_enqueue(adapter, txo, skb, &wrb_params);
-       if (unlikely(!wrb_cnt)) {
-               dev_kfree_skb_any(skb);
-               goto drop;
-       }
+       if (unlikely(!wrb_cnt))
+               goto drop_skb;
 
        /* if os2bmc is enabled and if the pkt is destined to bmc,
         * enqueue the pkt a 2nd time with mgmt bit set.
@@ -1393,7 +1391,7 @@ static netdev_tx_t be_xmit(struct sk_buff *skb, struct net_device *netdev)
                BE_WRB_F_SET(wrb_params.features, OS2BMC, 1);
                wrb_cnt = be_xmit_enqueue(adapter, txo, skb, &wrb_params);
                if (unlikely(!wrb_cnt))
-                       goto drop;
+                       goto drop_skb;
                else
                        skb_get(skb);
        }
@@ -1407,6 +1405,8 @@ static netdev_tx_t be_xmit(struct sk_buff *skb, struct net_device *netdev)
                be_xmit_flush(adapter, txo);
 
        return NETDEV_TX_OK;
+drop_skb:
+       dev_kfree_skb_any(skb);
 drop:
        tx_stats(txo)->tx_drv_drops++;
        /* Flush the already enqueued tx requests */
index f3cc14cc757d271688c23610aa0cc471f6f6d90b..0b61f548fd188f64344ff67136c882a49598f6d3 100644 (file)
@@ -1906,7 +1906,12 @@ static int ftgmac100_probe(struct platform_device *pdev)
                        goto err_phy_connect;
                }
 
-               phydev = fixed_phy_register(PHY_POLL, &ncsi_phy_status, NULL);
+               phydev = fixed_phy_register(PHY_POLL, &ncsi_phy_status, np);
+               if (IS_ERR(phydev)) {
+                       dev_err(&pdev->dev, "failed to register fixed PHY device\n");
+                       err = PTR_ERR(phydev);
+                       goto err_phy_connect;
+               }
                err = phy_connect_direct(netdev, phydev, ftgmac100_adjust_link,
                                         PHY_INTERFACE_MODE_MII);
                if (err) {
index 032d8eadd003f6dbfb3663b3fdff14d8685cedc2..c09370eab319b239d2334b80a5bf19668b170665 100644 (file)
@@ -902,6 +902,7 @@ static bool enetc_clean_tx_ring(struct enetc_bdr *tx_ring, int napi_budget)
 
        if (unlikely(tx_frm_cnt && netif_carrier_ok(ndev) &&
                     __netif_subqueue_stopped(ndev, tx_ring->index) &&
+                    !test_bit(ENETC_TX_DOWN, &priv->flags) &&
                     (enetc_bd_unused(tx_ring) >= ENETC_TXBDS_MAX_NEEDED))) {
                netif_wake_subqueue(ndev, tx_ring->index);
        }
@@ -1377,6 +1378,9 @@ int enetc_xdp_xmit(struct net_device *ndev, int num_frames,
        int xdp_tx_bd_cnt, i, k;
        int xdp_tx_frm_cnt = 0;
 
+       if (unlikely(test_bit(ENETC_TX_DOWN, &priv->flags)))
+               return -ENETDOWN;
+
        enetc_lock_mdio();
 
        tx_ring = priv->xdp_tx_ring[smp_processor_id()];
@@ -1521,7 +1525,6 @@ static void enetc_xdp_drop(struct enetc_bdr *rx_ring, int rx_ring_first,
                                  &rx_ring->rx_swbd[rx_ring_first]);
                enetc_bdr_idx_inc(rx_ring, &rx_ring_first);
        }
-       rx_ring->stats.xdp_drops++;
 }
 
 static int enetc_clean_rx_ring_xdp(struct enetc_bdr *rx_ring,
@@ -1586,6 +1589,7 @@ static int enetc_clean_rx_ring_xdp(struct enetc_bdr *rx_ring,
                        fallthrough;
                case XDP_DROP:
                        enetc_xdp_drop(rx_ring, orig_i, i);
+                       rx_ring->stats.xdp_drops++;
                        break;
                case XDP_PASS:
                        rxbd = orig_rxbd;
@@ -1602,6 +1606,12 @@ static int enetc_clean_rx_ring_xdp(struct enetc_bdr *rx_ring,
                        break;
                case XDP_TX:
                        tx_ring = priv->xdp_tx_ring[rx_ring->index];
+                       if (unlikely(test_bit(ENETC_TX_DOWN, &priv->flags))) {
+                               enetc_xdp_drop(rx_ring, orig_i, i);
+                               tx_ring->stats.xdp_tx_drops++;
+                               break;
+                       }
+
                        xdp_tx_bd_cnt = enetc_rx_swbd_to_xdp_tx_swbd(xdp_tx_arr,
                                                                     rx_ring,
                                                                     orig_i, i);
@@ -2223,18 +2233,24 @@ static void enetc_enable_rxbdr(struct enetc_hw *hw, struct enetc_bdr *rx_ring)
        enetc_rxbdr_wr(hw, idx, ENETC_RBMR, rbmr);
 }
 
-static void enetc_enable_bdrs(struct enetc_ndev_priv *priv)
+static void enetc_enable_rx_bdrs(struct enetc_ndev_priv *priv)
 {
        struct enetc_hw *hw = &priv->si->hw;
        int i;
 
-       for (i = 0; i < priv->num_tx_rings; i++)
-               enetc_enable_txbdr(hw, priv->tx_ring[i]);
-
        for (i = 0; i < priv->num_rx_rings; i++)
                enetc_enable_rxbdr(hw, priv->rx_ring[i]);
 }
 
+static void enetc_enable_tx_bdrs(struct enetc_ndev_priv *priv)
+{
+       struct enetc_hw *hw = &priv->si->hw;
+       int i;
+
+       for (i = 0; i < priv->num_tx_rings; i++)
+               enetc_enable_txbdr(hw, priv->tx_ring[i]);
+}
+
 static void enetc_disable_rxbdr(struct enetc_hw *hw, struct enetc_bdr *rx_ring)
 {
        int idx = rx_ring->index;
@@ -2251,18 +2267,24 @@ static void enetc_disable_txbdr(struct enetc_hw *hw, struct enetc_bdr *rx_ring)
        enetc_txbdr_wr(hw, idx, ENETC_TBMR, 0);
 }
 
-static void enetc_disable_bdrs(struct enetc_ndev_priv *priv)
+static void enetc_disable_rx_bdrs(struct enetc_ndev_priv *priv)
 {
        struct enetc_hw *hw = &priv->si->hw;
        int i;
 
-       for (i = 0; i < priv->num_tx_rings; i++)
-               enetc_disable_txbdr(hw, priv->tx_ring[i]);
-
        for (i = 0; i < priv->num_rx_rings; i++)
                enetc_disable_rxbdr(hw, priv->rx_ring[i]);
 }
 
+static void enetc_disable_tx_bdrs(struct enetc_ndev_priv *priv)
+{
+       struct enetc_hw *hw = &priv->si->hw;
+       int i;
+
+       for (i = 0; i < priv->num_tx_rings; i++)
+               enetc_disable_txbdr(hw, priv->tx_ring[i]);
+}
+
 static void enetc_wait_txbdr(struct enetc_hw *hw, struct enetc_bdr *tx_ring)
 {
        int delay = 8, timeout = 100;
@@ -2460,9 +2482,13 @@ void enetc_start(struct net_device *ndev)
                enable_irq(irq);
        }
 
-       enetc_enable_bdrs(priv);
+       enetc_enable_tx_bdrs(priv);
+
+       enetc_enable_rx_bdrs(priv);
 
        netif_tx_start_all_queues(ndev);
+
+       clear_bit(ENETC_TX_DOWN, &priv->flags);
 }
 EXPORT_SYMBOL_GPL(enetc_start);
 
@@ -2520,9 +2546,15 @@ void enetc_stop(struct net_device *ndev)
        struct enetc_ndev_priv *priv = netdev_priv(ndev);
        int i;
 
+       set_bit(ENETC_TX_DOWN, &priv->flags);
+
        netif_tx_stop_all_queues(ndev);
 
-       enetc_disable_bdrs(priv);
+       enetc_disable_rx_bdrs(priv);
+
+       enetc_wait_bdrs(priv);
+
+       enetc_disable_tx_bdrs(priv);
 
        for (i = 0; i < priv->bdr_int_num; i++) {
                int irq = pci_irq_vector(priv->si->pdev,
@@ -2533,8 +2565,6 @@ void enetc_stop(struct net_device *ndev)
                napi_disable(&priv->int_vector[i]->napi);
        }
 
-       enetc_wait_bdrs(priv);
-
        enetc_clear_interrupts(priv);
 }
 EXPORT_SYMBOL_GPL(enetc_stop);
index 97524dfa234c7dd0f10811fa815cc7eb2f3cd9d7..fb7d98d577839991bb4058431824df60a410cb2f 100644 (file)
@@ -325,6 +325,7 @@ enum enetc_active_offloads {
 
 enum enetc_flags_bit {
        ENETC_TX_ONESTEP_TSTAMP_IN_PROGRESS = 0,
+       ENETC_TX_DOWN,
 };
 
 /* interrupt coalescing modes */
index 11b14555802c9a638a02497ce485925f7f8f3a17..8f6b0bf48139ac2f6b3acf5edd80656ccbb36fed 100644 (file)
@@ -1,7 +1,7 @@
 // SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
 /* Copyright 2017-2019 NXP */
 
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include <linux/mdio.h>
 #include <linux/module.h>
 #include <linux/fsl/enetc_mdio.h>
index a19cb2a786fd2808e355dd91c057afa35c752f17..1cca0425d49397bbdb97f2c058bd759f9e602f17 100644 (file)
@@ -691,10 +691,19 @@ struct fec_enet_private {
        /* XDP BPF Program */
        struct bpf_prog *xdp_prog;
 
+       struct {
+               int pps_enable;
+               u64 ns_sys, ns_phc;
+               u32 at_corr;
+               u8 at_inc_corr;
+       } ptp_saved_state;
+
        u64 ethtool_stats[];
 };
 
 void fec_ptp_init(struct platform_device *pdev, int irq_idx);
+void fec_ptp_restore_state(struct fec_enet_private *fep);
+void fec_ptp_save_state(struct fec_enet_private *fep);
 void fec_ptp_stop(struct platform_device *pdev);
 void fec_ptp_start_cyclecounter(struct net_device *ndev);
 int fec_ptp_set(struct net_device *ndev, struct kernel_hwtstamp_config *config,
index acbb627d51bfa62adeaa43e8e044861f1573b2d6..9d9fcec41488e3699dcc5c3a50c658de5c641496 100644 (file)
@@ -1077,6 +1077,9 @@ fec_restart(struct net_device *ndev)
        u32 rcntl = OPT_FRAME_SIZE | 0x04;
        u32 ecntl = FEC_ECR_ETHEREN;
 
+       if (fep->bufdesc_ex)
+               fec_ptp_save_state(fep);
+
        /* Whack a reset.  We should wait for this.
         * For i.MX6SX SOC, enet use AXI bus, we use disable MAC
         * instead of reset MAC itself.
@@ -1244,8 +1247,10 @@ fec_restart(struct net_device *ndev)
        writel(ecntl, fep->hwp + FEC_ECNTRL);
        fec_enet_active_rxring(ndev);
 
-       if (fep->bufdesc_ex)
+       if (fep->bufdesc_ex) {
                fec_ptp_start_cyclecounter(ndev);
+               fec_ptp_restore_state(fep);
+       }
 
        /* Enable interrupts we wish to service */
        if (fep->link)
@@ -1336,6 +1341,9 @@ fec_stop(struct net_device *ndev)
                        netdev_err(ndev, "Graceful transmit stop did not complete!\n");
        }
 
+       if (fep->bufdesc_ex)
+               fec_ptp_save_state(fep);
+
        /* Whack a reset.  We should wait for this.
         * For i.MX6SX SOC, enet use AXI bus, we use disable MAC
         * instead of reset MAC itself.
@@ -1366,6 +1374,9 @@ fec_stop(struct net_device *ndev)
                val = readl(fep->hwp + FEC_ECNTRL);
                val |= FEC_ECR_EN1588;
                writel(val, fep->hwp + FEC_ECNTRL);
+
+               fec_ptp_start_cyclecounter(ndev);
+               fec_ptp_restore_state(fep);
        }
 }
 
index 4cffda363a148e0c170d07aadbd83cb2aec411a0..a4eb6edb850adda55df0b3b5eedb26b570be06f8 100644 (file)
@@ -764,6 +764,56 @@ void fec_ptp_init(struct platform_device *pdev, int irq_idx)
        schedule_delayed_work(&fep->time_keep, HZ);
 }
 
+void fec_ptp_save_state(struct fec_enet_private *fep)
+{
+       unsigned long flags;
+       u32 atime_inc_corr;
+
+       spin_lock_irqsave(&fep->tmreg_lock, flags);
+
+       fep->ptp_saved_state.pps_enable = fep->pps_enable;
+
+       fep->ptp_saved_state.ns_phc = timecounter_read(&fep->tc);
+       fep->ptp_saved_state.ns_sys = ktime_get_ns();
+
+       fep->ptp_saved_state.at_corr = readl(fep->hwp + FEC_ATIME_CORR);
+       atime_inc_corr = readl(fep->hwp + FEC_ATIME_INC) & FEC_T_INC_CORR_MASK;
+       fep->ptp_saved_state.at_inc_corr = (u8)(atime_inc_corr >> FEC_T_INC_CORR_OFFSET);
+
+       spin_unlock_irqrestore(&fep->tmreg_lock, flags);
+}
+
+/* Restore PTP functionality after a reset */
+void fec_ptp_restore_state(struct fec_enet_private *fep)
+{
+       u32 atime_inc = readl(fep->hwp + FEC_ATIME_INC) & FEC_T_INC_MASK;
+       unsigned long flags;
+       u32 counter;
+       u64 ns;
+
+       spin_lock_irqsave(&fep->tmreg_lock, flags);
+
+       /* Reset turned it off, so adjust our status flag */
+       fep->pps_enable = 0;
+
+       writel(fep->ptp_saved_state.at_corr, fep->hwp + FEC_ATIME_CORR);
+       atime_inc |= ((u32)fep->ptp_saved_state.at_inc_corr) << FEC_T_INC_CORR_OFFSET;
+       writel(atime_inc, fep->hwp + FEC_ATIME_INC);
+
+       ns = ktime_get_ns() - fep->ptp_saved_state.ns_sys + fep->ptp_saved_state.ns_phc;
+       counter = ns & fep->cc.mask;
+       writel(counter, fep->hwp + FEC_ATIME);
+       timecounter_init(&fep->tc, &fep->cc, ns);
+
+       spin_unlock_irqrestore(&fep->tmreg_lock, flags);
+
+       /* Restart PPS if needed */
+       if (fep->ptp_saved_state.pps_enable) {
+               /* Re-enable PPS */
+               fec_ptp_enable_pps(fep, 1);
+       }
+}
+
 void fec_ptp_stop(struct platform_device *pdev)
 {
        struct net_device *ndev = platform_get_drvdata(pdev);
index 9767586b4eb3298fbb76543a330263405821cb15..11da139082e1bff8bf086872341839fd993775c4 100644 (file)
@@ -197,55 +197,67 @@ static int mac_probe(struct platform_device *_of_dev)
                err = -EINVAL;
                goto _return_of_node_put;
        }
+       mac_dev->fman_dev = &of_dev->dev;
 
        /* Get the FMan cell-index */
        err = of_property_read_u32(dev_node, "cell-index", &val);
        if (err) {
                dev_err(dev, "failed to read cell-index for %pOF\n", dev_node);
                err = -EINVAL;
-               goto _return_of_node_put;
+               goto _return_dev_put;
        }
        /* cell-index 0 => FMan id 1 */
        fman_id = (u8)(val + 1);
 
-       priv->fman = fman_bind(&of_dev->dev);
+       priv->fman = fman_bind(mac_dev->fman_dev);
        if (!priv->fman) {
                dev_err(dev, "fman_bind(%pOF) failed\n", dev_node);
                err = -ENODEV;
-               goto _return_of_node_put;
+               goto _return_dev_put;
        }
 
+       /* Two references have been taken in of_find_device_by_node()
+        * and fman_bind(). Release one of them here. The second one
+        * will be released in mac_remove().
+        */
+       put_device(mac_dev->fman_dev);
        of_node_put(dev_node);
+       dev_node = NULL;
 
        /* Get the address of the memory mapped registers */
        mac_dev->res = platform_get_mem_or_io(_of_dev, 0);
        if (!mac_dev->res) {
                dev_err(dev, "could not get registers\n");
-               return -EINVAL;
+               err = -EINVAL;
+               goto _return_dev_put;
        }
 
        err = devm_request_resource(dev, fman_get_mem_region(priv->fman),
                                    mac_dev->res);
        if (err) {
                dev_err_probe(dev, err, "could not request resource\n");
-               return err;
+               goto _return_dev_put;
        }
 
        mac_dev->vaddr = devm_ioremap(dev, mac_dev->res->start,
                                      resource_size(mac_dev->res));
        if (!mac_dev->vaddr) {
                dev_err(dev, "devm_ioremap() failed\n");
-               return -EIO;
+               err = -EIO;
+               goto _return_dev_put;
        }
 
-       if (!of_device_is_available(mac_node))
-               return -ENODEV;
+       if (!of_device_is_available(mac_node)) {
+               err = -ENODEV;
+               goto _return_dev_put;
+       }
 
        /* Get the cell-index */
        err = of_property_read_u32(mac_node, "cell-index", &val);
        if (err) {
                dev_err(dev, "failed to read cell-index for %pOF\n", mac_node);
-               return -EINVAL;
+               err = -EINVAL;
+               goto _return_dev_put;
        }
        priv->cell_index = (u8)val;
 
@@ -259,22 +271,26 @@ static int mac_probe(struct platform_device *_of_dev)
        if (unlikely(nph < 0)) {
                dev_err(dev, "of_count_phandle_with_args(%pOF, fsl,fman-ports) failed\n",
                        mac_node);
-               return nph;
+               err = nph;
+               goto _return_dev_put;
        }
 
        if (nph != ARRAY_SIZE(mac_dev->port)) {
                dev_err(dev, "Not supported number of fman-ports handles of mac node %pOF from device tree\n",
                        mac_node);
-               return -EINVAL;
+               err = -EINVAL;
+               goto _return_dev_put;
        }
 
-       for (i = 0; i < ARRAY_SIZE(mac_dev->port); i++) {
+       /* PORT_NUM determines the size of the port array */
+       for (i = 0; i < PORT_NUM; i++) {
                /* Find the port node */
                dev_node = of_parse_phandle(mac_node, "fsl,fman-ports", i);
                if (!dev_node) {
                        dev_err(dev, "of_parse_phandle(%pOF, fsl,fman-ports) failed\n",
                                mac_node);
-                       return -EINVAL;
+                       err = -EINVAL;
+                       goto _return_dev_arr_put;
                }
 
                of_dev = of_find_device_by_node(dev_node);
@@ -282,17 +298,24 @@ static int mac_probe(struct platform_device *_of_dev)
                        dev_err(dev, "of_find_device_by_node(%pOF) failed\n",
                                dev_node);
                        err = -EINVAL;
-                       goto _return_of_node_put;
+                       goto _return_dev_arr_put;
                }
+               mac_dev->fman_port_devs[i] = &of_dev->dev;
 
-               mac_dev->port[i] = fman_port_bind(&of_dev->dev);
+               mac_dev->port[i] = fman_port_bind(mac_dev->fman_port_devs[i]);
                if (!mac_dev->port[i]) {
                        dev_err(dev, "dev_get_drvdata(%pOF) failed\n",
                                dev_node);
                        err = -EINVAL;
-                       goto _return_of_node_put;
+                       goto _return_dev_arr_put;
                }
+               /* Two references have been taken in of_find_device_by_node()
+                * and fman_port_bind(). Release one of them here. The second
+                * one will be released in mac_remove().
+                */
+               put_device(mac_dev->fman_port_devs[i]);
                of_node_put(dev_node);
+               dev_node = NULL;
        }
 
        /* Get the PHY connection type */
@@ -312,7 +335,7 @@ static int mac_probe(struct platform_device *_of_dev)
 
        err = init(mac_dev, mac_node, &params);
        if (err < 0)
-               return err;
+               goto _return_dev_arr_put;
 
        if (!is_zero_ether_addr(mac_dev->addr))
                dev_info(dev, "FMan MAC address: %pM\n", mac_dev->addr);
@@ -327,6 +350,12 @@ static int mac_probe(struct platform_device *_of_dev)
 
        return err;
 
+_return_dev_arr_put:
+       /* mac_dev is kzalloc'ed */
+       for (i = 0; i < PORT_NUM; i++)
+               put_device(mac_dev->fman_port_devs[i]);
+_return_dev_put:
+       put_device(mac_dev->fman_dev);
 _return_of_node_put:
        of_node_put(dev_node);
        return err;
@@ -335,6 +364,11 @@ _return_of_node_put:
 static void mac_remove(struct platform_device *pdev)
 {
        struct mac_device *mac_dev = platform_get_drvdata(pdev);
+       int                i;
+
+       for (i = 0; i < PORT_NUM; i++)
+               put_device(mac_dev->fman_port_devs[i]);
+       put_device(mac_dev->fman_dev);
 
        platform_device_unregister(mac_dev->priv->eth_dev);
 }
index fe747915cc73792b66d8bfe4339894476fc841af..8b5b43d50f8efbaaeb3b1cec65068154f315eded 100644 (file)
 struct fman_mac;
 struct mac_priv_s;
 
+#define PORT_NUM 2
 struct mac_device {
        void __iomem            *vaddr;
        struct device           *dev;
        struct resource         *res;
        u8                       addr[ETH_ALEN];
-       struct fman_port        *port[2];
+       struct fman_port        *port[PORT_NUM];
        struct phylink          *phylink;
        struct phylink_config   phylink_config;
        phy_interface_t         phy_if;
@@ -52,6 +53,9 @@ struct mac_device {
 
        struct fman_mac         *fman_mac;
        struct mac_priv_s       *priv;
+
+       struct device           *fman_dev;
+       struct device           *fman_port_devs[PORT_NUM];
 };
 
 static inline struct mac_device
index 807eb3bbb11c0408fbdcfa678586646fb92f8861..841e5af7b2beeff047d0835275f57adceaf6ba46 100644 (file)
@@ -1293,8 +1293,10 @@ static ssize_t hns3_dbg_read(struct file *filp, char __user *buffer,
 
                /* save the buffer addr until the last read operation */
                *save_buf = read_buf;
+       }
 
-               /* get data ready for the first time to read */
+       /* get data ready for the first time to read */
+       if (!*ppos) {
                ret = hns3_dbg_read_cmd(dbg_data, hns3_dbg_cmd[index].cmd,
                                        read_buf, hns3_dbg_cmd[index].buf_len);
                if (ret)
index 4cbc4d069a1f369eaec2fec6b3412a0fce186782..b09f0cca34dc68604dc00b7e7ed233a16fcdadd7 100644 (file)
@@ -11,6 +11,7 @@
 #include <linux/irq.h>
 #include <linux/ip.h>
 #include <linux/ipv6.h>
+#include <linux/iommu.h>
 #include <linux/module.h>
 #include <linux/pci.h>
 #include <linux/skbuff.h>
@@ -380,6 +381,24 @@ static const struct hns3_rx_ptype hns3_rx_ptype_tbl[] = {
 #define HNS3_INVALID_PTYPE \
                ARRAY_SIZE(hns3_rx_ptype_tbl)
 
+static void hns3_dma_map_sync(struct device *dev, unsigned long iova)
+{
+       struct iommu_domain *domain = iommu_get_domain_for_dev(dev);
+       struct iommu_iotlb_gather iotlb_gather;
+       size_t granule;
+
+       if (!domain || !iommu_is_dma_domain(domain))
+               return;
+
+       granule = 1 << __ffs(domain->pgsize_bitmap);
+       iova = ALIGN_DOWN(iova, granule);
+       iotlb_gather.start = iova;
+       iotlb_gather.end = iova + granule - 1;
+       iotlb_gather.pgsize = granule;
+
+       iommu_iotlb_sync(domain, &iotlb_gather);
+}
+
 static irqreturn_t hns3_irq_handle(int irq, void *vector)
 {
        struct hns3_enet_tqp_vector *tqp_vector = vector;
@@ -1032,6 +1051,8 @@ static bool hns3_can_use_tx_sgl(struct hns3_enet_ring *ring,
 static void hns3_init_tx_spare_buffer(struct hns3_enet_ring *ring)
 {
        u32 alloc_size = ring->tqp->handle->kinfo.tx_spare_buf_size;
+       struct net_device *netdev = ring_to_netdev(ring);
+       struct hns3_nic_priv *priv = netdev_priv(netdev);
        struct hns3_tx_spare *tx_spare;
        struct page *page;
        dma_addr_t dma;
@@ -1073,6 +1094,7 @@ static void hns3_init_tx_spare_buffer(struct hns3_enet_ring *ring)
        tx_spare->buf = page_address(page);
        tx_spare->len = PAGE_SIZE << order;
        ring->tx_spare = tx_spare;
+       ring->tx_copybreak = priv->tx_copybreak;
        return;
 
 dma_mapping_error:
@@ -1724,7 +1746,9 @@ static int hns3_map_and_fill_desc(struct hns3_enet_ring *ring, void *priv,
                                  unsigned int type)
 {
        struct hns3_desc_cb *desc_cb = &ring->desc_cb[ring->next_to_use];
+       struct hnae3_handle *handle = ring->tqp->handle;
        struct device *dev = ring_to_dev(ring);
+       struct hnae3_ae_dev *ae_dev;
        unsigned int size;
        dma_addr_t dma;
 
@@ -1756,6 +1780,13 @@ static int hns3_map_and_fill_desc(struct hns3_enet_ring *ring, void *priv,
                return -ENOMEM;
        }
 
+       /* Add a SYNC command to sync io-pgtale to avoid errors in pgtable
+        * prefetch
+        */
+       ae_dev = hns3_get_ae_dev(handle);
+       if (ae_dev->dev_version >= HNAE3_DEVICE_VERSION_V3)
+               hns3_dma_map_sync(dev, dma);
+
        desc_cb->priv = priv;
        desc_cb->length = size;
        desc_cb->dma = dma;
@@ -2452,7 +2483,6 @@ static int hns3_nic_set_features(struct net_device *netdev,
                        return ret;
        }
 
-       netdev->features = features;
        return 0;
 }
 
@@ -4868,6 +4898,30 @@ static void hns3_nic_dealloc_vector_data(struct hns3_nic_priv *priv)
        devm_kfree(&pdev->dev, priv->tqp_vector);
 }
 
+static void hns3_update_tx_spare_buf_config(struct hns3_nic_priv *priv)
+{
+#define HNS3_MIN_SPARE_BUF_SIZE (2 * 1024 * 1024)
+#define HNS3_MAX_PACKET_SIZE (64 * 1024)
+
+       struct iommu_domain *domain = iommu_get_domain_for_dev(priv->dev);
+       struct hnae3_ae_dev *ae_dev = hns3_get_ae_dev(priv->ae_handle);
+       struct hnae3_handle *handle = priv->ae_handle;
+
+       if (ae_dev->dev_version < HNAE3_DEVICE_VERSION_V3)
+               return;
+
+       if (!(domain && iommu_is_dma_domain(domain)))
+               return;
+
+       priv->min_tx_copybreak = HNS3_MAX_PACKET_SIZE;
+       priv->min_tx_spare_buf_size = HNS3_MIN_SPARE_BUF_SIZE;
+
+       if (priv->tx_copybreak < priv->min_tx_copybreak)
+               priv->tx_copybreak = priv->min_tx_copybreak;
+       if (handle->kinfo.tx_spare_buf_size < priv->min_tx_spare_buf_size)
+               handle->kinfo.tx_spare_buf_size = priv->min_tx_spare_buf_size;
+}
+
 static void hns3_ring_get_cfg(struct hnae3_queue *q, struct hns3_nic_priv *priv,
                              unsigned int ring_type)
 {
@@ -5101,6 +5155,7 @@ int hns3_init_all_ring(struct hns3_nic_priv *priv)
        int i, j;
        int ret;
 
+       hns3_update_tx_spare_buf_config(priv);
        for (i = 0; i < ring_num; i++) {
                ret = hns3_alloc_ring_memory(&priv->ring[i]);
                if (ret) {
@@ -5305,6 +5360,8 @@ static int hns3_client_init(struct hnae3_handle *handle)
        priv->ae_handle = handle;
        priv->tx_timeout_count = 0;
        priv->max_non_tso_bd_num = ae_dev->dev_specs.max_non_tso_bd_num;
+       priv->min_tx_copybreak = 0;
+       priv->min_tx_spare_buf_size = 0;
        set_bit(HNS3_NIC_STATE_DOWN, &priv->state);
 
        handle->msg_enable = netif_msg_init(debug, DEFAULT_MSG_LEVEL);
index d36c4ed16d8dd25251df92377f91a24cf3961e01..caf7a4df8585275c8ae47b5f78d613bf26d5a425 100644 (file)
@@ -596,6 +596,8 @@ struct hns3_nic_priv {
        struct hns3_enet_coalesce rx_coal;
        u32 tx_copybreak;
        u32 rx_copybreak;
+       u32 min_tx_copybreak;
+       u32 min_tx_spare_buf_size;
 };
 
 union l3_hdr_info {
index b1e9883473476956d793f198c1c45f01fc16b343..97eaeec1952bb572534f87338982962073ee89f8 100644 (file)
@@ -1933,6 +1933,31 @@ static int hns3_set_tx_spare_buf_size(struct net_device *netdev,
        return ret;
 }
 
+static int hns3_check_tx_copybreak(struct net_device *netdev, u32 copybreak)
+{
+       struct hns3_nic_priv *priv = netdev_priv(netdev);
+
+       if (copybreak < priv->min_tx_copybreak) {
+               netdev_err(netdev, "tx copybreak %u should be no less than %u!\n",
+                          copybreak, priv->min_tx_copybreak);
+               return -EINVAL;
+       }
+       return 0;
+}
+
+static int hns3_check_tx_spare_buf_size(struct net_device *netdev, u32 buf_size)
+{
+       struct hns3_nic_priv *priv = netdev_priv(netdev);
+
+       if (buf_size < priv->min_tx_spare_buf_size) {
+               netdev_err(netdev,
+                          "tx spare buf size %u should be no less than %u!\n",
+                          buf_size, priv->min_tx_spare_buf_size);
+               return -EINVAL;
+       }
+       return 0;
+}
+
 static int hns3_set_tunable(struct net_device *netdev,
                            const struct ethtool_tunable *tuna,
                            const void *data)
@@ -1949,6 +1974,10 @@ static int hns3_set_tunable(struct net_device *netdev,
 
        switch (tuna->id) {
        case ETHTOOL_TX_COPYBREAK:
+               ret = hns3_check_tx_copybreak(netdev, *(u32 *)data);
+               if (ret)
+                       return ret;
+
                priv->tx_copybreak = *(u32 *)data;
 
                for (i = 0; i < h->kinfo.num_tqps; i++)
@@ -1963,6 +1992,10 @@ static int hns3_set_tunable(struct net_device *netdev,
 
                break;
        case ETHTOOL_TX_COPYBREAK_BUF_SIZE:
+               ret = hns3_check_tx_spare_buf_size(netdev, *(u32 *)data);
+               if (ret)
+                       return ret;
+
                old_tx_spare_buf_size = h->kinfo.tx_spare_buf_size;
                new_tx_spare_buf_size = *(u32 *)data;
                netdev_info(netdev, "request to set tx spare buf size from %u to %u\n",
index bd86efd92a5a7d0eb92b97b82b5e03dc875d1049..728f4777e51f0a1ee9f3c59d6d8f473ebc0b7c64 100644 (file)
@@ -6,6 +6,7 @@
 #include <linux/etherdevice.h>
 #include <linux/init.h>
 #include <linux/interrupt.h>
+#include <linux/irq.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/netdevice.h>
@@ -3584,6 +3585,17 @@ static int hclge_set_vf_link_state(struct hnae3_handle *handle, int vf,
        return ret;
 }
 
+static void hclge_set_reset_pending(struct hclge_dev *hdev,
+                                   enum hnae3_reset_type reset_type)
+{
+       /* When an incorrect reset type is executed, the get_reset_level
+        * function generates the HNAE3_NONE_RESET flag. As a result, this
+        * type do not need to pending.
+        */
+       if (reset_type != HNAE3_NONE_RESET)
+               set_bit(reset_type, &hdev->reset_pending);
+}
+
 static u32 hclge_check_event_cause(struct hclge_dev *hdev, u32 *clearval)
 {
        u32 cmdq_src_reg, msix_src_reg, hw_err_src_reg;
@@ -3604,7 +3616,7 @@ static u32 hclge_check_event_cause(struct hclge_dev *hdev, u32 *clearval)
         */
        if (BIT(HCLGE_VECTOR0_IMPRESET_INT_B) & msix_src_reg) {
                dev_info(&hdev->pdev->dev, "IMP reset interrupt\n");
-               set_bit(HNAE3_IMP_RESET, &hdev->reset_pending);
+               hclge_set_reset_pending(hdev, HNAE3_IMP_RESET);
                set_bit(HCLGE_COMM_STATE_CMD_DISABLE, &hdev->hw.hw.comm_state);
                *clearval = BIT(HCLGE_VECTOR0_IMPRESET_INT_B);
                hdev->rst_stats.imp_rst_cnt++;
@@ -3614,7 +3626,7 @@ static u32 hclge_check_event_cause(struct hclge_dev *hdev, u32 *clearval)
        if (BIT(HCLGE_VECTOR0_GLOBALRESET_INT_B) & msix_src_reg) {
                dev_info(&hdev->pdev->dev, "global reset interrupt\n");
                set_bit(HCLGE_COMM_STATE_CMD_DISABLE, &hdev->hw.hw.comm_state);
-               set_bit(HNAE3_GLOBAL_RESET, &hdev->reset_pending);
+               hclge_set_reset_pending(hdev, HNAE3_GLOBAL_RESET);
                *clearval = BIT(HCLGE_VECTOR0_GLOBALRESET_INT_B);
                hdev->rst_stats.global_rst_cnt++;
                return HCLGE_VECTOR0_EVENT_RST;
@@ -3769,7 +3781,7 @@ static int hclge_misc_irq_init(struct hclge_dev *hdev)
        snprintf(hdev->misc_vector.name, HNAE3_INT_NAME_LEN, "%s-misc-%s",
                 HCLGE_NAME, pci_name(hdev->pdev));
        ret = request_irq(hdev->misc_vector.vector_irq, hclge_misc_irq_handle,
-                         0, hdev->misc_vector.name, hdev);
+                         IRQ_NOAUTOEN, hdev->misc_vector.name, hdev);
        if (ret) {
                hclge_free_vector(hdev, 0);
                dev_err(&hdev->pdev->dev, "request misc irq(%d) fail\n",
@@ -4062,7 +4074,7 @@ static void hclge_do_reset(struct hclge_dev *hdev)
        case HNAE3_FUNC_RESET:
                dev_info(&pdev->dev, "PF reset requested\n");
                /* schedule again to check later */
-               set_bit(HNAE3_FUNC_RESET, &hdev->reset_pending);
+               hclge_set_reset_pending(hdev, HNAE3_FUNC_RESET);
                hclge_reset_task_schedule(hdev);
                break;
        default:
@@ -4096,6 +4108,8 @@ static enum hnae3_reset_type hclge_get_reset_level(struct hnae3_ae_dev *ae_dev,
                clear_bit(HNAE3_FLR_RESET, addr);
        }
 
+       clear_bit(HNAE3_NONE_RESET, addr);
+
        if (hdev->reset_type != HNAE3_NONE_RESET &&
            rst_level < hdev->reset_type)
                return HNAE3_NONE_RESET;
@@ -4237,7 +4251,7 @@ static bool hclge_reset_err_handle(struct hclge_dev *hdev)
                return false;
        } else if (hdev->rst_stats.reset_fail_cnt < MAX_RESET_FAIL_CNT) {
                hdev->rst_stats.reset_fail_cnt++;
-               set_bit(hdev->reset_type, &hdev->reset_pending);
+               hclge_set_reset_pending(hdev, hdev->reset_type);
                dev_info(&hdev->pdev->dev,
                         "re-schedule reset task(%u)\n",
                         hdev->rst_stats.reset_fail_cnt);
@@ -4480,8 +4494,20 @@ static void hclge_reset_event(struct pci_dev *pdev, struct hnae3_handle *handle)
 static void hclge_set_def_reset_request(struct hnae3_ae_dev *ae_dev,
                                        enum hnae3_reset_type rst_type)
 {
+#define HCLGE_SUPPORT_RESET_TYPE \
+       (BIT(HNAE3_FLR_RESET) | BIT(HNAE3_FUNC_RESET) | \
+       BIT(HNAE3_GLOBAL_RESET) | BIT(HNAE3_IMP_RESET))
+
        struct hclge_dev *hdev = ae_dev->priv;
 
+       if (!(BIT(rst_type) & HCLGE_SUPPORT_RESET_TYPE)) {
+               /* To prevent reset triggered by hclge_reset_event */
+               set_bit(HNAE3_NONE_RESET, &hdev->default_reset_request);
+               dev_warn(&hdev->pdev->dev, "unsupported reset type %d\n",
+                        rst_type);
+               return;
+       }
+
        set_bit(rst_type, &hdev->default_reset_request);
 }
 
@@ -11891,9 +11917,6 @@ static int hclge_init_ae_dev(struct hnae3_ae_dev *ae_dev)
 
        hclge_init_rxd_adv_layout(hdev);
 
-       /* Enable MISC vector(vector0) */
-       hclge_enable_vector(&hdev->misc_vector, true);
-
        ret = hclge_init_wol(hdev);
        if (ret)
                dev_warn(&pdev->dev,
@@ -11906,6 +11929,10 @@ static int hclge_init_ae_dev(struct hnae3_ae_dev *ae_dev)
        hclge_state_init(hdev);
        hdev->last_reset_time = jiffies;
 
+       /* Enable MISC vector(vector0) */
+       enable_irq(hdev->misc_vector.vector_irq);
+       hclge_enable_vector(&hdev->misc_vector, true);
+
        dev_info(&hdev->pdev->dev, "%s driver initialization finished.\n",
                 HCLGE_DRIVER_NAME);
 
@@ -12311,7 +12338,7 @@ static void hclge_uninit_ae_dev(struct hnae3_ae_dev *ae_dev)
 
        /* Disable MISC vector(vector0) */
        hclge_enable_vector(&hdev->misc_vector, false);
-       synchronize_irq(hdev->misc_vector.vector_irq);
+       disable_irq(hdev->misc_vector.vector_irq);
 
        /* Disable all hw interrupts */
        hclge_config_mac_tnl_int(hdev, false);
index 5505caea88e981e0bd9407ae9156f45d660edc51..bab16c2191b2f09363740c8cd510673285f4e798 100644 (file)
@@ -58,6 +58,9 @@ bool hclge_ptp_set_tx_info(struct hnae3_handle *handle, struct sk_buff *skb)
        struct hclge_dev *hdev = vport->back;
        struct hclge_ptp *ptp = hdev->ptp;
 
+       if (!ptp)
+               return false;
+
        if (!test_bit(HCLGE_PTP_FLAG_TX_EN, &ptp->flags) ||
            test_and_set_bit(HCLGE_STATE_PTP_TX_HANDLING, &hdev->state)) {
                ptp->tx_skipped++;
index 43c1c18fa81f8d572d37d15f2c7cc6d4dcbf3391..8c057192aae6e16abe24fdd1bbed3f088c111f8e 100644 (file)
@@ -510,9 +510,9 @@ out:
 static int hclge_fetch_pf_reg(struct hclge_dev *hdev, void *data,
                              struct hnae3_knic_private_info *kinfo)
 {
-#define HCLGE_RING_REG_OFFSET          0x200
 #define HCLGE_RING_INT_REG_OFFSET      0x4
 
+       struct hnae3_queue *tqp;
        int i, j, reg_num;
        int data_num_sum;
        u32 *reg = data;
@@ -533,10 +533,11 @@ static int hclge_fetch_pf_reg(struct hclge_dev *hdev, void *data,
        reg_num = ARRAY_SIZE(ring_reg_addr_list);
        for (j = 0; j < kinfo->num_tqps; j++) {
                reg += hclge_reg_get_tlv(HCLGE_REG_TAG_RING, reg_num, reg);
+               tqp = kinfo->tqp[j];
                for (i = 0; i < reg_num; i++)
-                       *reg++ = hclge_read_dev(&hdev->hw,
-                                               ring_reg_addr_list[i] +
-                                               HCLGE_RING_REG_OFFSET * j);
+                       *reg++ = readl_relaxed(tqp->io_base -
+                                              HCLGE_TQP_REG_OFFSET +
+                                              ring_reg_addr_list[i]);
        }
        data_num_sum += (reg_num + HCLGE_REG_TLV_SPACE) * kinfo->num_tqps;
 
index 094a7c7b55921f9a0ddb3637ebe8d5ca9eb46c38..896f1eb172d30e0769000db6c71a177f08133508 100644 (file)
@@ -1395,6 +1395,17 @@ static int hclgevf_notify_roce_client(struct hclgevf_dev *hdev,
        return ret;
 }
 
+static void hclgevf_set_reset_pending(struct hclgevf_dev *hdev,
+                                     enum hnae3_reset_type reset_type)
+{
+       /* When an incorrect reset type is executed, the get_reset_level
+        * function generates the HNAE3_NONE_RESET flag. As a result, this
+        * type do not need to pending.
+        */
+       if (reset_type != HNAE3_NONE_RESET)
+               set_bit(reset_type, &hdev->reset_pending);
+}
+
 static int hclgevf_reset_wait(struct hclgevf_dev *hdev)
 {
 #define HCLGEVF_RESET_WAIT_US  20000
@@ -1544,7 +1555,7 @@ static void hclgevf_reset_err_handle(struct hclgevf_dev *hdev)
                hdev->rst_stats.rst_fail_cnt);
 
        if (hdev->rst_stats.rst_fail_cnt < HCLGEVF_RESET_MAX_FAIL_CNT)
-               set_bit(hdev->reset_type, &hdev->reset_pending);
+               hclgevf_set_reset_pending(hdev, hdev->reset_type);
 
        if (hclgevf_is_reset_pending(hdev)) {
                set_bit(HCLGEVF_RESET_PENDING, &hdev->reset_state);
@@ -1664,6 +1675,8 @@ static enum hnae3_reset_type hclgevf_get_reset_level(unsigned long *addr)
                clear_bit(HNAE3_FLR_RESET, addr);
        }
 
+       clear_bit(HNAE3_NONE_RESET, addr);
+
        return rst_level;
 }
 
@@ -1673,14 +1686,15 @@ static void hclgevf_reset_event(struct pci_dev *pdev,
        struct hnae3_ae_dev *ae_dev = pci_get_drvdata(pdev);
        struct hclgevf_dev *hdev = ae_dev->priv;
 
-       dev_info(&hdev->pdev->dev, "received reset request from VF enet\n");
-
        if (hdev->default_reset_request)
                hdev->reset_level =
                        hclgevf_get_reset_level(&hdev->default_reset_request);
        else
                hdev->reset_level = HNAE3_VF_FUNC_RESET;
 
+       dev_info(&hdev->pdev->dev, "received reset request from VF enet, reset level is %d\n",
+                hdev->reset_level);
+
        /* reset of this VF requested */
        set_bit(HCLGEVF_RESET_REQUESTED, &hdev->reset_state);
        hclgevf_reset_task_schedule(hdev);
@@ -1691,8 +1705,20 @@ static void hclgevf_reset_event(struct pci_dev *pdev,
 static void hclgevf_set_def_reset_request(struct hnae3_ae_dev *ae_dev,
                                          enum hnae3_reset_type rst_type)
 {
+#define HCLGEVF_SUPPORT_RESET_TYPE \
+       (BIT(HNAE3_VF_RESET) | BIT(HNAE3_VF_FUNC_RESET) | \
+       BIT(HNAE3_VF_PF_FUNC_RESET) | BIT(HNAE3_VF_FULL_RESET) | \
+       BIT(HNAE3_FLR_RESET) | BIT(HNAE3_VF_EXP_RESET))
+
        struct hclgevf_dev *hdev = ae_dev->priv;
 
+       if (!(BIT(rst_type) & HCLGEVF_SUPPORT_RESET_TYPE)) {
+               /* To prevent reset triggered by hclge_reset_event */
+               set_bit(HNAE3_NONE_RESET, &hdev->default_reset_request);
+               dev_info(&hdev->pdev->dev, "unsupported reset type %d\n",
+                        rst_type);
+               return;
+       }
        set_bit(rst_type, &hdev->default_reset_request);
 }
 
@@ -1849,14 +1875,14 @@ static void hclgevf_reset_service_task(struct hclgevf_dev *hdev)
                 */
                if (hdev->reset_attempts > HCLGEVF_MAX_RESET_ATTEMPTS_CNT) {
                        /* prepare for full reset of stack + pcie interface */
-                       set_bit(HNAE3_VF_FULL_RESET, &hdev->reset_pending);
+                       hclgevf_set_reset_pending(hdev, HNAE3_VF_FULL_RESET);
 
                        /* "defer" schedule the reset task again */
                        set_bit(HCLGEVF_RESET_PENDING, &hdev->reset_state);
                } else {
                        hdev->reset_attempts++;
 
-                       set_bit(hdev->reset_level, &hdev->reset_pending);
+                       hclgevf_set_reset_pending(hdev, hdev->reset_level);
                        set_bit(HCLGEVF_RESET_PENDING, &hdev->reset_state);
                }
                hclgevf_reset_task_schedule(hdev);
@@ -1979,7 +2005,7 @@ static enum hclgevf_evt_cause hclgevf_check_evt_cause(struct hclgevf_dev *hdev,
                rst_ing_reg = hclgevf_read_dev(&hdev->hw, HCLGEVF_RST_ING);
                dev_info(&hdev->pdev->dev,
                         "receive reset interrupt 0x%x!\n", rst_ing_reg);
-               set_bit(HNAE3_VF_RESET, &hdev->reset_pending);
+               hclgevf_set_reset_pending(hdev, HNAE3_VF_RESET);
                set_bit(HCLGEVF_RESET_PENDING, &hdev->reset_state);
                set_bit(HCLGE_COMM_STATE_CMD_DISABLE, &hdev->hw.hw.comm_state);
                *clearval = ~(1U << HCLGEVF_VECTOR0_RST_INT_B);
@@ -2289,6 +2315,7 @@ static void hclgevf_state_init(struct hclgevf_dev *hdev)
        clear_bit(HCLGEVF_STATE_RST_FAIL, &hdev->state);
 
        INIT_DELAYED_WORK(&hdev->service_task, hclgevf_service_task);
+       timer_setup(&hdev->reset_timer, hclgevf_reset_timer, 0);
 
        mutex_init(&hdev->mbx_resp.mbx_mutex);
        sema_init(&hdev->reset_sem, 1);
@@ -2988,7 +3015,6 @@ static int hclgevf_init_hdev(struct hclgevf_dev *hdev)
                 HCLGEVF_DRIVER_NAME);
 
        hclgevf_task_schedule(hdev, round_jiffies_relative(HZ));
-       timer_setup(&hdev->reset_timer, hclgevf_reset_timer, 0);
 
        return 0;
 
index 6db415d8b9176cfb2b480518991fa2f14f097551..7d9d9dbc75603a3d6e8d2add3be51776bc1400ce 100644 (file)
@@ -123,10 +123,10 @@ int hclgevf_get_regs_len(struct hnae3_handle *handle)
 void hclgevf_get_regs(struct hnae3_handle *handle, u32 *version,
                      void *data)
 {
-#define HCLGEVF_RING_REG_OFFSET                0x200
 #define HCLGEVF_RING_INT_REG_OFFSET    0x4
 
        struct hclgevf_dev *hdev = hclgevf_ae_get_hdev(handle);
+       struct hnae3_queue *tqp;
        int i, j, reg_um;
        u32 *reg = data;
 
@@ -147,10 +147,11 @@ void hclgevf_get_regs(struct hnae3_handle *handle, u32 *version,
        reg_um = ARRAY_SIZE(ring_reg_addr_list);
        for (j = 0; j < hdev->num_tqps; j++) {
                reg += hclgevf_reg_get_tlv(HCLGEVF_REG_TAG_RING, reg_um, reg);
+               tqp = &hdev->htqp[j].q;
                for (i = 0; i < reg_um; i++)
-                       *reg++ = hclgevf_read_dev(&hdev->hw,
-                                                 ring_reg_addr_list[i] +
-                                                 HCLGEVF_RING_REG_OFFSET * j);
+                       *reg++ = readl_relaxed(tqp->io_base -
+                                              HCLGEVF_TQP_REG_OFFSET +
+                                              ring_reg_addr_list[i]);
        }
 
        reg_um = ARRAY_SIZE(tqp_intr_reg_addr_list);
index f2d4669c81cf2981df38f609789989c13058ad12..58a3d28d938c322b016582b3ea1597e6c744c207 100644 (file)
@@ -1012,6 +1012,7 @@ sun3_82586_send_packet(struct sk_buff *skb, struct net_device *dev)
        if(skb->len > XMIT_BUFF_SIZE)
        {
                printk("%s: Sorry, max. framelength is %d bytes. The length of your frame is %d bytes.\n",dev->name,XMIT_BUFF_SIZE,skb->len);
+               dev_kfree_skb(skb);
                return NETDEV_TX_OK;
        }
 
index d92dd9c83031ee48b14ac744ced49c7740cdfe7a..99d5f83f7c60b529b620075e32955403067eeffa 100644 (file)
@@ -578,7 +578,7 @@ static int mal_probe(struct platform_device *ofdev)
                printk(KERN_ERR "%pOF: Support for 405EZ not enabled!\n",
                                ofdev->dev.of_node);
                err = -ENODEV;
-               goto fail;
+               goto fail_unmap;
 #endif
        }
 
@@ -742,6 +742,8 @@ static void mal_remove(struct platform_device *ofdev)
 
        free_netdev(mal->dummy_dev);
 
+       dcr_unmap(mal->dcr_host, 0x100);
+
        dma_free_coherent(&ofdev->dev,
                          sizeof(struct mal_descriptor) *
                          (NUM_TX_BUFF * mal->num_tx_chans +
index 87e693a814331ad2f57d1a1832d3a9e30a87b50b..97425c06e1ed7f626a56740994737886c62489cc 100644 (file)
@@ -2472,9 +2472,11 @@ static netdev_tx_t ibmvnic_xmit(struct sk_buff *skb, struct net_device *netdev)
        /* if we are going to send_subcrq_direct this then we need to
         * update the checksum before copying the data into ltb. Essentially
         * these packets force disable CSO so that we can guarantee that
-        * FW does not need header info and we can send direct.
+        * FW does not need header info and we can send direct. Also, vnic
+        * server must be able to xmit standard packets without header data
         */
-       if (!skb_is_gso(skb) && !ind_bufp->index && !netdev_xmit_more()) {
+       if (*hdrs == 0 && !skb_is_gso(skb) &&
+           !ind_bufp->index && !netdev_xmit_more()) {
                use_scrq_send_direct = true;
                if (skb->ip_summed == CHECKSUM_PARTIAL &&
                    skb_checksum_help(skb))
index aa139b67a55bbf69859bb430ab05be5635917c16..3a5bbda235cbb236b631f2f75655c81399284144 100644 (file)
 #include <linux/string.h>
 #include <linux/firmware.h>
 #include <linux/rtnetlink.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 
 #define DRV_NAME               "e100"
index 4b6e7536170abc584a7dc95c6c80b926d7c17375..fc8ed38aa0955426d07112e0a1231cd4062544b0 100644 (file)
@@ -108,8 +108,8 @@ struct e1000_hw;
 #define E1000_DEV_ID_PCH_RPL_I219_V22          0x0DC8
 #define E1000_DEV_ID_PCH_MTP_I219_LM18         0x550A
 #define E1000_DEV_ID_PCH_MTP_I219_V18          0x550B
-#define E1000_DEV_ID_PCH_MTP_I219_LM19         0x550C
-#define E1000_DEV_ID_PCH_MTP_I219_V19          0x550D
+#define E1000_DEV_ID_PCH_ADP_I219_LM19         0x550C
+#define E1000_DEV_ID_PCH_ADP_I219_V19          0x550D
 #define E1000_DEV_ID_PCH_LNP_I219_LM20         0x550E
 #define E1000_DEV_ID_PCH_LNP_I219_V20          0x550F
 #define E1000_DEV_ID_PCH_LNP_I219_LM21         0x5510
index f103249b12facf46c09f6e762b00208d273541ab..07e90334635824792df934fec4679fd3d538f539 100644 (file)
@@ -7899,10 +7899,10 @@ static const struct pci_device_id e1000_pci_tbl[] = {
        { PCI_VDEVICE(INTEL, E1000_DEV_ID_PCH_ADP_I219_V17), board_pch_adp },
        { PCI_VDEVICE(INTEL, E1000_DEV_ID_PCH_RPL_I219_LM22), board_pch_adp },
        { PCI_VDEVICE(INTEL, E1000_DEV_ID_PCH_RPL_I219_V22), board_pch_adp },
+       { PCI_VDEVICE(INTEL, E1000_DEV_ID_PCH_ADP_I219_LM19), board_pch_adp },
+       { PCI_VDEVICE(INTEL, E1000_DEV_ID_PCH_ADP_I219_V19), board_pch_adp },
        { PCI_VDEVICE(INTEL, E1000_DEV_ID_PCH_MTP_I219_LM18), board_pch_mtp },
        { PCI_VDEVICE(INTEL, E1000_DEV_ID_PCH_MTP_I219_V18), board_pch_mtp },
-       { PCI_VDEVICE(INTEL, E1000_DEV_ID_PCH_MTP_I219_LM19), board_pch_mtp },
-       { PCI_VDEVICE(INTEL, E1000_DEV_ID_PCH_MTP_I219_V19), board_pch_mtp },
        { PCI_VDEVICE(INTEL, E1000_DEV_ID_PCH_LNP_I219_LM20), board_pch_mtp },
        { PCI_VDEVICE(INTEL, E1000_DEV_ID_PCH_LNP_I219_V20), board_pch_mtp },
        { PCI_VDEVICE(INTEL, E1000_DEV_ID_PCH_LNP_I219_LM21), board_pch_mtp },
index 03205eb9f925f3cf851976e5bc436cf24e2c5243..25295ae370b29c1245c45ac44d98f319fd3a7147 100644 (file)
@@ -1734,6 +1734,7 @@ struct i40e_mac_filter *i40e_add_mac_filter(struct i40e_vsi *vsi,
        struct hlist_node *h;
        int bkt;
 
+       lockdep_assert_held(&vsi->mac_filter_hash_lock);
        if (vsi->info.pvid)
                return i40e_add_filter(vsi, macaddr,
                                       le16_to_cpu(vsi->info.pvid));
index 662622f01e31254ba2bea685bddc588d81d2de8b..dfa785e39458dbeea4e028b070d5f16246cd8b1a 100644 (file)
@@ -2213,8 +2213,10 @@ static int i40e_vc_get_vf_resources_msg(struct i40e_vf *vf, u8 *msg)
                vfres->vsi_res[0].qset_handle
                                          = le16_to_cpu(vsi->info.qs_handle[0]);
                if (!(vf->driver_caps & VIRTCHNL_VF_OFFLOAD_USO) && !vf->pf_set_mac) {
+                       spin_lock_bh(&vsi->mac_filter_hash_lock);
                        i40e_del_mac_filter(vsi, vf->default_lan_addr.addr);
                        eth_zero_addr(vf->default_lan_addr.addr);
+                       spin_unlock_bh(&vsi->mac_filter_hash_lock);
                }
                ether_addr_copy(vfres->vsi_res[0].default_mac_addr,
                                vf->default_lan_addr.addr);
index 928c8bdb66494a15928ef63ed8e4176f38020fc7..c6779d9dffffda95ec1811b520f3e05101caa44a 100644 (file)
@@ -989,5 +989,11 @@ ice_devlink_port_new(struct devlink *devlink,
        if (err)
                return err;
 
+       if (!ice_is_eswitch_mode_switchdev(pf)) {
+               NL_SET_ERR_MSG_MOD(extack,
+                                  "SF ports are only supported in eswitch switchdev mode");
+               return -EOPNOTSUPP;
+       }
+
        return ice_alloc_dynamic_port(pf, new_attr, extack, devlink_port);
 }
index 953262b88a586fa55e9709de733769caf16154a8..272fd823a825d0f2796ff6677c91e41133d4172d 100644 (file)
@@ -31,7 +31,7 @@ static const struct ice_tunnel_type_scan tnls[] = {
  * Verifies various attributes of the package file, including length, format
  * version, and the requirement of at least one segment.
  */
-static enum ice_ddp_state ice_verify_pkg(struct ice_pkg_hdr *pkg, u32 len)
+static enum ice_ddp_state ice_verify_pkg(const struct ice_pkg_hdr *pkg, u32 len)
 {
        u32 seg_count;
        u32 i;
@@ -57,13 +57,13 @@ static enum ice_ddp_state ice_verify_pkg(struct ice_pkg_hdr *pkg, u32 len)
        /* all segments must fit within length */
        for (i = 0; i < seg_count; i++) {
                u32 off = le32_to_cpu(pkg->seg_offset[i]);
-               struct ice_generic_seg_hdr *seg;
+               const struct ice_generic_seg_hdr *seg;
 
                /* segment header must fit */
                if (len < off + sizeof(*seg))
                        return ICE_DDP_PKG_INVALID_FILE;
 
-               seg = (struct ice_generic_seg_hdr *)((u8 *)pkg + off);
+               seg = (void *)pkg + off;
 
                /* segment body must fit */
                if (len < off + le32_to_cpu(seg->seg_size))
@@ -119,13 +119,13 @@ static enum ice_ddp_state ice_chk_pkg_version(struct ice_pkg_ver *pkg_ver)
  *
  * This helper function validates a buffer's header.
  */
-static struct ice_buf_hdr *ice_pkg_val_buf(struct ice_buf *buf)
+static const struct ice_buf_hdr *ice_pkg_val_buf(const struct ice_buf *buf)
 {
-       struct ice_buf_hdr *hdr;
+       const struct ice_buf_hdr *hdr;
        u16 section_count;
        u16 data_end;
 
-       hdr = (struct ice_buf_hdr *)buf->buf;
+       hdr = (const struct ice_buf_hdr *)buf->buf;
        /* verify data */
        section_count = le16_to_cpu(hdr->section_count);
        if (section_count < ICE_MIN_S_COUNT || section_count > ICE_MAX_S_COUNT)
@@ -165,8 +165,8 @@ static struct ice_buf_table *ice_find_buf_table(struct ice_seg *ice_seg)
  * unexpected value has been detected (for example an invalid section count or
  * an invalid buffer end value).
  */
-static struct ice_buf_hdr *ice_pkg_enum_buf(struct ice_seg *ice_seg,
-                                           struct ice_pkg_enum *state)
+static const struct ice_buf_hdr *ice_pkg_enum_buf(struct ice_seg *ice_seg,
+                                                 struct ice_pkg_enum *state)
 {
        if (ice_seg) {
                state->buf_table = ice_find_buf_table(ice_seg);
@@ -1800,9 +1800,9 @@ int ice_update_pkg(struct ice_hw *hw, struct ice_buf *bufs, u32 count)
  * success it returns a pointer to the segment header, otherwise it will
  * return NULL.
  */
-static struct ice_generic_seg_hdr *
+static const struct ice_generic_seg_hdr *
 ice_find_seg_in_pkg(struct ice_hw *hw, u32 seg_type,
-                   struct ice_pkg_hdr *pkg_hdr)
+                   const struct ice_pkg_hdr *pkg_hdr)
 {
        u32 i;
 
@@ -1813,11 +1813,9 @@ ice_find_seg_in_pkg(struct ice_hw *hw, u32 seg_type,
 
        /* Search all package segments for the requested segment type */
        for (i = 0; i < le32_to_cpu(pkg_hdr->seg_count); i++) {
-               struct ice_generic_seg_hdr *seg;
+               const struct ice_generic_seg_hdr *seg;
 
-               seg = (struct ice_generic_seg_hdr
-                              *)((u8 *)pkg_hdr +
-                                 le32_to_cpu(pkg_hdr->seg_offset[i]));
+               seg = (void *)pkg_hdr + le32_to_cpu(pkg_hdr->seg_offset[i]);
 
                if (le32_to_cpu(seg->seg_type) == seg_type)
                        return seg;
@@ -2354,12 +2352,12 @@ ice_get_set_tx_topo(struct ice_hw *hw, u8 *buf, u16 buf_size,
  *
  * Return: zero when update was successful, negative values otherwise.
  */
-int ice_cfg_tx_topo(struct ice_hw *hw, u8 *buf, u32 len)
+int ice_cfg_tx_topo(struct ice_hw *hw, const void *buf, u32 len)
 {
-       u8 *current_topo, *new_topo = NULL;
-       struct ice_run_time_cfg_seg *seg;
-       struct ice_buf_hdr *section;
-       struct ice_pkg_hdr *pkg_hdr;
+       u8 *new_topo = NULL, *topo __free(kfree) = NULL;
+       const struct ice_run_time_cfg_seg *seg;
+       const struct ice_buf_hdr *section;
+       const struct ice_pkg_hdr *pkg_hdr;
        enum ice_ddp_state state;
        u16 offset, size = 0;
        u32 reg = 0;
@@ -2375,15 +2373,13 @@ int ice_cfg_tx_topo(struct ice_hw *hw, u8 *buf, u32 len)
                return -EOPNOTSUPP;
        }
 
-       current_topo = kzalloc(ICE_AQ_MAX_BUF_LEN, GFP_KERNEL);
-       if (!current_topo)
+       topo = kzalloc(ICE_AQ_MAX_BUF_LEN, GFP_KERNEL);
+       if (!topo)
                return -ENOMEM;
 
-       /* Get the current Tx topology */
-       status = ice_get_set_tx_topo(hw, current_topo, ICE_AQ_MAX_BUF_LEN, NULL,
-                                    &flags, false);
-
-       kfree(current_topo);
+       /* Get the current Tx topology flags */
+       status = ice_get_set_tx_topo(hw, topo, ICE_AQ_MAX_BUF_LEN, NULL, &flags,
+                                    false);
 
        if (status) {
                ice_debug(hw, ICE_DBG_INIT, "Get current topology is failed\n");
@@ -2419,7 +2415,7 @@ int ice_cfg_tx_topo(struct ice_hw *hw, u8 *buf, u32 len)
                goto update_topo;
        }
 
-       pkg_hdr = (struct ice_pkg_hdr *)buf;
+       pkg_hdr = (const struct ice_pkg_hdr *)buf;
        state = ice_verify_pkg(pkg_hdr, len);
        if (state) {
                ice_debug(hw, ICE_DBG_INIT, "Failed to verify pkg (err: %d)\n",
@@ -2428,7 +2424,7 @@ int ice_cfg_tx_topo(struct ice_hw *hw, u8 *buf, u32 len)
        }
 
        /* Find runtime configuration segment */
-       seg = (struct ice_run_time_cfg_seg *)
+       seg = (const struct ice_run_time_cfg_seg *)
              ice_find_seg_in_pkg(hw, SEGMENT_TYPE_ICE_RUN_TIME_CFG, pkg_hdr);
        if (!seg) {
                ice_debug(hw, ICE_DBG_INIT, "5 layer topology segment is missing\n");
@@ -2461,8 +2457,10 @@ int ice_cfg_tx_topo(struct ice_hw *hw, u8 *buf, u32 len)
                return -EIO;
        }
 
-       /* Get the new topology buffer */
-       new_topo = ((u8 *)section) + offset;
+       /* Get the new topology buffer, reuse current topo copy mem */
+       static_assert(ICE_PKG_BUF_SIZE == ICE_AQ_MAX_BUF_LEN);
+       new_topo = topo;
+       memcpy(new_topo, (u8 *)section + offset, size);
 
 update_topo:
        /* Acquire global lock to make sure that set topology issued
index 97f272317475489ebc67358c220153d95d744e38..79551da2a4b022ffeca58d179eb6260ae93c3c62 100644 (file)
@@ -438,7 +438,7 @@ struct ice_pkg_enum {
        u32 buf_idx;
 
        u32 type;
-       struct ice_buf_hdr *buf;
+       const struct ice_buf_hdr *buf;
        u32 sect_idx;
        void *sect;
        u32 sect_type;
@@ -467,6 +467,6 @@ ice_pkg_enum_entry(struct ice_seg *ice_seg, struct ice_pkg_enum *state,
 void *ice_pkg_enum_section(struct ice_seg *ice_seg, struct ice_pkg_enum *state,
                           u32 sect_type);
 
-int ice_cfg_tx_topo(struct ice_hw *hw, u8 *buf, u32 len);
+int ice_cfg_tx_topo(struct ice_hw *hw, const void *buf, u32 len);
 
 #endif
index cd95705d1e7fd6594bb71d8182a1c7b544ce71b5..d5ad6d84007c21551d0a18a66bfea06b8922769d 100644 (file)
@@ -10,6 +10,7 @@
 #define ICE_DPLL_PIN_IDX_INVALID               0xff
 #define ICE_DPLL_RCLK_NUM_PER_PF               1
 #define ICE_DPLL_PIN_ESYNC_PULSE_HIGH_PERCENT  25
+#define ICE_DPLL_PIN_GEN_RCLK_FREQ             1953125
 
 /**
  * enum ice_dpll_pin_type - enumerate ice pin types:
@@ -656,6 +657,8 @@ ice_dpll_output_state_set(const struct dpll_pin *pin, void *pin_priv,
        struct ice_dpll_pin *p = pin_priv;
        struct ice_dpll *d = dpll_priv;
 
+       if (state == DPLL_PIN_STATE_SELECTABLE)
+               return -EINVAL;
        if (!enable && p->state[d->dpll_idx] == DPLL_PIN_STATE_DISCONNECTED)
                return 0;
 
@@ -1843,6 +1846,8 @@ ice_dpll_init_rclk_pins(struct ice_pf *pf, struct ice_dpll_pin *pin,
        struct dpll_pin *parent;
        int ret, i;
 
+       if (WARN_ON((!vsi || !vsi->netdev)))
+               return -EINVAL;
        ret = ice_dpll_get_pins(pf, pin, start_idx, ICE_DPLL_RCLK_NUM_PER_PF,
                                pf->dplls.clock_id);
        if (ret)
@@ -1858,8 +1863,6 @@ ice_dpll_init_rclk_pins(struct ice_pf *pf, struct ice_dpll_pin *pin,
                if (ret)
                        goto unregister_pins;
        }
-       if (WARN_ON((!vsi || !vsi->netdev)))
-               return -EINVAL;
        dpll_netdev_pin_set(vsi->netdev, pf->dplls.rclk.pin);
 
        return 0;
@@ -2061,6 +2064,73 @@ static int ice_dpll_init_worker(struct ice_pf *pf)
        return 0;
 }
 
+/**
+ * ice_dpll_init_info_pins_generic - initializes generic pins info
+ * @pf: board private structure
+ * @input: if input pins initialized
+ *
+ * Init information for generic pins, cache them in PF's pins structures.
+ *
+ * Return:
+ * * 0 - success
+ * * negative - init failure reason
+ */
+static int ice_dpll_init_info_pins_generic(struct ice_pf *pf, bool input)
+{
+       struct ice_dpll *de = &pf->dplls.eec, *dp = &pf->dplls.pps;
+       static const char labels[][sizeof("99")] = {
+               "0", "1", "2", "3", "4", "5", "6", "7", "8",
+               "9", "10", "11", "12", "13", "14", "15" };
+       u32 cap = DPLL_PIN_CAPABILITIES_STATE_CAN_CHANGE;
+       enum ice_dpll_pin_type pin_type;
+       int i, pin_num, ret = -EINVAL;
+       struct ice_dpll_pin *pins;
+       u32 phase_adj_max;
+
+       if (input) {
+               pin_num = pf->dplls.num_inputs;
+               pins = pf->dplls.inputs;
+               phase_adj_max = pf->dplls.input_phase_adj_max;
+               pin_type = ICE_DPLL_PIN_TYPE_INPUT;
+               cap |= DPLL_PIN_CAPABILITIES_PRIORITY_CAN_CHANGE;
+       } else {
+               pin_num = pf->dplls.num_outputs;
+               pins = pf->dplls.outputs;
+               phase_adj_max = pf->dplls.output_phase_adj_max;
+               pin_type = ICE_DPLL_PIN_TYPE_OUTPUT;
+       }
+       if (pin_num > ARRAY_SIZE(labels))
+               return ret;
+
+       for (i = 0; i < pin_num; i++) {
+               pins[i].idx = i;
+               pins[i].prop.board_label = labels[i];
+               pins[i].prop.phase_range.min = phase_adj_max;
+               pins[i].prop.phase_range.max = -phase_adj_max;
+               pins[i].prop.capabilities = cap;
+               pins[i].pf = pf;
+               ret = ice_dpll_pin_state_update(pf, &pins[i], pin_type, NULL);
+               if (ret)
+                       break;
+               if (input && pins[i].freq == ICE_DPLL_PIN_GEN_RCLK_FREQ)
+                       pins[i].prop.type = DPLL_PIN_TYPE_MUX;
+               else
+                       pins[i].prop.type = DPLL_PIN_TYPE_EXT;
+               if (!input)
+                       continue;
+               ret = ice_aq_get_cgu_ref_prio(&pf->hw, de->dpll_idx, i,
+                                             &de->input_prio[i]);
+               if (ret)
+                       break;
+               ret = ice_aq_get_cgu_ref_prio(&pf->hw, dp->dpll_idx, i,
+                                             &dp->input_prio[i]);
+               if (ret)
+                       break;
+       }
+
+       return ret;
+}
+
 /**
  * ice_dpll_init_info_direct_pins - initializes direct pins info
  * @pf: board private structure
@@ -2099,6 +2169,8 @@ ice_dpll_init_info_direct_pins(struct ice_pf *pf,
        default:
                return -EINVAL;
        }
+       if (num_pins != ice_cgu_get_num_pins(hw, input))
+               return ice_dpll_init_info_pins_generic(pf, input);
 
        for (i = 0; i < num_pins; i++) {
                caps = 0;
index f5aceb32bf4dd21afa2197fd879fd6932dd3e4be..cccb7ddf61c9753bb9a97ccb19656781009db479 100644 (file)
@@ -582,10 +582,13 @@ ice_eswitch_br_switchdev_event(struct notifier_block *nb,
        return NOTIFY_DONE;
 }
 
-static void ice_eswitch_br_fdb_flush(struct ice_esw_br *bridge)
+void ice_eswitch_br_fdb_flush(struct ice_esw_br *bridge)
 {
        struct ice_esw_br_fdb_entry *entry, *tmp;
 
+       if (!bridge)
+               return;
+
        list_for_each_entry_safe(entry, tmp, &bridge->fdb_list, list)
                ice_eswitch_br_fdb_entry_notify_and_cleanup(bridge, entry);
 }
index c15c7344d7f85335cfd45ae6b8b0c1a41404b5af..66a2c804338f0d7b1b5c4965cdc95546a780818a 100644 (file)
@@ -117,5 +117,6 @@ void
 ice_eswitch_br_offloads_deinit(struct ice_pf *pf);
 int
 ice_eswitch_br_offloads_init(struct ice_pf *pf);
+void ice_eswitch_br_fdb_flush(struct ice_esw_br *bridge);
 
 #endif /* _ICE_ESWITCH_BR_H_ */
index f81db6c107c8efb47156aafe4ac42eb9369bbed8..2702a0da5c3e4673175b69e5c882809d8b494fd5 100644 (file)
@@ -1,7 +1,7 @@
 // SPDX-License-Identifier: GPL-2.0
 /* Copyright (C) 2018-2019, Intel Corporation. */
 
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include <linux/uuid.h>
 #include <linux/crc32.h>
 #include <linux/pldmfw.h>
index eeb48cc48e089f3d602f49016f372e7c36c2c40d..b1e7727b8677f93820e81018eb7e88610f89caa5 100644 (file)
@@ -87,7 +87,8 @@ ice_indr_setup_tc_cb(struct net_device *netdev, struct Qdisc *sch,
 
 bool netif_is_ice(const struct net_device *dev)
 {
-       return dev && (dev->netdev_ops == &ice_netdev_ops);
+       return dev && (dev->netdev_ops == &ice_netdev_ops ||
+                      dev->netdev_ops == &ice_netdev_safe_mode_ops);
 }
 
 /**
@@ -520,25 +521,6 @@ static void ice_pf_dis_all_vsi(struct ice_pf *pf, bool locked)
                pf->vf_agg_node[node].num_vsis = 0;
 }
 
-/**
- * ice_clear_sw_switch_recipes - clear switch recipes
- * @pf: board private structure
- *
- * Mark switch recipes as not created in sw structures. There are cases where
- * rules (especially advanced rules) need to be restored, either re-read from
- * hardware or added again. For example after the reset. 'recp_created' flag
- * prevents from doing that and need to be cleared upfront.
- */
-static void ice_clear_sw_switch_recipes(struct ice_pf *pf)
-{
-       struct ice_sw_recipe *recp;
-       u8 i;
-
-       recp = pf->hw.switch_info->recp_list;
-       for (i = 0; i < ICE_MAX_NUM_RECIPES; i++)
-               recp[i].recp_created = false;
-}
-
 /**
  * ice_prepare_for_reset - prep for reset
  * @pf: board private structure
@@ -575,8 +557,9 @@ ice_prepare_for_reset(struct ice_pf *pf, enum ice_reset_req reset_type)
        mutex_unlock(&pf->vfs.table_lock);
 
        if (ice_is_eswitch_mode_switchdev(pf)) {
-               if (reset_type != ICE_RESET_PFR)
-                       ice_clear_sw_switch_recipes(pf);
+               rtnl_lock();
+               ice_eswitch_br_fdb_flush(pf->eswitch.br_offloads->bridge);
+               rtnl_unlock();
        }
 
        /* release ADQ specific HW and SW resources */
@@ -4536,16 +4519,10 @@ ice_init_tx_topology(struct ice_hw *hw, const struct firmware *firmware)
        u8 num_tx_sched_layers = hw->num_tx_sched_layers;
        struct ice_pf *pf = hw->back;
        struct device *dev;
-       u8 *buf_copy;
        int err;
 
        dev = ice_pf_to_dev(pf);
-       /* ice_cfg_tx_topo buf argument is not a constant,
-        * so we have to make a copy
-        */
-       buf_copy = kmemdup(firmware->data, firmware->size, GFP_KERNEL);
-
-       err = ice_cfg_tx_topo(hw, buf_copy, firmware->size);
+       err = ice_cfg_tx_topo(hw, firmware->data, firmware->size);
        if (!err) {
                if (hw->num_tx_sched_layers > num_tx_sched_layers)
                        dev_info(dev, "Tx scheduling layers switching feature disabled\n");
@@ -4773,14 +4750,12 @@ int ice_init_dev(struct ice_pf *pf)
        ice_init_feature_support(pf);
 
        err = ice_init_ddp_config(hw, pf);
-       if (err)
-               return err;
 
        /* if ice_init_ddp_config fails, ICE_FLAG_ADV_FEATURES bit won't be
         * set in pf->state, which will cause ice_is_safe_mode to return
         * true
         */
-       if (ice_is_safe_mode(pf)) {
+       if (err || ice_is_safe_mode(pf)) {
                /* we already got function/device capabilities but these don't
                 * reflect what the driver needs to do in safe mode. Instead of
                 * adding conditional logic everywhere to ignore these
index 3a33e6b9b313d7a645739f41a5400492b3dc10c5..ec8db830ac73ae12be88df20cb333854752a0713 100644 (file)
@@ -34,7 +34,6 @@ static const struct ice_cgu_pin_desc ice_e810t_sfp_cgu_inputs[] = {
                ARRAY_SIZE(ice_cgu_pin_freq_common), ice_cgu_pin_freq_common },
        { "GNSS-1PPS",    ZL_REF4P, DPLL_PIN_TYPE_GNSS,
                ARRAY_SIZE(ice_cgu_pin_freq_1_hz), ice_cgu_pin_freq_1_hz },
-       { "OCXO",         ZL_REF4N, DPLL_PIN_TYPE_INT_OSCILLATOR, 0, },
 };
 
 static const struct ice_cgu_pin_desc ice_e810t_qsfp_cgu_inputs[] = {
@@ -52,7 +51,6 @@ static const struct ice_cgu_pin_desc ice_e810t_qsfp_cgu_inputs[] = {
                ARRAY_SIZE(ice_cgu_pin_freq_common), ice_cgu_pin_freq_common },
        { "GNSS-1PPS",    ZL_REF4P, DPLL_PIN_TYPE_GNSS,
                ARRAY_SIZE(ice_cgu_pin_freq_1_hz), ice_cgu_pin_freq_1_hz },
-       { "OCXO",         ZL_REF4N, DPLL_PIN_TYPE_INT_OSCILLATOR, },
 };
 
 static const struct ice_cgu_pin_desc ice_e810t_sfp_cgu_outputs[] = {
@@ -5964,6 +5962,25 @@ ice_cgu_get_pin_desc(struct ice_hw *hw, bool input, int *size)
        return t;
 }
 
+/**
+ * ice_cgu_get_num_pins - get pin description array size
+ * @hw: pointer to the hw struct
+ * @input: if request is done against input or output pins
+ *
+ * Return: size of pin description array for given hw.
+ */
+int ice_cgu_get_num_pins(struct ice_hw *hw, bool input)
+{
+       const struct ice_cgu_pin_desc *t;
+       int size;
+
+       t = ice_cgu_get_pin_desc(hw, input, &size);
+       if (t)
+               return size;
+
+       return 0;
+}
+
 /**
  * ice_cgu_get_pin_type - get pin's type
  * @hw: pointer to the hw struct
index 0852a34ade918bbe14548f6660cbe53271db6db2..6cedc1a906afb6f68408ccc28a65e8ef2b88f88b 100644 (file)
@@ -404,6 +404,7 @@ int ice_read_sma_ctrl_e810t(struct ice_hw *hw, u8 *data);
 int ice_write_sma_ctrl_e810t(struct ice_hw *hw, u8 data);
 int ice_read_pca9575_reg_e810t(struct ice_hw *hw, u8 offset, u8 *data);
 bool ice_is_pca9575_present(struct ice_hw *hw);
+int ice_cgu_get_num_pins(struct ice_hw *hw, bool input);
 enum dpll_pin_type ice_cgu_get_pin_type(struct ice_hw *hw, u8 pin, bool input);
 struct dpll_pin_frequency *
 ice_cgu_get_pin_freq_supp(struct ice_hw *hw, u8 pin, bool input, u8 *num);
index e34fe2516cccf2bd01df0db83addfc76e77a09f2..91cb393f616f2be6a9f0f6fd8cc2f0e8a7db5560 100644 (file)
@@ -1096,8 +1096,10 @@ int ice_sriov_set_msix_vec_count(struct pci_dev *vf_dev, int msix_vec_count)
                return -ENOENT;
 
        vsi = ice_get_vf_vsi(vf);
-       if (!vsi)
+       if (!vsi) {
+               ice_put_vf(vf);
                return -ENOENT;
+       }
 
        prev_msix = vf->num_msix;
        prev_queues = vf->num_vf_qs;
@@ -1119,7 +1121,10 @@ int ice_sriov_set_msix_vec_count(struct pci_dev *vf_dev, int msix_vec_count)
        if (vf->first_vector_idx < 0)
                goto unroll;
 
-       if (ice_vf_reconfig_vsi(vf) || ice_vf_init_host_cfg(vf, vsi)) {
+       vsi->req_txq = queues;
+       vsi->req_rxq = queues;
+
+       if (ice_vsi_rebuild(vsi, ICE_VSI_FLAG_NO_INIT)) {
                /* Try to rebuild with previous values */
                needs_rebuild = true;
                goto unroll;
@@ -1142,12 +1147,16 @@ unroll:
        vf->num_msix = prev_msix;
        vf->num_vf_qs = prev_queues;
        vf->first_vector_idx = ice_sriov_get_irqs(pf, vf->num_msix);
-       if (vf->first_vector_idx < 0)
+       if (vf->first_vector_idx < 0) {
+               ice_put_vf(vf);
                return -EINVAL;
+       }
 
        if (needs_rebuild) {
-               ice_vf_reconfig_vsi(vf);
-               ice_vf_init_host_cfg(vf, vsi);
+               vsi->req_txq = prev_queues;
+               vsi->req_rxq = prev_queues;
+
+               ice_vsi_rebuild(vsi, ICE_VSI_FLAG_NO_INIT);
        }
 
        ice_ena_vf_mappings(vf);
index 79d91e95358ca1f47026ba081112bbf278393b40..0e740342e2947eb4ee3ebae525e932f27454242f 100644 (file)
@@ -6322,8 +6322,6 @@ ice_replay_vsi_fltr(struct ice_hw *hw, u16 vsi_handle, u8 recp_id,
                if (!itr->vsi_list_info ||
                    !test_bit(vsi_handle, itr->vsi_list_info->vsi_map))
                        continue;
-               /* Clearing it so that the logic can add it back */
-               clear_bit(vsi_handle, itr->vsi_list_info->vsi_map);
                f_entry.fltr_info.vsi_handle = vsi_handle;
                f_entry.fltr_info.fltr_act = ICE_FWD_TO_VSI;
                /* update the src in case it is VSI num */
index e6923f8121a994822b1e940381bd21ec37fbb61e..ea39b999a0d000968fd55cbf6f767dfad5e33b59 100644 (file)
@@ -819,6 +819,17 @@ ice_eswitch_add_tc_fltr(struct ice_vsi *vsi, struct ice_tc_flower_fltr *fltr)
                rule_info.sw_act.flag |= ICE_FLTR_TX;
                rule_info.sw_act.src = vsi->idx;
                rule_info.flags_info.act = ICE_SINGLE_ACT_LAN_ENABLE;
+               /* This is a specific case. The destination VSI index is
+                * overwritten by the source VSI index. This type of filter
+                * should allow the packet to go to the LAN, not to the
+                * VSI passed here. It should set LAN_EN bit only. However,
+                * the VSI must be a valid one. Setting source VSI index
+                * here is safe. Even if the result from switch is set LAN_EN
+                * and LB_EN (which normally will pass the packet to this VSI)
+                * packet won't be seen on the VSI, because local loopback is
+                * turned off.
+                */
+               rule_info.sw_act.vsi_handle = vsi->idx;
        } else {
                /* VF to VF */
                rule_info.sw_act.flag |= ICE_FLTR_TX;
index a69e91f88d81181d4897c9fda2a930267f139404..8c434689e3f78e60968dee33829be5cfa1cb942c 100644 (file)
@@ -256,7 +256,7 @@ static void ice_vf_pre_vsi_rebuild(struct ice_vf *vf)
  *
  * It brings the VSI down and then reconfigures it with the hardware.
  */
-int ice_vf_reconfig_vsi(struct ice_vf *vf)
+static int ice_vf_reconfig_vsi(struct ice_vf *vf)
 {
        struct ice_vsi *vsi = ice_get_vf_vsi(vf);
        struct ice_pf *pf = vf->pf;
@@ -335,6 +335,13 @@ static int ice_vf_rebuild_host_vlan_cfg(struct ice_vf *vf, struct ice_vsi *vsi)
 
                err = vlan_ops->add_vlan(vsi, &vf->port_vlan_info);
        } else {
+               /* clear possible previous port vlan config */
+               err = ice_vsi_clear_port_vlan(vsi);
+               if (err) {
+                       dev_err(dev, "failed to clear port VLAN via VSI parameters for VF %u, error %d\n",
+                               vf->vf_id, err);
+                       return err;
+               }
                err = ice_vsi_add_vlan_zero(vsi);
        }
 
index 91ba7fe0eaee1acdd454cf723528079438e09c7c..0c7e77c0a09fa62547016149aa86b28106155759 100644 (file)
@@ -23,7 +23,6 @@
 #warning "Only include ice_vf_lib_private.h in CONFIG_PCI_IOV virtualization files"
 #endif
 
-int ice_vf_reconfig_vsi(struct ice_vf *vf);
 void ice_initialize_vf_entry(struct ice_vf *vf);
 void ice_dis_vf_qs(struct ice_vf *vf);
 int ice_check_vf_init(struct ice_vf *vf);
index 6e8f2aab6080153082f1fde3e58effabc5df720a..5291f2888ef89aa07fb0085a13ae09a8483cc449 100644 (file)
@@ -787,3 +787,60 @@ int ice_vsi_clear_outer_port_vlan(struct ice_vsi *vsi)
        kfree(ctxt);
        return err;
 }
+
+int ice_vsi_clear_port_vlan(struct ice_vsi *vsi)
+{
+       struct ice_hw *hw = &vsi->back->hw;
+       struct ice_vsi_ctx *ctxt;
+       int err;
+
+       ctxt = kzalloc(sizeof(*ctxt), GFP_KERNEL);
+       if (!ctxt)
+               return -ENOMEM;
+
+       ctxt->info = vsi->info;
+
+       ctxt->info.port_based_outer_vlan = 0;
+       ctxt->info.port_based_inner_vlan = 0;
+
+       ctxt->info.inner_vlan_flags =
+               FIELD_PREP(ICE_AQ_VSI_INNER_VLAN_TX_MODE_M,
+                          ICE_AQ_VSI_INNER_VLAN_TX_MODE_ALL);
+       if (ice_is_dvm_ena(hw)) {
+               ctxt->info.inner_vlan_flags |=
+                       FIELD_PREP(ICE_AQ_VSI_INNER_VLAN_EMODE_M,
+                                  ICE_AQ_VSI_INNER_VLAN_EMODE_NOTHING);
+               ctxt->info.outer_vlan_flags =
+                       FIELD_PREP(ICE_AQ_VSI_OUTER_VLAN_TX_MODE_M,
+                                  ICE_AQ_VSI_OUTER_VLAN_TX_MODE_ALL);
+               ctxt->info.outer_vlan_flags |=
+                       FIELD_PREP(ICE_AQ_VSI_OUTER_TAG_TYPE_M,
+                                  ICE_AQ_VSI_OUTER_TAG_VLAN_8100);
+               ctxt->info.outer_vlan_flags |=
+                       ICE_AQ_VSI_OUTER_VLAN_EMODE_NOTHING <<
+                       ICE_AQ_VSI_OUTER_VLAN_EMODE_S;
+       }
+
+       ctxt->info.sw_flags2 &= ~ICE_AQ_VSI_SW_FLAG_RX_VLAN_PRUNE_ENA;
+       ctxt->info.valid_sections =
+               cpu_to_le16(ICE_AQ_VSI_PROP_OUTER_TAG_VALID |
+                           ICE_AQ_VSI_PROP_VLAN_VALID |
+                           ICE_AQ_VSI_PROP_SW_VALID);
+
+       err = ice_update_vsi(hw, vsi->idx, ctxt, NULL);
+       if (err) {
+               dev_err(ice_pf_to_dev(vsi->back), "update VSI for clearing port based VLAN failed, err %d aq_err %s\n",
+                       err, ice_aq_str(hw->adminq.sq_last_status));
+       } else {
+               vsi->info.port_based_outer_vlan =
+                       ctxt->info.port_based_outer_vlan;
+               vsi->info.port_based_inner_vlan =
+                       ctxt->info.port_based_inner_vlan;
+               vsi->info.outer_vlan_flags = ctxt->info.outer_vlan_flags;
+               vsi->info.inner_vlan_flags = ctxt->info.inner_vlan_flags;
+               vsi->info.sw_flags2 = ctxt->info.sw_flags2;
+       }
+
+       kfree(ctxt);
+       return err;
+}
index f0d84d11bd5b1f83682779512bc9d1d15d36218e..12b227621a7ddc89c9dfed0c9a4a238d82e35e14 100644 (file)
@@ -36,5 +36,6 @@ int ice_vsi_ena_outer_insertion(struct ice_vsi *vsi, u16 tpid);
 int ice_vsi_dis_outer_insertion(struct ice_vsi *vsi);
 int ice_vsi_set_outer_port_vlan(struct ice_vsi *vsi, struct ice_vlan *vlan);
 int ice_vsi_clear_outer_port_vlan(struct ice_vsi *vsi);
+int ice_vsi_clear_port_vlan(struct ice_vsi *vsi);
 
 #endif /* _ICE_VSI_VLAN_LIB_H_ */
index 99b8dbaf4225c5317dd204f0ab5f03d794f2926b..aad62e270ae40ef43b6fc19ccfee8035ffb2469a 100644 (file)
@@ -99,6 +99,7 @@ static int idpf_vf_intr_reg_init(struct idpf_vport *vport)
                intr->dyn_ctl_intena_m = VF_INT_DYN_CTLN_INTENA_M;
                intr->dyn_ctl_intena_msk_m = VF_INT_DYN_CTLN_INTENA_MSK_M;
                intr->dyn_ctl_itridx_s = VF_INT_DYN_CTLN_ITR_INDX_S;
+               intr->dyn_ctl_intrvl_s = VF_INT_DYN_CTLN_INTERVAL_S;
                intr->dyn_ctl_wb_on_itr_m = VF_INT_DYN_CTLN_WB_ON_ITR_M;
 
                spacing = IDPF_ITR_IDX_SPACING(reg_vals[vec_id].itrn_index_spacing,
index 70986e12da28e3fe55891e370f49a05dc599b6d6..15c00a01f1c0b988e349e196fa3d9a25cbcf78d5 100644 (file)
@@ -666,7 +666,7 @@ idpf_vc_xn_forward_reply(struct idpf_adapter *adapter,
 
        if (ctlq_msg->data_len) {
                payload = ctlq_msg->ctx.indirect.payload->va;
-               payload_size = ctlq_msg->ctx.indirect.payload->size;
+               payload_size = ctlq_msg->data_len;
        }
 
        xn->reply_sz = payload_size;
@@ -1295,10 +1295,6 @@ int idpf_send_create_vport_msg(struct idpf_adapter *adapter,
                err = reply_sz;
                goto free_vport_params;
        }
-       if (reply_sz < IDPF_CTLQ_MAX_BUF_LEN) {
-               err = -EIO;
-               goto free_vport_params;
-       }
 
        return 0;
 
@@ -2602,9 +2598,6 @@ int idpf_send_get_rx_ptype_msg(struct idpf_vport *vport)
                if (reply_sz < 0)
                        return reply_sz;
 
-               if (reply_sz < IDPF_CTLQ_MAX_BUF_LEN)
-                       return -EIO;
-
                ptypes_recvd += le16_to_cpu(ptype_info->num_ptypes);
                if (ptypes_recvd > max_ptype)
                        return -EINVAL;
@@ -3088,9 +3081,9 @@ void idpf_vc_core_deinit(struct idpf_adapter *adapter)
        if (!test_bit(IDPF_VC_CORE_INIT, adapter->flags))
                return;
 
-       idpf_vc_xn_shutdown(adapter->vcxn_mngr);
        idpf_deinit_task(adapter);
        idpf_intr_rel(adapter);
+       idpf_vc_xn_shutdown(adapter->vcxn_mngr);
 
        cancel_delayed_work_sync(&adapter->serv_task);
        cancel_delayed_work_sync(&adapter->mbx_task);
index 1ef4cb871452a6a5aac3e92b4770a82194d927e4..b83df5f94b1f57d3b8f0000798aef0dd15521f62 100644 (file)
@@ -907,7 +907,7 @@ static int igb_request_msix(struct igb_adapter *adapter)
        int i, err = 0, vector = 0, free_vector = 0;
 
        err = request_irq(adapter->msix_entries[vector].vector,
-                         igb_msix_other, 0, netdev->name, adapter);
+                         igb_msix_other, IRQF_NO_THREAD, netdev->name, adapter);
        if (err)
                goto err_out;
 
@@ -9651,6 +9651,10 @@ static void igb_io_resume(struct pci_dev *pdev)
        struct igb_adapter *adapter = netdev_priv(netdev);
 
        if (netif_running(netdev)) {
+               if (!test_bit(__IGB_DOWN, &adapter->state)) {
+                       dev_dbg(&pdev->dev, "Resuming from non-fatal error, do nothing.\n");
+                       return;
+               }
                if (igb_up(adapter)) {
                        dev_err(&pdev->dev, "igb_up failed after reset\n");
                        return;
index 3c289bfe0a0920c15c4f88597eed359acf7a2b11..7179271f63b6552cb0bbadd0a5fc2994fbf8ffc9 100644 (file)
@@ -481,7 +481,9 @@ ltq_etop_tx(struct sk_buff *skb, struct net_device *dev)
        unsigned long flags;
        u32 byte_offset;
 
-       len = skb->len < ETH_ZLEN ? ETH_ZLEN : skb->len;
+       if (skb_put_padto(skb, ETH_ZLEN))
+               return NETDEV_TX_OK;
+       len = skb->len;
 
        if ((desc->ctl & (LTQ_DMA_OWN | LTQ_DMA_C)) || ch->skb[ch->dma.desc]) {
                netdev_err(dev, "tx ring full\n");
index 4746a6b258f08de884ccefd25a7cfc819d716ec8..8af75cb37c3ee8e6a0e0d85fde4f9a9dc14442fd 100644 (file)
@@ -336,6 +336,51 @@ static int octep_oq_check_hw_for_pkts(struct octep_device *oct,
        return new_pkts;
 }
 
+/**
+ * octep_oq_next_pkt() - Move to the next packet in Rx queue.
+ *
+ * @oq: Octeon Rx queue data structure.
+ * @buff_info: Current packet buffer info.
+ * @read_idx: Current packet index in the ring.
+ * @desc_used: Current packet descriptor number.
+ *
+ * Free the resources associated with a packet.
+ * Increment packet index in the ring and packet descriptor number.
+ */
+static void octep_oq_next_pkt(struct octep_oq *oq,
+                             struct octep_rx_buffer *buff_info,
+                             u32 *read_idx, u32 *desc_used)
+{
+       dma_unmap_page(oq->dev, oq->desc_ring[*read_idx].buffer_ptr,
+                      PAGE_SIZE, DMA_FROM_DEVICE);
+       buff_info->page = NULL;
+       (*read_idx)++;
+       (*desc_used)++;
+       if (*read_idx == oq->max_count)
+               *read_idx = 0;
+}
+
+/**
+ * octep_oq_drop_rx() - Free the resources associated with a packet.
+ *
+ * @oq: Octeon Rx queue data structure.
+ * @buff_info: Current packet buffer info.
+ * @read_idx: Current packet index in the ring.
+ * @desc_used: Current packet descriptor number.
+ *
+ */
+static void octep_oq_drop_rx(struct octep_oq *oq,
+                            struct octep_rx_buffer *buff_info,
+                            u32 *read_idx, u32 *desc_used)
+{
+       int data_len = buff_info->len - oq->max_single_buffer_size;
+
+       while (data_len > 0) {
+               octep_oq_next_pkt(oq, buff_info, read_idx, desc_used);
+               data_len -= oq->buffer_size;
+       };
+}
+
 /**
  * __octep_oq_process_rx() - Process hardware Rx queue and push to stack.
  *
@@ -367,10 +412,7 @@ static int __octep_oq_process_rx(struct octep_device *oct,
        desc_used = 0;
        for (pkt = 0; pkt < pkts_to_process; pkt++) {
                buff_info = (struct octep_rx_buffer *)&oq->buff_info[read_idx];
-               dma_unmap_page(oq->dev, oq->desc_ring[read_idx].buffer_ptr,
-                              PAGE_SIZE, DMA_FROM_DEVICE);
                resp_hw = page_address(buff_info->page);
-               buff_info->page = NULL;
 
                /* Swap the length field that is in Big-Endian to CPU */
                buff_info->len = be64_to_cpu(resp_hw->length);
@@ -394,36 +436,33 @@ static int __octep_oq_process_rx(struct octep_device *oct,
                        data_offset = OCTEP_OQ_RESP_HW_SIZE;
                        rx_ol_flags = 0;
                }
+
+               octep_oq_next_pkt(oq, buff_info, &read_idx, &desc_used);
+
+               skb = build_skb((void *)resp_hw, PAGE_SIZE);
+               if (!skb) {
+                       octep_oq_drop_rx(oq, buff_info,
+                                        &read_idx, &desc_used);
+                       oq->stats.alloc_failures++;
+                       continue;
+               }
+               skb_reserve(skb, data_offset);
+
                rx_bytes += buff_info->len;
 
                if (buff_info->len <= oq->max_single_buffer_size) {
-                       skb = build_skb((void *)resp_hw, PAGE_SIZE);
-                       skb_reserve(skb, data_offset);
                        skb_put(skb, buff_info->len);
-                       read_idx++;
-                       desc_used++;
-                       if (read_idx == oq->max_count)
-                               read_idx = 0;
                } else {
                        struct skb_shared_info *shinfo;
                        u16 data_len;
 
-                       skb = build_skb((void *)resp_hw, PAGE_SIZE);
-                       skb_reserve(skb, data_offset);
                        /* Head fragment includes response header(s);
                         * subsequent fragments contains only data.
                         */
                        skb_put(skb, oq->max_single_buffer_size);
-                       read_idx++;
-                       desc_used++;
-                       if (read_idx == oq->max_count)
-                               read_idx = 0;
-
                        shinfo = skb_shinfo(skb);
                        data_len = buff_info->len - oq->max_single_buffer_size;
                        while (data_len) {
-                               dma_unmap_page(oq->dev, oq->desc_ring[read_idx].buffer_ptr,
-                                              PAGE_SIZE, DMA_FROM_DEVICE);
                                buff_info = (struct octep_rx_buffer *)
                                            &oq->buff_info[read_idx];
                                if (data_len < oq->buffer_size) {
@@ -438,11 +477,8 @@ static int __octep_oq_process_rx(struct octep_device *oct,
                                                buff_info->page, 0,
                                                buff_info->len,
                                                buff_info->len);
-                               buff_info->page = NULL;
-                               read_idx++;
-                               desc_used++;
-                               if (read_idx == oq->max_count)
-                                       read_idx = 0;
+
+                               octep_oq_next_pkt(oq, buff_info, &read_idx, &desc_used);
                        }
                }
 
index 82832a24fbd866ef1908c06d6b06107dc90ffb39..da69350c6f76542ee38abbfa5ddcd2676da4362e 100644 (file)
@@ -2411,7 +2411,7 @@ static int nix_smq_flush(struct rvu *rvu, int blkaddr,
                                 NIX_AF_TL3_TL2X_LINKX_CFG(tl2_tl3_link_schq, link));
                if (!(cfg & BIT_ULL(12)))
                        continue;
-               bmap |= (1 << i);
+               bmap |= BIT_ULL(i);
                cfg &= ~BIT_ULL(12);
                rvu_write64(rvu, blkaddr,
                            NIX_AF_TL3_TL2X_LINKX_CFG(tl2_tl3_link_schq, link), cfg);
@@ -2432,7 +2432,7 @@ static int nix_smq_flush(struct rvu *rvu, int blkaddr,
 
        /* Set NIX_AF_TL3_TL2_LINKX_CFG[ENA] for the TL3/TL2 queue */
        for (i = 0; i < (rvu->hw->cgx_links + rvu->hw->lbk_links); i++) {
-               if (!(bmap & (1 << i)))
+               if (!(bmap & BIT_ULL(i)))
                        continue;
                cfg = rvu_read64(rvu, blkaddr,
                                 NIX_AF_TL3_TL2X_LINKX_CFG(tl2_tl3_link_schq, link));
index 930f180688e5caf1175481a43d243812bc07be07..2c26eb185283725ff50803437dac5143d7884b5a 100644 (file)
@@ -2471,10 +2471,6 @@ static netdev_tx_t airoha_dev_xmit(struct sk_buff *skb,
                e->dma_addr = addr;
                e->dma_len = len;
 
-               airoha_qdma_rmw(qdma, REG_TX_CPU_IDX(qid),
-                               TX_RING_CPU_IDX_MASK,
-                               FIELD_PREP(TX_RING_CPU_IDX_MASK, index));
-
                data = skb_frag_address(frag);
                len = skb_frag_size(frag);
        }
@@ -2483,6 +2479,11 @@ static netdev_tx_t airoha_dev_xmit(struct sk_buff *skb,
        q->queued += i;
 
        skb_tx_timestamp(skb);
+       if (!netdev_xmit_more())
+               airoha_qdma_rmw(qdma, REG_TX_CPU_IDX(qid),
+                               TX_RING_CPU_IDX_MASK,
+                               FIELD_PREP(TX_RING_CPU_IDX_MASK, q->head));
+
        if (q->ndesc - q->queued < q->free_thr)
                netif_tx_stop_queue(txq);
 
index 16ca427cf4c3f4325cc6942efefc2c9d68237d27..ed7313c10a0524eb0763825b4ce27b1b64363585 100644 (file)
@@ -1171,7 +1171,7 @@ static int mtk_init_fq_dma(struct mtk_eth *eth)
                if (unlikely(dma_mapping_error(eth->dma_dev, dma_addr)))
                        return -ENOMEM;
 
-               for (i = 0; i < cnt; i++) {
+               for (i = 0; i < len; i++) {
                        struct mtk_tx_dma_v2 *txd;
 
                        txd = eth->scratch_ring + (j * MTK_FQ_DMA_LENGTH + i) * soc->tx.desc_size;
index ea0884186d7644b0869edb186f4ca963c8716e89..c06e5ad18b0105c1ac63d7a63d422800316a7ae2 100644 (file)
@@ -10,7 +10,7 @@
 #include <linux/of_reserved_mem.h>
 #include <linux/mfd/syscon.h>
 #include <linux/soc/mediatek/mtk_wed.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #include "mtk_wed_regs.h"
 #include "mtk_wed_wo.h"
index 87a67fa3868d34387084935b646f266c796965af..c01b1e8428f6d530a21bcca54ef06ab728ef866f 100644 (file)
@@ -91,8 +91,8 @@ enum mtk_wed_dummy_cr_idx {
 #define MT7981_FIRMWARE_WO     "mediatek/mt7981_wo.bin"
 #define MT7986_FIRMWARE_WO0    "mediatek/mt7986_wo_0.bin"
 #define MT7986_FIRMWARE_WO1    "mediatek/mt7986_wo_1.bin"
-#define MT7988_FIRMWARE_WO0    "mediatek/mt7988_wo_0.bin"
-#define MT7988_FIRMWARE_WO1    "mediatek/mt7988_wo_1.bin"
+#define MT7988_FIRMWARE_WO0    "mediatek/mt7988/mt7988_wo_0.bin"
+#define MT7988_FIRMWARE_WO1    "mediatek/mt7988/mt7988_wo_1.bin"
 
 #define MTK_WO_MCU_CFG_LS_BASE                         0
 #define MTK_WO_MCU_CFG_LS_HW_VER_ADDR                  (MTK_WO_MCU_CFG_LS_BASE + 0x000)
index a64d96effb9eacc9640b704952f20d9ffbd17318..6bd8a18e3af3a1c6c78bd299e1811dd9b167125c 100644 (file)
@@ -1765,6 +1765,10 @@ static void mlx5_cmd_comp_handler(struct mlx5_core_dev *dev, u64 vec, bool force
        }
 }
 
+#define MLX5_MAX_MANAGE_PAGES_CMD_ENT 1
+#define MLX5_CMD_MASK ((1UL << (cmd->vars.max_reg_cmds + \
+                          MLX5_MAX_MANAGE_PAGES_CMD_ENT)) - 1)
+
 static void mlx5_cmd_trigger_completions(struct mlx5_core_dev *dev)
 {
        struct mlx5_cmd *cmd = &dev->cmd;
@@ -1776,7 +1780,7 @@ static void mlx5_cmd_trigger_completions(struct mlx5_core_dev *dev)
        /* wait for pending handlers to complete */
        mlx5_eq_synchronize_cmd_irq(dev);
        spin_lock_irqsave(&dev->cmd.alloc_lock, flags);
-       vector = ~dev->cmd.vars.bitmask & ((1ul << (1 << dev->cmd.vars.log_sz)) - 1);
+       vector = ~dev->cmd.vars.bitmask & MLX5_CMD_MASK;
        if (!vector)
                goto no_trig;
 
@@ -2361,7 +2365,7 @@ int mlx5_cmd_enable(struct mlx5_core_dev *dev)
 
        cmd->state = MLX5_CMDIF_STATE_DOWN;
        cmd->vars.max_reg_cmds = (1 << cmd->vars.log_sz) - 1;
-       cmd->vars.bitmask = (1UL << cmd->vars.max_reg_cmds) - 1;
+       cmd->vars.bitmask = MLX5_CMD_MASK;
 
        sema_init(&cmd->vars.sem, cmd->vars.max_reg_cmds);
        sema_init(&cmd->vars.pages_sem, 1);
index da0a1c65ec4a3b794f96eaaabfc1f8b46573bb66..57b7298a0e793ca14540c1c82b9b0fb7076882a6 100644 (file)
@@ -627,7 +627,7 @@ struct mlx5e_shampo_hd {
        struct mlx5e_dma_info *info;
        struct mlx5e_frag_page *pages;
        u16 curr_page_index;
-       u16 hd_per_wq;
+       u32 hd_per_wq;
        u16 hd_per_wqe;
        unsigned long *bitmap;
        u16 pi;
index d4239e3b3c88efcc2ed0b5f0d84eb82285032b20..11f724ad90dbfb2e7264941c6ee009b80ec1630e 100644 (file)
@@ -23,6 +23,9 @@ struct mlx5e_tir_builder *mlx5e_tir_builder_alloc(bool modify)
        struct mlx5e_tir_builder *builder;
 
        builder = kvzalloc(sizeof(*builder), GFP_KERNEL);
+       if (!builder)
+               return NULL;
+
        builder->modify = modify;
 
        return builder;
index 3d274599015be1eae6c43eee38e5bbb29fb50b88..ca92e518be766973d9d19d29e0c7de902f461be4 100644 (file)
@@ -67,7 +67,6 @@ static void mlx5e_ipsec_handle_sw_limits(struct work_struct *_work)
                return;
 
        spin_lock_bh(&x->lock);
-       xfrm_state_check_expire(x);
        if (x->km.state == XFRM_STATE_EXPIRED) {
                sa_entry->attrs.drop = true;
                spin_unlock_bh(&x->lock);
@@ -75,6 +74,13 @@ static void mlx5e_ipsec_handle_sw_limits(struct work_struct *_work)
                mlx5e_accel_ipsec_fs_modify(sa_entry);
                return;
        }
+
+       if (x->km.state != XFRM_STATE_VALID) {
+               spin_unlock_bh(&x->lock);
+               return;
+       }
+
+       xfrm_state_check_expire(x);
        spin_unlock_bh(&x->lock);
 
        queue_delayed_work(sa_entry->ipsec->wq, &dwork->dwork,
index a5659c0c42361323325b49d0e3b30dc2f5b8c8db..e601324a690a2b4d87d7340e357f5f7e2c64c82d 100644 (file)
@@ -6509,7 +6509,9 @@ static void _mlx5e_remove(struct auxiliary_device *adev)
        mlx5e_dcbnl_delete_app(priv);
        unregister_netdev(priv->netdev);
        _mlx5e_suspend(adev, false);
-       priv->profile->cleanup(priv);
+       /* Avoid cleanup if profile rollback failed. */
+       if (priv->profile)
+               priv->profile->cleanup(priv);
        mlx5e_destroy_netdev(priv);
        mlx5e_devlink_port_unregister(mlx5e_dev);
        mlx5e_destroy_devlink(mlx5e_dev);
index b09e9abd39f37ffa309bd71fb018c6fadaaf48dd..f8c7912abe0e3f5d2c6d7fedc3c79637ac4ac235 100644 (file)
@@ -642,7 +642,6 @@ mlx5e_sq_xmit_mpwqe(struct mlx5e_txqsq *sq, struct sk_buff *skb,
        return;
 
 err_unmap:
-       mlx5e_dma_unmap_wqe_err(sq, 1);
        sq->stats->dropped++;
        dev_kfree_skb_any(skb);
        mlx5e_tx_flush(sq);
index 2505f90c0b39d3a0489ed0ad944645f738b04f54..68cb86b37e561f1058c0de6044d1373b7e506f78 100644 (file)
@@ -1061,6 +1061,12 @@ int mlx5_comp_eqn_get(struct mlx5_core_dev *dev, u16 vecidx, int *eqn)
        struct mlx5_eq_comp *eq;
        int ret = 0;
 
+       if (vecidx >= table->max_comp_eqs) {
+               mlx5_core_dbg(dev, "Requested vector index %u should be less than %u",
+                             vecidx, table->max_comp_eqs);
+               return -EINVAL;
+       }
+
        mutex_lock(&table->comp_lock);
        eq = xa_load(&table->comp_eqs, vecidx);
        if (eq) {
index 17f78091ad30efea30f33d8c6f785e3138531ce5..7aef30dbd82d6c27fe4913792a989507750460af 100644 (file)
@@ -1489,7 +1489,7 @@ int mlx5_eswitch_enable_locked(struct mlx5_eswitch *esw, int num_vfs)
        }
 
        if (err)
-               goto abort;
+               goto err_esw_enable;
 
        esw->fdb_table.flags |= MLX5_ESW_FDB_CREATED;
 
@@ -1503,7 +1503,8 @@ int mlx5_eswitch_enable_locked(struct mlx5_eswitch *esw, int num_vfs)
 
        return 0;
 
-abort:
+err_esw_enable:
+       mlx5_eq_notifier_unregister(esw->dev, &esw->nb);
        mlx5_esw_acls_ns_cleanup(esw);
        return err;
 }
index d0b595ba611014bbfe16712506daf035a012fd7e..432c98f2626db9dcfb875d273eaf35fffdbd8832 100644 (file)
        pci_write_config_dword((dev)->pdev, (dev)->vsc_addr + (offset), (val))
 #define VSC_MAX_RETRIES 2048
 
+/* Reading VSC registers can take relatively long time.
+ * Yield the cpu every 128 registers read.
+ */
+#define VSC_GW_READ_BLOCK_COUNT 128
+
 enum {
        VSC_CTRL_OFFSET = 0x4,
        VSC_COUNTER_OFFSET = 0x8,
@@ -273,6 +278,7 @@ int mlx5_vsc_gw_read_block_fast(struct mlx5_core_dev *dev, u32 *data,
 {
        unsigned int next_read_addr = 0;
        unsigned int read_addr = 0;
+       unsigned int count = 0;
 
        while (read_addr < length) {
                if (mlx5_vsc_gw_read_fast(dev, read_addr, &next_read_addr,
@@ -280,6 +286,10 @@ int mlx5_vsc_gw_read_block_fast(struct mlx5_core_dev *dev, u32 *data,
                        return read_addr;
 
                read_addr = next_read_addr;
+               if (++count == VSC_GW_READ_BLOCK_COUNT) {
+                       cond_resched();
+                       count = 0;
+               }
        }
        return length;
 }
index bd52b05db36704a617446cbe7c29d0e371d620ea..8f3a6f9d703da4aaca8ef2d5b9fbdae26f5a34b2 100644 (file)
@@ -691,7 +691,6 @@ static int hws_bwc_matcher_move(struct mlx5hws_bwc_matcher *bwc_matcher)
 static int
 hws_bwc_matcher_rehash_size(struct mlx5hws_bwc_matcher *bwc_matcher)
 {
-       u32 num_of_rules;
        int ret;
 
        /* If the current matcher size is already at its max size, we can't
@@ -705,8 +704,7 @@ hws_bwc_matcher_rehash_size(struct mlx5hws_bwc_matcher *bwc_matcher)
         * Need to check again if we really need rehash.
         * If the reason for rehash was size, but not any more - skip rehash.
         */
-       num_of_rules = __atomic_load_n(&bwc_matcher->num_of_rules, __ATOMIC_RELAXED);
-       if (!hws_bwc_matcher_rehash_size_needed(bwc_matcher, num_of_rules))
+       if (!hws_bwc_matcher_rehash_size_needed(bwc_matcher, bwc_matcher->num_of_rules))
                return 0;
 
        /* Now we're done all the checking - do the rehash:
index bb563f50ef09a246c1c6e2f80e7cbcd6df4abf2b..601fad5fc54a39fd3540c2e6872c68fcccedbc1d 100644 (file)
@@ -33,7 +33,7 @@ bool mlx5hws_bwc_match_params_is_complex(struct mlx5hws_context *ctx,
                 * and let the usual match creation path handle it,
                 * both for good and bad flows.
                 */
-               if (ret == E2BIG) {
+               if (ret == -E2BIG) {
                        is_complex = true;
                        mlx5hws_dbg(ctx, "Matcher definer layout: need complex matcher\n");
                } else {
index e5a7ce60433401f8d463085001b6d1c44025e6ff..8ab548aa402be2921bb7e099f5003ede81fc9d2e 100644 (file)
@@ -46,6 +46,7 @@ struct mlx5hws_context {
        struct mlx5hws_send_engine *send_queue;
        size_t queues;
        struct mutex *bwc_send_queue_locks; /* protect BWC queues */
+       struct lock_class_key *bwc_lock_class_keys;
        struct list_head tbl_list;
        struct mlx5hws_context_debug_info debug_info;
        struct xarray peer_ctx_xa;
index 3bdb5c90efffa536940bbc66c75c6bba51e2f07d..3f4c58bada3745c1bae45980c38e0567f90bdab7 100644 (file)
@@ -1845,7 +1845,7 @@ hws_definer_find_best_match_fit(struct mlx5hws_context *ctx,
                return 0;
        }
 
-       return E2BIG;
+       return -E2BIG;
 }
 
 static void
@@ -1925,13 +1925,13 @@ mlx5hws_definer_calc_layout(struct mlx5hws_context *ctx,
        ret = hws_definer_conv_match_params_to_hl(ctx, mt, match_hl);
        if (ret) {
                mlx5hws_err(ctx, "Failed to convert items to header layout\n");
-               goto free_fc;
+               goto free_match_hl;
        }
 
        /* Find the match definer layout for header layout match union */
        ret = hws_definer_find_best_match_fit(ctx, match_definer, match_hl);
        if (ret) {
-               if (ret == E2BIG)
+               if (ret == -E2BIG)
                        mlx5hws_dbg(ctx,
                                    "Failed to create match definer from header layout - E2BIG\n");
                else
@@ -1946,7 +1946,7 @@ mlx5hws_definer_calc_layout(struct mlx5hws_context *ctx,
 
 free_fc:
        kfree(mt->fc);
-
+free_match_hl:
        kfree(match_hl);
        return ret;
 }
index 33d2b31e4b4645bbd9c3dd8baa64e0a518f07909..61a1155d4b4fdb26674229a8c045e853718ea262 100644 (file)
@@ -675,7 +675,7 @@ static int hws_matcher_bind_mt(struct mlx5hws_matcher *matcher)
        if (!(matcher->flags & MLX5HWS_MATCHER_FLAGS_COLLISION)) {
                ret = mlx5hws_definer_mt_init(ctx, matcher->mt);
                if (ret) {
-                       if (ret == E2BIG)
+                       if (ret == -E2BIG)
                                mlx5hws_err(ctx, "Failed to set matcher templates with match definers\n");
                        return ret;
                }
index a1adbb48735c10a2a9cf35a893068a348a632bee..6d443e6ee8d9e9d3a2ced7f50743a4fae5e7b13d 100644 (file)
@@ -653,6 +653,12 @@ static int hws_send_ring_create_sq(struct mlx5_core_dev *mdev, u32 pdn,
        return err;
 }
 
+static void hws_send_ring_destroy_sq(struct mlx5_core_dev *mdev,
+                                    struct mlx5hws_send_ring_sq *sq)
+{
+       mlx5_core_destroy_sq(mdev, sq->sqn);
+}
+
 static int hws_send_ring_set_sq_rdy(struct mlx5_core_dev *mdev, u32 sqn)
 {
        void *in, *sqc;
@@ -696,7 +702,7 @@ static int hws_send_ring_create_sq_rdy(struct mlx5_core_dev *mdev, u32 pdn,
 
        err = hws_send_ring_set_sq_rdy(mdev, sq->sqn);
        if (err)
-               hws_send_ring_close_sq(sq);
+               hws_send_ring_destroy_sq(mdev, sq);
 
        return err;
 }
@@ -935,14 +941,18 @@ static void __hws_send_queues_close(struct mlx5hws_context *ctx, u16 queues)
 
 static void hws_send_queues_bwc_locks_destroy(struct mlx5hws_context *ctx)
 {
-       int bwc_queues = ctx->queues - 1;
+       int bwc_queues = mlx5hws_bwc_queues(ctx);
        int i;
 
        if (!mlx5hws_context_bwc_supported(ctx))
                return;
 
-       for (i = 0; i < bwc_queues; i++)
+       for (i = 0; i < bwc_queues; i++) {
                mutex_destroy(&ctx->bwc_send_queue_locks[i]);
+               lockdep_unregister_key(ctx->bwc_lock_class_keys + i);
+       }
+
+       kfree(ctx->bwc_lock_class_keys);
        kfree(ctx->bwc_send_queue_locks);
 }
 
@@ -971,10 +981,22 @@ static int hws_bwc_send_queues_init(struct mlx5hws_context *ctx)
        if (!ctx->bwc_send_queue_locks)
                return -ENOMEM;
 
-       for (i = 0; i < bwc_queues; i++)
+       ctx->bwc_lock_class_keys = kcalloc(bwc_queues,
+                                          sizeof(*ctx->bwc_lock_class_keys),
+                                          GFP_KERNEL);
+       if (!ctx->bwc_lock_class_keys)
+               goto err_lock_class_keys;
+
+       for (i = 0; i < bwc_queues; i++) {
                mutex_init(&ctx->bwc_send_queue_locks[i]);
+               lockdep_register_key(ctx->bwc_lock_class_keys + i);
+       }
 
        return 0;
+
+err_lock_class_keys:
+       kfree(ctx->bwc_send_queue_locks);
+       return -ENOMEM;
 }
 
 int mlx5hws_send_queues_open(struct mlx5hws_context *ctx,
index 060e5b939211489558d5107aee37376985dfb1bf..d6f37456fb317d9cf7fba07bab261baaa09ba49c 100644 (file)
@@ -389,15 +389,27 @@ static void mlxsw_pci_wqe_frag_unmap(struct mlxsw_pci *mlxsw_pci, char *wqe,
        dma_unmap_single(&pdev->dev, mapaddr, frag_len, direction);
 }
 
-static struct sk_buff *mlxsw_pci_rdq_build_skb(struct page *pages[],
+static struct sk_buff *mlxsw_pci_rdq_build_skb(struct mlxsw_pci_queue *q,
+                                              struct page *pages[],
                                               u16 byte_count)
 {
+       struct mlxsw_pci_queue *cq = q->u.rdq.cq;
        unsigned int linear_data_size;
+       struct page_pool *page_pool;
        struct sk_buff *skb;
        int page_index = 0;
        bool linear_only;
        void *data;
 
+       linear_only = byte_count + MLXSW_PCI_RX_BUF_SW_OVERHEAD <= PAGE_SIZE;
+       linear_data_size = linear_only ? byte_count :
+                                        PAGE_SIZE -
+                                        MLXSW_PCI_RX_BUF_SW_OVERHEAD;
+
+       page_pool = cq->u.cq.page_pool;
+       page_pool_dma_sync_for_cpu(page_pool, pages[page_index],
+                                  MLXSW_PCI_SKB_HEADROOM, linear_data_size);
+
        data = page_address(pages[page_index]);
        net_prefetch(data);
 
@@ -405,11 +417,6 @@ static struct sk_buff *mlxsw_pci_rdq_build_skb(struct page *pages[],
        if (unlikely(!skb))
                return ERR_PTR(-ENOMEM);
 
-       linear_only = byte_count + MLXSW_PCI_RX_BUF_SW_OVERHEAD <= PAGE_SIZE;
-       linear_data_size = linear_only ? byte_count :
-                                        PAGE_SIZE -
-                                        MLXSW_PCI_RX_BUF_SW_OVERHEAD;
-
        skb_reserve(skb, MLXSW_PCI_SKB_HEADROOM);
        skb_put(skb, linear_data_size);
 
@@ -425,6 +432,7 @@ static struct sk_buff *mlxsw_pci_rdq_build_skb(struct page *pages[],
 
                page = pages[page_index];
                frag_size = min(byte_count, PAGE_SIZE);
+               page_pool_dma_sync_for_cpu(page_pool, page, 0, frag_size);
                skb_add_rx_frag(skb, skb_shinfo(skb)->nr_frags,
                                page, 0, frag_size, PAGE_SIZE);
                byte_count -= frag_size;
@@ -760,7 +768,7 @@ static void mlxsw_pci_cqe_rdq_handle(struct mlxsw_pci *mlxsw_pci,
        if (err)
                goto out;
 
-       skb = mlxsw_pci_rdq_build_skb(pages, byte_count);
+       skb = mlxsw_pci_rdq_build_skb(q, pages, byte_count);
        if (IS_ERR(skb)) {
                dev_err_ratelimited(&pdev->dev, "Failed to build skb for RDQ\n");
                mlxsw_pci_rdq_pages_recycle(q, pages, num_sg_entries);
@@ -988,12 +996,13 @@ static int mlxsw_pci_cq_page_pool_init(struct mlxsw_pci_queue *q,
        if (cq_type != MLXSW_PCI_CQ_RDQ)
                return 0;
 
-       pp_params.flags = PP_FLAG_DMA_MAP;
+       pp_params.flags = PP_FLAG_DMA_MAP | PP_FLAG_DMA_SYNC_DEV;
        pp_params.pool_size = MLXSW_PCI_WQE_COUNT * mlxsw_pci->num_sg_entries;
        pp_params.nid = dev_to_node(&mlxsw_pci->pdev->dev);
        pp_params.dev = &mlxsw_pci->pdev->dev;
        pp_params.napi = &q->u.cq.napi;
        pp_params.dma_dir = DMA_FROM_DEVICE;
+       pp_params.max_len = PAGE_SIZE;
 
        page_pool = page_pool_create(&pp_params);
        if (IS_ERR(page_pool))
index d761a1235994cce50d15ffaf71e4ab669a9491f1..7ea798a4949e2d3f8506c0c5e7f2a081d472660a 100644 (file)
@@ -481,11 +481,33 @@ mlxsw_sp_ipip_ol_netdev_change_gre6(struct mlxsw_sp *mlxsw_sp,
                                    struct mlxsw_sp_ipip_entry *ipip_entry,
                                    struct netlink_ext_ack *extack)
 {
+       u32 new_kvdl_index, old_kvdl_index = ipip_entry->dip_kvdl_index;
+       struct in6_addr old_addr6 = ipip_entry->parms.daddr.addr6;
        struct mlxsw_sp_ipip_parms new_parms;
+       int err;
 
        new_parms = mlxsw_sp_ipip_netdev_parms_init_gre6(ipip_entry->ol_dev);
-       return mlxsw_sp_ipip_ol_netdev_change_gre(mlxsw_sp, ipip_entry,
-                                                 &new_parms, extack);
+
+       err = mlxsw_sp_ipv6_addr_kvdl_index_get(mlxsw_sp,
+                                               &new_parms.daddr.addr6,
+                                               &new_kvdl_index);
+       if (err)
+               return err;
+       ipip_entry->dip_kvdl_index = new_kvdl_index;
+
+       err = mlxsw_sp_ipip_ol_netdev_change_gre(mlxsw_sp, ipip_entry,
+                                                &new_parms, extack);
+       if (err)
+               goto err_change_gre;
+
+       mlxsw_sp_ipv6_addr_put(mlxsw_sp, &old_addr6);
+
+       return 0;
+
+err_change_gre:
+       ipip_entry->dip_kvdl_index = old_kvdl_index;
+       mlxsw_sp_ipv6_addr_put(mlxsw_sp, &new_parms.daddr.addr6);
+       return err;
 }
 
 static int
index 5b174cb95eb8a360dd20ce70e19e94110860be68..d94081c7658e327919c415a776decd116d96a82e 100644 (file)
@@ -16,6 +16,7 @@
 #include "spectrum.h"
 #include "spectrum_ptp.h"
 #include "core.h"
+#include "txheader.h"
 
 #define MLXSW_SP1_PTP_CLOCK_CYCLES_SHIFT       29
 #define MLXSW_SP1_PTP_CLOCK_FREQ_KHZ           156257 /* 6.4nSec */
@@ -1684,6 +1685,12 @@ int mlxsw_sp_ptp_txhdr_construct(struct mlxsw_core *mlxsw_core,
                                 struct sk_buff *skb,
                                 const struct mlxsw_tx_info *tx_info)
 {
+       if (skb_cow_head(skb, MLXSW_TXHDR_LEN)) {
+               this_cpu_inc(mlxsw_sp_port->pcpu_stats->tx_dropped);
+               dev_kfree_skb_any(skb);
+               return -ENOMEM;
+       }
+
        mlxsw_sp_txhdr_construct(skb, tx_info);
        return 0;
 }
index 800dfb64ec830391e462da153ac938bc2e7bf0cd..7d6d859cef3f9f2646c16d5160ef7636ab695c2f 100644 (file)
@@ -3197,7 +3197,6 @@ mlxsw_sp_nexthop_sh_counter_get(struct mlxsw_sp *mlxsw_sp,
 {
        struct mlxsw_sp_nexthop_group *nh_grp = nh->nhgi->nh_grp;
        struct mlxsw_sp_nexthop_counter *nhct;
-       void *ptr;
        int err;
 
        nhct = xa_load(&nh_grp->nhgi->nexthop_counters, nh->id);
@@ -3210,12 +3209,10 @@ mlxsw_sp_nexthop_sh_counter_get(struct mlxsw_sp *mlxsw_sp,
        if (IS_ERR(nhct))
                return nhct;
 
-       ptr = xa_store(&nh_grp->nhgi->nexthop_counters, nh->id, nhct,
-                      GFP_KERNEL);
-       if (IS_ERR(ptr)) {
-               err = PTR_ERR(ptr);
+       err = xa_err(xa_store(&nh_grp->nhgi->nexthop_counters, nh->id, nhct,
+                             GFP_KERNEL));
+       if (err)
                goto err_store;
-       }
 
        return nhct;
 
index ef05ae8f5039a7bf2df2c9ad6ff3b18df8c90cb6..0072d612215e49856d614a8194f26a3fa5a94a83 100644 (file)
@@ -1,7 +1,7 @@
 // SPDX-License-Identifier: GPL-2.0
 /* Copyright (c) Meta Platforms, Inc. and affiliates. */
 
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include <linux/pci.h>
 #include <linux/types.h>
 #include <net/devlink.h>
index 59159ad6701ad50bb984c1a88d2e33919945ba82..ec228c0613517ec3fe31292be89baabfb64c0cb6 100644 (file)
@@ -6,7 +6,7 @@
 if NET_VENDOR_MICROCHIP
 
 config FDMA
-       bool "FDMA API"
+       bool "FDMA API" if COMPILE_TEST
        help
          Provides the basic FDMA functionality for multiple Microchip
          switchcores.
index dcea6652d56d2b43fcc65a58e47087a59a507542..4a777b449ecd03ac0d7576f8570f1a7794fb3d06 100644 (file)
@@ -401,28 +401,21 @@ static int lan743x_ptpci_settime64(struct ptp_clock_info *ptpci,
        u32 nano_seconds = 0;
        u32 seconds = 0;
 
-       if (ts) {
-               if (ts->tv_sec > 0xFFFFFFFFLL ||
-                   ts->tv_sec < 0) {
-                       netif_warn(adapter, drv, adapter->netdev,
-                                  "ts->tv_sec out of range, %lld\n",
-                                  ts->tv_sec);
-                       return -ERANGE;
-               }
-               if (ts->tv_nsec >= 1000000000L ||
-                   ts->tv_nsec < 0) {
-                       netif_warn(adapter, drv, adapter->netdev,
-                                  "ts->tv_nsec out of range, %ld\n",
-                                  ts->tv_nsec);
-                       return -ERANGE;
-               }
-               seconds = ts->tv_sec;
-               nano_seconds = ts->tv_nsec;
-               lan743x_ptp_clock_set(adapter, seconds, nano_seconds, 0);
-       } else {
-               netif_warn(adapter, drv, adapter->netdev, "ts == NULL\n");
-               return -EINVAL;
+       if (ts->tv_sec > 0xFFFFFFFFLL) {
+               netif_warn(adapter, drv, adapter->netdev,
+                          "ts->tv_sec out of range, %lld\n",
+                          ts->tv_sec);
+               return -ERANGE;
+       }
+       if (ts->tv_nsec < 0) {
+               netif_warn(adapter, drv, adapter->netdev,
+                          "ts->tv_nsec out of range, %ld\n",
+                          ts->tv_nsec);
+               return -ERANGE;
        }
+       seconds = ts->tv_sec;
+       nano_seconds = ts->tv_nsec;
+       lan743x_ptp_clock_set(adapter, seconds, nano_seconds, 0);
 
        return 0;
 }
index 15db423be4aa69ca926f31cb5be2014801b1207e..459a53676ae964af1a76408484b84510da3e2b26 100644 (file)
@@ -31,10 +31,10 @@ static u64 sparx5_mirror_port_get(struct sparx5 *sparx5, u32 idx)
 /* Add port to mirror (only front ports) */
 static void sparx5_mirror_port_add(struct sparx5 *sparx5, u32 idx, u32 portno)
 {
-       u32 val, reg = portno;
+       u64 reg = portno;
+       u32 val;
 
-       reg = portno / BITS_PER_BYTE;
-       val = BIT(portno % BITS_PER_BYTE);
+       val = BIT(do_div(reg, 32));
 
        if (reg == 0)
                return spx5_rmw(val, val, sparx5, ANA_AC_PROBE_PORT_CFG(idx));
@@ -45,10 +45,10 @@ static void sparx5_mirror_port_add(struct sparx5 *sparx5, u32 idx, u32 portno)
 /* Delete port from mirror (only front ports) */
 static void sparx5_mirror_port_del(struct sparx5 *sparx5, u32 idx, u32 portno)
 {
-       u32 val, reg = portno;
+       u64 reg = portno;
+       u32 val;
 
-       reg = portno / BITS_PER_BYTE;
-       val = BIT(portno % BITS_PER_BYTE);
+       val = BIT(do_div(reg, 32));
 
        if (reg == 0)
                return spx5_rmw(0, val, sparx5, ANA_AC_PROBE_PORT_CFG(idx));
index f3f5fb4204689bd3de47d6771a457bccf650829d..70427643f777c098f0284052a8f04ed6e0aa982f 100644 (file)
@@ -45,8 +45,12 @@ void sparx5_ifh_parse(u32 *ifh, struct frame_info *info)
        fwd = (fwd >> 5);
        info->src_port = FIELD_GET(GENMASK(7, 1), fwd);
 
+       /*
+        * Bit 270-271 are occasionally unexpectedly set by the hardware,
+        * clear bits before extracting timestamp
+        */
        info->timestamp =
-               ((u64)xtr_hdr[2] << 24) |
+               ((u64)(xtr_hdr[2] & GENMASK(5, 0)) << 24) |
                ((u64)xtr_hdr[3] << 16) |
                ((u64)xtr_hdr[4] <<  8) |
                ((u64)xtr_hdr[5] <<  0);
index f2a5a36fdacd4384b7f101e92df0074729ec4032..7251121ab196e36e141da426b37591505cf085a9 100644 (file)
@@ -1444,6 +1444,8 @@ static void vcap_api_encode_rule_test(struct kunit *test)
 
        ret = vcap_del_rule(&test_vctrl, &test_netdev, id);
        KUNIT_EXPECT_EQ(test, 0, ret);
+
+       vcap_free_rule(rule);
 }
 
 static void vcap_api_set_rule_counter_test(struct kunit *test)
index cc54faca2283b99950f05de98ee1f78e926dce8e..515069d5637b0d67d22f5844ff6f413f497e4017 100644 (file)
@@ -6,7 +6,7 @@
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/netdevice.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include <linux/ktime.h>
 #include <net/xfrm.h>
 
index 3f10c5365c80ebb2fe079b779fee644a46ed33da..7c2200b49ce42cfd9731ac70aedfa957ecb811a4 100644 (file)
@@ -15,7 +15,7 @@
  * abstraction builds upon this BAR interface.
  */
 
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/kref.h>
index a8286d0032d1e6c6a2b7c417055dcc731006ffee..669f9f8fb5079e21d7d6d5735898040314605f3a 100644 (file)
@@ -9,7 +9,7 @@
  *          Rolf Neugebauer <[email protected]>
  */
 
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include <linux/delay.h>
 #include <linux/device.h>
 #include <linux/ioport.h>
index 508ae6b571ca61631344c9bcc6f36082fc0b811b..addf02c63b1a09516e49d42dc9d4467738c51687 100644 (file)
@@ -9,7 +9,7 @@
  *          Rolf Neugebauer <[email protected]>
  */
 
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include <linux/bitfield.h>
 #include <linux/delay.h>
 #include <linux/kernel.h>
index f05dd34ab89ff2a4f8c80e9db5c35e0f06eefbdf..cfa4db5d3f8572ca73af279aa451df5943d16600 100644 (file)
@@ -15,7 +15,7 @@
  */
 
 #include <asm/byteorder.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include <linux/delay.h>
 #include <linux/log2.h>
 #include <linux/kernel.h>
index df0234a338a8b18c730f3f7835d5b32515f74256..0bd6477292a63c6a373d05b2d85df5bede8a2728 100644 (file)
@@ -7,7 +7,7 @@
  *         Jason McMullan <[email protected]>
  */
 
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include <linux/bitfield.h>
 #include <linux/delay.h>
 #include <linux/firmware.h>
index 2260c2403a83a177df578bfe5bcad47981cc339f..68862ac062d2b8cd47a38834a285e40e18382458 100644 (file)
@@ -10,7 +10,7 @@
  *          Francois H. Theron <[email protected]>
  */
 
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/slab.h>
index 1cc0010871932baa4f9c2d405e03d5105614d4df..a36d422b517339016d5ac81eb10cccda188a306f 100644 (file)
@@ -163,7 +163,7 @@ static int tx_params[MAX_UNITS] = {-1, -1, -1, -1, -1, -1, -1, -1};
 #include <linux/uaccess.h>
 #include <asm/processor.h>     /* Processor type for cache alignment. */
 #include <asm/io.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include <asm/cache.h>
 
 static const char version[] =
index 640ac01689fb5eb71aaa5239ef5db03a547194dd..c0515dc63246b2a3671d5d4ceb086a92f1be4e3d 100644 (file)
@@ -102,7 +102,7 @@ static int gx_fix;
 #include <linux/bitops.h>
 #include <linux/uaccess.h>
 #include <asm/processor.h>             /* Processor type for cache alignment. */
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include <asm/io.h>
 
 /* These identify the driver base version and may not be removed. */
index 305ec19ccef136d27a0c9f4897de8024ac3e595e..713a89bb21e93b926e65b08819b29dc2f3ebdc9c 100644 (file)
@@ -28,7 +28,7 @@
 #include <linux/bitfield.h>
 #include <linux/prefetch.h>
 #include <linux/ipv6.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include <net/ip6_checksum.h>
 #include <net/netdev_queues.h>
 
@@ -4682,7 +4682,9 @@ static irqreturn_t rtl8169_interrupt(int irq, void *dev_instance)
        if ((status & 0xffff) == 0xffff || !(status & tp->irq_mask))
                return IRQ_NONE;
 
-       if (unlikely(status & SYSErr)) {
+       /* At least RTL8168fp may unexpectedly set the SYSErr bit */
+       if (unlikely(status & SYSErr &&
+           tp->mac_version <= RTL_GIGA_MAC_VER_06)) {
                rtl8169_pcierr_interrupt(tp->dev);
                goto out;
        }
index d2a6518532f37a6b3143eb99fea42e0bf568f1fc..907af4651c55346557eca5b3629c9ded4b5f4abc 100644 (file)
@@ -1750,20 +1750,19 @@ static int ravb_get_ts_info(struct net_device *ndev,
        struct ravb_private *priv = netdev_priv(ndev);
        const struct ravb_hw_info *hw_info = priv->info;
 
-       info->so_timestamping =
-               SOF_TIMESTAMPING_TX_SOFTWARE |
-               SOF_TIMESTAMPING_TX_HARDWARE |
-               SOF_TIMESTAMPING_RX_HARDWARE |
-               SOF_TIMESTAMPING_RAW_HARDWARE;
-       info->tx_types = (1 << HWTSTAMP_TX_OFF) | (1 << HWTSTAMP_TX_ON);
-       info->rx_filters =
-               (1 << HWTSTAMP_FILTER_NONE) |
-               (1 << HWTSTAMP_FILTER_PTP_V2_L2_EVENT) |
-               (1 << HWTSTAMP_FILTER_ALL);
-       if (hw_info->gptp || hw_info->ccc_gac)
+       if (hw_info->gptp || hw_info->ccc_gac) {
+               info->so_timestamping =
+                       SOF_TIMESTAMPING_TX_SOFTWARE |
+                       SOF_TIMESTAMPING_TX_HARDWARE |
+                       SOF_TIMESTAMPING_RX_HARDWARE |
+                       SOF_TIMESTAMPING_RAW_HARDWARE;
+               info->tx_types = (1 << HWTSTAMP_TX_OFF) | (1 << HWTSTAMP_TX_ON);
+               info->rx_filters =
+                       (1 << HWTSTAMP_FILTER_NONE) |
+                       (1 << HWTSTAMP_FILTER_PTP_V2_L2_EVENT) |
+                       (1 << HWTSTAMP_FILTER_ALL);
                info->phc_index = ptp_clock_index(priv->ptp.clock);
-       else
-               info->phc_index = 0;
+       }
 
        return 0;
 }
index f9f63c61d79237c0114977869be9586501afa89e..6b3f7fca8d157283192dcb6edc7d0826a5b1539c 100644 (file)
@@ -1057,6 +1057,7 @@ static netdev_tx_t rtsn_start_xmit(struct sk_buff *skb, struct net_device *ndev)
        if (skb->len >= TX_DS) {
                priv->stats.tx_dropped++;
                priv->stats.tx_errors++;
+               dev_kfree_skb_any(skb);
                goto out;
        }
 
index c9e17a8208a90177c45a507ee433a050f606aecd..f1723a6fb082b4c9d7b6f870f815944c7a2c14f9 100644 (file)
@@ -1260,7 +1260,8 @@ static int efx_poll(struct napi_struct *napi, int budget)
 
        spent = efx_process_channel(channel, budget);
 
-       xdp_do_flush();
+       if (budget)
+               xdp_do_flush();
 
        if (spent < budget) {
                if (efx_channel_has_rx_queue(channel) &&
index a7346e965bfe707813af40e35b67d69b64e82e5d..d120b3c83ac07d4313c387722434cd2377d8c992 100644 (file)
@@ -1285,7 +1285,8 @@ static int efx_poll(struct napi_struct *napi, int budget)
 
        spent = efx_process_channel(channel, budget);
 
-       xdp_do_flush();
+       if (budget)
+               xdp_do_flush();
 
        if (spent < budget) {
                if (efx_channel_has_rx_queue(channel) &&
index 15cb96c2506d73aa2f7de1f57f440a8f1cacaffa..f30d4b17c7fbe087567776f1e4f514e47d47cd87 100644 (file)
@@ -18,7 +18,7 @@
 #include <linux/crc32.h>
 #include <linux/slab.h>
 #include <linux/module.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include "smsc9420.h"
 
 #define DRV_NAME               "smsc9420"
index 362f85136c3efe3dbef1037c3d993b3ef8ec5117..6fdd94c8919ec2697a81c6121c72bfe419fefabd 100644 (file)
@@ -127,10 +127,12 @@ static int mgbe_uphy_lane_bringup_serdes_up(struct net_device *ndev, void *mgbe_
        value &= ~XPCS_WRAP_UPHY_RX_CONTROL_AUX_RX_IDDQ;
        writel(value, mgbe->xpcs + XPCS_WRAP_UPHY_RX_CONTROL);
 
+       usleep_range(10, 20);  /* 50ns min delay needed as per HW design */
        value = readl(mgbe->xpcs + XPCS_WRAP_UPHY_RX_CONTROL);
        value &= ~XPCS_WRAP_UPHY_RX_CONTROL_RX_SLEEP;
        writel(value, mgbe->xpcs + XPCS_WRAP_UPHY_RX_CONTROL);
 
+       usleep_range(10, 20);  /* 500ns min delay needed as per HW design */
        value = readl(mgbe->xpcs + XPCS_WRAP_UPHY_RX_CONTROL);
        value |= XPCS_WRAP_UPHY_RX_CONTROL_RX_CAL_EN;
        writel(value, mgbe->xpcs + XPCS_WRAP_UPHY_RX_CONTROL);
@@ -143,22 +145,30 @@ static int mgbe_uphy_lane_bringup_serdes_up(struct net_device *ndev, void *mgbe_
                return err;
        }
 
+       usleep_range(10, 20);  /* 50ns min delay needed as per HW design */
        value = readl(mgbe->xpcs + XPCS_WRAP_UPHY_RX_CONTROL);
        value |= XPCS_WRAP_UPHY_RX_CONTROL_RX_DATA_EN;
        writel(value, mgbe->xpcs + XPCS_WRAP_UPHY_RX_CONTROL);
 
        value = readl(mgbe->xpcs + XPCS_WRAP_UPHY_RX_CONTROL);
-       value |= XPCS_WRAP_UPHY_RX_CONTROL_RX_CDR_RESET;
+       value &= ~XPCS_WRAP_UPHY_RX_CONTROL_RX_PCS_PHY_RDY;
        writel(value, mgbe->xpcs + XPCS_WRAP_UPHY_RX_CONTROL);
 
+       usleep_range(10, 20);  /* 50ns min delay needed as per HW design */
        value = readl(mgbe->xpcs + XPCS_WRAP_UPHY_RX_CONTROL);
-       value &= ~XPCS_WRAP_UPHY_RX_CONTROL_RX_CDR_RESET;
+       value |= XPCS_WRAP_UPHY_RX_CONTROL_RX_CDR_RESET;
        writel(value, mgbe->xpcs + XPCS_WRAP_UPHY_RX_CONTROL);
 
+       usleep_range(10, 20);  /* 50ns min delay needed as per HW design */
        value = readl(mgbe->xpcs + XPCS_WRAP_UPHY_RX_CONTROL);
        value |= XPCS_WRAP_UPHY_RX_CONTROL_RX_PCS_PHY_RDY;
        writel(value, mgbe->xpcs + XPCS_WRAP_UPHY_RX_CONTROL);
 
+       msleep(30);  /* 30ms delay needed as per HW design */
+       value = readl(mgbe->xpcs + XPCS_WRAP_UPHY_RX_CONTROL);
+       value &= ~XPCS_WRAP_UPHY_RX_CONTROL_RX_CDR_RESET;
+       writel(value, mgbe->xpcs + XPCS_WRAP_UPHY_RX_CONTROL);
+
        err = readl_poll_timeout(mgbe->xpcs + XPCS_WRAP_IRQ_STATUS, value,
                                 value & XPCS_WRAP_IRQ_STATUS_PCS_LINK_STS,
                                 500, 500 * 2000);
index a1858f083eef884a4aac484d39903b2e2efe431f..e65a65666cc1dee57cfe71eb5f7e17373ddb3e42 100644 (file)
@@ -14,6 +14,7 @@
 #include <linux/slab.h>
 #include <linux/ethtool.h>
 #include <linux/io.h>
+#include <linux/iopoll.h>
 #include "stmmac.h"
 #include "stmmac_pcs.h"
 #include "dwmac4.h"
@@ -471,7 +472,7 @@ static int dwmac4_write_vlan_filter(struct net_device *dev,
                                    u8 index, u32 data)
 {
        void __iomem *ioaddr = (void __iomem *)dev->base_addr;
-       int i, timeout = 10;
+       int ret;
        u32 val;
 
        if (index >= hw->num_vlan)
@@ -487,16 +488,15 @@ static int dwmac4_write_vlan_filter(struct net_device *dev,
 
        writel(val, ioaddr + GMAC_VLAN_TAG);
 
-       for (i = 0; i < timeout; i++) {
-               val = readl(ioaddr + GMAC_VLAN_TAG);
-               if (!(val & GMAC_VLAN_TAG_CTRL_OB))
-                       return 0;
-               udelay(1);
+       ret = readl_poll_timeout(ioaddr + GMAC_VLAN_TAG, val,
+                                !(val & GMAC_VLAN_TAG_CTRL_OB),
+                                1000, 500000);
+       if (ret) {
+               netdev_err(dev, "Timeout accessing MAC_VLAN_Tag_Filter\n");
+               return -EBUSY;
        }
 
-       netdev_err(dev, "Timeout accessing MAC_VLAN_Tag_Filter\n");
-
-       return -EBUSY;
+       return 0;
 }
 
 static int dwmac4_add_hw_vlan_rx_fltr(struct net_device *dev,
index e0165358c4ac88bb46adf17dcf449b08eafd5f6e..77b35abc6f6fa43a2cd88e020a3d6f6330bc22d8 100644 (file)
@@ -203,8 +203,12 @@ static void _dwmac4_dump_dma_regs(struct stmmac_priv *priv,
                readl(ioaddr + DMA_CHAN_TX_CONTROL(dwmac4_addrs, channel));
        reg_space[DMA_CHAN_RX_CONTROL(default_addrs, channel) / 4] =
                readl(ioaddr + DMA_CHAN_RX_CONTROL(dwmac4_addrs, channel));
+       reg_space[DMA_CHAN_TX_BASE_ADDR_HI(default_addrs, channel) / 4] =
+               readl(ioaddr + DMA_CHAN_TX_BASE_ADDR_HI(dwmac4_addrs, channel));
        reg_space[DMA_CHAN_TX_BASE_ADDR(default_addrs, channel) / 4] =
                readl(ioaddr + DMA_CHAN_TX_BASE_ADDR(dwmac4_addrs, channel));
+       reg_space[DMA_CHAN_RX_BASE_ADDR_HI(default_addrs, channel) / 4] =
+               readl(ioaddr + DMA_CHAN_RX_BASE_ADDR_HI(dwmac4_addrs, channel));
        reg_space[DMA_CHAN_RX_BASE_ADDR(default_addrs, channel) / 4] =
                readl(ioaddr + DMA_CHAN_RX_BASE_ADDR(dwmac4_addrs, channel));
        reg_space[DMA_CHAN_TX_END_ADDR(default_addrs, channel) / 4] =
@@ -225,8 +229,12 @@ static void _dwmac4_dump_dma_regs(struct stmmac_priv *priv,
                readl(ioaddr + DMA_CHAN_CUR_TX_DESC(dwmac4_addrs, channel));
        reg_space[DMA_CHAN_CUR_RX_DESC(default_addrs, channel) / 4] =
                readl(ioaddr + DMA_CHAN_CUR_RX_DESC(dwmac4_addrs, channel));
+       reg_space[DMA_CHAN_CUR_TX_BUF_ADDR_HI(default_addrs, channel) / 4] =
+               readl(ioaddr + DMA_CHAN_CUR_TX_BUF_ADDR_HI(dwmac4_addrs, channel));
        reg_space[DMA_CHAN_CUR_TX_BUF_ADDR(default_addrs, channel) / 4] =
                readl(ioaddr + DMA_CHAN_CUR_TX_BUF_ADDR(dwmac4_addrs, channel));
+       reg_space[DMA_CHAN_CUR_RX_BUF_ADDR_HI(default_addrs, channel) / 4] =
+               readl(ioaddr + DMA_CHAN_CUR_RX_BUF_ADDR_HI(dwmac4_addrs, channel));
        reg_space[DMA_CHAN_CUR_RX_BUF_ADDR(default_addrs, channel) / 4] =
                readl(ioaddr + DMA_CHAN_CUR_RX_BUF_ADDR(dwmac4_addrs, channel));
        reg_space[DMA_CHAN_STATUS(default_addrs, channel) / 4] =
index 17d9120db5fe90e5148026ae8447121420db2e4a..4f980dcd39582399616d49016b7548999b3f9cfd 100644 (file)
@@ -127,7 +127,9 @@ static inline u32 dma_chanx_base_addr(const struct dwmac4_addrs *addrs,
 #define DMA_CHAN_SLOT_CTRL_STATUS(addrs, x)    (dma_chanx_base_addr(addrs, x) + 0x3c)
 #define DMA_CHAN_CUR_TX_DESC(addrs, x) (dma_chanx_base_addr(addrs, x) + 0x44)
 #define DMA_CHAN_CUR_RX_DESC(addrs, x) (dma_chanx_base_addr(addrs, x) + 0x4c)
+#define DMA_CHAN_CUR_TX_BUF_ADDR_HI(addrs, x)  (dma_chanx_base_addr(addrs, x) + 0x50)
 #define DMA_CHAN_CUR_TX_BUF_ADDR(addrs, x)     (dma_chanx_base_addr(addrs, x) + 0x54)
+#define DMA_CHAN_CUR_RX_BUF_ADDR_HI(addrs, x)  (dma_chanx_base_addr(addrs, x) + 0x58)
 #define DMA_CHAN_CUR_RX_BUF_ADDR(addrs, x)     (dma_chanx_base_addr(addrs, x) + 0x5c)
 #define DMA_CHAN_STATUS(addrs, x)      (dma_chanx_base_addr(addrs, x) + 0x60)
 
index e2140482270a880d937e4353b9e8b1a235490d4e..208dbc68aaf9d4a650f167a76d1ef223d5eb6aec 100644 (file)
@@ -2035,7 +2035,7 @@ static int __alloc_dma_rx_desc_resources(struct stmmac_priv *priv,
        rx_q->queue_index = queue;
        rx_q->priv_data = priv;
 
-       pp_params.flags = PP_FLAG_DMA_MAP | (xdp_prog ? PP_FLAG_DMA_SYNC_DEV : 0);
+       pp_params.flags = PP_FLAG_DMA_MAP | PP_FLAG_DMA_SYNC_DEV;
        pp_params.pool_size = dma_conf->dma_rx_size;
        num_pages = DIV_ROUND_UP(dma_conf->dma_buf_sz, PAGE_SIZE);
        pp_params.order = ilog2(num_pages);
@@ -4304,11 +4304,6 @@ static netdev_tx_t stmmac_tso_xmit(struct sk_buff *skb, struct net_device *dev)
        if (dma_mapping_error(priv->device, des))
                goto dma_map_err;
 
-       tx_q->tx_skbuff_dma[first_entry].buf = des;
-       tx_q->tx_skbuff_dma[first_entry].len = skb_headlen(skb);
-       tx_q->tx_skbuff_dma[first_entry].map_as_page = false;
-       tx_q->tx_skbuff_dma[first_entry].buf_type = STMMAC_TXBUF_T_SKB;
-
        if (priv->dma_cap.addr64 <= 32) {
                first->des0 = cpu_to_le32(des);
 
@@ -4327,6 +4322,23 @@ static netdev_tx_t stmmac_tso_xmit(struct sk_buff *skb, struct net_device *dev)
 
        stmmac_tso_allocator(priv, des, tmp_pay_len, (nfrags == 0), queue);
 
+       /* In case two or more DMA transmit descriptors are allocated for this
+        * non-paged SKB data, the DMA buffer address should be saved to
+        * tx_q->tx_skbuff_dma[].buf corresponding to the last descriptor,
+        * and leave the other tx_q->tx_skbuff_dma[].buf as NULL to guarantee
+        * that stmmac_tx_clean() does not unmap the entire DMA buffer too early
+        * since the tail areas of the DMA buffer can be accessed by DMA engine
+        * sooner or later.
+        * By saving the DMA buffer address to tx_q->tx_skbuff_dma[].buf
+        * corresponding to the last descriptor, stmmac_tx_clean() will unmap
+        * this DMA buffer right after the DMA engine completely finishes the
+        * full buffer transmission.
+        */
+       tx_q->tx_skbuff_dma[tx_q->cur_tx].buf = des;
+       tx_q->tx_skbuff_dma[tx_q->cur_tx].len = skb_headlen(skb);
+       tx_q->tx_skbuff_dma[tx_q->cur_tx].map_as_page = false;
+       tx_q->tx_skbuff_dma[tx_q->cur_tx].buf_type = STMMAC_TXBUF_T_SKB;
+
        /* Prepare fragments */
        for (i = 0; i < nfrags; i++) {
                const skb_frag_t *frag = &skb_shinfo(skb)->frags[i];
index cbe99017cbfa479fe8329c2c65394e45539cb709..0520e9f4bea7009c006908f4093ced816db37e01 100644 (file)
@@ -763,7 +763,7 @@ fail_tx:
        k3_udma_glue_disable_rx_chn(rx_chn->rx_chn);
 
 fail_rx:
-       for (i = 0; i < common->rx_ch_num_flows; i--)
+       for (i = 0; i < common->rx_ch_num_flows; i++)
                k3_udma_glue_reset_rx_chn(rx_chn->rx_chn, i, &rx_chn->flows[i],
                                          am65_cpsw_nuss_rx_cleanup, 0);
 
@@ -2744,10 +2744,9 @@ am65_cpsw_nuss_init_port_ndev(struct am65_cpsw_common *common, u32 port_idx)
                return 0;
 
        /* alloc netdev */
-       port->ndev = devm_alloc_etherdev_mqs(common->dev,
-                                            sizeof(struct am65_cpsw_ndev_priv),
-                                            AM65_CPSW_MAX_QUEUES,
-                                            AM65_CPSW_MAX_QUEUES);
+       port->ndev = alloc_etherdev_mqs(sizeof(struct am65_cpsw_ndev_priv),
+                                       AM65_CPSW_MAX_QUEUES,
+                                       AM65_CPSW_MAX_QUEUES);
        if (!port->ndev) {
                dev_err(dev, "error allocating slave net_device %u\n",
                        port->port_id);
@@ -2868,8 +2867,12 @@ static void am65_cpsw_nuss_cleanup_ndev(struct am65_cpsw_common *common)
 
        for (i = 0; i < common->port_num; i++) {
                port = &common->ports[i];
-               if (port->ndev && port->ndev->reg_state == NETREG_REGISTERED)
+               if (!port->ndev)
+                       continue;
+               if (port->ndev->reg_state == NETREG_REGISTERED)
                        unregister_netdev(port->ndev);
+               free_netdev(port->ndev);
+               port->ndev = NULL;
        }
 }
 
@@ -3613,16 +3616,17 @@ static int am65_cpsw_nuss_probe(struct platform_device *pdev)
 
        ret = am65_cpsw_nuss_init_ndevs(common);
        if (ret)
-               goto err_free_phylink;
+               goto err_ndevs_clear;
 
        ret = am65_cpsw_nuss_register_ndevs(common);
        if (ret)
-               goto err_free_phylink;
+               goto err_ndevs_clear;
 
        pm_runtime_put(dev);
        return 0;
 
-err_free_phylink:
+err_ndevs_clear:
+       am65_cpsw_nuss_cleanup_ndev(common);
        am65_cpsw_nuss_phylink_cleanup(common);
        am65_cpts_release(common->cpts);
 err_of_clear:
@@ -3652,13 +3656,13 @@ static void am65_cpsw_nuss_remove(struct platform_device *pdev)
                return;
        }
 
-       am65_cpsw_unregister_devlink(common);
        am65_cpsw_unregister_notifiers(common);
 
        /* must unregister ndevs here because DD release_driver routine calls
         * dma_deconfigure(dev) before devres_release_all(dev)
         */
        am65_cpsw_nuss_cleanup_ndev(common);
+       am65_cpsw_unregister_devlink(common);
        am65_cpsw_nuss_phylink_cleanup(common);
        am65_cpts_release(common->cpts);
        am65_cpsw_disable_serdes_phy(common);
index 0d5d8917c70b56f65ffb28021ac379753e646dc3..8d02d2b214293768cb45f215402bc8bbdcf18939 100644 (file)
@@ -96,6 +96,7 @@ enum {
  * @features: features supported by ALE
  * @tbl_entries: number of ALE entries
  * @reg_fields: pointer to array of register field configuration
+ * @num_fields: number of fields in the reg_fields array
  * @nu_switch_ale: NU Switch ALE
  * @vlan_entry_tbl: ALE vlan entry fields description tbl
  */
@@ -104,6 +105,7 @@ struct cpsw_ale_dev_id {
        u32 features;
        u32 tbl_entries;
        const struct reg_field *reg_fields;
+       int num_fields;
        bool nu_switch_ale;
        const struct ale_entry_fld *vlan_entry_tbl;
 };
@@ -1400,6 +1402,7 @@ static const struct cpsw_ale_dev_id cpsw_ale_id_match[] = {
                .dev_id = "cpsw",
                .tbl_entries = 1024,
                .reg_fields = ale_fields_cpsw,
+               .num_fields = ARRAY_SIZE(ale_fields_cpsw),
                .vlan_entry_tbl = vlan_entry_cpsw,
        },
        {
@@ -1407,12 +1410,14 @@ static const struct cpsw_ale_dev_id cpsw_ale_id_match[] = {
                .dev_id = "66ak2h-xgbe",
                .tbl_entries = 2048,
                .reg_fields = ale_fields_cpsw,
+               .num_fields = ARRAY_SIZE(ale_fields_cpsw),
                .vlan_entry_tbl = vlan_entry_cpsw,
        },
        {
                .dev_id = "66ak2el",
                .features = CPSW_ALE_F_STATUS_REG,
                .reg_fields = ale_fields_cpsw_nu,
+               .num_fields = ARRAY_SIZE(ale_fields_cpsw_nu),
                .nu_switch_ale = true,
                .vlan_entry_tbl = vlan_entry_nu,
        },
@@ -1421,6 +1426,7 @@ static const struct cpsw_ale_dev_id cpsw_ale_id_match[] = {
                .features = CPSW_ALE_F_STATUS_REG,
                .tbl_entries = 64,
                .reg_fields = ale_fields_cpsw_nu,
+               .num_fields = ARRAY_SIZE(ale_fields_cpsw_nu),
                .nu_switch_ale = true,
                .vlan_entry_tbl = vlan_entry_nu,
        },
@@ -1429,6 +1435,7 @@ static const struct cpsw_ale_dev_id cpsw_ale_id_match[] = {
                .features = CPSW_ALE_F_STATUS_REG | CPSW_ALE_F_HW_AUTOAGING,
                .tbl_entries = 64,
                .reg_fields = ale_fields_cpsw_nu,
+               .num_fields = ARRAY_SIZE(ale_fields_cpsw_nu),
                .nu_switch_ale = true,
                .vlan_entry_tbl = vlan_entry_nu,
        },
@@ -1436,12 +1443,14 @@ static const struct cpsw_ale_dev_id cpsw_ale_id_match[] = {
                .dev_id = "j721e-cpswxg",
                .features = CPSW_ALE_F_STATUS_REG | CPSW_ALE_F_HW_AUTOAGING,
                .reg_fields = ale_fields_cpsw_nu,
+               .num_fields = ARRAY_SIZE(ale_fields_cpsw_nu),
                .vlan_entry_tbl = vlan_entry_k3_cpswxg,
        },
        {
                .dev_id = "am64-cpswxg",
                .features = CPSW_ALE_F_STATUS_REG | CPSW_ALE_F_HW_AUTOAGING,
                .reg_fields = ale_fields_cpsw_nu,
+               .num_fields = ARRAY_SIZE(ale_fields_cpsw_nu),
                .vlan_entry_tbl = vlan_entry_k3_cpswxg,
                .tbl_entries = 512,
        },
@@ -1477,7 +1486,7 @@ static int cpsw_ale_regfield_init(struct cpsw_ale *ale)
        struct regmap *regmap = ale->regmap;
        int i;
 
-       for (i = 0; i < ALE_FIELDS_MAX; i++) {
+       for (i = 0; i < ale->params.num_fields; i++) {
                ale->fields[i] = devm_regmap_field_alloc(dev, regmap,
                                                         reg_fields[i]);
                if (IS_ERR(ale->fields[i])) {
@@ -1503,6 +1512,7 @@ struct cpsw_ale *cpsw_ale_create(struct cpsw_ale_params *params)
        params->ale_entries = ale_dev_id->tbl_entries;
        params->nu_switch_ale = ale_dev_id->nu_switch_ale;
        params->reg_fields = ale_dev_id->reg_fields;
+       params->num_fields = ale_dev_id->num_fields;
 
        ale = devm_kzalloc(params->dev, sizeof(*ale), GFP_KERNEL);
        if (!ale)
index 1e4e9a3dd234577fea10cd4750e21bd71cb64a74..87b7d1b3a34a90ec1bf1435ace6fbb565bd2ad81 100644 (file)
@@ -24,6 +24,7 @@ struct cpsw_ale_params {
         */
        bool                    nu_switch_ale;
        const struct reg_field *reg_fields;
+       int                     num_fields;
        const char              *dev_id;
        unsigned long           bus_freq;
 };
index 72ace151d8e9c941b460128a07b0386e8011f636..5d2491c2943a8b2f67c3dfbf6de863b2b28d2855 100644 (file)
@@ -735,6 +735,7 @@ void icssg_vtbl_modify(struct prueth_emac *emac, u8 vid, u8 port_mask,
        u8 fid_c1;
 
        tbl = prueth->vlan_tbl;
+       spin_lock(&prueth->vtbl_lock);
        fid_c1 = tbl[vid].fid_c1;
 
        /* FID_C1: bit0..2 port membership mask,
@@ -750,6 +751,7 @@ void icssg_vtbl_modify(struct prueth_emac *emac, u8 vid, u8 port_mask,
        }
 
        tbl[vid].fid_c1 = fid_c1;
+       spin_unlock(&prueth->vtbl_lock);
 }
 EXPORT_SYMBOL_GPL(icssg_vtbl_modify);
 
index 5fd9902ab181e9db23e928f4da3ea7bdde8dbe7a..5c20ceb164dff2198799582aa2c64ca2328fec3e 100644 (file)
@@ -1442,6 +1442,7 @@ static int prueth_probe(struct platform_device *pdev)
                icss_iep_init_fw(prueth->iep1);
        }
 
+       spin_lock_init(&prueth->vtbl_lock);
        /* setup netdev interfaces */
        if (eth0_node) {
                ret = prueth_netdev_init(prueth, eth0_node);
index bba6da2e6bd8f9dd4dedc19e6f5c6bca6564e8c3..8722bb4a268a1571cda5ac1086359ad816ac69f3 100644 (file)
@@ -296,6 +296,8 @@ struct prueth {
        bool is_switchmode_supported;
        unsigned char switch_id[MAX_PHYS_ITEM_ID_LEN];
        int default_vlan;
+       /** @vtbl_lock: Lock for vtbl in shared memory */
+       spinlock_t vtbl_lock;
 };
 
 struct emac_tx_ts_response {
index fc35fcb22d94fda11c2f3b7675e7368e0c4e4d0e..d940853acc0b637e3126c9a2e1d1a9e2464af011 100644 (file)
@@ -1051,6 +1051,7 @@ axienet_start_xmit(struct sk_buff *skb, struct net_device *ndev)
                if (net_ratelimit())
                        netdev_err(ndev, "TX DMA mapping error\n");
                ndev->stats.tx_dropped++;
+               dev_kfree_skb_any(skb);
                return NETDEV_TX_OK;
        }
        desc_set_phys_addr(lp, phys, cur_p);
@@ -1071,6 +1072,7 @@ axienet_start_xmit(struct sk_buff *skb, struct net_device *ndev)
                        ndev->stats.tx_dropped++;
                        axienet_free_tx_chain(lp, orig_tail_ptr, ii + 1,
                                              true, NULL, 0);
+                       dev_kfree_skb_any(skb);
                        return NETDEV_TX_OK;
                }
                desc_set_phys_addr(lp, phys, cur_p);
index a60bfb1abb7f01e41cfe1986fa764bc8df0525de..70f981887518aaab77c568f4eb381f2bb36429b0 100644 (file)
@@ -1702,20 +1702,24 @@ static int gtp_encap_enable(struct gtp_dev *gtp, struct nlattr *data[])
                return -EINVAL;
 
        if (data[IFLA_GTP_FD0]) {
-               u32 fd0 = nla_get_u32(data[IFLA_GTP_FD0]);
+               int fd0 = nla_get_u32(data[IFLA_GTP_FD0]);
 
-               sk0 = gtp_encap_enable_socket(fd0, UDP_ENCAP_GTP0, gtp);
-               if (IS_ERR(sk0))
-                       return PTR_ERR(sk0);
+               if (fd0 >= 0) {
+                       sk0 = gtp_encap_enable_socket(fd0, UDP_ENCAP_GTP0, gtp);
+                       if (IS_ERR(sk0))
+                               return PTR_ERR(sk0);
+               }
        }
 
        if (data[IFLA_GTP_FD1]) {
-               u32 fd1 = nla_get_u32(data[IFLA_GTP_FD1]);
+               int fd1 = nla_get_u32(data[IFLA_GTP_FD1]);
 
-               sk1u = gtp_encap_enable_socket(fd1, UDP_ENCAP_GTP1U, gtp);
-               if (IS_ERR(sk1u)) {
-                       gtp_encap_disable_sock(sk0);
-                       return PTR_ERR(sk1u);
+               if (fd1 >= 0) {
+                       sk1u = gtp_encap_enable_socket(fd1, UDP_ENCAP_GTP1U, gtp);
+                       if (IS_ERR(sk1u)) {
+                               gtp_encap_disable_sock(sk0);
+                               return PTR_ERR(sk1u);
+                       }
                }
        }
 
index 153b97f8ec0df9d42b4e46d9fdef0eae9eac63b3..23180f7b67b6aa9bc1241f9133bc3a4a28ad149a 100644 (file)
@@ -2798,6 +2798,31 @@ static struct  hv_driver netvsc_drv = {
        },
 };
 
+/* Set VF's namespace same as the synthetic NIC */
+static void netvsc_event_set_vf_ns(struct net_device *ndev)
+{
+       struct net_device_context *ndev_ctx = netdev_priv(ndev);
+       struct net_device *vf_netdev;
+       int ret;
+
+       vf_netdev = rtnl_dereference(ndev_ctx->vf_netdev);
+       if (!vf_netdev)
+               return;
+
+       if (!net_eq(dev_net(ndev), dev_net(vf_netdev))) {
+               ret = dev_change_net_namespace(vf_netdev, dev_net(ndev),
+                                              "eth%d");
+               if (ret)
+                       netdev_err(vf_netdev,
+                                  "Cannot move to same namespace as %s: %d\n",
+                                  ndev->name, ret);
+               else
+                       netdev_info(vf_netdev,
+                                   "Moved VF to namespace with: %s\n",
+                                   ndev->name);
+       }
+}
+
 /*
  * On Hyper-V, every VF interface is matched with a corresponding
  * synthetic interface. The synthetic interface is presented first
@@ -2810,6 +2835,11 @@ static int netvsc_netdev_event(struct notifier_block *this,
        struct net_device *event_dev = netdev_notifier_info_to_dev(ptr);
        int ret = 0;
 
+       if (event_dev->netdev_ops == &device_ops && event == NETDEV_REGISTER) {
+               netvsc_event_set_vf_ns(event_dev);
+               return NOTIFY_DONE;
+       }
+
        ret = check_dev_is_matching_vf(event_dev);
        if (ret != 0)
                return NOTIFY_DONE;
index 95da876c561384bf99e1ae3b9c372b03af440796..1075e24b11defcb2b67bc83035b418ebeb0990d6 100644 (file)
@@ -101,6 +101,7 @@ config IEEE802154_CA8210_DEBUGFS
 
 config IEEE802154_MCR20A
        tristate "MCR20A transceiver driver"
+       select REGMAP_SPI
        depends on IEEE802154_DRIVERS && MAC802154
        depends on SPI
        help
index a94d8dd71aad9aa424430407a7507f128c28b3b8..2b7034193a00b8bf097f20c0b34d19bb67b235a9 100644 (file)
@@ -16,7 +16,7 @@
 #include <linux/skbuff.h>
 #include <linux/ieee802154.h>
 #include <linux/crc-ccitt.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #include <net/mac802154.h>
 #include <net/cfg802154.h>
index 433fb5839203105bd5880e299f3df54d1f084a85..020d392a98b69d3ceeee0ba110b7c10fb1a5690b 100644 (file)
@@ -1302,16 +1302,13 @@ mcr20a_probe(struct spi_device *spi)
                irq_type = IRQF_TRIGGER_FALLING;
 
        ret = devm_request_irq(&spi->dev, spi->irq, mcr20a_irq_isr,
-                              irq_type, dev_name(&spi->dev), lp);
+                              irq_type | IRQF_NO_AUTOEN, dev_name(&spi->dev), lp);
        if (ret) {
                dev_err(&spi->dev, "could not request_irq for mcr20a\n");
                ret = -ENODEV;
                goto free_dev;
        }
 
-       /* disable_irq by default and wait for starting hardware */
-       disable_irq(spi->irq);
-
        ret = ieee802154_register_hw(hw);
        if (ret) {
                dev_crit(&spi->dev, "ieee802154_register_hw failed\n");
index 12d1b205f6d1173cb1d0001d2bfb05a172a65ff1..ee215928257387c89b386ed3c4fcfcf251973dcd 100644 (file)
@@ -154,19 +154,6 @@ static struct macsec_rx_sa *macsec_rxsa_get(struct macsec_rx_sa __rcu *ptr)
        return sa;
 }
 
-static struct macsec_rx_sa *macsec_active_rxsa_get(struct macsec_rx_sc *rx_sc)
-{
-       struct macsec_rx_sa *sa = NULL;
-       int an;
-
-       for (an = 0; an < MACSEC_NUM_AN; an++)  {
-               sa = macsec_rxsa_get(rx_sc->sa[an]);
-               if (sa)
-                       break;
-       }
-       return sa;
-}
-
 static void free_rx_sc_rcu(struct rcu_head *head)
 {
        struct macsec_rx_sc *rx_sc = container_of(head, struct macsec_rx_sc, rcu_head);
@@ -1208,15 +1195,12 @@ static rx_handler_result_t macsec_handle_frame(struct sk_buff **pskb)
                /* If validateFrames is Strict or the C bit in the
                 * SecTAG is set, discard
                 */
-               struct macsec_rx_sa *active_rx_sa = macsec_active_rxsa_get(rx_sc);
                if (hdr->tci_an & MACSEC_TCI_C ||
                    secy->validate_frames == MACSEC_VALIDATE_STRICT) {
                        u64_stats_update_begin(&rxsc_stats->syncp);
                        rxsc_stats->stats.InPktsNotUsingSA++;
                        u64_stats_update_end(&rxsc_stats->syncp);
                        DEV_STATS_INC(secy->netdev, rx_errors);
-                       if (active_rx_sa)
-                               this_cpu_inc(active_rx_sa->stats->InPktsNotUsingSA);
                        goto drop_nosa;
                }
 
@@ -1226,8 +1210,6 @@ static rx_handler_result_t macsec_handle_frame(struct sk_buff **pskb)
                u64_stats_update_begin(&rxsc_stats->syncp);
                rxsc_stats->stats.InPktsUnusedSA++;
                u64_stats_update_end(&rxsc_stats->syncp);
-               if (active_rx_sa)
-                       this_cpu_inc(active_rx_sa->stats->InPktsUnusedSA);
                goto deliver;
        }
 
@@ -3816,8 +3798,7 @@ static void macsec_free_netdev(struct net_device *dev)
 {
        struct macsec_dev *macsec = macsec_priv(dev);
 
-       if (macsec->secy.tx_sc.md_dst)
-               metadata_dst_free(macsec->secy.tx_sc.md_dst);
+       dst_release(&macsec->secy.tx_sc.md_dst->dst);
        free_percpu(macsec->stats);
        free_percpu(macsec->secy.tx_sc.stats);
 
index 4dc057c121f5d0fb9c9c48bf16b6933ae2f7b2ac..e70fb66879941f3937b7ffc5bc1e20a8a435a441 100644 (file)
@@ -588,6 +588,9 @@ static int mctp_i2c_header_create(struct sk_buff *skb, struct net_device *dev,
        if (len > MCTP_I2C_MAXMTU)
                return -EMSGSIZE;
 
+       if (!daddr || !saddr)
+               return -EINVAL;
+
        lldst = *((u8 *)daddr);
        llsrc = *((u8 *)saddr);
 
index 8e989c157caaf5349360655cb707b340dc8bc791..1bc87a0626860fecc0025536a4cb481d03a5fa7e 100644 (file)
@@ -13,7 +13,7 @@
 #include <linux/i3c/device.h>
 #include <linux/i3c/master.h>
 #include <linux/if_arp.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include <net/mctp.h>
 #include <net/mctpdevice.h>
 
index f40eb50bb978d8eed8b3755392c34ffec02f243f..b7bc70586ee0a418dadb2c318a9d1294df21e0bf 100644 (file)
@@ -337,6 +337,7 @@ static const struct of_device_id unimac_mdio_ids[] = {
        { .compatible = "brcm,asp-v2.2-mdio", },
        { .compatible = "brcm,asp-v2.1-mdio", },
        { .compatible = "brcm,asp-v2.0-mdio", },
+       { .compatible = "brcm,bcm6846-mdio", },
        { .compatible = "brcm,genet-mdio-v5", },
        { .compatible = "brcm,genet-mdio-v4", },
        { .compatible = "brcm,genet-mdio-v3", },
index 01cf33fa75036c641f416fcd4ebf735aaf465b75..de20928f740211a55fe288cd83230a026237c8b5 100644 (file)
@@ -1161,8 +1161,14 @@ static void send_ext_msg_udp(struct netconsole_target *nt, const char *msg,
 
                        this_chunk = min(userdata_len - sent_userdata,
                                         MAX_PRINT_CHUNK - preceding_bytes);
-                       if (WARN_ON_ONCE(this_chunk <= 0))
+                       if (WARN_ON_ONCE(this_chunk < 0))
+                               /* this_chunk could be zero if all the previous
+                                * message used all the buffer. This is not a
+                                * problem, userdata will be sent in the next
+                                * iteration
+                                */
                                return;
+
                        memcpy(buf + this_header + this_offset,
                               userdata + sent_userdata,
                               this_chunk);
index 92a7a36b93ac0cc1b02a551b974fb390254ac484..3e0b61202f0c9824952040c8d4c79eb8775954c6 100644 (file)
@@ -836,7 +836,8 @@ static void nsim_dev_trap_report_work(struct work_struct *work)
        nsim_dev = nsim_trap_data->nsim_dev;
 
        if (!devl_trylock(priv_to_devlink(nsim_dev))) {
-               schedule_delayed_work(&nsim_dev->trap_data->trap_report_dw, 1);
+               queue_delayed_work(system_unbound_wq,
+                                  &nsim_dev->trap_data->trap_report_dw, 1);
                return;
        }
 
@@ -848,11 +849,12 @@ static void nsim_dev_trap_report_work(struct work_struct *work)
                        continue;
 
                nsim_dev_trap_report(nsim_dev_port);
+               cond_resched();
        }
        devl_unlock(priv_to_devlink(nsim_dev));
-
-       schedule_delayed_work(&nsim_dev->trap_data->trap_report_dw,
-                             msecs_to_jiffies(NSIM_TRAP_REPORT_INTERVAL_MS));
+       queue_delayed_work(system_unbound_wq,
+                          &nsim_dev->trap_data->trap_report_dw,
+                          msecs_to_jiffies(NSIM_TRAP_REPORT_INTERVAL_MS));
 }
 
 static int nsim_dev_traps_init(struct devlink *devlink)
@@ -907,8 +909,9 @@ static int nsim_dev_traps_init(struct devlink *devlink)
 
        INIT_DELAYED_WORK(&nsim_dev->trap_data->trap_report_dw,
                          nsim_dev_trap_report_work);
-       schedule_delayed_work(&nsim_dev->trap_data->trap_report_dw,
-                             msecs_to_jiffies(NSIM_TRAP_REPORT_INTERVAL_MS));
+       queue_delayed_work(system_unbound_wq,
+                          &nsim_dev->trap_data->trap_report_dw,
+                          msecs_to_jiffies(NSIM_TRAP_REPORT_INTERVAL_MS));
 
        return 0;
 
index 41e80f78b316024f562d6e972ff02e0264bb9d96..16c382c42227e770eb7fdd7c96d98d87aff944b3 100644 (file)
@@ -1377,10 +1377,12 @@ static ssize_t nsim_nexthop_bucket_activity_write(struct file *file,
 
        if (pos != 0)
                return -EINVAL;
-       if (size > sizeof(buf))
+       if (size > sizeof(buf) - 1)
                return -EINVAL;
        if (copy_from_user(buf, user_buf, size))
                return -EFAULT;
+       buf[size] = 0;
+
        if (sscanf(buf, "%u %hu", &nhid, &bucket_index) != 2)
                return -EINVAL;
 
index 19c75886f070eaf2b856b8953b93911e0948e2ba..5f5cd3596cb846309514a1b133e773eae783c84e 100644 (file)
@@ -109,7 +109,7 @@ static void txgbe_pma_config_1g(struct dw_xpcs *xpcs)
        txgbe_write_pma(xpcs, TXGBE_DFE_TAP_CTL0, 0);
        val = txgbe_read_pma(xpcs, TXGBE_RX_GEN_CTL3);
        val = u16_replace_bits(val, 0x4, TXGBE_RX_GEN_CTL3_LOS_TRSHLD0);
-       txgbe_write_pma(xpcs, TXGBE_RX_EQ_ATTN_CTL, val);
+       txgbe_write_pma(xpcs, TXGBE_RX_GEN_CTL3, val);
 
        txgbe_write_pma(xpcs, TXGBE_MPLLA_CTL0, 0x20);
        txgbe_write_pma(xpcs, TXGBE_MPLLA_CTL3, 0x46);
index 3cdc8c6b30b648fe33149438de8b078da4526d85..8d076b9609fdbd04e797684dfb7eada5c7ae41d9 100644 (file)
@@ -15,7 +15,7 @@
 #include <linux/firmware.h>
 #include <linux/property.h>
 #include <linux/wordpart.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #define EN8811H_PHY_ID         0x03a2a411
 
index dac6464b5fe2e36fd8b8b7c6ad3ca976500cff4e..dab3af80593f51ff6dc670dfb54ae358c2458c40 100644 (file)
@@ -6,7 +6,7 @@
 #include <linux/crc-itu-t.h>
 #include <linux/nvmem-consumer.h>
 
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #include "aquantia.h"
 
index 4d156d406bab9aea0d1100b26376a8c904d35317..c33a5ef34ba032a0cc5a73f33334757beaf04d05 100644 (file)
@@ -537,12 +537,6 @@ static int aqcs109_config_init(struct phy_device *phydev)
        if (!ret)
                aqr107_chip_info(phydev);
 
-       /* AQCS109 belongs to a chip family partially supporting 10G and 5G.
-        * PMA speed ability bits are the same for all members of the family,
-        * AQCS109 however supports speeds up to 2.5G only.
-        */
-       phy_set_max_speed(phydev, SPEED_2500);
-
        return aqr107_set_downshift(phydev, MDIO_AN_VEND_PROV_DOWNSHIFT_DFLT);
 }
 
@@ -731,6 +725,31 @@ static int aqr113c_fill_interface_modes(struct phy_device *phydev)
        return aqr107_fill_interface_modes(phydev);
 }
 
+static int aqr115c_get_features(struct phy_device *phydev)
+{
+       unsigned long *supported = phydev->supported;
+
+       /* PHY supports speeds up to 2.5G with autoneg. PMA capabilities
+        * are not useful.
+        */
+       linkmode_or(supported, supported, phy_gbit_features);
+       linkmode_set_bit(ETHTOOL_LINK_MODE_2500baseT_Full_BIT, supported);
+
+       return 0;
+}
+
+static int aqr111_get_features(struct phy_device *phydev)
+{
+       /* PHY supports speeds up to 5G with autoneg. PMA capabilities
+        * are not useful.
+        */
+       aqr115c_get_features(phydev);
+       linkmode_set_bit(ETHTOOL_LINK_MODE_5000baseT_Full_BIT,
+                        phydev->supported);
+
+       return 0;
+}
+
 static int aqr113c_config_init(struct phy_device *phydev)
 {
        int ret;
@@ -767,15 +786,6 @@ static int aqr107_probe(struct phy_device *phydev)
        return aqr_hwmon_probe(phydev);
 }
 
-static int aqr111_config_init(struct phy_device *phydev)
-{
-       /* AQR111 reports supporting speed up to 10G,
-        * however only speeds up to 5G are supported.
-        */
-       phy_set_max_speed(phydev, SPEED_5000);
-
-       return aqr107_config_init(phydev);
-}
 
 static struct phy_driver aqr_driver[] = {
 {
@@ -853,6 +863,7 @@ static struct phy_driver aqr_driver[] = {
        .get_sset_count = aqr107_get_sset_count,
        .get_strings    = aqr107_get_strings,
        .get_stats      = aqr107_get_stats,
+       .get_features   = aqr115c_get_features,
        .link_change_notify = aqr107_link_change_notify,
        .led_brightness_set = aqr_phy_led_brightness_set,
        .led_hw_is_supported = aqr_phy_led_hw_is_supported,
@@ -865,7 +876,7 @@ static struct phy_driver aqr_driver[] = {
        .name           = "Aquantia AQR111",
        .probe          = aqr107_probe,
        .get_rate_matching = aqr107_get_rate_matching,
-       .config_init    = aqr111_config_init,
+       .config_init    = aqr107_config_init,
        .config_aneg    = aqr_config_aneg,
        .config_intr    = aqr_config_intr,
        .handle_interrupt = aqr_handle_interrupt,
@@ -877,6 +888,7 @@ static struct phy_driver aqr_driver[] = {
        .get_sset_count = aqr107_get_sset_count,
        .get_strings    = aqr107_get_strings,
        .get_stats      = aqr107_get_stats,
+       .get_features   = aqr111_get_features,
        .link_change_notify = aqr107_link_change_notify,
        .led_brightness_set = aqr_phy_led_brightness_set,
        .led_hw_is_supported = aqr_phy_led_hw_is_supported,
@@ -889,7 +901,7 @@ static struct phy_driver aqr_driver[] = {
        .name           = "Aquantia AQR111B0",
        .probe          = aqr107_probe,
        .get_rate_matching = aqr107_get_rate_matching,
-       .config_init    = aqr111_config_init,
+       .config_init    = aqr107_config_init,
        .config_aneg    = aqr_config_aneg,
        .config_intr    = aqr_config_intr,
        .handle_interrupt = aqr_handle_interrupt,
@@ -901,6 +913,7 @@ static struct phy_driver aqr_driver[] = {
        .get_sset_count = aqr107_get_sset_count,
        .get_strings    = aqr107_get_strings,
        .get_stats      = aqr107_get_stats,
+       .get_features   = aqr111_get_features,
        .link_change_notify = aqr107_link_change_notify,
        .led_brightness_set = aqr_phy_led_brightness_set,
        .led_hw_is_supported = aqr_phy_led_hw_is_supported,
@@ -1010,7 +1023,7 @@ static struct phy_driver aqr_driver[] = {
        .name           = "Aquantia AQR114C",
        .probe          = aqr107_probe,
        .get_rate_matching = aqr107_get_rate_matching,
-       .config_init    = aqr111_config_init,
+       .config_init    = aqr107_config_init,
        .config_aneg    = aqr_config_aneg,
        .config_intr    = aqr_config_intr,
        .handle_interrupt = aqr_handle_interrupt,
@@ -1022,6 +1035,7 @@ static struct phy_driver aqr_driver[] = {
        .get_sset_count = aqr107_get_sset_count,
        .get_strings    = aqr107_get_strings,
        .get_stats      = aqr107_get_stats,
+       .get_features   = aqr111_get_features,
        .link_change_notify = aqr107_link_change_notify,
        .led_brightness_set = aqr_phy_led_brightness_set,
        .led_hw_is_supported = aqr_phy_led_hw_is_supported,
@@ -1046,6 +1060,7 @@ static struct phy_driver aqr_driver[] = {
        .get_sset_count = aqr107_get_sset_count,
        .get_strings    = aqr107_get_strings,
        .get_stats      = aqr107_get_stats,
+       .get_features   = aqr115c_get_features,
        .link_change_notify = aqr107_link_change_notify,
        .led_brightness_set = aqr_phy_led_brightness_set,
        .led_hw_is_supported = aqr_phy_led_hw_is_supported,
index 874a1b64b115f5f3124e9a097c06852d7cf06b44..208e8f561e0696e64bd5e842b66d88c65d70bfc0 100644 (file)
@@ -4,7 +4,7 @@
  * Copyright (C) 2022 Jonathan Lemon <[email protected]>
  */
 
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include <linux/mii.h>
 #include <linux/phy.h>
 #include <linux/ptp_classify.h>
index f1d47c2640585b663fc12ec8e5658a2d96d450c7..97da3aee49422c85c9a70c0aa2b1c26d4088080a 100644 (file)
@@ -132,7 +132,7 @@ static int bcm84881_aneg_done(struct phy_device *phydev)
 
        bmsr = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_AN_C22 + MII_BMSR);
        if (bmsr < 0)
-               return val;
+               return bmsr;
 
        return !!(val & MDIO_AN_STAT1_COMPLETE) &&
               !!(bmsr & BMSR_ANEGCOMPLETE);
@@ -158,7 +158,7 @@ static int bcm84881_read_status(struct phy_device *phydev)
 
        bmsr = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_AN_C22 + MII_BMSR);
        if (bmsr < 0)
-               return val;
+               return bmsr;
 
        phydev->autoneg_complete = !!(val & MDIO_AN_STAT1_COMPLETE) &&
                                   !!(bmsr & BMSR_ANEGCOMPLETE);
index fc247f479257ae6655bb177489eb413ba3de3eb0..3ab64e04a01c9cbcb4109f5fb358270c525fb592 100644 (file)
@@ -45,8 +45,8 @@
 /* Control Register 2 bits */
 #define DP83822_FX_ENABLE      BIT(14)
 
-#define DP83822_HW_RESET       BIT(15)
-#define DP83822_SW_RESET       BIT(14)
+#define DP83822_SW_RESET       BIT(15)
+#define DP83822_DIG_RESTART    BIT(14)
 
 /* PHY STS bits */
 #define DP83822_PHYSTS_DUPLEX                  BIT(2)
index d7aaefb5226b62ad5de3c3783c189b8f45b1a7c2..5f056d7db83eed23f1cab42365fdc566a0d8e47f 100644 (file)
@@ -645,7 +645,6 @@ static int dp83869_configure_fiber(struct phy_device *phydev,
                     phydev->supported);
 
        linkmode_set_bit(ETHTOOL_LINK_MODE_FIBRE_BIT, phydev->supported);
-       linkmode_set_bit(ADVERTISED_FIBRE, phydev->advertising);
 
        if (dp83869->mode == DP83869_RGMII_1000_BASE) {
                linkmode_set_bit(ETHTOOL_LINK_MODE_1000baseX_Full_BIT,
index c1ddae36a2ae6161ff3b1536a103bcfabfcaf51f..738a8822fcf014ff456ebbb7a0d57595a94ef5c6 100644 (file)
@@ -15,7 +15,7 @@
 #include <linux/ptp_classify.h>
 #include <linux/ptp_clock_kernel.h>
 #include <linux/udp.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #include "mscc.h"
 #include "mscc_ptp.h"
index 560e338b307a40988e2b35962471152690fbaf1b..499797646580e3a07c7bdc58fd5c46264f915525 100644 (file)
@@ -3326,10 +3326,11 @@ static __maybe_unused int phy_led_hw_is_supported(struct led_classdev *led_cdev,
 
 static void phy_leds_unregister(struct phy_device *phydev)
 {
-       struct phy_led *phyled;
+       struct phy_led *phyled, *tmp;
 
-       list_for_each_entry(phyled, &phydev->leds, list) {
+       list_for_each_entry_safe(phyled, tmp, &phydev->leds, list) {
                led_classdev_unregister(&phyled->led_cdev);
+               list_del(&phyled->list);
        }
 }
 
index 28d8981f410bb5bbda804761430531edd237d0c7..1ab065798175b4f54c5f2fd6c871ba2942c48bf1 100644 (file)
@@ -15,7 +15,7 @@ use kernel::firmware::Firmware;
 use kernel::net::phy::{
     self,
     reg::{Mmd, C45},
-    DeviceId, Driver,
+    Driver,
 };
 use kernel::prelude::*;
 use kernel::sizes::{SZ_16K, SZ_8K};
@@ -23,7 +23,7 @@ use kernel::sizes::{SZ_16K, SZ_8K};
 kernel::module_phy_driver! {
     drivers: [PhyQT2025],
     device_table: [
-        DeviceId::new_with_driver::<PhyQT2025>(),
+        phy::DeviceId::new_with_driver::<PhyQT2025>(),
     ],
     name: "qt2025_phy",
     author: "FUJITA Tomonori <[email protected]>",
index 25e5bfbb6f89b8176b0a38c30562462c18cc3f2a..166f6a7283731e2d3536214b7cda481d7cc7b9ac 100644 (file)
@@ -527,6 +527,9 @@ static int rtl8211f_led_hw_control_get(struct phy_device *phydev, u8 index,
 {
        int val;
 
+       if (index >= RTL8211F_LED_COUNT)
+               return -EINVAL;
+
        val = phy_read_paged(phydev, 0xd04, RTL8211F_LEDCR);
        if (val < 0)
                return val;
@@ -1078,6 +1081,16 @@ static int rtl8221b_vn_cg_c45_match_phy_device(struct phy_device *phydev)
        return rtlgen_is_c45_match(phydev, RTL_8221B_VN_CG, true);
 }
 
+static int rtl8251b_c22_match_phy_device(struct phy_device *phydev)
+{
+       return rtlgen_is_c45_match(phydev, RTL_8251B, false);
+}
+
+static int rtl8251b_c45_match_phy_device(struct phy_device *phydev)
+{
+       return rtlgen_is_c45_match(phydev, RTL_8251B, true);
+}
+
 static int rtlgen_resume(struct phy_device *phydev)
 {
        int ret = genphy_resume(phydev);
@@ -1415,7 +1428,7 @@ static struct phy_driver realtek_drvs[] = {
                .suspend        = genphy_c45_pma_suspend,
                .resume         = rtlgen_c45_resume,
        }, {
-               PHY_ID_MATCH_EXACT(0x001cc862),
+               .match_phy_device = rtl8251b_c45_match_phy_device,
                .name           = "RTL8251B 5Gbps PHY",
                .get_features   = rtl822x_get_features,
                .config_aneg    = rtl822x_config_aneg,
@@ -1424,6 +1437,18 @@ static struct phy_driver realtek_drvs[] = {
                .resume         = rtlgen_resume,
                .read_page      = rtl821x_read_page,
                .write_page     = rtl821x_write_page,
+       }, {
+               .match_phy_device = rtl8251b_c22_match_phy_device,
+               .name           = "RTL8126A-internal 5Gbps PHY",
+               .get_features   = rtl822x_get_features,
+               .config_aneg    = rtl822x_config_aneg,
+               .read_status    = rtl822x_read_status,
+               .suspend        = genphy_suspend,
+               .resume         = rtlgen_resume,
+               .read_page      = rtl821x_read_page,
+               .write_page     = rtl821x_write_page,
+               .read_mmd       = rtl822x_read_mmd,
+               .write_mmd      = rtl822x_write_mmd,
        }, {
                PHY_ID_MATCH_EXACT(0x001ccad0),
                .name           = "RTL8224 2.5Gbps PHY",
index e39bfaefe8c50ba72238d04f08deaa46ca650c70..d81163bc910a3bcaa770a10c0e2d7d9b334a381b 100644 (file)
@@ -815,7 +815,7 @@ plip_send_packet(struct net_device *dev, struct net_local *nl,
                                return HS_TIMEOUT;
                        }
                }
-               break;
+               fallthrough;
 
        case PLIP_PK_LENGTH_LSB:
                if (plip_send(nibble_timeout, dev,
index c33c3db3cc0896d9b033aa2b188fbf46be8afd68..c97406c6004d421623c1a3b0b8e30e9237c1dfeb 100644 (file)
@@ -29,7 +29,7 @@
 #include <linux/interrupt.h>
 #include <linux/jiffies.h>
 #include <linux/slab.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include <linux/uaccess.h>
 #include <asm/string.h>
 
@@ -542,7 +542,7 @@ ppp_async_encode(struct asyncppp *ap)
         * and 7 (code-reject) must be sent as though no options
         * had been negotiated.
         */
-       islcp = proto == PPP_LCP && 1 <= data[2] && data[2] <= 7;
+       islcp = proto == PPP_LCP && count >= 3 && 1 <= data[2] && data[2] <= 7;
 
        if (i == 0) {
                if (islcp)
index 4d2ff63f2ee2f6bb02a07419513549890956d32e..d93aeacc0dba9a4a5cb79c24d625de9527d67f9b 100644 (file)
@@ -16,7 +16,7 @@
 #include <linux/ppp-comp.h>
 
 #include <linux/zlib.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 /*
  * State for a Deflate (de)compressor.
index 4b2971e2bf484a13b5e94ac3b9862224adac4c41..4583e15ad03a0b0ae219d9d07a4cdb5462e28748 100644 (file)
@@ -44,7 +44,7 @@
 #include <linux/mutex.h>
 #include <linux/slab.h>
 #include <linux/file.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include <net/slhc_vj.h>
 #include <linux/atomic.h>
 #include <linux/refcount.h>
@@ -2269,7 +2269,7 @@ static bool ppp_channel_bridge_input(struct channel *pch, struct sk_buff *skb)
        if (!pchb)
                goto out_rcu;
 
-       spin_lock(&pchb->downl);
+       spin_lock_bh(&pchb->downl);
        if (!pchb->chan) {
                /* channel got unregistered */
                kfree_skb(skb);
@@ -2281,7 +2281,7 @@ static bool ppp_channel_bridge_input(struct channel *pch, struct sk_buff *skb)
                kfree_skb(skb);
 
 outl:
-       spin_unlock(&pchb->downl);
+       spin_unlock_bh(&pchb->downl);
 out_rcu:
        rcu_read_unlock();
 
index 208f6e24f37c49df0b29f271e495631cbb33ab15..bcc1eaedf58fb54a2eb495f2aeb51563aa9475aa 100644 (file)
@@ -56,7 +56,7 @@
 #include <linux/ppp_defs.h>
 #include <linux/ppp-comp.h>
 #include <linux/scatterlist.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #include "ppp_mppe.h"
 
index 45bf59ac8f5711867ed1ba433d3f5e7800b769e4..644e99fc3623f510343b464a7db7de988cc67925 100644 (file)
@@ -43,7 +43,7 @@
 #include <linux/interrupt.h>
 #include <linux/slab.h>
 #include <linux/refcount.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include <linux/uaccess.h>
 
 #define PPP_VERSION    "2.4.2"
index 4f032b16a8a0a6ce33911179e60764136c1b0cef..2906ce173f66cdea5953888c5f2594ab67ed2fe9 100644 (file)
@@ -113,7 +113,7 @@ static void pse_release_pis(struct pse_controller_dev *pcdev)
 {
        int i;
 
-       for (i = 0; i <= pcdev->nr_lines; i++) {
+       for (i = 0; i < pcdev->nr_lines; i++) {
                of_node_put(pcdev->pi[i].pairset[0].np);
                of_node_put(pcdev->pi[i].pairset[1].np);
                of_node_put(pcdev->pi[i].np);
@@ -647,7 +647,7 @@ static int of_pse_match_pi(struct pse_controller_dev *pcdev,
 {
        int i;
 
-       for (i = 0; i <= pcdev->nr_lines; i++) {
+       for (i = 0; i < pcdev->nr_lines; i++) {
                if (pcdev->pi[i].np == np)
                        return i;
        }
@@ -785,6 +785,17 @@ static int pse_ethtool_c33_set_config(struct pse_control *psec,
         */
        switch (config->c33_admin_control) {
        case ETHTOOL_C33_PSE_ADMIN_STATE_ENABLED:
+               /* We could have mismatch between admin_state_enabled and
+                * state reported by regulator_is_enabled. This can occur when
+                * the PI is forcibly turn off by the controller. Call
+                * regulator_disable on that case to fix the counters state.
+                */
+               if (psec->pcdev->pi[psec->id].admin_state_enabled &&
+                   !regulator_is_enabled(psec->ps)) {
+                       err = regulator_disable(psec->ps);
+                       if (err)
+                               break;
+               }
                if (!psec->pcdev->pi[psec->id].admin_state_enabled)
                        err = regulator_enable(psec->ps);
                break;
index 18df7ca6619814681adcb879ebb790e5cbaea959..ee9fd3a94b96fe11c02eb5da56deb876f6ac5a81 100644 (file)
@@ -77,7 +77,7 @@
 #include <linux/timer.h>
 #include <linux/uaccess.h>
 #include <net/checksum.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 static unsigned char *encode(unsigned char *cp, unsigned short n);
 static long decode(unsigned char **cpp);
@@ -643,46 +643,57 @@ bad:
 int
 slhc_remember(struct slcompress *comp, unsigned char *icp, int isize)
 {
-       struct cstate *cs;
-       unsigned ihl;
-
+       const struct tcphdr *th;
        unsigned char index;
+       struct iphdr *iph;
+       struct cstate *cs;
+       unsigned int ihl;
 
-       if(isize < 20) {
-               /* The packet is shorter than a legal IP header */
+       /* The packet is shorter than a legal IP header.
+        * Also make sure isize is positive.
+        */
+       if (isize < (int)sizeof(struct iphdr)) {
+runt:
                comp->sls_i_runt++;
-               return slhc_toss( comp );
+               return slhc_toss(comp);
        }
+       iph = (struct iphdr *)icp;
        /* Peek at the IP header's IHL field to find its length */
-       ihl = icp[0] & 0xf;
-       if(ihl < 20 / 4){
-               /* The IP header length field is too small */
-               comp->sls_i_runt++;
-               return slhc_toss( comp );
-       }
-       index = icp[9];
-       icp[9] = IPPROTO_TCP;
+       ihl = iph->ihl;
+       /* The IP header length field is too small,
+        * or packet is shorter than the IP header followed
+        * by minimal tcp header.
+        */
+       if (ihl < 5 || isize < ihl * 4 + sizeof(struct tcphdr))
+               goto runt;
+
+       index = iph->protocol;
+       iph->protocol = IPPROTO_TCP;
 
        if (ip_fast_csum(icp, ihl)) {
                /* Bad IP header checksum; discard */
                comp->sls_i_badcheck++;
-               return slhc_toss( comp );
+               return slhc_toss(comp);
        }
-       if(index > comp->rslot_limit) {
+       if (index > comp->rslot_limit) {
                comp->sls_i_error++;
                return slhc_toss(comp);
        }
-
+       th = (struct tcphdr *)(icp + ihl * 4);
+       if (th->doff < sizeof(struct tcphdr) / 4)
+               goto runt;
+       if (isize < ihl * 4 + th->doff * 4)
+               goto runt;
        /* Update local state */
        cs = &comp->rstate[comp->recv_current = index];
        comp->flags &=~ SLF_TOSS;
-       memcpy(&cs->cs_ip,icp,20);
-       memcpy(&cs->cs_tcp,icp + ihl*4,20);
+       memcpy(&cs->cs_ip, iph, sizeof(*iph));
+       memcpy(&cs->cs_tcp, th, sizeof(*th));
        if (ihl > 5)
-         memcpy(cs->cs_ipopt, icp + sizeof(struct iphdr), (ihl - 5) * 4);
-       if (cs->cs_tcp.doff > 5)
-         memcpy(cs->cs_tcpopt, icp + ihl*4 + sizeof(struct tcphdr), (cs->cs_tcp.doff - 5) * 4);
-       cs->cs_hsize = ihl*2 + cs->cs_tcp.doff*2;
+         memcpy(cs->cs_ipopt, &iph[1], (ihl - 5) * 4);
+       if (th->doff > 5)
+         memcpy(cs->cs_tcpopt, &th[1], (th->doff - 5) * 4);
+       cs->cs_hsize = ihl*2 + th->doff*2;
        cs->initialized = true;
        /* Put headers back on packet
         * Neither header checksum is recalculated
index b0c0c9dd6a028d6f3e4bf3a8e17f0b5ff8e3171c..5d4a1fd2b5244c4f72f68077549d5bb8b81448e2 100644 (file)
@@ -17,7 +17,7 @@
 #include <linux/usb/usbnet.h>
 #include <linux/slab.h>
 
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 
 /*
index 4823dbdf54656f08c6c590ee6641a932d43ef0c2..0c011d8f5d4db2b4752b85d8a4b12cb30fa529ee 100644 (file)
@@ -1076,6 +1076,7 @@ static const struct usb_device_id products[] = {
                USB_DEVICE_AND_INTERFACE_INFO(0x03f0, 0x581d, USB_CLASS_VENDOR_SPEC, 1, 7),
                .driver_info = (unsigned long)&qmi_wwan_info,
        },
+       {QMI_MATCH_FF_FF_FF(0x2c7c, 0x0122)},   /* Quectel RG650V */
        {QMI_MATCH_FF_FF_FF(0x2c7c, 0x0125)},   /* Quectel EC25, EC20 R2.0  Mini PCIe */
        {QMI_MATCH_FF_FF_FF(0x2c7c, 0x0306)},   /* Quectel EP06/EG06/EM06 */
        {QMI_MATCH_FF_FF_FF(0x2c7c, 0x0512)},   /* Quectel EG12/EM12 */
@@ -1426,6 +1427,7 @@ static const struct usb_device_id products[] = {
        {QMI_FIXED_INTF(0x2c7c, 0x0296, 4)},    /* Quectel BG96 */
        {QMI_QUIRK_SET_DTR(0x2c7c, 0x030e, 4)}, /* Quectel EM05GV2 */
        {QMI_QUIRK_SET_DTR(0x2cb7, 0x0104, 4)}, /* Fibocom NL678 series */
+       {QMI_QUIRK_SET_DTR(0x2cb7, 0x0112, 0)}, /* Fibocom FG132 */
        {QMI_FIXED_INTF(0x0489, 0xe0b4, 0)},    /* Foxconn T77W968 LTE */
        {QMI_FIXED_INTF(0x0489, 0xe0b5, 0)},    /* Foxconn T77W968 LTE with eSIM support*/
        {QMI_FIXED_INTF(0x2692, 0x9025, 4)},    /* Cellient MPL200 (rebranded Qualcomm 05c6:9025) */
index a5612c799f5ef79c8cc3485c14c4455e1b0bccca..468c739740463d73609aa2a48ad76adcd9101d06 100644 (file)
@@ -10069,6 +10069,7 @@ static const struct usb_device_id rtl8152_table[] = {
        { USB_DEVICE(VENDOR_ID_LENOVO,  0x3062) },
        { USB_DEVICE(VENDOR_ID_LENOVO,  0x3069) },
        { USB_DEVICE(VENDOR_ID_LENOVO,  0x3082) },
+       { USB_DEVICE(VENDOR_ID_LENOVO,  0x3098) },
        { USB_DEVICE(VENDOR_ID_LENOVO,  0x7205) },
        { USB_DEVICE(VENDOR_ID_LENOVO,  0x720c) },
        { USB_DEVICE(VENDOR_ID_LENOVO,  0x7214) },
index 673d3aa8379267832749fca8450f443a601ce4fc..3d239b8d1a1bcb2340692b4884cf3d66e62defc2 100644 (file)
@@ -30,7 +30,7 @@ static const char driver_name[] = "sierra_net";
 #include <linux/usb/cdc.h>
 #include <net/ip.h>
 #include <net/udp.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include <linux/usb/usbnet.h>
 
 #define SWI_USB_REQUEST_GET_FW_ATTR    0x06
index 2506aa8c603ec0f965bb8ebe5439e7596a47e564..44179f4e807fc350f3d5710f0bc5f42e6414fd6e 100644 (file)
@@ -1767,7 +1767,8 @@ usbnet_probe (struct usb_interface *udev, const struct usb_device_id *prod)
                // can rename the link if it knows better.
                if ((dev->driver_info->flags & FLAG_ETHER) != 0 &&
                    ((dev->driver_info->flags & FLAG_POINTTOPOINT) == 0 ||
-                    (net->dev_addr [0] & 0x02) == 0))
+                    /* somebody touched it*/
+                    !is_zero_ether_addr(net->dev_addr)))
                        strscpy(net->name, "eth%d", sizeof(net->name));
                /* WLAN devices should always be named "wlan%d" */
                if ((dev->driver_info->flags & FLAG_WLAN) != 0)
@@ -1870,6 +1871,7 @@ out1:
         * may trigger an error resubmitting itself and, worse,
         * schedule a timer. So we kill it all just in case.
         */
+       usbnet_mark_going_away(dev);
        cancel_work_sync(&dev->kevent);
        del_timer_sync(&dev->delay);
        free_netdev(net);
index f8131f92a3928896497ff299526e958415a82123..792e9eadbfc3dce4bc146b7b799d602dd32f7f82 100644 (file)
@@ -4155,7 +4155,7 @@ struct virtnet_stats_ctx {
        u32 desc_num[3];
 
        /* The actual supported stat types. */
-       u32 bitmap[3];
+       u64 bitmap[3];
 
        /* Used to calculate the reply buffer size. */
        u32 size[3];
index a6c787454a1aebcad356fe44f61e16a5b5a6b8eb..1341374a4588a0f9a6c5c1ebb8951b5531c473c3 100644 (file)
@@ -148,7 +148,7 @@ vmxnet3_xdp_xmit_frame(struct vmxnet3_adapter *adapter,
        } else { /* XDP buffer from page pool */
                page = virt_to_page(xdpf->data);
                tbi->dma_addr = page_pool_get_dma_addr(page) +
-                               VMXNET3_XDP_HEADROOM;
+                               (xdpf->data - (void *)xdpf);
                dma_sync_single_for_device(&adapter->pdev->dev,
                                           tbi->dma_addr, buf_size,
                                           DMA_TO_DEVICE);
index 4d8ccaf9a2b4d3f9bf677c00608ee5c6f18d78de..4087f72f0d2be866dbc93adc257a931e9a10477c 100644 (file)
@@ -608,7 +608,9 @@ static void vrf_finish_direct(struct sk_buff *skb)
                eth_zero_addr(eth->h_dest);
                eth->h_proto = skb->protocol;
 
+               rcu_read_lock_bh();
                dev_queue_xmit_nit(skb, vrf_dev);
+               rcu_read_unlock_bh();
 
                skb_pull(skb, ETH_HLEN);
        }
index 53dcb9fffc04fe8109a032c53dff95674f6dc635..6e9a3795846aa3080b6815c2c5b36787226ee336 100644 (file)
@@ -4913,9 +4913,13 @@ static int __init vxlan_init_module(void)
        if (rc)
                goto out4;
 
-       vxlan_vnifilter_init();
+       rc = vxlan_vnifilter_init();
+       if (rc)
+               goto out5;
 
        return 0;
+out5:
+       rtnl_link_unregister(&vxlan_link_ops);
 out4:
        unregister_switchdev_notifier(&vxlan_switchdev_notifier_block);
 out3:
index b35d96b7884378db714aba64d444e42eb875d25a..76a351a997d510f18de802dbf6fe8968485dbd25 100644 (file)
@@ -202,7 +202,7 @@ int vxlan_vni_in_use(struct net *src_net, struct vxlan_dev *vxlan,
 int vxlan_vnigroup_init(struct vxlan_dev *vxlan);
 void vxlan_vnigroup_uninit(struct vxlan_dev *vxlan);
 
-void vxlan_vnifilter_init(void);
+int vxlan_vnifilter_init(void);
 void vxlan_vnifilter_uninit(void);
 void vxlan_vnifilter_count(struct vxlan_dev *vxlan, __be32 vni,
                           struct vxlan_vni_node *vninode,
index 9c59d0bf8c3de09ba87ecdeac93ea7b615a62a31..d2023e7131bd4f76a9a3ae521fdbbc04e1739525 100644 (file)
@@ -992,19 +992,18 @@ static int vxlan_vnifilter_process(struct sk_buff *skb, struct nlmsghdr *nlh,
        return err;
 }
 
-void vxlan_vnifilter_init(void)
+static const struct rtnl_msg_handler vxlan_vnifilter_rtnl_msg_handlers[] = {
+       {THIS_MODULE, PF_BRIDGE, RTM_GETTUNNEL, NULL, vxlan_vnifilter_dump, 0},
+       {THIS_MODULE, PF_BRIDGE, RTM_NEWTUNNEL, vxlan_vnifilter_process, NULL, 0},
+       {THIS_MODULE, PF_BRIDGE, RTM_DELTUNNEL, vxlan_vnifilter_process, NULL, 0},
+};
+
+int vxlan_vnifilter_init(void)
 {
-       rtnl_register_module(THIS_MODULE, PF_BRIDGE, RTM_GETTUNNEL, NULL,
-                            vxlan_vnifilter_dump, 0);
-       rtnl_register_module(THIS_MODULE, PF_BRIDGE, RTM_NEWTUNNEL,
-                            vxlan_vnifilter_process, NULL, 0);
-       rtnl_register_module(THIS_MODULE, PF_BRIDGE, RTM_DELTUNNEL,
-                            vxlan_vnifilter_process, NULL, 0);
+       return rtnl_register_many(vxlan_vnifilter_rtnl_msg_handlers);
 }
 
 void vxlan_vnifilter_uninit(void)
 {
-       rtnl_unregister(PF_BRIDGE, RTM_GETTUNNEL);
-       rtnl_unregister(PF_BRIDGE, RTM_NEWTUNNEL);
-       rtnl_unregister(PF_BRIDGE, RTM_DELTUNNEL);
+       rtnl_unregister_many(vxlan_vnifilter_rtnl_msg_handlers);
 }
index dbaf26d6a7a61806ac0f7d19ee9d69ead306aecf..16d07d619b4df9245606a227c2aa9d1a156d06b9 100644 (file)
@@ -3043,9 +3043,14 @@ ath10k_wmi_tlv_op_cleanup_mgmt_tx_send(struct ath10k *ar,
                                       struct sk_buff *msdu)
 {
        struct ath10k_skb_cb *cb = ATH10K_SKB_CB(msdu);
+       struct ath10k_mgmt_tx_pkt_addr *pkt_addr;
        struct ath10k_wmi *wmi = &ar->wmi;
 
-       idr_remove(&wmi->mgmt_pending_tx, cb->msdu_id);
+       spin_lock_bh(&ar->data_lock);
+       pkt_addr = idr_remove(&wmi->mgmt_pending_tx, cb->msdu_id);
+       spin_unlock_bh(&ar->data_lock);
+
+       kfree(pkt_addr);
 
        return 0;
 }
index 4861179b221786ef0f673c0ea508d49b2579bdd7..5e061f7525a6bdec402e3571810fd86774ec8588 100644 (file)
@@ -2441,6 +2441,7 @@ wmi_process_mgmt_tx_comp(struct ath10k *ar, struct mgmt_tx_compl_params *param)
        dma_unmap_single(ar->dev, pkt_addr->paddr,
                         msdu->len, DMA_TO_DEVICE);
        info = IEEE80211_SKB_CB(msdu);
+       kfree(pkt_addr);
 
        if (param->status) {
                info->flags &= ~IEEE80211_TX_STAT_ACK;
@@ -9612,6 +9613,7 @@ static int ath10k_wmi_mgmt_tx_clean_up_pending(int msdu_id, void *ptr,
        dma_unmap_single(ar->dev, pkt_addr->paddr,
                         msdu->len, DMA_TO_DEVICE);
        ieee80211_free_txskb(ar->hw, msdu);
+       kfree(pkt_addr);
 
        return 0;
 }
index c087d8a0f5b25540bea70503e53fefbf103eae51..40088e62572e1205d304546d762cf95d75e66913 100644 (file)
@@ -5291,8 +5291,11 @@ int ath11k_dp_rx_process_mon_status(struct ath11k_base *ab, int mac_id,
                    hal_status == HAL_TLV_STATUS_PPDU_DONE) {
                        rx_mon_stats->status_ppdu_done++;
                        pmon->mon_ppdu_status = DP_PPDU_STATUS_DONE;
-                       ath11k_dp_rx_mon_dest_process(ar, mac_id, budget, napi);
-                       pmon->mon_ppdu_status = DP_PPDU_STATUS_START;
+                       if (!ab->hw_params.full_monitor_mode) {
+                               ath11k_dp_rx_mon_dest_process(ar, mac_id,
+                                                             budget, napi);
+                               pmon->mon_ppdu_status = DP_PPDU_STATUS_START;
+                       }
                }
 
                if (ppdu_info->peer_id == HAL_INVALID_PEERID ||
index abe41330fb69292d0fc727fac12ac9d594216667..4d88b02ffa79519160095f06a4425669be5dc8dc 100644 (file)
@@ -59,7 +59,7 @@
 #include <net/cfg80211.h>
 #include <net/ieee80211_radiotap.h>
 
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #include <net/mac80211.h>
 #include "base.h"
index eea4bda776080bdd7449c86c9896f154d6d8e3b9..d81b2ad0b095fc5c2432bc6eb838be488f6b6c9b 100644 (file)
@@ -44,7 +44,7 @@
 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
 
 #include <net/mac80211.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #include "ath5k.h"
 #include "base.h"
index 3f4ce4e9c5320d89fa585e703fb1978f0fd6ea87..90e0859a8e5015100228fd79eefd9e3f32f6bdd8 100644 (file)
@@ -24,7 +24,7 @@
 * Protocol Control Unit Functions *
 \*********************************/
 
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #include "ath5k.h"
 #include "reg.h"
index 7ee4e1616f45acf1c8880d2ca8ec6b5d421fc403..4825f9cb9cb8573aa4eb2305a24eba64180b0a1b 100644 (file)
@@ -27,7 +27,7 @@
 #include <linux/delay.h>
 #include <linux/slab.h>
 #include <linux/sort.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #include "ath5k.h"
 #include "reg.h"
index 9fdb5283b39c32c2fb707c7f754669ac57188311..c67f163c0858d7dc05d102ba3faed74d38d27813 100644 (file)
@@ -25,7 +25,7 @@
 
 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
 
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #include <linux/pci.h>         /* To determine if a card is pci-e */
 #include <linux/log2.h>
index fb5144e2d86c40b0322e33bf66feba1c6b3ca901..f8a94d764be6045bea5b4b4996420e96c58f18f8 100644 (file)
@@ -21,7 +21,7 @@
 #include "hif-ops.h"
 #include "trace.h"
 
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #define CALC_TXRX_PADDED_LEN(dev, len)  (__ALIGN_MASK((len), (dev)->block_mask))
 
index 944f46cdf34c002a5eaf5e0d6820d32e994c69de..73c38a6b488098395c2dd747231e2033c6a89be6 100644 (file)
@@ -14,7 +14,7 @@
  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  */
 
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include <linux/kernel.h>
 #include "hw.h"
 #include "ar9003_phy.h"
index 51abc470125b3cc4e773f5272e2394c8f790a32e..eff894958a7384ecdfa6658213db7deb178e3d90 100644 (file)
@@ -17,7 +17,7 @@
 #include <linux/slab.h>
 #include <linux/vmalloc.h>
 #include <linux/export.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #include "ath9k.h"
 
index 27b860b0c7694a4e5c763fd0cc2f907066f660a5..3e16cfe059f37af4fbdbc35540f017cf032857b3 100644 (file)
@@ -14,7 +14,7 @@
  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  */
 
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include "hw.h"
 #include "ar9002_phy.h"
 
index d85472ee4d85f33bf51afbb1add60bd2a7933442..c139ac49ccf6905fceb7310eacdda955a4bf89f6 100644 (file)
@@ -14,7 +14,7 @@
  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  */
 
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include "hw.h"
 #include "ar9002_phy.h"
 
index 84b31caf8ca6feb68905a47b4c00d49dade48cd9..5ba467cb7425cee6ccf22e3054e553a556aa32cc 100644 (file)
@@ -14,7 +14,7 @@
  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  */
 
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include "hw.h"
 #include "ar9002_phy.h"
 
index a3733c9b484e46a9890d740e8aceefa24216ccb7..7265766cddbdebbac8880e01b440d4c08c8b2132 100644 (file)
@@ -14,7 +14,7 @@
  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  */
 
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include "htc.h"
 
 MODULE_FIRMWARE(HTC_7010_MODULE_FW);
index 04a4b9ea61c3059ca18567446a9cc2d05cfd7b80..c3a6368bfc68abd3f04a907b02445f5e1cd11456 100644 (file)
@@ -21,7 +21,7 @@
 #include <linux/bitops.h>
 #include <linux/etherdevice.h>
 #include <linux/gpio.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #include "hw.h"
 #include "hw-ops.h"
index 6cdbee5beb077a0a4010d863f456f298885ee227..20ceed0dd4be16e17c9b6efae941f823a1f2c318 100644 (file)
@@ -36,7 +36,7 @@
  *    OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  */
 
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #include "carl9170.h"
 #include "cmd.h"
index 85955572a705ec0e1782798c0f19148659e1a1d7..b301e6fbce6cbd5c6920d4c50692198d665ffcf1 100644 (file)
@@ -15,7 +15,7 @@
  */
 
 #include <linux/export.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #include "ath.h"
 #include "reg.h"
index 21a93fec284d65eea4963ff0aeb7d48e6a90eb0e..0ae436bd9b665ccf43886b9688cedabfbfe36ca8 100644 (file)
@@ -16,7 +16,7 @@
  */
 
 #include <linux/export.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include <net/mac80211.h>
 
 #include "ath.h"
index f29ac6de713994df19194b77bcd36a4e75fb2e7f..19702b6f09c32917061045458039907d4766cb0d 100644 (file)
@@ -306,7 +306,7 @@ static void wil_rx_add_radiotap_header(struct wil6210_priv *wil,
                                       struct sk_buff *skb)
 {
        struct wil6210_rtap {
-               struct ieee80211_radiotap_header rthdr;
+               struct ieee80211_radiotap_header_fixed rthdr;
                /* fields should be in the order of bits in rthdr.it_present */
                /* flags */
                u8 flags;
index 8e56dcf9309d1330b5762534d15a01ad2199e0e6..25b4ef9d3c9a100314d4a6dd0da7add3befe1279 100644 (file)
@@ -30,7 +30,7 @@
 #include <linux/io.h>
 #include <linux/dma-mapping.h>
 #include <linux/slab.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #include "b43.h"
 #include "main.h"
index 441d6440671baf72435ba1c14d9ba44809615032..2370a2e6a2e3cc185fa8eea2a22cfe3f03923125 100644 (file)
@@ -27,7 +27,7 @@
 #include <linux/dma-mapping.h>
 #include <linux/slab.h>
 #include <net/dst.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #include "b43legacy.h"
 #include "main.h"
index 3a1a35b5672f1a27911a287579a7ce737a157f0e..19d0c003f62626756aebf1068c1e1274e3e9030a 100644 (file)
@@ -27,6 +27,7 @@ source "drivers/net/wireless/broadcom/brcm80211/brcmfmac/Kconfig"
 config BRCM_TRACING
        bool "Broadcom device tracing"
        depends on BRCMSMAC || BRCMFMAC
+       depends on TRACING
        help
          If you say Y here, the Broadcom wireless drivers will register
          with ftrace to dump event information into the trace ringbuffer.
index 9ca1b2aadcb537c47cb4f76de85ecf508ad3f4bc..eed439b840109fe37841d5a3730eae1d1b6f3f87 100644 (file)
@@ -7,7 +7,7 @@
 #ifndef FWEH_H_
 #define FWEH_H_
 
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include <linux/skbuff.h>
 #include <linux/if_ether.h>
 #include <linux/if.h>
index ce482a3877e90ac16373ec7b081261d509c8bc34..5dee54819fbdfb69ff26d9d6d24030ad4e33b125 100644 (file)
@@ -16,7 +16,7 @@
 #include <linux/kthread.h>
 #include <linux/io.h>
 #include <linux/random.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #include <soc.h>
 #include <chipcommon.h>
index 1461dc453ac22e45766d2e8fd50b895e08dd0a5d..7b936668c1b66d3afb2a41c41adc63e2d2599929 100644 (file)
@@ -23,7 +23,7 @@
 #include <linux/bcma/bcma.h>
 #include <linux/debugfs.h>
 #include <linux/vmalloc.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include <defs.h>
 #include <brcmu_wifi.h>
 #include <brcmu_utils.h>
index 2f8908074303790717e121cd2302a31061753690..08841b9a5b81f4463850e54bfea981b1d31b680e 100644 (file)
@@ -3,7 +3,7 @@
  * Copyright (c) 2019 Broadcom
  */
 
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #include <linux/math.h>
 #include <linux/string.h>
index b6636002c7d220eeeb08b12f2bc23c2dd924455f..fe75941c584d15574dccd70c4d4d29aa600efe4d 100644 (file)
@@ -2518,7 +2518,7 @@ static void isr_rx_monitor(struct ipw2100_priv *priv, int i,
         * to build this manually element by element, we can write it much
         * more efficiently than we can parse it. ORDER MATTERS HERE */
        struct ipw_rt_hdr {
-               struct ieee80211_radiotap_header rt_hdr;
+               struct ieee80211_radiotap_header_fixed rt_hdr;
                s8 rt_dbmsignal; /* signal in dbM, kluged to signed */
        } *ipw_rt;
 
index 8ebf09121e173c7646580f68dac1e4e19f60bf92..226286cb7eb82271b4480c45a1c61d6bf6c8356f 100644 (file)
@@ -1143,7 +1143,7 @@ struct ipw_prom_priv {
  * structure is provided regardless of any bits unset.
  */
 struct ipw_rt_hdr {
-       struct ieee80211_radiotap_header rt_hdr;
+       struct ieee80211_radiotap_header_fixed rt_hdr;
        u64 rt_tsf;      /* TSF */      /* XXX */
        u8 rt_flags;    /* radiotap packet flags */
        u8 rt_rate;     /* rate in 500kb/s */
index e95800b77f6b37d76e01272675fc2b8a374c65d8..14d2331ee6cb978afcda319a06968f45d73ef9b0 100644 (file)
@@ -20,7 +20,7 @@
 #include <linux/netdevice.h>
 #include <linux/firmware.h>
 #include <linux/etherdevice.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include <net/mac80211.h>
 
 #include "common.h"
index c34729f576cdad768cced58198e03e36dd64b7f7..b63e29590b0487f365f1f14e65469f7a495e43ea 100644 (file)
@@ -20,7 +20,7 @@
 #include <linux/units.h>
 #include <net/mac80211.h>
 #include <linux/etherdevice.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #include "common.h"
 #include "4965.h"
index 9d33a66a49b5930ba7c33408188be443b29352ba..958dd4f9bc69201ba477e46d2e749871daddde28 100644 (file)
@@ -3122,6 +3122,7 @@ il_enqueue_hcmd(struct il_priv *il, struct il_host_cmd *cmd)
        struct il_cmd_meta *out_meta;
        dma_addr_t phys_addr;
        unsigned long flags;
+       u8 *out_payload;
        u32 idx;
        u16 fix_size;
 
@@ -3157,6 +3158,16 @@ il_enqueue_hcmd(struct il_priv *il, struct il_host_cmd *cmd)
        out_cmd = txq->cmd[idx];
        out_meta = &txq->meta[idx];
 
+       /* The payload is in the same place in regular and huge
+        * command buffers, but we need to let the compiler know when
+        * we're using a larger payload buffer to avoid "field-
+        * spanning write" warnings at run-time for huge commands.
+        */
+       if (cmd->flags & CMD_SIZE_HUGE)
+               out_payload = ((struct il_device_cmd_huge *)out_cmd)->cmd.payload;
+       else
+               out_payload = out_cmd->cmd.payload;
+
        if (WARN_ON(out_meta->flags & CMD_MAPPED)) {
                spin_unlock_irqrestore(&il->hcmd_lock, flags);
                return -ENOSPC;
@@ -3170,7 +3181,7 @@ il_enqueue_hcmd(struct il_priv *il, struct il_host_cmd *cmd)
                out_meta->callback = cmd->callback;
 
        out_cmd->hdr.cmd = cmd->id;
-       memcpy(&out_cmd->cmd.payload, cmd->data, cmd->len);
+       memcpy(out_payload, cmd->data, cmd->len);
 
        /* At this point, the out_cmd now has all of the incoming cmd
         * information */
@@ -4962,6 +4973,8 @@ il_pci_resume(struct device *device)
         */
        pci_write_config_byte(pdev, PCI_CFG_RETRY_TIMEOUT, 0x00);
 
+       _il_wr(il, CSR_INT, 0xffffffff);
+       _il_wr(il, CSR_FH_INT_STATUS, 0xffffffff);
        il_enable_interrupts(il);
 
        if (!(_il_rd(il, CSR_GP_CNTRL) & CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW))
index 2147781b5fffb0d09fb7ae9ed9198de2062ed1ad..725c2a88ddb782c53fff14f3ad73078d5a8aa3cb 100644 (file)
@@ -560,6 +560,18 @@ struct il_device_cmd {
 
 #define TFD_MAX_PAYLOAD_SIZE (sizeof(struct il_device_cmd))
 
+/**
+ * struct il_device_cmd_huge
+ *
+ * For use when sending huge commands.
+ */
+struct il_device_cmd_huge {
+       struct il_cmd_header hdr;       /* uCode API */
+       union {
+               u8 payload[IL_MAX_CMD_SIZE - sizeof(struct il_cmd_header)];
+       } __packed cmd;
+} __packed;
+
 struct il_host_cmd {
        const void *data;
        unsigned long reply_page;
index 71f67a019cf60f65d096def650e4704dcf2883e6..5ca85d90a8d64c39068a0eacd670c928fb65a779 100644 (file)
@@ -13,7 +13,7 @@
 #include <linux/netdevice.h>
 #include <net/mac80211.h>
 #include <linux/etherdevice.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include "iwl-io.h"
 #include "iwl-trans.h"
 #include "iwl-modparams.h"
index e9d2717362cf9ad713e51dbaf7a2161d2d7b5b9c..7f67e602940ca6f27962a344c69366102710a1ea 100644 (file)
@@ -13,7 +13,7 @@
 #include <linux/slab.h>
 #include <linux/sched.h>
 #include <net/mac80211.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #include "iwl-trans.h"
 #include "iwl-io.h"
index a7cea0a55b35af15f35b11bb869e9f2583cb5d9e..0bc32291815e1bade074c92f8a02a42ba8ad5acd 100644 (file)
@@ -429,38 +429,28 @@ out_free:
        return ret;
 }
 
-static int iwl_acpi_sar_set_profile(union acpi_object *table,
-                                   struct iwl_sar_profile *profile,
-                                   bool enabled, u8 num_chains,
-                                   u8 num_sub_bands)
+static int
+iwl_acpi_parse_chains_table(union acpi_object *table,
+                           struct iwl_sar_profile_chain *chains,
+                           u8 num_chains, u8 num_sub_bands)
 {
-       int i, j, idx = 0;
-
-       /*
-        * The table from ACPI is flat, but we store it in a
-        * structured array.
-        */
-       for (i = 0; i < BIOS_SAR_MAX_CHAINS_PER_PROFILE; i++) {
-               for (j = 0; j < BIOS_SAR_MAX_SUB_BANDS_NUM; j++) {
+       for (u8 chain = 0; chain < num_chains; chain++) {
+               for (u8 subband = 0; subband < BIOS_SAR_MAX_SUB_BANDS_NUM;
+                    subband++) {
                        /* if we don't have the values, use the default */
-                       if (i >= num_chains || j >= num_sub_bands) {
-                               profile->chains[i].subbands[j] = 0;
+                       if (subband >= num_sub_bands) {
+                               chains[chain].subbands[subband] = 0;
+                       } else if (table->type != ACPI_TYPE_INTEGER ||
+                                  table->integer.value > U8_MAX) {
+                               return -EINVAL;
                        } else {
-                               if (table[idx].type != ACPI_TYPE_INTEGER ||
-                                   table[idx].integer.value > U8_MAX)
-                                       return -EINVAL;
-
-                               profile->chains[i].subbands[j] =
-                                       table[idx].integer.value;
-
-                               idx++;
+                               chains[chain].subbands[subband] =
+                                       table->integer.value;
+                               table++;
                        }
                }
        }
 
-       /* Only if all values were valid can the profile be enabled */
-       profile->enabled = enabled;
-
        return 0;
 }
 
@@ -543,9 +533,11 @@ read_table:
        /* The profile from WRDS is officially profile 1, but goes
         * into sar_profiles[0] (because we don't have a profile 0).
         */
-       ret = iwl_acpi_sar_set_profile(table, &fwrt->sar_profiles[0],
-                                      flags & IWL_SAR_ENABLE_MSK,
-                                      num_chains, num_sub_bands);
+       ret = iwl_acpi_parse_chains_table(table, fwrt->sar_profiles[0].chains,
+                                         num_chains, num_sub_bands);
+       if (!ret && flags & IWL_SAR_ENABLE_MSK)
+               fwrt->sar_profiles[0].enabled = true;
+
 out_free:
        kfree(data);
        return ret;
@@ -557,7 +549,7 @@ int iwl_acpi_get_ewrd_table(struct iwl_fw_runtime *fwrt)
        bool enabled;
        int i, n_profiles, tbl_rev, pos;
        int ret = 0;
-       u8 num_chains, num_sub_bands;
+       u8 num_sub_bands;
 
        data = iwl_acpi_get_object(fwrt->dev, ACPI_EWRD_METHOD);
        if (IS_ERR(data))
@@ -573,7 +565,6 @@ int iwl_acpi_get_ewrd_table(struct iwl_fw_runtime *fwrt)
                        goto out_free;
                }
 
-               num_chains = ACPI_SAR_NUM_CHAINS_REV2;
                num_sub_bands = ACPI_SAR_NUM_SUB_BANDS_REV2;
 
                goto read_table;
@@ -589,7 +580,6 @@ int iwl_acpi_get_ewrd_table(struct iwl_fw_runtime *fwrt)
                        goto out_free;
                }
 
-               num_chains = ACPI_SAR_NUM_CHAINS_REV1;
                num_sub_bands = ACPI_SAR_NUM_SUB_BANDS_REV1;
 
                goto read_table;
@@ -605,7 +595,6 @@ int iwl_acpi_get_ewrd_table(struct iwl_fw_runtime *fwrt)
                        goto out_free;
                }
 
-               num_chains = ACPI_SAR_NUM_CHAINS_REV0;
                num_sub_bands = ACPI_SAR_NUM_SUB_BANDS_REV0;
 
                goto read_table;
@@ -637,23 +626,54 @@ read_table:
        /* the tables start at element 3 */
        pos = 3;
 
+       BUILD_BUG_ON(ACPI_SAR_NUM_CHAINS_REV0 != ACPI_SAR_NUM_CHAINS_REV1);
+       BUILD_BUG_ON(ACPI_SAR_NUM_CHAINS_REV2 != 2 * ACPI_SAR_NUM_CHAINS_REV0);
+
+       /* parse non-cdb chains for all profiles */
        for (i = 0; i < n_profiles; i++) {
                union acpi_object *table = &wifi_pkg->package.elements[pos];
+
                /* The EWRD profiles officially go from 2 to 4, but we
                 * save them in sar_profiles[1-3] (because we don't
                 * have profile 0).  So in the array we start from 1.
                 */
-               ret = iwl_acpi_sar_set_profile(table,
-                                              &fwrt->sar_profiles[i + 1],
-                                              enabled, num_chains,
-                                              num_sub_bands);
+               ret = iwl_acpi_parse_chains_table(table,
+                                                 fwrt->sar_profiles[i + 1].chains,
+                                                 ACPI_SAR_NUM_CHAINS_REV0,
+                                                 num_sub_bands);
                if (ret < 0)
-                       break;
+                       goto out_free;
 
                /* go to the next table */
-               pos += num_chains * num_sub_bands;
+               pos += ACPI_SAR_NUM_CHAINS_REV0 * num_sub_bands;
        }
 
+       /* non-cdb table revisions */
+       if (tbl_rev < 2)
+               goto set_enabled;
+
+       /* parse cdb chains for all profiles */
+       for (i = 0; i < n_profiles; i++) {
+               struct iwl_sar_profile_chain *chains;
+               union acpi_object *table;
+
+               table = &wifi_pkg->package.elements[pos];
+               chains = &fwrt->sar_profiles[i + 1].chains[ACPI_SAR_NUM_CHAINS_REV0];
+               ret = iwl_acpi_parse_chains_table(table,
+                                                 chains,
+                                                 ACPI_SAR_NUM_CHAINS_REV0,
+                                                 num_sub_bands);
+               if (ret < 0)
+                       goto out_free;
+
+               /* go to the next table */
+               pos += ACPI_SAR_NUM_CHAINS_REV0 * num_sub_bands;
+       }
+
+set_enabled:
+       for (i = 0; i < n_profiles; i++)
+               fwrt->sar_profiles[i + 1].enabled = enabled;
+
 out_free:
        kfree(data);
        return ret;
index d8b083be5b6b5e5a60a582870185d1788c1d38ee..de87e0e3e0725dfb983ba4fced10c0e916a56108 100644 (file)
@@ -39,10 +39,12 @@ void iwl_fw_runtime_init(struct iwl_fw_runtime *fwrt, struct iwl_trans *trans,
 }
 IWL_EXPORT_SYMBOL(iwl_fw_runtime_init);
 
+/* Assumes the appropriate lock is held by the caller */
 void iwl_fw_runtime_suspend(struct iwl_fw_runtime *fwrt)
 {
        iwl_fw_suspend_timestamp(fwrt);
-       iwl_dbg_tlv_time_point(fwrt, IWL_FW_INI_TIME_POINT_HOST_D3_START, NULL);
+       iwl_dbg_tlv_time_point_sync(fwrt, IWL_FW_INI_TIME_POINT_HOST_D3_START,
+                                   NULL);
 }
 IWL_EXPORT_SYMBOL(iwl_fw_runtime_suspend);
 
index 2abfc986701f8efa7012d45d4d1ec85469a692f5..c620911a11933a988df4031b1f2ded16769e834b 100644 (file)
@@ -1413,25 +1413,35 @@ _iwl_op_mode_start(struct iwl_drv *drv, struct iwlwifi_opmode_table *op)
        const struct iwl_op_mode_ops *ops = op->ops;
        struct dentry *dbgfs_dir = NULL;
        struct iwl_op_mode *op_mode = NULL;
+       int retry, max_retry = !!iwlwifi_mod_params.fw_restart * IWL_MAX_INIT_RETRY;
 
        /* also protects start/stop from racing against each other */
        lockdep_assert_held(&iwlwifi_opmode_table_mtx);
 
+       for (retry = 0; retry <= max_retry; retry++) {
+
 #ifdef CONFIG_IWLWIFI_DEBUGFS
-       drv->dbgfs_op_mode = debugfs_create_dir(op->name,
-                                               drv->dbgfs_drv);
-       dbgfs_dir = drv->dbgfs_op_mode;
+               drv->dbgfs_op_mode = debugfs_create_dir(op->name,
+                                                       drv->dbgfs_drv);
+               dbgfs_dir = drv->dbgfs_op_mode;
 #endif
 
-       op_mode = ops->start(drv->trans, drv->trans->cfg,
-                            &drv->fw, dbgfs_dir);
-       if (op_mode)
-               return op_mode;
+               op_mode = ops->start(drv->trans, drv->trans->cfg,
+                                    &drv->fw, dbgfs_dir);
+
+               if (op_mode)
+                       return op_mode;
+
+               if (test_bit(STATUS_TRANS_DEAD, &drv->trans->status))
+                       break;
+
+               IWL_ERR(drv, "retry init count %d\n", retry);
 
 #ifdef CONFIG_IWLWIFI_DEBUGFS
-       debugfs_remove_recursive(drv->dbgfs_op_mode);
-       drv->dbgfs_op_mode = NULL;
+               debugfs_remove_recursive(drv->dbgfs_op_mode);
+               drv->dbgfs_op_mode = NULL;
 #endif
+       }
 
        return NULL;
 }
index 1549ff429549788173c769239d9ebcd118a9a302..6a1d31892417b45fa24859b7ba7e133a5b8944cf 100644 (file)
@@ -98,6 +98,9 @@ void iwl_drv_stop(struct iwl_drv *drv);
 #define VISIBLE_IF_IWLWIFI_KUNIT static
 #endif
 
+/* max retry for init flow */
+#define IWL_MAX_INIT_RETRY 2
+
 #define FW_NAME_PRE_BUFSIZE    64
 struct iwl_trans;
 const char *iwl_drv_get_fwname_pre(struct iwl_trans *trans, char *buf);
index 49a6aff42376b5f0cb8af791542247327dde5431..244ca8cab9d1a239b7936b46fa58904ebf2ed4b3 100644 (file)
@@ -1398,7 +1398,9 @@ int iwl_mvm_suspend(struct ieee80211_hw *hw, struct cfg80211_wowlan *wowlan)
 
        iwl_mvm_pause_tcm(mvm, true);
 
+       mutex_lock(&mvm->mutex);
        iwl_fw_runtime_suspend(&mvm->fwrt);
+       mutex_unlock(&mvm->mutex);
 
        return __iwl_mvm_suspend(hw, wowlan, false);
 }
index 08546e673cf51ea5dbec8702453fa9c44862e9a0..f30b0fc8eca97d5dba26eb41ea06cd71259ec46d 100644 (file)
@@ -1307,8 +1307,8 @@ static void iwl_mvm_disconnect_iterator(void *data, u8 *mac,
 void iwl_mvm_send_recovery_cmd(struct iwl_mvm *mvm, u32 flags)
 {
        u32 error_log_size = mvm->fw->ucode_capa.error_log_size;
+       u32 status = 0;
        int ret;
-       u32 resp;
 
        struct iwl_fw_error_recovery_cmd recovery_cmd = {
                .flags = cpu_to_le32(flags),
@@ -1316,7 +1316,6 @@ void iwl_mvm_send_recovery_cmd(struct iwl_mvm *mvm, u32 flags)
        };
        struct iwl_host_cmd host_cmd = {
                .id = WIDE_ID(SYSTEM_GROUP, FW_ERROR_RECOVERY_CMD),
-               .flags = CMD_WANT_SKB,
                .data = {&recovery_cmd, },
                .len = {sizeof(recovery_cmd), },
        };
@@ -1336,7 +1335,7 @@ void iwl_mvm_send_recovery_cmd(struct iwl_mvm *mvm, u32 flags)
                recovery_cmd.buf_size = cpu_to_le32(error_log_size);
        }
 
-       ret = iwl_mvm_send_cmd(mvm, &host_cmd);
+       ret = iwl_mvm_send_cmd_status(mvm, &host_cmd, &status);
        kfree(mvm->error_recovery_buf);
        mvm->error_recovery_buf = NULL;
 
@@ -1347,11 +1346,10 @@ void iwl_mvm_send_recovery_cmd(struct iwl_mvm *mvm, u32 flags)
 
        /* skb respond is only relevant in ERROR_RECOVERY_UPDATE_DB */
        if (flags & ERROR_RECOVERY_UPDATE_DB) {
-               resp = le32_to_cpu(*(__le32 *)host_cmd.resp_pkt->data);
-               if (resp) {
+               if (status) {
                        IWL_ERR(mvm,
                                "Failed to send recovery cmd blob was invalid %d\n",
-                               resp);
+                               status);
 
                        ieee80211_iterate_interfaces(mvm->hw, 0,
                                                     iwl_mvm_disconnect_iterator,
index a327893c6dce4750e4e17e15209fd65876cb475f..80b9a115245fe87c9fcba999e16298de20a15367 100644 (file)
@@ -1293,12 +1293,14 @@ int iwl_mvm_mac_start(struct ieee80211_hw *hw)
 {
        struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
        int ret;
+       int retry, max_retry = 0;
 
        mutex_lock(&mvm->mutex);
 
        /* we are starting the mac not in error flow, and restart is enabled */
        if (!test_bit(IWL_MVM_STATUS_HW_RESTART_REQUESTED, &mvm->status) &&
            iwlwifi_mod_params.fw_restart) {
+               max_retry = IWL_MAX_INIT_RETRY;
                /*
                 * This will prevent mac80211 recovery flows to trigger during
                 * init failures
@@ -1306,7 +1308,13 @@ int iwl_mvm_mac_start(struct ieee80211_hw *hw)
                set_bit(IWL_MVM_STATUS_STARTING, &mvm->status);
        }
 
-       ret = __iwl_mvm_mac_start(mvm);
+       for (retry = 0; retry <= max_retry; retry++) {
+               ret = __iwl_mvm_mac_start(mvm);
+               if (!ret)
+                       break;
+
+               IWL_ERR(mvm, "mac start retry %d\n", retry);
+       }
        clear_bit(IWL_MVM_STATUS_STARTING, &mvm->status);
 
        mutex_unlock(&mvm->mutex);
@@ -1970,7 +1978,6 @@ static void iwl_mvm_mac_remove_interface(struct ieee80211_hw *hw,
                mvm->p2p_device_vif = NULL;
        }
 
-       iwl_mvm_unset_link_mapping(mvm, vif, &vif->bss_conf);
        iwl_mvm_mac_ctxt_remove(mvm, vif);
 
        RCU_INIT_POINTER(mvm->vif_id_to_mac[mvmvif->id], NULL);
@@ -1979,6 +1986,7 @@ static void iwl_mvm_mac_remove_interface(struct ieee80211_hw *hw,
                mvm->monitor_on = false;
 
 out:
+       iwl_mvm_unset_link_mapping(mvm, vif, &vif->bss_conf);
        if (vif->type == NL80211_IFTYPE_AP ||
            vif->type == NL80211_IFTYPE_ADHOC) {
                iwl_mvm_dealloc_int_sta(mvm, &mvmvif->deflink.mcast_sta);
index f2378e0fb2fb38edf6259d583442ff80af881c2c..e252f0dcea20572ca79e85888ff73f1487e11cac 100644 (file)
@@ -41,8 +41,6 @@ static int iwl_mvm_mld_mac_add_interface(struct ieee80211_hw *hw,
        /* reset deflink MLO parameters */
        mvmvif->deflink.fw_link_id = IWL_MVM_FW_LINK_ID_INVALID;
        mvmvif->deflink.active = 0;
-       /* the first link always points to the default one */
-       mvmvif->link[0] = &mvmvif->deflink;
 
        ret = iwl_mvm_mld_mac_ctxt_add(mvm, vif);
        if (ret)
@@ -60,9 +58,19 @@ static int iwl_mvm_mld_mac_add_interface(struct ieee80211_hw *hw,
                                     IEEE80211_VIF_SUPPORTS_CQM_RSSI;
        }
 
-       ret = iwl_mvm_add_link(mvm, vif, &vif->bss_conf);
-       if (ret)
-               goto out_free_bf;
+       /* We want link[0] to point to the default link, unless we have MLO and
+        * in this case this will be modified later by .change_vif_links()
+        * If we are in the restart flow with an MLD connection, we will wait
+        * to .change_vif_links() to setup the links.
+        */
+       if (!test_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status) ||
+           !ieee80211_vif_is_mld(vif)) {
+               mvmvif->link[0] = &mvmvif->deflink;
+
+               ret = iwl_mvm_add_link(mvm, vif, &vif->bss_conf);
+               if (ret)
+                       goto out_free_bf;
+       }
 
        /* Save a pointer to p2p device vif, so it can later be used to
         * update the p2p device MAC when a GO is started/stopped
@@ -350,11 +358,6 @@ __iwl_mvm_mld_assign_vif_chanctx(struct iwl_mvm *mvm,
                rcu_read_unlock();
        }
 
-       if (vif->type == NL80211_IFTYPE_STATION)
-               iwl_mvm_send_ap_tx_power_constraint_cmd(mvm, vif,
-                                                       link_conf,
-                                                       false);
-
        /* then activate */
        ret = iwl_mvm_link_changed(mvm, vif, link_conf,
                                   LINK_CONTEXT_MODIFY_ACTIVE |
@@ -363,6 +366,11 @@ __iwl_mvm_mld_assign_vif_chanctx(struct iwl_mvm *mvm,
        if (ret)
                goto out;
 
+       if (vif->type == NL80211_IFTYPE_STATION)
+               iwl_mvm_send_ap_tx_power_constraint_cmd(mvm, vif,
+                                                       link_conf,
+                                                       false);
+
        /*
         * Power state must be updated before quotas,
         * otherwise fw will complain.
@@ -1194,7 +1202,11 @@ iwl_mvm_mld_change_vif_links(struct ieee80211_hw *hw,
 
        mutex_lock(&mvm->mutex);
 
-       if (old_links == 0) {
+       /* If we're in RESTART flow, the default link wasn't added in
+         * drv_add_interface(), and link[0] doesn't point to it.
+        */
+       if (old_links == 0 && !test_bit(IWL_MVM_STATUS_IN_HW_RESTART,
+                                       &mvm->status)) {
                err = iwl_mvm_disable_link(mvm, vif, &vif->bss_conf);
                if (err)
                        goto out_err;
index 047c020f8efa1878dd1a61968454db169a7ceab2..1a0b5f8d43390ec63f157483f36678859f346877 100644 (file)
@@ -4,7 +4,7 @@
  * Copyright (C) 2013-2015 Intel Mobile Communications GmbH
  * Copyright (C) 2016-2017 Intel Deutschland GmbH
  */
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include <linux/etherdevice.h>
 #include <linux/skbuff.h>
 #include "iwl-trans.h"
index 3ce9150213a74452e32082aeb2019942384ae9f8..ddcbd80a49fb2b71d3e693f597938728bee50537 100644 (file)
@@ -1774,7 +1774,7 @@ iwl_mvm_umac_scan_cfg_channels_v7_6g(struct iwl_mvm *mvm,
                        &cp->channel_config[ch_cnt];
 
                u32 s_ssid_bitmap = 0, bssid_bitmap = 0, flags = 0;
-               u8 j, k, n_s_ssids = 0, n_bssids = 0;
+               u8 k, n_s_ssids = 0, n_bssids = 0;
                u8 max_s_ssids, max_bssids;
                bool force_passive = false, found = false, allow_passive = true,
                     unsolicited_probe_on_chan = false, psc_no_listen = false;
@@ -1799,7 +1799,7 @@ iwl_mvm_umac_scan_cfg_channels_v7_6g(struct iwl_mvm *mvm,
                cfg->v5.iter_count = 1;
                cfg->v5.iter_interval = 0;
 
-               for (j = 0; j < params->n_6ghz_params; j++) {
+               for (u32 j = 0; j < params->n_6ghz_params; j++) {
                        s8 tmp_psd_20;
 
                        if (!(scan_6ghz_params[j].channel_idx == i))
@@ -1873,7 +1873,7 @@ iwl_mvm_umac_scan_cfg_channels_v7_6g(struct iwl_mvm *mvm,
                 * SSID.
                 * TODO: improve this logic
                 */
-               for (j = 0; j < params->n_6ghz_params; j++) {
+               for (u32 j = 0; j < params->n_6ghz_params; j++) {
                        if (!(scan_6ghz_params[j].channel_idx == i))
                                continue;
 
index b700c213d10c4f82b82cab8f549543b1c9d06af5..afe9bcd3ad46d7d37fdb0c138210f540e3173a19 100644 (file)
@@ -15,7 +15,7 @@
 #include <linux/slab.h>
 #include <linux/ieee80211.h>
 #include <net/cfg80211.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #include "decl.h"
 #include "cfg.h"
index 74cb7551f4275cfe02e8bfec2877bc7f69002662..f2aa659e77148e3863bb8b3953b419cad749964e 100644 (file)
@@ -8,7 +8,7 @@
 #include <linux/slab.h>
 #include <linux/delay.h>
 #include <linux/sched.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include <net/cfg80211.h>
 
 #include "cfg.h"
index 1ed5608d353ff5fcb82ab8ff811bb63af13129e9..d543bfe739dcb9aa438c2c47947ccc8e36c34bbf 100644 (file)
@@ -2,7 +2,7 @@
 #include <net/ieee80211_radiotap.h>
 
 struct tx_radiotap_hdr {
-       struct ieee80211_radiotap_header hdr;
+       struct ieee80211_radiotap_header_fixed hdr;
        u8 rate;
        u8 txpower;
        u8 rts_retries;
@@ -31,7 +31,7 @@ struct tx_radiotap_hdr {
 #define IEEE80211_FC_DSTODS          0x0300
 
 struct rx_radiotap_hdr {
-       struct ieee80211_radiotap_header hdr;
+       struct ieee80211_radiotap_header_fixed hdr;
        u8 flags;
        u8 rate;
        u8 antsignal;
index 7894102f03eb0e81aad9a401bcd44c57cbea832c..1cff001bdc514540e6ebddc449f541bfa04927f1 100644 (file)
@@ -5,7 +5,7 @@
  * Copyright 2011-2020 NXP
  */
 
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include "decl.h"
 #include "ioctl.h"
 #include "util.h"
index 98da82b74094ddd09397cb6644464a2e75bebdb8..3353012e8542984a081c863707cccb915d4a1504 100644 (file)
@@ -84,13 +84,16 @@ int mt76_mcu_skb_send_and_get_msg(struct mt76_dev *dev, struct sk_buff *skb,
        mutex_lock(&dev->mcu.mutex);
 
        if (dev->mcu_ops->mcu_skb_prepare_msg) {
+               orig_skb = skb;
                ret = dev->mcu_ops->mcu_skb_prepare_msg(dev, skb, cmd, &seq);
                if (ret < 0)
                        goto out;
        }
 
 retry:
-       orig_skb = skb_get(skb);
+       /* orig skb might be needed for retry, mcu_skb_send_msg consumes it */
+       if (orig_skb)
+               skb_get(orig_skb);
        ret = dev->mcu_ops->mcu_skb_send_msg(dev, skb, cmd, &seq);
        if (ret < 0)
                goto out;
@@ -105,7 +108,7 @@ retry:
        do {
                skb = mt76_mcu_get_response(dev, expires);
                if (!skb && !test_bit(MT76_MCU_RESET, &dev->phy.state) &&
-                   retry++ < dev->mcu_ops->max_retry) {
+                   orig_skb && retry++ < dev->mcu_ops->max_retry) {
                        dev_err(dev->dev, "Retry message %08x (seq %d)\n",
                                cmd, seq);
                        skb = orig_skb;
index bcd24c9072ec9e52f68c7dac0f124279d525eba0..4de45a56812d67ae675f065252853c08c7291186 100644 (file)
@@ -10,7 +10,7 @@
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/partitions.h>
 #include <linux/etherdevice.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include "mt76x0.h"
 #include "eeprom.h"
 #include "../mt76x02_phy.h"
index 5d402cf2951cb35c2aa5bd1dde0ca20a142a56dc..a5e3392c0b48f9d458672cf8a85a5c40364d025a 100644 (file)
@@ -4,7 +4,7 @@
  * Copyright (C) 2018 Lorenzo Bianconi <[email protected]>
  */
 
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #include "mt76x02_eeprom.h"
 
index 1fe5f5a02f937783c669205e286e917ec0872db1..156b16c17b2b44e3d20714fb78c5bc089765b0d7 100644 (file)
@@ -5,7 +5,7 @@
 
 #include <linux/module.h>
 #include <linux/of.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include "mt76x2.h"
 #include "eeprom.h"
 
index 81e559ec1c7b3b71bf2f3f894d9e9d606652108e..cda9c267516ec9e4d9f74531a28388d3d91180f8 100644 (file)
@@ -7,7 +7,7 @@
 #ifndef __MT7601U_DMA_H
 #define __MT7601U_DMA_H
 
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include <linux/skbuff.h>
 
 #define MT_DMA_HDR_LEN                 4
index 625bebe605388791d55944b1ad92643537e039bf..d4d31a54655692e29bbed3ad8999c9eb9f286b8e 100644 (file)
@@ -8,7 +8,7 @@
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/partitions.h>
 #include <linux/etherdevice.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include "mt7601u.h"
 #include "eeprom.h"
 #include "mac.h"
index 03b7229a0ff5aab90e1b1e860e67142478f3f61c..c3d27aaec297422c4cf34f01cd4056b6929fad33 100644 (file)
@@ -7,12 +7,12 @@
 #include "cfg80211.h"
 
 struct wilc_wfi_radiotap_hdr {
-       struct ieee80211_radiotap_header hdr;
+       struct ieee80211_radiotap_header_fixed hdr;
        u8 rate;
 } __packed;
 
 struct wilc_wfi_radiotap_cb_hdr {
-       struct ieee80211_radiotap_header hdr;
+       struct ieee80211_radiotap_header_fixed hdr;
        u8 rate;
        u8 dump;
        u16 tx_flags;
index 15334940287d86a6fe5e1dec6e2b645e3f58dd38..56d1139ba8bcceaff0c276768ef05842e88ce5ac 100644 (file)
@@ -16,7 +16,7 @@
 #include <linux/string.h>
 #include <linux/module.h>
 #include <net/mac80211.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include <linux/sysfs.h>
 
 #include "mac.h"
index d069a81ac617521a8ad44b96b65743b358ede837..cc699efa9c79385398d93c2e9ddf9c731db3be24 100644 (file)
@@ -352,7 +352,6 @@ static const struct usb_device_id rtl8192d_usb_ids[] = {
        {RTL_USB_DEVICE(USB_VENDOR_ID_REALTEK, 0x8194, rtl92du_hal_cfg)},
        {RTL_USB_DEVICE(USB_VENDOR_ID_REALTEK, 0x8111, rtl92du_hal_cfg)},
        {RTL_USB_DEVICE(USB_VENDOR_ID_REALTEK, 0x0193, rtl92du_hal_cfg)},
-       {RTL_USB_DEVICE(USB_VENDOR_ID_REALTEK, 0x8171, rtl92du_hal_cfg)},
        {RTL_USB_DEVICE(USB_VENDOR_ID_REALTEK, 0xe194, rtl92du_hal_cfg)},
        {RTL_USB_DEVICE(0x2019, 0xab2c, rtl92du_hal_cfg)},
        {RTL_USB_DEVICE(0x2019, 0xab2d, rtl92du_hal_cfg)},
index e83ab6fb83f5b7502c0a499ef9ef22aac81abb70..b17a429bcd2994e0fc50dc80e11bc7a8e52fc099 100644 (file)
@@ -771,7 +771,6 @@ static void rtw_usb_dynamic_rx_agg_v1(struct rtw_dev *rtwdev, bool enable)
        u8 size, timeout;
        u16 val16;
 
-       rtw_write32_set(rtwdev, REG_RXDMA_AGG_PG_TH, BIT_EN_PRE_CALC);
        rtw_write8_set(rtwdev, REG_TXDMA_PQ_MAP, BIT_RXDMA_AGG_EN);
        rtw_write8_clr(rtwdev, REG_RXDMA_AGG_PG_TH + 3, BIT(7));
 
index df51b29142aa2646a72107610ab77f44eaf9baab..8d27374db83ca0728afe4c65e3e40d142f64298a 100644 (file)
@@ -6445,6 +6445,8 @@ static void _update_wl_info_v7(struct rtw89_dev *rtwdev, u8 rid)
 
        /* todo DBCC related event */
        rtw89_debug(rtwdev, RTW89_DBG_BTC, "[BTC] wl_info phy_now=%d\n", phy_now);
+       rtw89_debug(rtwdev, RTW89_DBG_BTC,
+                   "[BTC] rlink cnt_2g=%d cnt_5g=%d\n", cnt_2g, cnt_5g);
 
        if (wl_rinfo->dbcc_en != rtwdev->dbcc_en) {
                wl_rinfo->dbcc_chg = 1;
index 02afeb3acce469927a08bf81d45dd2c638345c06..5aef7fa378788c5d219c3ed19259aff3f4c67ddf 100644 (file)
@@ -3026,24 +3026,54 @@ static void rtw89_pci_declaim_device(struct rtw89_dev *rtwdev,
        pci_disable_device(pdev);
 }
 
-static void rtw89_pci_cfg_dac(struct rtw89_dev *rtwdev)
+static bool rtw89_pci_chip_is_manual_dac(struct rtw89_dev *rtwdev)
 {
-       struct rtw89_pci *rtwpci = (struct rtw89_pci *)rtwdev->priv;
        const struct rtw89_chip_info *chip = rtwdev->chip;
 
-       if (!rtwpci->enable_dac)
-               return;
-
        switch (chip->chip_id) {
        case RTL8852A:
        case RTL8852B:
        case RTL8851B:
        case RTL8852BT:
-               break;
+               return true;
        default:
-               return;
+               return false;
+       }
+}
+
+static bool rtw89_pci_is_dac_compatible_bridge(struct rtw89_dev *rtwdev)
+{
+       struct rtw89_pci *rtwpci = (struct rtw89_pci *)rtwdev->priv;
+       struct pci_dev *bridge = pci_upstream_bridge(rtwpci->pdev);
+
+       if (!rtw89_pci_chip_is_manual_dac(rtwdev))
+               return true;
+
+       if (!bridge)
+               return false;
+
+       switch (bridge->vendor) {
+       case PCI_VENDOR_ID_INTEL:
+               return true;
+       case PCI_VENDOR_ID_ASMEDIA:
+               if (bridge->device == 0x2806)
+                       return true;
+               break;
        }
 
+       return false;
+}
+
+static void rtw89_pci_cfg_dac(struct rtw89_dev *rtwdev)
+{
+       struct rtw89_pci *rtwpci = (struct rtw89_pci *)rtwdev->priv;
+
+       if (!rtwpci->enable_dac)
+               return;
+
+       if (!rtw89_pci_chip_is_manual_dac(rtwdev))
+               return;
+
        rtw89_pci_config_byte_set(rtwdev, RTW89_PCIE_L1_CTRL, RTW89_PCIE_BIT_EN_64BITS);
 }
 
@@ -3061,6 +3091,9 @@ static int rtw89_pci_setup_mapping(struct rtw89_dev *rtwdev,
                goto err;
        }
 
+       if (!rtw89_pci_is_dac_compatible_bridge(rtwdev))
+               goto no_dac;
+
        ret = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(36));
        if (!ret) {
                rtwpci->enable_dac = true;
@@ -3073,6 +3106,7 @@ static int rtw89_pci_setup_mapping(struct rtw89_dev *rtwdev,
                        goto err_release_regions;
                }
        }
+no_dac:
 
        resource_len = pci_resource_len(pdev, bar_id);
        rtwpci->mmap = pci_iomap(pdev, bar_id, resource_len);
index f0e528abb1b46f6becbfc73ab3fb7ce5a5ce05cf..3f424f14de4ec265be1512139cd1fad6e66c620d 100644 (file)
@@ -763,7 +763,7 @@ static const struct rhashtable_params hwsim_rht_params = {
 };
 
 struct hwsim_radiotap_hdr {
-       struct ieee80211_radiotap_header hdr;
+       struct ieee80211_radiotap_header_fixed hdr;
        __le64 rt_tsft;
        u8 rt_flags;
        u8 rt_rate;
@@ -772,7 +772,7 @@ struct hwsim_radiotap_hdr {
 } __packed;
 
 struct hwsim_radiotap_ack_hdr {
-       struct ieee80211_radiotap_header hdr;
+       struct ieee80211_radiotap_header_fixed hdr;
        u8 rt_flags;
        u8 pad;
        __le16 rt_channel;
index a8a94edf2a707a6e60fb5ffc181109d5ca43a068..9ae10f65f2af0b6346b5e5dc77f1056569e5fde9 100644 (file)
@@ -17,7 +17,7 @@
 #include <linux/workqueue.h>
 #include <linux/module.h>
 #include <net/mac80211.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #include "zd_def.h"
 #include "zd_mac.h"
index 26ca719fa0de4393621e8de113b7c5eeea088056..5dcb9a84a12e35962c9ac1be8c31d4bbb4a67c28 100644 (file)
@@ -823,17 +823,17 @@ static int bam_dmux_probe(struct platform_device *pdev)
        ret = devm_request_threaded_irq(dev, pc_ack_irq, NULL, bam_dmux_pc_ack_irq,
                                        IRQF_ONESHOT, NULL, dmux);
        if (ret)
-               return ret;
+               goto err_disable_pm;
 
        ret = devm_request_threaded_irq(dev, dmux->pc_irq, NULL, bam_dmux_pc_irq,
                                        IRQF_ONESHOT, NULL, dmux);
        if (ret)
-               return ret;
+               goto err_disable_pm;
 
        ret = irq_get_irqchip_state(dmux->pc_irq, IRQCHIP_STATE_LINE_LEVEL,
                                    &dmux->pc_state);
        if (ret)
-               return ret;
+               goto err_disable_pm;
 
        /* Check if remote finished initialization before us */
        if (dmux->pc_state) {
@@ -844,6 +844,11 @@ static int bam_dmux_probe(struct platform_device *pdev)
        }
 
        return 0;
+
+err_disable_pm:
+       pm_runtime_disable(dev);
+       pm_runtime_dont_use_autosuspend(dev);
+       return ret;
 }
 
 static void bam_dmux_remove(struct platform_device *pdev)
index 17431f1b1a0c0e61d67cdb52b2b2db5b15140efc..65a7ed4d67660d1b12c8619089f2e3b2504d8aa5 100644 (file)
@@ -1038,7 +1038,7 @@ static const struct nla_policy wwan_rtnl_policy[IFLA_WWAN_MAX + 1] = {
 
 static struct rtnl_link_ops wwan_rtnl_link_ops __read_mostly = {
        .kind = "wwan",
-       .maxtype = __IFLA_WWAN_MAX,
+       .maxtype = IFLA_WWAN_MAX,
        .alloc = wwan_rtnl_alloc,
        .validate = wwan_rtnl_validate,
        .newlink = wwan_rtnl_newlink,
index e83f65596a88a0d514b9d5d8c08e805883c721a9..93094418fd247ef1f92f74688cb42e29c2df9b70 100644 (file)
@@ -6,7 +6,7 @@
  */
 
 #include <linux/module.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include <linux/firmware.h>
 #include <linux/nfc.h>
 #include <net/nfc/nci.h>
index 119bf305c642850cf5ac4dea28469287e1963457..381b5bb754779c0b4b13d79db77c95f39a99bdae 100644 (file)
@@ -13,7 +13,7 @@
 #include <linux/completion.h>
 #include <linux/firmware.h>
 #include <linux/nfc.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #include "nxp-nci.h"
 
index a8aced0b801004754a109568b5030c8061bdcedc..049662ffdf972982d79ee8242a88cfb0a078cb13 100644 (file)
@@ -19,7 +19,7 @@
 #include <linux/module.h>
 #include <linux/nfc.h>
 #include <linux/gpio/consumer.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #include <net/nfc/nfc.h>
 
index e2a6575b9ff7f8d55aaec1f683b93e703844a2dd..a0dfb3f98d5a9f5810dec64cfba8526ea405e460 100644 (file)
@@ -17,7 +17,7 @@
 #include <linux/firmware.h>
 #include <linux/gpio/consumer.h>
 
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #include <net/nfc/hci.h>
 #include <net/nfc/llc.h>
index a3455f1d67fae20268a0e9e02a4c5c34ff054afe..9b7126e1a19d9eafdf0fd0643a63f4954f8adb75 100644 (file)
@@ -8,7 +8,7 @@
 #include <linux/base64.h>
 #include <linux/prandom.h>
 #include <linux/scatterlist.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include <crypto/hash.h>
 #include <crypto/dh.h>
 #include <linux/nvme.h>
index 371e14f0a20392d9e43ed45084f6a8f04dc87949..5ea0e21709da3753432a3401c40627c12436ffb5 100644 (file)
@@ -6,7 +6,7 @@
 #include <linux/crc32.h>
 #include <linux/base64.h>
 #include <linux/prandom.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include <crypto/hash.h>
 #include <crypto/dh.h>
 #include "nvme.h"
index ba6508455e185fc6a3331580a5b61bc9c4b7a922..b149b638453f7082fe0af88d2a918345f00791bf 100644 (file)
@@ -22,7 +22,7 @@
 #include <linux/nvme_ioctl.h>
 #include <linux/pm_qos.h>
 #include <linux/ratelimit.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #include "nvme.h"
 #include "fabrics.h"
@@ -91,6 +91,17 @@ module_param(apst_secondary_latency_tol_us, ulong, 0644);
 MODULE_PARM_DESC(apst_secondary_latency_tol_us,
        "secondary APST latency tolerance in us");
 
+/*
+ * Older kernels didn't enable protection information if it was at an offset.
+ * Newer kernels do, so it breaks reads on the upgrade if such formats were
+ * used in prior kernels since the metadata written did not contain a valid
+ * checksum.
+ */
+static bool disable_pi_offsets = false;
+module_param(disable_pi_offsets, bool, 0444);
+MODULE_PARM_DESC(disable_pi_offsets,
+       "disable protection information if it has an offset");
+
 /*
  * nvme_wq - hosts nvme related works that are not reset or delete
  * nvme_reset_wq - hosts nvme reset works
@@ -1292,14 +1303,12 @@ static void nvme_queue_keep_alive_work(struct nvme_ctrl *ctrl)
        queue_delayed_work(nvme_wq, &ctrl->ka_work, delay);
 }
 
-static enum rq_end_io_ret nvme_keep_alive_end_io(struct request *rq,
-                                                blk_status_t status)
+static void nvme_keep_alive_finish(struct request *rq,
+               blk_status_t status, struct nvme_ctrl *ctrl)
 {
-       struct nvme_ctrl *ctrl = rq->end_io_data;
-       unsigned long flags;
-       bool startka = false;
        unsigned long rtt = jiffies - (rq->deadline - rq->timeout);
        unsigned long delay = nvme_keep_alive_work_period(ctrl);
+       enum nvme_ctrl_state state = nvme_ctrl_state(ctrl);
 
        /*
         * Subtract off the keepalive RTT so nvme_keep_alive_work runs
@@ -1313,25 +1322,17 @@ static enum rq_end_io_ret nvme_keep_alive_end_io(struct request *rq,
                delay = 0;
        }
 
-       blk_mq_free_request(rq);
-
        if (status) {
                dev_err(ctrl->device,
                        "failed nvme_keep_alive_end_io error=%d\n",
                                status);
-               return RQ_END_IO_NONE;
+               return;
        }
 
        ctrl->ka_last_check_time = jiffies;
        ctrl->comp_seen = false;
-       spin_lock_irqsave(&ctrl->lock, flags);
-       if (ctrl->state == NVME_CTRL_LIVE ||
-           ctrl->state == NVME_CTRL_CONNECTING)
-               startka = true;
-       spin_unlock_irqrestore(&ctrl->lock, flags);
-       if (startka)
+       if (state == NVME_CTRL_LIVE || state == NVME_CTRL_CONNECTING)
                queue_delayed_work(nvme_wq, &ctrl->ka_work, delay);
-       return RQ_END_IO_NONE;
 }
 
 static void nvme_keep_alive_work(struct work_struct *work)
@@ -1340,6 +1341,7 @@ static void nvme_keep_alive_work(struct work_struct *work)
                        struct nvme_ctrl, ka_work);
        bool comp_seen = ctrl->comp_seen;
        struct request *rq;
+       blk_status_t status;
 
        ctrl->ka_last_check_time = jiffies;
 
@@ -1362,9 +1364,9 @@ static void nvme_keep_alive_work(struct work_struct *work)
        nvme_init_request(rq, &ctrl->ka_cmd);
 
        rq->timeout = ctrl->kato * HZ;
-       rq->end_io = nvme_keep_alive_end_io;
-       rq->end_io_data = ctrl;
-       blk_execute_rq_nowait(rq, false);
+       status = blk_execute_rq(rq, false);
+       nvme_keep_alive_finish(rq, status, ctrl);
+       blk_mq_free_request(rq);
 }
 
 static void nvme_start_keep_alive(struct nvme_ctrl *ctrl)
@@ -1399,17 +1401,30 @@ static void nvme_update_keep_alive(struct nvme_ctrl *ctrl,
        nvme_start_keep_alive(ctrl);
 }
 
-/*
- * In NVMe 1.0 the CNS field was just a binary controller or namespace
- * flag, thus sending any new CNS opcodes has a big chance of not working.
- * Qemu unfortunately had that bug after reporting a 1.1 version compliance
- * (but not for any later version).
- */
-static bool nvme_ctrl_limited_cns(struct nvme_ctrl *ctrl)
+static bool nvme_id_cns_ok(struct nvme_ctrl *ctrl, u8 cns)
 {
-       if (ctrl->quirks & NVME_QUIRK_IDENTIFY_CNS)
-               return ctrl->vs < NVME_VS(1, 2, 0);
-       return ctrl->vs < NVME_VS(1, 1, 0);
+       /*
+        * The CNS field occupies a full byte starting with NVMe 1.2
+        */
+       if (ctrl->vs >= NVME_VS(1, 2, 0))
+               return true;
+
+       /*
+        * NVMe 1.1 expanded the CNS value to two bits, which means values
+        * larger than that could get truncated and treated as an incorrect
+        * value.
+        *
+        * Qemu implemented 1.0 behavior for controllers claiming 1.1
+        * compliance, so they need to be quirked here.
+        */
+       if (ctrl->vs >= NVME_VS(1, 1, 0) &&
+           !(ctrl->quirks & NVME_QUIRK_IDENTIFY_CNS))
+               return cns <= 3;
+
+       /*
+        * NVMe 1.0 used a single bit for the CNS value.
+        */
+       return cns <= 1;
 }
 
 static int nvme_identify_ctrl(struct nvme_ctrl *dev, struct nvme_id_ctrl **id)
@@ -1922,8 +1937,12 @@ static void nvme_configure_metadata(struct nvme_ctrl *ctrl,
 
        if (head->pi_size && head->ms >= head->pi_size)
                head->pi_type = id->dps & NVME_NS_DPS_PI_MASK;
-       if (!(id->dps & NVME_NS_DPS_PI_FIRST))
-               info->pi_offset = head->ms - head->pi_size;
+       if (!(id->dps & NVME_NS_DPS_PI_FIRST)) {
+               if (disable_pi_offsets)
+                       head->pi_type = 0;
+               else
+                       info->pi_offset = head->ms - head->pi_size;
+       }
 
        if (ctrl->ops->flags & NVME_F_FABRICS) {
                /*
@@ -2458,8 +2477,13 @@ int nvme_enable_ctrl(struct nvme_ctrl *ctrl)
        else
                ctrl->ctrl_config = NVME_CC_CSS_NVM;
 
-       if (ctrl->cap & NVME_CAP_CRMS_CRWMS && ctrl->cap & NVME_CAP_CRMS_CRIMS)
-               ctrl->ctrl_config |= NVME_CC_CRIME;
+       /*
+        * Setting CRIME results in CSTS.RDY before the media is ready. This
+        * makes it possible for media related commands to return the error
+        * NVME_SC_ADMIN_COMMAND_MEDIA_NOT_READY. Until the driver is
+        * restructured to handle retries, disable CC.CRIME.
+        */
+       ctrl->ctrl_config &= ~NVME_CC_CRIME;
 
        ctrl->ctrl_config |= (NVME_CTRL_PAGE_SHIFT - 12) << NVME_CC_MPS_SHIFT;
        ctrl->ctrl_config |= NVME_CC_AMS_RR | NVME_CC_SHN_NONE;
@@ -2489,10 +2513,7 @@ int nvme_enable_ctrl(struct nvme_ctrl *ctrl)
                 * devices are known to get this wrong. Use the larger of the
                 * two values.
                 */
-               if (ctrl->ctrl_config & NVME_CC_CRIME)
-                       ready_timeout = NVME_CRTO_CRIMT(crto);
-               else
-                       ready_timeout = NVME_CRTO_CRWMT(crto);
+               ready_timeout = NVME_CRTO_CRWMT(crto);
 
                if (ready_timeout < timeout)
                        dev_warn_once(ctrl->device, "bad crto:%x cap:%llx\n",
@@ -3111,7 +3132,7 @@ static int nvme_init_non_mdts_limits(struct nvme_ctrl *ctrl)
                ctrl->max_zeroes_sectors = 0;
 
        if (ctrl->subsys->subtype != NVME_NQN_NVME ||
-           nvme_ctrl_limited_cns(ctrl) ||
+           !nvme_id_cns_ok(ctrl, NVME_ID_CNS_CS_CTRL) ||
            test_bit(NVME_CTRL_SKIP_ID_CNS_CS, &ctrl->flags))
                return 0;
 
@@ -4207,7 +4228,7 @@ static void nvme_scan_work(struct work_struct *work)
        }
 
        mutex_lock(&ctrl->scan_lock);
-       if (nvme_ctrl_limited_cns(ctrl)) {
+       if (!nvme_id_cns_ok(ctrl, NVME_ID_CNS_NS_ACTIVE_LIST)) {
                nvme_scan_ns_sequential(ctrl);
        } else {
                /*
index 8df73a0b3980cde3f150b66672db7965eda9a328..89a1a1043d63b05577896035a3cc67e584f02770 100644 (file)
@@ -6,7 +6,7 @@
 
 #include <linux/hwmon.h>
 #include <linux/units.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #include "nvme.h"
 
index b9b79ccfabf8ab17f7fe4370779d4e2f79822802..a96976b22fa7968c110a73199ac3cbabcb8bc755 100644 (file)
@@ -421,10 +421,13 @@ static enum rq_end_io_ret nvme_uring_cmd_end_io(struct request *req,
        struct io_uring_cmd *ioucmd = req->end_io_data;
        struct nvme_uring_cmd_pdu *pdu = nvme_uring_cmd_pdu(ioucmd);
 
-       if (nvme_req(req)->flags & NVME_REQ_CANCELLED)
+       if (nvme_req(req)->flags & NVME_REQ_CANCELLED) {
                pdu->status = -EINTR;
-       else
+       } else {
                pdu->status = nvme_req(req)->status;
+               if (!pdu->status)
+                       pdu->status = blk_status_to_errno(err);
+       }
        pdu->result = le64_to_cpu(nvme_req(req)->result.u64);
 
        /*
index 48e7a8906d01211e44cd90bfc33e56fbb7c7b972..6a15873055b9513f827709ad780bc7e18f75e439 100644 (file)
@@ -431,7 +431,6 @@ static bool nvme_available_path(struct nvme_ns_head *head)
                case NVME_CTRL_LIVE:
                case NVME_CTRL_RESETTING:
                case NVME_CTRL_CONNECTING:
-                       /* fallthru */
                        return true;
                default:
                        break;
@@ -580,6 +579,20 @@ static int nvme_add_ns_head_cdev(struct nvme_ns_head *head)
        return ret;
 }
 
+static void nvme_partition_scan_work(struct work_struct *work)
+{
+       struct nvme_ns_head *head =
+               container_of(work, struct nvme_ns_head, partition_scan_work);
+
+       if (WARN_ON_ONCE(!test_and_clear_bit(GD_SUPPRESS_PART_SCAN,
+                                            &head->disk->state)))
+               return;
+
+       mutex_lock(&head->disk->open_mutex);
+       bdev_disk_changed(head->disk, false);
+       mutex_unlock(&head->disk->open_mutex);
+}
+
 static void nvme_requeue_work(struct work_struct *work)
 {
        struct nvme_ns_head *head =
@@ -606,6 +619,7 @@ int nvme_mpath_alloc_disk(struct nvme_ctrl *ctrl, struct nvme_ns_head *head)
        bio_list_init(&head->requeue_list);
        spin_lock_init(&head->requeue_lock);
        INIT_WORK(&head->requeue_work, nvme_requeue_work);
+       INIT_WORK(&head->partition_scan_work, nvme_partition_scan_work);
 
        /*
         * Add a multipath node if the subsystems supports multiple controllers.
@@ -629,6 +643,16 @@ int nvme_mpath_alloc_disk(struct nvme_ctrl *ctrl, struct nvme_ns_head *head)
                return PTR_ERR(head->disk);
        head->disk->fops = &nvme_ns_head_ops;
        head->disk->private_data = head;
+
+       /*
+        * We need to suppress the partition scan from occuring within the
+        * controller's scan_work context. If a path error occurs here, the IO
+        * will wait until a path becomes available or all paths are torn down,
+        * but that action also occurs within scan_work, so it would deadlock.
+        * Defer the partion scan to a different context that does not block
+        * scan_work.
+        */
+       set_bit(GD_SUPPRESS_PART_SCAN, &head->disk->state);
        sprintf(head->disk->disk_name, "nvme%dn%d",
                        ctrl->subsys->instance, head->instance);
        return 0;
@@ -655,6 +679,7 @@ static void nvme_mpath_set_live(struct nvme_ns *ns)
                        return;
                }
                nvme_add_ns_head_cdev(head);
+               kblockd_schedule_work(&head->partition_scan_work);
        }
 
        mutex_lock(&head->lock);
@@ -974,14 +999,14 @@ void nvme_mpath_shutdown_disk(struct nvme_ns_head *head)
                return;
        if (test_and_clear_bit(NVME_NSHEAD_DISK_LIVE, &head->flags)) {
                nvme_cdev_del(&head->cdev, &head->cdev_device);
+               /*
+                * requeue I/O after NVME_NSHEAD_DISK_LIVE has been cleared
+                * to allow multipath to fail all I/O.
+                */
+               synchronize_srcu(&head->srcu);
+               kblockd_schedule_work(&head->requeue_work);
                del_gendisk(head->disk);
        }
-       /*
-        * requeue I/O after NVME_NSHEAD_DISK_LIVE has been cleared
-        * to allow multipath to fail all I/O.
-        */
-       synchronize_srcu(&head->srcu);
-       kblockd_schedule_work(&head->requeue_work);
 }
 
 void nvme_mpath_remove_disk(struct nvme_ns_head *head)
@@ -991,6 +1016,7 @@ void nvme_mpath_remove_disk(struct nvme_ns_head *head)
        /* make sure all pending bios are cleaned up */
        kblockd_schedule_work(&head->requeue_work);
        flush_work(&head->requeue_work);
+       flush_work(&head->partition_scan_work);
        put_disk(head->disk);
 }
 
index 313a4f978a2cf3ce00fb3e9918fb17729a39ce90..093cb423f536bebb2272bf7985b0413f9c2b0237 100644 (file)
@@ -494,6 +494,7 @@ struct nvme_ns_head {
        struct bio_list         requeue_list;
        spinlock_t              requeue_lock;
        struct work_struct      requeue_work;
+       struct work_struct      partition_scan_work;
        struct mutex            lock;
        unsigned long           flags;
 #define NVME_NSHEAD_DISK_LIVE  0
index 7990c3f22ecf660a5c82825cf1d372dc180e34f7..4b9fda0b1d9a33af4d7030b72532835b205e9cbb 100644 (file)
@@ -2506,17 +2506,29 @@ static unsigned int nvme_pci_nr_maps(struct nvme_dev *dev)
        return 1;
 }
 
-static void nvme_pci_update_nr_queues(struct nvme_dev *dev)
+static bool nvme_pci_update_nr_queues(struct nvme_dev *dev)
 {
        if (!dev->ctrl.tagset) {
                nvme_alloc_io_tag_set(&dev->ctrl, &dev->tagset, &nvme_mq_ops,
                                nvme_pci_nr_maps(dev), sizeof(struct nvme_iod));
-               return;
+               return true;
+       }
+
+       /* Give up if we are racing with nvme_dev_disable() */
+       if (!mutex_trylock(&dev->shutdown_lock))
+               return false;
+
+       /* Check if nvme_dev_disable() has been executed already */
+       if (!dev->online_queues) {
+               mutex_unlock(&dev->shutdown_lock);
+               return false;
        }
 
        blk_mq_update_nr_hw_queues(&dev->tagset, dev->online_queues - 1);
        /* free previously allocated queues that are no longer usable */
        nvme_free_queues(dev, dev->online_queues);
+       mutex_unlock(&dev->shutdown_lock);
+       return true;
 }
 
 static int nvme_pci_enable(struct nvme_dev *dev)
@@ -2797,7 +2809,8 @@ static void nvme_reset_work(struct work_struct *work)
                nvme_dbbuf_set(dev);
                nvme_unquiesce_io_queues(&dev->ctrl);
                nvme_wait_freeze(&dev->ctrl);
-               nvme_pci_update_nr_queues(dev);
+               if (!nvme_pci_update_nr_queues(dev))
+                       goto out;
                nvme_unfreeze(&dev->ctrl);
        } else {
                dev_warn(dev->ctrl.device, "IO queues lost\n");
index 7347ddf85f00b350ed04531bbceb428e0c78da7d..dc7922f226004f60c165556066284bdd4f60c7f6 100644 (file)
@@ -5,7 +5,7 @@
  */
 #include <linux/blkdev.h>
 #include <linux/pr.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #include "nvme.h"
 
index c8fd0e8f023754f5403ca1f574373276b566a43a..24a2759798d01e9f38928b1662bf0aeedd8cc284 100644 (file)
@@ -18,7 +18,7 @@
 #include <linux/mutex.h>
 #include <linux/scatterlist.h>
 #include <linux/nvme.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #include <rdma/ib_verbs.h>
 #include <rdma/rdma_cm.h>
index 89c44413c59394e57d315c9f1cbc9a333dff74af..3e416af2659f19f6a7377319d45ac368a6dedf38 100644 (file)
@@ -2644,10 +2644,11 @@ static int nvme_tcp_get_address(struct nvme_ctrl *ctrl, char *buf, int size)
 
        len = nvmf_get_address(ctrl, buf, size);
 
+       if (!test_bit(NVME_TCP_Q_LIVE, &queue->flags))
+               return len;
+
        mutex_lock(&queue->queue_lock);
 
-       if (!test_bit(NVME_TCP_Q_LIVE, &queue->flags))
-               goto done;
        ret = kernel_getsockname(queue->sock, (struct sockaddr *)&src_addr);
        if (ret > 0) {
                if (len > 0)
@@ -2655,7 +2656,7 @@ static int nvme_tcp_get_address(struct nvme_ctrl *ctrl, char *buf, int size)
                len += scnprintf(buf + len, size - len, "%ssrc_addr=%pISc\n",
                                (len) ? "," : "", &src_addr);
        }
-done:
+
        mutex_unlock(&queue->queue_lock);
 
        return len;
index 0288315f00502872eb8d3a3a6b47027f32059042..87c437fc070d12632bdec27f912d1f16fd6f7e3c 100644 (file)
@@ -4,7 +4,7 @@
  * Copyright (c) 2018 Johannes Thumshirn, SUSE Linux GmbH
  */
 
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include "trace.h"
 
 static const char *nvme_trace_delete_sq(struct trace_seq *p, u8 *cdw10)
index 954d4c0747704d5ee451c8d146b7bfc2897e05ca..081f0473cd9ea12020f1a37d973ca6f2091748b0 100644 (file)
@@ -9,7 +9,7 @@
 #include <linux/part_stat.h>
 
 #include <generated/utsrelease.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include "nvmet.h"
 
 u32 nvmet_get_log_page_len(struct nvme_command *cmd)
index 7897d02c681daa9ecef1bd83656693a14b877d1a..b47d675232d2d8171e429f3a913b1cdf015df480 100644 (file)
@@ -15,7 +15,7 @@
 #include <linux/ctype.h>
 #include <linux/random.h>
 #include <linux/nvme-auth.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #include "nvmet.h"
 
@@ -115,6 +115,7 @@ int nvmet_setup_dhgroup(struct nvmet_ctrl *ctrl, u8 dhgroup_id)
                        pr_debug("%s: ctrl %d failed to generate private key, err %d\n",
                                 __func__, ctrl->cntlid, ret);
                        kfree_sensitive(ctrl->dh_key);
+                       ctrl->dh_key = NULL;
                        return ret;
                }
                ctrl->dh_keysize = crypto_kpp_maxsize(ctrl->dh_tfm);
index e32790d8fc260c8a2146bc925a974aa4cea90e04..a9d112d34d4f434ff0ba3310435581cb49285cbb 100644 (file)
@@ -265,6 +265,13 @@ static void nvme_loop_destroy_admin_queue(struct nvme_loop_ctrl *ctrl)
 {
        if (!test_and_clear_bit(NVME_LOOP_Q_LIVE, &ctrl->queues[0].flags))
                return;
+       /*
+        * It's possible that some requests might have been added
+        * after admin queue is stopped/quiesced. So now start the
+        * queue to flush these requests to the completion.
+        */
+       nvme_unquiesce_admin_queue(&ctrl->ctrl);
+
        nvmet_sq_destroy(&ctrl->queues[0].nvme_sq);
        nvme_remove_admin_tag_set(&ctrl->ctrl);
 }
@@ -297,6 +304,12 @@ static void nvme_loop_destroy_io_queues(struct nvme_loop_ctrl *ctrl)
                nvmet_sq_destroy(&ctrl->queues[i].nvme_sq);
        }
        ctrl->ctrl.queue_count = 1;
+       /*
+        * It's possible that some requests might have been added
+        * after io queue is stopped/quiesced. So now start the
+        * queue to flush these requests to the completion.
+        */
+       nvme_unquiesce_io_queues(&ctrl->ctrl);
 }
 
 static int nvme_loop_init_io_queues(struct nvme_loop_ctrl *ctrl)
index 24d0e2418d2e6beff7e28e5f45306bc8825f0845..0f9b280c438d98dbcf1d3dd65d25709ebdb4e575 100644 (file)
@@ -535,10 +535,6 @@ u16 nvmet_parse_passthru_admin_cmd(struct nvmet_req *req)
                break;
        case nvme_admin_identify:
                switch (req->cmd->identify.cns) {
-               case NVME_ID_CNS_CTRL:
-                       req->execute = nvmet_passthru_execute_cmd;
-                       req->p.use_workqueue = true;
-                       return NVME_SC_SUCCESS;
                case NVME_ID_CNS_CS_CTRL:
                        switch (req->cmd->identify.csi) {
                        case NVME_CSI_ZNS:
@@ -547,7 +543,9 @@ u16 nvmet_parse_passthru_admin_cmd(struct nvmet_req *req)
                                return NVME_SC_SUCCESS;
                        }
                        return NVME_SC_INVALID_OPCODE | NVME_STATUS_DNR;
+               case NVME_ID_CNS_CTRL:
                case NVME_ID_CNS_NS:
+               case NVME_ID_CNS_NS_DESC_LIST:
                        req->execute = nvmet_passthru_execute_cmd;
                        req->p.use_workqueue = true;
                        return NVME_SC_SUCCESS;
index 1b6264fa580399a616a7fcc7a6074efc313a0f54..1afd93026f9bf0481de5910e84502078d5912766 100644 (file)
@@ -16,7 +16,7 @@
 #include <linux/string.h>
 #include <linux/wait.h>
 #include <linux/inet.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #include <rdma/ib_verbs.h>
 #include <rdma/rdma_cm.h>
@@ -39,6 +39,8 @@
 
 #define NVMET_RDMA_BACKLOG 128
 
+#define NVMET_RDMA_DISCRETE_RSP_TAG            -1
+
 struct nvmet_rdma_srq;
 
 struct nvmet_rdma_cmd {
@@ -75,7 +77,7 @@ struct nvmet_rdma_rsp {
        u32                     invalidate_rkey;
 
        struct list_head        wait_list;
-       struct list_head        free_list;
+       int                     tag;
 };
 
 enum nvmet_rdma_queue_state {
@@ -98,8 +100,7 @@ struct nvmet_rdma_queue {
        struct nvmet_sq         nvme_sq;
 
        struct nvmet_rdma_rsp   *rsps;
-       struct list_head        free_rsps;
-       spinlock_t              rsps_lock;
+       struct sbitmap          rsp_tags;
        struct nvmet_rdma_cmd   *cmds;
 
        struct work_struct      release_work;
@@ -172,7 +173,8 @@ static void nvmet_rdma_queue_disconnect(struct nvmet_rdma_queue *queue);
 static void nvmet_rdma_free_rsp(struct nvmet_rdma_device *ndev,
                                struct nvmet_rdma_rsp *r);
 static int nvmet_rdma_alloc_rsp(struct nvmet_rdma_device *ndev,
-                               struct nvmet_rdma_rsp *r);
+                               struct nvmet_rdma_rsp *r,
+                               int tag);
 
 static const struct nvmet_fabrics_ops nvmet_rdma_ops;
 
@@ -210,15 +212,12 @@ static inline bool nvmet_rdma_need_data_out(struct nvmet_rdma_rsp *rsp)
 static inline struct nvmet_rdma_rsp *
 nvmet_rdma_get_rsp(struct nvmet_rdma_queue *queue)
 {
-       struct nvmet_rdma_rsp *rsp;
-       unsigned long flags;
+       struct nvmet_rdma_rsp *rsp = NULL;
+       int tag;
 
-       spin_lock_irqsave(&queue->rsps_lock, flags);
-       rsp = list_first_entry_or_null(&queue->free_rsps,
-                               struct nvmet_rdma_rsp, free_list);
-       if (likely(rsp))
-               list_del(&rsp->free_list);
-       spin_unlock_irqrestore(&queue->rsps_lock, flags);
+       tag = sbitmap_get(&queue->rsp_tags);
+       if (tag >= 0)
+               rsp = &queue->rsps[tag];
 
        if (unlikely(!rsp)) {
                int ret;
@@ -226,13 +225,12 @@ nvmet_rdma_get_rsp(struct nvmet_rdma_queue *queue)
                rsp = kzalloc(sizeof(*rsp), GFP_KERNEL);
                if (unlikely(!rsp))
                        return NULL;
-               ret = nvmet_rdma_alloc_rsp(queue->dev, rsp);
+               ret = nvmet_rdma_alloc_rsp(queue->dev, rsp,
+                               NVMET_RDMA_DISCRETE_RSP_TAG);
                if (unlikely(ret)) {
                        kfree(rsp);
                        return NULL;
                }
-
-               rsp->allocated = true;
        }
 
        return rsp;
@@ -241,17 +239,13 @@ nvmet_rdma_get_rsp(struct nvmet_rdma_queue *queue)
 static inline void
 nvmet_rdma_put_rsp(struct nvmet_rdma_rsp *rsp)
 {
-       unsigned long flags;
-
-       if (unlikely(rsp->allocated)) {
+       if (unlikely(rsp->tag == NVMET_RDMA_DISCRETE_RSP_TAG)) {
                nvmet_rdma_free_rsp(rsp->queue->dev, rsp);
                kfree(rsp);
                return;
        }
 
-       spin_lock_irqsave(&rsp->queue->rsps_lock, flags);
-       list_add_tail(&rsp->free_list, &rsp->queue->free_rsps);
-       spin_unlock_irqrestore(&rsp->queue->rsps_lock, flags);
+       sbitmap_clear_bit(&rsp->queue->rsp_tags, rsp->tag);
 }
 
 static void nvmet_rdma_free_inline_pages(struct nvmet_rdma_device *ndev,
@@ -404,7 +398,7 @@ static void nvmet_rdma_free_cmds(struct nvmet_rdma_device *ndev,
 }
 
 static int nvmet_rdma_alloc_rsp(struct nvmet_rdma_device *ndev,
-               struct nvmet_rdma_rsp *r)
+               struct nvmet_rdma_rsp *r, int tag)
 {
        /* NVMe CQE / RDMA SEND */
        r->req.cqe = kmalloc(sizeof(*r->req.cqe), GFP_KERNEL);
@@ -432,6 +426,7 @@ static int nvmet_rdma_alloc_rsp(struct nvmet_rdma_device *ndev,
        r->read_cqe.done = nvmet_rdma_read_data_done;
        /* Data Out / RDMA WRITE */
        r->write_cqe.done = nvmet_rdma_write_data_done;
+       r->tag = tag;
 
        return 0;
 
@@ -454,21 +449,23 @@ nvmet_rdma_alloc_rsps(struct nvmet_rdma_queue *queue)
 {
        struct nvmet_rdma_device *ndev = queue->dev;
        int nr_rsps = queue->recv_queue_size * 2;
-       int ret = -EINVAL, i;
+       int ret = -ENOMEM, i;
+
+       if (sbitmap_init_node(&queue->rsp_tags, nr_rsps, -1, GFP_KERNEL,
+                       NUMA_NO_NODE, false, true))
+               goto out;
 
        queue->rsps = kcalloc(nr_rsps, sizeof(struct nvmet_rdma_rsp),
                        GFP_KERNEL);
        if (!queue->rsps)
-               goto out;
+               goto out_free_sbitmap;
 
        for (i = 0; i < nr_rsps; i++) {
                struct nvmet_rdma_rsp *rsp = &queue->rsps[i];
 
-               ret = nvmet_rdma_alloc_rsp(ndev, rsp);
+               ret = nvmet_rdma_alloc_rsp(ndev, rsp, i);
                if (ret)
                        goto out_free;
-
-               list_add_tail(&rsp->free_list, &queue->free_rsps);
        }
 
        return 0;
@@ -477,6 +474,8 @@ out_free:
        while (--i >= 0)
                nvmet_rdma_free_rsp(ndev, &queue->rsps[i]);
        kfree(queue->rsps);
+out_free_sbitmap:
+       sbitmap_free(&queue->rsp_tags);
 out:
        return ret;
 }
@@ -489,6 +488,7 @@ static void nvmet_rdma_free_rsps(struct nvmet_rdma_queue *queue)
        for (i = 0; i < nr_rsps; i++)
                nvmet_rdma_free_rsp(ndev, &queue->rsps[i]);
        kfree(queue->rsps);
+       sbitmap_free(&queue->rsp_tags);
 }
 
 static int nvmet_rdma_post_recv(struct nvmet_rdma_device *ndev,
@@ -1447,8 +1447,6 @@ nvmet_rdma_alloc_queue(struct nvmet_rdma_device *ndev,
        INIT_LIST_HEAD(&queue->rsp_wait_list);
        INIT_LIST_HEAD(&queue->rsp_wr_wait_list);
        spin_lock_init(&queue->rsp_wr_wait_lock);
-       INIT_LIST_HEAD(&queue->free_rsps);
-       spin_lock_init(&queue->rsps_lock);
        INIT_LIST_HEAD(&queue->queue_list);
 
        queue->idx = ida_alloc(&nvmet_rdma_queue_ida, GFP_KERNEL);
index 8d1806a828879a28b8ef1ba25e0437d695c0f56b..9a3548179a8e364c8b85a9b4b4b6a692eb032c05 100644 (file)
@@ -4,7 +4,7 @@
  * Copyright (c) 2018 Johannes Thumshirn, SUSE Linux GmbH
  */
 
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include "trace.h"
 
 static const char *nvmet_trace_admin_identify(struct trace_seq *p, u8 *cdw10)
index 287d6c91bb3721fb592f758fb917fe34cdfc28da..7b3ed5a382aaa562a07a13c30111fbda602f46a9 100644 (file)
 #include <kunit/test.h>
 #include <kunit/resource.h>
 
+#include "of_private.h"
+
+/**
+ * of_root_kunit_skip() - Skip test if the root node isn't populated
+ * @test: test to skip if the root node isn't populated
+ */
+void of_root_kunit_skip(struct kunit *test)
+{
+       if (IS_ENABLED(CONFIG_ARM64) && IS_ENABLED(CONFIG_ACPI) && !of_root)
+               kunit_skip(test, "arm64+acpi doesn't populate a root node");
+}
+EXPORT_SYMBOL_GPL(of_root_kunit_skip);
+
 #if defined(CONFIG_OF_OVERLAY) && defined(CONFIG_OF_EARLY_FLATTREE)
 
 static void of_overlay_fdt_apply_kunit_exit(void *ovcs_id)
@@ -36,6 +49,8 @@ int of_overlay_fdt_apply_kunit(struct kunit *test, void *overlay_fdt,
        int ret;
        int *copy_id;
 
+       of_root_kunit_skip(test);
+
        copy_id = kunit_kmalloc(test, sizeof(*copy_id), GFP_KERNEL);
        if (!copy_id)
                return -ENOMEM;
index 04aa2a91f851acd9b2da47c5b53edb025b9a1f8f..c235d6c909a16a75b8e2995282abf5473532eb53 100644 (file)
@@ -42,6 +42,9 @@ extern raw_spinlock_t devtree_lock;
 extern struct list_head aliases_lookup;
 extern struct kset *of_kset;
 
+struct kunit;
+extern void of_root_kunit_skip(struct kunit *test);
+
 #if defined(CONFIG_OF_DYNAMIC)
 extern int of_property_notify(int action, struct device_node *np,
                              struct property *prop, struct property *old_prop);
index c85a258bc6ae64b83b76fdfb99533914b02ff8b3..b0557ded838fdf70f0b679c31ead38f501371304 100644 (file)
@@ -7,6 +7,8 @@
 
 #include <kunit/test.h>
 
+#include "of_private.h"
+
 /*
  * Test that the root node "/" can be found by path.
  */
@@ -36,6 +38,7 @@ static struct kunit_case of_dtb_test_cases[] = {
 
 static int of_dtb_test_init(struct kunit *test)
 {
+       of_root_kunit_skip(test);
        if (!IS_ENABLED(CONFIG_OF_EARLY_FLATTREE))
                kunit_skip(test, "requires CONFIG_OF_EARLY_FLATTREE");
 
index 19a292cdeee31b1d00c952034abdeb1baaba0fd9..1f76d50fb16a5237989341b9ca50a7664a7b31be 100644 (file)
@@ -11,6 +11,8 @@
 #include <kunit/of.h>
 #include <kunit/test.h>
 
+#include "of_private.h"
+
 static const char * const kunit_node_name = "kunit-test";
 static const char * const kunit_compatible = "test,empty";
 
@@ -62,6 +64,7 @@ static void of_overlay_apply_kunit_cleanup(struct kunit *test)
        struct device *dev;
        struct device_node *np;
 
+       of_root_kunit_skip(test);
        if (!IS_ENABLED(CONFIG_OF_EARLY_FLATTREE))
                kunit_skip(test, "requires CONFIG_OF_EARLY_FLATTREE for root node");
 
@@ -73,7 +76,7 @@ static void of_overlay_apply_kunit_cleanup(struct kunit *test)
 
        np = of_find_node_by_name(NULL, kunit_node_name);
        KUNIT_ASSERT_NOT_ERR_OR_NULL(test, np);
-       of_node_put_kunit(test, np);
+       of_node_put_kunit(&fake, np);
 
        pdev = of_find_device_by_node(np);
        KUNIT_ASSERT_NOT_ERR_OR_NULL(test, pdev);
index 494f8860220d97fc690ebab5ed3b7f5f04f22d73..3aa18737470fa2af4528efe3885eed01005f0ca8 100644 (file)
@@ -2630,8 +2630,10 @@ int dev_pm_opp_set_config(struct device *dev, struct dev_pm_opp_config *config)
 
        /* Attach genpds */
        if (config->genpd_names) {
-               if (config->required_devs)
+               if (config->required_devs) {
+                       ret = -EINVAL;
                        goto err;
+               }
 
                ret = _opp_attach_genpd(opp_table, dev, config->genpd_names,
                                        config->virt_devs);
index 3ef486cd3d6d57bb9b5caa1f8e7d7b932fa0dc6b..3880460e67f25a7d8708a734c6f4d9e6c363c726 100644 (file)
@@ -51,12 +51,12 @@ static int do_active_device(const struct ctl_table *table, int write,
        
        for (dev = port->devices; dev ; dev = dev->next) {
                if(dev == port->cad) {
-                       len += snprintf(buffer, sizeof(buffer), "%s\n", dev->name);
+                       len += scnprintf(buffer, sizeof(buffer), "%s\n", dev->name);
                }
        }
 
        if(!len) {
-               len += snprintf(buffer, sizeof(buffer), "%s\n", "none");
+               len += scnprintf(buffer, sizeof(buffer), "%s\n", "none");
        }
 
        if (len > *lenp)
@@ -87,19 +87,19 @@ static int do_autoprobe(const struct ctl_table *table, int write,
        }
        
        if ((str = info->class_name) != NULL)
-               len += snprintf (buffer + len, sizeof(buffer) - len, "CLASS:%s;\n", str);
+               len += scnprintf (buffer + len, sizeof(buffer) - len, "CLASS:%s;\n", str);
 
        if ((str = info->model) != NULL)
-               len += snprintf (buffer + len, sizeof(buffer) - len, "MODEL:%s;\n", str);
+               len += scnprintf (buffer + len, sizeof(buffer) - len, "MODEL:%s;\n", str);
 
        if ((str = info->mfr) != NULL)
-               len += snprintf (buffer + len, sizeof(buffer) - len, "MANUFACTURER:%s;\n", str);
+               len += scnprintf (buffer + len, sizeof(buffer) - len, "MANUFACTURER:%s;\n", str);
 
        if ((str = info->description) != NULL)
-               len += snprintf (buffer + len, sizeof(buffer) - len, "DESCRIPTION:%s;\n", str);
+               len += scnprintf (buffer + len, sizeof(buffer) - len, "DESCRIPTION:%s;\n", str);
 
        if ((str = info->cmdset) != NULL)
-               len += snprintf (buffer + len, sizeof(buffer) - len, "COMMAND SET:%s;\n", str);
+               len += scnprintf (buffer + len, sizeof(buffer) - len, "COMMAND SET:%s;\n", str);
 
        if (len > *lenp)
                len = *lenp;
@@ -128,7 +128,7 @@ static int do_hardware_base_addr(const struct ctl_table *table, int write,
        if (write) /* permissions prevent this anyway */
                return -EACCES;
 
-       len += snprintf (buffer, sizeof(buffer), "%lu\t%lu\n", port->base, port->base_hi);
+       len += scnprintf (buffer, sizeof(buffer), "%lu\t%lu\n", port->base, port->base_hi);
 
        if (len > *lenp)
                len = *lenp;
@@ -155,7 +155,7 @@ static int do_hardware_irq(const struct ctl_table *table, int write,
        if (write) /* permissions prevent this anyway */
                return -EACCES;
 
-       len += snprintf (buffer, sizeof(buffer), "%d\n", port->irq);
+       len += scnprintf (buffer, sizeof(buffer), "%d\n", port->irq);
 
        if (len > *lenp)
                len = *lenp;
@@ -182,7 +182,7 @@ static int do_hardware_dma(const struct ctl_table *table, int write,
        if (write) /* permissions prevent this anyway */
                return -EACCES;
 
-       len += snprintf (buffer, sizeof(buffer), "%d\n", port->dma);
+       len += scnprintf (buffer, sizeof(buffer), "%d\n", port->dma);
 
        if (len > *lenp)
                len = *lenp;
@@ -213,7 +213,7 @@ static int do_hardware_modes(const struct ctl_table *table, int write,
 #define printmode(x)                                                   \
 do {                                                                   \
        if (port->modes & PARPORT_MODE_##x)                             \
-               len += snprintf(buffer + len, sizeof(buffer) - len, "%s%s", f++ ? "," : "", #x); \
+               len += scnprintf(buffer + len, sizeof(buffer) - len, "%s%s", f++ ? "," : "", #x); \
 } while (0)
                int f = 0;
                printmode(PCSPP);
index 7d85c04fbba2ae937f15f2a5b481e002ce81f334..225a6cd2e9ca3bf9885a1b8a9e4d7ad4b291fc8e 100644 (file)
@@ -1067,8 +1067,15 @@ static void pci_std_enable_acs(struct pci_dev *dev, struct pci_acs *caps)
 static void pci_enable_acs(struct pci_dev *dev)
 {
        struct pci_acs caps;
+       bool enable_acs = false;
        int pos;
 
+       /* If an iommu is present we start with kernel default caps */
+       if (pci_acs_enable) {
+               if (pci_dev_specific_enable_acs(dev))
+                       enable_acs = true;
+       }
+
        pos = dev->acs_cap;
        if (!pos)
                return;
@@ -1077,11 +1084,8 @@ static void pci_enable_acs(struct pci_dev *dev)
        pci_read_config_word(dev, pos + PCI_ACS_CTRL, &caps.ctrl);
        caps.fw_ctrl = caps.ctrl;
 
-       /* If an iommu is present we start with kernel default caps */
-       if (pci_acs_enable) {
-               if (pci_dev_specific_enable_acs(dev))
-                       pci_std_enable_acs(dev, &caps);
-       }
+       if (enable_acs)
+               pci_std_enable_acs(dev, &caps);
 
        /*
         * Always apply caps from the command line, even if there is no iommu.
index 4f68414c308609ed99e675a943e73a8f6ae0dfe3..f1615805f5b078b4e1238a4f825bed23ac1fe3ea 100644 (file)
@@ -3105,7 +3105,9 @@ int pci_host_probe(struct pci_host_bridge *bridge)
        list_for_each_entry(child, &bus->children, node)
                pcie_bus_configure_settings(child);
 
+       pci_lock_rescan_remove();
        pci_bus_add_devices(bus);
+       pci_unlock_rescan_remove();
        return 0;
 }
 EXPORT_SYMBOL_GPL(pci_host_probe);
index a23a4312574b9f4b61c1a0d59bcea5f89ac33670..0e6bd47671c2e6e37863ccc59fbfbb97a5d1be39 100644 (file)
@@ -6,9 +6,9 @@
 #include <linux/device.h>
 #include <linux/mod_devicetable.h>
 #include <linux/module.h>
-#include <linux/of.h>
 #include <linux/pci-pwrctl.h>
 #include <linux/platform_device.h>
+#include <linux/property.h>
 #include <linux/pwrseq/consumer.h>
 #include <linux/slab.h>
 #include <linux/types.h>
@@ -18,6 +18,40 @@ struct pci_pwrctl_pwrseq_data {
        struct pwrseq_desc *pwrseq;
 };
 
+struct pci_pwrctl_pwrseq_pdata {
+       const char *target;
+       /*
+        * Called before doing anything else to perform device-specific
+        * verification between requesting the power sequencing handle.
+        */
+       int (*validate_device)(struct device *dev);
+};
+
+static int pci_pwrctl_pwrseq_qcm_wcn_validate_device(struct device *dev)
+{
+       /*
+        * Old device trees for some platforms already define wifi nodes for
+        * the WCN family of chips since before power sequencing was added
+        * upstream.
+        *
+        * These nodes don't consume the regulator outputs from the PMU, and
+        * if we allow this driver to bind to one of such "incomplete" nodes,
+        * we'll see a kernel log error about the indefinite probe deferral.
+        *
+        * Check the existence of the regulator supply that exists on all
+        * WCN models before moving forward.
+        */
+       if (!device_property_present(dev, "vddaon-supply"))
+               return -ENODEV;
+
+       return 0;
+}
+
+static const struct pci_pwrctl_pwrseq_pdata pci_pwrctl_pwrseq_qcom_wcn_pdata = {
+       .target = "wlan",
+       .validate_device = pci_pwrctl_pwrseq_qcm_wcn_validate_device,
+};
+
 static void devm_pci_pwrctl_pwrseq_power_off(void *data)
 {
        struct pwrseq_desc *pwrseq = data;
@@ -27,15 +61,26 @@ static void devm_pci_pwrctl_pwrseq_power_off(void *data)
 
 static int pci_pwrctl_pwrseq_probe(struct platform_device *pdev)
 {
+       const struct pci_pwrctl_pwrseq_pdata *pdata;
        struct pci_pwrctl_pwrseq_data *data;
        struct device *dev = &pdev->dev;
        int ret;
 
+       pdata = device_get_match_data(dev);
+       if (!pdata || !pdata->target)
+               return -EINVAL;
+
+       if (pdata->validate_device) {
+               ret = pdata->validate_device(dev);
+               if (ret)
+                       return ret;
+       }
+
        data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL);
        if (!data)
                return -ENOMEM;
 
-       data->pwrseq = devm_pwrseq_get(dev, of_device_get_match_data(dev));
+       data->pwrseq = devm_pwrseq_get(dev, pdata->target);
        if (IS_ERR(data->pwrseq))
                return dev_err_probe(dev, PTR_ERR(data->pwrseq),
                                     "Failed to get the power sequencer\n");
@@ -64,17 +109,17 @@ static const struct of_device_id pci_pwrctl_pwrseq_of_match[] = {
        {
                /* ATH11K in QCA6390 package. */
                .compatible = "pci17cb,1101",
-               .data = "wlan",
+               .data = &pci_pwrctl_pwrseq_qcom_wcn_pdata,
        },
        {
                /* ATH11K in WCN6855 package. */
                .compatible = "pci17cb,1103",
-               .data = "wlan",
+               .data = &pci_pwrctl_pwrseq_qcom_wcn_pdata,
        },
        {
                /* ATH12K in WCN7850 package. */
                .compatible = "pci17cb,1107",
-               .data = "wlan",
+               .data = &pci_pwrctl_pwrseq_qcom_wcn_pdata,
        },
        { }
 };
index 485a642b9304da15059009986b46475415ace75a..e4300f5f304f3ca55a657fd25a1fa5ed919737a7 100644 (file)
@@ -9,7 +9,7 @@
 #include <linux/delay.h>
 #include <linux/export.h>
 #include <linux/sched/signal.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include "pci.h"
 
 #define PCI_VPD_LRDT_TAG_SIZE          3
index 948b763dc451ec179253c570d9f53f7534cfb7a3..d018f36f3a8935630f88a627d7241025f24b5be9 100644 (file)
@@ -23,7 +23,7 @@
 #include <linux/io.h>
 #include <linux/security.h>
 #include <asm/byteorder.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #include <pcmcia/ss.h>
 #include <pcmcia/cisreg.h>
index de7046e6b9c49d366de9bcd7f7ba0c2b061c836e..b93eb6f43b98faa71fde7efe87d8880e9b122cdf 100644 (file)
@@ -2,7 +2,7 @@
 // Copyright (c) 2012-2017 ASPEED Technology Inc.
 // Copyright (c) 2018-2021 Intel Corporation
 
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #include <linux/bitfield.h>
 #include <linux/clk.h>
index 8d6dd7b6b5595359473e21c0f092b20f8a6b8a9e..87eefe66743f2de13791f58f475364e916e704bb 100644 (file)
@@ -8,7 +8,7 @@
 #include <linux/slab.h>
 #include <linux/types.h>
 
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #include "internal.h"
 
index 04487ad7fba0b538508ba3ae3628e437d2dc1b53..93c8e0fdb5898587e89115c10587d69380da19ec 100644 (file)
@@ -22,13 +22,13 @@ static int pmu_legacy_ctr_get_idx(struct perf_event *event)
        struct perf_event_attr *attr = &event->attr;
 
        if (event->attr.type != PERF_TYPE_HARDWARE)
-               return -EOPNOTSUPP;
+               return -ENOENT;
        if (attr->config == PERF_COUNT_HW_CPU_CYCLES)
                return RISCV_PMU_LEGACY_CYCLE;
        else if (attr->config == PERF_COUNT_HW_INSTRUCTIONS)
                return RISCV_PMU_LEGACY_INSTRET;
        else
-               return -EOPNOTSUPP;
+               return -ENOENT;
 }
 
 /* For legacy config & counter index are same */
index 5c39fbd8ed04d6fc222ae8ee0c0945f407ee9d86..391ca1422caec15b69b747bc8bcaef3c9faead23 100644 (file)
@@ -309,7 +309,7 @@ static void pmu_sbi_check_event(struct sbi_pmu_event_data *edata)
                          ret.value, 0x1, SBI_PMU_STOP_FLAG_RESET, 0, 0, 0);
        } else if (ret.error == SBI_ERR_NOT_SUPPORTED) {
                /* This event cannot be monitored by any counter */
-               edata->event_idx = -EINVAL;
+               edata->event_idx = -ENOENT;
        }
 }
 
@@ -556,7 +556,7 @@ static int pmu_sbi_event_map(struct perf_event *event, u64 *econfig)
                }
                break;
        default:
-               ret = -EINVAL;
+               ret = -ENOENT;
                break;
        }
 
index 2101d30bd66c15908fc74f929529cdbf3fc8adef..14c26c023590e6d01b439b1d67835448f044c3c9 100644 (file)
@@ -46,6 +46,7 @@ config PINCTRL_INTEL_PLATFORM
          of Intel PCH pins and using them as GPIOs. Currently the following
          Intel SoCs / platforms require this to be functional:
          - Lunar Lake
+         - Panther Lake
 
 config PINCTRL_ALDERLAKE
        tristate "Intel Alder Lake pinctrl and GPIO driver"
index 4a19ab3b4ba74364116061ef8d3d4022b4485a54..016a9f62eecc10353fb763c78b6d8bfec241443d 100644 (file)
@@ -90,7 +90,6 @@ static int intel_platform_pinctrl_prepare_community(struct device *dev,
                                                    struct intel_community *community,
                                                    struct intel_platform_pins *pins)
 {
-       struct fwnode_handle *child;
        struct intel_padgroup *gpps;
        unsigned int group;
        size_t ngpps;
@@ -131,7 +130,7 @@ static int intel_platform_pinctrl_prepare_community(struct device *dev,
                return -ENOMEM;
 
        group = 0;
-       device_for_each_child_node(dev, child) {
+       device_for_each_child_node_scoped(dev, child) {
                struct intel_padgroup *gpp = &gpps[group];
 
                gpp->reg_num = group;
@@ -159,7 +158,7 @@ static int intel_platform_pinctrl_prepare_soc_data(struct device *dev,
        int ret;
 
        /* Version 1.0 of the specification assumes only a single community per device node */
-       ncommunities = 1,
+       ncommunities = 1;
        communities = devm_kcalloc(dev, ncommunities, sizeof(*communities), GFP_KERNEL);
        if (!communities)
                return -ENOMEM;
index 1fa00a23534a9d6864a74b86ee362490014ba1da..59c4e7c6cddea1277ebb75f02172e60e18e03e1e 100644 (file)
@@ -218,7 +218,7 @@ static int ma35_pinctrl_dt_node_to_map_func(struct pinctrl_dev *pctldev,
        }
 
        map_num += grp->npins;
-       new_map = devm_kcalloc(pctldev->dev, map_num, sizeof(*new_map), GFP_KERNEL);
+       new_map = kcalloc(map_num, sizeof(*new_map), GFP_KERNEL);
        if (!new_map)
                return -ENOMEM;
 
index 3751c7de37aa9fc48c5708742db9e908ca2b61e3..f861e63f41152109f53bb6479f390c2e414d3fd6 100644 (file)
@@ -474,6 +474,9 @@ static int apple_gpio_pinctrl_probe(struct platform_device *pdev)
        for (i = 0; i < npins; i++) {
                pins[i].number = i;
                pins[i].name = devm_kasprintf(&pdev->dev, GFP_KERNEL, "PIN%u", i);
+               if (!pins[i].name)
+                       return -ENOMEM;
+
                pins[i].drv_data = pctl;
                pin_names[i] = pins[i].name;
                pin_nums[i] = i;
index b5e1c467625ba0f6794bfbf280225d608de17f0f..1374f30166bc3b679b5c7e418f4848e7ca1cf40a 100644 (file)
@@ -987,8 +987,10 @@ static int aw9523_probe(struct i2c_client *client)
        lockdep_set_subclass(&awi->i2c_lock, i2c_adapter_depth(client->adapter));
 
        pdesc = devm_kzalloc(dev, sizeof(*pdesc), GFP_KERNEL);
-       if (!pdesc)
-               return -ENOMEM;
+       if (!pdesc) {
+               ret = -ENOMEM;
+               goto err_disable_vregs;
+       }
 
        ret = aw9523_hw_init(awi);
        if (ret)
index be9b8c01016708fa2e7810ad66f898a97705abac..d1ab8450ea93eb3dd07c3271257845fee4d82cb6 100644 (file)
@@ -1955,21 +1955,21 @@ static void ocelot_irq_handler(struct irq_desc *desc)
        unsigned int reg = 0, irq, i;
        unsigned long irqs;
 
+       chained_irq_enter(parent_chip, desc);
+
        for (i = 0; i < info->stride; i++) {
                regmap_read(info->map, id_reg + 4 * i, &reg);
                if (!reg)
                        continue;
 
-               chained_irq_enter(parent_chip, desc);
-
                irqs = reg;
 
                for_each_set_bit(irq, &irqs,
                                 min(32U, info->desc->npins - 32 * i))
                        generic_handle_domain_irq(chip->irq.domain, irq + 32 * i);
-
-               chained_irq_exit(parent_chip, desc);
        }
+
+       chained_irq_exit(parent_chip, desc);
 }
 
 static int ocelot_gpiochip_register(struct platform_device *pdev,
index d18fc5aa84f750e6b1de610baffc6ecc4073ab23..57f2674e75d688c61309ea2f76b0537ce3c530b9 100644 (file)
@@ -221,7 +221,7 @@ static int cv1800_pctrl_dt_node_to_map(struct pinctrl_dev *pctldev,
        if (!grpnames)
                return -ENOMEM;
 
-       map = devm_kcalloc(dev, ngroups * 2, sizeof(*map), GFP_KERNEL);
+       map = kcalloc(ngroups * 2, sizeof(*map), GFP_KERNEL);
        if (!map)
                return -ENOMEM;
 
index a8673739871d811c736312a2b6d841cede7738f7..5b7fa77c118436f2a94ef92b92ef8d5ede0c81ff 100644 (file)
@@ -1374,10 +1374,15 @@ static int stm32_gpiolib_register_bank(struct stm32_pinctrl *pctl, struct fwnode
 
        for (i = 0; i < npins; i++) {
                stm32_pin = stm32_pctrl_get_desc_pin_from_gpio(pctl, bank, i);
-               if (stm32_pin && stm32_pin->pin.name)
+               if (stm32_pin && stm32_pin->pin.name) {
                        names[i] = devm_kasprintf(dev, GFP_KERNEL, "%s", stm32_pin->pin.name);
-               else
+                       if (!names[i]) {
+                               err = -ENOMEM;
+                               goto err_clk;
+                       }
+               } else {
                        names[i] = NULL;
+               }
        }
 
        bank->gpio_chip.names = (const char * const *)names;
index dbb1cce139654a444c71a3b6979413de08360f10..2df42406430db7bd9ae5dcca6aace88c3bf3baa0 100644 (file)
@@ -1,7 +1,7 @@
 // SPDX-License-Identifier: GPL-2.0-only
 /* Copyright (c) 2024, Nikita Travkin <[email protected]> */
 
-#include <asm-generic/unaligned.h>
+#include <linux/unaligned.h>
 #include <drm/drm_bridge.h>
 #include <linux/bits.h>
 #include <linux/delay.h>
index 73f75958e15c10f07f7495c2aa43f7f33ec53caa..5c9a53dffcf95a27cd99ba6be1a2cec851601e10 100644 (file)
@@ -10,7 +10,7 @@
 #include <linux/platform_data/cros_ec_commands.h>
 #include <linux/platform_data/cros_ec_proto.h>
 #include <linux/slab.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #include "cros_ec_trace.h"
 
index 7ca9895a0065eec94abf07cdfa28d28dc587df81..3f281996a6863c015746891a5eeb45912f11f740 100644 (file)
@@ -5,7 +5,7 @@
 
 #include <kunit/test.h>
 
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #include <linux/platform_data/cros_ec_commands.h>
 #include <linux/platform_data/cros_ec_proto.h>
index c2bf4c95c5d2c981bab6ae2f562713bd80c40f3f..9951c8db04da06597e7579f3b46aa6321133c73c 100644 (file)
@@ -8,7 +8,7 @@
 #include <linux/platform_data/wilco-ec.h>
 #include <linux/string.h>
 #include <linux/types.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 /* Operation code; what the EC should do with the property */
 enum ec_property_op {
index 91da56a704c7bc040c5c62ad03d2991eb1cf238c..88e208d458820a9aeef14a1ae9b0354417d694f2 100644 (file)
@@ -20,7 +20,7 @@
 #include <linux/sysfs.h>
 #include <linux/types.h>
 #include <linux/workqueue.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #include <linux/turris-omnia-mcu-interface.h>
 #include "turris-omnia-mcu.h"
index fed0d357fea39c0adb8eb1ee440ffaaae984a976..57ef5d3500436ab048e188267772c94ee7678b98 100644 (file)
@@ -18,7 +18,7 @@
 #include <linux/watchdog.h>
 #include <linux/workqueue.h>
 #include <asm/byteorder.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 struct i2c_client;
 struct rtc_device;
index 438873e060986d3f57172872e96ba9770e97ba13..80aa568a0759e876c924e27ad85c24e7e4c38345 100644 (file)
@@ -8,7 +8,7 @@
 #ifndef _SURFACE_AGGREGATOR_SSH_MSGB_H
 #define _SURFACE_AGGREGATOR_SSH_MSGB_H
 
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include <linux/types.h>
 
 #include <linux/surface_aggregator/controller.h>
index d726b1a8631999f74f6ad621ec410ae7060ba258..6081b0146d5f21be5b1876fcb224a92742e659a7 100644 (file)
@@ -5,7 +5,7 @@
  * Copyright (C) 2019-2022 Maximilian Luz <[email protected]>
  */
 
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include <linux/atomic.h>
 #include <linux/error-injection.h>
 #include <linux/jiffies.h>
index a6f6686943652732effccab6515abc71e33d8a68..6cfda85d3b33b109cf611f31413a4a8933ec3f9d 100644 (file)
@@ -5,7 +5,7 @@
  * Copyright (C) 2019-2022 Maximilian Luz <[email protected]>
  */
 
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include <linux/compiler.h>
 #include <linux/device.h>
 #include <linux/types.h>
index 90634dcacabf28f77613b97c54986c62a65788ba..879ca9ee7ff683dc701eb8032c737ea24983a173 100644 (file)
@@ -5,7 +5,7 @@
  * Copyright (C) 2019-2022 Maximilian Luz <[email protected]>
  */
 
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include <linux/atomic.h>
 #include <linux/completion.h>
 #include <linux/error-injection.h>
index 55cc61bba1da6e45d70c2149ef67bae70e08288e..caf7d3cb5d8b7943ba5fd2091faa89f8407778de 100644 (file)
@@ -13,7 +13,7 @@
 
 #include <linux/surface_aggregator/serial_hub.h>
 
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include <linux/tracepoint.h>
 
 TRACE_DEFINE_ENUM(SSH_FRAME_TYPE_DATA_SEQ);
index 4c0f92562a794fd72737ba255918b99c8bb31886..1ee5239269ae03a8a265d17cfcca3454217e6852 100644 (file)
@@ -40,7 +40,7 @@
 #include <linux/slab.h>
 #include <linux/types.h>
 #include <linux/uuid.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #define SURFACE_3_POLL_INTERVAL                (2 * HZ)
 #define SURFACE_3_STRLEN               10
index 20f3870915d2b7f7b9d14fb24023b23b7abb131a..14a9d8a267cbbecc9d92be896a147eb03431dbe7 100644 (file)
@@ -11,7 +11,7 @@
  * Copyright (C) 2019-2022 Maximilian Luz <[email protected]>
  */
 
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include <linux/acpi.h>
 #include <linux/delay.h>
 #include <linux/jiffies.h>
index c0a1a5869246edde0e5e65f1e1b75a019fe1ced0..ffa36ed9289700964e256e5add2be3c343041f75 100644 (file)
@@ -5,7 +5,7 @@
  * Copyright (C) 2022 Maximilian Luz <[email protected]>
  */
 
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include <linux/input.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
index 3de864bc66108dbf3df01022f20a4ed6c096a508..08db878f1d7d46ff234971186eca032e229cecba 100644 (file)
@@ -6,7 +6,7 @@
  * Copyright (C) 2021-2022 Maximilian Luz <[email protected]>
  */
 
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/platform_profile.h>
index b441d8ca72d3f775aa1eb1ec3ad5f1302f619671..ca4670d0dc678c9f999e71c9ceb8cc23f5197357 100644 (file)
@@ -26,7 +26,7 @@
 #include <linux/module.h>
 #include <linux/pm.h>
 #include <linux/workqueue.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 static bool fnlock;
 module_param(fnlock, bool, 0644);
index 7a48220b4f5a66f4d188af4fdfb5301a8f902f41..abdca3f05c5c15b99450414256d6e30ff5c0eaf9 100644 (file)
@@ -3908,6 +3908,16 @@ static int platform_profile_setup(struct asus_wmi *asus)
        if (!asus->throttle_thermal_policy_dev)
                return 0;
 
+       /*
+        * We need to set the default thermal profile during probe or otherwise
+        * the system will often remain in silent mode, causing low performance.
+        */
+       err = throttle_thermal_policy_set_default(asus);
+       if (err < 0) {
+               pr_warn("Failed to set default thermal profile\n");
+               return err;
+       }
+
        dev_info(dev, "Using throttle_thermal_policy for platform_profile support\n");
 
        asus->platform_profile_handler.profile_get = asus_wmi_platform_profile_get;
index a3cd0505f2820113461dc74117eddff3b4c2e6ac..5671bd0deee7d1602284ba1b47cfa223a23b9c5f 100644 (file)
@@ -2391,12 +2391,18 @@ static struct attribute *dell_battery_attrs[] = {
 };
 ATTRIBUTE_GROUPS(dell_battery);
 
+static bool dell_battery_supported(struct power_supply *battery)
+{
+       /* We currently only support the primary battery */
+       return strcmp(battery->desc->name, "BAT0") == 0;
+}
+
 static int dell_battery_add(struct power_supply *battery,
                struct acpi_battery_hook *hook)
 {
-       /* this currently only supports the primary battery */
-       if (strcmp(battery->desc->name, "BAT0") != 0)
-               return -ENODEV;
+       /* Return 0 instead of an error to avoid being unloaded */
+       if (!dell_battery_supported(battery))
+               return 0;
 
        return device_add_groups(&battery->dev, dell_battery_groups);
 }
@@ -2404,6 +2410,9 @@ static int dell_battery_add(struct power_supply *battery,
 static int dell_battery_remove(struct power_supply *battery,
                struct acpi_battery_hook *hook)
 {
+       if (!dell_battery_supported(battery))
+               return 0;
+
        device_remove_groups(&battery->dev, dell_battery_groups);
        return 0;
 }
index 502783a7adb118322d2b8c158b56b3c1ac268776..24fd7ffadda95263e6af1e73da32586f4fde53a7 100644 (file)
@@ -264,6 +264,15 @@ static const struct key_entry dell_wmi_keymap_type_0010[] = {
        /*Speaker Mute*/
        { KE_KEY, 0x109, { KEY_MUTE} },
 
+       /* S2Idle screen off */
+       { KE_IGNORE, 0x120, { KEY_RESERVED }},
+
+       /* Leaving S4 or S2Idle suspend */
+       { KE_IGNORE, 0x130, { KEY_RESERVED }},
+
+       /* Entering S2Idle suspend */
+       { KE_IGNORE, 0x140, { KEY_RESERVED }},
+
        /* Mic mute */
        { KE_KEY, 0x150, { KEY_MICMUTE } },
 
index 0b2299f7a2de5aacab3847e1956c62e71fbbc6be..e75cd6e1efe6ac886b7c6b7c80768d31edc25d8e 100644 (file)
@@ -31,7 +31,7 @@
 
 #include <acpi/battery.h>
 
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #define DRIVER_NAME    "dell-wmi-ddv"
 
index 9def7983d7d66ad4aa7d084915014f87b9480447..40ddc6eb75624e713dc4d2f7e92bc5f63fa4fde8 100644 (file)
@@ -521,6 +521,7 @@ static int __init sysman_init(void)
        int ret = 0;
 
        if (!dmi_find_device(DMI_DEV_TYPE_OEM_STRING, "Dell System", NULL) &&
+           !dmi_find_device(DMI_DEV_TYPE_OEM_STRING, "Alienware", NULL) &&
            !dmi_find_device(DMI_DEV_TYPE_OEM_STRING, "www.dell.com", NULL)) {
                pr_err("Unable to run on non-Dell system\n");
                return -ENODEV;
index 9d9c07f44ff61c001eafdc5c6def48b1402cbdfa..e7878558fd9090140e6de7c6ce192e8419eb5306 100644 (file)
@@ -295,8 +295,6 @@ const struct pmc_reg_map adl_reg_map = {
        .ppfear_buckets = CNP_PPFEAR_NUM_ENTRIES,
        .pm_cfg_offset = CNP_PMC_PM_CFG_OFFSET,
        .pm_read_disable_bit = CNP_PMC_READ_DISABLE_BIT,
-       .acpi_pm_tmr_ctl_offset = SPT_PMC_ACPI_PM_TMR_CTL_OFFSET,
-       .acpi_pm_tmr_disable_bit = SPT_PMC_BIT_ACPI_PM_TMR_DISABLE,
        .ltr_ignore_max = ADL_NUM_IP_IGN_ALLOWED,
        .lpm_num_modes = ADL_LPM_NUM_MODES,
        .lpm_num_maps = ADL_LPM_NUM_MAPS,
index 513c02670c5aa97fde095f59eb123e51eccab9f2..dd72974bf71e2abe248a1f1b671a45756ad61288 100644 (file)
@@ -200,8 +200,6 @@ const struct pmc_reg_map cnp_reg_map = {
        .ppfear_buckets = CNP_PPFEAR_NUM_ENTRIES,
        .pm_cfg_offset = CNP_PMC_PM_CFG_OFFSET,
        .pm_read_disable_bit = CNP_PMC_READ_DISABLE_BIT,
-       .acpi_pm_tmr_ctl_offset = SPT_PMC_ACPI_PM_TMR_CTL_OFFSET,
-       .acpi_pm_tmr_disable_bit = SPT_PMC_BIT_ACPI_PM_TMR_DISABLE,
        .ltr_ignore_max = CNP_NUM_IP_IGN_ALLOWED,
        .etr3_offset = ETR3_OFFSET,
 };
index ecb47f8b4f834dd9df622ec37b596a85dc0ff26f..4e9c8c96c8cceedc195093035d045a9f55aed3f1 100644 (file)
@@ -11,7 +11,6 @@
 
 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
 
-#include <linux/acpi_pmtmr.h>
 #include <linux/bitfield.h>
 #include <linux/debugfs.h>
 #include <linux/delay.h>
@@ -1258,39 +1257,6 @@ static bool pmc_core_is_pson_residency_enabled(struct pmc_dev *pmcdev)
        return val == 1;
 }
 
-/*
- * Enable or disable ACPI PM Timer
- *
- * This function is intended to be a callback for ACPI PM suspend/resume event.
- * The ACPI PM Timer is enabled on resume only if it was enabled during suspend.
- */
-static void pmc_core_acpi_pm_timer_suspend_resume(void *data, bool suspend)
-{
-       struct pmc_dev *pmcdev = data;
-       struct pmc *pmc = pmcdev->pmcs[PMC_IDX_MAIN];
-       const struct pmc_reg_map *map = pmc->map;
-       bool enabled;
-       u32 reg;
-
-       if (!map->acpi_pm_tmr_ctl_offset)
-               return;
-
-       guard(mutex)(&pmcdev->lock);
-
-       if (!suspend && !pmcdev->enable_acpi_pm_timer_on_resume)
-               return;
-
-       reg = pmc_core_reg_read(pmc, map->acpi_pm_tmr_ctl_offset);
-       enabled = !(reg & map->acpi_pm_tmr_disable_bit);
-       if (suspend)
-               reg |= map->acpi_pm_tmr_disable_bit;
-       else
-               reg &= ~map->acpi_pm_tmr_disable_bit;
-       pmc_core_reg_write(pmc, map->acpi_pm_tmr_ctl_offset, reg);
-
-       pmcdev->enable_acpi_pm_timer_on_resume = suspend && enabled;
-}
-
 static void pmc_core_dbgfs_unregister(struct pmc_dev *pmcdev)
 {
        debugfs_remove_recursive(pmcdev->dbgfs_dir);
@@ -1486,7 +1452,6 @@ static int pmc_core_probe(struct platform_device *pdev)
        struct pmc_dev *pmcdev;
        const struct x86_cpu_id *cpu_id;
        int (*core_init)(struct pmc_dev *pmcdev);
-       const struct pmc_reg_map *map;
        struct pmc *primary_pmc;
        int ret;
 
@@ -1545,11 +1510,6 @@ static int pmc_core_probe(struct platform_device *pdev)
        pm_report_max_hw_sleep(FIELD_MAX(SLP_S0_RES_COUNTER_MASK) *
                               pmc_core_adjust_slp_s0_step(primary_pmc, 1));
 
-       map = primary_pmc->map;
-       if (map->acpi_pm_tmr_ctl_offset)
-               acpi_pmtmr_register_suspend_resume_callback(pmc_core_acpi_pm_timer_suspend_resume,
-                                                        pmcdev);
-
        device_initialized = true;
        dev_info(&pdev->dev, " initialized\n");
 
@@ -1559,12 +1519,6 @@ static int pmc_core_probe(struct platform_device *pdev)
 static void pmc_core_remove(struct platform_device *pdev)
 {
        struct pmc_dev *pmcdev = platform_get_drvdata(pdev);
-       const struct pmc *pmc = pmcdev->pmcs[PMC_IDX_MAIN];
-       const struct pmc_reg_map *map = pmc->map;
-
-       if (map->acpi_pm_tmr_ctl_offset)
-               acpi_pmtmr_unregister_suspend_resume_callback();
-
        pmc_core_dbgfs_unregister(pmcdev);
        pmc_core_clean_structure(pdev);
 }
index 75fd593a7b0ffd9094aafbe44399f8137e05ca53..b9d3291d0bf2c82ab2e2bcf6f7cca49b844e49cd 100644 (file)
@@ -68,8 +68,6 @@ struct telem_endpoint;
 #define SPT_PMC_LTR_SCC                                0x3A0
 #define SPT_PMC_LTR_ISH                                0x3A4
 
-#define SPT_PMC_ACPI_PM_TMR_CTL_OFFSET         0x18FC
-
 /* Sunrise Point: PGD PFET Enable Ack Status Registers */
 enum ppfear_regs {
        SPT_PMC_XRAM_PPFEAR0A = 0x590,
@@ -150,8 +148,6 @@ enum ppfear_regs {
 #define SPT_PMC_VRIC1_SLPS0LVEN                        BIT(13)
 #define SPT_PMC_VRIC1_XTALSDQDIS               BIT(22)
 
-#define SPT_PMC_BIT_ACPI_PM_TMR_DISABLE                BIT(1)
-
 /* Cannonlake Power Management Controller register offsets */
 #define CNP_PMC_SLPS0_DBG_OFFSET               0x10B4
 #define CNP_PMC_PM_CFG_OFFSET                  0x1818
@@ -355,8 +351,6 @@ struct pmc_reg_map {
        const u8  *lpm_reg_index;
        const u32 pson_residency_offset;
        const u32 pson_residency_counter_step;
-       const u32 acpi_pm_tmr_ctl_offset;
-       const u32 acpi_pm_tmr_disable_bit;
 };
 
 /**
@@ -432,8 +426,6 @@ struct pmc_dev {
        u32 die_c6_offset;
        struct telem_endpoint *punit_ep;
        struct pmc_info *regmap_list;
-
-       bool enable_acpi_pm_timer_on_resume;
 };
 
 enum pmc_index {
index c259c96b7dfdb4a3b8267bfee17d4b3e74091f26..8504154b649f47de9ec94fefb1a48e2b58548472 100644 (file)
@@ -29,7 +29,7 @@
 #define LPM_REG_COUNT          28
 #define LPM_MODE_OFFSET                1
 
-DEFINE_FREE(pmc_core_iounmap, void __iomem *, iounmap(_T));
+DEFINE_FREE(pmc_core_iounmap, void __iomem *, if (_T) iounmap(_T))
 
 static u32 pmc_core_find_guid(struct pmc_info *list, const struct pmc_reg_map *map)
 {
@@ -262,6 +262,8 @@ pmc_core_ssram_get_pmc(struct pmc_dev *pmcdev, int pmc_idx, u32 offset)
 
        ssram_base = ssram_pcidev->resource[0].start;
        tmp_ssram = ioremap(ssram_base, SSRAM_HDR_SIZE);
+       if (!tmp_ssram)
+               return -ENOMEM;
 
        if (pmc_idx != PMC_IDX_MAIN) {
                /*
index cbbd4405446888cd57e3f212e6ae4b47e183b0e0..71b0fd6cb7d840e1b2e9c71f3f8d40dd9d93126e 100644 (file)
@@ -46,8 +46,6 @@ const struct pmc_reg_map icl_reg_map = {
        .ppfear_buckets = ICL_PPFEAR_NUM_ENTRIES,
        .pm_cfg_offset = CNP_PMC_PM_CFG_OFFSET,
        .pm_read_disable_bit = CNP_PMC_READ_DISABLE_BIT,
-       .acpi_pm_tmr_ctl_offset = SPT_PMC_ACPI_PM_TMR_CTL_OFFSET,
-       .acpi_pm_tmr_disable_bit = SPT_PMC_BIT_ACPI_PM_TMR_DISABLE,
        .ltr_ignore_max = ICL_NUM_IP_IGN_ALLOWED,
        .etr3_offset = ETR3_OFFSET,
 };
index 91f2fa728f5c88b5b0e56a77f386d5339e39ad61..c7d15d864039d0265199861316c5911539e10358 100644 (file)
@@ -462,8 +462,6 @@ const struct pmc_reg_map mtl_socm_reg_map = {
        .ppfear_buckets = MTL_SOCM_PPFEAR_NUM_ENTRIES,
        .pm_cfg_offset = CNP_PMC_PM_CFG_OFFSET,
        .pm_read_disable_bit = CNP_PMC_READ_DISABLE_BIT,
-       .acpi_pm_tmr_ctl_offset = SPT_PMC_ACPI_PM_TMR_CTL_OFFSET,
-       .acpi_pm_tmr_disable_bit = SPT_PMC_BIT_ACPI_PM_TMR_DISABLE,
        .lpm_num_maps = ADL_LPM_NUM_MAPS,
        .ltr_ignore_max = MTL_SOCM_NUM_IP_IGN_ALLOWED,
        .lpm_res_counter_step_x2 = TGL_PMC_LPM_RES_COUNTER_STEP_X2,
index 2cd2b3c68e468c41135fbfb9562bf470d7c384fd..ab993a69e33ee204ddc59a246f0ff9e9bed22ff8 100644 (file)
@@ -130,8 +130,6 @@ const struct pmc_reg_map spt_reg_map = {
        .ppfear_buckets = SPT_PPFEAR_NUM_ENTRIES,
        .pm_cfg_offset = SPT_PMC_PM_CFG_OFFSET,
        .pm_read_disable_bit = SPT_PMC_READ_DISABLE_BIT,
-       .acpi_pm_tmr_ctl_offset = SPT_PMC_ACPI_PM_TMR_CTL_OFFSET,
-       .acpi_pm_tmr_disable_bit = SPT_PMC_BIT_ACPI_PM_TMR_DISABLE,
        .ltr_ignore_max = SPT_NUM_IP_IGN_ALLOWED,
        .pm_vric1_offset = SPT_PMC_VRIC1_OFFSET,
 };
index 371b4e30f142636d5019ab8d742cb513b03e8049..e0580de180773c57e6b1c2208d341402e97c64ad 100644 (file)
@@ -197,8 +197,6 @@ const struct pmc_reg_map tgl_reg_map = {
        .ppfear_buckets = ICL_PPFEAR_NUM_ENTRIES,
        .pm_cfg_offset = CNP_PMC_PM_CFG_OFFSET,
        .pm_read_disable_bit = CNP_PMC_READ_DISABLE_BIT,
-       .acpi_pm_tmr_ctl_offset = SPT_PMC_ACPI_PM_TMR_CTL_OFFSET,
-       .acpi_pm_tmr_disable_bit = SPT_PMC_BIT_ACPI_PM_TMR_DISABLE,
        .ltr_ignore_max = TGL_NUM_IP_IGN_ALLOWED,
        .lpm_num_maps = TGL_LPM_NUM_MAPS,
        .lpm_res_counter_step_x2 = TGL_PMC_LPM_RES_COUNTER_STEP_X2,
index 9ad35fefea4781a68fd4e3541973c9c95a186525..1e46e30dae96699d9b1cd4e1dd5fc6d2f8b3edec 100644 (file)
@@ -316,7 +316,9 @@ static struct pci_dev *_isst_if_get_pci_dev(int cpu, int bus_no, int dev, int fn
            cpu >= nr_cpu_ids || cpu >= num_possible_cpus())
                return NULL;
 
-       pkg_id = topology_physical_package_id(cpu);
+       pkg_id = topology_logical_package_id(cpu);
+       if (pkg_id >= topology_max_packages())
+               return NULL;
 
        bus_number = isst_cpu_info[cpu].bus_info[bus_no];
        if (bus_number < 0)
@@ -807,6 +809,7 @@ static const struct x86_cpu_id isst_cpu_ids[] = {
        X86_MATCH_VFM(INTEL_GRANITERAPIDS_X,    SST_HPM_SUPPORTED),
        X86_MATCH_VFM(INTEL_ICELAKE_D,          0),
        X86_MATCH_VFM(INTEL_ICELAKE_X,          0),
+       X86_MATCH_VFM(INTEL_PANTHERCOVE_X,      SST_HPM_SUPPORTED),
        X86_MATCH_VFM(INTEL_SAPPHIRERAPIDS_X,   0),
        X86_MATCH_VFM(INTEL_SKYLAKE_X,          SST_MBOX_SUPPORTED),
        {}
index 4eb02553957cfca8dab0a833c69da2fc4c90a5a9..0609a8320f7ec14c821b8a824e7c82f20c0a6257 100644 (file)
@@ -82,6 +82,7 @@ static const struct x86_cpu_id tpmi_cpu_ids[] = {
        X86_MATCH_VFM(INTEL_ATOM_CRESTMONT_X,   NULL),
        X86_MATCH_VFM(INTEL_ATOM_CRESTMONT,     NULL),
        X86_MATCH_VFM(INTEL_GRANITERAPIDS_D,    NULL),
+       X86_MATCH_VFM(INTEL_PANTHERCOVE_X,      NULL),
        {}
 };
 MODULE_DEVICE_TABLE(x86cpu, tpmi_cpu_ids);
index 436fb91a47db7f56bb125c834298a22a4df74e66..9b5c7f8c79b0ddd410f90593f0d0022f38d6d147 100644 (file)
@@ -22,7 +22,7 @@
 #include <linux/types.h>
 #include <linux/wmi.h>
 
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #define DRIVER_NAME    "msi-wmi-platform"
 
index df496c7e717142dd2f09dbb2deb49fc909e37472..8d540a1c86024ed1eb2cb4edaf943092ad42221a 100644 (file)
@@ -26,7 +26,7 @@
 #include <linux/sysfs.h>
 #include <linux/types.h>
 
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #define DRIVER_NAME    "quickstart"
 
index 1427a9a3900855a822cded14c87af2dc46a6c467..ef572b90e06ba4012f5eecfc7a7e857c5937abea 100644 (file)
@@ -390,8 +390,9 @@ static __init int x86_android_tablet_probe(struct platform_device *pdev)
        for (i = 0; i < pdev_count; i++) {
                pdevs[i] = platform_device_register_full(&dev_info->pdev_info[i]);
                if (IS_ERR(pdevs[i])) {
+                       ret = PTR_ERR(pdevs[i]);
                        x86_android_tablet_remove(pdev);
-                       return PTR_ERR(pdevs[i]);
+                       return ret;
                }
        }
 
@@ -443,8 +444,9 @@ static __init int x86_android_tablet_probe(struct platform_device *pdev)
                                                                  PLATFORM_DEVID_AUTO,
                                                                  &pdata, sizeof(pdata));
                if (IS_ERR(pdevs[pdev_count])) {
+                       ret = PTR_ERR(pdevs[pdev_count]);
                        x86_android_tablet_remove(pdev);
-                       return PTR_ERR(pdevs[pdev_count]);
+                       return ret;
                }
                pdev_count++;
        }
index e1fca65b80becbe9757f56862ae329478b3b7fe4..26a60a101e42a03919fe4117b45fba3f85315e19 100644 (file)
@@ -1052,7 +1052,7 @@ static unsigned long cpr_get_opp_hz_for_req(struct dev_pm_opp *ref,
                        of_parse_phandle(child_np, "required-opps", 0);
 
                if (child_req_np == ref_np) {
-                       u64 rate;
+                       u64 rate = 0;
 
                        of_property_read_u64(child_np, "opp-hz", &rate);
                        return (unsigned long) rate;
index 95d9a35243c2df9ce6cc898aec8b07df190c62ab..a3d71fc72064158ae0ef2d29273de35b02af8933 100644 (file)
@@ -21,7 +21,7 @@
 #include <linux/platform_device.h>
 #include <linux/power_supply.h>
 #include <linux/iio/consumer.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include <asm/iosf_mbi.h>
 
 #define PS_STAT_VBUS_TRIGGER                   (1 << 0)
index c1737f964840a1e036b0f9eafdffaafe5da5a2c7..ba0d22d904295060966f0f678d5e648e8cf8bf18 100644 (file)
@@ -9,7 +9,7 @@
 #include <linux/i2c.h>
 #include <linux/interrupt.h>
 #include <linux/module.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #include <linux/power/bq27xxx_battery.h>
 
index d406f2a784497256f671a81336fd64a78c1e4296..962a6fd298323eb16b7a029c90e4314be36098b6 100644 (file)
@@ -15,7 +15,7 @@
 #include <linux/slab.h>
 #include <linux/stringify.h>
 #include <linux/types.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #define DRV_NAME               "cros-ec-pchg"
 #define PCHG_DIR_PREFIX                "peripheral"
index 2bc3dce963a3ab178ceb68f6cc1676bca96425d1..33105419e2427bb37963bda9948b647c239f8faa 100644 (file)
@@ -14,7 +14,7 @@
 #include <linux/power_supply.h>
 #include <linux/regmap.h>
 
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 /* Nonvolatile registers */
 #define MAX1720X_NXTABLE0              0x80
index a3d377a32b497b294917d8ad510d37e1281edd46..57b6ddefad28db60aa60db977505747ec9c19b23 100644 (file)
@@ -8,7 +8,7 @@
  *         Chris Morgan <[email protected]>
  */
 
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include <linux/devm-helpers.h>
 #include <linux/mfd/rk808.h>
 #include <linux/irq.h>
index 196d290dc5966b70c14d28ff59a4e1d734b8137a..ebd1edde28f12aa7711e4ff07f8516abc8cbc946 100644 (file)
@@ -6,7 +6,7 @@
  * Copyright (C) 2019-2021 Maximilian Luz <[email protected]>
  */
 
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include <linux/jiffies.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
index 7a6c62d6f8836487a640dc394de9af74e752c91c..90b823848c998a49bfb4bc5e256841b9666db4fe 100644 (file)
@@ -6,7 +6,7 @@
  * Copyright (C) 2019-2021 Maximilian Luz <[email protected]>
  */
 
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/mutex.h>
index f40bce8176df27aeab28ee00303dd8204cfc6b4c..d1dff6ccab1207ddbe82d2aed1f7960d1ddca307 100644 (file)
@@ -178,7 +178,7 @@ static int __dtpm_devfreq_setup(struct devfreq *devfreq, struct dtpm *parent)
        ret = dev_pm_qos_add_request(dev, &dtpm_devfreq->qos_req,
                                     DEV_PM_QOS_MAX_FREQUENCY,
                                     PM_QOS_MAX_FREQUENCY_DEFAULT_VALUE);
-       if (ret) {
+       if (ret < 0) {
                pr_err("Failed to add QoS request: %d\n", ret);
                goto out_dtpm_unregister;
        }
index 733a36f67fbc69cb55d0c847d9e80989886fe237..cbe07450de933b869d9fbb4955c46c6b1c3838a0 100644 (file)
@@ -147,6 +147,8 @@ static const struct x86_cpu_id pl4_support_ids[] = {
        X86_MATCH_VFM(INTEL_RAPTORLAKE_P, NULL),
        X86_MATCH_VFM(INTEL_METEORLAKE, NULL),
        X86_MATCH_VFM(INTEL_METEORLAKE_L, NULL),
+       X86_MATCH_VFM(INTEL_ARROWLAKE_U, NULL),
+       X86_MATCH_VFM(INTEL_ARROWLAKE_H, NULL),
        {}
 };
 
index 947544e4d229aa963ea22a04a4c3e2a6a4e62961..645fd1dc51a982edd6ac1edebfb598eed7f79384 100644 (file)
@@ -15,7 +15,8 @@
 #include <linux/module.h>
 #include <linux/slab.h>
 
-#define TPMI_RAPL_VERSION 1
+#define TPMI_RAPL_MAJOR_VERSION 0
+#define TPMI_RAPL_MINOR_VERSION 1
 
 /* 1 header + 10 registers + 5 reserved. 8 bytes for each. */
 #define TPMI_RAPL_DOMAIN_SIZE 128
@@ -154,11 +155,21 @@ static int parse_one_domain(struct tpmi_rapl_package *trp, u32 offset)
        tpmi_domain_size = tpmi_domain_header >> 16 & 0xff;
        tpmi_domain_flags = tpmi_domain_header >> 32 & 0xffff;
 
-       if (tpmi_domain_version != TPMI_RAPL_VERSION) {
-               pr_warn(FW_BUG "Unsupported version:%d\n", tpmi_domain_version);
+       if (tpmi_domain_version == TPMI_VERSION_INVALID) {
+               pr_warn(FW_BUG "Invalid version\n");
                return -ENODEV;
        }
 
+       if (TPMI_MAJOR_VERSION(tpmi_domain_version) != TPMI_RAPL_MAJOR_VERSION) {
+               pr_warn(FW_BUG "Unsupported major version:%ld\n",
+                       TPMI_MAJOR_VERSION(tpmi_domain_version));
+               return -ENODEV;
+       }
+
+       if (TPMI_MINOR_VERSION(tpmi_domain_version) > TPMI_RAPL_MINOR_VERSION)
+               pr_info("Ignore: Unsupported minor version:%ld\n",
+                       TPMI_MINOR_VERSION(tpmi_domain_version));
+
        /* Domain size: in unit of 128 Bytes */
        if (tpmi_domain_size != 1) {
                pr_warn(FW_BUG "Invalid Domain size %d\n", tpmi_domain_size);
@@ -181,7 +192,7 @@ static int parse_one_domain(struct tpmi_rapl_package *trp, u32 offset)
                        pr_warn(FW_BUG "System domain must support Domain Info register\n");
                        return -ENODEV;
                }
-               tpmi_domain_info = readq(trp->base + offset + TPMI_RAPL_REG_DOMAIN_INFO);
+               tpmi_domain_info = readq(trp->base + offset + TPMI_RAPL_REG_DOMAIN_INFO * 8);
                if (!(tpmi_domain_info & TPMI_RAPL_DOMAIN_ROOT))
                        return 0;
                domain_type = RAPL_DOMAIN_PLATFORM;
index 209a45a76e6bd8c6884131380a120de77d2372a1..b6f1941308b17ac6a65be6ef1269ccc40ca8fc4e 100644 (file)
@@ -17,7 +17,7 @@
 #include <linux/of.h>
 #include <linux/mfd/rsmu.h>
 #include <linux/mfd/idt8a340_reg.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #include "ptp_private.h"
 #include "ptp_clockmatrix.h"
index 6ef982862e27d7e3647e7ba5379e4a9d2d5699b4..e14e149b746eb2aa7c596eb3b63b949a55563c77 100644 (file)
@@ -18,7 +18,7 @@
 #include <linux/bitfield.h>
 #include <linux/mfd/rsmu.h>
 #include <linux/mfd/idtRC38xxx_reg.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #include "ptp_private.h"
 #include "ptp_fc3.h"
index 8935ef95a2d1fc6ff517ae276577903ae53d36d1..a200cc8c7955028df1bb2c1ca643297b7deb195b 100644 (file)
@@ -405,8 +405,8 @@ static int npcm_rc_probe(struct platform_device *pdev)
        if (!of_property_read_u32(pdev->dev.of_node, "nuvoton,sw-reset-number",
                                  &rc->sw_reset_number)) {
                if (rc->sw_reset_number && rc->sw_reset_number < 5) {
-                       rc->restart_nb.priority = 192,
-                       rc->restart_nb.notifier_call = npcm_rc_restart,
+                       rc->restart_nb.priority = 192;
+                       rc->restart_nb.notifier_call = npcm_rc_restart;
                        ret = register_restart_handler(&rc->restart_nb);
                        if (ret)
                                dev_warn(&pdev->dev, "failed to register restart handler\n");
index 55bbbd2de52cf9388ff256e5248c3513dfe32ccf..29ce3486752f38feb64817a7de2f4ff18fbee7d8 100644 (file)
@@ -94,6 +94,9 @@ static int jh71x0_reset_status(struct reset_controller_dev *rcdev,
        void __iomem *reg_status = data->status + offset * sizeof(u32);
        u32 value = readl(reg_status);
 
+       if (!data->asserted)
+               return !(value & mask);
+
        return !((value ^ data->asserted[offset]) & mask);
 }
 
index 9a456f537d3b9ee71c098d1f543151e39a03d2a4..3fbcf5f6b92ffd4581e9c4dbc87ec848867522dc 100644 (file)
@@ -8,7 +8,7 @@
  *
  */
 
-#include <asm-generic/unaligned.h>
+#include <linux/unaligned.h>
 #include <linux/bcd.h>
 #include <linux/bitfield.h>
 #include <linux/bitops.h>
index f6b779c12ca724177731fa1bee96f5f7696f6bb6..c32fba550c8e0aba82aa1940465fcf672474536c 100644 (file)
@@ -17,7 +17,7 @@
 #include <linux/slab.h>
 #include <linux/spinlock.h>
 
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 /* RTC_CTRL register bit fields */
 #define PM8xxx_RTC_ENABLE              BIT(7)
index f3621adbd5debc59d2b71fc1be2790e0cbd31f76..fbffd451031fdb526d9b802da50df7f3eba5c48e 100644 (file)
@@ -1195,7 +1195,8 @@ sclp_reboot_event(struct notifier_block *this, unsigned long event, void *ptr)
 }
 
 static struct notifier_block sclp_reboot_notifier = {
-       .notifier_call = sclp_reboot_event
+       .notifier_call = sclp_reboot_event,
+       .priority      = INT_MIN,
 };
 
 static ssize_t con_pages_show(struct device_driver *dev, char *buf)
index 218ae604f737ff9e20764ebce857ce427e4a7c44..33b9c968dbcba6584015d70a8500f9f5f70227db 100644 (file)
@@ -319,7 +319,7 @@ sclp_vt220_add_msg(struct sclp_vt220_request *request,
        buffer = (void *) ((addr_t) sccb + sccb->header.length);
 
        if (convertlf) {
-               /* Perform Linefeed conversion (0x0a -> 0x0a 0x0d)*/
+               /* Perform Linefeed conversion (0x0a -> 0x0d 0x0a)*/
                for (from=0, to=0;
                     (from < count) && (to < sclp_vt220_space_left(request));
                     from++) {
@@ -328,8 +328,8 @@ sclp_vt220_add_msg(struct sclp_vt220_request *request,
                        /* Perform conversion */
                        if (c == 0x0a) {
                                if (to + 1 < sclp_vt220_space_left(request)) {
-                                       ((unsigned char *) buffer)[to++] = c;
                                        ((unsigned char *) buffer)[to++] = 0x0d;
+                                       ((unsigned char *) buffer)[to++] = c;
                                } else
                                        break;
 
index 60cea6c243497b9f788c8da18eb77c055ac81cc6..e14638936de6b8773a43aec14b04df94f26e6357 100644 (file)
@@ -1864,13 +1864,12 @@ static inline void ap_scan_domains(struct ap_card *ac)
                }
                /* if no queue device exists, create a new one */
                if (!aq) {
-                       aq = ap_queue_create(qid, ac->ap_dev.device_type);
+                       aq = ap_queue_create(qid, ac);
                        if (!aq) {
                                AP_DBF_WARN("%s(%d,%d) ap_queue_create() failed\n",
                                            __func__, ac->id, dom);
                                continue;
                        }
-                       aq->card = ac;
                        aq->config = !decfg;
                        aq->chkstop = chkstop;
                        aq->se_bstate = hwinfo.bs;
index 0b275c719319645368f2bfba3fb59e78888e361e..f4622ee4d8947396dda5b73ce300c84dab27c6c5 100644 (file)
@@ -272,7 +272,7 @@ int ap_test_config_usage_domain(unsigned int domain);
 int ap_test_config_ctrl_domain(unsigned int domain);
 
 void ap_queue_init_reply(struct ap_queue *aq, struct ap_message *ap_msg);
-struct ap_queue *ap_queue_create(ap_qid_t qid, int device_type);
+struct ap_queue *ap_queue_create(ap_qid_t qid, struct ap_card *ac);
 void ap_queue_prepare_remove(struct ap_queue *aq);
 void ap_queue_remove(struct ap_queue *aq);
 void ap_queue_init_state(struct ap_queue *aq);
index 8c878c5aa31fd72c73889eb35aa213a82a1930bb..9a0e6e4d8a5e2aef03bf2d06e588c2c787a8b7bf 100644 (file)
@@ -22,6 +22,11 @@ static void __ap_flush_queue(struct ap_queue *aq);
  * some AP queue helper functions
  */
 
+static inline bool ap_q_supported_in_se(struct ap_queue *aq)
+{
+       return aq->card->hwinfo.ep11 || aq->card->hwinfo.accel;
+}
+
 static inline bool ap_q_supports_bind(struct ap_queue *aq)
 {
        return aq->card->hwinfo.ep11 || aq->card->hwinfo.accel;
@@ -1104,18 +1109,19 @@ static void ap_queue_device_release(struct device *dev)
        kfree(aq);
 }
 
-struct ap_queue *ap_queue_create(ap_qid_t qid, int device_type)
+struct ap_queue *ap_queue_create(ap_qid_t qid, struct ap_card *ac)
 {
        struct ap_queue *aq;
 
        aq = kzalloc(sizeof(*aq), GFP_KERNEL);
        if (!aq)
                return NULL;
+       aq->card = ac;
        aq->ap_dev.device.release = ap_queue_device_release;
        aq->ap_dev.device.type = &ap_queue_type;
-       aq->ap_dev.device_type = device_type;
-       // add optional SE secure binding attributes group
-       if (ap_sb_available() && is_prot_virt_guest())
+       aq->ap_dev.device_type = ac->ap_dev.device_type;
+       /* in SE environment add bind/associate attributes group */
+       if (ap_is_se_guest() && ap_q_supported_in_se(aq))
                aq->ap_dev.device.groups = ap_queue_dev_sb_attr_groups;
        aq->qid = qid;
        spin_lock_init(&aq->lock);
@@ -1196,10 +1202,16 @@ bool ap_queue_usable(struct ap_queue *aq)
        }
 
        /* SE guest's queues additionally need to be bound */
-       if (ap_q_needs_bind(aq) &&
-           !(aq->se_bstate == AP_BS_Q_USABLE ||
-             aq->se_bstate == AP_BS_Q_USABLE_NO_SECURE_KEY))
-               rc = false;
+       if (ap_is_se_guest()) {
+               if (!ap_q_supported_in_se(aq)) {
+                       rc = false;
+                       goto unlock_and_out;
+               }
+               if (ap_q_needs_bind(aq) &&
+                   !(aq->se_bstate == AP_BS_Q_USABLE ||
+                     aq->se_bstate == AP_BS_Q_USABLE_NO_SECURE_KEY))
+                       rc = false;
+       }
 
 unlock_and_out:
        spin_unlock_bh(&aq->lock);
index 98079b1ed6db81722ccab1e741f8d17fc9f3c858..beeca8827c4649c93bbfcbf5e889846607df9d91 100644 (file)
@@ -324,6 +324,7 @@ static int pckmo_key2protkey(const u8 *key, u32 keylen,
                memcpy(protkey, t->protkey, t->len);
                *protkeylen = t->len;
                *protkeytype = t->keytype;
+               rc = 0;
                break;
        }
        case TOKVER_CLEAR_KEY: {
index ec3834bda111e5d7960fe493e120bb45f086b9a3..abf6a82b74af352e516a956dcb26f328dd5a5810 100644 (file)
@@ -27,7 +27,7 @@
 #include <linux/uaccess.h>
 #include <linux/module.h>
 
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #include <scsi/scsi.h>
 #include <scsi/scsi_cmnd.h>
index 5b3ffefae476d011999a9ac66913381080b34920..6cc1d53165a0df240c080f285d4de70cfb0feac9 100644 (file)
@@ -38,7 +38,7 @@
 #include <linux/utsname.h>
 #include <scsi/scsi_device.h>
 #include <scsi/scsi_transport_fc.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include <scsi/fc/fc_els.h>
 #include <scsi/fc/fc_fs.h>
 #include <scsi/fc/fc_gs.h>
index 05e1a63e00c3a11266abca93910879a20ca7c7aa..8329f0cab4e7db2aca779bc51e7413dc9f871cfb 100644 (file)
@@ -41,7 +41,7 @@
 #include <linux/compiler.h>
 #include <linux/export.h>
 #include <linux/module.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include <asm/page.h>
 #include <scsi/scsi.h>
 #include <scsi/scsi_device.h>
index 52405c6462f8097370e09a2e63e224dc57f34d62..962c797fda07d989ce604dcb74858fa83b5986c3 100644 (file)
@@ -8,7 +8,7 @@
  * Copyright (C) 2015 IBM Corporation
  */
 
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #include <linux/interrupt.h>
 #include <linux/pci.h>
index e4b45b7e327774dde48ca8e6045b0c4777bd76c4..60d62b93d62442fae156f8521276f2c4f55daa50 100644 (file)
@@ -13,7 +13,7 @@
 #include <linux/module.h>
 #include <linux/pci.h>
 
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #include <scsi/scsi_cmnd.h>
 #include <scsi/scsi_host.h>
index 2d356fe2457a2a02fc1d49caf5dea4bd2c74b3a1..b375509d14709e6f04185a67553581f52d1bd39e 100644 (file)
@@ -13,7 +13,7 @@
 #include <linux/interrupt.h>
 #include <linux/pci.h>
 #include <linux/syscalls.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #include <scsi/scsi.h>
 #include <scsi/scsi_host.h>
index 35326e31199131f250c8df8184bf47756f34d287..32e8077033778f85ef06809d6bb1ae6a2d7232e1 100644 (file)
@@ -11,7 +11,7 @@
 #include <linux/interrupt.h>
 #include <linux/pci.h>
 #include <linux/syscalls.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include <asm/bitsperlong.h>
 
 #include <scsi/scsi_cmnd.h>
index 4eb0837298d4d2dddf159fbdfc348a6e5a8386c6..1bf5948d1188f65a23fa930fbad577c3f7105893 100644 (file)
@@ -8,7 +8,7 @@
 #include <linux/slab.h>
 #include <linux/delay.h>
 #include <linux/module.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include <scsi/scsi.h>
 #include <scsi/scsi_proto.h>
 #include <scsi/scsi_dbg.h>
index 0044717d4486c68ec998d015aa6380b9010da19f..adec0df24bc475ea4d7d8089ea0f75fe96746956 100644 (file)
@@ -830,7 +830,6 @@ static int fnic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
                spin_lock_init(&fnic->vlans_lock);
                INIT_WORK(&fnic->fip_frame_work, fnic_handle_fip_frame);
                INIT_WORK(&fnic->event_work, fnic_handle_event);
-               INIT_WORK(&fnic->flush_work, fnic_flush_tx);
                skb_queue_head_init(&fnic->fip_frame_queue);
                INIT_LIST_HEAD(&fnic->evlist);
                INIT_LIST_HEAD(&fnic->vlans);
@@ -948,6 +947,7 @@ static int fnic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 
        INIT_WORK(&fnic->link_work, fnic_handle_link);
        INIT_WORK(&fnic->frame_work, fnic_handle_frame);
+       INIT_WORK(&fnic->flush_work, fnic_flush_tx);
        skb_queue_head_init(&fnic->frame_queue);
        skb_queue_head_init(&fnic->tx_queue);
 
index e044ed09d7e0d474610664684ce1e80caeca0bff..0c49414c1f350bd318b9fc5fd2285499e4e23f63 100644 (file)
@@ -51,7 +51,7 @@
 #include <linux/jiffies.h>
 #include <linux/percpu-defs.h>
 #include <linux/percpu.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include <asm/div64.h>
 #include "hpsa_cmd.h"
 #include "hpsa.h"
index b2b643c6dbbe68251628512ce8c32ecc80a411df..fde7145835de4677e16b7796035f44995a71eb7a 100644 (file)
@@ -13,7 +13,7 @@
 #ifndef _IPR_H
 #define _IPR_H
 
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include <linux/types.h>
 #include <linux/completion.h>
 #include <linux/list.h>
index 384f48ff64d721f667fa97f6827ae1ced988a5a8..60d621ad002487d851bb830c9a59c1c3277d9fd5 100644 (file)
@@ -26,7 +26,7 @@
 #include <linux/export.h>
 #include <linux/list.h>
 
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #include <scsi/fc/fc_gs.h>
 
index 8d3006edbe12835a5a30fa462d582c0ad27ab414..4fa18a317f77f3a8b3a583f3abe72492830c1ade 100644 (file)
@@ -10,7 +10,7 @@
  */
 
 #include <linux/export.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include <scsi/fc/fc_gs.h>
 #include <scsi/fc/fc_ns.h>
 #include <scsi/fc/fc_els.h>
index 6b7e4ca6b7b5ee98d4c876fced7b0d1c9e0687aa..02e31db31d68e623462d7c4fe44095ec29af8855 100644 (file)
@@ -7,7 +7,7 @@
 
 #ifndef _FC_ENCODE_H_
 #define _FC_ENCODE_H_
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include <linux/utsname.h>
 #include <scsi/fc/fc_ms.h>
 
index ab06e9aeb613e7c7d9cf4e45ea7c02b98e7106e8..310fa5add5f087618f4513ebb482a6c54bb63123 100644 (file)
@@ -79,7 +79,7 @@
 #include <linux/delay.h>
 #include <linux/module.h>
 #include <linux/slab.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #include <scsi/fc/fc_gs.h>
 
index 308cb4872f968adaf637a7c524e70efee46f40c2..c25979d96808a9072c21f5d6a13a501ed7ed978f 100644 (file)
@@ -55,7 +55,7 @@
 #include <linux/export.h>
 #include <linux/rculist.h>
 
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #include <scsi/libfc.h>
 
index 0fda8905eabd8278f578e54a8f502ab2996629ed..2b1bf990a9dc0707b3579aa643a2ff943e4eedfe 100644 (file)
@@ -15,7 +15,7 @@
 #include <linux/slab.h>
 #include <linux/sched/signal.h>
 #include <linux/module.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include <net/tcp.h>
 #include <scsi/scsi_cmnd.h>
 #include <scsi/scsi_device.h>
index 4e6bb3d0f1636bc1760123ebbec4f93ee8d55e4e..2b8004eb6f1b3533e6a64f8032bdb110e17cbc39 100644 (file)
@@ -11,7 +11,7 @@
 #include <linux/scatterlist.h>
 #include <linux/blkdev.h>
 #include <linux/slab.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #include "sas_internal.h"
 
index d70da2736c945297f680eaaa0e1cf0c594189564..fec23c7237304b471e58194726ff7932b0010385 100644 (file)
@@ -24,7 +24,7 @@
 #include <linux/slab.h>
 #include <linux/interrupt.h>
 #include <linux/delay.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include <linux/crc-t10dif.h>
 #include <net/checksum.h>
 
index 0cef5d089f34b530c28be242742e039b2087faab..55c3e2c2bf8f7ee54b856f8971060441f01c3601 100644 (file)
@@ -24,7 +24,7 @@
 #include <linux/slab.h>
 #include <linux/interrupt.h>
 #include <linux/delay.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include <linux/crc-t10dif.h>
 #include <net/checksum.h>
 
index 0eaede8275dac40c2d9fd682898ab87c9d14b58e..11c974bffa72099436056418f7c2f32ca70e7c08 100644 (file)
@@ -25,7 +25,7 @@
 #include <linux/interrupt.h>
 #include <linux/export.h>
 #include <linux/delay.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include <linux/t10-pi.h>
 #include <linux/crc-t10dif.h>
 #include <linux/blk-cgroup.h>
index 4ecf5284c0fc3460845f2a090ffdeae16696b8c1..8e75e2e279a40ae5fdc6b7b07a7aed15241a8d54 100644 (file)
@@ -29,7 +29,7 @@
 #include <linux/uio.h>
 #include <linux/slab.h>
 #include <linux/uaccess.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include <linux/fs.h>
 #include <linux/compat.h>
 #include <linux/blkdev.h>
index fcb0fa31536bd077f456fad2d772411a3917a398..81bb408ce56d8f9599e6f62276666bedce6d0d32 100644 (file)
@@ -31,7 +31,7 @@
 #include <linux/uaccess.h>
 #include <linux/utsname.h>
 #include <linux/workqueue.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include <scsi/scsi.h>
 #include <scsi/scsi_cmnd.h>
 #include <scsi/scsi_dbg.h>
@@ -542,8 +542,8 @@ struct mpi3mr_hba_port {
  * @port_list: List of ports belonging to a SAS node
  * @num_phys: Number of phys associated with port
  * @marked_responding: used while refresing the sas ports
- * @lowest_phy: lowest phy ID of current sas port
- * @phy_mask: phy_mask of current sas port
+ * @lowest_phy: lowest phy ID of current sas port, valid for controller port
+ * @phy_mask: phy_mask of current sas port, valid for controller port
  * @hba_port: HBA port entry
  * @remote_identify: Attached device identification
  * @rphy: SAS transport layer rphy object
index ccd23def2e0cfa7e0fe68d312f137c1a4f5b36c9..0ba9e6a6a13c6d21f7d40f4c7eb8bd7a911ea48d 100644 (file)
@@ -590,12 +590,13 @@ static enum sas_linkrate mpi3mr_convert_phy_link_rate(u8 link_rate)
  * @mrioc: Adapter instance reference
  * @mr_sas_port: Internal Port object
  * @mr_sas_phy: Internal Phy object
+ * @host_node: Flag to indicate this is a host_node
  *
  * Return: None.
  */
 static void mpi3mr_delete_sas_phy(struct mpi3mr_ioc *mrioc,
        struct mpi3mr_sas_port *mr_sas_port,
-       struct mpi3mr_sas_phy *mr_sas_phy)
+       struct mpi3mr_sas_phy *mr_sas_phy, u8 host_node)
 {
        u64 sas_address = mr_sas_port->remote_identify.sas_address;
 
@@ -605,9 +606,13 @@ static void mpi3mr_delete_sas_phy(struct mpi3mr_ioc *mrioc,
 
        list_del(&mr_sas_phy->port_siblings);
        mr_sas_port->num_phys--;
-       mr_sas_port->phy_mask &= ~(1 << mr_sas_phy->phy_id);
-       if (mr_sas_port->lowest_phy == mr_sas_phy->phy_id)
-               mr_sas_port->lowest_phy = ffs(mr_sas_port->phy_mask) - 1;
+
+       if (host_node) {
+               mr_sas_port->phy_mask &= ~(1 << mr_sas_phy->phy_id);
+
+               if (mr_sas_port->lowest_phy == mr_sas_phy->phy_id)
+                       mr_sas_port->lowest_phy = ffs(mr_sas_port->phy_mask) - 1;
+       }
        sas_port_delete_phy(mr_sas_port->port, mr_sas_phy->phy);
        mr_sas_phy->phy_belongs_to_port = 0;
 }
@@ -617,12 +622,13 @@ static void mpi3mr_delete_sas_phy(struct mpi3mr_ioc *mrioc,
  * @mrioc: Adapter instance reference
  * @mr_sas_port: Internal Port object
  * @mr_sas_phy: Internal Phy object
+ * @host_node: Flag to indicate this is a host_node
  *
  * Return: None.
  */
 static void mpi3mr_add_sas_phy(struct mpi3mr_ioc *mrioc,
        struct mpi3mr_sas_port *mr_sas_port,
-       struct mpi3mr_sas_phy *mr_sas_phy)
+       struct mpi3mr_sas_phy *mr_sas_phy, u8 host_node)
 {
        u64 sas_address = mr_sas_port->remote_identify.sas_address;
 
@@ -632,9 +638,12 @@ static void mpi3mr_add_sas_phy(struct mpi3mr_ioc *mrioc,
 
        list_add_tail(&mr_sas_phy->port_siblings, &mr_sas_port->phy_list);
        mr_sas_port->num_phys++;
-       mr_sas_port->phy_mask |= (1 << mr_sas_phy->phy_id);
-       if (mr_sas_phy->phy_id < mr_sas_port->lowest_phy)
-               mr_sas_port->lowest_phy = ffs(mr_sas_port->phy_mask) - 1;
+       if (host_node) {
+               mr_sas_port->phy_mask |= (1 << mr_sas_phy->phy_id);
+
+               if (mr_sas_phy->phy_id < mr_sas_port->lowest_phy)
+                       mr_sas_port->lowest_phy = ffs(mr_sas_port->phy_mask) - 1;
+       }
        sas_port_add_phy(mr_sas_port->port, mr_sas_phy->phy);
        mr_sas_phy->phy_belongs_to_port = 1;
 }
@@ -675,7 +684,7 @@ static void mpi3mr_add_phy_to_an_existing_port(struct mpi3mr_ioc *mrioc,
                        if (srch_phy == mr_sas_phy)
                                return;
                }
-               mpi3mr_add_sas_phy(mrioc, mr_sas_port, mr_sas_phy);
+               mpi3mr_add_sas_phy(mrioc, mr_sas_port, mr_sas_phy, mr_sas_node->host_node);
                return;
        }
 }
@@ -736,7 +745,7 @@ static void mpi3mr_del_phy_from_an_existing_port(struct mpi3mr_ioc *mrioc,
                                mpi3mr_delete_sas_port(mrioc, mr_sas_port);
                        else
                                mpi3mr_delete_sas_phy(mrioc, mr_sas_port,
-                                   mr_sas_phy);
+                                   mr_sas_phy, mr_sas_node->host_node);
                        return;
                }
        }
@@ -1028,7 +1037,7 @@ mpi3mr_alloc_hba_port(struct mpi3mr_ioc *mrioc, u16 port_id)
 /**
  * mpi3mr_get_hba_port_by_id - find hba port by id
  * @mrioc: Adapter instance reference
- * @port_id - Port ID to search
+ * @port_id: Port ID to search
  *
  * Return: mpi3mr_hba_port reference for the matched port
  */
@@ -1367,7 +1376,8 @@ static struct mpi3mr_sas_port *mpi3mr_sas_port_add(struct mpi3mr_ioc *mrioc,
        mpi3mr_sas_port_sanity_check(mrioc, mr_sas_node,
            mr_sas_port->remote_identify.sas_address, hba_port);
 
-       if (mr_sas_node->num_phys >= sizeof(mr_sas_port->phy_mask) * 8)
+       if (mr_sas_node->host_node && mr_sas_node->num_phys >=
+                       sizeof(mr_sas_port->phy_mask) * 8)
                ioc_info(mrioc, "max port count %u could be too high\n",
                    mr_sas_node->num_phys);
 
@@ -1377,7 +1387,7 @@ static struct mpi3mr_sas_port *mpi3mr_sas_port_add(struct mpi3mr_ioc *mrioc,
                    (mr_sas_node->phy[i].hba_port != hba_port))
                        continue;
 
-               if (i >= sizeof(mr_sas_port->phy_mask) * 8) {
+               if (mr_sas_node->host_node && (i >= sizeof(mr_sas_port->phy_mask) * 8)) {
                        ioc_warn(mrioc, "skipping port %u, max allowed value is %zu\n",
                            i, sizeof(mr_sas_port->phy_mask) * 8);
                        goto out_fail;
@@ -1385,7 +1395,8 @@ static struct mpi3mr_sas_port *mpi3mr_sas_port_add(struct mpi3mr_ioc *mrioc,
                list_add_tail(&mr_sas_node->phy[i].port_siblings,
                    &mr_sas_port->phy_list);
                mr_sas_port->num_phys++;
-               mr_sas_port->phy_mask |= (1 << i);
+               if (mr_sas_node->host_node)
+                       mr_sas_port->phy_mask |= (1 << i);
        }
 
        if (!mr_sas_port->num_phys) {
@@ -1394,7 +1405,8 @@ static struct mpi3mr_sas_port *mpi3mr_sas_port_add(struct mpi3mr_ioc *mrioc,
                goto out_fail;
        }
 
-       mr_sas_port->lowest_phy = ffs(mr_sas_port->phy_mask) - 1;
+       if (mr_sas_node->host_node)
+               mr_sas_port->lowest_phy = ffs(mr_sas_port->phy_mask) - 1;
 
        if (mr_sas_port->remote_identify.device_type == SAS_END_DEVICE) {
                tgtdev = mpi3mr_get_tgtdev_by_addr(mrioc,
index 728cced42b0e3c5bda7d9d04ac675eb0276c5274..f2a55aa5fe65036a3beabae5c0c6e9db835d2aab 100644 (file)
@@ -54,7 +54,7 @@
 #include <linux/interrupt.h>
 #include <linux/raid_class.h>
 #include <linux/blk-mq-pci.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #include "mpt3sas_base.h"
 
index 1d64e5056a8ab1bbba868a4e11c9445c0f3ea8b9..2b04f0852decd32062202d7a05f121c1d3540d8a 100644 (file)
@@ -42,7 +42,7 @@
 #include <linux/module.h>
 #include <linux/errno.h>
 #include <linux/types.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #include "mpt3sas_base.h"
 
index 68df771e29759d251dca0e3354ecca5942b6afee..19b01f7c4767720b9c96457e216c154e9f7e4de5 100644 (file)
@@ -23,7 +23,7 @@
 #include <linux/irq.h>
 #include <linux/slab.h>
 #include <linux/vmalloc.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include <scsi/libsas.h>
 #include <scsi/scsi.h>
 #include <scsi/scsi_tcq.h>
index bfc2b835e61251af82b0eb4199a52482bd475cca..a7e64b867c8e28289a13fa1660087e75805f047c 100644 (file)
@@ -16,7 +16,7 @@
 #include <linux/interrupt.h>
 #include <linux/pci.h>
 #include <linux/raid_class.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include <scsi/scsi.h>
 #include <scsi/scsi_host.h>
 #include <scsi/scsi_device.h>
index 3392feb15cb4076a0ca94e97e1801b9faaeaa9bc..1469d0c54e45580c84226abdf42b1a3fc769f737 100644 (file)
@@ -17,7 +17,7 @@
 #include <linux/interrupt.h>
 #include <linux/pci.h>
 #include <linux/raid_class.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include <scsi/scsi.h>
 #include <scsi/scsi_host.h>
 #include <scsi/scsi_device.h>
index 20788054b91bc136965d0eaa570255e833784b0c..52e060f83b37d93832a3390c104fa3c720c669d8 100644 (file)
@@ -1,7 +1,7 @@
 #ifndef _QLA_DSD_H_
 #define _QLA_DSD_H_
 
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 /* 32-bit data segment descriptor (8 bytes) */
 struct dsd32 {
index d7551b1443e4a7538df5d45beb003a11b0c29b9f..11eadb3bd36e5c33d06fc34e4e3d5d3cb1f9ed86 100644 (file)
@@ -23,7 +23,7 @@
 #include <linux/delay.h>
 #include <linux/list.h>
 #include <linux/workqueue.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include <scsi/scsi.h>
 #include <scsi/scsi_host.h>
 #include <scsi/scsi_tcq.h>
index 7e7460a747a447efacfd06ed8b8335c223eb11c2..ceaf1c7b1d17b85113fe94c80a28fe0441e41540 100644 (file)
@@ -24,7 +24,7 @@
 #include <linux/string.h>
 #include <linux/configfs.h>
 #include <linux/ctype.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include <scsi/scsi_host.h>
 #include <target/target_core_base.h>
 #include <target/target_core_fabric.h>
index ee69bd35889d17130fdc6430783c221a766dfcb5..a77e0499b738a639c42cc18aaafd05eabc394060 100644 (file)
@@ -55,7 +55,7 @@
 #include <linux/notifier.h>
 #include <linux/cpu.h>
 #include <linux/mutex.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #include <scsi/scsi.h>
 #include <scsi/scsi_cmnd.h>
index 04749fde1636d985eddf117885eb50ebc5367750..e1a2a62b6910fe31322730544a731470f2c572fb 100644 (file)
@@ -9,7 +9,7 @@
 #include <linux/errno.h>
 #include <linux/module.h>
 #include <uapi/linux/pr.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include <scsi/scsi_common.h>
 
 MODULE_DESCRIPTION("SCSI functions used by both the initiator and the target code");
index d95f417e24c0da1c86c7fb0a16dce6f1e4916219..b52513eeeafa759d8c01bd67f3213da06fc72cc1 100644 (file)
@@ -47,7 +47,7 @@
 
 #include <net/checksum.h>
 
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #include <scsi/scsi.h>
 #include <scsi/scsi_cmnd.h>
@@ -3651,7 +3651,7 @@ static int do_device_access(struct sdeb_store_info *sip, struct scsi_cmnd *scp,
        enum dma_data_direction dir;
        struct scsi_data_buffer *sdb = &scp->sdb;
        u8 *fsp;
-       int i;
+       int i, total = 0;
 
        /*
         * Even though reads are inherently atomic (in this driver), we expect
@@ -3688,18 +3688,16 @@ static int do_device_access(struct sdeb_store_info *sip, struct scsi_cmnd *scp,
                   fsp + (block * sdebug_sector_size),
                   sdebug_sector_size, sg_skip, do_write);
                sdeb_data_sector_unlock(sip, do_write);
-               if (ret != sdebug_sector_size) {
-                       ret += (i * sdebug_sector_size);
+               total += ret;
+               if (ret != sdebug_sector_size)
                        break;
-               }
                sg_skip += sdebug_sector_size;
                if (++block >= sdebug_store_sectors)
                        block = 0;
        }
-       ret = num * sdebug_sector_size;
        sdeb_data_unlock(sip, atomic);
 
-       return ret;
+       return total;
 }
 
 /* Returns number of bytes copied or -1 if error. */
index 612489afe8d2467965759c80562562e26919f704..10154d78e3360b1c3d23e763e2128a166e9fcfc6 100644 (file)
@@ -48,7 +48,7 @@
 
 #include <trace/events/scsi.h>
 
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 /*
  * These should *probably* be handled by the host itself.
index 0561b318dade13e3c5e29d7561bfba022d8d7a6a..adee6f60c966553ffb9dc632b12646d7225477d5 100644 (file)
@@ -23,7 +23,7 @@
 #include <linux/blk-mq.h>
 #include <linux/blk-integrity.h>
 #include <linux/ratelimit.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #include <scsi/scsi.h>
 #include <scsi/scsi_cmnd.h>
index 7fa0a78a2ad16800a0c07aa55858a931c053c32e..c093389edabb52d9d4cbcd4462214eb2ccc34e52 100644 (file)
@@ -3,7 +3,7 @@
  * Copyright 2023 Google LLC
  */
 #include <kunit/test.h>
-#include <asm-generic/unaligned.h>
+#include <linux/unaligned.h>
 #include <scsi/scsi_proto.h>
 
 static void test_scsi_proto(struct kunit *test)
index c0b72199b4faac2bd1ed97533ab8f340a2326bf6..042329b74c6e6829afae5a4feed057bba4bff64b 100644 (file)
@@ -35,7 +35,7 @@
 #include <linux/spinlock.h>
 #include <linux/async.h>
 #include <linux/slab.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #include <scsi/scsi.h>
 #include <scsi/scsi_cmnd.h>
index 3e47c4472a80e7c2f98d55614c472cf86abbdaa8..b3baae91e7a24904b116e31446a48b97054616cf 100644 (file)
@@ -5,7 +5,7 @@
  */
 #include <linux/kernel.h>
 #include <linux/trace_seq.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include <trace/events/scsi.h>
 
 #define SERVICE_ACTION16(cdb) (cdb[1] & 0x1f)
index 62ea7e44460e52d77cb155750f4d204bf1ccc1cd..082f76e7672107dcf64e4e26ef0c69fe29a0c030 100644 (file)
@@ -1250,7 +1250,7 @@ static ssize_t fc_rport_set_marginal_state(struct device *dev,
                 */
                if (rport->port_state == FC_PORTSTATE_ONLINE)
                        rport->port_state = port_state;
-               else
+               else if (port_state != rport->port_state)
                        return -EINVAL;
        } else if (port_state == FC_PORTSTATE_ONLINE) {
                /*
@@ -1260,7 +1260,7 @@ static ssize_t fc_rport_set_marginal_state(struct device *dev,
                 */
                if (rport->port_state == FC_PORTSTATE_MARGINAL)
                        rport->port_state = port_state;
-               else
+               else if (port_state != rport->port_state)
                        return -EINVAL;
        } else
                return -EINVAL;
index dd69342bbe7815886b44a0c58bd3b45239babeca..19e6c3852d50482d30c515b17888b3ee5eecda73 100644 (file)
@@ -18,7 +18,7 @@
 #include <linux/blkdev.h>
 #include <linux/pagemap.h>
 #include <linux/msdos_partition.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #include <scsi/scsicam.h>
 
index 41e2dfa2d67d89cbf3a3d8d5e557dcaf102112b5..ca4bc0ac76adcfa8a883df8f4259ba755d3b6413 100644 (file)
@@ -57,7 +57,7 @@
 #include <linux/pr.h>
 #include <linux/t10-pi.h>
 #include <linux/uaccess.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #include <scsi/scsi.h>
 #include <scsi/scsi_cmnd.h>
index c8b9654d30f0c384ea9cd7e09ee3278341d5e4e6..ee2b742387581bc13ecbe4ef8a826d53b031a8d8 100644 (file)
@@ -13,7 +13,7 @@
 #include <linux/sched/mm.h>
 #include <linux/mutex.h>
 
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #include <scsi/scsi.h>
 #include <scsi/scsi_cmnd.h>
index e22c7f5e652bd9f9bd6f989113ac7303a90a8c11..2c61624cb4b038b07073f5538378c126bbd44c29 100644 (file)
@@ -9,7 +9,7 @@
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/enclosure.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #include <scsi/scsi.h>
 #include <scsi/scsi_cmnd.h>
index 7fd5a8c813dc739a0d4fb8ac0395c7a2c193483d..870f37b7054644426a2695e857c45a0a12aff051 100644 (file)
@@ -25,7 +25,7 @@
 #include <scsi/scsi_device.h>
 #include <scsi/scsi_eh.h>
 #include <scsi/scsi_transport_sas.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include "smartpqi.h"
 #include "smartpqi_sis.h"
 
index a981d037794809f1d6499fad6cd68464813bb5d7..93e96705754e8eac0f8d35f0fccfdc71166d6341 100644 (file)
@@ -14,7 +14,7 @@
 #include <scsi/scsi_host.h>
 #include <scsi/scsi_cmnd.h>
 #include <scsi/scsi_transport_sas.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include "smartpqi.h"
 
 static struct pqi_sas_phy *pqi_alloc_sas_phy(struct pqi_sas_port *pqi_sas_port)
index ca1df36b83f7b409da4503722c43e9fe1884360c..ae5a264d062deab90e208d4ac0d21fc3cdf2f7b8 100644 (file)
@@ -14,7 +14,7 @@
 #include <linux/delay.h>
 #include <linux/pci.h>
 #include <scsi/scsi_device.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include "smartpqi.h"
 #include "smartpqi_sis.h"
 
index 3f491019103e0c1b58452a51ba67089c1063fa86..198bec87bb8e7c95da96cc992f7c148782eebc61 100644 (file)
@@ -52,7 +52,7 @@
 #include <linux/pm_runtime.h>
 #include <linux/uaccess.h>
 
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #include <scsi/scsi.h>
 #include <scsi/scsi_dbg.h>
index d50bad3a2ce92b4f3edd57ba031af3b93850cf81..beb88f25dbb9937336a49c4e27826d441bac8924 100644 (file)
@@ -46,7 +46,7 @@ static const char *verstr = "20160209";
 
 #include <linux/uaccess.h>
 #include <asm/dma.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #include <scsi/scsi.h>
 #include <scsi/scsi_dbg.h>
index a44b60c9004ab0a5e01abbb05c4095e90ddaba2a..dd1fef9226f227b92b80acb862dbe4fd2406d3d2 100644 (file)
@@ -831,7 +831,7 @@ wd33c93_intr(struct Scsi_Host *instance)
                /* construct an IDENTIFY message with correct disconnect bit */
 
                hostdata->outgoing_msg[0] = IDENTIFY(0, cmd->device->lun);
-               if (scsi_pointer->phase)
+               if (WD33C93_scsi_pointer(cmd)->phase)
                        hostdata->outgoing_msg[0] |= 0x40;
 
                if (hostdata->sync_stat[cmd->device->id] == SS_FIRST) {
index 3dffebb48b0daced840746c1a77503b9f94540de..19cc581b06d0c806f315091c4f2b6e7d4eb06d6e 100644 (file)
@@ -1761,10 +1761,9 @@ static int qmc_qe_init_resources(struct qmc *qmc, struct platform_device *pdev)
         */
        info = devm_qe_muram_alloc(qmc->dev, UCC_SLOW_PRAM_SIZE + 2 * 64,
                                   ALIGNMENT_OF_UCC_SLOW_PRAM);
-       if (IS_ERR_VALUE(info)) {
-               dev_err(qmc->dev, "cannot allocate MURAM for PRAM");
-               return -ENOMEM;
-       }
+       if (info < 0)
+               return info;
+
        if (!qe_issue_cmd(QE_ASSIGN_PAGE_TO_DEVICE, qmc->qe_subblock,
                          QE_CR_PROTOCOL_UNSPECIFIED, info)) {
                dev_err(qmc->dev, "QE_ASSIGN_PAGE_TO_DEVICE cmd failed");
@@ -2056,7 +2055,7 @@ static void qmc_remove(struct platform_device *pdev)
        qmc_exit_xcc(qmc);
 }
 
-static const struct qmc_data qmc_data_cpm1 = {
+static const struct qmc_data qmc_data_cpm1 __maybe_unused = {
        .version = QMC_CPM1,
        .tstate = 0x30000000,
        .rstate = 0x31000000,
@@ -2066,7 +2065,7 @@ static const struct qmc_data qmc_data_cpm1 = {
        .rpack = 0x00000000,
 };
 
-static const struct qmc_data qmc_data_qe = {
+static const struct qmc_data qmc_data_qe __maybe_unused = {
        .version = QMC_QE,
        .tstate = 0x30000000,
        .rstate = 0x30000000,
index 24c3971f2ef17f54dce2a4be54989079c00003cd..64fc4f41da7715ee72b5845c8bacf1ee02e6c5d1 100644 (file)
@@ -17,7 +17,7 @@
 #include <linux/sys_soc.h>
 #include <linux/types.h>
 
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #include <dt-bindings/arm/qcom,ids.h>
 
index fff312c6968dd37c06369b2bd0d49eba0b05f804..4f3dd70d6a1a78fff6679fb5ac1c6599627d8c93 100644 (file)
@@ -376,11 +376,12 @@ static int intel_hw_params(struct snd_pcm_substream *substream,
 static int intel_prepare(struct snd_pcm_substream *substream,
                         struct snd_soc_dai *dai)
 {
+       struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
        struct sdw_cdns *cdns = snd_soc_dai_get_drvdata(dai);
        struct sdw_intel *sdw = cdns_to_intel(cdns);
        struct sdw_cdns_dai_runtime *dai_runtime;
+       struct snd_pcm_hw_params *hw_params;
        int ch, dir;
-       int ret = 0;
 
        dai_runtime = cdns->dai_runtime_array[dai->id];
        if (!dai_runtime) {
@@ -389,12 +390,8 @@ static int intel_prepare(struct snd_pcm_substream *substream,
                return -EIO;
        }
 
+       hw_params = &rtd->dpcm[substream->stream].hw_params;
        if (dai_runtime->suspended) {
-               struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
-               struct snd_pcm_hw_params *hw_params;
-
-               hw_params = &rtd->dpcm[substream->stream].hw_params;
-
                dai_runtime->suspended = false;
 
                /*
@@ -415,15 +412,11 @@ static int intel_prepare(struct snd_pcm_substream *substream,
                /* the SHIM will be configured in the callback functions */
 
                sdw_cdns_config_stream(cdns, ch, dir, dai_runtime->pdi);
-
-               /* Inform DSP about PDI stream number */
-               ret = intel_params_stream(sdw, substream, dai,
-                                         hw_params,
-                                         sdw->instance,
-                                         dai_runtime->pdi->intel_alh_id);
        }
 
-       return ret;
+       /* Inform DSP about PDI stream number */
+       return intel_params_stream(sdw, substream, dai, hw_params, sdw->instance,
+                                  dai_runtime->pdi->intel_alh_id);
 }
 
 static int
index 4f288f07e38f918d06922f5f10961a0a74a479b2..95cdfc28361ef7bfdf880de55ff31c1c86742959 100644 (file)
@@ -377,7 +377,7 @@ static int atmel_qspi_set_cfg(struct atmel_qspi *aq,
         */
        if (!(aq->mr & QSPI_MR_SMM)) {
                aq->mr |= QSPI_MR_SMM;
-               atmel_qspi_write(aq->scr, aq, QSPI_MR);
+               atmel_qspi_write(aq->mr, aq, QSPI_MR);
        }
 
        /* Clear pending interrupts */
index 94458df53eae23a975ac9fd061dffbc167174c2c..1369691a997bfc307303ba3940b05955809622ce 100644 (file)
@@ -23,7 +23,7 @@
 #include <linux/spi/spi.h>
 #include <linux/spi/spi-mem.h>
 #include <linux/types.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 /* SPI */
 #define REG_SPI_CTRL_BASE                      0x1FA10000
index e07e081de5ea418e9fcc7d6aae5a3eeedda94d86..3c87d2bf786a9e04a8e118cc9c5c847a176cd717 100644 (file)
@@ -678,8 +678,8 @@ static int cdns_spi_probe(struct platform_device *pdev)
 
 clk_dis_all:
        if (!spi_controller_is_target(ctlr)) {
-               pm_runtime_set_suspended(&pdev->dev);
                pm_runtime_disable(&pdev->dev);
+               pm_runtime_set_suspended(&pdev->dev);
        }
 remove_ctlr:
        spi_controller_put(ctlr);
@@ -701,8 +701,10 @@ static void cdns_spi_remove(struct platform_device *pdev)
 
        cdns_spi_write(xspi, CDNS_SPI_ER, CDNS_SPI_ER_DISABLE);
 
-       pm_runtime_set_suspended(&pdev->dev);
-       pm_runtime_disable(&pdev->dev);
+       if (!spi_controller_is_target(ctlr)) {
+               pm_runtime_disable(&pdev->dev);
+               pm_runtime_set_suspended(&pdev->dev);
+       }
 
        spi_unregister_controller(ctlr);
 }
index d319dc357fef078fb1f5f81ea22610cb910039d8..4ba1d9245c9fd1367095b4bdd4e43248c8aff648 100644 (file)
@@ -12,7 +12,7 @@
 #include <linux/mfd/dln2.h>
 #include <linux/spi/spi.h>
 #include <linux/pm_runtime.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #define DLN2_SPI_MODULE_ID             0x02
 #define DLN2_SPI_CMD(cmd)              DLN2_CMD(cmd, DLN2_SPI_MODULE_ID)
index 191de1917f8316784e07a3737f491dcba2388427..3fa990fb59c78b3cb04061f4c006aa9975f103a2 100644 (file)
@@ -1003,6 +1003,7 @@ static int dspi_setup(struct spi_device *spi)
        u32 cs_sck_delay = 0, sck_cs_delay = 0;
        struct fsl_dspi_platform_data *pdata;
        unsigned char pasc = 0, asc = 0;
+       struct gpio_desc *gpio_cs;
        struct chip_data *chip;
        unsigned long clkrate;
        bool cs = true;
@@ -1077,7 +1078,10 @@ static int dspi_setup(struct spi_device *spi)
                        chip->ctar_val |= SPI_CTAR_LSBFE;
        }
 
-       gpiod_direction_output(spi_get_csgpiod(spi, 0), false);
+       gpio_cs = spi_get_csgpiod(spi, 0);
+       if (gpio_cs)
+               gpiod_direction_output(gpio_cs, false);
+
        dspi_deassert_cs(spi, &cs);
 
        spi_set_ctldata(spi, chip);
index f6e40f90418f4221f02e3eb00164cca7c0e32fef..768d7482102adec9b7178077724dc3976a2760c8 100644 (file)
@@ -1116,6 +1116,11 @@ static int spi_geni_probe(struct platform_device *pdev)
        init_completion(&mas->tx_reset_done);
        init_completion(&mas->rx_reset_done);
        spin_lock_init(&mas->lock);
+
+       ret = geni_icc_get(&mas->se, NULL);
+       if (ret)
+               return ret;
+
        pm_runtime_use_autosuspend(&pdev->dev);
        pm_runtime_set_autosuspend_delay(&pdev->dev, 250);
        ret = devm_pm_runtime_enable(dev);
@@ -1125,9 +1130,6 @@ static int spi_geni_probe(struct platform_device *pdev)
        if (device_property_read_bool(&pdev->dev, "spi-slave"))
                spi->target = true;
 
-       ret = geni_icc_get(&mas->se, NULL);
-       if (ret)
-               return ret;
        /* Set the bus quota to a reasonable value for register access */
        mas->se.icc_paths[GENI_TO_CORE].avg_bw = Bps_to_icc(CORE_2X_50_MHZ);
        mas->se.icc_paths[CPU_TO_GENI].avg_bw = GENI_DEFAULT_BW;
index 85bd1a82a34eb4bc76a4b4528e087fc2ebfa8b85..4c31d36f3130a95cf87c74b6dd6c0ebe2fc86f93 100644 (file)
@@ -1865,8 +1865,8 @@ out_register_controller:
                spi_imx_sdma_exit(spi_imx);
 out_runtime_pm_put:
        pm_runtime_dont_use_autosuspend(spi_imx->dev);
-       pm_runtime_set_suspended(&pdev->dev);
        pm_runtime_disable(spi_imx->dev);
+       pm_runtime_set_suspended(&pdev->dev);
 
        clk_disable_unprepare(spi_imx->clk_ipg);
 out_put_per:
index ddd98ddb79130a77c831b82d14355f65f0bd99c3..c5677fd94e5e147addec28b0ee08e9c18d57584b 100644 (file)
@@ -1187,7 +1187,7 @@ cleanup:
 
 /**
  * mtk_snand_is_page_ops() - check if the op is a controller supported page op.
- * @op spi-mem op to check
+ * @op: spi-mem op to check
  *
  * Check whether op can be executed with read_from_cache or program_load
  * mode in the controller.
index a7feb20b06eee1112653e46d6c0d219b09515f17..30aa37b0c3b82f13932fdab09c0b971e87f9c850 100644 (file)
@@ -12,7 +12,7 @@
 #include <linux/spi/spi.h>
 #include <linux/reset.h>
 
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #include <linux/regmap.h>
 #include <linux/mfd/syscon.h>
index eee9ff4bfa5b57f10effb3966266a6d2bdcda236..4730e4ba8901014dc8dd19eaf883f9e4be9dc077 100644 (file)
@@ -18,7 +18,7 @@
 #include <linux/of_address.h>
 #include <linux/clk.h>
 #include <linux/sizes.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #define DRIVER_NAME                    "orion_spi"
 
index b468a95972bf7290eab7e656aaf68ece5bf643a6..c24dad51a0e96624ae980da4e0cf81215e205704 100644 (file)
@@ -14,7 +14,7 @@
 
 #include <memory/renesas-rpc-if.h>
 
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 static void rpcif_spi_mem_prepare(struct spi_device *spi_dev,
                                  const struct spi_mem_op *spi_op,
index 51a002b3f51887b18ba5f40878026f59152d79b4..8c9e5e97041f9c575d06cfb0d18d0c10003173c2 100644 (file)
@@ -245,7 +245,7 @@ static void s3c64xx_flush_fifo(struct s3c64xx_spi_driver_data *sdd)
        loops = msecs_to_loops(1);
        do {
                val = readl(regs + S3C64XX_SPI_STATUS);
-       } while (TX_FIFO_LVL(val, sdd) && loops--);
+       } while (TX_FIFO_LVL(val, sdd) && --loops);
 
        if (loops == 0)
                dev_warn(&sdd->pdev->dev, "Timed out flushing TX FIFO\n");
@@ -258,7 +258,7 @@ static void s3c64xx_flush_fifo(struct s3c64xx_spi_driver_data *sdd)
                        readl(regs + S3C64XX_SPI_RX_DATA);
                else
                        break;
-       } while (loops--);
+       } while (--loops);
 
        if (loops == 0)
                dev_warn(&sdd->pdev->dev, "Timed out flushing RX FIFO\n");
index 6f12e4fb2e2e184f1bb4cf9fe12e5437384fc4ac..3519656515ea12a96cb4b591d2ba4a34691621e6 100644 (file)
@@ -27,7 +27,7 @@
 #include <linux/spi/sh_msiof.h>
 #include <linux/spi/spi.h>
 
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #define SH_MSIOF_FLAG_FIXED_DTDL_200   BIT(0)
 
index 4c4ff074e3f6f84caa2c9aa617f9808405093b04..fc72a89fb3a7b7602016b67d875fcad0e2d140b4 100644 (file)
@@ -2044,6 +2044,7 @@ static const struct stm32_spi_cfg stm32mp25_spi_cfg = {
        .baud_rate_div_max = STM32H7_SPI_MBR_DIV_MAX,
        .has_fifo = true,
        .prevent_dma_burst = true,
+       .has_device_mode = true,
 };
 
 static const struct of_device_id stm32_spi_of_match[] = {
index 4a18cf89619473f825160d5bf45be728e6478a66..07b155980e712c1edf25320cd736dc81274a41d2 100644 (file)
@@ -15,7 +15,7 @@
 #include <linux/platform_device.h>
 #include <linux/spi/spi.h>
 
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #define SSI_TIMEOUT_MS         2000
 #define SSI_POLL_TIMEOUT_US    200
index 846f00e23b7176863b2ed51db11d03f85e42ae2e..3bd0149d8f4eaeb0abcb29b815420c8e7f2c9c82 100644 (file)
@@ -12,7 +12,7 @@
 #include <linux/i2c.h>
 #include <linux/gpio/driver.h>
 #include <linux/spi/spi.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #define SPI_XCOMM_SETTINGS_LEN_OFFSET          10
 #define SPI_XCOMM_SETTINGS_3WIRE               BIT(6)
index 6c390c4eb26deaa5c716facf3e69e51436545067..492612e8f8bad5bbbda14daec6a558934323518d 100644 (file)
@@ -129,12 +129,15 @@ static unsigned long ad9832_calc_freqreg(unsigned long mclk, unsigned long fout)
 static int ad9832_write_frequency(struct ad9832_state *st,
                                  unsigned int addr, unsigned long fout)
 {
+       unsigned long clk_freq;
        unsigned long regval;
 
-       if (fout > (clk_get_rate(st->mclk) / 2))
+       clk_freq = clk_get_rate(st->mclk);
+
+       if (!clk_freq || fout > (clk_freq / 2))
                return -EINVAL;
 
-       regval = ad9832_calc_freqreg(clk_get_rate(st->mclk), fout);
+       regval = ad9832_calc_freqreg(clk_freq, fout);
 
        st->freq_data[0] = cpu_to_be16((AD9832_CMD_FRE8BITSW << CMD_SHIFT) |
                                        (addr << ADD_SHIFT) |
index 728b3892a20c455dc80bf34bdd6f752621fb5ef6..bc9a2a40afcb5483bdac584aa64c2babcd663089 100644 (file)
@@ -32,7 +32,7 @@
 #include <linux/i2c.h>
 #include <linux/kthread.h>
 #include <linux/slab.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include <asm/byteorder.h>
 
 #include <linux/dvb/frontend.h>
index 834329886ea2efa0d101118d5fe75ca3fd6061f8..c400d4f8ff9a24aa17fb161c02e63214c392d30d 100644 (file)
@@ -5,7 +5,7 @@
  * Contact Information: wlanfae <[email protected]>
  */
 #include <asm/byteorder.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include <linux/etherdevice.h>
 #include "rtllib.h"
 #include "rtl819x_BA.h"
index e55b4f7e0aef64b2e3dd9bf92e338bc2c147e3b0..a6dc88dd4ba15806a930fba78eacd4b1e2799c49 100644 (file)
@@ -6,7 +6,7 @@
  ******************************************************************************/
 
 #include <drv_types.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 void init_mlme_ap_info(struct adapter *padapter)
 {
index 5a76069a8222b8ef23f17e53e25c76e2b2706fd7..0ed420f3d09628a5f73d4188b018d6cd27c8b59d 100644 (file)
@@ -7,7 +7,7 @@
 
 #include <drv_types.h>
 #include <linux/of.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 u8 RTW_WPA_OUI_TYPE[] = { 0x00, 0x50, 0xf2, 1 };
 u16 RTW_WPA_VERSION = 1;
index bbdd5fce28a1e4d62e3a86f096c708cfd9b2d586..4d4bec47d1874cd125fc8fdb034c664f7c4efa16 100644 (file)
@@ -8,7 +8,7 @@
 #include <rtw_wifi_regd.h>
 #include <hal_btcoex.h>
 #include <linux/kernel.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 static struct mlme_handler mlme_sta_tbl[] = {
        {WIFI_ASSOCREQ,         "OnAssocReq",   &OnAssocReq},
index b30f026789b684a4ff5f497dc3bcb7f8c984a829..a389ba5ecc6f6dfeff7925d1eee6289ea96ee472 100644 (file)
@@ -8,7 +8,7 @@
 #include <linux/jiffies.h>
 #include <rtw_recv.h>
 #include <net/cfg80211.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 static u8 SNAP_ETH_TYPE_IPX[2] = {0x81, 0x37};
 static u8 SNAP_ETH_TYPE_APPLETALK_AARP[2] = {0x80, 0xf3};
index 746f45cf9aac5596a55e992243304dd4679054a2..ca808ded61ac0fd78a53b4804fb3ace386e81394 100644 (file)
@@ -7,7 +7,7 @@
 #include <drv_types.h>
 #include <linux/jiffies.h>
 #include <net/cfg80211.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 void rtw_os_free_recvframe(union recv_frame *precvframe)
 {
index acfc39683c87f07b16a5ed6e42477968e99a159e..3698f2eb097e37168d9bb882655ea8db2933a272 100644 (file)
@@ -7,7 +7,7 @@
 #include <linux/kthread.h>
 #include <linux/sched/signal.h>
 
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include <net/tcp.h>
 #include <target/target_core_base.h>
 #include <target/target_core_fabric.h>
index 1d25e64b068a02867b1320d1c29577cb8d6c81e9..6002283cbebabc474b405a21ab2b1960c33cb836 100644 (file)
@@ -17,7 +17,7 @@
 #include <linux/idr.h>
 #include <linux/delay.h>
 #include <linux/sched/signal.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include <linux/inet.h>
 #include <net/ipv6.h>
 #include <scsi/scsi_proto.h>
index 9c4aa01b6351b5b578705e16ee0985af0e75fa03..f60b156ede12eb3b199d769c2498e3d1ebb6432a 100644 (file)
@@ -8,7 +8,7 @@
  *
  ******************************************************************************/
 
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include <scsi/scsi_proto.h>
 #include <scsi/iscsi_proto.h>
 #include <target/target_core_base.h>
index b604fcae21e1125bc6d1a7767f1072ef9ce9dc3c..3b89b5a70331f625c067dbcccf655a12347d9445 100644 (file)
@@ -23,7 +23,7 @@
 #include <target/target_core_base.h>
 #include <target/target_core_backend.h>
 #include <target/target_core_fabric.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #include "sbp_target.h"
 
index 01751faad38663ef6bd95e118c07df52d40b4fa0..10250aca5a816a2d6c3df9d49e4aae7f2418b846 100644 (file)
@@ -19,7 +19,7 @@
 #include <linux/file.h>
 #include <linux/fs.h>
 #include <scsi/scsi_proto.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #include <target/target_core_base.h>
 #include <target/target_core_backend.h>
index bf4892544cfdb4f5aeb0db262f3355b6b40b6155..d1ae3df069a4f3217ab9cca7db2a411520527799 100644 (file)
@@ -21,7 +21,7 @@
 #include <linux/in.h>
 #include <linux/export.h>
 #include <linux/t10-pi.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include <net/sock.h>
 #include <net/tcp.h>
 #include <scsi/scsi_common.h>
@@ -691,7 +691,7 @@ struct se_device *target_alloc_device(struct se_hba *hba, const char *name)
 
        dev->queues = kcalloc(nr_cpu_ids, sizeof(*dev->queues), GFP_KERNEL);
        if (!dev->queues) {
-               dev->transport->free_device(dev);
+               hba->backend->ops->free_device(dev);
                return NULL;
        }
 
index 6600ae44f29d9e969e4c3c15f4add85564a15616..43f47e3aa4482c03d52529cddda1b73995e4b1bc 100644 (file)
@@ -21,7 +21,7 @@
 #include <linux/ctype.h>
 #include <linux/spinlock.h>
 #include <linux/export.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #include <scsi/scsi_proto.h>
 
index 94e6cd4e7e43dff4ca6b641528311ba42d441717..2d78ef74633c8b17116be2a6393a14929a8093cd 100644 (file)
@@ -22,7 +22,7 @@
 #include <linux/uio.h>
 #include <linux/scatterlist.h>
 #include <scsi/scsi_proto.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #include <target/target_core_base.h>
 #include <target/target_core_backend.h>
index a3e09adc4e767c505469617846577f27b47df8f0..c8dc92a7d63e64afc5ae440241041da3169cf5be 100644 (file)
@@ -26,7 +26,7 @@
 #include <linux/pr.h>
 #include <scsi/scsi_proto.h>
 #include <scsi/scsi_common.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #include <target/target_core_base.h>
 #include <target/target_core_backend.h>
index 80b7d85030d006760132d22d061164f889de9a5d..4f4ad6af416c8fa721c3c6edd6566ce06d0c32eb 100644 (file)
@@ -19,7 +19,7 @@
 #include <linux/fcntl.h>
 #include <linux/fs.h>
 #include <scsi/scsi_proto.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #include <target/target_core_base.h>
 #include <target/target_core_backend.h>
index f98ebb18666bf09354daa36a97c04a8755f3233b..440e07b1d5cdb1326f23fc23467905f26ec37ab1 100644 (file)
@@ -20,7 +20,7 @@
 #include <linux/cdrom.h>
 #include <linux/ratelimit.h>
 #include <linux/module.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #include <scsi/scsi_device.h>
 #include <scsi/scsi_host.h>
index 6a02561cc20ce9fb73fbc5f25ee5db0f375058fc..fe8beb7dbab12ab6eba74b107b429ae97b7413a1 100644 (file)
@@ -12,7 +12,7 @@
 #include <linux/ratelimit.h>
 #include <linux/crc-t10dif.h>
 #include <linux/t10-pi.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include <scsi/scsi_proto.h>
 #include <scsi/scsi_tcq.h>
 
index 50290abc07bc23869b7aad67ae714756507b0ee8..ea14a38356814d3afd0c942c17e1be1ff615d186 100644 (file)
@@ -9,7 +9,7 @@
 
 #include <linux/kernel.h>
 #include <linux/module.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #include <scsi/scsi_proto.h>
 #include <scsi/scsi_common.h>
index 73d0d6133ac8f2860323a98662db7a21acfe2d6c..05d29201b730f0ef970f6c3962e9c02d17492a9b 100644 (file)
@@ -22,7 +22,7 @@
 #include <linux/module.h>
 #include <linux/ratelimit.h>
 #include <linux/vmalloc.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include <net/sock.h>
 #include <net/tcp.h>
 #include <scsi/scsi_proto.h>
index 7eb94894bd68faf639a9fc02da004b986df89c2b..717931267bda0c52829c628d09cbfbf80ea63a54 100644 (file)
@@ -2130,7 +2130,7 @@ static int tcmu_netlink_event_send(struct tcmu_dev *udev,
        }
 
        ret = genlmsg_multicast_allns(&tcmu_genl_family, skb, 0,
-                                     TCMU_MCGRP_CONFIG, GFP_KERNEL);
+                                     TCMU_MCGRP_CONFIG);
 
        /* Wait during an add as the listener may not be up yet */
        if (ret == 0 ||
index 4128631c9dfdd365d75534791d211c8a242ee543..877ce58c0a708d2621660686706225f8cfb864ae 100644 (file)
@@ -19,7 +19,7 @@
 #include <linux/configfs.h>
 #include <linux/ratelimit.h>
 #include <scsi/scsi_proto.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #include <target/target_core_base.h>
 #include <target/target_core_backend.h>
index 21783cd71c15d247a0f6de672f7f652bdb08f0b7..34ab628809e82c7f97d5a4550fd4ed3a4356cd20 100644 (file)
@@ -16,7 +16,7 @@
 #include <linux/configfs.h>
 #include <linux/ctype.h>
 #include <linux/hash.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include <scsi/scsi_tcq.h>
 #include <scsi/libfc.h>
 
index 5ee03d1cba2bee5fbe04b0ba8122cf5ac4513dff..639fc358ed0fdb3b425d68211af19ed79170bd0d 100644 (file)
@@ -25,7 +25,7 @@
 #include <linux/configfs.h>
 #include <linux/kernel.h>
 #include <linux/ctype.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include <scsi/libfc.h>
 
 #include <target/target_core_base.h>
index bbe2e29612fa85d49eff0eea819f3c6cccfee798..45329284f52f591bd402df94e9ce2f443850a75f 100644 (file)
@@ -26,7 +26,7 @@
 #include <linux/ctype.h>
 #include <linux/hash.h>
 #include <linux/ratelimit.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include <scsi/libfc.h>
 
 #include <target/target_core_base.h>
index 593540da93465ba855a75bceb853b0c8874edd94..d6afaba52ea561b3139529eaa61f57e458a6a61b 100644 (file)
@@ -19,7 +19,7 @@
 #include <linux/rcupdate.h>
 #include <linux/rculist.h>
 #include <linux/kref.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include <scsi/libfc.h>
 
 #include <target/target_core_base.h>
index 006614921870288f607e9c067dfa70f28b41af28..ba5d36d36fc404c9e69279a961d3b63383f53903 100644 (file)
@@ -416,7 +416,6 @@ err_del_legacy:
        if (!pci_info->no_legacy)
                proc_thermal_remove(proc_priv);
        proc_thermal_mmio_remove(pdev, proc_priv);
-       pci_disable_device(pdev);
 
        return ret;
 }
@@ -438,7 +437,6 @@ static void proc_thermal_pci_remove(struct pci_dev *pdev)
        proc_thermal_mmio_remove(pdev, pci_info->proc_priv);
        if (!pci_info->no_legacy)
                proc_thermal_remove(proc_priv);
-       pci_disable_device(pdev);
 }
 
 #ifdef CONFIG_PM_SLEEP
index e9aa9e23aab9ec9db2e17206ac8bc51a67f862d4..bde2cc386afdda62d11d51837de9e66c3cf26a9e 100644 (file)
@@ -13,48 +13,12 @@ static struct rapl_if_priv rapl_mmio_priv;
 
 static const struct rapl_mmio_regs rapl_mmio_default = {
        .reg_unit = 0x5938,
-       .regs[RAPL_DOMAIN_PACKAGE] = { 0x59a0, 0x593c, 0x58f0, 0, 0x5930},
+       .regs[RAPL_DOMAIN_PACKAGE] = { 0x59a0, 0x593c, 0x58f0, 0, 0x5930, 0x59b0},
        .regs[RAPL_DOMAIN_DRAM] = { 0x58e0, 0x58e8, 0x58ec, 0, 0},
-       .limits[RAPL_DOMAIN_PACKAGE] = BIT(POWER_LIMIT2),
+       .limits[RAPL_DOMAIN_PACKAGE] = BIT(POWER_LIMIT2) | BIT(POWER_LIMIT4),
        .limits[RAPL_DOMAIN_DRAM] = BIT(POWER_LIMIT2),
 };
 
-static int rapl_mmio_cpu_online(unsigned int cpu)
-{
-       struct rapl_package *rp;
-
-       /* mmio rapl supports package 0 only for now */
-       if (topology_physical_package_id(cpu))
-               return 0;
-
-       rp = rapl_find_package_domain_cpuslocked(cpu, &rapl_mmio_priv, true);
-       if (!rp) {
-               rp = rapl_add_package_cpuslocked(cpu, &rapl_mmio_priv, true);
-               if (IS_ERR(rp))
-                       return PTR_ERR(rp);
-       }
-       cpumask_set_cpu(cpu, &rp->cpumask);
-       return 0;
-}
-
-static int rapl_mmio_cpu_down_prep(unsigned int cpu)
-{
-       struct rapl_package *rp;
-       int lead_cpu;
-
-       rp = rapl_find_package_domain_cpuslocked(cpu, &rapl_mmio_priv, true);
-       if (!rp)
-               return 0;
-
-       cpumask_clear_cpu(cpu, &rp->cpumask);
-       lead_cpu = cpumask_first(&rp->cpumask);
-       if (lead_cpu >= nr_cpu_ids)
-               rapl_remove_package_cpuslocked(rp);
-       else if (rp->lead_cpu == cpu)
-               rp->lead_cpu = lead_cpu;
-       return 0;
-}
-
 static int rapl_mmio_read_raw(int cpu, struct reg_action *ra)
 {
        if (!ra->reg.mmio)
@@ -82,6 +46,7 @@ static int rapl_mmio_write_raw(int cpu, struct reg_action *ra)
 int proc_thermal_rapl_add(struct pci_dev *pdev, struct proc_thermal_device *proc_priv)
 {
        const struct rapl_mmio_regs *rapl_regs = &rapl_mmio_default;
+       struct rapl_package *rp;
        enum rapl_domain_reg_id reg;
        enum rapl_domain_type domain;
        int ret;
@@ -109,25 +74,38 @@ int proc_thermal_rapl_add(struct pci_dev *pdev, struct proc_thermal_device *proc
                return PTR_ERR(rapl_mmio_priv.control_type);
        }
 
-       ret = cpuhp_setup_state(CPUHP_AP_ONLINE_DYN, "powercap/rapl:online",
-                               rapl_mmio_cpu_online, rapl_mmio_cpu_down_prep);
-       if (ret < 0) {
-               powercap_unregister_control_type(rapl_mmio_priv.control_type);
-               rapl_mmio_priv.control_type = NULL;
-               return ret;
+       /* Register a RAPL package device for package 0 which is always online */
+       rp = rapl_find_package_domain(0, &rapl_mmio_priv, false);
+       if (rp) {
+               ret = -EEXIST;
+               goto err;
+       }
+
+       rp = rapl_add_package(0, &rapl_mmio_priv, false);
+       if (IS_ERR(rp)) {
+               ret = PTR_ERR(rp);
+               goto err;
        }
-       rapl_mmio_priv.pcap_rapl_online = ret;
 
        return 0;
+
+err:
+       powercap_unregister_control_type(rapl_mmio_priv.control_type);
+       rapl_mmio_priv.control_type = NULL;
+       return ret;
 }
 EXPORT_SYMBOL_GPL(proc_thermal_rapl_add);
 
 void proc_thermal_rapl_remove(void)
 {
+       struct rapl_package *rp;
+
        if (IS_ERR_OR_NULL(rapl_mmio_priv.control_type))
                return;
 
-       cpuhp_remove_state(rapl_mmio_priv.pcap_rapl_online);
+       rp = rapl_find_package_domain(0, &rapl_mmio_priv, false);
+       if (rp)
+               rapl_remove_package(rp);
        powercap_unregister_control_type(rapl_mmio_priv.control_type);
 }
 EXPORT_SYMBOL_GPL(proc_thermal_rapl_remove);
index 7c9f4023babcfc75ae90d2c4b7370406036e8a4f..5e94a45eba3eef65e436a01b3aa58aabf5f706c2 100644 (file)
@@ -18,7 +18,7 @@
 #include <linux/regmap.h>
 #include <linux/thermal.h>
 
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #include "../thermal_hwmon.h"
 
index 073d02e21352e69c183394b0c396449326a6625b..8f03985f971c3058dc1ed6018d8d3dea86b733bc 100644 (file)
@@ -728,6 +728,7 @@ struct thermal_zone_device *thermal_zone_get_by_id(int id)
        mutex_lock(&thermal_list_lock);
        list_for_each_entry(tz, &thermal_tz_list, node) {
                if (tz->id == id) {
+                       get_device(&tz->device);
                        match = tz;
                        break;
                }
@@ -1605,14 +1606,12 @@ void thermal_zone_device_unregister(struct thermal_zone_device *tz)
        ida_destroy(&tz->ida);
 
        device_del(&tz->device);
-
-       kfree(tz->tzp);
-
        put_device(&tz->device);
 
        thermal_notify_tz_delete(tz);
 
        wait_for_completion(&tz->removal);
+       kfree(tz->tzp);
        kfree(tz);
 }
 EXPORT_SYMBOL_GPL(thermal_zone_device_unregister);
index 50b858aa173a070e6cc993efd246b9c9449ff277..a64d39b1c86b235cb1dd624b17e1599a70fe74ad 100644 (file)
@@ -194,6 +194,9 @@ int for_each_thermal_governor(int (*cb)(struct thermal_governor *, void *),
 
 struct thermal_zone_device *thermal_zone_get_by_id(int id);
 
+DEFINE_CLASS(thermal_zone_get_by_id, struct thermal_zone_device *,
+            if (_T) put_device(&_T->device), thermal_zone_get_by_id(id), int id)
+
 static inline bool cdev_is_power_actor(struct thermal_cooling_device *cdev)
 {
        return cdev->ops->get_requested_power && cdev->ops->state2power &&
index 97157c4536301963414e28927ba73cf15fbda8af..f3c58c708969c2c5bfcc700c67baabe53521bf84 100644 (file)
@@ -443,7 +443,6 @@ static int thermal_genl_cmd_tz_get_trip(struct param *p)
 {
        struct sk_buff *msg = p->msg;
        const struct thermal_trip_desc *td;
-       struct thermal_zone_device *tz;
        struct nlattr *start_trip;
        int id;
 
@@ -452,7 +451,7 @@ static int thermal_genl_cmd_tz_get_trip(struct param *p)
 
        id = nla_get_u32(p->attrs[THERMAL_GENL_ATTR_TZ_ID]);
 
-       tz = thermal_zone_get_by_id(id);
+       CLASS(thermal_zone_get_by_id, tz)(id);
        if (!tz)
                return -EINVAL;
 
@@ -488,7 +487,6 @@ out_cancel_nest:
 static int thermal_genl_cmd_tz_get_temp(struct param *p)
 {
        struct sk_buff *msg = p->msg;
-       struct thermal_zone_device *tz;
        int temp, ret, id;
 
        if (!p->attrs[THERMAL_GENL_ATTR_TZ_ID])
@@ -496,7 +494,7 @@ static int thermal_genl_cmd_tz_get_temp(struct param *p)
 
        id = nla_get_u32(p->attrs[THERMAL_GENL_ATTR_TZ_ID]);
 
-       tz = thermal_zone_get_by_id(id);
+       CLASS(thermal_zone_get_by_id, tz)(id);
        if (!tz)
                return -EINVAL;
 
@@ -514,7 +512,6 @@ static int thermal_genl_cmd_tz_get_temp(struct param *p)
 static int thermal_genl_cmd_tz_get_gov(struct param *p)
 {
        struct sk_buff *msg = p->msg;
-       struct thermal_zone_device *tz;
        int id, ret = 0;
 
        if (!p->attrs[THERMAL_GENL_ATTR_TZ_ID])
@@ -522,7 +519,7 @@ static int thermal_genl_cmd_tz_get_gov(struct param *p)
 
        id = nla_get_u32(p->attrs[THERMAL_GENL_ATTR_TZ_ID]);
 
-       tz = thermal_zone_get_by_id(id);
+       CLASS(thermal_zone_get_by_id, tz)(id);
        if (!tz)
                return -EINVAL;
 
index 721319329afa96b34ff7518c3c06b27273cc753c..7db9869a9f3fe7681301c7586b13569597fea9a3 100644 (file)
@@ -516,7 +516,7 @@ int tb_retimer_scan(struct tb_port *port, bool add)
         */
        tb_retimer_set_inbound_sbtx(port);
 
-       for (i = 1; i <= TB_MAX_RETIMER_INDEX; i++) {
+       for (max = 1, i = 1; i <= TB_MAX_RETIMER_INDEX; i++) {
                /*
                 * Last retimer is true only for the last on-board
                 * retimer (the one connected directly to the Type-C
@@ -527,9 +527,10 @@ int tb_retimer_scan(struct tb_port *port, bool add)
                        last_idx = i;
                else if (ret < 0)
                        break;
+
+               max = i;
        }
 
-       max = i;
        ret = 0;
 
        /* Add retimers if they do not exist already */
index 10e719dd837cec7646f49b37af739016559cbc02..4f777788e9179c54c1528c65a77e04b4e9194e97 100644 (file)
@@ -288,6 +288,24 @@ static void tb_increase_tmu_accuracy(struct tb_tunnel *tunnel)
        device_for_each_child(&sw->dev, NULL, tb_increase_switch_tmu_accuracy);
 }
 
+static int tb_switch_tmu_hifi_uni_required(struct device *dev, void *not_used)
+{
+       struct tb_switch *sw = tb_to_switch(dev);
+
+       if (sw && tb_switch_tmu_is_enabled(sw) &&
+           tb_switch_tmu_is_configured(sw, TB_SWITCH_TMU_MODE_HIFI_UNI))
+               return 1;
+
+       return device_for_each_child(dev, NULL,
+                                    tb_switch_tmu_hifi_uni_required);
+}
+
+static bool tb_tmu_hifi_uni_required(struct tb *tb)
+{
+       return device_for_each_child(&tb->dev, NULL,
+                                    tb_switch_tmu_hifi_uni_required) == 1;
+}
+
 static int tb_enable_tmu(struct tb_switch *sw)
 {
        int ret;
@@ -302,12 +320,30 @@ static int tb_enable_tmu(struct tb_switch *sw)
        ret = tb_switch_tmu_configure(sw,
                        TB_SWITCH_TMU_MODE_MEDRES_ENHANCED_UNI);
        if (ret == -EOPNOTSUPP) {
-               if (tb_switch_clx_is_enabled(sw, TB_CL1))
-                       ret = tb_switch_tmu_configure(sw,
-                                       TB_SWITCH_TMU_MODE_LOWRES);
-               else
-                       ret = tb_switch_tmu_configure(sw,
-                                       TB_SWITCH_TMU_MODE_HIFI_BI);
+               if (tb_switch_clx_is_enabled(sw, TB_CL1)) {
+                       /*
+                        * Figure out uni-directional HiFi TMU requirements
+                        * currently in the domain. If there are no
+                        * uni-directional HiFi requirements we can put the TMU
+                        * into LowRes mode.
+                        *
+                        * Deliberately skip bi-directional HiFi links
+                        * as these work independently of other links
+                        * (and they do not allow any CL states anyway).
+                        */
+                       if (tb_tmu_hifi_uni_required(sw->tb))
+                               ret = tb_switch_tmu_configure(sw,
+                                               TB_SWITCH_TMU_MODE_HIFI_UNI);
+                       else
+                               ret = tb_switch_tmu_configure(sw,
+                                               TB_SWITCH_TMU_MODE_LOWRES);
+               } else {
+                       ret = tb_switch_tmu_configure(sw, TB_SWITCH_TMU_MODE_HIFI_BI);
+               }
+
+               /* If not supported, fallback to bi-directional HiFi */
+               if (ret == -EOPNOTSUPP)
+                       ret = tb_switch_tmu_configure(sw, TB_SWITCH_TMU_MODE_HIFI_BI);
        }
        if (ret)
                return ret;
index 5d37a09849163fc28a2e43c8b0bf4b5ef22980ff..252849910588f6c8fc8eaf6026048e072fc572cd 100644 (file)
@@ -3157,6 +3157,8 @@ static void gsm_cleanup_mux(struct gsm_mux *gsm, bool disc)
        mutex_unlock(&gsm->mutex);
        /* Now wipe the queues */
        tty_ldisc_flush(gsm->tty);
+
+       guard(spinlock_irqsave)(&gsm->tx_lock);
        list_for_each_entry_safe(txq, ntxq, &gsm->tx_ctrl_list, list)
                kfree(txq);
        INIT_LIST_HEAD(&gsm->tx_ctrl_list);
index 67d4a72eda770b3c8015e4ec9400222e392c45eb..90974d338f3c0bfd6b1ed8459540aab205046c89 100644 (file)
@@ -762,6 +762,21 @@ static irqreturn_t __imx_uart_rtsint(int irq, void *dev_id)
 
        imx_uart_writel(sport, USR1_RTSD, USR1);
        usr1 = imx_uart_readl(sport, USR1) & USR1_RTSS;
+       /*
+        * Update sport->old_status here, so any follow-up calls to
+        * imx_uart_mctrl_check() will be able to recognize that RTS
+        * state changed since last imx_uart_mctrl_check() call.
+        *
+        * In case RTS has been detected as asserted here and later on
+        * deasserted by the time imx_uart_mctrl_check() was called,
+        * imx_uart_mctrl_check() can detect the RTS state change and
+        * trigger uart_handle_cts_change() to unblock the port for
+        * further TX transfers.
+        */
+       if (usr1 & USR1_RTSS)
+               sport->old_status |= TIOCM_CTS;
+       else
+               sport->old_status &= ~TIOCM_CTS;
        uart_handle_cts_change(&sport->port, usr1);
        wake_up_interruptible(&sport->port.state->port.delta_msr_wait);
 
index fda63918d1eb85aec74500c0b066ad3fea90e59f..cde5f1c86353e32a1a281ffafb08a28dccb63e6c 100644 (file)
@@ -32,7 +32,7 @@
 #include <linux/tty.h>
 #include <linux/types.h>
 
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #define MAX3100_C    (1<<14)
 #define MAX3100_D    (0<<14)
index 6f0db310cf69e90b82e7ae73262d15095d4697b5..5dfe4e599ad68df1a10de0722f69035460fa51de 100644 (file)
@@ -147,6 +147,7 @@ static struct uart_driver qcom_geni_uart_driver;
 
 static void __qcom_geni_serial_cancel_tx_cmd(struct uart_port *uport);
 static void qcom_geni_serial_cancel_tx_cmd(struct uart_port *uport);
+static int qcom_geni_serial_port_setup(struct uart_port *uport);
 
 static inline struct qcom_geni_serial_port *to_dev_port(struct uart_port *uport)
 {
@@ -395,6 +396,23 @@ static void qcom_geni_serial_poll_put_char(struct uart_port *uport,
        writel(c, uport->membase + SE_GENI_TX_FIFOn);
        qcom_geni_serial_poll_tx_done(uport);
 }
+
+static int qcom_geni_serial_poll_init(struct uart_port *uport)
+{
+       struct qcom_geni_serial_port *port = to_dev_port(uport);
+       int ret;
+
+       if (!port->setup) {
+               ret = qcom_geni_serial_port_setup(uport);
+               if (ret)
+                       return ret;
+       }
+
+       if (!qcom_geni_serial_secondary_active(uport))
+               geni_se_setup_s_cmd(&port->se, UART_START_READ, 0);
+
+       return 0;
+}
 #endif
 
 #ifdef CONFIG_SERIAL_QCOM_GENI_CONSOLE
@@ -562,7 +580,7 @@ static void handle_rx_console(struct uart_port *uport, u32 bytes, bool drop)
 }
 #endif /* CONFIG_SERIAL_QCOM_GENI_CONSOLE */
 
-static void handle_rx_uart(struct uart_port *uport, u32 bytes, bool drop)
+static void handle_rx_uart(struct uart_port *uport, u32 bytes)
 {
        struct qcom_geni_serial_port *port = to_dev_port(uport);
        struct tty_port *tport = &uport->state->port;
@@ -570,9 +588,8 @@ static void handle_rx_uart(struct uart_port *uport, u32 bytes, bool drop)
 
        ret = tty_insert_flip_string(tport, port->rx_buf, bytes);
        if (ret != bytes) {
-               dev_err(uport->dev, "%s:Unable to push data ret %d_bytes %d\n",
-                               __func__, ret, bytes);
-               WARN_ON_ONCE(1);
+               dev_err_ratelimited(uport->dev, "failed to push data (%d < %u)\n",
+                               ret, bytes);
        }
        uport->icount.rx += ret;
        tty_flip_buffer_push(tport);
@@ -787,17 +804,27 @@ static void qcom_geni_serial_start_rx_fifo(struct uart_port *uport)
 static void qcom_geni_serial_stop_rx_dma(struct uart_port *uport)
 {
        struct qcom_geni_serial_port *port = to_dev_port(uport);
+       bool done;
 
        if (!qcom_geni_serial_secondary_active(uport))
                return;
 
        geni_se_cancel_s_cmd(&port->se);
-       qcom_geni_serial_poll_bit(uport, SE_GENI_S_IRQ_STATUS,
-                                 S_CMD_CANCEL_EN, true);
-
-       if (qcom_geni_serial_secondary_active(uport))
+       done = qcom_geni_serial_poll_bit(uport, SE_DMA_RX_IRQ_STAT,
+                       RX_EOT, true);
+       if (done) {
+               writel(RX_EOT | RX_DMA_DONE,
+                               uport->membase + SE_DMA_RX_IRQ_CLR);
+       } else {
                qcom_geni_serial_abort_rx(uport);
 
+               writel(1, uport->membase + SE_DMA_RX_FSM_RST);
+               qcom_geni_serial_poll_bit(uport, SE_DMA_RX_IRQ_STAT,
+                               RX_RESET_DONE, true);
+               writel(RX_RESET_DONE | RX_DMA_DONE,
+                               uport->membase + SE_DMA_RX_IRQ_CLR);
+       }
+
        if (port->rx_dma_addr) {
                geni_se_rx_dma_unprep(&port->se, port->rx_dma_addr,
                                      DMA_RX_BUF_SIZE);
@@ -846,7 +873,7 @@ static void qcom_geni_serial_handle_rx_dma(struct uart_port *uport, bool drop)
        }
 
        if (!drop)
-               handle_rx_uart(uport, rx_in, drop);
+               handle_rx_uart(uport, rx_in);
 
        ret = geni_se_rx_dma_prep(&port->se, port->rx_buf,
                                  DMA_RX_BUF_SIZE,
@@ -1096,10 +1123,12 @@ static void qcom_geni_serial_shutdown(struct uart_port *uport)
 {
        disable_irq(uport->irq);
 
+       uart_port_lock_irq(uport);
        qcom_geni_serial_stop_tx(uport);
        qcom_geni_serial_stop_rx(uport);
 
        qcom_geni_serial_cancel_tx_cmd(uport);
+       uart_port_unlock_irq(uport);
 }
 
 static void qcom_geni_serial_flush_buffer(struct uart_port *uport)
@@ -1152,7 +1181,6 @@ static int qcom_geni_serial_port_setup(struct uart_port *uport)
                               false, true, true);
        geni_se_init(&port->se, UART_RX_WM, port->rx_fifo_depth - 2);
        geni_se_select_mode(&port->se, port->dev_data->mode);
-       qcom_geni_serial_start_rx(uport);
        port->setup = true;
 
        return 0;
@@ -1168,6 +1196,11 @@ static int qcom_geni_serial_startup(struct uart_port *uport)
                if (ret)
                        return ret;
        }
+
+       uart_port_lock_irq(uport);
+       qcom_geni_serial_start_rx(uport);
+       uart_port_unlock_irq(uport);
+
        enable_irq(uport->irq);
 
        return 0;
@@ -1253,7 +1286,6 @@ static void qcom_geni_serial_set_termios(struct uart_port *uport,
        unsigned int avg_bw_core;
        unsigned long timeout;
 
-       qcom_geni_serial_stop_rx(uport);
        /* baud rate */
        baud = uart_get_baud_rate(uport, termios, old, 300, 4000000);
 
@@ -1269,7 +1301,7 @@ static void qcom_geni_serial_set_termios(struct uart_port *uport,
                dev_err(port->se.dev,
                        "Couldn't find suitable clock rate for %u\n",
                        baud * sampling_rate);
-               goto out_restart_rx;
+               return;
        }
 
        dev_dbg(port->se.dev, "desired_rate = %u, clk_rate = %lu, clk_div = %u\n",
@@ -1360,8 +1392,6 @@ static void qcom_geni_serial_set_termios(struct uart_port *uport,
        writel(stop_bit_len, uport->membase + SE_UART_TX_STOP_BIT_LEN);
        writel(ser_clk_cfg, uport->membase + GENI_SER_M_CLK_CFG);
        writel(ser_clk_cfg, uport->membase + GENI_SER_S_CLK_CFG);
-out_restart_rx:
-       qcom_geni_serial_start_rx(uport);
 }
 
 #ifdef CONFIG_SERIAL_QCOM_GENI_CONSOLE
@@ -1582,7 +1612,7 @@ static const struct uart_ops qcom_geni_console_pops = {
 #ifdef CONFIG_CONSOLE_POLL
        .poll_get_char  = qcom_geni_serial_get_char,
        .poll_put_char  = qcom_geni_serial_poll_put_char,
-       .poll_init = qcom_geni_serial_port_setup,
+       .poll_init = qcom_geni_serial_poll_init,
 #endif
        .pm = qcom_geni_serial_pm,
 };
@@ -1749,7 +1779,7 @@ static void qcom_geni_serial_remove(struct platform_device *pdev)
        uart_remove_one_port(drv, &port->uport);
 }
 
-static int qcom_geni_serial_sys_suspend(struct device *dev)
+static int qcom_geni_serial_suspend(struct device *dev)
 {
        struct qcom_geni_serial_port *port = dev_get_drvdata(dev);
        struct uart_port *uport = &port->uport;
@@ -1766,7 +1796,7 @@ static int qcom_geni_serial_sys_suspend(struct device *dev)
        return uart_suspend_port(private_data->drv, uport);
 }
 
-static int qcom_geni_serial_sys_resume(struct device *dev)
+static int qcom_geni_serial_resume(struct device *dev)
 {
        int ret;
        struct qcom_geni_serial_port *port = dev_get_drvdata(dev);
@@ -1781,38 +1811,6 @@ static int qcom_geni_serial_sys_resume(struct device *dev)
        return ret;
 }
 
-static int qcom_geni_serial_sys_hib_resume(struct device *dev)
-{
-       int ret = 0;
-       struct uart_port *uport;
-       struct qcom_geni_private_data *private_data;
-       struct qcom_geni_serial_port *port = dev_get_drvdata(dev);
-
-       uport = &port->uport;
-       private_data = uport->private_data;
-
-       if (uart_console(uport)) {
-               geni_icc_set_tag(&port->se, QCOM_ICC_TAG_ALWAYS);
-               geni_icc_set_bw(&port->se);
-               ret = uart_resume_port(private_data->drv, uport);
-               /*
-                * For hibernation usecase clients for
-                * console UART won't call port setup during restore,
-                * hence call port setup for console uart.
-                */
-               qcom_geni_serial_port_setup(uport);
-       } else {
-               /*
-                * Peripheral register settings are lost during hibernation.
-                * Update setup flag such that port setup happens again
-                * during next session. Clients of HS-UART will close and
-                * open the port during hibernation.
-                */
-               port->setup = false;
-       }
-       return ret;
-}
-
 static const struct qcom_geni_device_data qcom_geni_console_data = {
        .console = true,
        .mode = GENI_SE_FIFO,
@@ -1824,12 +1822,7 @@ static const struct qcom_geni_device_data qcom_geni_uart_data = {
 };
 
 static const struct dev_pm_ops qcom_geni_serial_pm_ops = {
-       .suspend = pm_sleep_ptr(qcom_geni_serial_sys_suspend),
-       .resume = pm_sleep_ptr(qcom_geni_serial_sys_resume),
-       .freeze = pm_sleep_ptr(qcom_geni_serial_sys_suspend),
-       .poweroff = pm_sleep_ptr(qcom_geni_serial_sys_suspend),
-       .restore = pm_sleep_ptr(qcom_geni_serial_sys_hib_resume),
-       .thaw = pm_sleep_ptr(qcom_geni_serial_sys_hib_resume),
+       SYSTEM_SLEEP_PM_OPS(qcom_geni_serial_suspend, qcom_geni_serial_resume)
 };
 
 static const struct of_device_id qcom_geni_serial_match_table[] = {
index da33c6c4691c0682d9cf87d96adbf5218f5bbf53..79b33d998d4359c571a97cf0459e02b17ad732c3 100644 (file)
@@ -48,7 +48,7 @@
 
 #include <linux/uaccess.h>
 #include <asm/byteorder.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #define HEADER_SIZE    4u
 #define CON_BUF_SIZE (IS_ENABLED(CONFIG_BASE_SMALL) ? 256 : PAGE_SIZE)
index cd87e3d1291edcddf0f672bb71e5eecd3a2bbe3d..96842ce817af47905ba795b31ef45a27dec8eb66 100644 (file)
@@ -4726,7 +4726,7 @@ static int con_font_get(struct vc_data *vc, struct console_font_op *op)
                return -EINVAL;
 
        if (op->data) {
-               font.data = kvmalloc(max_font_size, GFP_KERNEL);
+               font.data = kvzalloc(max_font_size, GFP_KERNEL);
                if (!font.data)
                        return -ENOMEM;
        } else
index 5891cdacd0b3c59360324476669ef10226053624..dba935c712d64b895aa1d34288c9639825066516 100644 (file)
@@ -7,7 +7,7 @@
  *     Can Guo <[email protected]>
  */
 
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include <linux/dma-mapping.h>
 #include <linux/module.h>
 #include <linux/platform_device.h>
@@ -539,7 +539,7 @@ int ufshcd_mcq_sq_cleanup(struct ufs_hba *hba, int task_tag)
        struct scsi_cmnd *cmd = lrbp->cmd;
        struct ufs_hw_queue *hwq;
        void __iomem *reg, *opr_sqd_base;
-       u32 nexus, id, val;
+       u32 nexus, id, val, rtc;
        int err;
 
        if (hba->quirks & UFSHCD_QUIRK_MCQ_BROKEN_RTC)
@@ -569,17 +569,18 @@ int ufshcd_mcq_sq_cleanup(struct ufs_hba *hba, int task_tag)
        opr_sqd_base = mcq_opr_base(hba, OPR_SQD, id);
        writel(nexus, opr_sqd_base + REG_SQCTI);
 
-       /* SQRTCy.ICU = 1 */
-       writel(SQ_ICU, opr_sqd_base + REG_SQRTC);
+       /* Initiate Cleanup */
+       writel(readl(opr_sqd_base + REG_SQRTC) | SQ_ICU,
+               opr_sqd_base + REG_SQRTC);
 
        /* Poll SQRTSy.CUS = 1. Return result from SQRTSy.RTC */
        reg = opr_sqd_base + REG_SQRTS;
        err = read_poll_timeout(readl, val, val & SQ_CUS, 20,
                                MCQ_POLL_US, false, reg);
-       if (err)
-               dev_err(hba->dev, "%s: failed. hwq=%d, tag=%d err=%ld\n",
-                       __func__, id, task_tag,
-                       FIELD_GET(SQ_ICU_ERR_CODE_MASK, readl(reg)));
+       rtc = FIELD_GET(SQ_ICU_ERR_CODE_MASK, readl(reg));
+       if (err || rtc)
+               dev_err(hba->dev, "%s: failed. hwq=%d, tag=%d err=%d RTC=%d\n",
+                       __func__, id, task_tag, err, rtc);
 
        if (ufshcd_mcq_sq_start(hba, hwq))
                err = -ETIMEDOUT;
index fe313800aed0261463b99f37e0c31e2626ead9fb..265f21133b633e36790205d58338a98dd30ed3ad 100644 (file)
@@ -4,7 +4,7 @@
 #include <linux/err.h>
 #include <linux/string.h>
 #include <linux/bitfield.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #include <ufs/ufs.h>
 #include <ufs/unipro.h>
index 24a32e2fd75e4b4efffbc32e3e28cf7bab6996b7..f5846598d80e69b3ba01e8cdcae3fcf7d867b7d9 100644 (file)
@@ -36,7 +36,7 @@
 #include "ufs-fault-injection.h"
 #include "ufs_bsg.h"
 #include "ufshcd-crypto.h"
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #define CREATE_TRACE_POINTS
 #include "ufs_trace.h"
@@ -2933,9 +2933,8 @@ static void ufshcd_init_lrb(struct ufs_hba *hba, struct ufshcd_lrb *lrb, int i)
        struct utp_transfer_req_desc *utrdlp = hba->utrdl_base_addr;
        dma_addr_t cmd_desc_element_addr = hba->ucdl_dma_addr +
                i * ufshcd_get_ucd_size(hba);
-       u16 response_offset = offsetof(struct utp_transfer_cmd_desc,
-                                      response_upiu);
-       u16 prdt_offset = offsetof(struct utp_transfer_cmd_desc, prd_table);
+       u16 response_offset = le16_to_cpu(utrdlp[i].response_upiu_offset);
+       u16 prdt_offset = le16_to_cpu(utrdlp[i].prd_table_offset);
 
        lrb->utr_descriptor_ptr = utrdlp + i;
        lrb->utrd_dma_addr = hba->utrdl_dma_addr +
@@ -5417,10 +5416,12 @@ ufshcd_transfer_rsp_status(struct ufs_hba *hba, struct ufshcd_lrb *lrbp,
                }
                break;
        case OCS_ABORTED:
-               result |= DID_ABORT << 16;
-               break;
        case OCS_INVALID_COMMAND_STATUS:
                result |= DID_REQUEUE << 16;
+               dev_warn(hba->dev,
+                               "OCS %s from controller for tag %d\n",
+                               (ocs == OCS_ABORTED ? "aborted" : "invalid"),
+                               lrbp->task_tag);
                break;
        case OCS_INVALID_CMD_TABLE_ATTR:
        case OCS_INVALID_PRDT_ATTR:
@@ -6466,26 +6467,12 @@ static bool ufshcd_abort_one(struct request *rq, void *priv)
        struct scsi_device *sdev = cmd->device;
        struct Scsi_Host *shost = sdev->host;
        struct ufs_hba *hba = shost_priv(shost);
-       struct ufshcd_lrb *lrbp = &hba->lrb[tag];
-       struct ufs_hw_queue *hwq;
-       unsigned long flags;
 
        *ret = ufshcd_try_to_abort_task(hba, tag);
        dev_err(hba->dev, "Aborting tag %d / CDB %#02x %s\n", tag,
                hba->lrb[tag].cmd ? hba->lrb[tag].cmd->cmnd[0] : -1,
                *ret ? "failed" : "succeeded");
 
-       /* Release cmd in MCQ mode if abort succeeds */
-       if (hba->mcq_enabled && (*ret == 0)) {
-               hwq = ufshcd_mcq_req_to_hwq(hba, scsi_cmd_to_rq(lrbp->cmd));
-               if (!hwq)
-                       return 0;
-               spin_lock_irqsave(&hwq->cq_lock, flags);
-               if (ufshcd_cmd_inflight(lrbp->cmd))
-                       ufshcd_release_scsi_cmd(hba, lrbp);
-               spin_unlock_irqrestore(&hwq->cq_lock, flags);
-       }
-
        return *ret == 0;
 }
 
@@ -8232,7 +8219,7 @@ static void ufshcd_update_rtc(struct ufs_hba *hba)
 
        err = ufshcd_query_attr(hba, UPIU_QUERY_OPCODE_WRITE_ATTR, QUERY_ATTR_IDN_SECONDS_PASSED,
                                0, 0, &val);
-       ufshcd_rpm_put_sync(hba);
+       ufshcd_rpm_put(hba);
 
        if (err)
                dev_err(hba->dev, "%s: Failed to update rtc %d\n", __func__, err);
@@ -10210,7 +10197,9 @@ static void ufshcd_wl_shutdown(struct device *dev)
        shost_for_each_device(sdev, hba->host) {
                if (sdev == hba->ufs_device_wlun)
                        continue;
-               scsi_device_quiesce(sdev);
+               mutex_lock(&sdev->state_mutex);
+               scsi_device_set_state(sdev, SDEV_OFFLINE);
+               mutex_unlock(&sdev->state_mutex);
        }
        __ufshcd_wl_suspend(hba, UFS_SHUTDOWN_PM);
 
index 9ec318ef52bff2dbc897ecb1268793ea14c5e2ce..5867e6338562333e57b5c555f9ef265988931ce5 100644 (file)
@@ -8,7 +8,7 @@
  *
  */
 
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include <crypto/aes.h>
 #include <linux/arm-smccc.h>
 #include <linux/clk.h>
index 8f3b9a0a38e1dd1179eb693ff901d1d0df193e48..0dd85d2635b99804534267a85ee7967bc806e668 100644 (file)
@@ -24,7 +24,7 @@
 #include <linux/device.h>
 #include <linux/firmware.h>
 #include <linux/mutex.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #include "usbatm.h"
 
index 16703815be0c482328cb45c72dabf457eedcf4e9..e8e43c38aa1b4338c8968dcd4316f920df749700 100644 (file)
@@ -25,7 +25,7 @@
 #include <linux/slab.h>
 #include <linux/kernel.h>
 
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #include "usbatm.h"
 
index 605fea4611029bb295f2b43ff00cad20a2659de4..6b37d1c47fce13853cb98c97e53fcfc9baa0d1b1 100644 (file)
@@ -35,7 +35,7 @@
 #include <linux/usb.h>
 #include <linux/usb/cdc.h>
 #include <asm/byteorder.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include <linux/idr.h>
 #include <linux/list.h>
 
index 6830be4419e20aea282af4b25aefef0d1bdc74e4..86ee39db013f3932cf96635ddbde3a86b5c9309a 100644 (file)
@@ -26,7 +26,7 @@
 #include <linux/usb/cdc.h>
 #include <linux/wwan.h>
 #include <asm/byteorder.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include <linux/usb/cdc-wdm.h>
 
 #define DRIVER_AUTHOR "Oliver Neukum"
index 1ff7d901fedead2e6b94221ad49a52176336880a..500dc35e64774d2f436c5a354028d1bd80082ed7 100644 (file)
@@ -24,7 +24,7 @@
 #include <linux/mutex.h>
 #include <asm/irq.h>
 #include <asm/byteorder.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include <linux/platform_device.h>
 #include <linux/workqueue.h>
 #include <linux/pm_runtime.h>
index 21585ed89ef849d2f2a1ce6c4196dcfc64ac9176..03c22114214b5ac0aa70df83f350238c6dc6e0a5 100644 (file)
@@ -170,11 +170,11 @@ static int usb_acpi_add_usb4_devlink(struct usb_device *udev)
        struct fwnode_handle *nhi_fwnode __free(fwnode_handle) =
                fwnode_find_reference(dev_fwnode(&port_dev->dev), "usb4-host-interface", 0);
 
-       if (IS_ERR(nhi_fwnode))
+       if (IS_ERR(nhi_fwnode) || !nhi_fwnode->dev)
                return 0;
 
        link = device_link_add(&port_dev->child->dev, nhi_fwnode->dev,
-                              DL_FLAG_AUTOREMOVE_CONSUMER |
+                              DL_FLAG_STATELESS |
                               DL_FLAG_RPM_ACTIVE |
                               DL_FLAG_PM_RUNTIME);
        if (!link) {
index 68226defdc60af4cac0f00256519a25da74bd1ab..4d73fae80b1230309ef707ce365a32f6bbab34ee 100644 (file)
@@ -23,7 +23,6 @@ static void dwc2_set_bcm_params(struct dwc2_hsotg *hsotg)
        p->max_transfer_size = 65535;
        p->max_packet_count = 511;
        p->ahbcfg = 0x10;
-       p->no_clock_gating = true;
 }
 
 static void dwc2_set_his_params(struct dwc2_hsotg *hsotg)
index 9eb085f359ce3fe7ee9667ccfbe29bc591de0d54..427e5660f87c248572fbe7f4424e9613ae5909c3 100644 (file)
@@ -544,6 +544,7 @@ static int dwc3_alloc_event_buffers(struct dwc3 *dwc, unsigned int length)
 int dwc3_event_buffers_setup(struct dwc3 *dwc)
 {
        struct dwc3_event_buffer        *evt;
+       u32                             reg;
 
        if (!dwc->ev_buf)
                return 0;
@@ -556,8 +557,10 @@ int dwc3_event_buffers_setup(struct dwc3 *dwc)
                        upper_32_bits(evt->dma));
        dwc3_writel(dwc->regs, DWC3_GEVNTSIZ(0),
                        DWC3_GEVNTSIZ_SIZE(evt->length));
-       dwc3_writel(dwc->regs, DWC3_GEVNTCOUNT(0), 0);
 
+       /* Clear any stale event */
+       reg = dwc3_readl(dwc->regs, DWC3_GEVNTCOUNT(0));
+       dwc3_writel(dwc->regs, DWC3_GEVNTCOUNT(0), reg);
        return 0;
 }
 
@@ -584,7 +587,10 @@ void dwc3_event_buffers_cleanup(struct dwc3 *dwc)
        dwc3_writel(dwc->regs, DWC3_GEVNTADRHI(0), 0);
        dwc3_writel(dwc->regs, DWC3_GEVNTSIZ(0), DWC3_GEVNTSIZ_INTMASK
                        | DWC3_GEVNTSIZ_SIZE(0));
-       dwc3_writel(dwc->regs, DWC3_GEVNTCOUNT(0), 0);
+
+       /* Clear any stale event */
+       reg = dwc3_readl(dwc->regs, DWC3_GEVNTCOUNT(0));
+       dwc3_writel(dwc->regs, DWC3_GEVNTCOUNT(0), reg);
 }
 
 static void dwc3_core_num_eps(struct dwc3 *dwc)
@@ -2336,6 +2342,11 @@ static int dwc3_suspend_common(struct dwc3 *dwc, pm_message_t msg)
        u32 reg;
        int i;
 
+       dwc->susphy_state = (dwc3_readl(dwc->regs, DWC3_GUSB2PHYCFG(0)) &
+                           DWC3_GUSB2PHYCFG_SUSPHY) ||
+                           (dwc3_readl(dwc->regs, DWC3_GUSB3PIPECTL(0)) &
+                           DWC3_GUSB3PIPECTL_SUSPHY);
+
        switch (dwc->current_dr_role) {
        case DWC3_GCTL_PRTCAP_DEVICE:
                if (pm_runtime_suspended(dwc->dev))
@@ -2387,6 +2398,15 @@ static int dwc3_suspend_common(struct dwc3 *dwc, pm_message_t msg)
                break;
        }
 
+       if (!PMSG_IS_AUTO(msg)) {
+               /*
+                * TI AM62 platform requires SUSPHY to be
+                * enabled for system suspend to work.
+                */
+               if (!dwc->susphy_state)
+                       dwc3_enable_susphy(dwc, true);
+       }
+
        return 0;
 }
 
@@ -2454,6 +2474,11 @@ static int dwc3_resume_common(struct dwc3 *dwc, pm_message_t msg)
                break;
        }
 
+       if (!PMSG_IS_AUTO(msg)) {
+               /* restore SUSPHY state to that before system suspend. */
+               dwc3_enable_susphy(dwc, dwc->susphy_state);
+       }
+
        return 0;
 }
 
@@ -2499,7 +2524,11 @@ static int dwc3_runtime_resume(struct device *dev)
 
        switch (dwc->current_dr_role) {
        case DWC3_GCTL_PRTCAP_DEVICE:
-               dwc3_gadget_process_pending_events(dwc);
+               if (dwc->pending_events) {
+                       pm_runtime_put(dwc->dev);
+                       dwc->pending_events = false;
+                       enable_irq(dwc->irq_gadget);
+               }
                break;
        case DWC3_GCTL_PRTCAP_HOST:
        default:
@@ -2552,7 +2581,7 @@ static int dwc3_suspend(struct device *dev)
 static int dwc3_resume(struct device *dev)
 {
        struct dwc3     *dwc = dev_get_drvdata(dev);
-       int             ret;
+       int             ret = 0;
 
        pinctrl_pm_select_default_state(dev);
 
@@ -2560,14 +2589,12 @@ static int dwc3_resume(struct device *dev)
        pm_runtime_set_active(dev);
 
        ret = dwc3_resume_common(dwc, PMSG_RESUME);
-       if (ret) {
+       if (ret)
                pm_runtime_set_suspended(dev);
-               return ret;
-       }
 
        pm_runtime_enable(dev);
 
-       return 0;
+       return ret;
 }
 
 static void dwc3_complete(struct device *dev)
@@ -2589,6 +2616,12 @@ static void dwc3_complete(struct device *dev)
 static const struct dev_pm_ops dwc3_dev_pm_ops = {
        SET_SYSTEM_SLEEP_PM_OPS(dwc3_suspend, dwc3_resume)
        .complete = dwc3_complete,
+
+       /*
+        * Runtime suspend halts the controller on disconnection. It relies on
+        * platforms with custom connection notification to start the controller
+        * again.
+        */
        SET_RUNTIME_PM_OPS(dwc3_runtime_suspend, dwc3_runtime_resume,
                        dwc3_runtime_idle)
 };
index c71240e8f7c7dadca3d952163270815f3953a1a6..eab81dfdcc35023cbf13da92c0654bc32824f627 100644 (file)
@@ -1150,6 +1150,8 @@ struct dwc3_scratchpad_array {
  * @sys_wakeup: set if the device may do system wakeup.
  * @wakeup_configured: set if the device is configured for remote wakeup.
  * @suspended: set to track suspend event due to U3/L2.
+ * @susphy_state: state of DWC3_GUSB2PHYCFG_SUSPHY + DWC3_GUSB3PIPECTL_SUSPHY
+ *               before PM suspend.
  * @imod_interval: set the interrupt moderation interval in 250ns
  *                     increments or 0 to disable.
  * @max_cfg_eps: current max number of IN eps used across all USB configs.
@@ -1382,6 +1384,7 @@ struct dwc3 {
        unsigned                sys_wakeup:1;
        unsigned                wakeup_configured:1;
        unsigned                suspended:1;
+       unsigned                susphy_state:1;
 
        u16                     imod_interval;
 
@@ -1675,7 +1678,6 @@ static inline void dwc3_otg_host_init(struct dwc3 *dwc)
 #if !IS_ENABLED(CONFIG_USB_DWC3_HOST)
 int dwc3_gadget_suspend(struct dwc3 *dwc);
 int dwc3_gadget_resume(struct dwc3 *dwc);
-void dwc3_gadget_process_pending_events(struct dwc3 *dwc);
 #else
 static inline int dwc3_gadget_suspend(struct dwc3 *dwc)
 {
@@ -1687,9 +1689,6 @@ static inline int dwc3_gadget_resume(struct dwc3 *dwc)
        return 0;
 }
 
-static inline void dwc3_gadget_process_pending_events(struct dwc3 *dwc)
-{
-}
 #endif /* !IS_ENABLED(CONFIG_USB_DWC3_HOST) */
 
 #if IS_ENABLED(CONFIG_USB_DWC3_ULPI)
index 291bc549935bb1530df6708f2cfb232596762796..4959c26d3b71b89347e9118b1fb732b512ba8c05 100644 (file)
@@ -438,6 +438,10 @@ skip_status:
                        dwc3_gadget_ep_get_transfer_index(dep);
        }
 
+       if (DWC3_DEPCMD_CMD(cmd) == DWC3_DEPCMD_ENDTRANSFER &&
+           !(cmd & DWC3_DEPCMD_CMDIOC))
+               mdelay(1);
+
        if (saved_config) {
                reg = dwc3_readl(dwc->regs, DWC3_GUSB2PHYCFG(0));
                reg |= saved_config;
@@ -1715,12 +1719,10 @@ static int __dwc3_stop_active_transfer(struct dwc3_ep *dep, bool force, bool int
        WARN_ON_ONCE(ret);
        dep->resource_index = 0;
 
-       if (!interrupt) {
-               mdelay(1);
+       if (!interrupt)
                dep->flags &= ~DWC3_EP_TRANSFER_STARTED;
-       } else if (!ret) {
+       else if (!ret)
                dep->flags |= DWC3_EP_END_TRANSFER_PENDING;
-       }
 
        dep->flags &= ~DWC3_EP_DELAY_STOP;
        return ret;
@@ -4728,14 +4730,3 @@ int dwc3_gadget_resume(struct dwc3 *dwc)
 
        return dwc3_gadget_soft_connect(dwc);
 }
-
-void dwc3_gadget_process_pending_events(struct dwc3 *dwc)
-{
-       if (dwc->pending_events) {
-               dwc3_interrupt(dwc->irq_gadget, dwc->ev_buf);
-               dwc3_thread_interrupt(dwc->irq_gadget, dwc->ev_buf);
-               pm_runtime_put(dwc->dev);
-               dwc->pending_events = false;
-               enable_irq(dwc->irq_gadget);
-       }
-}
index 8c5aaf8606357d8b4e8efc672a9c6982d2956b0a..3d404d19a205e3e432f8d367a28f1008bdc533dd 100644 (file)
@@ -36,7 +36,7 @@
 
 #include <asm/byteorder.h>
 #include <asm/irq.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #include "fotg210.h"
 
index f45d5bedda689e029740125049b225bb3542a35e..f25dd2cb5d03b148be6f45e3517908de258db03c 100644 (file)
@@ -19,7 +19,7 @@
 #include <linux/usb/composite.h>
 #include <linux/usb/otg.h>
 #include <linux/usb/webusb.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #include "u_os_desc.h"
 
index c626bb73ea598f06374553d52caea32b01732b33..2920f8000bbd83a80fa92bcd6721acda99ef6960 100644 (file)
@@ -28,7 +28,7 @@
 #include <linux/sched/signal.h>
 #include <linux/uio.h>
 #include <linux/vmalloc.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #include <linux/usb/ccid.h>
 #include <linux/usb/composite.h>
index e11d8c0edf064282db479c2c6005b9000988c03c..08e0d1c511e8d969fe74ad098c9b5b0b7b405ebe 100644 (file)
 #include <linux/freezer.h>
 #include <linux/module.h>
 #include <linux/uaccess.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #include <linux/usb/ch9.h>
 #include <linux/usb/gadget.h>
index ef2ffde625c3284c7015c886d87e834db339a855..d295ade8fa679782ab0ca674783e8cf09dbb62ce 100644 (file)
@@ -37,7 +37,7 @@
 #include <linux/io.h>
 #include <linux/irq.h>
 #include <linux/uaccess.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #include <linux/usb/ch9.h>
 #include <linux/usb/composite.h>
index 90906d71473658361a2e1607a1bce39d7883ed40..15bb3aa12aa8b415ee2a35e1bc11b188596e9f50 100644 (file)
@@ -19,7 +19,7 @@
 #include <scsi/scsi_tcq.h>
 #include <target/target_core_base.h>
 #include <target/target_core_fabric.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #include "tcm.h"
 #include "u_tcm.h"
index 1cdda44455b343fdb0d1ef32ab727e2a91bf2d57..ce5b77f8919026054e104b6b1511f8b08a292597 100644 (file)
@@ -2061,7 +2061,7 @@ static ssize_t f_uac2_opts_##name##_store(struct config_item *item,       \
                                          const char *page, size_t len) \
 {                                                                      \
        struct f_uac2_opts *opts = to_f_uac2_opts(item);                \
-       int ret = 0;                                                    \
+       int ret = len;                                                  \
                                                                        \
        mutex_lock(&opts->lock);                                        \
        if (opts->refcnt) {                                             \
@@ -2072,8 +2072,8 @@ static ssize_t f_uac2_opts_##name##_store(struct config_item *item,       \
        if (len && page[len - 1] == '\n')                               \
                len--;                                                  \
                                                                        \
-       ret = scnprintf(opts->name, min(sizeof(opts->name), len + 1),   \
-                       "%s", page);                                    \
+       scnprintf(opts->name, min(sizeof(opts->name), len + 1),         \
+                 "%s", page);                                          \
                                                                        \
 end:                                                                   \
        mutex_unlock(&opts->lock);                                      \
index 12c5d9cf450c10133139f1cae5f83bc2302e4e30..afd75d72412c9f757fbef88efce1c54356f786e4 100644 (file)
@@ -31,7 +31,7 @@
 
 #include <asm/io.h>
 #include <asm/byteorder.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #include "u_rndis.h"
 
index 0a544a82cbf8504a7a351def7bc0a47da12dd871..ced5d2b09234dc09bd0cc0b873379d3c9c1cdbf2 100644 (file)
@@ -5,7 +5,7 @@
 #include <linux/device.h>
 #include <linux/usb/storage.h>
 #include <scsi/scsi.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #ifndef DEBUG
 #undef VERBOSE_DEBUG
index a9edd60fbbf779706f72bd6ff3f48cd66b9bedcf..57a851151225dec1c478a8dee619f5c101a99671 100644 (file)
@@ -12,7 +12,7 @@
 #include <linux/usb/ch9.h>
 #include <linux/usb/gadget.h>
 #include <linux/usb/video.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #include <media/v4l2-dev.h>
 
index 40870227999ab9338f2f6ca372a6749c9552dcbe..fc1e06246d9df1ee2237f1fe1d6bdd1ddfead02d 100644 (file)
@@ -19,7 +19,7 @@
 #include <scsi/scsi_tcq.h>
 #include <target/target_core_base.h>
 #include <target/target_core_fabric.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #include "u_tcm.h"
 
index 5d7d35c8cc314e7277a7769f7babacd737c33f92..f8b9f0faa9b16d08e2482d0b85755da2c7d6bc4c 100644 (file)
@@ -13,7 +13,7 @@
 #ifndef __U_OS_DESC_H__
 #define __U_OS_DESC_H__
 
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include <linux/nls.h>
 
 #define USB_EXT_PROP_DW_SIZE                   0
index 8d00b1239f219847c81d6b637878f87a0f1ba705..2f4abf6f8f77362337ee93804808ea265bdf0dd3 100644 (file)
@@ -20,7 +20,7 @@
 #include <linux/debugfs.h>
 #include <linux/usb/ch9.h>
 #include <linux/usb/gadget.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #define BRCM_BDC_NAME "bdc"
 #define BRCM_BDC_DESC "Broadcom USB Device Controller driver"
index fa88f210ecd57dba04c86444c28ac00393a76d21..f995cfa9b99e14fa6e0e9b50547e9b494170dffb 100644 (file)
@@ -30,7 +30,7 @@
 #include <linux/pm.h>
 #include <linux/io.h>
 #include <linux/irq.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include <linux/platform_device.h>
 #include <linux/usb/composite.h>
 
index 53ffaf4e2e3762a777071c8539339bf18cc5a1b6..23826fd7a8e6938c053dc64e1468d95bbdba2161 100644 (file)
@@ -29,7 +29,7 @@
 #include <linux/pm.h>
 #include <linux/io.h>
 #include <linux/irq.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include <linux/platform_device.h>
 
 #include "bdc.h"
index fa12a5d46f2e9ae480abd04fe996006ae4f759e2..a5a9d395fd0d8107aeeca505ecdd74ea0e24d910 100644 (file)
@@ -8,7 +8,7 @@
  */
 
 #include <linux/usb/composite.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #include "cdns2-gadget.h"
 #include "cdns2-trace.h"
index cf6478f97f4a3db1784d016a8b0d2610bd2891ad..a6f46364be65f08a2462fcc7700a779dcac42116 100644 (file)
@@ -1696,6 +1696,7 @@ int usb_gadget_register_driver_owner(struct usb_gadget_driver *driver,
        driver->driver.bus = &gadget_bus_type;
        driver->driver.owner = owner;
        driver->driver.mod_name = mod_name;
+       driver->driver.probe_type = PROBE_FORCE_SYNCHRONOUS;
        ret = driver_register(&driver->driver);
        if (ret) {
                pr_warn("%s: driver registration failed: %d\n",
index ff7bee78bcc49246041fdd15a4aa158a348fe1dd..081ac7683c0b350c4675af107bcac78acf38c915 100644 (file)
@@ -42,7 +42,7 @@
 #include <asm/byteorder.h>
 #include <linux/io.h>
 #include <asm/irq.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #define DRIVER_DESC    "USB Host+Gadget Emulator"
 #define DRIVER_VERSION "02 May 2005"
@@ -254,6 +254,7 @@ struct dummy_hcd {
        u32                             stream_en_ep;
        u8                              num_stream[30 / 2];
 
+       unsigned                        timer_pending:1;
        unsigned                        active:1;
        unsigned                        old_active:1;
        unsigned                        resuming:1;
@@ -1303,9 +1304,11 @@ static int dummy_urb_enqueue(
                urb->error_count = 1;           /* mark as a new urb */
 
        /* kick the scheduler, it'll do the rest */
-       if (!hrtimer_active(&dum_hcd->timer))
+       if (!dum_hcd->timer_pending) {
+               dum_hcd->timer_pending = 1;
                hrtimer_start(&dum_hcd->timer, ns_to_ktime(DUMMY_TIMER_INT_NSECS),
                                HRTIMER_MODE_REL_SOFT);
+       }
 
  done:
        spin_unlock_irqrestore(&dum_hcd->dum->lock, flags);
@@ -1324,9 +1327,10 @@ static int dummy_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status)
        spin_lock_irqsave(&dum_hcd->dum->lock, flags);
 
        rc = usb_hcd_check_unlink_urb(hcd, urb, status);
-       if (!rc && dum_hcd->rh_state != DUMMY_RH_RUNNING &&
-                       !list_empty(&dum_hcd->urbp_list))
+       if (rc == 0 && !dum_hcd->timer_pending) {
+               dum_hcd->timer_pending = 1;
                hrtimer_start(&dum_hcd->timer, ns_to_ktime(0), HRTIMER_MODE_REL_SOFT);
+       }
 
        spin_unlock_irqrestore(&dum_hcd->dum->lock, flags);
        return rc;
@@ -1813,6 +1817,7 @@ static enum hrtimer_restart dummy_timer(struct hrtimer *t)
 
        /* look at each urb queued by the host side driver */
        spin_lock_irqsave(&dum->lock, flags);
+       dum_hcd->timer_pending = 0;
 
        if (!dum_hcd->udev) {
                dev_err(dummy_dev(dum_hcd),
@@ -1994,8 +1999,10 @@ return_urb:
        if (list_empty(&dum_hcd->urbp_list)) {
                usb_put_dev(dum_hcd->udev);
                dum_hcd->udev = NULL;
-       } else if (dum_hcd->rh_state == DUMMY_RH_RUNNING) {
+       } else if (!dum_hcd->timer_pending &&
+                       dum_hcd->rh_state == DUMMY_RH_RUNNING) {
                /* want a 1 msec delay here */
+               dum_hcd->timer_pending = 1;
                hrtimer_start(&dum_hcd->timer, ns_to_ktime(DUMMY_TIMER_INT_NSECS),
                                HRTIMER_MODE_REL_SOFT);
        }
@@ -2390,8 +2397,10 @@ static int dummy_bus_resume(struct usb_hcd *hcd)
        } else {
                dum_hcd->rh_state = DUMMY_RH_RUNNING;
                set_link_state(dum_hcd);
-               if (!list_empty(&dum_hcd->urbp_list))
+               if (!list_empty(&dum_hcd->urbp_list)) {
+                       dum_hcd->timer_pending = 1;
                        hrtimer_start(&dum_hcd->timer, ns_to_ktime(0), HRTIMER_MODE_REL_SOFT);
+               }
                hcd->state = HC_STATE_RUNNING;
        }
        spin_unlock_irq(&dum_hcd->dum->lock);
@@ -2522,6 +2531,7 @@ static void dummy_stop(struct usb_hcd *hcd)
        struct dummy_hcd        *dum_hcd = hcd_to_dummy_hcd(hcd);
 
        hrtimer_cancel(&dum_hcd->timer);
+       dum_hcd->timer_pending = 0;
        device_remove_file(dummy_dev(dum_hcd), &dev_attr_urbs);
        dev_info(dummy_dev(dum_hcd), "stopped\n");
 }
index 3432ebfae978794fa88b60811bbaedfbc0822bb8..0cabd4eee6acb5f6e885ff7a9c624ac1add14be9 100644 (file)
@@ -39,7 +39,7 @@
 
 #include <asm/byteorder.h>
 #include <asm/io.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include <asm/dma.h>
 
 #include "fsl_usb2_udc.h"
index 5ffb3d5c635becbfa9bfa275f2471df29d002c57..b860c2e764494055a15f4735ada6a2da41df5456 100644 (file)
@@ -40,7 +40,7 @@
 #include <asm/byteorder.h>
 #include <asm/io.h>
 #include <asm/irq.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 
 #include "goku_udc.h"
index 78308b64955dd1e42332d40913ae55026ee27ef0..71012b282891056690a4e14600c5f45abd450a72 100644 (file)
@@ -30,7 +30,7 @@
 #include <linux/platform_device.h>
 #include <linux/clk.h>
 #include <linux/platform_data/mv_usb.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #include "mv_udc.h"
 
index 19bbc38f3d35dc7977dde74d67eec7e5908834e5..9230db57dab7a6361d2d9a5089c8dc3d2018f5a0 100644 (file)
@@ -28,7 +28,7 @@
 #include <linux/usb/gadget.h>
 
 #include <asm/byteorder.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #include "net2272.h"
 
index 1b929c519cd7126853b9b8487cf814957225cb0c..b2903e4bbf54d0308f99599aa529080b9cad3aca 100644 (file)
@@ -56,7 +56,7 @@
 
 #include <asm/byteorder.h>
 #include <asm/irq.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #define        DRIVER_DESC             "PLX NET228x/USB338x USB Peripheral Controller"
 #define        DRIVER_VERSION          "2005 Sept 27/v3.0"
index e13b8ec8ef8ad036c4bb58ae5aac5060c2ec1866..61a45e4657d5d4996502cb870f478667742e6aaf 100644 (file)
@@ -36,7 +36,7 @@
 
 #include <asm/byteorder.h>
 #include <asm/irq.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include <asm/mach-types.h>
 
 #include <linux/omap-dma.h>
index 1ac26cb49ecf987b6153cf819fe7d321da507cb8..7c96fc9f680f1b5f5ae32bde2668769f6881e38a 100644 (file)
@@ -38,7 +38,7 @@
 #include <asm/byteorder.h>
 #include <asm/dma.h>
 #include <asm/mach-types.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #include <linux/usb/ch9.h>
 #include <linux/usb/gadget.h>
index 2fc5d4d277bc4a594f3ed883a0b2398712347334..cd89532adec2629473d565eb89f5a4f654bacc77 100644 (file)
@@ -33,7 +33,7 @@
 #include <linux/prefetch.h>
 #include <linux/moduleparam.h>
 #include <asm/byteorder.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include "amd5536udc.h"
 
 static void udc_setup_endpoints(struct udc *dev);
index 802bfafb1012bbb5fb14aff0d685abc12515ccb0..cbc0b86fcc365e145852fd9dd9140c0fbb983e4b 100644 (file)
@@ -32,7 +32,7 @@
 #include <asm/byteorder.h>
 #include <asm/io.h>
 #include <asm/irq.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #if defined(CONFIG_PPC_PS3)
 #include <asm/firmware.h>
index a52c3d858f3ee50aee29873d6663869a194c31a8..31059c8f94e63f4ecf18d9fb2a87ffc365f4a95c 100644 (file)
@@ -83,7 +83,7 @@
 
 #include <asm/irq.h>
 #include <asm/byteorder.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 static int dbg_level;
 #ifdef ISP1362_DEBUG
index d9adae53466b7a36caac69e23acdd667eef62e91..d2b67da76762c6489581b759500ba2a738bdce92 100644 (file)
@@ -22,7 +22,7 @@
 #include <linux/regulator/consumer.h>
 #include <linux/usb.h>
 #include <linux/usb/hcd.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #include "ohci.h"
 
index 5cec7640e913c8bac477f67c517304bb0afe5941..9b24181fee601787bd13cebc789fca67b5f06524 100644 (file)
@@ -44,7 +44,7 @@
 
 #include <asm/io.h>
 #include <asm/irq.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include <asm/byteorder.h>
 
 
index 3f871fe62b90f23e217c79a63f7b505dc49d7195..ca3859463ba1415cc3c023e51e41a4bfcf894b37 100644 (file)
@@ -27,7 +27,7 @@
 #include <linux/iopoll.h>
 
 #include <asm/irq.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #include <linux/irq.h>
 #include <linux/platform_device.h>
index 2b871540bb50025f53c814da0fa544e2176fd760..92f2d12384488f2eab7a66db5dbd44a1dc91c8f9 100644 (file)
@@ -54,7 +54,7 @@
 #include <asm/io.h>
 #include <asm/irq.h>
 #include <asm/byteorder.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #include "sl811.h"
 
index 8ec813b6e9fda675217051516adcea534006622f..9dc8f4d8077cc424047d89de950cca11685c355c 100644 (file)
@@ -110,6 +110,7 @@ struct dbc_port {
        struct tasklet_struct           push;
 
        struct list_head                write_pool;
+       unsigned int                    tx_boundary;
 
        bool                            registered;
 };
index b8e78867e25a54f36a1fe06a7ad5b17381994cf3..d719c16ea30b57f8499d2f481386f3471403d301 100644 (file)
@@ -24,6 +24,29 @@ static inline struct dbc_port *dbc_to_port(struct xhci_dbc *dbc)
        return dbc->priv;
 }
 
+static unsigned int
+dbc_kfifo_to_req(struct dbc_port *port, char *packet)
+{
+       unsigned int    len;
+
+       len = kfifo_len(&port->port.xmit_fifo);
+
+       if (len == 0)
+               return 0;
+
+       len = min(len, DBC_MAX_PACKET);
+
+       if (port->tx_boundary)
+               len = min(port->tx_boundary, len);
+
+       len = kfifo_out(&port->port.xmit_fifo, packet, len);
+
+       if (port->tx_boundary)
+               port->tx_boundary -= len;
+
+       return len;
+}
+
 static int dbc_start_tx(struct dbc_port *port)
        __releases(&port->port_lock)
        __acquires(&port->port_lock)
@@ -36,7 +59,7 @@ static int dbc_start_tx(struct dbc_port *port)
 
        while (!list_empty(pool)) {
                req = list_entry(pool->next, struct dbc_request, list_pool);
-               len = kfifo_out(&port->port.xmit_fifo, req->buf, DBC_MAX_PACKET);
+               len = dbc_kfifo_to_req(port, req->buf);
                if (len == 0)
                        break;
                do_tty_wake = true;
@@ -200,14 +223,32 @@ static ssize_t dbc_tty_write(struct tty_struct *tty, const u8 *buf,
 {
        struct dbc_port         *port = tty->driver_data;
        unsigned long           flags;
+       unsigned int            written = 0;
 
        spin_lock_irqsave(&port->port_lock, flags);
-       if (count)
-               count = kfifo_in(&port->port.xmit_fifo, buf, count);
-       dbc_start_tx(port);
+
+       /*
+        * Treat tty write as one usb transfer. Make sure the writes are turned
+        * into TRB request having the same size boundaries as the tty writes.
+        * Don't add data to kfifo before previous write is turned into TRBs
+        */
+       if (port->tx_boundary) {
+               spin_unlock_irqrestore(&port->port_lock, flags);
+               return 0;
+       }
+
+       if (count) {
+               written = kfifo_in(&port->port.xmit_fifo, buf, count);
+
+               if (written == count)
+                       port->tx_boundary = kfifo_len(&port->port.xmit_fifo);
+
+               dbc_start_tx(port);
+       }
+
        spin_unlock_irqrestore(&port->port_lock, flags);
 
-       return count;
+       return written;
 }
 
 static int dbc_tty_put_char(struct tty_struct *tty, u8 ch)
@@ -241,6 +282,10 @@ static unsigned int dbc_tty_write_room(struct tty_struct *tty)
 
        spin_lock_irqsave(&port->port_lock, flags);
        room = kfifo_avail(&port->port.xmit_fifo);
+
+       if (port->tx_boundary)
+               room = 0;
+
        spin_unlock_irqrestore(&port->port_lock, flags);
 
        return room;
index d27c30ac17fd43f61740b5bb5df19a1c6d007e1f..8d774f19271e6afa6809db5257e28e2b7eee0115 100644 (file)
@@ -10,7 +10,7 @@
 
 
 #include <linux/slab.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include <linux/bitfield.h>
 
 #include "xhci.h"
index 30cc5a1380a5029174f73427abf9a039e0f64dba..65fc9319d5e70fd4bf52c4ec9a2857b012794db6 100644 (file)
@@ -6,7 +6,7 @@
 #include <linux/module.h>
 #include <linux/pci.h>
 #include <linux/slab.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #include "xhci.h"
 #include "xhci-trace.h"
index 91dccd25a55142661f58e8f26feb79b8cda3ce74..cb07cee9ed0c75de60777f438fcfd07bc7ded092 100644 (file)
@@ -79,6 +79,7 @@
 #define PCI_DEVICE_ID_ASMEDIA_1042A_XHCI               0x1142
 #define PCI_DEVICE_ID_ASMEDIA_1142_XHCI                        0x1242
 #define PCI_DEVICE_ID_ASMEDIA_2142_XHCI                        0x2142
+#define PCI_DEVICE_ID_ASMEDIA_3042_XHCI                        0x3042
 #define PCI_DEVICE_ID_ASMEDIA_3242_XHCI                        0x3242
 
 #define PCI_DEVICE_ID_CADENCE                          0x17CD
@@ -451,6 +452,10 @@ static void xhci_pci_quirks(struct device *dev, struct xhci_hcd *xhci)
                pdev->device == PCI_DEVICE_ID_ASMEDIA_1042A_XHCI)
                xhci->quirks |= XHCI_ASMEDIA_MODIFY_FLOWCONTROL;
 
+       if (pdev->vendor == PCI_VENDOR_ID_ASMEDIA &&
+           pdev->device == PCI_DEVICE_ID_ASMEDIA_3042_XHCI)
+               xhci->quirks |= XHCI_RESET_ON_RESUME;
+
        if (pdev->vendor == PCI_VENDOR_ID_TI && pdev->device == 0x8241)
                xhci->quirks |= XHCI_LIMIT_ENDPOINT_INTERVAL_7;
 
@@ -635,7 +640,7 @@ int xhci_pci_common_probe(struct pci_dev *dev, const struct pci_device_id *id)
        pm_runtime_put_noidle(&dev->dev);
 
        if (pci_choose_state(dev, PMSG_SUSPEND) == PCI_D0)
-               pm_runtime_forbid(&dev->dev);
+               pm_runtime_get(&dev->dev);
        else if (xhci->quirks & XHCI_DEFAULT_PM_RUNTIME_ALLOW)
                pm_runtime_allow(&dev->dev);
 
@@ -678,7 +683,9 @@ void xhci_pci_remove(struct pci_dev *dev)
 
        xhci->xhc_state |= XHCI_STATE_REMOVING;
 
-       if (xhci->quirks & XHCI_DEFAULT_PM_RUNTIME_ALLOW)
+       if (pci_choose_state(dev, PMSG_SUSPEND) == PCI_D0)
+               pm_runtime_put(&dev->dev);
+       else if (xhci->quirks & XHCI_DEFAULT_PM_RUNTIME_ALLOW)
                pm_runtime_forbid(&dev->dev);
 
        if (xhci->shared_hcd) {
index 4d664ba53fe9a45a7ed5bb36624a905497267f89..928b93ad1ee866a54bb930ada7b8214caf4abfab 100644 (file)
@@ -1023,7 +1023,7 @@ static int xhci_invalidate_cancelled_tds(struct xhci_virt_ep *ep)
                                        td_to_noop(xhci, ring, cached_td, false);
                                        cached_td->cancel_status = TD_CLEARED;
                                }
-
+                               td_to_noop(xhci, ring, td, false);
                                td->cancel_status = TD_CLEARING_CACHE;
                                cached_td = td;
                                break;
@@ -1718,6 +1718,14 @@ static void handle_cmd_completion(struct xhci_hcd *xhci,
 
        trace_xhci_handle_command(xhci->cmd_ring, &cmd_trb->generic);
 
+       cmd_comp_code = GET_COMP_CODE(le32_to_cpu(event->status));
+
+       /* If CMD ring stopped we own the trbs between enqueue and dequeue */
+       if (cmd_comp_code == COMP_COMMAND_RING_STOPPED) {
+               complete_all(&xhci->cmd_ring_stop_completion);
+               return;
+       }
+
        cmd_dequeue_dma = xhci_trb_virt_to_dma(xhci->cmd_ring->deq_seg,
                        cmd_trb);
        /*
@@ -1734,14 +1742,6 @@ static void handle_cmd_completion(struct xhci_hcd *xhci,
 
        cancel_delayed_work(&xhci->cmd_timer);
 
-       cmd_comp_code = GET_COMP_CODE(le32_to_cpu(event->status));
-
-       /* If CMD ring stopped we own the trbs between enqueue and dequeue */
-       if (cmd_comp_code == COMP_COMMAND_RING_STOPPED) {
-               complete_all(&xhci->cmd_ring_stop_completion);
-               return;
-       }
-
        if (cmd->command_trb != xhci->cmd_ring->dequeue) {
                xhci_err(xhci,
                         "Command completion event does not match command\n");
@@ -2775,6 +2775,29 @@ static int handle_tx_event(struct xhci_hcd *xhci,
                return 0;
        }
 
+       /*
+        * xhci 4.10.2 states isoc endpoints should continue
+        * processing the next TD if there was an error mid TD.
+        * So host like NEC don't generate an event for the last
+        * isoc TRB even if the IOC flag is set.
+        * xhci 4.9.1 states that if there are errors in mult-TRB
+        * TDs xHC should generate an error for that TRB, and if xHC
+        * proceeds to the next TD it should genete an event for
+        * any TRB with IOC flag on the way. Other host follow this.
+        *
+        * We wait for the final IOC event, but if we get an event
+        * anywhere outside this TD, just give it back already.
+        */
+       td = list_first_entry_or_null(&ep_ring->td_list, struct xhci_td, td_list);
+
+       if (td && td->error_mid_td && !trb_in_td(xhci, td, ep_trb_dma, false)) {
+               xhci_dbg(xhci, "Missing TD completion event after mid TD error\n");
+               ep_ring->dequeue = td->last_trb;
+               ep_ring->deq_seg = td->last_trb_seg;
+               inc_deq(xhci, ep_ring);
+               xhci_td_cleanup(xhci, td, ep_ring, td->status);
+       }
+
        if (list_empty(&ep_ring->td_list)) {
                /*
                 * Don't print wanings if ring is empty due to a stopped endpoint generating an
@@ -2836,44 +2859,13 @@ static int handle_tx_event(struct xhci_hcd *xhci,
                                return 0;
                        }
 
-                       /*
-                        * xhci 4.10.2 states isoc endpoints should continue
-                        * processing the next TD if there was an error mid TD.
-                        * So host like NEC don't generate an event for the last
-                        * isoc TRB even if the IOC flag is set.
-                        * xhci 4.9.1 states that if there are errors in mult-TRB
-                        * TDs xHC should generate an error for that TRB, and if xHC
-                        * proceeds to the next TD it should genete an event for
-                        * any TRB with IOC flag on the way. Other host follow this.
-                        * So this event might be for the next TD.
-                        */
-                       if (td->error_mid_td &&
-                           !list_is_last(&td->td_list, &ep_ring->td_list)) {
-                               struct xhci_td *td_next = list_next_entry(td, td_list);
-
-                               ep_seg = trb_in_td(xhci, td_next, ep_trb_dma, false);
-                               if (ep_seg) {
-                                       /* give back previous TD, start handling new */
-                                       xhci_dbg(xhci, "Missing TD completion event after mid TD error\n");
-                                       ep_ring->dequeue = td->last_trb;
-                                       ep_ring->deq_seg = td->last_trb_seg;
-                                       inc_deq(xhci, ep_ring);
-                                       xhci_td_cleanup(xhci, td, ep_ring, td->status);
-                                       td = td_next;
-                               }
-                       }
-
-                       if (!ep_seg) {
-                               /* HC is busted, give up! */
-                               xhci_err(xhci,
-                                       "ERROR Transfer event TRB DMA ptr not "
-                                       "part of current TD ep_index %d "
-                                       "comp_code %u\n", ep_index,
-                                       trb_comp_code);
-                               trb_in_td(xhci, td, ep_trb_dma, true);
+                       /* HC is busted, give up! */
+                       xhci_err(xhci,
+                                "ERROR Transfer event TRB DMA ptr not part of current TD ep_index %d comp_code %u\n",
+                                ep_index, trb_comp_code);
+                       trb_in_td(xhci, td, ep_trb_dma, true);
 
-                               return -ESHUTDOWN;
-                       }
+                       return -ESHUTDOWN;
                }
 
                if (ep->skip) {
index 6246d5ad146848271527c7a893c2a7c3daecc927..76f228e7443cb6abb7ad5c513d2eaa7ba4f4f228 100644 (file)
@@ -2183,7 +2183,7 @@ static int tegra_xusb_enter_elpg(struct tegra_xusb *tegra, bool runtime)
                goto out;
        }
 
-       for (i = 0; i < tegra->num_usb_phys; i++) {
+       for (i = 0; i < xhci->usb2_rhub.num_ports; i++) {
                if (!xhci->usb2_rhub.ports[i])
                        continue;
                portsc = readl(xhci->usb2_rhub.ports[i]->addr);
index 620502de971a435b76e37d53ef1c0e6ff7c2e771..f0fb696d56198618484102e38c7d970d4b22328a 100644 (file)
@@ -1001,7 +1001,7 @@ enum xhci_setup_dev {
 /* Set TR Dequeue Pointer command TRB fields, 6.4.3.9 */
 #define TRB_TO_STREAM_ID(p)            ((((p) & (0xffff << 16)) >> 16))
 #define STREAM_ID_FOR_TRB(p)           ((((p)) & 0xffff) << 16)
-#define SCT_FOR_TRB(p)                 (((p) << 1) & 0x7)
+#define SCT_FOR_TRB(p)                 (((p) & 0x7) << 1)
 
 /* Link TRB specific fields */
 #define TRB_TC                 (1<<1)
index 0e5e4cb74c876f85392c79e44d3e672b2a7b0c8d..add2d2e3b61bfda86ab7ca9e2a8a5f5405ab912f 100644 (file)
@@ -27,7 +27,7 @@
 #include <linux/iopoll.h>
 #include <linux/mm.h>
 #include <linux/timer.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include <asm/cacheflush.h>
 
 #include "isp1760-core.h"
index 50b86d531701de27f6112f20864faa48701b2ed1..6497c4e81e951a14201ad965dadc29f9888f8254 100644 (file)
@@ -331,3 +331,15 @@ config USB_ONBOARD_DEV
          this config will enable the driver and it will automatically
          match the state of the USB subsystem. If this driver is a
          module it will be called onboard_usb_dev.
+
+config USB_ONBOARD_DEV_USB5744
+       bool "Onboard USB Microchip usb5744 hub with SMBus support"
+       depends on (USB_ONBOARD_DEV && I2C=y) || (USB_ONBOARD_DEV=m && I2C=m)
+       help
+         Say Y here if you want to support onboard USB Microchip usb5744
+         hub that requires SMBus initialization.
+
+         This options enables usb5744 i2c default initialization sequence
+         during hub start-up configuration stage. It is must to enable this
+         option on AMD Kria KR260 Robotics Starter Kit as this hub is
+         connected to USB-SD converter which mounts the root filesystem.
index 560591e02d6a4ec7ec4f41cc1b0539d1f4c8036f..75dfdca04ff1c26381020ebb1917bc9155a6a28f 100644 (file)
@@ -311,7 +311,7 @@ static void onboard_dev_attach_usb_driver(struct work_struct *work)
 
 static int onboard_dev_5744_i2c_init(struct i2c_client *client)
 {
-#if IS_ENABLED(CONFIG_I2C)
+#if IS_ENABLED(CONFIG_USB_ONBOARD_DEV_USB5744)
        struct device *dev = &client->dev;
        int ret;
 
@@ -394,9 +394,11 @@ static int onboard_dev_probe(struct platform_device *pdev)
 
        i2c_node = of_parse_phandle(pdev->dev.of_node, "i2c-bus", 0);
        if (i2c_node) {
-               struct i2c_client *client;
+               struct i2c_client *client = NULL;
 
+#if IS_ENABLED(CONFIG_USB_ONBOARD_DEV_USB5744)
                client = of_find_i2c_device_by_node(i2c_node);
+#endif
                of_node_put(i2c_node);
 
                if (!client) {
index 1a8d5e80b9aec2daf3977fee7c0d873efaea6ba7..01ceafc4ab78ce28ffae8372c58a745247a2ff6b 100644 (file)
@@ -18,7 +18,7 @@
 #include <linux/usb.h>
 #include <linux/usb/ljca.h>
 
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 /* command flags */
 #define LJCA_ACK_FLAG                  BIT(0)
index 4a9859e03f6b4cf3eaec0b64a3d90ede4086af31..6aebc736a80c6625d9bc70b599f6b177353c758e 100644 (file)
@@ -34,8 +34,6 @@
 #define YUREX_BUF_SIZE         8
 #define YUREX_WRITE_TIMEOUT    (HZ*2)
 
-#define MAX_S64_STRLEN 20 /* {-}922337203685477580{7,8} */
-
 /* table of devices that work with this driver */
 static struct usb_device_id yurex_table[] = {
        { USB_DEVICE(YUREX_VENDOR_ID, YUREX_PRODUCT_ID) },
@@ -402,8 +400,9 @@ static ssize_t yurex_read(struct file *file, char __user *buffer, size_t count,
                          loff_t *ppos)
 {
        struct usb_yurex *dev;
-       int len = 0;
-       char in_buffer[MAX_S64_STRLEN];
+       int len;
+       char in_buffer[20];
+       unsigned long flags;
 
        dev = file->private_data;
 
@@ -413,16 +412,14 @@ static ssize_t yurex_read(struct file *file, char __user *buffer, size_t count,
                return -ENODEV;
        }
 
-       if (WARN_ON_ONCE(dev->bbu > S64_MAX || dev->bbu < S64_MIN)) {
-               mutex_unlock(&dev->io_mutex);
-               return -EIO;
-       }
-
-       spin_lock_irq(&dev->lock);
-       scnprintf(in_buffer, MAX_S64_STRLEN, "%lld\n", dev->bbu);
-       spin_unlock_irq(&dev->lock);
+       spin_lock_irqsave(&dev->lock, flags);
+       len = snprintf(in_buffer, 20, "%lld\n", dev->bbu);
+       spin_unlock_irqrestore(&dev->lock, flags);
        mutex_unlock(&dev->io_mutex);
 
+       if (WARN_ON_ONCE(len >= sizeof(in_buffer)))
+               return -EIO;
+
        return simple_read_from_buffer(buffer, count, ppos, in_buffer, len);
 }
 
index 2b2164e028b3187e14dab8192acba89a8dd24732..ce6f25a9650b3bb0a4cede73add9770a1ac1abd4 100644 (file)
@@ -14,7 +14,7 @@
 #include <linux/time.h>
 #include <linux/timer.h>
 
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #include "musb_core.h"
 
index 1ebbf189a53509139677de4adfc2c8606500b0de..c5c6b818998eead4509da026843d969145bc62e1 100644 (file)
@@ -27,7 +27,7 @@
 #include <linux/platform_device.h>
 #include <linux/uaccess.h>
 
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #include "phy-fsl-usb.h"
 
index 06e0fb23566cefdc0d25c4b234e7e0a89b7e0783..06f789097989f19fbdd41bbc035013f9958c3cc9 100644 (file)
@@ -628,7 +628,7 @@ void devm_usb_put_phy(struct device *dev, struct usb_phy *phy)
 {
        int r;
 
-       r = devres_destroy(dev, devm_usb_phy_release, devm_usb_phy_match, phy);
+       r = devres_release(dev, devm_usb_phy_release, devm_usb_phy_match, phy);
        dev_WARN_ONCE(dev, r, "couldn't find PHY resource\n");
 }
 EXPORT_SYMBOL_GPL(devm_usb_put_phy);
index aa517242d060b54666a40a989ea46e8f56133e1d..2a76f1f0ee4f83c742721b541114af5cd0fadcd3 100644 (file)
@@ -35,7 +35,7 @@
  *
  */
 
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include <linux/tty.h>
 #include <linux/slab.h>
 #include <linux/module.h>
index 02945ccf531dc269a386c7993df2e939f3d0d360..d10e4c4848a0ab9073c4c93638a8796ab61ce3a6 100644 (file)
@@ -19,7 +19,7 @@
 #include <linux/usb.h>
 #include <linux/usb/serial.h>
 #include <linux/serial.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #define DEFAULT_BAUD_RATE 9600
 #define DEFAULT_TIMEOUT   1000
index ce9134bb30f3d0dbefb53a42f2185a69038035ab..e29569d65991b3d85b3a40bd768476af15fbe244 100644 (file)
@@ -36,7 +36,7 @@
 #include <linux/kfifo.h>
 #include <linux/delay.h>
 #include <linux/uaccess.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #include "cypress_m8.h"
 
index a2c0bebc041f73815fd5eebaa3b6468b3e172949..d36155b6d2bfaaa6a9bb0127fff7ac26a78d000b 100644 (file)
@@ -39,7 +39,7 @@
 #include <linux/tty_flip.h>
 #include <linux/module.h>
 #include <linux/uaccess.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include <linux/usb.h>
 #include <linux/usb/serial.h>
 #include "kl5kusb105.h"
index e5a139ed5d901ea91e1078989d6bda55adb237b7..2bce8cc03aca2ec63b4f5a7d903fcedeeab10953 100644 (file)
@@ -26,7 +26,7 @@
 #include <linux/module.h>
 #include <linux/spinlock.h>
 #include <linux/uaccess.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include <linux/usb.h>
 #include <linux/usb/serial.h>
 #include <linux/serial.h>
index 57e4f2b215d84e48146a63b5ed0e6457a154d86c..ad5fdf55a02e18a57a86205a3b7943a26cf2fac5 100644 (file)
@@ -25,7 +25,7 @@
 #include <linux/uaccess.h>
 #include <linux/usb.h>
 #include <linux/usb/serial.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 /* Definitions for the vendor ID and device ID */
 #define MX_USBSERIAL_VID       0x110A
index eb0731992ca9091b556494640ddf0039fa3d318c..4f18f189f3096758357654d8d02db058fef408c9 100644 (file)
@@ -279,6 +279,7 @@ static void option_instat_callback(struct urb *urb);
 #define QUECTEL_PRODUCT_EG912Y                 0x6001
 #define QUECTEL_PRODUCT_EC200S_CN              0x6002
 #define QUECTEL_PRODUCT_EC200A                 0x6005
+#define QUECTEL_PRODUCT_EG916Q                 0x6007
 #define QUECTEL_PRODUCT_EM061K_LWW             0x6008
 #define QUECTEL_PRODUCT_EM061K_LCN             0x6009
 #define QUECTEL_PRODUCT_EC200T                 0x6026
@@ -1270,6 +1271,7 @@ static const struct usb_device_id option_ids[] = {
        { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EC200S_CN, 0xff, 0, 0) },
        { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EC200T, 0xff, 0, 0) },
        { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EG912Y, 0xff, 0, 0) },
+       { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EG916Q, 0xff, 0x00, 0x00) },
        { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_RM500K, 0xff, 0x00, 0x00) },
 
        { USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_6001) },
@@ -1380,10 +1382,16 @@ static const struct usb_device_id option_ids[] = {
          .driver_info = NCTRL(0) | RSVD(1) },
        { USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x10a0, 0xff),    /* Telit FN20C04 (rmnet) */
          .driver_info = RSVD(0) | NCTRL(3) },
+       { USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x10a2, 0xff),    /* Telit FN920C04 (MBIM) */
+         .driver_info = NCTRL(4) },
        { USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x10a4, 0xff),    /* Telit FN20C04 (rmnet) */
          .driver_info = RSVD(0) | NCTRL(3) },
+       { USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x10a7, 0xff),    /* Telit FN920C04 (MBIM) */
+         .driver_info = NCTRL(4) },
        { USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x10a9, 0xff),    /* Telit FN20C04 (rmnet) */
          .driver_info = RSVD(0) | NCTRL(2) | RSVD(3) | RSVD(4) },
+       { USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x10aa, 0xff),    /* Telit FN920C04 (MBIM) */
+         .driver_info = NCTRL(3) | RSVD(4) | RSVD(5) },
        { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_ME910),
          .driver_info = NCTRL(0) | RSVD(1) | RSVD(3) },
        { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_ME910_DUAL_MODEM),
index ab48f8875249a8262c482c53335209ae27276d41..ad41363e3cea5abd09ff24a85e4c670bd5d1de67 100644 (file)
@@ -24,7 +24,7 @@
 #include <linux/uaccess.h>
 #include <linux/usb.h>
 #include <linux/usb/serial.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include "pl2303.h"
 
 
index 4167a45d1be36128c117624610b37899f33e6142..a317bdbd00ad5c56a25e27dbf0921b2deff0ae15 100644 (file)
@@ -9,7 +9,7 @@
  *
  */
 
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include <linux/errno.h>
 #include <linux/slab.h>
 #include <linux/tty.h>
index fd68204374f2ce4437a39a109ab75c507cca6d70..e5ad23d86833d5ec644b4c78fe5aef1e0fe0f576 100644 (file)
@@ -2423,6 +2423,17 @@ UNUSUAL_DEV(  0xc251, 0x4003, 0x0100, 0x0100,
                USB_SC_DEVICE, USB_PR_DEVICE, NULL,
                US_FL_NOT_LOCKABLE),
 
+/*
+ * Reported by Icenowy Zheng <[email protected]>
+ * This is an interface for vendor-specific cryptic commands instead
+ * of real USB storage device.
+ */
+UNUSUAL_DEV(  0xe5b7, 0x0811, 0x0100, 0x0100,
+               "ZhuHai JieLi Technology",
+               "JieLi BR21",
+               USB_SC_DEVICE, USB_PR_DEVICE, NULL,
+               US_FL_IGNORE_DEVICE),
+
 /* Reported by Andrew Simmons <[email protected]> */
 UNUSUAL_DEV(  0xed06, 0x4500, 0x0001, 0x0001,
                "DataStor",
index 9262fcd4144f85ab3f089f820c2063fbe634b0d1..58f40156de56226fb954c3f6495ef9e993234cc9 100644 (file)
@@ -519,6 +519,7 @@ static void typec_altmode_release(struct device *dev)
                typec_altmode_put_partner(alt);
 
        altmode_id_remove(alt->adev.dev.parent, alt->id);
+       put_device(alt->adev.dev.parent);
        kfree(alt);
 }
 
@@ -568,6 +569,8 @@ typec_register_altmode(struct device *parent,
        alt->adev.dev.type = &typec_altmode_dev_type;
        dev_set_name(&alt->adev.dev, "%s.%u", dev_name(parent), id);
 
+       get_device(alt->adev.dev.parent);
+
        /* Link partners and plugs with the ports */
        if (!is_port)
                typec_altmode_set_partner(alt);
@@ -2290,7 +2293,7 @@ void typec_port_register_altmodes(struct typec_port *port,
        const struct typec_altmode_ops *ops, void *drvdata,
        struct typec_altmode **altmodes, size_t n)
 {
-       struct fwnode_handle *altmodes_node, *child;
+       struct fwnode_handle *child;
        struct typec_altmode_desc desc;
        struct typec_altmode *alt;
        size_t index = 0;
@@ -2298,7 +2301,9 @@ void typec_port_register_altmodes(struct typec_port *port,
        u32 vdo;
        int ret;
 
-       altmodes_node = device_get_named_child_node(&port->dev, "altmodes");
+       struct fwnode_handle *altmodes_node  __free(fwnode_handle) =
+               device_get_named_child_node(&port->dev, "altmodes");
+
        if (!altmodes_node)
                return; /* No altmodes specified */
 
index 501eddb294e4329f9fd33b185a79a3847b0cd7e4..b80eb2d78d88b432e227548eeb3e69e40f59b0b2 100644 (file)
@@ -93,8 +93,10 @@ static int qcom_pmic_typec_probe(struct platform_device *pdev)
                return -EINVAL;
 
        bridge_dev = devm_drm_dp_hpd_bridge_alloc(tcpm->dev, to_of_node(tcpm->tcpc.fwnode));
-       if (IS_ERR(bridge_dev))
-               return PTR_ERR(bridge_dev);
+       if (IS_ERR(bridge_dev)) {
+               ret = PTR_ERR(bridge_dev);
+               goto fwnode_remove;
+       }
 
        tcpm->tcpm_port = tcpm_register_port(tcpm->dev, &tcpm->tcpc);
        if (IS_ERR(tcpm->tcpm_port)) {
@@ -123,7 +125,7 @@ port_stop:
 port_unregister:
        tcpm_unregister_port(tcpm->tcpm_port);
 fwnode_remove:
-       fwnode_remove_software_node(tcpm->tcpc.fwnode);
+       fwnode_handle_put(tcpm->tcpc.fwnode);
 
        return ret;
 }
@@ -135,7 +137,7 @@ static void qcom_pmic_typec_remove(struct platform_device *pdev)
        tcpm->pdphy_stop(tcpm);
        tcpm->port_stop(tcpm);
        tcpm_unregister_port(tcpm->tcpm_port);
-       fwnode_remove_software_node(tcpm->tcpc.fwnode);
+       fwnode_handle_put(tcpm->tcpc.fwnode);
 }
 
 static const struct pmic_typec_resources pm8150b_typec_res = {
index a747baa2978498cc13d8660ee9da10880dbda416..c37dede62e12cd8a105da108838b5ca4f5e632d7 100644 (file)
@@ -432,7 +432,6 @@ static int qcom_pmic_typec_port_get_cc(struct tcpc_dev *tcpc,
                        val = TYPEC_CC_RP_DEF;
                        break;
                }
-               val = TYPEC_CC_RP_DEF;
        }
 
        if (misc & CC_ORIENTATION)
index fc619478200f5dc87f9f5a03ab6d28128296ccc2..7ae341a403424cbc00825ad3c8ac740213ef9193 100644 (file)
@@ -4515,7 +4515,8 @@ static inline enum tcpm_state hard_reset_state(struct tcpm_port *port)
                return ERROR_RECOVERY;
        if (port->pwr_role == TYPEC_SOURCE)
                return SRC_UNATTACHED;
-       if (port->state == SNK_WAIT_CAPABILITIES_TIMEOUT)
+       if (port->state == SNK_WAIT_CAPABILITIES ||
+           port->state == SNK_WAIT_CAPABILITIES_TIMEOUT)
                return SNK_READY;
        return SNK_UNATTACHED;
 }
@@ -5043,8 +5044,11 @@ static void run_state_machine(struct tcpm_port *port)
                        tcpm_set_state(port, SNK_SOFT_RESET,
                                       PD_T_SINK_WAIT_CAP);
                } else {
-                       tcpm_set_state(port, SNK_WAIT_CAPABILITIES_TIMEOUT,
-                                      PD_T_SINK_WAIT_CAP);
+                       if (!port->self_powered)
+                               upcoming_state = SNK_WAIT_CAPABILITIES_TIMEOUT;
+                       else
+                               upcoming_state = hard_reset_state(port);
+                       tcpm_set_state(port, upcoming_state, PD_T_SINK_WAIT_CAP);
                }
                break;
        case SNK_WAIT_CAPABILITIES_TIMEOUT:
index 4a017eb6a65ba6d39ad94499f48ee3eeaedf8d11..1cf5aad4c23a9e70230449774a89573636fed164 100644 (file)
@@ -11,7 +11,7 @@
 #include <linux/usb/typec.h>
 #include <linux/usb/pd.h>
 #include <linux/usb/role.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 /* -------------------------------------------------------------------------- */
 
index b3ec799fc8733717e03d7e672c9181be92255b67..ba58d11907bc589564bc6e91b518ba5700a59bfb 100644 (file)
@@ -18,7 +18,7 @@
 #include <linux/pm_runtime.h>
 #include <linux/usb/typec_dp.h>
 
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include "ucsi.h"
 
 enum enum_fw_mode {
index ddbec2b78c8e18f50ead7df5ff8f94c7d7fa67f6..6923fad31d795194a22db7633e1f8a56475142a0 100644 (file)
@@ -12,7 +12,7 @@
 #include <linux/interrupt.h>
 #include <linux/module.h>
 #include <linux/platform_device.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #include "ucsi.h"
 
index 11bd76ae18cf937c5dd25ec7c000abe7a4b5c130..1d4767b33315e29e0733c5154440f5d7f242f42d 100644 (file)
@@ -475,11 +475,11 @@ int octep_hw_caps_read(struct octep_hw *oct_hw, struct pci_dev *pdev)
                dev_err(dev, "Incomplete PCI capabilities");
                return -EIO;
        }
-       dev_info(dev, "common cfg mapped at: 0x%016llx\n", (u64)(uintptr_t)oct_hw->common_cfg);
-       dev_info(dev, "device cfg mapped at: 0x%016llx\n", (u64)(uintptr_t)oct_hw->dev_cfg);
-       dev_info(dev, "isr cfg mapped at: 0x%016llx\n", (u64)(uintptr_t)oct_hw->isr);
-       dev_info(dev, "notify base: 0x%016llx, notify off multiplier: %u\n",
-                (u64)(uintptr_t)oct_hw->notify_base, oct_hw->notify_off_multiplier);
+       dev_info(dev, "common cfg mapped at: %p\n", oct_hw->common_cfg);
+       dev_info(dev, "device cfg mapped at: %p\n", oct_hw->dev_cfg);
+       dev_info(dev, "isr cfg mapped at: %p\n", oct_hw->isr);
+       dev_info(dev, "notify base: %p, notify off multiplier: %u\n",
+                oct_hw->notify_base, oct_hw->notify_off_multiplier);
 
        oct_hw->config_size = octep_get_config_size(oct_hw);
        oct_hw->features = octep_hw_get_dev_features(oct_hw);
@@ -511,7 +511,7 @@ int octep_hw_caps_read(struct octep_hw *oct_hw, struct pci_dev *pdev)
        }
        mbox = octep_get_mbox(oct_hw);
        octep_mbox_init(mbox);
-       dev_info(dev, "mbox mapped at: 0x%016llx\n", (u64)(uintptr_t)mbox);
+       dev_info(dev, "mbox mapped at: %p\n", mbox);
 
        return 0;
 }
index 006ffacf1c56cbecf92ca7cbd2f03ee31bde913f..718fa4e0b31ec2ae5abe902a784d941ac4d56adf 100644 (file)
@@ -27,7 +27,7 @@
 #include <linux/miscdevice.h>
 #include <linux/blk_types.h>
 #include <linux/bio.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include <scsi/scsi_common.h>
 #include <scsi/scsi_proto.h>
 #include <target/target_core_base.h>
@@ -1029,20 +1029,23 @@ vhost_scsi_get_req(struct vhost_virtqueue *vq, struct vhost_scsi_ctx *vc,
                /* virtio-scsi spec requires byte 0 of the lun to be 1 */
                vq_err(vq, "Illegal virtio-scsi lun: %u\n", *vc->lunp);
        } else {
-               struct vhost_scsi_tpg **vs_tpg, *tpg;
-
-               vs_tpg = vhost_vq_get_backend(vq);      /* validated at handler entry */
-
-               tpg = READ_ONCE(vs_tpg[*vc->target]);
-               if (unlikely(!tpg)) {
-                       vq_err(vq, "Target 0x%x does not exist\n", *vc->target);
-               } else {
-                       if (tpgp)
-                               *tpgp = tpg;
-                       ret = 0;
+               struct vhost_scsi_tpg **vs_tpg, *tpg = NULL;
+
+               if (vc->target) {
+                       /* validated at handler entry */
+                       vs_tpg = vhost_vq_get_backend(vq);
+                       tpg = READ_ONCE(vs_tpg[*vc->target]);
+                       if (unlikely(!tpg)) {
+                               vq_err(vq, "Target 0x%x does not exist\n", *vc->target);
+                               goto out;
+                       }
                }
-       }
 
+               if (tpgp)
+                       *tpgp = tpg;
+               ret = 0;
+       }
+out:
        return ret;
 }
 
index ea36c6956bf36103772c576e8fc0d29c830958e2..de035071fedb1b8a3fcef5d950ec778d10a7b962 100644 (file)
@@ -1236,7 +1236,6 @@ config FB_3DFX_I2C
 config FB_VOODOO1
        tristate "3Dfx Voodoo Graphics (sst1) support"
        depends on FB && PCI
-       depends on FB_DEVICE
        select FB_IOMEM_HELPERS
        help
          Say Y here if you have a 3Dfx Voodoo Graphics (Voodoo1/sst1) or
@@ -1374,6 +1373,7 @@ config FB_VT8500
 config FB_WM8505
        bool "Wondermedia WM8xxx-series frame buffer support"
        depends on (FB = y) && HAS_IOMEM && (ARCH_VT8500 || COMPILE_TEST)
+       select FB_IOMEM_FOPS
        select FB_SYS_FILLRECT if (!FB_WMT_GE_ROPS)
        select FB_SYS_COPYAREA if (!FB_WMT_GE_ROPS)
        select FB_SYS_IMAGEBLIT
@@ -1660,19 +1660,6 @@ config FB_SH7760
          and 8, 15 or 16 bpp color; 90 degrees clockwise display rotation for
          panels <= 320 pixel horizontal resolution.
 
-config FB_DA8XX
-       tristate "DA8xx/OMAP-L1xx/AM335x Framebuffer support"
-       depends on FB && HAVE_CLK && HAS_IOMEM
-       depends on ARCH_DAVINCI_DA8XX || SOC_AM33XX || COMPILE_TEST
-       select FB_CFB_REV_PIXELS_IN_BYTE
-       select FB_IOMEM_HELPERS
-       select FB_MODE_HELPERS
-       select VIDEOMODE_HELPERS
-       help
-         This is the frame buffer device driver for the TI LCD controller
-         found on DA8xx/OMAP-L1xx/AM335x SoCs.
-         If unsure, say N.
-
 config FB_VIRTUAL
        tristate "Virtual Frame Buffer support (ONLY FOR TESTING!)"
        depends on FB
index 3eecd51267fab93b6d28fad8d1453a5e9a3cee0d..b3d12f977c06b1f117b222d406c6f303d8e182e2 100644 (file)
@@ -121,7 +121,6 @@ obj-$(CONFIG_FB_VESA)             += vesafb.o
 obj-$(CONFIG_FB_EFI)              += efifb.o
 obj-$(CONFIG_FB_VGA16)            += vga16fb.o
 obj-$(CONFIG_FB_OF)               += offb.o
-obj-$(CONFIG_FB_DA8XX)           += da8xx-fb.o
 obj-$(CONFIG_FB_SSD1307)         += ssd1307fb.o
 obj-$(CONFIG_FB_SIMPLE)           += simplefb.o
 
index 13263824052181a1b7c2d2d618983be40cec4749..1116a0789ca4d39e9dc5fbc55683dd0a5b769c9f 100644 (file)
@@ -3774,8 +3774,8 @@ static void __exit amifb_remove(struct platform_device *pdev)
  * triggers a section mismatch warning.
  */
 static struct platform_driver amifb_driver __refdata = {
-       .remove_new = __exit_p(amifb_remove),
-       .driver   = {
+       .remove = __exit_p(amifb_remove),
+       .driver = {
                .name   = "amiga-video",
        },
 };
index b2408543277cee9040d1d7027ae337b821619caf..b807cf07522de1ffbab9719b99f0587fd90aece4 100644 (file)
@@ -548,7 +548,7 @@ static void arcfb_remove(struct platform_device *dev)
 
 static struct platform_driver arcfb_driver = {
        .probe  = arcfb_probe,
-       .remove_new = arcfb_remove,
+       .remove = arcfb_remove,
        .driver = {
                .name   = "arcfb",
        },
index 5574fb0361ee3b87244732c0f3cdf15a76223b13..e13f53965a0d4e621eeaf731e0415ec60aba0ef0 100644 (file)
@@ -1299,7 +1299,7 @@ static int atmel_lcdfb_resume(struct platform_device *pdev)
 
 static struct platform_driver atmel_lcdfb_driver = {
        .probe          = atmel_lcdfb_probe,
-       .remove_new     = atmel_lcdfb_remove,
+       .remove         = atmel_lcdfb_remove,
        .suspend        = atmel_lcdfb_suspend,
        .resume         = atmel_lcdfb_resume,
        .driver         = {
index e4b2c89baee2d4e1cb422078605baa1c2cfe56b3..826fb04de64c2620e652e280758bc86f64f55ccf 100644 (file)
@@ -5,7 +5,7 @@
  */
 
 #include <linux/delay.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include <linux/fb.h>
 #include <video/mach64.h>
 #include "atyfb.h"
index 08109ce535cd4e9a8396bfd62ca751572ecb58c4..840f221607635bfe3c8a9860ede7ebd2004cc7a6 100644 (file)
@@ -588,7 +588,7 @@ static struct platform_driver au1100fb_driver = {
                .name           = "au1100-lcd",
        },
        .probe          = au1100fb_drv_probe,
-       .remove_new     = au1100fb_drv_remove,
+       .remove         = au1100fb_drv_remove,
        .suspend        = au1100fb_drv_suspend,
        .resume         = au1100fb_drv_resume,
 };
index e718fea636628ad3a87459c13dace85b52bb15a9..ed770222660b515fde3ca95ae41ea7ebff6be7c3 100644 (file)
@@ -1833,7 +1833,7 @@ static struct platform_driver au1200fb_driver = {
                .pm     = AU1200FB_PMOPS,
        },
        .probe          = au1200fb_drv_probe,
-       .remove_new     = au1200fb_drv_remove,
+       .remove         = au1200fb_drv_remove,
 };
 module_platform_driver(au1200fb_driver);
 
index e857b15e9f5deb3ae28df0fd2c4775d83706016e..c8ba098a8c42f34ce56e65db1b0c8dcd602f4f17 100644 (file)
@@ -1151,7 +1151,7 @@ static void broadsheetfb_remove(struct platform_device *dev)
 
 static struct platform_driver broadsheetfb_driver = {
        .probe  = broadsheetfb_probe,
-       .remove_new = broadsheetfb_remove,
+       .remove = broadsheetfb_remove,
        .driver = {
                .name   = "broadsheetfb",
        },
index eaab51be74f83ac4975fbf9f46b0ae280562a50f..e757462af0a61cf0ce911f339207a388cb3b5e65 100644 (file)
@@ -147,7 +147,7 @@ bw2_blank(int blank, struct fb_info *info)
        return 0;
 }
 
-static struct sbus_mmap_map bw2_mmap_map[] = {
+static const struct sbus_mmap_map bw2_mmap_map[] = {
        {
                .size = SBUS_MMAP_FBSIZE(1)
        },
@@ -372,7 +372,7 @@ static struct platform_driver bw2_driver = {
                .of_match_table = bw2_match,
        },
        .probe          = bw2_probe,
-       .remove_new     = bw2_remove,
+       .remove         = bw2_remove,
 };
 
 static int __init bw2_init(void)
index 19156dc6158cfc88362145df11ccf2a106489e6a..cfd2361f24b1d382432c34f4889d98d868acdf1e 100644 (file)
@@ -11,7 +11,7 @@
 #include <linux/module.h>
 #include <linux/string.h>
 
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #include "c2p.h"
 #include "c2p_core.h"
index 22c8c1b6db60bb9ee0de29210d96c203df3040ce..819c82a98ac09018839f84690067027ede9da096 100644 (file)
@@ -11,7 +11,7 @@
 #include <linux/module.h>
 #include <linux/string.h>
 
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #include "c2p.h"
 #include "c2p_core.h"
index c161b2af8933081b3dbbc2c5fc3e48a552015c2f..5389f8f07346bd73807e70818afcce7d773e44fd 100644 (file)
@@ -360,7 +360,7 @@ static void cg14_init_fix(struct fb_info *info, int linebytes,
        info->fix.accel = FB_ACCEL_SUN_CG14;
 }
 
-static struct sbus_mmap_map __cg14_mmap_map[CG14_MMAP_ENTRIES] = {
+static const struct sbus_mmap_map __cg14_mmap_map[CG14_MMAP_ENTRIES] = {
        {
                .voff   = CG14_REGS,
                .poff   = 0x80000000,
@@ -590,7 +590,7 @@ static struct platform_driver cg14_driver = {
                .of_match_table = cg14_match,
        },
        .probe          = cg14_probe,
-       .remove_new     = cg14_remove,
+       .remove         = cg14_remove,
 };
 
 static int __init cg14_init(void)
index 5e1f1b9a81b636e2b4666e1b7cb05f3b2bf94a96..a58a483014e6ae95c4b1bdd057f3974c9d7ea1a8 100644 (file)
@@ -209,7 +209,7 @@ static int cg3_blank(int blank, struct fb_info *info)
        return 0;
 }
 
-static struct sbus_mmap_map cg3_mmap_map[] = {
+static const struct sbus_mmap_map cg3_mmap_map[] = {
        {
                .voff   = CG3_MMAP_OFFSET,
                .poff   = CG3_RAM_OFFSET,
@@ -458,7 +458,7 @@ static struct platform_driver cg3_driver = {
                .of_match_table = cg3_match,
        },
        .probe          = cg3_probe,
-       .remove_new     = cg3_remove,
+       .remove         = cg3_remove,
 };
 
 static int __init cg3_init(void)
index 69d3ce50948de341ff1828a7ea981cf34562fa2e..56d74468040a02ddd3dd720f0070590fbb2f598e 100644 (file)
@@ -545,7 +545,7 @@ static int cg6_blank(int blank, struct fb_info *info)
        return 0;
 }
 
-static struct sbus_mmap_map cg6_mmap_map[] = {
+static const struct sbus_mmap_map cg6_mmap_map[] = {
        {
                .voff   = CG6_FBC,
                .poff   = CG6_FBC_OFFSET,
@@ -858,7 +858,7 @@ static struct platform_driver cg6_driver = {
                .of_match_table = cg6_match,
        },
        .probe          = cg6_probe,
-       .remove_new     = cg6_remove,
+       .remove         = cg6_remove,
 };
 
 static int __init cg6_init(void)
index 6171a98a48fd5f3a5da01e28b51ee97d2657c2ea..0d0ba617b4aa87b711440f86b5ac56a65799e5c5 100644 (file)
@@ -371,7 +371,7 @@ static struct platform_driver clps711x_fb_driver = {
                .of_match_table = clps711x_fb_dt_ids,
        },
        .probe  = clps711x_fb_probe,
-       .remove_new = clps711x_fb_remove,
+       .remove = clps711x_fb_remove,
 };
 module_platform_driver(clps711x_fb_driver);
 
index c2b8f894799ca01fe1048a5a68fff69e67c4d708..308967b5096ad1ae409564484555e9b4fb589159 100644 (file)
@@ -344,7 +344,7 @@ static void cobalt_lcdfb_remove(struct platform_device *dev)
 
 static struct platform_driver cobalt_lcdfb_driver = {
        .probe  = cobalt_lcdfb_probe,
-       .remove_new = cobalt_lcdfb_remove,
+       .remove = cobalt_lcdfb_remove,
        .driver = {
                .name   = "cobalt-lcd",
        },
diff --git a/drivers/video/fbdev/da8xx-fb.c b/drivers/video/fbdev/da8xx-fb.c
deleted file mode 100644 (file)
index 4ca70a1..0000000
+++ /dev/null
@@ -1,1665 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-or-later
-/*
- * Copyright (C) 2008-2009 MontaVista Software Inc.
- * Copyright (C) 2008-2009 Texas Instruments Inc
- *
- * Based on the LCD driver for TI Avalanche processors written by
- * Ajay Singh and Shalom Hai.
- */
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/fb.h>
-#include <linux/dma-mapping.h>
-#include <linux/device.h>
-#include <linux/platform_device.h>
-#include <linux/uaccess.h>
-#include <linux/pm_runtime.h>
-#include <linux/interrupt.h>
-#include <linux/wait.h>
-#include <linux/clk.h>
-#include <linux/cpufreq.h>
-#include <linux/console.h>
-#include <linux/regulator/consumer.h>
-#include <linux/spinlock.h>
-#include <linux/slab.h>
-#include <linux/delay.h>
-#include <linux/lcm.h>
-#include <video/da8xx-fb.h>
-#include <asm/div64.h>
-
-#define DRIVER_NAME "da8xx_lcdc"
-
-#define LCD_VERSION_1  1
-#define LCD_VERSION_2  2
-
-/* LCD Status Register */
-#define LCD_END_OF_FRAME1              BIT(9)
-#define LCD_END_OF_FRAME0              BIT(8)
-#define LCD_PL_LOAD_DONE               BIT(6)
-#define LCD_FIFO_UNDERFLOW             BIT(5)
-#define LCD_SYNC_LOST                  BIT(2)
-#define LCD_FRAME_DONE                 BIT(0)
-
-/* LCD DMA Control Register */
-#define LCD_DMA_BURST_SIZE(x)          ((x) << 4)
-#define LCD_DMA_BURST_1                        0x0
-#define LCD_DMA_BURST_2                        0x1
-#define LCD_DMA_BURST_4                        0x2
-#define LCD_DMA_BURST_8                        0x3
-#define LCD_DMA_BURST_16               0x4
-#define LCD_V1_END_OF_FRAME_INT_ENA    BIT(2)
-#define LCD_V2_END_OF_FRAME0_INT_ENA   BIT(8)
-#define LCD_V2_END_OF_FRAME1_INT_ENA   BIT(9)
-#define LCD_DUAL_FRAME_BUFFER_ENABLE   BIT(0)
-
-/* LCD Control Register */
-#define LCD_CLK_DIVISOR(x)             ((x) << 8)
-#define LCD_RASTER_MODE                        0x01
-
-/* LCD Raster Control Register */
-#define LCD_PALETTE_LOAD_MODE(x)       ((x) << 20)
-#define PALETTE_AND_DATA               0x00
-#define PALETTE_ONLY                   0x01
-#define DATA_ONLY                      0x02
-
-#define LCD_MONO_8BIT_MODE             BIT(9)
-#define LCD_RASTER_ORDER               BIT(8)
-#define LCD_TFT_MODE                   BIT(7)
-#define LCD_V1_UNDERFLOW_INT_ENA       BIT(6)
-#define LCD_V2_UNDERFLOW_INT_ENA       BIT(5)
-#define LCD_V1_PL_INT_ENA              BIT(4)
-#define LCD_V2_PL_INT_ENA              BIT(6)
-#define LCD_MONOCHROME_MODE            BIT(1)
-#define LCD_RASTER_ENABLE              BIT(0)
-#define LCD_TFT_ALT_ENABLE             BIT(23)
-#define LCD_STN_565_ENABLE             BIT(24)
-#define LCD_V2_DMA_CLK_EN              BIT(2)
-#define LCD_V2_LIDD_CLK_EN             BIT(1)
-#define LCD_V2_CORE_CLK_EN             BIT(0)
-#define LCD_V2_LPP_B10                 26
-#define LCD_V2_TFT_24BPP_MODE          BIT(25)
-#define LCD_V2_TFT_24BPP_UNPACK                BIT(26)
-
-/* LCD Raster Timing 2 Register */
-#define LCD_AC_BIAS_TRANSITIONS_PER_INT(x)     ((x) << 16)
-#define LCD_AC_BIAS_FREQUENCY(x)               ((x) << 8)
-#define LCD_SYNC_CTRL                          BIT(25)
-#define LCD_SYNC_EDGE                          BIT(24)
-#define LCD_INVERT_PIXEL_CLOCK                 BIT(22)
-#define LCD_INVERT_LINE_CLOCK                  BIT(21)
-#define LCD_INVERT_FRAME_CLOCK                 BIT(20)
-
-/* LCD Block */
-#define  LCD_PID_REG                           0x0
-#define  LCD_CTRL_REG                          0x4
-#define  LCD_STAT_REG                          0x8
-#define  LCD_RASTER_CTRL_REG                   0x28
-#define  LCD_RASTER_TIMING_0_REG               0x2C
-#define  LCD_RASTER_TIMING_1_REG               0x30
-#define  LCD_RASTER_TIMING_2_REG               0x34
-#define  LCD_DMA_CTRL_REG                      0x40
-#define  LCD_DMA_FRM_BUF_BASE_ADDR_0_REG       0x44
-#define  LCD_DMA_FRM_BUF_CEILING_ADDR_0_REG    0x48
-#define  LCD_DMA_FRM_BUF_BASE_ADDR_1_REG       0x4C
-#define  LCD_DMA_FRM_BUF_CEILING_ADDR_1_REG    0x50
-
-/* Interrupt Registers available only in Version 2 */
-#define  LCD_RAW_STAT_REG                      0x58
-#define  LCD_MASKED_STAT_REG                   0x5c
-#define  LCD_INT_ENABLE_SET_REG                        0x60
-#define  LCD_INT_ENABLE_CLR_REG                        0x64
-#define  LCD_END_OF_INT_IND_REG                        0x68
-
-/* Clock registers available only on Version 2 */
-#define  LCD_CLK_ENABLE_REG                    0x6c
-#define  LCD_CLK_RESET_REG                     0x70
-#define  LCD_CLK_MAIN_RESET                    BIT(3)
-
-#define LCD_NUM_BUFFERS        2
-
-#define PALETTE_SIZE   256
-
-#define        CLK_MIN_DIV     2
-#define        CLK_MAX_DIV     255
-
-static void __iomem *da8xx_fb_reg_base;
-static unsigned int lcd_revision;
-static irq_handler_t lcdc_irq_handler;
-static wait_queue_head_t frame_done_wq;
-static int frame_done_flag;
-
-static unsigned int lcdc_read(unsigned int addr)
-{
-       return (unsigned int)__raw_readl(da8xx_fb_reg_base + (addr));
-}
-
-static void lcdc_write(unsigned int val, unsigned int addr)
-{
-       __raw_writel(val, da8xx_fb_reg_base + (addr));
-}
-
-struct da8xx_fb_par {
-       struct device           *dev;
-       dma_addr_t              p_palette_base;
-       unsigned char *v_palette_base;
-       dma_addr_t              vram_phys;
-       unsigned long           vram_size;
-       void                    *vram_virt;
-       unsigned int            dma_start;
-       unsigned int            dma_end;
-       struct clk *lcdc_clk;
-       int irq;
-       unsigned int palette_sz;
-       int blank;
-       wait_queue_head_t       vsync_wait;
-       int                     vsync_flag;
-       int                     vsync_timeout;
-       spinlock_t              lock_for_chan_update;
-
-       /*
-        * LCDC has 2 ping pong DMA channels, channel 0
-        * and channel 1.
-        */
-       unsigned int            which_dma_channel_done;
-#ifdef CONFIG_CPU_FREQ
-       struct notifier_block   freq_transition;
-#endif
-       unsigned int            lcdc_clk_rate;
-       struct regulator        *lcd_supply;
-       u32 pseudo_palette[16];
-       struct fb_videomode     mode;
-       struct lcd_ctrl_config  cfg;
-};
-
-static struct fb_var_screeninfo da8xx_fb_var;
-
-static struct fb_fix_screeninfo da8xx_fb_fix = {
-       .id = "DA8xx FB Drv",
-       .type = FB_TYPE_PACKED_PIXELS,
-       .type_aux = 0,
-       .visual = FB_VISUAL_PSEUDOCOLOR,
-       .xpanstep = 0,
-       .ypanstep = 1,
-       .ywrapstep = 0,
-       .accel = FB_ACCEL_NONE
-};
-
-static struct fb_videomode known_lcd_panels[] = {
-       /* Sharp LCD035Q3DG01 */
-       [0] = {
-               .name           = "Sharp_LCD035Q3DG01",
-               .xres           = 320,
-               .yres           = 240,
-               .pixclock       = KHZ2PICOS(4607),
-               .left_margin    = 6,
-               .right_margin   = 8,
-               .upper_margin   = 2,
-               .lower_margin   = 2,
-               .hsync_len      = 0,
-               .vsync_len      = 0,
-               .sync           = FB_SYNC_CLK_INVERT,
-       },
-       /* Sharp LK043T1DG01 */
-       [1] = {
-               .name           = "Sharp_LK043T1DG01",
-               .xres           = 480,
-               .yres           = 272,
-               .pixclock       = KHZ2PICOS(7833),
-               .left_margin    = 2,
-               .right_margin   = 2,
-               .upper_margin   = 2,
-               .lower_margin   = 2,
-               .hsync_len      = 41,
-               .vsync_len      = 10,
-               .sync           = 0,
-               .flag           = 0,
-       },
-       [2] = {
-               /* Hitachi SP10Q010 */
-               .name           = "SP10Q010",
-               .xres           = 320,
-               .yres           = 240,
-               .pixclock       = KHZ2PICOS(7833),
-               .left_margin    = 10,
-               .right_margin   = 10,
-               .upper_margin   = 10,
-               .lower_margin   = 10,
-               .hsync_len      = 10,
-               .vsync_len      = 10,
-               .sync           = 0,
-               .flag           = 0,
-       },
-       [3] = {
-               /* Densitron 84-0023-001T */
-               .name           = "Densitron_84-0023-001T",
-               .xres           = 320,
-               .yres           = 240,
-               .pixclock       = KHZ2PICOS(6400),
-               .left_margin    = 0,
-               .right_margin   = 0,
-               .upper_margin   = 0,
-               .lower_margin   = 0,
-               .hsync_len      = 30,
-               .vsync_len      = 3,
-               .sync           = 0,
-       },
-};
-
-static bool da8xx_fb_is_raster_enabled(void)
-{
-       return !!(lcdc_read(LCD_RASTER_CTRL_REG) & LCD_RASTER_ENABLE);
-}
-
-/* Enable the Raster Engine of the LCD Controller */
-static void lcd_enable_raster(void)
-{
-       u32 reg;
-
-       /* Put LCDC in reset for several cycles */
-       if (lcd_revision == LCD_VERSION_2)
-               /* Write 1 to reset LCDC */
-               lcdc_write(LCD_CLK_MAIN_RESET, LCD_CLK_RESET_REG);
-       mdelay(1);
-
-       /* Bring LCDC out of reset */
-       if (lcd_revision == LCD_VERSION_2)
-               lcdc_write(0, LCD_CLK_RESET_REG);
-       mdelay(1);
-
-       /* Above reset sequence doesnot reset register context */
-       reg = lcdc_read(LCD_RASTER_CTRL_REG);
-       if (!(reg & LCD_RASTER_ENABLE))
-               lcdc_write(reg | LCD_RASTER_ENABLE, LCD_RASTER_CTRL_REG);
-}
-
-/* Disable the Raster Engine of the LCD Controller */
-static void lcd_disable_raster(enum da8xx_frame_complete wait_for_frame_done)
-{
-       u32 reg;
-       int ret;
-
-       reg = lcdc_read(LCD_RASTER_CTRL_REG);
-       if (reg & LCD_RASTER_ENABLE)
-               lcdc_write(reg & ~LCD_RASTER_ENABLE, LCD_RASTER_CTRL_REG);
-       else
-               /* return if already disabled */
-               return;
-
-       if ((wait_for_frame_done == DA8XX_FRAME_WAIT) &&
-                       (lcd_revision == LCD_VERSION_2)) {
-               frame_done_flag = 0;
-               ret = wait_event_interruptible_timeout(frame_done_wq,
-                               frame_done_flag != 0,
-                               msecs_to_jiffies(50));
-               if (ret == 0)
-                       pr_err("LCD Controller timed out\n");
-       }
-}
-
-static void lcd_blit(int load_mode, struct da8xx_fb_par *par)
-{
-       u32 start;
-       u32 end;
-       u32 reg_ras;
-       u32 reg_dma;
-       u32 reg_int;
-
-       /* init reg to clear PLM (loading mode) fields */
-       reg_ras = lcdc_read(LCD_RASTER_CTRL_REG);
-       reg_ras &= ~(3 << 20);
-
-       reg_dma  = lcdc_read(LCD_DMA_CTRL_REG);
-
-       if (load_mode == LOAD_DATA) {
-               start    = par->dma_start;
-               end      = par->dma_end;
-
-               reg_ras |= LCD_PALETTE_LOAD_MODE(DATA_ONLY);
-               if (lcd_revision == LCD_VERSION_1) {
-                       reg_dma |= LCD_V1_END_OF_FRAME_INT_ENA;
-               } else {
-                       reg_int = lcdc_read(LCD_INT_ENABLE_SET_REG) |
-                               LCD_V2_END_OF_FRAME0_INT_ENA |
-                               LCD_V2_END_OF_FRAME1_INT_ENA |
-                               LCD_FRAME_DONE | LCD_SYNC_LOST;
-                       lcdc_write(reg_int, LCD_INT_ENABLE_SET_REG);
-               }
-               reg_dma |= LCD_DUAL_FRAME_BUFFER_ENABLE;
-
-               lcdc_write(start, LCD_DMA_FRM_BUF_BASE_ADDR_0_REG);
-               lcdc_write(end, LCD_DMA_FRM_BUF_CEILING_ADDR_0_REG);
-               lcdc_write(start, LCD_DMA_FRM_BUF_BASE_ADDR_1_REG);
-               lcdc_write(end, LCD_DMA_FRM_BUF_CEILING_ADDR_1_REG);
-       } else if (load_mode == LOAD_PALETTE) {
-               start    = par->p_palette_base;
-               end      = start + par->palette_sz - 1;
-
-               reg_ras |= LCD_PALETTE_LOAD_MODE(PALETTE_ONLY);
-
-               if (lcd_revision == LCD_VERSION_1) {
-                       reg_ras |= LCD_V1_PL_INT_ENA;
-               } else {
-                       reg_int = lcdc_read(LCD_INT_ENABLE_SET_REG) |
-                               LCD_V2_PL_INT_ENA;
-                       lcdc_write(reg_int, LCD_INT_ENABLE_SET_REG);
-               }
-
-               lcdc_write(start, LCD_DMA_FRM_BUF_BASE_ADDR_0_REG);
-               lcdc_write(end, LCD_DMA_FRM_BUF_CEILING_ADDR_0_REG);
-       }
-
-       lcdc_write(reg_dma, LCD_DMA_CTRL_REG);
-       lcdc_write(reg_ras, LCD_RASTER_CTRL_REG);
-
-       /*
-        * The Raster enable bit must be set after all other control fields are
-        * set.
-        */
-       lcd_enable_raster();
-}
-
-/* Configure the Burst Size and fifo threhold of DMA */
-static int lcd_cfg_dma(int burst_size, int fifo_th)
-{
-       u32 reg;
-
-       reg = lcdc_read(LCD_DMA_CTRL_REG) & 0x00000001;
-       switch (burst_size) {
-       case 1:
-               reg |= LCD_DMA_BURST_SIZE(LCD_DMA_BURST_1);
-               break;
-       case 2:
-               reg |= LCD_DMA_BURST_SIZE(LCD_DMA_BURST_2);
-               break;
-       case 4:
-               reg |= LCD_DMA_BURST_SIZE(LCD_DMA_BURST_4);
-               break;
-       case 8:
-               reg |= LCD_DMA_BURST_SIZE(LCD_DMA_BURST_8);
-               break;
-       case 16:
-       default:
-               reg |= LCD_DMA_BURST_SIZE(LCD_DMA_BURST_16);
-               break;
-       }
-
-       reg |= (fifo_th << 8);
-
-       lcdc_write(reg, LCD_DMA_CTRL_REG);
-
-       return 0;
-}
-
-static void lcd_cfg_ac_bias(int period, int transitions_per_int)
-{
-       u32 reg;
-
-       /* Set the AC Bias Period and Number of Transisitons per Interrupt */
-       reg = lcdc_read(LCD_RASTER_TIMING_2_REG) & 0xFFF00000;
-       reg |= LCD_AC_BIAS_FREQUENCY(period) |
-               LCD_AC_BIAS_TRANSITIONS_PER_INT(transitions_per_int);
-       lcdc_write(reg, LCD_RASTER_TIMING_2_REG);
-}
-
-static void lcd_cfg_horizontal_sync(int back_porch, int pulse_width,
-               int front_porch)
-{
-       u32 reg;
-
-       reg = lcdc_read(LCD_RASTER_TIMING_0_REG) & 0x3ff;
-       reg |= (((back_porch-1) & 0xff) << 24)
-           | (((front_porch-1) & 0xff) << 16)
-           | (((pulse_width-1) & 0x3f) << 10);
-       lcdc_write(reg, LCD_RASTER_TIMING_0_REG);
-
-       /*
-        * LCDC Version 2 adds some extra bits that increase the allowable
-        * size of the horizontal timing registers.
-        * remember that the registers use 0 to represent 1 so all values
-        * that get set into register need to be decremented by 1
-        */
-       if (lcd_revision == LCD_VERSION_2) {
-               /* Mask off the bits we want to change */
-               reg = lcdc_read(LCD_RASTER_TIMING_2_REG) & ~0x780000ff;
-               reg |= ((front_porch-1) & 0x300) >> 8;
-               reg |= ((back_porch-1) & 0x300) >> 4;
-               reg |= ((pulse_width-1) & 0x3c0) << 21;
-               lcdc_write(reg, LCD_RASTER_TIMING_2_REG);
-       }
-}
-
-static void lcd_cfg_vertical_sync(int back_porch, int pulse_width,
-               int front_porch)
-{
-       u32 reg;
-
-       reg = lcdc_read(LCD_RASTER_TIMING_1_REG) & 0x3ff;
-       reg |= ((back_porch & 0xff) << 24)
-           | ((front_porch & 0xff) << 16)
-           | (((pulse_width-1) & 0x3f) << 10);
-       lcdc_write(reg, LCD_RASTER_TIMING_1_REG);
-}
-
-static int lcd_cfg_display(const struct lcd_ctrl_config *cfg,
-               struct fb_videomode *panel)
-{
-       u32 reg;
-       u32 reg_int;
-
-       reg = lcdc_read(LCD_RASTER_CTRL_REG) & ~(LCD_TFT_MODE |
-                                               LCD_MONO_8BIT_MODE |
-                                               LCD_MONOCHROME_MODE);
-
-       switch (cfg->panel_shade) {
-       case MONOCHROME:
-               reg |= LCD_MONOCHROME_MODE;
-               if (cfg->mono_8bit_mode)
-                       reg |= LCD_MONO_8BIT_MODE;
-               break;
-       case COLOR_ACTIVE:
-               reg |= LCD_TFT_MODE;
-               if (cfg->tft_alt_mode)
-                       reg |= LCD_TFT_ALT_ENABLE;
-               break;
-
-       case COLOR_PASSIVE:
-               /* AC bias applicable only for Pasive panels */
-               lcd_cfg_ac_bias(cfg->ac_bias, cfg->ac_bias_intrpt);
-               if (cfg->bpp == 12 && cfg->stn_565_mode)
-                       reg |= LCD_STN_565_ENABLE;
-               break;
-
-       default:
-               return -EINVAL;
-       }
-
-       /* enable additional interrupts here */
-       if (lcd_revision == LCD_VERSION_1) {
-               reg |= LCD_V1_UNDERFLOW_INT_ENA;
-       } else {
-               reg_int = lcdc_read(LCD_INT_ENABLE_SET_REG) |
-                       LCD_V2_UNDERFLOW_INT_ENA;
-               lcdc_write(reg_int, LCD_INT_ENABLE_SET_REG);
-       }
-
-       lcdc_write(reg, LCD_RASTER_CTRL_REG);
-
-       reg = lcdc_read(LCD_RASTER_TIMING_2_REG);
-
-       reg |= LCD_SYNC_CTRL;
-
-       if (cfg->sync_edge)
-               reg |= LCD_SYNC_EDGE;
-       else
-               reg &= ~LCD_SYNC_EDGE;
-
-       if ((panel->sync & FB_SYNC_HOR_HIGH_ACT) == 0)
-               reg |= LCD_INVERT_LINE_CLOCK;
-       else
-               reg &= ~LCD_INVERT_LINE_CLOCK;
-
-       if ((panel->sync & FB_SYNC_VERT_HIGH_ACT) == 0)
-               reg |= LCD_INVERT_FRAME_CLOCK;
-       else
-               reg &= ~LCD_INVERT_FRAME_CLOCK;
-
-       lcdc_write(reg, LCD_RASTER_TIMING_2_REG);
-
-       return 0;
-}
-
-static int lcd_cfg_frame_buffer(struct da8xx_fb_par *par, u32 width, u32 height,
-               u32 bpp, u32 raster_order)
-{
-       u32 reg;
-
-       if (bpp > 16 && lcd_revision == LCD_VERSION_1)
-               return -EINVAL;
-
-       /* Set the Panel Width */
-       /* Pixels per line = (PPL + 1)*16 */
-       if (lcd_revision == LCD_VERSION_1) {
-               /*
-                * 0x3F in bits 4..9 gives max horizontal resolution = 1024
-                * pixels.
-                */
-               width &= 0x3f0;
-       } else {
-               /*
-                * 0x7F in bits 4..10 gives max horizontal resolution = 2048
-                * pixels.
-                */
-               width &= 0x7f0;
-       }
-
-       reg = lcdc_read(LCD_RASTER_TIMING_0_REG);
-       reg &= 0xfffffc00;
-       if (lcd_revision == LCD_VERSION_1) {
-               reg |= ((width >> 4) - 1) << 4;
-       } else {
-               width = (width >> 4) - 1;
-               reg |= ((width & 0x3f) << 4) | ((width & 0x40) >> 3);
-       }
-       lcdc_write(reg, LCD_RASTER_TIMING_0_REG);
-
-       /* Set the Panel Height */
-       /* Set bits 9:0 of Lines Per Pixel */
-       reg = lcdc_read(LCD_RASTER_TIMING_1_REG);
-       reg = ((height - 1) & 0x3ff) | (reg & 0xfffffc00);
-       lcdc_write(reg, LCD_RASTER_TIMING_1_REG);
-
-       /* Set bit 10 of Lines Per Pixel */
-       if (lcd_revision == LCD_VERSION_2) {
-               reg = lcdc_read(LCD_RASTER_TIMING_2_REG);
-               reg |= ((height - 1) & 0x400) << 16;
-               lcdc_write(reg, LCD_RASTER_TIMING_2_REG);
-       }
-
-       /* Set the Raster Order of the Frame Buffer */
-       reg = lcdc_read(LCD_RASTER_CTRL_REG) & ~(1 << 8);
-       if (raster_order)
-               reg |= LCD_RASTER_ORDER;
-
-       par->palette_sz = 16 * 2;
-
-       switch (bpp) {
-       case 1:
-       case 2:
-       case 4:
-       case 16:
-               break;
-       case 24:
-               reg |= LCD_V2_TFT_24BPP_MODE;
-               break;
-       case 32:
-               reg |= LCD_V2_TFT_24BPP_MODE;
-               reg |= LCD_V2_TFT_24BPP_UNPACK;
-               break;
-       case 8:
-               par->palette_sz = 256 * 2;
-               break;
-
-       default:
-               return -EINVAL;
-       }
-
-       lcdc_write(reg, LCD_RASTER_CTRL_REG);
-
-       return 0;
-}
-
-#define CNVT_TOHW(val, width) ((((val) << (width)) + 0x7FFF - (val)) >> 16)
-static int fb_setcolreg(unsigned regno, unsigned red, unsigned green,
-                             unsigned blue, unsigned transp,
-                             struct fb_info *info)
-{
-       struct da8xx_fb_par *par = info->par;
-       unsigned short *palette = (unsigned short *) par->v_palette_base;
-       u_short pal;
-       int update_hw = 0;
-
-       if (regno > 255)
-               return 1;
-
-       if (info->fix.visual == FB_VISUAL_DIRECTCOLOR)
-               return 1;
-
-       if (info->var.bits_per_pixel > 16 && lcd_revision == LCD_VERSION_1)
-               return -EINVAL;
-
-       switch (info->fix.visual) {
-       case FB_VISUAL_TRUECOLOR:
-               red = CNVT_TOHW(red, info->var.red.length);
-               green = CNVT_TOHW(green, info->var.green.length);
-               blue = CNVT_TOHW(blue, info->var.blue.length);
-               break;
-       case FB_VISUAL_PSEUDOCOLOR:
-               switch (info->var.bits_per_pixel) {
-               case 4:
-                       if (regno > 15)
-                               return -EINVAL;
-
-                       if (info->var.grayscale) {
-                               pal = regno;
-                       } else {
-                               red >>= 4;
-                               green >>= 8;
-                               blue >>= 12;
-
-                               pal = red & 0x0f00;
-                               pal |= green & 0x00f0;
-                               pal |= blue & 0x000f;
-                       }
-                       if (regno == 0)
-                               pal |= 0x2000;
-                       palette[regno] = pal;
-                       break;
-
-               case 8:
-                       red >>= 4;
-                       green >>= 8;
-                       blue >>= 12;
-
-                       pal = (red & 0x0f00);
-                       pal |= (green & 0x00f0);
-                       pal |= (blue & 0x000f);
-
-                       if (palette[regno] != pal) {
-                               update_hw = 1;
-                               palette[regno] = pal;
-                       }
-                       break;
-               }
-               break;
-       }
-
-       /* Truecolor has hardware independent palette */
-       if (info->fix.visual == FB_VISUAL_TRUECOLOR) {
-               u32 v;
-
-               if (regno > 15)
-                       return -EINVAL;
-
-               v = (red << info->var.red.offset) |
-                       (green << info->var.green.offset) |
-                       (blue << info->var.blue.offset);
-
-               ((u32 *) (info->pseudo_palette))[regno] = v;
-               if (palette[0] != 0x4000) {
-                       update_hw = 1;
-                       palette[0] = 0x4000;
-               }
-       }
-
-       /* Update the palette in the h/w as needed. */
-       if (update_hw)
-               lcd_blit(LOAD_PALETTE, par);
-
-       return 0;
-}
-#undef CNVT_TOHW
-
-static void da8xx_fb_lcd_reset(void)
-{
-       /* DMA has to be disabled */
-       lcdc_write(0, LCD_DMA_CTRL_REG);
-       lcdc_write(0, LCD_RASTER_CTRL_REG);
-
-       if (lcd_revision == LCD_VERSION_2) {
-               lcdc_write(0, LCD_INT_ENABLE_SET_REG);
-               /* Write 1 to reset */
-               lcdc_write(LCD_CLK_MAIN_RESET, LCD_CLK_RESET_REG);
-               lcdc_write(0, LCD_CLK_RESET_REG);
-       }
-}
-
-static int da8xx_fb_config_clk_divider(struct da8xx_fb_par *par,
-                                             unsigned lcdc_clk_div,
-                                             unsigned lcdc_clk_rate)
-{
-       int ret;
-
-       if (par->lcdc_clk_rate != lcdc_clk_rate) {
-               ret = clk_set_rate(par->lcdc_clk, lcdc_clk_rate);
-               if (ret) {
-                       dev_err(par->dev,
-                               "unable to set clock rate at %u\n",
-                               lcdc_clk_rate);
-                       return ret;
-               }
-               par->lcdc_clk_rate = clk_get_rate(par->lcdc_clk);
-       }
-
-       /* Configure the LCD clock divisor. */
-       lcdc_write(LCD_CLK_DIVISOR(lcdc_clk_div) |
-                       (LCD_RASTER_MODE & 0x1), LCD_CTRL_REG);
-
-       if (lcd_revision == LCD_VERSION_2)
-               lcdc_write(LCD_V2_DMA_CLK_EN | LCD_V2_LIDD_CLK_EN |
-                               LCD_V2_CORE_CLK_EN, LCD_CLK_ENABLE_REG);
-
-       return 0;
-}
-
-static unsigned int da8xx_fb_calc_clk_divider(struct da8xx_fb_par *par,
-                                             unsigned pixclock,
-                                             unsigned *lcdc_clk_rate)
-{
-       unsigned lcdc_clk_div;
-
-       pixclock = PICOS2KHZ(pixclock) * 1000;
-
-       *lcdc_clk_rate = par->lcdc_clk_rate;
-
-       if (pixclock < (*lcdc_clk_rate / CLK_MAX_DIV)) {
-               *lcdc_clk_rate = clk_round_rate(par->lcdc_clk,
-                                               pixclock * CLK_MAX_DIV);
-               lcdc_clk_div = CLK_MAX_DIV;
-       } else if (pixclock > (*lcdc_clk_rate / CLK_MIN_DIV)) {
-               *lcdc_clk_rate = clk_round_rate(par->lcdc_clk,
-                                               pixclock * CLK_MIN_DIV);
-               lcdc_clk_div = CLK_MIN_DIV;
-       } else {
-               lcdc_clk_div = *lcdc_clk_rate / pixclock;
-       }
-
-       return lcdc_clk_div;
-}
-
-static int da8xx_fb_calc_config_clk_divider(struct da8xx_fb_par *par,
-                                           struct fb_videomode *mode)
-{
-       unsigned lcdc_clk_rate;
-       unsigned lcdc_clk_div = da8xx_fb_calc_clk_divider(par, mode->pixclock,
-                                                         &lcdc_clk_rate);
-
-       return da8xx_fb_config_clk_divider(par, lcdc_clk_div, lcdc_clk_rate);
-}
-
-static unsigned da8xx_fb_round_clk(struct da8xx_fb_par *par,
-                                         unsigned pixclock)
-{
-       unsigned lcdc_clk_div, lcdc_clk_rate;
-
-       lcdc_clk_div = da8xx_fb_calc_clk_divider(par, pixclock, &lcdc_clk_rate);
-       return KHZ2PICOS(lcdc_clk_rate / (1000 * lcdc_clk_div));
-}
-
-static int lcd_init(struct da8xx_fb_par *par, const struct lcd_ctrl_config *cfg,
-               struct fb_videomode *panel)
-{
-       u32 bpp;
-       int ret = 0;
-
-       ret = da8xx_fb_calc_config_clk_divider(par, panel);
-       if (ret) {
-               dev_err(par->dev, "unable to configure clock\n");
-               return ret;
-       }
-
-       if (panel->sync & FB_SYNC_CLK_INVERT)
-               lcdc_write((lcdc_read(LCD_RASTER_TIMING_2_REG) |
-                       LCD_INVERT_PIXEL_CLOCK), LCD_RASTER_TIMING_2_REG);
-       else
-               lcdc_write((lcdc_read(LCD_RASTER_TIMING_2_REG) &
-                       ~LCD_INVERT_PIXEL_CLOCK), LCD_RASTER_TIMING_2_REG);
-
-       /* Configure the DMA burst size and fifo threshold. */
-       ret = lcd_cfg_dma(cfg->dma_burst_sz, cfg->fifo_th);
-       if (ret < 0)
-               return ret;
-
-       /* Configure the vertical and horizontal sync properties. */
-       lcd_cfg_vertical_sync(panel->upper_margin, panel->vsync_len,
-                       panel->lower_margin);
-       lcd_cfg_horizontal_sync(panel->left_margin, panel->hsync_len,
-                       panel->right_margin);
-
-       /* Configure for disply */
-       ret = lcd_cfg_display(cfg, panel);
-       if (ret < 0)
-               return ret;
-
-       bpp = cfg->bpp;
-
-       if (bpp == 12)
-               bpp = 16;
-       ret = lcd_cfg_frame_buffer(par, (unsigned int)panel->xres,
-                               (unsigned int)panel->yres, bpp,
-                               cfg->raster_order);
-       if (ret < 0)
-               return ret;
-
-       /* Configure FDD */
-       lcdc_write((lcdc_read(LCD_RASTER_CTRL_REG) & 0xfff00fff) |
-                      (cfg->fdd << 12), LCD_RASTER_CTRL_REG);
-
-       return 0;
-}
-
-/* IRQ handler for version 2 of LCDC */
-static irqreturn_t lcdc_irq_handler_rev02(int irq, void *arg)
-{
-       struct da8xx_fb_par *par = arg;
-       u32 stat = lcdc_read(LCD_MASKED_STAT_REG);
-
-       if ((stat & LCD_SYNC_LOST) && (stat & LCD_FIFO_UNDERFLOW)) {
-               lcd_disable_raster(DA8XX_FRAME_NOWAIT);
-               lcdc_write(stat, LCD_MASKED_STAT_REG);
-               lcd_enable_raster();
-       } else if (stat & LCD_PL_LOAD_DONE) {
-               /*
-                * Must disable raster before changing state of any control bit.
-                * And also must be disabled before clearing the PL loading
-                * interrupt via the following write to the status register. If
-                * this is done after then one gets multiple PL done interrupts.
-                */
-               lcd_disable_raster(DA8XX_FRAME_NOWAIT);
-
-               lcdc_write(stat, LCD_MASKED_STAT_REG);
-
-               /* Disable PL completion interrupt */
-               lcdc_write(LCD_V2_PL_INT_ENA, LCD_INT_ENABLE_CLR_REG);
-
-               /* Setup and start data loading mode */
-               lcd_blit(LOAD_DATA, par);
-       } else {
-               lcdc_write(stat, LCD_MASKED_STAT_REG);
-
-               if (stat & LCD_END_OF_FRAME0) {
-                       par->which_dma_channel_done = 0;
-                       lcdc_write(par->dma_start,
-                                  LCD_DMA_FRM_BUF_BASE_ADDR_0_REG);
-                       lcdc_write(par->dma_end,
-                                  LCD_DMA_FRM_BUF_CEILING_ADDR_0_REG);
-                       par->vsync_flag = 1;
-                       wake_up_interruptible(&par->vsync_wait);
-               }
-
-               if (stat & LCD_END_OF_FRAME1) {
-                       par->which_dma_channel_done = 1;
-                       lcdc_write(par->dma_start,
-                                  LCD_DMA_FRM_BUF_BASE_ADDR_1_REG);
-                       lcdc_write(par->dma_end,
-                                  LCD_DMA_FRM_BUF_CEILING_ADDR_1_REG);
-                       par->vsync_flag = 1;
-                       wake_up_interruptible(&par->vsync_wait);
-               }
-
-               /* Set only when controller is disabled and at the end of
-                * active frame
-                */
-               if (stat & BIT(0)) {
-                       frame_done_flag = 1;
-                       wake_up_interruptible(&frame_done_wq);
-               }
-       }
-
-       lcdc_write(0, LCD_END_OF_INT_IND_REG);
-       return IRQ_HANDLED;
-}
-
-/* IRQ handler for version 1 LCDC */
-static irqreturn_t lcdc_irq_handler_rev01(int irq, void *arg)
-{
-       struct da8xx_fb_par *par = arg;
-       u32 stat = lcdc_read(LCD_STAT_REG);
-       u32 reg_ras;
-
-       if ((stat & LCD_SYNC_LOST) && (stat & LCD_FIFO_UNDERFLOW)) {
-               lcd_disable_raster(DA8XX_FRAME_NOWAIT);
-               lcdc_write(stat, LCD_STAT_REG);
-               lcd_enable_raster();
-       } else if (stat & LCD_PL_LOAD_DONE) {
-               /*
-                * Must disable raster before changing state of any control bit.
-                * And also must be disabled before clearing the PL loading
-                * interrupt via the following write to the status register. If
-                * this is done after then one gets multiple PL done interrupts.
-                */
-               lcd_disable_raster(DA8XX_FRAME_NOWAIT);
-
-               lcdc_write(stat, LCD_STAT_REG);
-
-               /* Disable PL completion inerrupt */
-               reg_ras  = lcdc_read(LCD_RASTER_CTRL_REG);
-               reg_ras &= ~LCD_V1_PL_INT_ENA;
-               lcdc_write(reg_ras, LCD_RASTER_CTRL_REG);
-
-               /* Setup and start data loading mode */
-               lcd_blit(LOAD_DATA, par);
-       } else {
-               lcdc_write(stat, LCD_STAT_REG);
-
-               if (stat & LCD_END_OF_FRAME0) {
-                       par->which_dma_channel_done = 0;
-                       lcdc_write(par->dma_start,
-                                  LCD_DMA_FRM_BUF_BASE_ADDR_0_REG);
-                       lcdc_write(par->dma_end,
-                                  LCD_DMA_FRM_BUF_CEILING_ADDR_0_REG);
-                       par->vsync_flag = 1;
-                       wake_up_interruptible(&par->vsync_wait);
-               }
-
-               if (stat & LCD_END_OF_FRAME1) {
-                       par->which_dma_channel_done = 1;
-                       lcdc_write(par->dma_start,
-                                  LCD_DMA_FRM_BUF_BASE_ADDR_1_REG);
-                       lcdc_write(par->dma_end,
-                                  LCD_DMA_FRM_BUF_CEILING_ADDR_1_REG);
-                       par->vsync_flag = 1;
-                       wake_up_interruptible(&par->vsync_wait);
-               }
-       }
-
-       return IRQ_HANDLED;
-}
-
-static int fb_check_var(struct fb_var_screeninfo *var,
-                       struct fb_info *info)
-{
-       int err = 0;
-       struct da8xx_fb_par *par = info->par;
-       int bpp = var->bits_per_pixel >> 3;
-       unsigned long line_size = var->xres_virtual * bpp;
-
-       if (var->bits_per_pixel > 16 && lcd_revision == LCD_VERSION_1)
-               return -EINVAL;
-
-       switch (var->bits_per_pixel) {
-       case 1:
-       case 8:
-               var->red.offset = 0;
-               var->red.length = 8;
-               var->green.offset = 0;
-               var->green.length = 8;
-               var->blue.offset = 0;
-               var->blue.length = 8;
-               var->transp.offset = 0;
-               var->transp.length = 0;
-               var->nonstd = 0;
-               break;
-       case 4:
-               var->red.offset = 0;
-               var->red.length = 4;
-               var->green.offset = 0;
-               var->green.length = 4;
-               var->blue.offset = 0;
-               var->blue.length = 4;
-               var->transp.offset = 0;
-               var->transp.length = 0;
-               var->nonstd = FB_NONSTD_REV_PIX_IN_B;
-               break;
-       case 16:                /* RGB 565 */
-               var->red.offset = 11;
-               var->red.length = 5;
-               var->green.offset = 5;
-               var->green.length = 6;
-               var->blue.offset = 0;
-               var->blue.length = 5;
-               var->transp.offset = 0;
-               var->transp.length = 0;
-               var->nonstd = 0;
-               break;
-       case 24:
-               var->red.offset = 16;
-               var->red.length = 8;
-               var->green.offset = 8;
-               var->green.length = 8;
-               var->blue.offset = 0;
-               var->blue.length = 8;
-               var->nonstd = 0;
-               break;
-       case 32:
-               var->transp.offset = 24;
-               var->transp.length = 8;
-               var->red.offset = 16;
-               var->red.length = 8;
-               var->green.offset = 8;
-               var->green.length = 8;
-               var->blue.offset = 0;
-               var->blue.length = 8;
-               var->nonstd = 0;
-               break;
-       default:
-               err = -EINVAL;
-       }
-
-       var->red.msb_right = 0;
-       var->green.msb_right = 0;
-       var->blue.msb_right = 0;
-       var->transp.msb_right = 0;
-
-       if (line_size * var->yres_virtual > par->vram_size)
-               var->yres_virtual = par->vram_size / line_size;
-
-       if (var->yres > var->yres_virtual)
-               var->yres = var->yres_virtual;
-
-       if (var->xres > var->xres_virtual)
-               var->xres = var->xres_virtual;
-
-       if (var->xres + var->xoffset > var->xres_virtual)
-               var->xoffset = var->xres_virtual - var->xres;
-       if (var->yres + var->yoffset > var->yres_virtual)
-               var->yoffset = var->yres_virtual - var->yres;
-
-       var->pixclock = da8xx_fb_round_clk(par, var->pixclock);
-
-       return err;
-}
-
-#ifdef CONFIG_CPU_FREQ
-static int lcd_da8xx_cpufreq_transition(struct notifier_block *nb,
-                                    unsigned long val, void *data)
-{
-       struct da8xx_fb_par *par;
-
-       par = container_of(nb, struct da8xx_fb_par, freq_transition);
-       if (val == CPUFREQ_POSTCHANGE) {
-               if (par->lcdc_clk_rate != clk_get_rate(par->lcdc_clk)) {
-                       par->lcdc_clk_rate = clk_get_rate(par->lcdc_clk);
-                       lcd_disable_raster(DA8XX_FRAME_WAIT);
-                       da8xx_fb_calc_config_clk_divider(par, &par->mode);
-                       if (par->blank == FB_BLANK_UNBLANK)
-                               lcd_enable_raster();
-               }
-       }
-
-       return 0;
-}
-
-static int lcd_da8xx_cpufreq_register(struct da8xx_fb_par *par)
-{
-       par->freq_transition.notifier_call = lcd_da8xx_cpufreq_transition;
-
-       return cpufreq_register_notifier(&par->freq_transition,
-                                        CPUFREQ_TRANSITION_NOTIFIER);
-}
-
-static void lcd_da8xx_cpufreq_deregister(struct da8xx_fb_par *par)
-{
-       cpufreq_unregister_notifier(&par->freq_transition,
-                                   CPUFREQ_TRANSITION_NOTIFIER);
-}
-#endif
-
-static void fb_remove(struct platform_device *dev)
-{
-       struct fb_info *info = platform_get_drvdata(dev);
-       struct da8xx_fb_par *par = info->par;
-       int ret;
-
-#ifdef CONFIG_CPU_FREQ
-       lcd_da8xx_cpufreq_deregister(par);
-#endif
-       if (par->lcd_supply) {
-               ret = regulator_disable(par->lcd_supply);
-               if (ret)
-                       dev_warn(&dev->dev, "Failed to disable regulator (%pe)\n",
-                                ERR_PTR(ret));
-       }
-
-       lcd_disable_raster(DA8XX_FRAME_WAIT);
-       lcdc_write(0, LCD_RASTER_CTRL_REG);
-
-       /* disable DMA  */
-       lcdc_write(0, LCD_DMA_CTRL_REG);
-
-       unregister_framebuffer(info);
-       fb_dealloc_cmap(&info->cmap);
-       pm_runtime_put_sync(&dev->dev);
-       pm_runtime_disable(&dev->dev);
-       framebuffer_release(info);
-}
-
-/*
- * Function to wait for vertical sync which for this LCD peripheral
- * translates into waiting for the current raster frame to complete.
- */
-static int fb_wait_for_vsync(struct fb_info *info)
-{
-       struct da8xx_fb_par *par = info->par;
-       int ret;
-
-       /*
-        * Set flag to 0 and wait for isr to set to 1. It would seem there is a
-        * race condition here where the ISR could have occurred just before or
-        * just after this set. But since we are just coarsely waiting for
-        * a frame to complete then that's OK. i.e. if the frame completed
-        * just before this code executed then we have to wait another full
-        * frame time but there is no way to avoid such a situation. On the
-        * other hand if the frame completed just after then we don't need
-        * to wait long at all. Either way we are guaranteed to return to the
-        * user immediately after a frame completion which is all that is
-        * required.
-        */
-       par->vsync_flag = 0;
-       ret = wait_event_interruptible_timeout(par->vsync_wait,
-                                              par->vsync_flag != 0,
-                                              par->vsync_timeout);
-       if (ret < 0)
-               return ret;
-       if (ret == 0)
-               return -ETIMEDOUT;
-
-       return 0;
-}
-
-static int fb_ioctl(struct fb_info *info, unsigned int cmd,
-                         unsigned long arg)
-{
-       struct lcd_sync_arg sync_arg;
-
-       switch (cmd) {
-       case FBIOGET_CONTRAST:
-       case FBIOPUT_CONTRAST:
-       case FBIGET_BRIGHTNESS:
-       case FBIPUT_BRIGHTNESS:
-       case FBIGET_COLOR:
-       case FBIPUT_COLOR:
-               return -ENOTTY;
-       case FBIPUT_HSYNC:
-               if (copy_from_user(&sync_arg, (char *)arg,
-                               sizeof(struct lcd_sync_arg)))
-                       return -EFAULT;
-               lcd_cfg_horizontal_sync(sync_arg.back_porch,
-                                       sync_arg.pulse_width,
-                                       sync_arg.front_porch);
-               break;
-       case FBIPUT_VSYNC:
-               if (copy_from_user(&sync_arg, (char *)arg,
-                               sizeof(struct lcd_sync_arg)))
-                       return -EFAULT;
-               lcd_cfg_vertical_sync(sync_arg.back_porch,
-                                       sync_arg.pulse_width,
-                                       sync_arg.front_porch);
-               break;
-       case FBIO_WAITFORVSYNC:
-               return fb_wait_for_vsync(info);
-       default:
-               return -EINVAL;
-       }
-       return 0;
-}
-
-static int cfb_blank(int blank, struct fb_info *info)
-{
-       struct da8xx_fb_par *par = info->par;
-       int ret = 0;
-
-       if (par->blank == blank)
-               return 0;
-
-       par->blank = blank;
-       switch (blank) {
-       case FB_BLANK_UNBLANK:
-               lcd_enable_raster();
-
-               if (par->lcd_supply) {
-                       ret = regulator_enable(par->lcd_supply);
-                       if (ret)
-                               return ret;
-               }
-               break;
-       case FB_BLANK_NORMAL:
-       case FB_BLANK_VSYNC_SUSPEND:
-       case FB_BLANK_HSYNC_SUSPEND:
-       case FB_BLANK_POWERDOWN:
-               if (par->lcd_supply) {
-                       ret = regulator_disable(par->lcd_supply);
-                       if (ret)
-                               return ret;
-               }
-
-               lcd_disable_raster(DA8XX_FRAME_WAIT);
-               break;
-       default:
-               ret = -EINVAL;
-       }
-
-       return ret;
-}
-
-/*
- * Set new x,y offsets in the virtual display for the visible area and switch
- * to the new mode.
- */
-static int da8xx_pan_display(struct fb_var_screeninfo *var,
-                            struct fb_info *fbi)
-{
-       int ret = 0;
-       struct fb_var_screeninfo new_var;
-       struct da8xx_fb_par         *par = fbi->par;
-       struct fb_fix_screeninfo    *fix = &fbi->fix;
-       unsigned int end;
-       unsigned int start;
-       unsigned long irq_flags;
-
-       if (var->xoffset != fbi->var.xoffset ||
-                       var->yoffset != fbi->var.yoffset) {
-               memcpy(&new_var, &fbi->var, sizeof(new_var));
-               new_var.xoffset = var->xoffset;
-               new_var.yoffset = var->yoffset;
-               if (fb_check_var(&new_var, fbi))
-                       ret = -EINVAL;
-               else {
-                       memcpy(&fbi->var, &new_var, sizeof(new_var));
-
-                       start   = fix->smem_start +
-                               new_var.yoffset * fix->line_length +
-                               new_var.xoffset * fbi->var.bits_per_pixel / 8;
-                       end     = start + fbi->var.yres * fix->line_length - 1;
-                       par->dma_start  = start;
-                       par->dma_end    = end;
-                       spin_lock_irqsave(&par->lock_for_chan_update,
-                                       irq_flags);
-                       if (par->which_dma_channel_done == 0) {
-                               lcdc_write(par->dma_start,
-                                          LCD_DMA_FRM_BUF_BASE_ADDR_0_REG);
-                               lcdc_write(par->dma_end,
-                                          LCD_DMA_FRM_BUF_CEILING_ADDR_0_REG);
-                       } else if (par->which_dma_channel_done == 1) {
-                               lcdc_write(par->dma_start,
-                                          LCD_DMA_FRM_BUF_BASE_ADDR_1_REG);
-                               lcdc_write(par->dma_end,
-                                          LCD_DMA_FRM_BUF_CEILING_ADDR_1_REG);
-                       }
-                       spin_unlock_irqrestore(&par->lock_for_chan_update,
-                                       irq_flags);
-               }
-       }
-
-       return ret;
-}
-
-static int da8xxfb_set_par(struct fb_info *info)
-{
-       struct da8xx_fb_par *par = info->par;
-       int ret;
-       bool raster = da8xx_fb_is_raster_enabled();
-
-       if (raster)
-               lcd_disable_raster(DA8XX_FRAME_WAIT);
-
-       fb_var_to_videomode(&par->mode, &info->var);
-
-       par->cfg.bpp = info->var.bits_per_pixel;
-
-       info->fix.visual = (par->cfg.bpp <= 8) ?
-                               FB_VISUAL_PSEUDOCOLOR : FB_VISUAL_TRUECOLOR;
-       info->fix.line_length = (par->mode.xres * par->cfg.bpp) / 8;
-
-       ret = lcd_init(par, &par->cfg, &par->mode);
-       if (ret < 0) {
-               dev_err(par->dev, "lcd init failed\n");
-               return ret;
-       }
-
-       par->dma_start = info->fix.smem_start +
-                        info->var.yoffset * info->fix.line_length +
-                        info->var.xoffset * info->var.bits_per_pixel / 8;
-       par->dma_end   = par->dma_start +
-                        info->var.yres * info->fix.line_length - 1;
-
-       lcdc_write(par->dma_start, LCD_DMA_FRM_BUF_BASE_ADDR_0_REG);
-       lcdc_write(par->dma_end, LCD_DMA_FRM_BUF_CEILING_ADDR_0_REG);
-       lcdc_write(par->dma_start, LCD_DMA_FRM_BUF_BASE_ADDR_1_REG);
-       lcdc_write(par->dma_end, LCD_DMA_FRM_BUF_CEILING_ADDR_1_REG);
-
-       if (raster)
-               lcd_enable_raster();
-
-       return 0;
-}
-
-static const struct fb_ops da8xx_fb_ops = {
-       .owner = THIS_MODULE,
-       FB_DEFAULT_IOMEM_OPS,
-       .fb_check_var = fb_check_var,
-       .fb_set_par = da8xxfb_set_par,
-       .fb_setcolreg = fb_setcolreg,
-       .fb_pan_display = da8xx_pan_display,
-       .fb_ioctl = fb_ioctl,
-       .fb_blank = cfb_blank,
-};
-
-static struct fb_videomode *da8xx_fb_get_videomode(struct platform_device *dev)
-{
-       struct da8xx_lcdc_platform_data *fb_pdata = dev_get_platdata(&dev->dev);
-       struct fb_videomode *lcdc_info;
-       int i;
-
-       for (i = 0, lcdc_info = known_lcd_panels;
-               i < ARRAY_SIZE(known_lcd_panels); i++, lcdc_info++) {
-               if (strcmp(fb_pdata->type, lcdc_info->name) == 0)
-                       break;
-       }
-
-       if (i == ARRAY_SIZE(known_lcd_panels)) {
-               dev_err(&dev->dev, "no panel found\n");
-               return NULL;
-       }
-       dev_info(&dev->dev, "found %s panel\n", lcdc_info->name);
-
-       return lcdc_info;
-}
-
-static int fb_probe(struct platform_device *device)
-{
-       struct da8xx_lcdc_platform_data *fb_pdata =
-                                               dev_get_platdata(&device->dev);
-       struct lcd_ctrl_config *lcd_cfg;
-       struct fb_videomode *lcdc_info;
-       struct fb_info *da8xx_fb_info;
-       struct da8xx_fb_par *par;
-       struct clk *tmp_lcdc_clk;
-       int ret;
-       unsigned long ulcm;
-
-       if (fb_pdata == NULL) {
-               dev_err(&device->dev, "Can not get platform data\n");
-               return -ENOENT;
-       }
-
-       lcdc_info = da8xx_fb_get_videomode(device);
-       if (lcdc_info == NULL)
-               return -ENODEV;
-
-       da8xx_fb_reg_base = devm_platform_ioremap_resource(device, 0);
-       if (IS_ERR(da8xx_fb_reg_base))
-               return PTR_ERR(da8xx_fb_reg_base);
-
-       tmp_lcdc_clk = devm_clk_get(&device->dev, "fck");
-       if (IS_ERR(tmp_lcdc_clk))
-               return dev_err_probe(&device->dev, PTR_ERR(tmp_lcdc_clk),
-                                    "Can not get device clock\n");
-
-       pm_runtime_enable(&device->dev);
-       pm_runtime_get_sync(&device->dev);
-
-       /* Determine LCD IP Version */
-       switch (lcdc_read(LCD_PID_REG)) {
-       case 0x4C100102:
-               lcd_revision = LCD_VERSION_1;
-               break;
-       case 0x4F200800:
-       case 0x4F201000:
-               lcd_revision = LCD_VERSION_2;
-               break;
-       default:
-               dev_warn(&device->dev, "Unknown PID Reg value 0x%x, "
-                               "defaulting to LCD revision 1\n",
-                               lcdc_read(LCD_PID_REG));
-               lcd_revision = LCD_VERSION_1;
-               break;
-       }
-
-       lcd_cfg = (struct lcd_ctrl_config *)fb_pdata->controller_data;
-
-       if (!lcd_cfg) {
-               ret = -EINVAL;
-               goto err_pm_runtime_disable;
-       }
-
-       da8xx_fb_info = framebuffer_alloc(sizeof(struct da8xx_fb_par),
-                                       &device->dev);
-       if (!da8xx_fb_info) {
-               ret = -ENOMEM;
-               goto err_pm_runtime_disable;
-       }
-
-       par = da8xx_fb_info->par;
-       par->dev = &device->dev;
-       par->lcdc_clk = tmp_lcdc_clk;
-       par->lcdc_clk_rate = clk_get_rate(par->lcdc_clk);
-
-       par->lcd_supply = devm_regulator_get_optional(&device->dev, "lcd");
-       if (IS_ERR(par->lcd_supply)) {
-               if (PTR_ERR(par->lcd_supply) == -EPROBE_DEFER) {
-                       ret = -EPROBE_DEFER;
-                       goto err_release_fb;
-               }
-
-               par->lcd_supply = NULL;
-       } else {
-               ret = regulator_enable(par->lcd_supply);
-               if (ret)
-                       goto err_release_fb;
-       }
-
-       fb_videomode_to_var(&da8xx_fb_var, lcdc_info);
-       par->cfg = *lcd_cfg;
-
-       da8xx_fb_lcd_reset();
-
-       /* allocate frame buffer */
-       par->vram_size = lcdc_info->xres * lcdc_info->yres * lcd_cfg->bpp;
-       ulcm = lcm((lcdc_info->xres * lcd_cfg->bpp)/8, PAGE_SIZE);
-       par->vram_size = roundup(par->vram_size/8, ulcm);
-       par->vram_size = par->vram_size * LCD_NUM_BUFFERS;
-
-       par->vram_virt = dmam_alloc_coherent(par->dev,
-                                            par->vram_size,
-                                            &par->vram_phys,
-                                            GFP_KERNEL | GFP_DMA);
-       if (!par->vram_virt) {
-               dev_err(&device->dev,
-                       "GLCD: kmalloc for frame buffer failed\n");
-               ret = -EINVAL;
-               goto err_disable_reg;
-       }
-
-       da8xx_fb_info->screen_base = (char __iomem *) par->vram_virt;
-       da8xx_fb_fix.smem_start    = par->vram_phys;
-       da8xx_fb_fix.smem_len      = par->vram_size;
-       da8xx_fb_fix.line_length   = (lcdc_info->xres * lcd_cfg->bpp) / 8;
-
-       par->dma_start = par->vram_phys;
-       par->dma_end   = par->dma_start + lcdc_info->yres *
-               da8xx_fb_fix.line_length - 1;
-
-       /* allocate palette buffer */
-       par->v_palette_base = dmam_alloc_coherent(par->dev, PALETTE_SIZE,
-                                                 &par->p_palette_base,
-                                                 GFP_KERNEL | GFP_DMA);
-       if (!par->v_palette_base) {
-               dev_err(&device->dev,
-                       "GLCD: kmalloc for palette buffer failed\n");
-               ret = -EINVAL;
-               goto err_release_fb;
-       }
-
-       par->irq = platform_get_irq(device, 0);
-       if (par->irq < 0) {
-               ret = -ENOENT;
-               goto err_release_fb;
-       }
-
-       da8xx_fb_var.grayscale =
-           lcd_cfg->panel_shade == MONOCHROME ? 1 : 0;
-       da8xx_fb_var.bits_per_pixel = lcd_cfg->bpp;
-
-       /* Initialize fbinfo */
-       da8xx_fb_info->fix = da8xx_fb_fix;
-       da8xx_fb_info->var = da8xx_fb_var;
-       da8xx_fb_info->fbops = &da8xx_fb_ops;
-       da8xx_fb_info->pseudo_palette = par->pseudo_palette;
-       da8xx_fb_info->fix.visual = (da8xx_fb_info->var.bits_per_pixel <= 8) ?
-                               FB_VISUAL_PSEUDOCOLOR : FB_VISUAL_TRUECOLOR;
-
-       ret = fb_alloc_cmap(&da8xx_fb_info->cmap, PALETTE_SIZE, 0);
-       if (ret)
-               goto err_disable_reg;
-       da8xx_fb_info->cmap.len = par->palette_sz;
-
-       /* initialize var_screeninfo */
-       da8xx_fb_var.activate = FB_ACTIVATE_FORCE;
-       fb_set_var(da8xx_fb_info, &da8xx_fb_var);
-
-       platform_set_drvdata(device, da8xx_fb_info);
-
-       /* initialize the vsync wait queue */
-       init_waitqueue_head(&par->vsync_wait);
-       par->vsync_timeout = HZ / 5;
-       par->which_dma_channel_done = -1;
-       spin_lock_init(&par->lock_for_chan_update);
-
-       /* Register the Frame Buffer  */
-       if (register_framebuffer(da8xx_fb_info) < 0) {
-               dev_err(&device->dev,
-                       "GLCD: Frame Buffer Registration Failed!\n");
-               ret = -EINVAL;
-               goto err_dealloc_cmap;
-       }
-
-#ifdef CONFIG_CPU_FREQ
-       ret = lcd_da8xx_cpufreq_register(par);
-       if (ret) {
-               dev_err(&device->dev, "failed to register cpufreq\n");
-               goto err_cpu_freq;
-       }
-#endif
-
-       if (lcd_revision == LCD_VERSION_1)
-               lcdc_irq_handler = lcdc_irq_handler_rev01;
-       else {
-               init_waitqueue_head(&frame_done_wq);
-               lcdc_irq_handler = lcdc_irq_handler_rev02;
-       }
-
-       ret = devm_request_irq(&device->dev, par->irq, lcdc_irq_handler, 0,
-                              DRIVER_NAME, par);
-       if (ret)
-               goto irq_freq;
-       return 0;
-
-irq_freq:
-#ifdef CONFIG_CPU_FREQ
-       lcd_da8xx_cpufreq_deregister(par);
-err_cpu_freq:
-#endif
-       unregister_framebuffer(da8xx_fb_info);
-
-err_dealloc_cmap:
-       fb_dealloc_cmap(&da8xx_fb_info->cmap);
-
-err_disable_reg:
-       if (par->lcd_supply)
-               regulator_disable(par->lcd_supply);
-err_release_fb:
-       framebuffer_release(da8xx_fb_info);
-
-err_pm_runtime_disable:
-       pm_runtime_put_sync(&device->dev);
-       pm_runtime_disable(&device->dev);
-
-       return ret;
-}
-
-#ifdef CONFIG_PM_SLEEP
-static struct lcdc_context {
-       u32 clk_enable;
-       u32 ctrl;
-       u32 dma_ctrl;
-       u32 raster_timing_0;
-       u32 raster_timing_1;
-       u32 raster_timing_2;
-       u32 int_enable_set;
-       u32 dma_frm_buf_base_addr_0;
-       u32 dma_frm_buf_ceiling_addr_0;
-       u32 dma_frm_buf_base_addr_1;
-       u32 dma_frm_buf_ceiling_addr_1;
-       u32 raster_ctrl;
-} reg_context;
-
-static void lcd_context_save(void)
-{
-       if (lcd_revision == LCD_VERSION_2) {
-               reg_context.clk_enable = lcdc_read(LCD_CLK_ENABLE_REG);
-               reg_context.int_enable_set = lcdc_read(LCD_INT_ENABLE_SET_REG);
-       }
-
-       reg_context.ctrl = lcdc_read(LCD_CTRL_REG);
-       reg_context.dma_ctrl = lcdc_read(LCD_DMA_CTRL_REG);
-       reg_context.raster_timing_0 = lcdc_read(LCD_RASTER_TIMING_0_REG);
-       reg_context.raster_timing_1 = lcdc_read(LCD_RASTER_TIMING_1_REG);
-       reg_context.raster_timing_2 = lcdc_read(LCD_RASTER_TIMING_2_REG);
-       reg_context.dma_frm_buf_base_addr_0 =
-               lcdc_read(LCD_DMA_FRM_BUF_BASE_ADDR_0_REG);
-       reg_context.dma_frm_buf_ceiling_addr_0 =
-               lcdc_read(LCD_DMA_FRM_BUF_CEILING_ADDR_0_REG);
-       reg_context.dma_frm_buf_base_addr_1 =
-               lcdc_read(LCD_DMA_FRM_BUF_BASE_ADDR_1_REG);
-       reg_context.dma_frm_buf_ceiling_addr_1 =
-               lcdc_read(LCD_DMA_FRM_BUF_CEILING_ADDR_1_REG);
-       reg_context.raster_ctrl = lcdc_read(LCD_RASTER_CTRL_REG);
-       return;
-}
-
-static void lcd_context_restore(void)
-{
-       if (lcd_revision == LCD_VERSION_2) {
-               lcdc_write(reg_context.clk_enable, LCD_CLK_ENABLE_REG);
-               lcdc_write(reg_context.int_enable_set, LCD_INT_ENABLE_SET_REG);
-       }
-
-       lcdc_write(reg_context.ctrl, LCD_CTRL_REG);
-       lcdc_write(reg_context.dma_ctrl, LCD_DMA_CTRL_REG);
-       lcdc_write(reg_context.raster_timing_0, LCD_RASTER_TIMING_0_REG);
-       lcdc_write(reg_context.raster_timing_1, LCD_RASTER_TIMING_1_REG);
-       lcdc_write(reg_context.raster_timing_2, LCD_RASTER_TIMING_2_REG);
-       lcdc_write(reg_context.dma_frm_buf_base_addr_0,
-                       LCD_DMA_FRM_BUF_BASE_ADDR_0_REG);
-       lcdc_write(reg_context.dma_frm_buf_ceiling_addr_0,
-                       LCD_DMA_FRM_BUF_CEILING_ADDR_0_REG);
-       lcdc_write(reg_context.dma_frm_buf_base_addr_1,
-                       LCD_DMA_FRM_BUF_BASE_ADDR_1_REG);
-       lcdc_write(reg_context.dma_frm_buf_ceiling_addr_1,
-                       LCD_DMA_FRM_BUF_CEILING_ADDR_1_REG);
-       lcdc_write(reg_context.raster_ctrl, LCD_RASTER_CTRL_REG);
-       return;
-}
-
-static int fb_suspend(struct device *dev)
-{
-       struct fb_info *info = dev_get_drvdata(dev);
-       struct da8xx_fb_par *par = info->par;
-       int ret;
-
-       console_lock();
-       if (par->lcd_supply) {
-               ret = regulator_disable(par->lcd_supply);
-               if (ret)
-                       return ret;
-       }
-
-       fb_set_suspend(info, 1);
-       lcd_disable_raster(DA8XX_FRAME_WAIT);
-       lcd_context_save();
-       pm_runtime_put_sync(dev);
-       console_unlock();
-
-       return 0;
-}
-static int fb_resume(struct device *dev)
-{
-       struct fb_info *info = dev_get_drvdata(dev);
-       struct da8xx_fb_par *par = info->par;
-       int ret;
-
-       console_lock();
-       pm_runtime_get_sync(dev);
-       lcd_context_restore();
-       if (par->blank == FB_BLANK_UNBLANK) {
-               lcd_enable_raster();
-
-               if (par->lcd_supply) {
-                       ret = regulator_enable(par->lcd_supply);
-                       if (ret)
-                               return ret;
-               }
-       }
-
-       fb_set_suspend(info, 0);
-       console_unlock();
-
-       return 0;
-}
-#endif
-
-static SIMPLE_DEV_PM_OPS(fb_pm_ops, fb_suspend, fb_resume);
-
-static struct platform_driver da8xx_fb_driver = {
-       .probe = fb_probe,
-       .remove_new = fb_remove,
-       .driver = {
-                  .name = DRIVER_NAME,
-                  .pm  = &fb_pm_ops,
-                  },
-};
-module_platform_driver(da8xx_fb_driver);
-
-MODULE_DESCRIPTION("Framebuffer driver for TI da8xx/omap-l1xx");
-MODULE_AUTHOR("Texas Instruments");
-MODULE_LICENSE("GPL");
index 3e378874ccc79ea673d340c8a183cddbd227cb78..801ef427f1baf1bf3b3762c94da14112b062a111 100644 (file)
@@ -592,7 +592,7 @@ static void ep93xxfb_remove(struct platform_device *pdev)
 
 static struct platform_driver ep93xxfb_driver = {
        .probe          = ep93xxfb_probe,
-       .remove_new     = ep93xxfb_remove,
+       .remove         = ep93xxfb_remove,
        .driver = {
                .name   = "ep93xx-fb",
        },
index 2a0f5337e091ef036ab39d317e57ab5831a7b636..34b6abff9493e30d9fa5e80d2ce77111c9bd096d 100644 (file)
@@ -710,7 +710,7 @@ static int ffb_blank(int blank, struct fb_info *info)
        return 0;
 }
 
-static struct sbus_mmap_map ffb_mmap_map[] = {
+static const struct sbus_mmap_map ffb_mmap_map[] = {
        {
                .voff   = FFB_SFB8R_VOFF,
                .poff   = FFB_SFB8R_POFF,
@@ -1053,7 +1053,7 @@ static struct platform_driver ffb_driver = {
                .of_match_table = ffb_match,
        },
        .probe          = ffb_probe,
-       .remove_new     = ffb_remove,
+       .remove         = ffb_remove,
 };
 
 static int __init ffb_init(void)
index ea37a60da10c42c88770482e99a9566ee90e4b0b..5ac8201c353378fbef760b513013c4b88e562a7b 100644 (file)
@@ -1876,12 +1876,12 @@ static const struct of_device_id fsl_diu_match[] = {
 MODULE_DEVICE_TABLE(of, fsl_diu_match);
 
 static struct platform_driver fsl_diu_driver = {
-       .driver = {
+       .driver         = {
                .name = "fsl-diu-fb",
                .of_match_table = fsl_diu_match,
        },
-       .probe          = fsl_diu_probe,
-       .remove_new     = fsl_diu_remove,
+       .probe          = fsl_diu_probe,
+       .remove         = fsl_diu_remove,
        .suspend        = fsl_diu_suspend,
        .resume         = fsl_diu_resume,
 };
index 8463de833d1e19efb27b2c4d2b6d1952e139fb71..4c36a3e409bea9c6b4b99316759f4ba7a84eb338 100644 (file)
@@ -1247,10 +1247,10 @@ static void gbefb_remove(struct platform_device* p_dev)
 
 static struct platform_driver gbefb_driver = {
        .probe = gbefb_probe,
-       .remove_new = gbefb_remove,
-       .driver = {
+       .remove = gbefb_remove,
+       .driver = {
                .name = "gbefb",
-               .dev_groups     = gbefb_groups,
+               .dev_groups = gbefb_groups,
        },
 };
 
index 5f8de1ec23c3c89fc1f1775ef5bf24071e957e07..7704f2ab18c03cc2f8accfeceffd5ff7a377dcfe 100644 (file)
@@ -311,7 +311,7 @@ MODULE_DEVICE_TABLE(acpi, goldfish_fb_acpi_match);
 
 static struct platform_driver goldfish_fb_driver = {
        .probe          = goldfish_fb_probe,
-       .remove_new     = goldfish_fb_remove,
+       .remove         = goldfish_fb_remove,
        .driver = {
                .name = "goldfish_fb",
                .of_match_table = goldfish_fb_of_match,
index 6d917e06e5f3b36b25fe60d7203fce6f256f268d..de8ab817d406568c93248c63ecce3ced694b41dd 100644 (file)
@@ -540,7 +540,7 @@ static struct platform_driver grvga_driver = {
                .of_match_table = svgactrl_of_match,
        },
        .probe          = grvga_probe,
-       .remove_new     = grvga_remove,
+       .remove         = grvga_remove,
 };
 
 module_platform_driver(grvga_driver);
index ef526ed4a2d9ca39aa893b8403666b9e43bdb302..3547d58a29cf2f848c1c0197e890279cf0c5cdfd 100644 (file)
@@ -235,7 +235,7 @@ static void hecubafb_remove(struct platform_device *dev)
 
 static struct platform_driver hecubafb_driver = {
        .probe  = hecubafb_probe,
-       .remove_new = hecubafb_remove,
+       .remove = hecubafb_remove,
        .driver = {
                .name   = "hecubafb",
        },
index c3bc5b78b749a295883dfcdea3c923ebef11fff4..14418aa3791aa3b223361e729112b9b9d22bf45c 100644 (file)
@@ -629,7 +629,7 @@ static void hgafb_remove(struct platform_device *pdev)
 
 static struct platform_driver hgafb_driver = {
        .probe = hgafb_probe,
-       .remove_new = hgafb_remove,
+       .remove = hgafb_remove,
        .driver = {
                .name = "hgafb",
        },
index b64b74b76c71f955e9489544dfaa0b735e3389e7..97db325df2b4564a0542499357be499c8bc2e1d7 100644 (file)
@@ -476,7 +476,7 @@ static const struct dev_pm_ops hitfb_dev_pm_ops = {
 
 static struct platform_driver hitfb_driver = {
        .probe          = hitfb_probe,
-       .remove_new     = hitfb_remove,
+       .remove         = hitfb_remove,
        .driver         = {
                .name   = "hitfb",
                .pm     = &hitfb_dev_pm_ops,
index 4ebfe9b9df60a4b87614571b56f28daede5669ba..ff343e4ed35ba5c120cbaf487c46d85cdf68cfc4 100644 (file)
@@ -1105,7 +1105,7 @@ static struct platform_driver imxfb_driver = {
                .pm     = pm_sleep_ptr(&imxfb_pm_ops),
        },
        .probe          = imxfb_probe,
-       .remove_new     = imxfb_remove,
+       .remove         = imxfb_remove,
        .id_table       = imxfb_devtype,
 };
 module_platform_driver(imxfb_driver);
index 7cf525c76079b63b12c9eba0e8604448b81caf2b..b9fb059df2c700994d73eff582b15e1fdc4869ef 100644 (file)
@@ -338,7 +338,7 @@ static int leo_blank(int blank, struct fb_info *info)
        return 0;
 }
 
-static struct sbus_mmap_map leo_mmap_map[] = {
+static const struct sbus_mmap_map leo_mmap_map[] = {
        {
                .voff   = LEO_SS0_MAP,
                .poff   = LEO_OFF_SS0,
@@ -657,7 +657,7 @@ static struct platform_driver leo_driver = {
                .of_match_table = leo_match,
        },
        .probe          = leo_probe,
-       .remove_new     = leo_remove,
+       .remove         = leo_remove,
 };
 
 static int __init leo_init(void)
index c93c69bbcd579b807049ed5455be57699d43619a..a6437c40fc57dbbe5566e2c577d9813aeef37e2e 100644 (file)
@@ -44,7 +44,7 @@
 #include <linux/kd.h>
 
 #include <asm/io.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #if defined(CONFIG_PPC_PMAC)
 #include "../macmodes.h"
index baec312d7b33bc9f03a7aa8c5155358e3a791331..ade88e7bc7607f78bb9972b0286b73119c00682f 100644 (file)
@@ -834,7 +834,7 @@ static struct platform_driver of_platform_mb862xxfb_driver = {
                .of_match_table = of_platform_mb862xx_tbl,
        },
        .probe          = of_platform_mb862xx_probe,
-       .remove_new     = of_platform_mb862xx_remove,
+       .remove         = of_platform_mb862xx_remove,
 };
 #endif
 
index 130394616a7ca58f4e25deb3d402c74241df459b..6f0942c6e5f1c68d97b6d6db598bda839a8cae04 100644 (file)
@@ -37,7 +37,7 @@
 
 #include <video/metronomefb.h>
 
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 /* Display specific information */
 #define DPY_W 832
@@ -707,7 +707,7 @@ static void metronomefb_remove(struct platform_device *dev)
 
 static struct platform_driver metronomefb_driver = {
        .probe  = metronomefb_probe,
-       .remove_new = metronomefb_remove,
+       .remove = metronomefb_remove,
        .driver = {
                .name   = "metronomefb",
        },
index 9b0a324bb1b481573727476660a45a2a8eeb04a9..75afaa07e7eba5bb1d1e384882d7ec30d6147eba 100644 (file)
@@ -1509,10 +1509,10 @@ void NVLoadStateExt(struct nvidia_par *par, RIVA_HW_STATE * state)
        NV_WR32(par->PFIFO, 0x0495 * 4, 0x00000001);
        NV_WR32(par->PFIFO, 0x0140 * 4, 0x00000001);
 
-    if (!state) {
-           par->CurrentState = NULL;
-           return;
-    }
+       if (!state) {
+               par->CurrentState = NULL;
+               return;
+       }
 
        if (par->Architecture >= NV_ARCH_10) {
                if (par->twoHeads) {
index 7dc305c67af80522c7932cb72a9d61098933c7fa..893888260c21c406ea7668c2d629e6a80aa34a51 100644 (file)
@@ -391,7 +391,7 @@ MODULE_DEVICE_TABLE(of, ocfb_match);
 
 static struct platform_driver ocfb_driver = {
        .probe  = ocfb_probe,
-       .remove_new = ocfb_remove,
+       .remove = ocfb_remove,
        .driver = {
                .name = "ocfb_fb",
                .of_match_table = ocfb_match,
index e8ff33894603cefebc2c5191324a1065db272a91..f85428e13996baf473c14fc4114a7cb90a45d6c9 100644 (file)
@@ -673,7 +673,7 @@ static struct platform_driver offb_driver_bootx_noscreen = {
                .name = "bootx-noscreen",
        },
        .probe = offb_probe_bootx_noscreen,
-       .remove_new = offb_remove,
+       .remove = offb_remove,
 };
 
 static int offb_probe_display(struct platform_device *pdev)
@@ -695,7 +695,7 @@ static struct platform_driver offb_driver_display = {
                .of_match_table = offb_of_match_display,
        },
        .probe = offb_probe_display,
-       .remove_new = offb_remove,
+       .remove = offb_remove,
 };
 
 static int __init offb_init(void)
index e12c6019a4d64237758ce25349cc14d93f1c5cc0..2682b20d184a096d3783130975ef0bf6f6802417 100644 (file)
@@ -1825,7 +1825,7 @@ static int omapfb_resume(struct platform_device *pdev)
 
 static struct platform_driver omapfb_driver = {
        .probe          = omapfb_probe,
-       .remove_new     = omapfb_remove,
+       .remove         = omapfb_remove,
        .suspend        = omapfb_suspend,
        .resume         = omapfb_resume,
        .driver         = {
index c6786726a1af1da9cd50b940c9f0502a0512b317..cef1603b753084b92b43f162952080cbcd91fc95 100644 (file)
@@ -245,7 +245,7 @@ MODULE_DEVICE_TABLE(of, tvc_of_match);
 
 static struct platform_driver tvc_connector_driver = {
        .probe  = tvc_probe,
-       .remove_new = tvc_remove,
+       .remove = tvc_remove,
        .driver = {
                .name   = "connector-analog-tv",
                .of_match_table = tvc_of_match,
index 0cc9294f89b497eb963888a831fa91044e300fad..3f129ce9ff01a44776878465e2054c2671de25af 100644 (file)
@@ -328,7 +328,7 @@ MODULE_DEVICE_TABLE(of, dvic_of_match);
 
 static struct platform_driver dvi_connector_driver = {
        .probe  = dvic_probe,
-       .remove_new = dvic_remove,
+       .remove = dvic_remove,
        .driver = {
                .name   = "connector-dvi",
                .of_match_table = dvic_of_match,
index b862a32670aeff30c79214bf21ad5d0a58ce1419..e3df731172e83004b6734faa8befd0c5b0052b30 100644 (file)
@@ -272,7 +272,7 @@ MODULE_DEVICE_TABLE(of, hdmic_of_match);
 
 static struct platform_driver hdmi_connector_driver = {
        .probe  = hdmic_probe,
-       .remove_new = hdmic_remove,
+       .remove = hdmic_remove,
        .driver = {
                .name   = "connector-hdmi",
                .of_match_table = hdmic_of_match,
index f0d3eb581166bd3a66a5f4fcb8053a9c9abf9752..f4e7ed943b8a4256e72f95c5a20b94d48f25d1a9 100644 (file)
@@ -258,7 +258,7 @@ MODULE_DEVICE_TABLE(of, opa362_of_match);
 
 static struct platform_driver opa362_driver = {
        .probe  = opa362_probe,
-       .remove_new = opa362_remove,
+       .remove = opa362_remove,
        .driver = {
                .name   = "amplifier-opa362",
                .of_match_table = opa362_of_match,
index c8aca4592949cb3b1ea61a1cf40fc6debd3ec32a..458e65771cbb76b1b64b353c5e4b686dc1b0a6f0 100644 (file)
@@ -245,7 +245,7 @@ MODULE_DEVICE_TABLE(of, tfp410_of_match);
 
 static struct platform_driver tfp410_driver = {
        .probe  = tfp410_probe,
-       .remove_new = tfp410_remove,
+       .remove = tfp410_remove,
        .driver = {
                .name   = "tfp410",
                .of_match_table = tfp410_of_match,
index eb3926d0361b9e928365739fe2e3adda8c423b3d..8cf0cb922f3c003fe473b897d8026aec239bb481 100644 (file)
@@ -311,7 +311,7 @@ MODULE_DEVICE_TABLE(of, tpd_of_match);
 
 static struct platform_driver tpd_driver = {
        .probe  = tpd_probe,
-       .remove_new = tpd_remove,
+       .remove = tpd_remove,
        .driver = {
                .name   = "tpd12s015",
                .of_match_table = tpd_of_match,
index 937f9091274f03d3e9855a77ca228c4527fa0b01..22f4262b2432421cf7680c9b7311e69f77ba86b7 100644 (file)
@@ -234,7 +234,7 @@ MODULE_DEVICE_TABLE(of, panel_dpi_of_match);
 
 static struct platform_driver panel_dpi_driver = {
        .probe = panel_dpi_probe,
-       .remove_new = panel_dpi_remove,
+       .remove = panel_dpi_remove,
        .driver = {
                .name = "panel-dpi",
                .of_match_table = panel_dpi_of_match,
index 274bdf7b3b459fbcd4e34af51dbaf937d2b0e7cf..4a0df640ab6484c787070f503402dbb5798214d6 100644 (file)
@@ -1275,7 +1275,7 @@ MODULE_DEVICE_TABLE(of, dsicm_of_match);
 
 static struct platform_driver dsicm_driver = {
        .probe = dsicm_probe,
-       .remove_new = dsicm_remove,
+       .remove = dsicm_remove,
        .driver = {
                .name = "panel-dsi-cm",
                .of_match_table = dsicm_of_match,
index e37268cf8dcaec4536e11369343966beb5538aa7..888d94ea8e7db8a20c7e31c6f24752be0b2d5c80 100644 (file)
@@ -315,7 +315,7 @@ MODULE_DEVICE_TABLE(of, sharp_ls_of_match);
 
 static struct platform_driver sharp_ls_driver = {
        .probe = sharp_ls_probe,
-       .remove_new = sharp_ls_remove,
+       .remove = sharp_ls_remove,
        .driver = {
                .name = "panel-sharp-ls037v7dw01",
                .of_match_table = sharp_ls_of_match,
index 5fbd8885bad8a75a1d9cfefacca0259bbe827e0f..55b640f2f24564a8d89af3582ac136c8edf5a828 100644 (file)
@@ -185,10 +185,10 @@ static void omap_dss_shutdown(struct platform_device *pdev)
 }
 
 static struct platform_driver omap_dss_driver = {
-       .remove_new     = omap_dss_remove,
+       .remove         = omap_dss_remove,
        .shutdown       = omap_dss_shutdown,
-       .driver         = {
-               .name   = "omapdss",
+       .driver         = {
+               .name   = "omapdss",
        },
 };
 
index 21fef9db90d26a371906ad78fd00c37d8de31156..5832485ab998c48e698e403c6be73c7d74aa14f3 100644 (file)
@@ -4072,7 +4072,7 @@ static const struct of_device_id dispc_of_match[] = {
 
 static struct platform_driver omap_dispchw_driver = {
        .probe          = dispc_probe,
-       .remove_new     = dispc_remove,
+       .remove         = dispc_remove,
        .driver         = {
                .name   = "omapdss_dispc",
                .pm     = &dispc_pm_ops,
index 7c1b7d89389aa4f6928cdb7e0a05479ec0a236c6..c40b87ffe8fcbfa2a687597eb18cd1e79b775e93 100644 (file)
@@ -817,8 +817,8 @@ static void dpi_remove(struct platform_device *pdev)
 
 static struct platform_driver omap_dpi_driver = {
        .probe          = dpi_probe,
-       .remove_new     = dpi_remove,
-       .driver         = {
+       .remove         = dpi_remove,
+       .driver         = {
                .name   = "omapdss_dpi",
                .suppress_bind_attrs = true,
        },
index 1f13bcf73da54fe1eb38724be8e27065f98b5bb8..1f3434c040c14a0325f17fa24840c3be757d74ae 100644 (file)
@@ -5565,7 +5565,7 @@ static const struct of_device_id dsi_of_match[] = {
 
 static struct platform_driver omap_dsihw_driver = {
        .probe          = dsi_probe,
-       .remove_new     = dsi_remove,
+       .remove         = dsi_remove,
        .driver         = {
                .name   = "omapdss_dsi",
                .pm     = &dsi_pm_ops,
index d814e4baa4b33a66ad36a866a48f96da1b139287..f06debee02c5c57b29ed0aa6fb8eee7cf00e88cb 100644 (file)
@@ -1278,7 +1278,7 @@ MODULE_DEVICE_TABLE(of, dss_of_match);
 
 static struct platform_driver omap_dsshw_driver = {
        .probe          = dss_probe,
-       .remove_new     = dss_remove,
+       .remove         = dss_remove,
        .driver         = {
                .name   = "omapdss_dss",
                .pm     = &dss_pm_ops,
index 8f407ec134dc3302d643b747c21883654ee497fa..428001fd4ac9d4fc731dff068fbeb77f7e8a6e7b 100644 (file)
@@ -792,9 +792,9 @@ static const struct of_device_id hdmi_of_match[] = {
 
 static struct platform_driver omapdss_hdmihw_driver = {
        .probe          = hdmi4_probe,
-       .remove_new     = hdmi4_remove,
-       .driver         = {
-               .name   = "omapdss_hdmi",
+       .remove         = hdmi4_remove,
+       .driver         = {
+               .name   = "omapdss_hdmi",
                .pm     = &hdmi_pm_ops,
                .of_match_table = hdmi_of_match,
                .suppress_bind_attrs = true,
index 4ad219f522b90befee7ec311851441f9a79feb18..aa052805050e467cb11a381cd943f10d02499be4 100644 (file)
@@ -834,7 +834,7 @@ static const struct of_device_id hdmi_of_match[] = {
 
 static struct platform_driver omapdss_hdmihw_driver = {
        .probe          = hdmi5_probe,
-       .remove_new     = hdmi5_remove,
+       .remove         = hdmi5_remove,
        .driver         = {
                .name   = "omapdss_hdmi5",
                .pm     = &hdmi_pm_ops,
index d527931b2b165421f82fda7d16f9db7160ffe74c..2a45f019ef4574a946b2c5568dea55aacd0d9d0b 100644 (file)
@@ -382,9 +382,9 @@ static void sdi_remove(struct platform_device *pdev)
 
 static struct platform_driver omap_sdi_driver = {
        .probe          = sdi_probe,
-       .remove_new     = sdi_remove,
-       .driver         = {
-               .name   = "omapdss_sdi",
+       .remove         = sdi_remove,
+       .driver         = {
+               .name   = "omapdss_sdi",
                .suppress_bind_attrs = true,
        },
 };
index d13ad00d353bb5e8de048ae21fba6fbaf1d3e4fb..f99dda9e55a5abe0a7a45d3871418d5372bdd99a 100644 (file)
@@ -920,9 +920,9 @@ static const struct of_device_id venc_of_match[] = {
 
 static struct platform_driver omap_venchw_driver = {
        .probe          = venc_probe,
-       .remove_new     = venc_remove,
-       .driver         = {
-               .name   = "omapdss_venc",
+       .remove         = venc_remove,
+       .driver         = {
+               .name   = "omapdss_venc",
                .pm     = &venc_pm_ops,
                .of_match_table = venc_of_match,
                .suppress_bind_attrs = true,
index 0db9c55fce5a281b21aeadb386a77be469638908..211f23648686ced67eaa7ee5e00322936e254ba1 100644 (file)
@@ -2614,7 +2614,7 @@ static void omapfb_remove(struct platform_device *pdev)
 
 static struct platform_driver omapfb_driver = {
        .probe          = omapfb_probe,
-       .remove_new     = omapfb_remove,
+       .remove         = omapfb_remove,
        .driver         = {
                .name   = "omapfb",
        },
index e1356f8a866ea25cb9ff545fe135c3cce196fb80..0bc0f78fe4b9f4cbf0aa379eaaccb46ef66e6688 100644 (file)
@@ -206,7 +206,7 @@ p9100_blank(int blank, struct fb_info *info)
        return 0;
 }
 
-static struct sbus_mmap_map p9100_mmap_map[] = {
+static const struct sbus_mmap_map p9100_mmap_map[] = {
        { CG3_MMAP_OFFSET,      0,              SBUS_MMAP_FBSIZE(1) },
        { 0,                    0,              0                   }
 };
@@ -347,7 +347,7 @@ static struct platform_driver p9100_driver = {
                .of_match_table = p9100_match,
        },
        .probe          = p9100_probe,
-       .remove_new     = p9100_remove,
+       .remove         = p9100_remove,
 };
 
 static int __init p9100_init(void)
index cb6fcc64c8e20c37132f2d4babed4095ffef626d..a08d955d9b439426e457394031661d6d319f5554 100644 (file)
@@ -668,7 +668,7 @@ static struct platform_driver platinum_driver =
                .of_match_table = platinumfb_match,
        },
        .probe          = platinumfb_probe,
-       .remove_new     = platinumfb_remove,
+       .remove         = platinumfb_remove,
 };
 
 static int __init platinumfb_init(void)
index adee34386580061f39e9a6306146b3ce62250c2a..ec602f7776eb03105d8ce0cc1b582d40ca6dab40 100644 (file)
@@ -799,7 +799,7 @@ static struct platform_driver pxa168fb_driver = {
                .name   = "pxa168-fb",
        },
        .probe          = pxa168fb_probe,
-       .remove_new     = pxa168fb_remove,
+       .remove         = pxa168fb_remove,
 };
 
 module_platform_driver(pxa168fb_driver);
index 489088b4e467baba1dc2a2d644efe7c824d1ce0c..4a78b387b34356a1bfa0a5be80adeebe32d783f8 100644 (file)
@@ -696,10 +696,10 @@ MODULE_DEVICE_TABLE(of, pxa3xx_gcu_of_match);
 #endif
 
 static struct platform_driver pxa3xx_gcu_driver = {
-       .probe    = pxa3xx_gcu_probe,
-       .remove_new      = pxa3xx_gcu_remove,
-       .driver  = {
-               .name   = DRV_NAME,
+       .probe = pxa3xx_gcu_probe,
+       .remove = pxa3xx_gcu_remove,
+       .driver = {
+               .name = DRV_NAME,
                .of_match_table = of_match_ptr(pxa3xx_gcu_of_match),
        },
 };
index 5ce02495cda6380b30f67d202f131d105133cf4c..4aa84853e31a842b35d5a89e7285b0a43fe5321d 100644 (file)
@@ -2427,7 +2427,7 @@ MODULE_DEVICE_TABLE(of, pxafb_of_dev_id);
 
 static struct platform_driver pxafb_driver = {
        .probe          = pxafb_probe,
-       .remove_new     = pxafb_remove,
+       .remove         = pxafb_remove,
        .driver         = {
                .name   = "pxa2xx-fb",
                .of_match_table = pxafb_of_dev_id,
index 0e871197c6de681593f910785f03d419a4404d0c..e80c806ef520dc4beba2c5091a446c3c4c947a22 100644 (file)
@@ -1001,7 +1001,7 @@ static int s1d13xxxfb_resume(struct platform_device *dev)
 
 static struct platform_driver s1d13xxxfb_driver = {
        .probe          = s1d13xxxfb_probe,
-       .remove_new     = s1d13xxxfb_remove,
+       .remove         = s1d13xxxfb_remove,
 #ifdef CONFIG_PM
        .suspend        = s1d13xxxfb_suspend,
        .resume         = s1d13xxxfb_resume,
index 2b85aad6a3045130cacad76feaeb3d3e7e622afd..2f4d707e2e097f52bc7a8008ba33796b07b85735 100644 (file)
@@ -1789,7 +1789,7 @@ static const struct dev_pm_ops s3cfb_pm_ops = {
 
 static struct platform_driver s3c_fb_driver = {
        .probe          = s3c_fb_probe,
-       .remove_new     = s3c_fb_remove,
+       .remove         = s3c_fb_remove,
        .id_table       = s3c_fb_driver_ids,
        .driver         = {
                .name   = "s3c-fb",
index 634e3d159452c1619a311b13f22fedd787478563..4c79654bda30e6f141749aac1e8789997f9d6c1d 100644 (file)
@@ -38,7 +38,7 @@ static unsigned long sbusfb_mmapsize(long size, unsigned long fbsize)
        return fbsize * (-size);
 }
 
-int sbusfb_mmap_helper(struct sbus_mmap_map *map,
+int sbusfb_mmap_helper(const struct sbus_mmap_map *map,
                       unsigned long physbase,
                       unsigned long fbsize,
                       unsigned long iospace,
index 6466b4cbcd7b3a6afe2da66bf7688fea566856ea..e9af2dc93f94942bbde104705b0d81d06329c4c8 100644 (file)
@@ -19,7 +19,7 @@ struct sbus_mmap_map {
 
 extern void sbusfb_fill_var(struct fb_var_screeninfo *var,
                            struct device_node *dp, int bpp);
-extern int sbusfb_mmap_helper(struct sbus_mmap_map *map,
+extern int sbusfb_mmap_helper(const struct sbus_mmap_map *map,
                              unsigned long physbase, unsigned long fbsize,
                              unsigned long iospace,
                              struct vm_area_struct *vma);
index 08a4943dc54184144ff231211ac3887fb9aa2f99..3d2a27fefc874a766b27c0ab9984bb2676d5abb5 100644 (file)
@@ -575,7 +575,7 @@ static struct platform_driver sh7760_lcdc_driver = {
                   .name = "sh7760-lcdc",
                   },
        .probe = sh7760fb_probe,
-       .remove_new = sh7760fb_remove,
+       .remove = sh7760fb_remove,
 };
 
 module_platform_driver(sh7760_lcdc_driver);
index 73c69e39a68de7728a380c89dbc61d062e816567..6b37b188af3149112c6f6dd33cab8042b49a7ce1 100644 (file)
@@ -2648,7 +2648,7 @@ static struct platform_driver sh_mobile_lcdc_driver = {
                .pm             = &sh_mobile_lcdc_dev_pm_ops,
        },
        .probe          = sh_mobile_lcdc_probe,
-       .remove_new     = sh_mobile_lcdc_remove,
+       .remove         = sh_mobile_lcdc_remove,
 };
 
 module_platform_driver(sh_mobile_lcdc_driver);
index 028a565250476c5f58434b68a6ea5152e4ccd606..be95fcddce4c8ca794826b805cd7dad2985bd637 100644 (file)
@@ -677,7 +677,7 @@ static struct platform_driver simplefb_driver = {
                .of_match_table = simplefb_of_match,
        },
        .probe = simplefb_probe,
-       .remove_new = simplefb_remove,
+       .remove = simplefb_remove,
 };
 
 module_platform_driver(simplefb_driver);
index d6fdc1737cd2441f0537d2ab1436852b370ef601..86ecbb2d86db8d99a1d2c3b8f23e157a52992db5 100644 (file)
@@ -2211,7 +2211,7 @@ static int sm501fb_resume(struct platform_device *pdev)
 
 static struct platform_driver sm501fb_driver = {
        .probe          = sm501fb_probe,
-       .remove_new     = sm501fb_remove,
+       .remove         = sm501fb_remove,
        .suspend        = sm501fb_suspend,
        .resume         = sm501fb_resume,
        .driver         = {
index f8ae54ca0cc34f2e10735857bcfc05d504b46db5..2ea947f57efb3dd7eae170f3a44da1ffc191a08b 100644 (file)
@@ -716,6 +716,7 @@ static void sstfb_setvgapass( struct fb_info *info, int enable )
        pci_write_config_dword(sst_dev, PCI_INIT_ENABLE, tmp);
 }
 
+#ifdef CONFIG_FB_DEVICE
 static ssize_t store_vgapass(struct device *device, struct device_attribute *attr,
                        const char *buf, size_t count)
 {
@@ -739,7 +740,8 @@ static ssize_t show_vgapass(struct device *device, struct device_attribute *attr
 
 static struct device_attribute device_attrs[] = {
        __ATTR(vgapass, S_IRUGO|S_IWUSR, show_vgapass, store_vgapass)
-       };
+};
+#endif
 
 static int sstfb_ioctl(struct fb_info *info, unsigned int cmd,
                        unsigned long arg)
@@ -1436,9 +1438,10 @@ static int sstfb_probe(struct pci_dev *pdev, const struct pci_device_id *id)
 
        sstfb_clear_screen(info);
 
+#ifdef CONFIG_FB_DEVICE
        if (device_create_file(info->dev, &device_attrs[0]))
                printk(KERN_WARNING "sstfb: can't create sysfs entry.\n");
-
+#endif
 
        fb_info(info, "%s frame buffer device at 0x%p\n",
                fix->id, info->screen_base);
@@ -1468,7 +1471,9 @@ static void sstfb_remove(struct pci_dev *pdev)
        info = pci_get_drvdata(pdev);
        par = info->par;
 
+#ifdef CONFIG_FB_DEVICE
        device_remove_file(info->dev, &device_attrs[0]);
+#endif
        sst_shutdown(info);
        iounmap(info->screen_base);
        iounmap(par->mmio_vbase);
index fe7b7bc77eda39db4436c54f255c4d6b053c6a91..f9a0085ad72bf7f274eea48967d79e10b1dbd2cb 100644 (file)
@@ -236,7 +236,7 @@ tcx_blank(int blank, struct fb_info *info)
        return 0;
 }
 
-static struct sbus_mmap_map __tcx_mmap_map[TCX_MMAP_ENTRIES] = {
+static const struct sbus_mmap_map __tcx_mmap_map[TCX_MMAP_ENTRIES] = {
        {
                .voff   = TCX_RAM8BIT,
                .size   = SBUS_MMAP_FBSIZE(1)
@@ -505,7 +505,7 @@ static struct platform_driver tcx_driver = {
                .of_match_table = tcx_match,
        },
        .probe          = tcx_probe,
-       .remove_new     = tcx_remove,
+       .remove         = tcx_remove,
 };
 
 static int __init tcx_init(void)
index 1514ddac4cafc4b4b9483d707dc6bb7dc07a2c79..71ac9e36f67c68aa7a54dce32323047a2a9a48bf 100644 (file)
@@ -23,7 +23,7 @@
 #include <linux/vmalloc.h>
 #include <linux/slab.h>
 #include <linux/delay.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include <video/udlfb.h>
 #include "edid.h"
 
index 2a88f0d4a84c5c4cfc6f5d3959afb96f4e63d083..5d52fd00806e9f88ef045eef102a8307819c0d4d 100644 (file)
@@ -1794,7 +1794,7 @@ static void uvesafb_remove(struct platform_device *dev)
 
 static struct platform_driver uvesafb_driver = {
        .probe  = uvesafb_probe,
-       .remove_new = uvesafb_remove,
+       .remove = uvesafb_remove,
        .driver = {
                .name = "uvesafb",
        },
index 5a161750a3aeeff51b8a2ee1fa43b231c347dfc1..a81df88651433aa082f8a0c0a02c84ec93c3a683 100644 (file)
@@ -515,7 +515,7 @@ static struct platform_driver vesafb_driver = {
                .name = "vesa-framebuffer",
        },
        .probe = vesafb_probe,
-       .remove_new = vesafb_remove,
+       .remove = vesafb_remove,
 };
 
 module_platform_driver(vesafb_driver);
index 158e48385c243b5d8577a90fb98c67fbdf0c0bb8..5b7965f36c5eda0123410422cd5bebecc6dad78d 100644 (file)
@@ -493,7 +493,7 @@ static void vfb_remove(struct platform_device *dev)
 
 static struct platform_driver vfb_driver = {
        .probe  = vfb_probe,
-       .remove_new = vfb_remove,
+       .remove = vfb_remove,
        .driver = {
                .name   = "vfb",
        },
index a87bafbb119cc1dc6b60732d14ef6260fe8ca7c5..fce0f5db7ba3e5d57c3acf662c2295632859f3b7 100644 (file)
@@ -1417,7 +1417,7 @@ MODULE_DEVICE_TABLE(platform, vga16fb_driver_id_table);
 
 static struct platform_driver vga16fb_driver = {
        .probe = vga16fb_probe,
-       .remove_new = vga16fb_remove,
+       .remove = vga16fb_remove,
        .driver = {
                .name = "vga16fb",
        },
index 2719943c06f4268519fae2b572e670d3e12e6c5d..9577c2cd52c76c15fd6c13495e13646f69db6e21 100644 (file)
@@ -292,7 +292,7 @@ static struct platform_driver via_gpio_driver = {
                .name = "viafb-gpio",
        },
        .probe = viafb_gpio_probe,
-       .remove_new = viafb_gpio_remove,
+       .remove = viafb_gpio_remove,
 };
 
 int viafb_gpio_init(void)
index 5edd3827ca271a441c277d3977b61cdfc271289d..cdbd7a9b88173f9838d6cb289cd99010c8ee56e8 100644 (file)
@@ -265,7 +265,7 @@ static struct platform_driver via_i2c_driver = {
                .name = "viafb-i2c",
        },
        .probe = viafb_i2c_probe,
-       .remove_new = viafb_i2c_remove,
+       .remove = viafb_i2c_remove,
 };
 
 int viafb_i2c_init(void)
index ac73937073a76f7d22df39a503ac59bda2d4a7da..b08a6fdc53fd2f1b89a0524e7e97de9878031966 100644 (file)
@@ -471,7 +471,7 @@ static const struct of_device_id via_dt_ids[] = {
 
 static struct platform_driver vt8500lcd_driver = {
        .probe          = vt8500lcd_probe,
-       .remove_new     = vt8500lcd_remove,
+       .remove         = vt8500lcd_remove,
        .driver         = {
                .name   = "vt8500-lcd",
                .of_match_table = of_match_ptr(via_dt_ids),
index 00952e9c880287abf7fe17240e70aa15f9c20c6a..5caf74ca92fb3b21b78cc3c610ddd9dd39f00ad9 100644 (file)
@@ -392,7 +392,7 @@ static const struct of_device_id wmt_dt_ids[] = {
 
 static struct platform_driver wm8505fb_driver = {
        .probe          = wm8505fb_probe,
-       .remove_new     = wm8505fb_remove,
+       .remove         = wm8505fb_remove,
        .driver         = {
                .name   = DRIVER_NAME,
                .of_match_table = wmt_dt_ids,
index b70961901683f686f0d2760b37e657396e1a8fe5..69106299ab47cb75a4c1c5c923950ddabde836b0 100644 (file)
@@ -159,7 +159,7 @@ static const struct of_device_id wmt_dt_ids[] = {
 
 static struct platform_driver wmt_ge_rops_driver = {
        .probe          = wmt_ge_rops_probe,
-       .remove_new     = wmt_ge_rops_remove,
+       .remove         = wmt_ge_rops_remove,
        .driver         = {
                .name   = "wmt_ge_rops",
                .of_match_table = wmt_dt_ids,
index 33d20910cb41c4f82adf7c8ce3332ba60aba44db..0a6e05cd155a2cbdfff6d6c6900a2188446bb3bd 100644 (file)
@@ -488,7 +488,7 @@ MODULE_DEVICE_TABLE(of, xilinxfb_of_match);
 
 static struct platform_driver xilinxfb_of_driver = {
        .probe = xilinxfb_of_probe,
-       .remove_new = xilinxfb_of_remove,
+       .remove = xilinxfb_of_remove,
        .driver = {
                .name = DRIVER_NAME,
                .of_match_table = xilinxfb_of_match,
index be7309b1e86027e57de20ea20a1f37ce9c44811b..98374ed7c57723461c5ecfca46bf2d99731eaaf7 100644 (file)
@@ -2588,7 +2588,7 @@ irqreturn_t vring_interrupt(int irq, void *_vq)
 
        /* Just a hint for performance: so it's ok that this can be racy! */
        if (vq->event)
-               vq->event_triggered = true;
+               data_race(vq->event_triggered = true);
 
        pr_debug("virtqueue callback for %p (%p)\n", vq, vq->vq.callback);
        if (vq->vq.callback)
index 5ed33df68e9aba4ff67de423d7a6ab0be2b5eaa7..775838346bb50b5fe939d71444e2762144d42145 100644 (file)
@@ -20,7 +20,7 @@
 #include <linux/types.h>
 #include <linux/watchdog.h>
 
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #define ZIIRAVE_TIMEOUT_MIN    3
 #define ZIIRAVE_TIMEOUT_MAX    255
index 62035fe16bb8ac1354ea87720c0d0721983b9918..f7d6f47971fdf8a27db45841f43af081e7030289 100644 (file)
@@ -261,7 +261,6 @@ config XEN_SCSI_BACKEND
 config XEN_PRIVCMD
        tristate "Xen hypercall passthrough driver"
        depends on XEN
-       imply CONFIG_XEN_PCIDEV_BACKEND
        default m
        help
          The hypercall passthrough driver allows privileged user programs to
index 9e2096524fbc5c8136d14df557b334983d940b98..d2ee605c5ca1c7898a4dc5cc324b51af84497f13 100644 (file)
@@ -125,3 +125,27 @@ int xen_acpi_get_gsi_info(struct pci_dev *dev,
        return 0;
 }
 EXPORT_SYMBOL_GPL(xen_acpi_get_gsi_info);
+
+static get_gsi_from_sbdf_t get_gsi_from_sbdf;
+static DEFINE_RWLOCK(get_gsi_from_sbdf_lock);
+
+void xen_acpi_register_get_gsi_func(get_gsi_from_sbdf_t func)
+{
+       write_lock(&get_gsi_from_sbdf_lock);
+       get_gsi_from_sbdf = func;
+       write_unlock(&get_gsi_from_sbdf_lock);
+}
+EXPORT_SYMBOL_GPL(xen_acpi_register_get_gsi_func);
+
+int xen_acpi_get_gsi_from_sbdf(u32 sbdf)
+{
+       int ret = -EOPNOTSUPP;
+
+       read_lock(&get_gsi_from_sbdf_lock);
+       if (get_gsi_from_sbdf)
+               ret = get_gsi_from_sbdf(sbdf);
+       read_unlock(&get_gsi_from_sbdf_lock);
+
+       return ret;
+}
+EXPORT_SYMBOL_GPL(xen_acpi_get_gsi_from_sbdf);
index 3273cb8c2a6627ce9652773a0c16057aa12f7a8f..4f75bc876454fc20afa0cf6fc39578e582f963ce 100644 (file)
@@ -850,15 +850,13 @@ out:
 static long privcmd_ioctl_pcidev_get_gsi(struct file *file, void __user *udata)
 {
 #if defined(CONFIG_XEN_ACPI)
-       int rc = -EINVAL;
+       int rc;
        struct privcmd_pcidev_get_gsi kdata;
 
        if (copy_from_user(&kdata, udata, sizeof(kdata)))
                return -EFAULT;
 
-       if (IS_REACHABLE(CONFIG_XEN_PCIDEV_BACKEND))
-               rc = pcistub_get_gsi_from_sbdf(kdata.sbdf);
-
+       rc = xen_acpi_get_gsi_from_sbdf(kdata.sbdf);
        if (rc < 0)
                return rc;
 
index 2f3da5ac62cd888b60b1b5423f121196aa953d5a..b616b7768c3b97598446d43feef7f4aa2e266440 100644 (file)
@@ -227,7 +227,7 @@ static struct pci_dev *pcistub_device_get_pci_dev(struct xen_pcibk_device *pdev,
 }
 
 #ifdef CONFIG_XEN_ACPI
-int pcistub_get_gsi_from_sbdf(unsigned int sbdf)
+static int pcistub_get_gsi_from_sbdf(unsigned int sbdf)
 {
        struct pcistub_device *psdev;
        int domain = (sbdf >> 16) & 0xffff;
@@ -242,7 +242,6 @@ int pcistub_get_gsi_from_sbdf(unsigned int sbdf)
 
        return psdev->gsi;
 }
-EXPORT_SYMBOL_GPL(pcistub_get_gsi_from_sbdf);
 #endif
 
 struct pci_dev *pcistub_get_pci_dev_by_slot(struct xen_pcibk_device *pdev,
@@ -1757,11 +1756,19 @@ static int __init xen_pcibk_init(void)
                bus_register_notifier(&pci_bus_type, &pci_stub_nb);
 #endif
 
+#ifdef CONFIG_XEN_ACPI
+       xen_acpi_register_get_gsi_func(pcistub_get_gsi_from_sbdf);
+#endif
+
        return err;
 }
 
 static void __exit xen_pcibk_cleanup(void)
 {
+#ifdef CONFIG_XEN_ACPI
+       xen_acpi_register_get_gsi_func(NULL);
+#endif
+
 #ifdef CONFIG_PCI_IOV
        bus_unregister_notifier(&pci_bus_type, &pci_stub_nb);
 #endif
index de009a33e0e26d7b0cdfa6794fbc218b63fc0059..f84412290a30cf8019e24defeb9301f910371a50 100644 (file)
@@ -131,10 +131,9 @@ static struct p9_fid *v9fs_fid_find(struct dentry *dentry, kuid_t uid, int any)
                        }
                }
                spin_unlock(&dentry->d_lock);
-       } else {
-               if (dentry->d_inode)
-                       ret = v9fs_fid_find_inode(dentry->d_inode, false, uid, any);
        }
+       if (!ret && dentry->d_inode)
+               ret = v9fs_fid_find_inode(dentry->d_inode, false, uid, any);
 
        return ret;
 }
index 1775fcc7f0e8efa8b22f4c14e6886d85a22faeb5..698c43dd5dc867984e5072d0c43897080c1177b1 100644 (file)
@@ -179,14 +179,16 @@ extern int v9fs_vfs_rename(struct mnt_idmap *idmap,
                           struct inode *old_dir, struct dentry *old_dentry,
                           struct inode *new_dir, struct dentry *new_dentry,
                           unsigned int flags);
-extern struct inode *v9fs_fid_iget(struct super_block *sb, struct p9_fid *fid,
-                                               bool new);
+extern struct inode *v9fs_inode_from_fid(struct v9fs_session_info *v9ses,
+                                        struct p9_fid *fid,
+                                        struct super_block *sb, int new);
 extern const struct inode_operations v9fs_dir_inode_operations_dotl;
 extern const struct inode_operations v9fs_file_inode_operations_dotl;
 extern const struct inode_operations v9fs_symlink_inode_operations_dotl;
 extern const struct netfs_request_ops v9fs_req_ops;
-extern struct inode *v9fs_fid_iget_dotl(struct super_block *sb,
-                                               struct p9_fid *fid, bool new);
+extern struct inode *v9fs_inode_from_fid_dotl(struct v9fs_session_info *v9ses,
+                                             struct p9_fid *fid,
+                                             struct super_block *sb, int new);
 
 /* other default globals */
 #define V9FS_PORT      564
@@ -225,12 +227,30 @@ static inline int v9fs_proto_dotl(struct v9fs_session_info *v9ses)
  */
 static inline struct inode *
 v9fs_get_inode_from_fid(struct v9fs_session_info *v9ses, struct p9_fid *fid,
-                       struct super_block *sb, bool new)
+                       struct super_block *sb)
 {
        if (v9fs_proto_dotl(v9ses))
-               return v9fs_fid_iget_dotl(sb, fid, new);
+               return v9fs_inode_from_fid_dotl(v9ses, fid, sb, 0);
        else
-               return v9fs_fid_iget(sb, fid, new);
+               return v9fs_inode_from_fid(v9ses, fid, sb, 0);
+}
+
+/**
+ * v9fs_get_new_inode_from_fid - Helper routine to populate an inode by
+ * issuing a attribute request
+ * @v9ses: session information
+ * @fid: fid to issue attribute request for
+ * @sb: superblock on which to create inode
+ *
+ */
+static inline struct inode *
+v9fs_get_new_inode_from_fid(struct v9fs_session_info *v9ses, struct p9_fid *fid,
+                           struct super_block *sb)
+{
+       if (v9fs_proto_dotl(v9ses))
+               return v9fs_inode_from_fid_dotl(v9ses, fid, sb, 1);
+       else
+               return v9fs_inode_from_fid(v9ses, fid, sb, 1);
 }
 
 #endif
index 7923c3c347cbd54475d45f255a67dc5fc30df162..d3aefbec4de6e3e72046df01daa849fed9e183d3 100644 (file)
@@ -42,7 +42,7 @@ struct inode *v9fs_alloc_inode(struct super_block *sb);
 void v9fs_free_inode(struct inode *inode);
 void v9fs_set_netfs_context(struct inode *inode);
 int v9fs_init_inode(struct v9fs_session_info *v9ses,
-                   struct inode *inode, struct p9_qid *qid, umode_t mode, dev_t rdev);
+                   struct inode *inode, umode_t mode, dev_t rdev);
 void v9fs_evict_inode(struct inode *inode);
 #if (BITS_PER_LONG == 32)
 #define QID2INO(q) ((ino_t) (((q)->path+2) ^ (((q)->path) >> 32)))
index fd72fc38c8f5b1ff971414388f6fab16ce53ac4c..3e68521f4e2f9842019cdea2755d8a657a8ebb21 100644 (file)
@@ -256,12 +256,9 @@ void v9fs_set_netfs_context(struct inode *inode)
 }
 
 int v9fs_init_inode(struct v9fs_session_info *v9ses,
-                   struct inode *inode, struct p9_qid *qid, umode_t mode, dev_t rdev)
+                   struct inode *inode, umode_t mode, dev_t rdev)
 {
        int err = 0;
-       struct v9fs_inode *v9inode = V9FS_I(inode);
-
-       memcpy(&v9inode->qid, qid, sizeof(struct p9_qid));
 
        inode_init_owner(&nop_mnt_idmap, inode, NULL, mode);
        inode->i_blocks = 0;
@@ -365,59 +362,105 @@ void v9fs_evict_inode(struct inode *inode)
                clear_inode(inode);
 }
 
-struct inode *
-v9fs_fid_iget(struct super_block *sb, struct p9_fid *fid, bool new)
+static int v9fs_test_inode(struct inode *inode, void *data)
+{
+       int umode;
+       dev_t rdev;
+       struct v9fs_inode *v9inode = V9FS_I(inode);
+       struct p9_wstat *st = (struct p9_wstat *)data;
+       struct v9fs_session_info *v9ses = v9fs_inode2v9ses(inode);
+
+       umode = p9mode2unixmode(v9ses, st, &rdev);
+       /* don't match inode of different type */
+       if (inode_wrong_type(inode, umode))
+               return 0;
+
+       /* compare qid details */
+       if (memcmp(&v9inode->qid.version,
+                  &st->qid.version, sizeof(v9inode->qid.version)))
+               return 0;
+
+       if (v9inode->qid.type != st->qid.type)
+               return 0;
+
+       if (v9inode->qid.path != st->qid.path)
+               return 0;
+       return 1;
+}
+
+static int v9fs_test_new_inode(struct inode *inode, void *data)
+{
+       return 0;
+}
+
+static int v9fs_set_inode(struct inode *inode,  void *data)
+{
+       struct v9fs_inode *v9inode = V9FS_I(inode);
+       struct p9_wstat *st = (struct p9_wstat *)data;
+
+       memcpy(&v9inode->qid, &st->qid, sizeof(st->qid));
+       return 0;
+}
+
+static struct inode *v9fs_qid_iget(struct super_block *sb,
+                                  struct p9_qid *qid,
+                                  struct p9_wstat *st,
+                                  int new)
 {
        dev_t rdev;
        int retval;
        umode_t umode;
        struct inode *inode;
-       struct p9_wstat *st;
        struct v9fs_session_info *v9ses = sb->s_fs_info;
+       int (*test)(struct inode *inode, void *data);
 
-       inode = iget_locked(sb, QID2INO(&fid->qid));
-       if (unlikely(!inode))
-               return ERR_PTR(-ENOMEM);
-       if (!(inode->i_state & I_NEW)) {
-               if (!new) {
-                       goto done;
-               } else {
-                       p9_debug(P9_DEBUG_VFS, "WARNING: Inode collision %ld\n",
-                                               inode->i_ino);
-                       iput(inode);
-                       remove_inode_hash(inode);
-                       inode = iget_locked(sb, QID2INO(&fid->qid));
-                       WARN_ON(!(inode->i_state & I_NEW));
-               }
-       }
+       if (new)
+               test = v9fs_test_new_inode;
+       else
+               test = v9fs_test_inode;
 
+       inode = iget5_locked(sb, QID2INO(qid), test, v9fs_set_inode, st);
+       if (!inode)
+               return ERR_PTR(-ENOMEM);
+       if (!(inode->i_state & I_NEW))
+               return inode;
        /*
         * initialize the inode with the stat info
         * FIXME!! we may need support for stale inodes
         * later.
         */
-       st = p9_client_stat(fid);
-       if (IS_ERR(st)) {
-               retval = PTR_ERR(st);
-               goto error;
-       }
-
+       inode->i_ino = QID2INO(qid);
        umode = p9mode2unixmode(v9ses, st, &rdev);
-       retval = v9fs_init_inode(v9ses, inode, &fid->qid, umode, rdev);
-       v9fs_stat2inode(st, inode, sb, 0);
-       p9stat_free(st);
-       kfree(st);
+       retval = v9fs_init_inode(v9ses, inode, umode, rdev);
        if (retval)
                goto error;
 
+       v9fs_stat2inode(st, inode, sb, 0);
        v9fs_set_netfs_context(inode);
        v9fs_cache_inode_get_cookie(inode);
        unlock_new_inode(inode);
-done:
        return inode;
 error:
        iget_failed(inode);
        return ERR_PTR(retval);
+
+}
+
+struct inode *
+v9fs_inode_from_fid(struct v9fs_session_info *v9ses, struct p9_fid *fid,
+                   struct super_block *sb, int new)
+{
+       struct p9_wstat *st;
+       struct inode *inode = NULL;
+
+       st = p9_client_stat(fid);
+       if (IS_ERR(st))
+               return ERR_CAST(st);
+
+       inode = v9fs_qid_iget(sb, &st->qid, st, new);
+       p9stat_free(st);
+       kfree(st);
+       return inode;
 }
 
 /**
@@ -449,15 +492,8 @@ static int v9fs_at_to_dotl_flags(int flags)
  */
 static void v9fs_dec_count(struct inode *inode)
 {
-       if (!S_ISDIR(inode->i_mode) || inode->i_nlink > 2) {
-               if (inode->i_nlink) {
-                       drop_nlink(inode);
-               } else {
-                       p9_debug(P9_DEBUG_VFS,
-                                               "WARNING: unexpected i_nlink zero %d inode %ld\n",
-                                               inode->i_nlink, inode->i_ino);
-               }
-       }
+       if (!S_ISDIR(inode->i_mode) || inode->i_nlink > 2)
+               drop_nlink(inode);
 }
 
 /**
@@ -508,9 +544,6 @@ static int v9fs_remove(struct inode *dir, struct dentry *dentry, int flags)
                } else
                        v9fs_dec_count(inode);
 
-               if (inode->i_nlink <= 0)        /* no more refs unhash it */
-                       remove_inode_hash(inode);
-
                v9fs_invalidate_inode_attr(inode);
                v9fs_invalidate_inode_attr(dir);
 
@@ -576,7 +609,7 @@ v9fs_create(struct v9fs_session_info *v9ses, struct inode *dir,
                /*
                 * instantiate inode and assign the unopened fid to the dentry
                 */
-               inode = v9fs_get_inode_from_fid(v9ses, fid, dir->i_sb, true);
+               inode = v9fs_get_new_inode_from_fid(v9ses, fid, dir->i_sb);
                if (IS_ERR(inode)) {
                        err = PTR_ERR(inode);
                        p9_debug(P9_DEBUG_VFS,
@@ -704,8 +737,10 @@ struct dentry *v9fs_vfs_lookup(struct inode *dir, struct dentry *dentry,
                inode = NULL;
        else if (IS_ERR(fid))
                inode = ERR_CAST(fid);
+       else if (v9ses->cache & (CACHE_META|CACHE_LOOSE))
+               inode = v9fs_get_inode_from_fid(v9ses, fid, dir->i_sb);
        else
-               inode = v9fs_get_inode_from_fid(v9ses, fid, dir->i_sb, false);
+               inode = v9fs_get_new_inode_from_fid(v9ses, fid, dir->i_sb);
        /*
         * If we had a rename on the server and a parallel lookup
         * for the new name, then make sure we instantiate with
index c61b97bd13b9a7875b14f9af6e109b85143c79da..143ac03b7425c0e589bc097dac8b070792ef8679 100644 (file)
@@ -52,50 +52,80 @@ static kgid_t v9fs_get_fsgid_for_create(struct inode *dir_inode)
        return current_fsgid();
 }
 
+static int v9fs_test_inode_dotl(struct inode *inode, void *data)
+{
+       struct v9fs_inode *v9inode = V9FS_I(inode);
+       struct p9_stat_dotl *st = (struct p9_stat_dotl *)data;
 
+       /* don't match inode of different type */
+       if (inode_wrong_type(inode, st->st_mode))
+               return 0;
 
-struct inode *
-v9fs_fid_iget_dotl(struct super_block *sb, struct p9_fid *fid, bool new)
+       if (inode->i_generation != st->st_gen)
+               return 0;
+
+       /* compare qid details */
+       if (memcmp(&v9inode->qid.version,
+                  &st->qid.version, sizeof(v9inode->qid.version)))
+               return 0;
+
+       if (v9inode->qid.type != st->qid.type)
+               return 0;
+
+       if (v9inode->qid.path != st->qid.path)
+               return 0;
+       return 1;
+}
+
+/* Always get a new inode */
+static int v9fs_test_new_inode_dotl(struct inode *inode, void *data)
+{
+       return 0;
+}
+
+static int v9fs_set_inode_dotl(struct inode *inode,  void *data)
+{
+       struct v9fs_inode *v9inode = V9FS_I(inode);
+       struct p9_stat_dotl *st = (struct p9_stat_dotl *)data;
+
+       memcpy(&v9inode->qid, &st->qid, sizeof(st->qid));
+       inode->i_generation = st->st_gen;
+       return 0;
+}
+
+static struct inode *v9fs_qid_iget_dotl(struct super_block *sb,
+                                       struct p9_qid *qid,
+                                       struct p9_fid *fid,
+                                       struct p9_stat_dotl *st,
+                                       int new)
 {
        int retval;
        struct inode *inode;
-       struct p9_stat_dotl *st;
        struct v9fs_session_info *v9ses = sb->s_fs_info;
+       int (*test)(struct inode *inode, void *data);
 
-       inode = iget_locked(sb, QID2INO(&fid->qid));
-       if (unlikely(!inode))
-               return ERR_PTR(-ENOMEM);
-       if (!(inode->i_state & I_NEW)) {
-               if (!new) {
-                       goto done;
-               } else { /* deal with race condition in inode number reuse */
-                       p9_debug(P9_DEBUG_ERROR, "WARNING: Inode collision %lx\n",
-                                               inode->i_ino);
-                       iput(inode);
-                       remove_inode_hash(inode);
-                       inode = iget_locked(sb, QID2INO(&fid->qid));
-                       WARN_ON(!(inode->i_state & I_NEW));
-               }
-       }
+       if (new)
+               test = v9fs_test_new_inode_dotl;
+       else
+               test = v9fs_test_inode_dotl;
 
+       inode = iget5_locked(sb, QID2INO(qid), test, v9fs_set_inode_dotl, st);
+       if (!inode)
+               return ERR_PTR(-ENOMEM);
+       if (!(inode->i_state & I_NEW))
+               return inode;
        /*
         * initialize the inode with the stat info
         * FIXME!! we may need support for stale inodes
         * later.
         */
-       st = p9_client_getattr_dotl(fid, P9_STATS_BASIC | P9_STATS_GEN);
-       if (IS_ERR(st)) {
-               retval = PTR_ERR(st);
-               goto error;
-       }
-
-       retval = v9fs_init_inode(v9ses, inode, &fid->qid,
+       inode->i_ino = QID2INO(qid);
+       retval = v9fs_init_inode(v9ses, inode,
                                 st->st_mode, new_decode_dev(st->st_rdev));
-       v9fs_stat2inode_dotl(st, inode, 0);
-       kfree(st);
        if (retval)
                goto error;
 
+       v9fs_stat2inode_dotl(st, inode, 0);
        v9fs_set_netfs_context(inode);
        v9fs_cache_inode_get_cookie(inode);
        retval = v9fs_get_acl(inode, fid);
@@ -103,11 +133,27 @@ v9fs_fid_iget_dotl(struct super_block *sb, struct p9_fid *fid, bool new)
                goto error;
 
        unlock_new_inode(inode);
-done:
        return inode;
 error:
        iget_failed(inode);
        return ERR_PTR(retval);
+
+}
+
+struct inode *
+v9fs_inode_from_fid_dotl(struct v9fs_session_info *v9ses, struct p9_fid *fid,
+                        struct super_block *sb, int new)
+{
+       struct p9_stat_dotl *st;
+       struct inode *inode = NULL;
+
+       st = p9_client_getattr_dotl(fid, P9_STATS_BASIC | P9_STATS_GEN);
+       if (IS_ERR(st))
+               return ERR_CAST(st);
+
+       inode = v9fs_qid_iget_dotl(sb, &st->qid, fid, st, new);
+       kfree(st);
+       return inode;
 }
 
 struct dotl_openflag_map {
@@ -259,7 +305,7 @@ v9fs_vfs_atomic_open_dotl(struct inode *dir, struct dentry *dentry,
                p9_debug(P9_DEBUG_VFS, "p9_client_walk failed %d\n", err);
                goto out;
        }
-       inode = v9fs_fid_iget_dotl(dir->i_sb, fid, true);
+       inode = v9fs_get_new_inode_from_fid(v9ses, fid, dir->i_sb);
        if (IS_ERR(inode)) {
                err = PTR_ERR(inode);
                p9_debug(P9_DEBUG_VFS, "inode creation failed %d\n", err);
@@ -309,6 +355,7 @@ static int v9fs_vfs_mkdir_dotl(struct mnt_idmap *idmap,
                               umode_t omode)
 {
        int err;
+       struct v9fs_session_info *v9ses;
        struct p9_fid *fid = NULL, *dfid = NULL;
        kgid_t gid;
        const unsigned char *name;
@@ -318,6 +365,7 @@ static int v9fs_vfs_mkdir_dotl(struct mnt_idmap *idmap,
        struct posix_acl *dacl = NULL, *pacl = NULL;
 
        p9_debug(P9_DEBUG_VFS, "name %pd\n", dentry);
+       v9ses = v9fs_inode2v9ses(dir);
 
        omode |= S_IFDIR;
        if (dir->i_mode & S_ISGID)
@@ -352,7 +400,7 @@ static int v9fs_vfs_mkdir_dotl(struct mnt_idmap *idmap,
        }
 
        /* instantiate inode and assign the unopened fid to the dentry */
-       inode = v9fs_fid_iget_dotl(dir->i_sb, fid, true);
+       inode = v9fs_get_new_inode_from_fid(v9ses, fid, dir->i_sb);
        if (IS_ERR(inode)) {
                err = PTR_ERR(inode);
                p9_debug(P9_DEBUG_VFS, "inode creation failed %d\n",
@@ -749,6 +797,7 @@ v9fs_vfs_mknod_dotl(struct mnt_idmap *idmap, struct inode *dir,
        kgid_t gid;
        const unsigned char *name;
        umode_t mode;
+       struct v9fs_session_info *v9ses;
        struct p9_fid *fid = NULL, *dfid = NULL;
        struct inode *inode;
        struct p9_qid qid;
@@ -758,6 +807,7 @@ v9fs_vfs_mknod_dotl(struct mnt_idmap *idmap, struct inode *dir,
                 dir->i_ino, dentry, omode,
                 MAJOR(rdev), MINOR(rdev));
 
+       v9ses = v9fs_inode2v9ses(dir);
        dfid = v9fs_parent_fid(dentry);
        if (IS_ERR(dfid)) {
                err = PTR_ERR(dfid);
@@ -788,7 +838,7 @@ v9fs_vfs_mknod_dotl(struct mnt_idmap *idmap, struct inode *dir,
                         err);
                goto error;
        }
-       inode = v9fs_fid_iget_dotl(dir->i_sb, fid, true);
+       inode = v9fs_get_new_inode_from_fid(v9ses, fid, dir->i_sb);
        if (IS_ERR(inode)) {
                err = PTR_ERR(inode);
                p9_debug(P9_DEBUG_VFS, "inode creation failed %d\n",
index f52fdf42945cf15d21fe55f01da21967714ed07c..489db161abc9831b23148396bdf49ebf34525542 100644 (file)
@@ -139,7 +139,7 @@ static struct dentry *v9fs_mount(struct file_system_type *fs_type, int flags,
        else
                sb->s_d_op = &v9fs_dentry_operations;
 
-       inode = v9fs_get_inode_from_fid(v9ses, fid, sb, true);
+       inode = v9fs_get_new_inode_from_fid(v9ses, fid, sb);
        if (IS_ERR(inode)) {
                retval = PTR_ERR(inode);
                goto release_sb;
index 949895cff872847e718e15156cc90b6548d8f4ba..aae170fc2795246a09c4f95ed2acf9fb6d5c4a82 100644 (file)
@@ -388,7 +388,7 @@ config NFS_COMMON
 
 config NFS_COMMON_LOCALIO_SUPPORT
        tristate
-       default n
+       depends on NFS_LOCALIO
        default y if NFSD=y || NFS_FS=y
        default m if NFSD=m && NFS_FS=m
        select SUNRPC
index a81de80c45c1b09c85aa12a79c85f9e3e44d1e10..a0ce272b40986517d52aa8dc836d645f50fce911 100644 (file)
@@ -6,7 +6,7 @@
  */
 #include <linux/slab.h>
 #include <linux/statfs.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include "adfs.h"
 
 /*
index 9c65ffb8a523bd90debe526c7eda4872a0336d98..a06296c8827d42e9ce78f04c49365a220c584c86 100644 (file)
@@ -134,13 +134,4 @@ struct afs_uvldbentry__xdr {
        __be32                  spares9;
 };
 
-struct afs_address_list {
-       refcount_t              usage;
-       unsigned int            version;
-       unsigned int            nr_addrs;
-       struct sockaddr_rxrpc   addrs[];
-};
-
-extern void afs_put_address_list(struct afs_address_list *alist);
-
 #endif /* AFS_VL_H */
index f8622ed72e08126aebfb9ede3943ba54469b2d78..ada363af5aab8e8e1fc806327dfecae1d4ca14cb 100644 (file)
@@ -12,6 +12,7 @@
 #include <linux/swap.h>
 #include <linux/ctype.h>
 #include <linux/sched.h>
+#include <linux/iversion.h>
 #include <linux/task_io_accounting_ops.h>
 #include "internal.h"
 #include "afs_fs.h"
@@ -1823,6 +1824,8 @@ error:
 
 static void afs_rename_success(struct afs_operation *op)
 {
+       struct afs_vnode *vnode = AFS_FS_I(d_inode(op->dentry));
+
        _enter("op=%08x", op->debug_id);
 
        op->ctime = op->file[0].scb.status.mtime_client;
@@ -1832,6 +1835,22 @@ static void afs_rename_success(struct afs_operation *op)
                op->ctime = op->file[1].scb.status.mtime_client;
                afs_vnode_commit_status(op, &op->file[1]);
        }
+
+       /* If we're moving a subdir between dirs, we need to update
+        * its DV counter too as the ".." will be altered.
+        */
+       if (S_ISDIR(vnode->netfs.inode.i_mode) &&
+           op->file[0].vnode != op->file[1].vnode) {
+               u64 new_dv;
+
+               write_seqlock(&vnode->cb_lock);
+
+               new_dv = vnode->status.data_version + 1;
+               vnode->status.data_version = new_dv;
+               inode_set_iversion_raw(&vnode->netfs.inode, new_dv);
+
+               write_sequnlock(&vnode->cb_lock);
+       }
 }
 
 static void afs_rename_edit_dir(struct afs_operation *op)
@@ -1873,6 +1892,12 @@ static void afs_rename_edit_dir(struct afs_operation *op)
                                 &vnode->fid, afs_edit_dir_for_rename_2);
        }
 
+       if (S_ISDIR(vnode->netfs.inode.i_mode) &&
+           new_dvnode != orig_dvnode &&
+           test_bit(AFS_VNODE_DIR_VALID, &vnode->flags))
+               afs_edit_dir_update_dotdot(vnode, new_dvnode,
+                                          afs_edit_dir_for_rename_sub);
+
        new_inode = d_inode(new_dentry);
        if (new_inode) {
                spin_lock(&new_inode->i_lock);
index a71bff10496b2b9c5282086aec950fe85d79491a..fe223fb781111a4ee5fab5c95c5d0ffc61600123 100644 (file)
@@ -127,10 +127,10 @@ static struct folio *afs_dir_get_folio(struct afs_vnode *vnode, pgoff_t index)
 /*
  * Scan a directory block looking for a dirent of the right name.
  */
-static int afs_dir_scan_block(union afs_xdr_dir_block *block, struct qstr *name,
+static int afs_dir_scan_block(const union afs_xdr_dir_block *block, const struct qstr *name,
                              unsigned int blocknum)
 {
-       union afs_xdr_dirent *de;
+       const union afs_xdr_dirent *de;
        u64 bitmap;
        int d, len, n;
 
@@ -492,3 +492,90 @@ error:
        clear_bit(AFS_VNODE_DIR_VALID, &vnode->flags);
        goto out_unmap;
 }
+
+/*
+ * Edit a subdirectory that has been moved between directories to update the
+ * ".." entry.
+ */
+void afs_edit_dir_update_dotdot(struct afs_vnode *vnode, struct afs_vnode *new_dvnode,
+                               enum afs_edit_dir_reason why)
+{
+       union afs_xdr_dir_block *block;
+       union afs_xdr_dirent *de;
+       struct folio *folio;
+       unsigned int nr_blocks, b;
+       pgoff_t index;
+       loff_t i_size;
+       int slot;
+
+       _enter("");
+
+       i_size = i_size_read(&vnode->netfs.inode);
+       if (i_size < AFS_DIR_BLOCK_SIZE) {
+               clear_bit(AFS_VNODE_DIR_VALID, &vnode->flags);
+               return;
+       }
+       nr_blocks = i_size / AFS_DIR_BLOCK_SIZE;
+
+       /* Find a block that has sufficient slots available.  Each folio
+        * contains two or more directory blocks.
+        */
+       for (b = 0; b < nr_blocks; b++) {
+               index = b / AFS_DIR_BLOCKS_PER_PAGE;
+               folio = afs_dir_get_folio(vnode, index);
+               if (!folio)
+                       goto error;
+
+               block = kmap_local_folio(folio, b * AFS_DIR_BLOCK_SIZE - folio_pos(folio));
+
+               /* Abandon the edit if we got a callback break. */
+               if (!test_bit(AFS_VNODE_DIR_VALID, &vnode->flags))
+                       goto invalidated;
+
+               slot = afs_dir_scan_block(block, &dotdot_name, b);
+               if (slot >= 0)
+                       goto found_dirent;
+
+               kunmap_local(block);
+               folio_unlock(folio);
+               folio_put(folio);
+       }
+
+       /* Didn't find the dirent to clobber.  Download the directory again. */
+       trace_afs_edit_dir(vnode, why, afs_edit_dir_update_nodd,
+                          0, 0, 0, 0, "..");
+       clear_bit(AFS_VNODE_DIR_VALID, &vnode->flags);
+       goto out;
+
+found_dirent:
+       de = &block->dirents[slot];
+       de->u.vnode  = htonl(new_dvnode->fid.vnode);
+       de->u.unique = htonl(new_dvnode->fid.unique);
+
+       trace_afs_edit_dir(vnode, why, afs_edit_dir_update_dd, b, slot,
+                          ntohl(de->u.vnode), ntohl(de->u.unique), "..");
+
+       kunmap_local(block);
+       folio_unlock(folio);
+       folio_put(folio);
+       inode_set_iversion_raw(&vnode->netfs.inode, vnode->status.data_version);
+
+out:
+       _leave("");
+       return;
+
+invalidated:
+       kunmap_local(block);
+       folio_unlock(folio);
+       folio_put(folio);
+       trace_afs_edit_dir(vnode, why, afs_edit_dir_update_inval,
+                          0, 0, 0, 0, "..");
+       clear_bit(AFS_VNODE_DIR_VALID, &vnode->flags);
+       goto out;
+
+error:
+       trace_afs_edit_dir(vnode, why, afs_edit_dir_update_error,
+                          0, 0, 0, 0, "..");
+       clear_bit(AFS_VNODE_DIR_VALID, &vnode->flags);
+       goto out;
+}
index 492d857a3fa0728fa1fd8628c96465939b42d3ff..6762eff9751722c3950f1a90df1de515887b0fb4 100644 (file)
@@ -420,6 +420,7 @@ const struct netfs_request_ops afs_req_ops = {
        .begin_writeback        = afs_begin_writeback,
        .prepare_write          = afs_prepare_write,
        .issue_write            = afs_issue_write,
+       .retry_request          = afs_retry_request,
 };
 
 static void afs_add_open_mmap(struct afs_vnode *vnode)
index 3546b087e791d49555fb6566246a1bacba781d70..428721bbe4f6e377726ba75e2478732a1487205d 100644 (file)
@@ -201,7 +201,7 @@ void afs_wait_for_operation(struct afs_operation *op)
                }
        }
 
-       if (op->call_responded)
+       if (op->call_responded && op->server)
                set_bit(AFS_SERVER_FL_RESPONDING, &op->server->flags);
 
        if (!afs_op_error(op)) {
index 580de4adaaf652bf09d53854dba3a5ebd9a39e48..b516d05b0fefc5dcf84cc11c6ebeed795f061e89 100644 (file)
@@ -506,10 +506,10 @@ int afs_wait_for_one_fs_probe(struct afs_server *server, struct afs_endpoint_sta
        finish_wait(&server->probe_wq, &wait);
 
 dont_wait:
-       if (estate->responsive_set & ~exclude)
-               return 1;
        if (test_bit(AFS_ESTATE_SUPERSEDED, &estate->flags))
                return 0;
+       if (estate->responsive_set & ~exclude)
+               return 1;
        if (is_intr && signal_pending(current))
                return -ERESTARTSYS;
        if (timo == 0)
index 6e1d3c4daf72c6578b173b32364a1e136c7b6fec..c9d620175e80caea177fc51ddb9c09c5964e7807 100644 (file)
@@ -130,6 +130,7 @@ struct afs_call {
        wait_queue_head_t       waitq;          /* processes awaiting completion */
        struct work_struct      async_work;     /* async I/O processor */
        struct work_struct      work;           /* actual work processor */
+       struct work_struct      free_work;      /* Deferred free processor */
        struct rxrpc_call       *rxcall;        /* RxRPC call handle */
        struct rxrpc_peer       *peer;          /* Remote endpoint */
        struct key              *key;           /* security for this call */
@@ -1072,6 +1073,8 @@ extern void afs_check_for_remote_deletion(struct afs_operation *);
 extern void afs_edit_dir_add(struct afs_vnode *, struct qstr *, struct afs_fid *,
                             enum afs_edit_dir_reason);
 extern void afs_edit_dir_remove(struct afs_vnode *, struct qstr *, enum afs_edit_dir_reason);
+void afs_edit_dir_update_dotdot(struct afs_vnode *vnode, struct afs_vnode *new_dvnode,
+                               enum afs_edit_dir_reason why);
 
 /*
  * dir_silly.c
@@ -1331,6 +1334,7 @@ extern int __net_init afs_open_socket(struct afs_net *);
 extern void __net_exit afs_close_socket(struct afs_net *);
 extern void afs_charge_preallocation(struct work_struct *);
 extern void afs_put_call(struct afs_call *);
+void afs_deferred_put_call(struct afs_call *call);
 void afs_make_call(struct afs_call *call, gfp_t gfp);
 void afs_wait_for_call_to_complete(struct afs_call *call);
 extern struct afs_call *afs_alloc_flat_call(struct afs_net *,
index ed09d4d4c2112189bfa724d577769e5ae8f15bdd..d612983d6f38e6390c9f3379b53349ce5db8d229 100644 (file)
@@ -632,8 +632,10 @@ iterate_address:
 wait_for_more_probe_results:
        error = afs_wait_for_one_fs_probe(op->server, op->estate, op->addr_tried,
                                          !(op->flags & AFS_OPERATION_UNINTR));
-       if (!error)
+       if (error == 1)
                goto iterate_address;
+       if (!error)
+               goto restart_from_beginning;
 
        /* We've now had a failure to respond on all of a server's addresses -
         * immediately probe them again and consider retrying the server.
@@ -644,10 +646,13 @@ wait_for_more_probe_results:
                error = afs_wait_for_one_fs_probe(op->server, op->estate, op->addr_tried,
                                                  !(op->flags & AFS_OPERATION_UNINTR));
                switch (error) {
-               case 0:
+               case 1:
                        op->flags &= ~AFS_OPERATION_RETRY_SERVER;
-                       trace_afs_rotate(op, afs_rotate_trace_retry_server, 0);
+                       trace_afs_rotate(op, afs_rotate_trace_retry_server, 1);
                        goto retry_server;
+               case 0:
+                       trace_afs_rotate(op, afs_rotate_trace_retry_server, 0);
+                       goto restart_from_beginning;
                case -ERESTARTSYS:
                        afs_op_set_error(op, error);
                        goto failed;
index c453428f3c8ba9706fbc39943a02cf370117d2c2..9f2a3bb56ec69e49a1ce4c7a60fe898b322c5e43 100644 (file)
@@ -18,6 +18,7 @@
 
 struct workqueue_struct *afs_async_calls;
 
+static void afs_deferred_free_worker(struct work_struct *work);
 static void afs_wake_up_call_waiter(struct sock *, struct rxrpc_call *, unsigned long);
 static void afs_wake_up_async_call(struct sock *, struct rxrpc_call *, unsigned long);
 static void afs_process_async_call(struct work_struct *);
@@ -149,6 +150,7 @@ static struct afs_call *afs_alloc_call(struct afs_net *net,
        call->debug_id = atomic_inc_return(&rxrpc_debug_id);
        refcount_set(&call->ref, 1);
        INIT_WORK(&call->async_work, afs_process_async_call);
+       INIT_WORK(&call->free_work, afs_deferred_free_worker);
        init_waitqueue_head(&call->waitq);
        spin_lock_init(&call->state_lock);
        call->iter = &call->def_iter;
@@ -159,6 +161,36 @@ static struct afs_call *afs_alloc_call(struct afs_net *net,
        return call;
 }
 
+static void afs_free_call(struct afs_call *call)
+{
+       struct afs_net *net = call->net;
+       int o;
+
+       ASSERT(!work_pending(&call->async_work));
+
+       rxrpc_kernel_put_peer(call->peer);
+
+       if (call->rxcall) {
+               rxrpc_kernel_shutdown_call(net->socket, call->rxcall);
+               rxrpc_kernel_put_call(net->socket, call->rxcall);
+               call->rxcall = NULL;
+       }
+       if (call->type->destructor)
+               call->type->destructor(call);
+
+       afs_unuse_server_notime(call->net, call->server, afs_server_trace_put_call);
+       kfree(call->request);
+
+       o = atomic_read(&net->nr_outstanding_calls);
+       trace_afs_call(call->debug_id, afs_call_trace_free, 0, o,
+                      __builtin_return_address(0));
+       kfree(call);
+
+       o = atomic_dec_return(&net->nr_outstanding_calls);
+       if (o == 0)
+               wake_up_var(&net->nr_outstanding_calls);
+}
+
 /*
  * Dispose of a reference on a call.
  */
@@ -173,32 +205,34 @@ void afs_put_call(struct afs_call *call)
        o = atomic_read(&net->nr_outstanding_calls);
        trace_afs_call(debug_id, afs_call_trace_put, r - 1, o,
                       __builtin_return_address(0));
+       if (zero)
+               afs_free_call(call);
+}
 
-       if (zero) {
-               ASSERT(!work_pending(&call->async_work));
-               ASSERT(call->type->name != NULL);
-
-               rxrpc_kernel_put_peer(call->peer);
-
-               if (call->rxcall) {
-                       rxrpc_kernel_shutdown_call(net->socket, call->rxcall);
-                       rxrpc_kernel_put_call(net->socket, call->rxcall);
-                       call->rxcall = NULL;
-               }
-               if (call->type->destructor)
-                       call->type->destructor(call);
+static void afs_deferred_free_worker(struct work_struct *work)
+{
+       struct afs_call *call = container_of(work, struct afs_call, free_work);
 
-               afs_unuse_server_notime(call->net, call->server, afs_server_trace_put_call);
-               kfree(call->request);
+       afs_free_call(call);
+}
 
-               trace_afs_call(call->debug_id, afs_call_trace_free, 0, o,
-                              __builtin_return_address(0));
-               kfree(call);
+/*
+ * Dispose of a reference on a call, deferring the cleanup to a workqueue
+ * to avoid lock recursion.
+ */
+void afs_deferred_put_call(struct afs_call *call)
+{
+       struct afs_net *net = call->net;
+       unsigned int debug_id = call->debug_id;
+       bool zero;
+       int r, o;
 
-               o = atomic_dec_return(&net->nr_outstanding_calls);
-               if (o == 0)
-                       wake_up_var(&net->nr_outstanding_calls);
-       }
+       zero = __refcount_dec_and_test(&call->ref, &r);
+       o = atomic_read(&net->nr_outstanding_calls);
+       trace_afs_call(debug_id, afs_call_trace_put, r - 1, o,
+                      __builtin_return_address(0));
+       if (zero)
+               schedule_work(&call->free_work);
 }
 
 static struct afs_call *afs_get_call(struct afs_call *call,
@@ -640,7 +674,8 @@ static void afs_wake_up_call_waiter(struct sock *sk, struct rxrpc_call *rxcall,
 }
 
 /*
- * wake up an asynchronous call
+ * Wake up an asynchronous call.  The caller is holding the call notify
+ * spinlock around this, so we can't call afs_put_call().
  */
 static void afs_wake_up_async_call(struct sock *sk, struct rxrpc_call *rxcall,
                                   unsigned long call_user_ID)
@@ -657,7 +692,7 @@ static void afs_wake_up_async_call(struct sock *sk, struct rxrpc_call *rxcall,
                               __builtin_return_address(0));
 
                if (!queue_work(afs_async_calls, &call->async_work))
-                       afs_put_call(call);
+                       afs_deferred_put_call(call);
        }
 }
 
index f011e026358ebc51b9f85d4718b2f0ea7a6f3053..6d57efbb81102edcfe86070d699eb0ceb833d2b1 100644 (file)
@@ -110,6 +110,7 @@ static inline void free_dev_ioctl(struct autofs_dev_ioctl *param)
  */
 static int validate_dev_ioctl(int cmd, struct autofs_dev_ioctl *param)
 {
+       unsigned int inr = _IOC_NR(cmd);
        int err;
 
        err = check_dev_ioctl_version(cmd, param);
@@ -133,7 +134,7 @@ static int validate_dev_ioctl(int cmd, struct autofs_dev_ioctl *param)
                 * check_name() return for AUTOFS_DEV_IOCTL_TIMEOUT_CMD.
                 */
                err = check_name(param->path);
-               if (cmd == AUTOFS_DEV_IOCTL_TIMEOUT_CMD)
+               if (inr == AUTOFS_DEV_IOCTL_TIMEOUT_CMD)
                        err = err ? 0 : -EINVAL;
                if (err) {
                        pr_warn("invalid path supplied for cmd(0x%08x)\n",
@@ -141,8 +142,6 @@ static int validate_dev_ioctl(int cmd, struct autofs_dev_ioctl *param)
                        goto out;
                }
        } else {
-               unsigned int inr = _IOC_NR(cmd);
-
                if (inr == AUTOFS_DEV_IOCTL_OPENMOUNT_CMD ||
                    inr == AUTOFS_DEV_IOCTL_REQUESTER_CMD ||
                    inr == AUTOFS_DEV_IOCTL_ISMOUNTPOINT_CMD) {
index 8860dac58c37e147eebd27b58fa28c5fe4f2aa91..09a9be945d45e67fcb5ea70ed3a602fea7df69a8 100644 (file)
@@ -80,7 +80,7 @@ struct backing_aio {
        refcount_t ref;
        struct kiocb *orig_iocb;
        /* used for aio completion */
-       void (*end_write)(struct file *);
+       void (*end_write)(struct file *, loff_t, ssize_t);
        struct work_struct work;
        long res;
 };
@@ -109,7 +109,7 @@ static void backing_aio_cleanup(struct backing_aio *aio, long res)
        struct kiocb *orig_iocb = aio->orig_iocb;
 
        if (aio->end_write)
-               aio->end_write(orig_iocb->ki_filp);
+               aio->end_write(orig_iocb->ki_filp, iocb->ki_pos, res);
 
        orig_iocb->ki_pos = iocb->ki_pos;
        backing_aio_put(aio);
@@ -239,7 +239,7 @@ ssize_t backing_file_write_iter(struct file *file, struct iov_iter *iter,
 
                ret = vfs_iter_write(file, iter, &iocb->ki_pos, rwf);
                if (ctx->end_write)
-                       ctx->end_write(ctx->user_file);
+                       ctx->end_write(ctx->user_file, iocb->ki_pos, ret);
        } else {
                struct backing_aio *aio;
 
@@ -317,7 +317,7 @@ ssize_t backing_file_splice_write(struct pipe_inode_info *pipe,
        revert_creds(old_cred);
 
        if (ctx->end_write)
-               ctx->end_write(ctx->user_file);
+               ctx->end_write(ctx->user_file, ppos ? *ppos : 0, ret);
 
        return ret;
 }
index 645b5ed4babb187d25567c07412727d782a1660d..c84a91572a1da88b4c5a1aff96a1b6f16ee03a6e 100644 (file)
@@ -332,7 +332,6 @@ void bch2_alloc_v4_swab(struct bkey_s k)
        a->io_time[1]           = swab64(a->io_time[1]);
        a->stripe               = swab32(a->stripe);
        a->nr_external_backpointers = swab32(a->nr_external_backpointers);
-       a->fragmentation_lru    = swab64(a->fragmentation_lru);
        a->stripe_sectors       = swab32(a->stripe_sectors);
 
        bps = alloc_v4_backpointers(a);
@@ -347,6 +346,7 @@ void bch2_alloc_to_text(struct printbuf *out, struct bch_fs *c, struct bkey_s_c
 {
        struct bch_alloc_v4 _a;
        const struct bch_alloc_v4 *a = bch2_alloc_to_v4(k, &_a);
+       struct bch_dev *ca = c ? bch2_dev_bucket_tryget_noerror(c, k.k->p) : NULL;
 
        prt_newline(out);
        printbuf_indent_add(out, 2);
@@ -364,9 +364,13 @@ void bch2_alloc_to_text(struct printbuf *out, struct bch_fs *c, struct bkey_s_c
        prt_printf(out, "stripe_redundancy %u\n",       a->stripe_redundancy);
        prt_printf(out, "io_time[READ]     %llu\n",     a->io_time[READ]);
        prt_printf(out, "io_time[WRITE]    %llu\n",     a->io_time[WRITE]);
-       prt_printf(out, "fragmentation     %llu\n",     a->fragmentation_lru);
+
+       if (ca)
+               prt_printf(out, "fragmentation     %llu\n",     alloc_lru_idx_fragmentation(*a, ca));
        prt_printf(out, "bp_start          %llu\n", BCH_ALLOC_V4_BACKPOINTERS_START(a));
        printbuf_indent_sub(out, 2);
+
+       bch2_dev_put(ca);
 }
 
 void __bch2_alloc_to_v4(struct bkey_s_c k, struct bch_alloc_v4 *out)
@@ -635,6 +639,16 @@ int bch2_alloc_read(struct bch_fs *c)
                                continue;
                        }
 
+                       if (k.k->p.offset < ca->mi.first_bucket) {
+                               bch2_btree_iter_set_pos(&iter, POS(k.k->p.inode, ca->mi.first_bucket));
+                               continue;
+                       }
+
+                       if (k.k->p.offset >= ca->mi.nbuckets) {
+                               bch2_btree_iter_set_pos(&iter, POS(k.k->p.inode + 1, 0));
+                               continue;
+                       }
+
                        struct bch_alloc_v4 a;
                        *bucket_gen(ca, k.k->p.offset) = bch2_alloc_to_v4(k, &a)->gen;
                        0;
@@ -882,12 +896,13 @@ int bch2_trigger_alloc(struct btree_trans *trans,
                                goto err;
                }
 
-               new_a->fragmentation_lru = alloc_lru_idx_fragmentation(*new_a, ca);
-               if (old_a->fragmentation_lru != new_a->fragmentation_lru) {
+               old_lru = alloc_lru_idx_fragmentation(*old_a, ca);
+               new_lru = alloc_lru_idx_fragmentation(*new_a, ca);
+               if (old_lru != new_lru) {
                        ret = bch2_lru_change(trans,
                                        BCH_LRU_FRAGMENTATION_START,
                                        bucket_to_u64(new.k->p),
-                                       old_a->fragmentation_lru, new_a->fragmentation_lru);
+                                       old_lru, new_lru);
                        if (ret)
                                goto err;
                }
@@ -1629,18 +1644,22 @@ static int bch2_check_alloc_to_lru_ref(struct btree_trans *trans,
        if (ret)
                return ret;
 
+       struct bch_dev *ca = bch2_dev_tryget_noerror(c, alloc_k.k->p.inode);
+       if (!ca)
+               return 0;
+
        a = bch2_alloc_to_v4(alloc_k, &a_convert);
 
-       if (a->fragmentation_lru) {
+       u64 lru_idx = alloc_lru_idx_fragmentation(*a, ca);
+       if (lru_idx) {
                ret = bch2_lru_check_set(trans, BCH_LRU_FRAGMENTATION_START,
-                                        a->fragmentation_lru,
-                                        alloc_k, last_flushed);
+                                        lru_idx, alloc_k, last_flushed);
                if (ret)
-                       return ret;
+                       goto err;
        }
 
        if (a->data_type != BCH_DATA_cached)
-               return 0;
+               goto err;
 
        if (fsck_err_on(!a->io_time[READ],
                        trans, alloc_key_cached_but_read_time_zero,
@@ -1669,6 +1688,7 @@ static int bch2_check_alloc_to_lru_ref(struct btree_trans *trans,
                goto err;
 err:
 fsck_err:
+       bch2_dev_put(ca);
        printbuf_exit(&buf);
        return ret;
 }
@@ -1957,7 +1977,7 @@ static void bch2_do_discards_fast_work(struct work_struct *work)
                                             ca->mi.bucket_size,
                                             GFP_KERNEL);
 
-               int ret = bch2_trans_do(c, NULL, NULL,
+               int ret = bch2_trans_commit_do(c, NULL, NULL,
                        BCH_WATERMARK_btree|
                        BCH_TRANS_COMMIT_no_enospc,
                        bch2_clear_bucket_needs_discard(trans, POS(ca->dev_idx, bucket)));
@@ -2117,14 +2137,15 @@ static void bch2_do_invalidates_work(struct work_struct *work)
 
                struct bkey_s_c k = next_lru_key(trans, &iter, ca, &wrapped);
                ret = bkey_err(k);
-               if (bch2_err_matches(ret, BCH_ERR_transaction_restart))
-                       continue;
                if (ret)
-                       break;
+                       goto restart_err;
                if (!k.k)
                        break;
 
                ret = invalidate_one_bucket(trans, &iter, k, &nr_to_invalidate);
+restart_err:
+               if (bch2_err_matches(ret, BCH_ERR_transaction_restart))
+                       continue;
                if (ret)
                        break;
 
@@ -2330,24 +2351,19 @@ int bch2_dev_remove_alloc(struct bch_fs *c, struct bch_dev *ca)
 
 /* Bucket IO clocks: */
 
-int bch2_bucket_io_time_reset(struct btree_trans *trans, unsigned dev,
-                             size_t bucket_nr, int rw)
+static int __bch2_bucket_io_time_reset(struct btree_trans *trans, unsigned dev,
+                               size_t bucket_nr, int rw)
 {
        struct bch_fs *c = trans->c;
-       struct btree_iter iter;
-       struct bkey_i_alloc_v4 *a;
-       u64 now;
-       int ret = 0;
 
-       if (bch2_trans_relock(trans))
-               bch2_trans_begin(trans);
-
-       a = bch2_trans_start_alloc_update_noupdate(trans, &iter, POS(dev, bucket_nr));
-       ret = PTR_ERR_OR_ZERO(a);
+       struct btree_iter iter;
+       struct bkey_i_alloc_v4 *a =
+               bch2_trans_start_alloc_update_noupdate(trans, &iter, POS(dev, bucket_nr));
+       int ret = PTR_ERR_OR_ZERO(a);
        if (ret)
                return ret;
 
-       now = bch2_current_io_time(c, rw);
+       u64 now = bch2_current_io_time(c, rw);
        if (a->v.io_time[rw] == now)
                goto out;
 
@@ -2360,6 +2376,15 @@ out:
        return ret;
 }
 
+int bch2_bucket_io_time_reset(struct btree_trans *trans, unsigned dev,
+                             size_t bucket_nr, int rw)
+{
+       if (bch2_trans_relock(trans))
+               bch2_trans_begin(trans);
+
+       return nested_lockrestart_do(trans, __bch2_bucket_io_time_reset(trans, dev, bucket_nr, rw));
+}
+
 /* Startup/shutdown (ro/rw): */
 
 void bch2_recalc_capacity(struct bch_fs *c)
index f8e87c6721b1220864132b96d283336f5ae73416..163a67b97a4094e66c4cdf20beccd4eacab42b04 100644 (file)
@@ -168,6 +168,9 @@ static inline bool data_type_movable(enum bch_data_type type)
 static inline u64 alloc_lru_idx_fragmentation(struct bch_alloc_v4 a,
                                              struct bch_dev *ca)
 {
+       if (a.data_type >= BCH_DATA_NR)
+               return 0;
+
        if (!data_type_movable(a.data_type) ||
            !bch2_bucket_sectors_fragmented(ca, a))
                return 0;
index f754a2951d8aab538aa92a64b04b00f8ce4ec8a4..befdaa95c515b8315fd7d6d149ce51dcff844215 100644 (file)
@@ -70,7 +70,7 @@ struct bch_alloc_v4 {
        __u32                   stripe;
        __u32                   nr_external_backpointers;
        /* end of fields in original version of alloc_v4 */
-       __u64                   fragmentation_lru;
+       __u64                   _fragmentation_lru; /* obsolete */
        __u32                   stripe_sectors;
        __u32                   pad;
 } __packed __aligned(8);
index d0e0b56892e39f86fc00a1936cf3864d110e94eb..372178c8d4168f4a76566d7b6f8d0ea94bb394f7 100644 (file)
@@ -162,6 +162,10 @@ static void open_bucket_free_unused(struct bch_fs *c, struct open_bucket *ob)
               ARRAY_SIZE(c->open_buckets_partial));
 
        spin_lock(&c->freelist_lock);
+       rcu_read_lock();
+       bch2_dev_rcu(c, ob->dev)->nr_partial_buckets++;
+       rcu_read_unlock();
+
        ob->on_partial_list = true;
        c->open_buckets_partial[c->open_buckets_partial_nr++] =
                ob - c->open_buckets;
@@ -684,7 +688,7 @@ struct open_bucket *bch2_bucket_alloc(struct bch_fs *c, struct bch_dev *ca,
        struct bch_dev_usage usage;
        struct open_bucket *ob;
 
-       bch2_trans_do(c, NULL, NULL, 0,
+       bch2_trans_do(c,
                      PTR_ERR_OR_ZERO(ob = bch2_bucket_alloc_trans(trans, ca, watermark,
                                                        data_type, cl, false, &usage)));
        return ob;
@@ -972,7 +976,7 @@ static int bucket_alloc_set_partial(struct bch_fs *c,
                        u64 avail;
 
                        bch2_dev_usage_read_fast(ca, &usage);
-                       avail = dev_buckets_free(ca, usage, watermark);
+                       avail = dev_buckets_free(ca, usage, watermark) + ca->nr_partial_buckets;
                        if (!avail)
                                continue;
 
@@ -981,6 +985,10 @@ static int bucket_alloc_set_partial(struct bch_fs *c,
                                          i);
                        ob->on_partial_list = false;
 
+                       rcu_read_lock();
+                       bch2_dev_rcu(c, ob->dev)->nr_partial_buckets--;
+                       rcu_read_unlock();
+
                        ret = add_new_bucket(c, ptrs, devs_may_alloc,
                                             nr_replicas, nr_effective,
                                             have_cache, ob);
@@ -1191,7 +1199,13 @@ void bch2_open_buckets_stop(struct bch_fs *c, struct bch_dev *ca,
                        --c->open_buckets_partial_nr;
                        swap(c->open_buckets_partial[i],
                             c->open_buckets_partial[c->open_buckets_partial_nr]);
+
                        ob->on_partial_list = false;
+
+                       rcu_read_lock();
+                       bch2_dev_rcu(c, ob->dev)->nr_partial_buckets--;
+                       rcu_read_unlock();
+
                        spin_unlock(&c->freelist_lock);
                        bch2_open_bucket_put(c, ob);
                        spin_lock(&c->freelist_lock);
@@ -1610,8 +1624,7 @@ void bch2_open_buckets_to_text(struct printbuf *out, struct bch_fs *c,
             ob < c->open_buckets + ARRAY_SIZE(c->open_buckets);
             ob++) {
                spin_lock(&ob->lock);
-               if (ob->valid && !ob->on_partial_list &&
-                   (!ca || ob->dev == ca->dev_idx))
+               if (ob->valid && (!ca || ob->dev == ca->dev_idx))
                        bch2_open_bucket_to_text(out, c, ob);
                spin_unlock(&ob->lock);
        }
index f4151ee51b034201d3f8077c07c77857f3f4f3f3..e94a83b8113e93a4889812376ef0fac2790c2b62 100644 (file)
@@ -555,6 +555,7 @@ struct bch_dev {
        u64                     alloc_cursor[3];
 
        unsigned                nr_open_buckets;
+       unsigned                nr_partial_buckets;
        unsigned                nr_btree_reserve;
 
        size_t                  inc_gen_needs_gc;
index 203ee627cab5d5118b2bef3c17cf684dacebb66e..5004f6ba997c9956a647293f69a5ba0305e92f1f 100644 (file)
@@ -223,7 +223,7 @@ struct bkey {
 #elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
        struct bpos     p;
        __u32           size;           /* extent size, in sectors */
-       struct bversion version;
+       struct bversion bversion;
 
        __u8            pad[1];
 #endif
@@ -678,7 +678,8 @@ struct bch_sb_field_ext {
        x(disk_accounting_v2,           BCH_VERSION(1,  9))             \
        x(disk_accounting_v3,           BCH_VERSION(1, 10))             \
        x(disk_accounting_inum,         BCH_VERSION(1, 11))             \
-       x(rebalance_work_acct_fix,      BCH_VERSION(1, 12))
+       x(rebalance_work_acct_fix,      BCH_VERSION(1, 12))             \
+       x(inode_has_child_snapshots,    BCH_VERSION(1, 13))
 
 enum bcachefs_metadata_version {
        bcachefs_metadata_version_min = 9,
index d1f6092624d86354e611cc8943058399d656daa8..9a4a83d6fd2ddd9ca3510b1e0c37bb6445f3ef1a 100644 (file)
@@ -13,7 +13,7 @@
 #include "trace.h"
 #include "util.h"
 
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include <linux/console.h>
 #include <linux/random.h>
 #include <linux/prefetch.h>
index 660d2fa02da21c93987c3bd0720891ad3e76bfc0..0ca3feeb42c808e689fb5ad46b3f9e34da01bfac 100644 (file)
@@ -820,15 +820,23 @@ static int bch2_alloc_write_key(struct btree_trans *trans,
         * fix that here:
         */
        alloc_data_type_set(&gc, gc.data_type);
-
        if (gc.data_type != old_gc.data_type ||
            gc.dirty_sectors != old_gc.dirty_sectors) {
                ret = bch2_alloc_key_to_dev_counters(trans, ca, &old_gc, &gc, BTREE_TRIGGER_gc);
                if (ret)
                        return ret;
-       }
 
-       gc.fragmentation_lru = alloc_lru_idx_fragmentation(gc, ca);
+               /*
+                * Ugly: alloc_key_to_dev_counters(..., BTREE_TRIGGER_gc) is not
+                * safe w.r.t. transaction restarts, so fixup the gc_bucket so
+                * we don't run it twice:
+                */
+               percpu_down_read(&c->mark_lock);
+               struct bucket *gc_m = gc_bucket(ca, iter->pos.offset);
+               gc_m->data_type = gc.data_type;
+               gc_m->dirty_sectors = gc.dirty_sectors;
+               percpu_up_read(&c->mark_lock);
+       }
 
        if (fsck_err_on(new.data_type != gc.data_type,
                        trans, alloc_key_data_type_wrong,
@@ -857,7 +865,6 @@ static int bch2_alloc_write_key(struct btree_trans *trans,
        copy_bucket_field(alloc_key_cached_sectors_wrong,       cached_sectors);
        copy_bucket_field(alloc_key_stripe_wrong,               stripe);
        copy_bucket_field(alloc_key_stripe_redundancy_wrong,    stripe_redundancy);
-       copy_bucket_field(alloc_key_fragmentation_lru_wrong,    fragmentation_lru);
 #undef copy_bucket_field
 
        if (!bch2_alloc_v4_cmp(*old, new))
@@ -1227,17 +1234,20 @@ int bch2_gc_gens(struct bch_fs *c)
        u64 b, start_time = local_clock();
        int ret;
 
-       /*
-        * Ideally we would be using state_lock and not gc_gens_lock here, but that
-        * introduces a deadlock in the RO path - we currently take the state
-        * lock at the start of going RO, thus the gc thread may get stuck:
-        */
        if (!mutex_trylock(&c->gc_gens_lock))
                return 0;
 
        trace_and_count(c, gc_gens_start, c);
 
-       down_read(&c->state_lock);
+       /*
+        * We have to use trylock here. Otherwise, we would
+        * introduce a deadlock in the RO path - we take the
+        * state lock at the start of going RO.
+        */
+       if (!down_read_trylock(&c->state_lock)) {
+               mutex_unlock(&c->gc_gens_lock);
+               return 0;
+       }
 
        for_each_member_device(c, ca) {
                struct bucket_gens *gens = bucket_gens(ca);
index 1c1448b52207bb92ab1f5c0725a63e83451f3fbb..6296a11ccb09023a7940b3a80cef5532d5caaf6c 100644 (file)
@@ -1838,10 +1838,11 @@ static void btree_node_write_done(struct bch_fs *c, struct btree *b)
        struct btree_trans *trans = bch2_trans_get(c);
 
        btree_node_lock_nopath_nofail(trans, &b->c, SIX_LOCK_read);
-       __btree_node_write_done(c, b);
-       six_unlock_read(&b->c.lock);
 
+       /* we don't need transaction context anymore after we got the lock. */
        bch2_trans_put(trans);
+       __btree_node_write_done(c, b);
+       six_unlock_read(&b->c.lock);
 }
 
 static void btree_node_write_work(struct work_struct *work)
@@ -1870,7 +1871,7 @@ static void btree_node_write_work(struct work_struct *work)
 
                }
        } else {
-               ret = bch2_trans_do(c, NULL, NULL, 0,
+               ret = bch2_trans_do(c,
                        bch2_btree_node_update_key_get_iter(trans, b, &wbio->key,
                                        BCH_WATERMARK_interior_updates|
                                        BCH_TRANS_COMMIT_journal_reclaim|
index bfe9f0c1e1be8e3c97fb22c740ff57748c9cb1f9..eef9b89c561ddfdd2ef4b886fde90fb012e8e45f 100644 (file)
@@ -882,6 +882,18 @@ static noinline int btree_node_iter_and_journal_peek(struct btree_trans *trans,
        __bch2_btree_and_journal_iter_init_node_iter(trans, &jiter, l->b, l->iter, path->pos);
 
        k = bch2_btree_and_journal_iter_peek(&jiter);
+       if (!k.k) {
+               struct printbuf buf = PRINTBUF;
+
+               prt_str(&buf, "node not found at pos ");
+               bch2_bpos_to_text(&buf, path->pos);
+               prt_str(&buf, " at btree ");
+               bch2_btree_pos_to_text(&buf, c, l->b);
+
+               ret = bch2_fs_topology_error(c, "%s", buf.buf);
+               printbuf_exit(&buf);
+               goto err;
+       }
 
        bch2_bkey_buf_reassemble(out, c, k);
 
@@ -889,6 +901,7 @@ static noinline int btree_node_iter_and_journal_peek(struct btree_trans *trans,
            c->opts.btree_node_prefetch)
                ret = btree_path_prefetch_j(trans, path, &jiter);
 
+err:
        bch2_btree_and_journal_iter_exit(&jiter);
        return ret;
 }
@@ -2381,9 +2394,9 @@ struct bkey_s_c bch2_btree_iter_peek_upto(struct btree_iter *iter, struct bpos e
                else
                        iter_pos = bkey_max(iter->pos, bkey_start_pos(k.k));
 
-               if (unlikely(!(iter->flags & BTREE_ITER_is_extents)
-                            ? bkey_gt(iter_pos, end)
-                            : bkey_ge(iter_pos, end)))
+               if (unlikely(iter->flags & BTREE_ITER_all_snapshots     ? bpos_gt(iter_pos, end) :
+                            iter->flags & BTREE_ITER_is_extents        ? bkey_ge(iter_pos, end) :
+                                                                         bkey_gt(iter_pos, end)))
                        goto end;
 
                break;
index 78e63ad7d380e47c481f33bb4f191e0e100c0e03..0bda054f80d76c609aaeb37f7445b84d82d9dae7 100644 (file)
@@ -857,6 +857,14 @@ struct bkey_s_c bch2_btree_iter_peek_and_restart_outlined(struct btree_iter *);
        for_each_btree_key_upto_norestart(_trans, _iter, _btree_id, _start,\
                                          SPOS_MAX, _flags, _k, _ret)
 
+#define for_each_btree_key_reverse_norestart(_trans, _iter, _btree_id, \
+                                            _start, _flags, _k, _ret)  \
+       for (bch2_trans_iter_init((_trans), &(_iter), (_btree_id),      \
+                                 (_start), (_flags));                  \
+            (_k) = bch2_btree_iter_peek_prev_type(&(_iter), _flags),   \
+            !((_ret) = bkey_err(_k)) && (_k).k;                        \
+            bch2_btree_iter_rewind(&(_iter)))
+
 #define for_each_btree_key_continue_norestart(_iter, _flags, _k, _ret) \
        for_each_btree_key_upto_continue_norestart(_iter, SPOS_MAX, _flags, _k, _ret)
 
@@ -904,6 +912,8 @@ struct bkey_s_c bch2_btree_iter_peek_and_restart_outlined(struct btree_iter *);
        _ret;                                                           \
 })
 
+#define bch2_trans_do(_c, _do) bch2_trans_run(_c, lockrestart_do(trans, _do))
+
 struct btree_trans *__bch2_trans_get(struct bch_fs *, unsigned);
 void bch2_trans_put(struct btree_trans *);
 
index 1e694fedc5da049895fa4cb692ca0799ff7f9d5e..a7aedb134e9f8c23e32dea792023cea871429bf4 100644 (file)
@@ -171,6 +171,9 @@ static void try_read_btree_node(struct find_btree_nodes *f, struct bch_dev *ca,
        if (BTREE_NODE_LEVEL(bn) >= BTREE_MAX_DEPTH)
                return;
 
+       if (BTREE_NODE_ID(bn) >= BTREE_ID_NR_MAX)
+               return;
+
        rcu_read_lock();
        struct found_btree_node n = {
                .btree_id       = BTREE_NODE_ID(bn),
index 1a74a1a252ee2384b6b35d8a120549d17fe0e697..9bf471fa4361405b21fd57faed5a82296fef9374 100644 (file)
@@ -832,7 +832,8 @@ revert_fs_usage:
        for (struct jset_entry *entry2 = trans->journal_entries;
             entry2 != entry;
             entry2 = vstruct_next(entry2))
-               if (jset_entry_is_key(entry2) && entry2->start->k.type == KEY_TYPE_accounting) {
+               if (entry2->type == BCH_JSET_ENTRY_write_buffer_keys &&
+                   entry2->start->k.type == KEY_TYPE_accounting) {
                        struct bkey_s_accounting a = bkey_i_to_s_accounting(entry2->start);
 
                        bch2_accounting_neg(a);
index 514df618548e28e624c71ba1fbb426d678789a49..5d809e8bd170886a3ec1baeddeb550d38d84a827 100644 (file)
@@ -668,7 +668,7 @@ int bch2_btree_insert(struct bch_fs *c, enum btree_id id, struct bkey_i *k,
                      struct disk_reservation *disk_res, int flags,
                      enum btree_iter_update_trigger_flags iter_flags)
 {
-       return bch2_trans_do(c, disk_res, NULL, flags,
+       return bch2_trans_commit_do(c, disk_res, NULL, flags,
                             bch2_btree_insert_trans(trans, id, k, iter_flags));
 }
 
@@ -865,7 +865,7 @@ __bch2_fs_log_msg(struct bch_fs *c, unsigned commit_flags, const char *fmt,
                memcpy(l->d, buf.buf, buf.pos);
                c->journal.early_journal_entries.nr += jset_u64s(u64s);
        } else {
-               ret = bch2_trans_do(c, NULL, NULL,
+               ret = bch2_trans_commit_do(c, NULL, NULL,
                        BCH_TRANS_COMMIT_lazy_rw|commit_flags,
                        __bch2_trans_log_msg(trans, &buf, u64s));
        }
index 6a454f2fa00534082a8013a3c7db321cabcbf603..70b3c989fac23d23b804062836f555caaeb5b687 100644 (file)
@@ -192,7 +192,7 @@ static inline int bch2_trans_commit(struct btree_trans *trans,
        nested_lockrestart_do(_trans, _do ?: bch2_trans_commit(_trans, (_disk_res),\
                                        (_journal_seq), (_flags)))
 
-#define bch2_trans_do(_c, _disk_res, _journal_seq, _flags, _do)                \
+#define bch2_trans_commit_do(_c, _disk_res, _journal_seq, _flags, _do)         \
        bch2_trans_run(_c, commit_do(trans, _disk_res, _journal_seq, _flags, _do))
 
 #define trans_for_each_update(_trans, _i)                              \
index 190bc1e81756ca9c3c4f48ca41ef4e38bd8e8701..64f0928e113784c5aabda46c0197d0a5882409da 100644 (file)
@@ -2239,10 +2239,8 @@ static void async_btree_node_rewrite_work(struct work_struct *work)
        struct async_btree_rewrite *a =
                container_of(work, struct async_btree_rewrite, work);
        struct bch_fs *c = a->c;
-       int ret;
 
-       ret = bch2_trans_do(c, NULL, NULL, 0,
-                     async_btree_node_rewrite_trans(trans, a));
+       int ret = bch2_trans_do(c, async_btree_node_rewrite_trans(trans, a));
        bch_err_fn_ratelimited(c, ret);
        bch2_write_ref_put(c, BCH_WRITE_REF_node_rewrite);
        kfree(a);
index 546cd01a72e36150d00fdfc28eb3853919e522bb..ec7d9a59bea9c0c204d60a0a4a2b4dd7b5739bd5 100644 (file)
@@ -1160,11 +1160,11 @@ int bch2_trans_mark_dev_sbs(struct bch_fs *c)
 #define SECTORS_CACHE  1024
 
 int __bch2_disk_reservation_add(struct bch_fs *c, struct disk_reservation *res,
-                             u64 sectors, int flags)
+                               u64 sectors, enum bch_reservation_flags flags)
 {
        struct bch_fs_pcpu *pcpu;
        u64 old, get;
-       s64 sectors_available;
+       u64 sectors_available;
        int ret;
 
        percpu_down_read(&c->mark_lock);
@@ -1202,6 +1202,9 @@ recalculate:
        percpu_u64_set(&c->pcpu->sectors_available, 0);
        sectors_available = avail_factor(__bch2_fs_usage_read_short(c).free);
 
+       if (sectors_available && (flags & BCH_DISK_RESERVATION_PARTIAL))
+               sectors = min(sectors, sectors_available);
+
        if (sectors <= sectors_available ||
            (flags & BCH_DISK_RESERVATION_NOFAIL)) {
                atomic64_set(&c->sectors_available,
index e2cb7b24b220634b711116518aee06cc85bbd497..fd5e6ccad45e916aa6fbf0a013ee544f1d23cb0a 100644 (file)
@@ -344,14 +344,16 @@ static inline void bch2_disk_reservation_put(struct bch_fs *c,
        }
 }
 
-#define BCH_DISK_RESERVATION_NOFAIL            (1 << 0)
+enum bch_reservation_flags {
+       BCH_DISK_RESERVATION_NOFAIL     = 1 << 0,
+       BCH_DISK_RESERVATION_PARTIAL    = 1 << 1,
+};
 
-int __bch2_disk_reservation_add(struct bch_fs *,
-                               struct disk_reservation *,
-                               u64, int);
+int __bch2_disk_reservation_add(struct bch_fs *, struct disk_reservation *,
+                               u64, enum bch_reservation_flags);
 
 static inline int bch2_disk_reservation_add(struct bch_fs *c, struct disk_reservation *res,
-                                           u64 sectors, int flags)
+                                           u64 sectors, enum bch_reservation_flags flags)
 {
 #ifdef __KERNEL__
        u64 old, new;
index cbfd88f9847237afa1e20af1ea94eb41cbeeb434..2182b555c112cc6c66949e2ebf84937971a185ba 100644 (file)
@@ -225,6 +225,7 @@ static long bch2_ioctl_fsck_offline(struct bch_ioctl_fsck_offline __user *user_a
 
        opt_set(thr->opts, stdio, (u64)(unsigned long)&thr->thr.stdio);
        opt_set(thr->opts, read_only, 1);
+       opt_set(thr->opts, ratelimit_errors, 0);
 
        /* We need request_key() to be called before we punt to kthread: */
        opt_set(thr->opts, nostart, true);
index 4f06cd8bbbe15be2bb68d7c2187eea3eef5d8720..e86d36d23e9e309d4e6a21eaf8d243706b538daa 100644 (file)
@@ -2,6 +2,7 @@
 
 #include <linux/log2.h>
 #include <linux/slab.h>
+#include <linux/vmalloc.h>
 #include "darray.h"
 
 int __bch2_darray_resize_noprof(darray_char *d, size_t element_size, size_t new_size, gfp_t gfp)
@@ -9,7 +10,19 @@ int __bch2_darray_resize_noprof(darray_char *d, size_t element_size, size_t new_
        if (new_size > d->size) {
                new_size = roundup_pow_of_two(new_size);
 
-               void *data = kvmalloc_array_noprof(new_size, element_size, gfp);
+               /*
+                * This is a workaround: kvmalloc() doesn't support > INT_MAX
+                * allocations, but vmalloc() does.
+                * The limit needs to be lifted from kvmalloc, and when it does
+                * we'll go back to just using that.
+                */
+               size_t bytes;
+               if (unlikely(check_mul_overflow(new_size, element_size, &bytes)))
+                       return -ENOMEM;
+
+               void *data = likely(bytes < INT_MAX)
+                       ? kvmalloc_noprof(bytes, gfp)
+                       : vmalloc_noprof(bytes);
                if (!data)
                        return -ENOMEM;
 
index 462b1a2fe1ad8d9c75841d9af4d0b1eaec0c551b..8e75a852b3584e37d3775e520d6fb990b0182b93 100644 (file)
@@ -80,6 +80,7 @@ static bool bkey_nocow_lock(struct bch_fs *c, struct moving_context *ctxt, struc
                                        if (ptr2 == ptr)
                                                break;
 
+                                       ca = bch2_dev_have_ref(c, ptr2->dev);
                                        bucket = PTR_BUCKET_POS(ca, ptr2);
                                        bch2_bucket_nocow_unlock(&c->nocow_locks, bucket, 0);
                                }
@@ -235,7 +236,8 @@ static int __bch2_data_update_index_update(struct btree_trans *trans,
                        if (((1U << i) & m->data_opts.rewrite_ptrs) &&
                            (ptr = bch2_extent_has_ptr(old, p, bkey_i_to_s(insert))) &&
                            !ptr->cached) {
-                               bch2_extent_ptr_set_cached(bkey_i_to_s(insert), ptr);
+                               bch2_extent_ptr_set_cached(c, &m->op.opts,
+                                                          bkey_i_to_s(insert), ptr);
                                rewrites_found |= 1U << i;
                        }
                        i++;
@@ -283,7 +285,8 @@ restart_drop_extra_replicas:
                            durability - ptr_durability >= m->op.opts.data_replicas) {
                                durability -= ptr_durability;
 
-                               bch2_extent_ptr_set_cached(bkey_i_to_s(insert), &entry->ptr);
+                               bch2_extent_ptr_set_cached(c, &m->op.opts,
+                                                          bkey_i_to_s(insert), &entry->ptr);
                                goto restart_drop_extra_replicas;
                        }
                }
@@ -294,7 +297,7 @@ restart_drop_extra_replicas:
                        bch2_extent_ptr_decoded_append(insert, &p);
 
                bch2_bkey_narrow_crcs(insert, (struct bch_extent_crc_unpacked) { 0 });
-               bch2_extent_normalize(c, bkey_i_to_s(insert));
+               bch2_extent_normalize_by_opts(c, &m->op.opts, bkey_i_to_s(insert));
 
                ret = bch2_sum_sector_overwrites(trans, &iter, insert,
                                                 &should_check_enospc,
@@ -557,7 +560,8 @@ void bch2_data_update_to_text(struct printbuf *out, struct data_update *m)
 int bch2_extent_drop_ptrs(struct btree_trans *trans,
                          struct btree_iter *iter,
                          struct bkey_s_c k,
-                         struct data_update_opts data_opts)
+                         struct bch_io_opts *io_opts,
+                         struct data_update_opts *data_opts)
 {
        struct bch_fs *c = trans->c;
        struct bkey_i *n;
@@ -568,11 +572,11 @@ int bch2_extent_drop_ptrs(struct btree_trans *trans,
        if (ret)
                return ret;
 
-       while (data_opts.kill_ptrs) {
-               unsigned i = 0, drop = __fls(data_opts.kill_ptrs);
+       while (data_opts->kill_ptrs) {
+               unsigned i = 0, drop = __fls(data_opts->kill_ptrs);
 
                bch2_bkey_drop_ptrs_noerror(bkey_i_to_s(n), ptr, i++ == drop);
-               data_opts.kill_ptrs ^= 1U << drop;
+               data_opts->kill_ptrs ^= 1U << drop;
        }
 
        /*
@@ -580,7 +584,7 @@ int bch2_extent_drop_ptrs(struct btree_trans *trans,
         * will do the appropriate thing with it (turning it into a
         * KEY_TYPE_error key, or just a discard if it was a cached extent)
         */
-       bch2_extent_normalize(c, bkey_i_to_s(n));
+       bch2_extent_normalize_by_opts(c, io_opts, bkey_i_to_s(n));
 
        /*
         * Since we're not inserting through an extent iterator
@@ -719,7 +723,7 @@ int bch2_data_update_init(struct btree_trans *trans,
                m->data_opts.rewrite_ptrs = 0;
                /* if iter == NULL, it's just a promote */
                if (iter)
-                       ret = bch2_extent_drop_ptrs(trans, iter, k, m->data_opts);
+                       ret = bch2_extent_drop_ptrs(trans, iter, k, &io_opts, &m->data_opts);
                goto out;
        }
 
index 8d36365bdea8a5fbdac77f86a92431a822bc580e..e4b50723428e27c0073a4b75bd14d580fd4501a0 100644 (file)
@@ -40,7 +40,8 @@ void bch2_data_update_read_done(struct data_update *,
 int bch2_extent_drop_ptrs(struct btree_trans *,
                          struct btree_iter *,
                          struct bkey_s_c,
-                         struct data_update_opts);
+                         struct bch_io_opts *,
+                         struct data_update_opts *);
 
 void bch2_data_update_exit(struct data_update *);
 int bch2_data_update_init(struct btree_trans *, struct btree_iter *,
index 84dd4a879d98472476345f1450ac77d817872655..faffc98d5605355e596094b7fa238ea579745564 100644 (file)
@@ -250,13 +250,6 @@ int bch2_dirent_create(struct btree_trans *trans, subvol_inum dir,
        return ret;
 }
 
-static void dirent_copy_target(struct bkey_i_dirent *dst,
-                              struct bkey_s_c_dirent src)
-{
-       dst->v.d_inum = src.v->d_inum;
-       dst->v.d_type = src.v->d_type;
-}
-
 int bch2_dirent_read_target(struct btree_trans *trans, subvol_inum dir,
                            struct bkey_s_c_dirent d, subvol_inum *target)
 {
index 8945145865c53b4b46ee82d86b55689f5fed6ab4..53ad996660226be6c46e991cc6b65709e466f851 100644 (file)
@@ -34,6 +34,13 @@ static inline unsigned dirent_val_u64s(unsigned len)
 int bch2_dirent_read_target(struct btree_trans *, subvol_inum,
                            struct bkey_s_c_dirent, subvol_inum *);
 
+static inline void dirent_copy_target(struct bkey_i_dirent *dst,
+                                     struct bkey_s_c_dirent src)
+{
+       dst->v.d_inum = src.v->d_inum;
+       dst->v.d_type = src.v->d_type;
+}
+
 int bch2_dirent_create_snapshot(struct btree_trans *, u32, u64, u32,
                        const struct bch_hash_info *, u8,
                        const struct qstr *, u64, u64 *,
index 9f3133e3e7e5e4deca5c45cc090f4792a5e2671e..07eb8fa1b02666acf88494818cc1d3759a75e451 100644 (file)
@@ -242,6 +242,14 @@ void bch2_accounting_swab(struct bkey_s k)
                *p = swab64(*p);
 }
 
+static inline void __accounting_to_replicas(struct bch_replicas_entry_v1 *r,
+                                           struct disk_accounting_pos acc)
+{
+       unsafe_memcpy(r, &acc.replicas,
+                     replicas_entry_bytes(&acc.replicas),
+                     "variable length struct");
+}
+
 static inline bool accounting_to_replicas(struct bch_replicas_entry_v1 *r, struct bpos p)
 {
        struct disk_accounting_pos acc_k;
@@ -249,9 +257,7 @@ static inline bool accounting_to_replicas(struct bch_replicas_entry_v1 *r, struc
 
        switch (acc_k.type) {
        case BCH_DISK_ACCOUNTING_replicas:
-               unsafe_memcpy(r, &acc_k.replicas,
-                             replicas_entry_bytes(&acc_k.replicas),
-                             "variable length struct");
+               __accounting_to_replicas(r, acc_k);
                return true;
        default:
                return false;
@@ -608,6 +614,81 @@ static int accounting_read_key(struct btree_trans *trans, struct bkey_s_c k)
        return ret;
 }
 
+static int bch2_disk_accounting_validate_late(struct btree_trans *trans,
+                                             struct disk_accounting_pos acc,
+                                             u64 *v, unsigned nr)
+{
+       struct bch_fs *c = trans->c;
+       struct printbuf buf = PRINTBUF;
+       int ret = 0, invalid_dev = -1;
+
+       switch (acc.type) {
+       case BCH_DISK_ACCOUNTING_replicas: {
+               struct bch_replicas_padded r;
+               __accounting_to_replicas(&r.e, acc);
+
+               for (unsigned i = 0; i < r.e.nr_devs; i++)
+                       if (r.e.devs[i] != BCH_SB_MEMBER_INVALID &&
+                           !bch2_dev_exists(c, r.e.devs[i])) {
+                               invalid_dev = r.e.devs[i];
+                               goto invalid_device;
+                       }
+
+               /*
+                * All replicas entry checks except for invalid device are done
+                * in bch2_accounting_validate
+                */
+               BUG_ON(bch2_replicas_entry_validate(&r.e, c, &buf));
+
+               if (fsck_err_on(!bch2_replicas_marked_locked(c, &r.e),
+                               trans, accounting_replicas_not_marked,
+                               "accounting not marked in superblock replicas\n  %s",
+                               (printbuf_reset(&buf),
+                                bch2_accounting_key_to_text(&buf, &acc),
+                                buf.buf))) {
+                       /*
+                        * We're not RW yet and still single threaded, dropping
+                        * and retaking lock is ok:
+                        */
+                       percpu_up_write(&c->mark_lock);
+                       ret = bch2_mark_replicas(c, &r.e);
+                       if (ret)
+                               goto fsck_err;
+                       percpu_down_write(&c->mark_lock);
+               }
+               break;
+       }
+
+       case BCH_DISK_ACCOUNTING_dev_data_type:
+               if (!bch2_dev_exists(c, acc.dev_data_type.dev)) {
+                       invalid_dev = acc.dev_data_type.dev;
+                       goto invalid_device;
+               }
+               break;
+       }
+
+fsck_err:
+       printbuf_exit(&buf);
+       return ret;
+invalid_device:
+       if (fsck_err(trans, accounting_to_invalid_device,
+                    "accounting entry points to invalid device %i\n  %s",
+                    invalid_dev,
+                    (printbuf_reset(&buf),
+                     bch2_accounting_key_to_text(&buf, &acc),
+                     buf.buf))) {
+               for (unsigned i = 0; i < nr; i++)
+                       v[i] = -v[i];
+
+               ret = commit_do(trans, NULL, NULL, 0,
+                               bch2_disk_accounting_mod(trans, &acc, v, nr, false)) ?:
+                       -BCH_ERR_remove_disk_accounting_entry;
+       } else {
+               ret = -BCH_ERR_remove_disk_accounting_entry;
+       }
+       goto fsck_err;
+}
+
 /*
  * At startup time, initialize the in memory accounting from the btree (and
  * journal)
@@ -666,44 +747,42 @@ int bch2_accounting_read(struct bch_fs *c)
        }
        keys->gap = keys->nr = dst - keys->data;
 
-       percpu_down_read(&c->mark_lock);
-       for (unsigned i = 0; i < acc->k.nr; i++) {
-               u64 v[BCH_ACCOUNTING_MAX_COUNTERS];
-               bch2_accounting_mem_read_counters(acc, i, v, ARRAY_SIZE(v), false);
+       percpu_down_write(&c->mark_lock);
+       unsigned i = 0;
+       while (i < acc->k.nr) {
+               unsigned idx = inorder_to_eytzinger0(i, acc->k.nr);
 
-               if (bch2_is_zero(v, sizeof(v[0]) * acc->k.data[i].nr_counters))
-                       continue;
+               struct disk_accounting_pos acc_k;
+               bpos_to_disk_accounting_pos(&acc_k, acc->k.data[idx].pos);
 
-               struct bch_replicas_padded r;
-               if (!accounting_to_replicas(&r.e, acc->k.data[i].pos))
-                       continue;
+               u64 v[BCH_ACCOUNTING_MAX_COUNTERS];
+               bch2_accounting_mem_read_counters(acc, idx, v, ARRAY_SIZE(v), false);
 
                /*
-                * If the replicas entry is invalid it'll get cleaned up by
-                * check_allocations:
+                * If the entry counters are zeroed, it should be treated as
+                * nonexistent - it might point to an invalid device.
+                *
+                * Remove it, so that if it's re-added it gets re-marked in the
+                * superblock:
                 */
-               if (bch2_replicas_entry_validate(&r.e, c, &buf))
+               ret = bch2_is_zero(v, sizeof(v[0]) * acc->k.data[idx].nr_counters)
+                       ? -BCH_ERR_remove_disk_accounting_entry
+                       : bch2_disk_accounting_validate_late(trans, acc_k,
+                                                       v, acc->k.data[idx].nr_counters);
+
+               if (ret == -BCH_ERR_remove_disk_accounting_entry) {
+                       free_percpu(acc->k.data[idx].v[0]);
+                       free_percpu(acc->k.data[idx].v[1]);
+                       darray_remove_item(&acc->k, &acc->k.data[idx]);
+                       eytzinger0_sort(acc->k.data, acc->k.nr, sizeof(acc->k.data[0]),
+                                       accounting_pos_cmp, NULL);
+                       ret = 0;
                        continue;
-
-               struct disk_accounting_pos k;
-               bpos_to_disk_accounting_pos(&k, acc->k.data[i].pos);
-
-               if (fsck_err_on(!bch2_replicas_marked_locked(c, &r.e),
-                               trans, accounting_replicas_not_marked,
-                               "accounting not marked in superblock replicas\n  %s",
-                               (printbuf_reset(&buf),
-                                bch2_accounting_key_to_text(&buf, &k),
-                                buf.buf))) {
-                       /*
-                        * We're not RW yet and still single threaded, dropping
-                        * and retaking lock is ok:
-                        */
-                       percpu_up_read(&c->mark_lock);
-                       ret = bch2_mark_replicas(c, &r.e);
-                       if (ret)
-                               goto fsck_err;
-                       percpu_down_read(&c->mark_lock);
                }
+
+               if (ret)
+                       goto fsck_err;
+               i++;
        }
 
        preempt_disable();
@@ -742,7 +821,7 @@ int bch2_accounting_read(struct bch_fs *c)
        }
        preempt_enable();
 fsck_err:
-       percpu_up_read(&c->mark_lock);
+       percpu_up_write(&c->mark_lock);
 err:
        printbuf_exit(&buf);
        bch2_trans_put(trans);
@@ -777,8 +856,10 @@ int bch2_dev_usage_init(struct bch_dev *ca, bool gc)
        };
        u64 v[3] = { ca->mi.nbuckets - ca->mi.first_bucket, 0, 0 };
 
-       int ret = bch2_trans_do(c, NULL, NULL, 0,
-                       bch2_disk_accounting_mod(trans, &acc, v, ARRAY_SIZE(v), gc));
+       int ret = bch2_trans_do(c, ({
+               bch2_disk_accounting_mod(trans, &acc, v, ARRAY_SIZE(v), gc) ?:
+               (!gc ? bch2_trans_commit(trans, NULL, NULL, 0) : 0);
+       }));
        bch_err_fn(c, ret);
        return ret;
 }
index 1587c6e1866ae6cebb0a501cf838a18f279d4620..749dcf368841d729ad5573b7b9959e962cf68d7f 100644 (file)
@@ -124,6 +124,11 @@ int bch2_stripe_validate(struct bch_fs *c, struct bkey_s_c k,
                         "incorrect value size (%zu < %u)",
                         bkey_val_u64s(k.k), stripe_val_u64s(s));
 
+       bkey_fsck_err_on(s->csum_granularity_bits >= 64,
+                        c, stripe_csum_granularity_bad,
+                        "invalid csum granularity (%u >= 64)",
+                        s->csum_granularity_bits);
+
        ret = bch2_bkey_ptrs_validate(c, k, flags);
 fsck_err:
        return ret;
@@ -145,7 +150,11 @@ void bch2_stripe_to_text(struct printbuf *out, struct bch_fs *c,
                   nr_data,
                   s.nr_redundant);
        bch2_prt_csum_type(out, s.csum_type);
-       prt_printf(out, " gran %u", 1U << s.csum_granularity_bits);
+       prt_str(out, " gran ");
+       if (s.csum_granularity_bits < 64)
+               prt_printf(out, "%llu", 1ULL << s.csum_granularity_bits);
+       else
+               prt_printf(out, "(invalid shift %u)", s.csum_granularity_bits);
 
        if (s.disk_label) {
                prt_str(out, " label");
@@ -257,12 +266,12 @@ static int __mark_stripe_bucket(struct btree_trans *trans,
        if (!deleting) {
                a->stripe               = s.k->p.offset;
                a->stripe_redundancy    = s.v->nr_redundant;
+               alloc_data_type_set(a, data_type);
        } else {
                a->stripe               = 0;
                a->stripe_redundancy    = 0;
+               alloc_data_type_set(a, BCH_DATA_user);
        }
-
-       alloc_data_type_set(a, data_type);
 err:
        printbuf_exit(&buf);
        return ret;
@@ -1177,7 +1186,7 @@ static void ec_stripe_delete_work(struct work_struct *work)
                if (!idx)
                        break;
 
-               int ret = bch2_trans_do(c, NULL, NULL, BCH_TRANS_COMMIT_no_enospc,
+               int ret = bch2_trans_commit_do(c, NULL, NULL, BCH_TRANS_COMMIT_no_enospc,
                                        ec_stripe_delete(trans, idx));
                bch_err_fn(c, ret);
                if (ret)
@@ -1197,47 +1206,62 @@ void bch2_do_stripe_deletes(struct bch_fs *c)
 /* stripe creation: */
 
 static int ec_stripe_key_update(struct btree_trans *trans,
-                               struct bkey_i_stripe *new,
-                               bool create)
+                               struct bkey_i_stripe *old,
+                               struct bkey_i_stripe *new)
 {
        struct bch_fs *c = trans->c;
-       struct btree_iter iter;
-       struct bkey_s_c k;
-       int ret;
+       bool create = !old;
 
-       k = bch2_bkey_get_iter(trans, &iter, BTREE_ID_stripes,
-                              new->k.p, BTREE_ITER_intent);
-       ret = bkey_err(k);
+       struct btree_iter iter;
+       struct bkey_s_c k = bch2_bkey_get_iter(trans, &iter, BTREE_ID_stripes,
+                                              new->k.p, BTREE_ITER_intent);
+       int ret = bkey_err(k);
        if (ret)
                goto err;
 
-       if (k.k->type != (create ? KEY_TYPE_deleted : KEY_TYPE_stripe)) {
-               bch2_fs_inconsistent(c, "error %s stripe: got existing key type %s",
-                                    create ? "creating" : "updating",
-                                    bch2_bkey_types[k.k->type]);
+       if (bch2_fs_inconsistent_on(k.k->type != (create ? KEY_TYPE_deleted : KEY_TYPE_stripe),
+                                   c, "error %s stripe: got existing key type %s",
+                                   create ? "creating" : "updating",
+                                   bch2_bkey_types[k.k->type])) {
                ret = -EINVAL;
                goto err;
        }
 
        if (k.k->type == KEY_TYPE_stripe) {
-               const struct bch_stripe *old = bkey_s_c_to_stripe(k).v;
-               unsigned i;
+               const struct bch_stripe *v = bkey_s_c_to_stripe(k).v;
 
-               if (old->nr_blocks != new->v.nr_blocks) {
-                       bch_err(c, "error updating stripe: nr_blocks does not match");
-                       ret = -EINVAL;
-                       goto err;
-               }
+               BUG_ON(old->v.nr_blocks != new->v.nr_blocks);
+               BUG_ON(old->v.nr_blocks != v->nr_blocks);
 
-               for (i = 0; i < new->v.nr_blocks; i++) {
-                       unsigned v = stripe_blockcount_get(old, i);
+               for (unsigned i = 0; i < new->v.nr_blocks; i++) {
+                       unsigned sectors = stripe_blockcount_get(v, i);
 
-                       BUG_ON(v &&
-                              (old->ptrs[i].dev != new->v.ptrs[i].dev ||
-                               old->ptrs[i].gen != new->v.ptrs[i].gen ||
-                               old->ptrs[i].offset != new->v.ptrs[i].offset));
+                       if (!bch2_extent_ptr_eq(old->v.ptrs[i], new->v.ptrs[i]) && sectors) {
+                               struct printbuf buf = PRINTBUF;
 
-                       stripe_blockcount_set(&new->v, i, v);
+                               prt_printf(&buf, "stripe changed nonempty block %u", i);
+                               prt_str(&buf, "\nold: ");
+                               bch2_bkey_val_to_text(&buf, c, k);
+                               prt_str(&buf, "\nnew: ");
+                               bch2_bkey_val_to_text(&buf, c, bkey_i_to_s_c(&new->k_i));
+                               bch2_fs_inconsistent(c, "%s", buf.buf);
+                               printbuf_exit(&buf);
+                               ret = -EINVAL;
+                               goto err;
+                       }
+
+                       /*
+                        * If the stripe ptr changed underneath us, it must have
+                        * been dev_remove_stripes() -> * invalidate_stripe_to_dev()
+                        */
+                       if (!bch2_extent_ptr_eq(old->v.ptrs[i], v->ptrs[i])) {
+                               BUG_ON(v->ptrs[i].dev != BCH_SB_MEMBER_INVALID);
+
+                               if (bch2_extent_ptr_eq(old->v.ptrs[i], new->v.ptrs[i]))
+                                       new->v.ptrs[i].dev = BCH_SB_MEMBER_INVALID;
+                       }
+
+                       stripe_blockcount_set(&new->v, i, sectors);
                }
        }
 
@@ -1495,12 +1519,14 @@ static void ec_stripe_create(struct ec_stripe_new *s)
                goto err;
        }
 
-       ret = bch2_trans_do(c, &s->res, NULL,
-                           BCH_TRANS_COMMIT_no_check_rw|
-                           BCH_TRANS_COMMIT_no_enospc,
-                           ec_stripe_key_update(trans,
-                                       bkey_i_to_stripe(&s->new_stripe.key),
-                                       !s->have_existing_stripe));
+       ret = bch2_trans_commit_do(c, &s->res, NULL,
+               BCH_TRANS_COMMIT_no_check_rw|
+               BCH_TRANS_COMMIT_no_enospc,
+               ec_stripe_key_update(trans,
+                                    s->have_existing_stripe
+                                    ? bkey_i_to_stripe(&s->existing_stripe.key)
+                                    : NULL,
+                                    bkey_i_to_stripe(&s->new_stripe.key)));
        bch_err_msg(c, ret, "creating stripe key");
        if (ret) {
                goto err;
@@ -1844,6 +1870,10 @@ __bch2_ec_stripe_head_get(struct btree_trans *trans,
                }
 
        h = ec_new_stripe_head_alloc(c, disk_label, algo, redundancy, watermark);
+       if (!h) {
+               h = ERR_PTR(-BCH_ERR_ENOMEM_stripe_head_alloc);
+               goto err;
+       }
 found:
        if (h->rw_devs_change_count != c->rw_devs_change_count)
                ec_stripe_head_devs_update(c, h);
@@ -1876,7 +1906,15 @@ static int new_stripe_alloc_buckets(struct btree_trans *trans, struct ec_stripe_
        bitmap_and(devs.d, devs.d, c->rw_devs[BCH_DATA_user].d, BCH_SB_MEMBERS_MAX);
 
        for_each_set_bit(i, h->s->blocks_gotten, v->nr_blocks) {
-               __clear_bit(v->ptrs[i].dev, devs.d);
+               /*
+                * Note: we don't yet repair invalid blocks (failed/removed
+                * devices) when reusing stripes - we still need a codepath to
+                * walk backpointers and update all extents that point to that
+                * block when updating the stripe
+                */
+               if (v->ptrs[i].dev != BCH_SB_MEMBER_INVALID)
+                       __clear_bit(v->ptrs[i].dev, devs.d);
+
                if (i < h->s->nr_data)
                        nr_have_data++;
                else
index 60b7875adada357d029b8b33e207e553ea77303c..a1bc6c7a8ba0e9c687a1a34cfed6f76637bc55b9 100644 (file)
@@ -83,6 +83,7 @@
        x(ENOMEM,                       ENOMEM_fs_other_alloc)                  \
        x(ENOMEM,                       ENOMEM_dev_alloc)                       \
        x(ENOMEM,                       ENOMEM_disk_accounting)                 \
+       x(ENOMEM,                       ENOMEM_stripe_head_alloc)               \
        x(ENOSPC,                       ENOSPC_disk_reservation)                \
        x(ENOSPC,                       ENOSPC_bucket_alloc)                    \
        x(ENOSPC,                       ENOSPC_disk_label_add)                  \
        x(BCH_ERR_invalid_sb_layout,    invalid_sb_layout_type)                 \
        x(BCH_ERR_invalid_sb_layout,    invalid_sb_layout_nr_superblocks)       \
        x(BCH_ERR_invalid_sb_layout,    invalid_sb_layout_superblocks_overlap)  \
+       x(BCH_ERR_invalid_sb_layout,    invalid_sb_layout_sb_max_size_bits)     \
        x(BCH_ERR_invalid_sb,           invalid_sb_members_missing)             \
        x(BCH_ERR_invalid_sb,           invalid_sb_members)                     \
        x(BCH_ERR_invalid_sb,           invalid_sb_disk_groups)                 \
        x(BCH_ERR_nopromote,            nopromote_no_writes)                    \
        x(BCH_ERR_nopromote,            nopromote_enomem)                       \
        x(0,                            invalid_snapshot_node)                  \
-       x(0,                            option_needs_open_fs)
+       x(0,                            option_needs_open_fs)                   \
+       x(0,                            remove_disk_accounting_entry)
 
 enum bch_errcode {
        BCH_ERR_START           = 2048,
index 3a16b535b6c324e7ecfc84aacd943a28c0e4ae11..b679def8fb98c7c94b70bb18b43b1b1600df1f4d 100644 (file)
@@ -251,7 +251,10 @@ int __bch2_fsck_err(struct bch_fs *c,
         *   delete the key)
         * - and we don't need to warn if we're not prompting
         */
-       WARN_ON(!(flags & FSCK_AUTOFIX) && !trans && bch2_current_has_btree_trans(c));
+       WARN_ON((flags & FSCK_CAN_FIX) &&
+               !(flags & FSCK_AUTOFIX) &&
+               !trans &&
+               bch2_current_has_btree_trans(c));
 
        if ((flags & FSCK_CAN_FIX) &&
            test_bit(err, c->sb.errors_silent))
@@ -393,6 +396,14 @@ int __bch2_fsck_err(struct bch_fs *c,
             !(flags & FSCK_CAN_IGNORE)))
                ret = -BCH_ERR_fsck_errors_not_fixed;
 
+       bool exiting =
+               test_bit(BCH_FS_fsck_running, &c->flags) &&
+               (ret != -BCH_ERR_fsck_fix &&
+                ret != -BCH_ERR_fsck_ignore);
+
+       if (exiting)
+               print = true;
+
        if (print) {
                if (bch2_fs_stdio_redirect(c))
                        bch2_print(c, "%s\n", out->buf);
@@ -400,9 +411,7 @@ int __bch2_fsck_err(struct bch_fs *c,
                        bch2_print_string_as_lines(KERN_ERR, out->buf);
        }
 
-       if (test_bit(BCH_FS_fsck_running, &c->flags) &&
-           (ret != -BCH_ERR_fsck_fix &&
-            ret != -BCH_ERR_fsck_ignore))
+       if (exiting)
                bch_err(c, "Unable to continue, halting");
        else if (suppressing)
                bch_err(c, "Ratelimiting new instances of previous error");
@@ -430,10 +439,17 @@ err:
 
 int __bch2_bkey_fsck_err(struct bch_fs *c,
                         struct bkey_s_c k,
-                        enum bch_fsck_flags flags,
+                        enum bch_validate_flags validate_flags,
                         enum bch_sb_error_id err,
                         const char *fmt, ...)
 {
+       if (validate_flags & BCH_VALIDATE_silent)
+               return -BCH_ERR_fsck_delete_bkey;
+
+       unsigned fsck_flags = 0;
+       if (!(validate_flags & (BCH_VALIDATE_write|BCH_VALIDATE_commit)))
+               fsck_flags |= FSCK_AUTOFIX|FSCK_CAN_FIX;
+
        struct printbuf buf = PRINTBUF;
        va_list args;
 
@@ -445,7 +461,7 @@ int __bch2_bkey_fsck_err(struct bch_fs *c,
        va_end(args);
        prt_str(&buf, ": delete?");
 
-       int ret = __bch2_fsck_err(c, NULL, flags, err, "%s", buf.buf);
+       int ret = __bch2_fsck_err(c, NULL, fsck_flags, err, "%s", buf.buf);
        printbuf_exit(&buf);
        return ret;
 }
index 21ee7211b03e8d708166a15ac5aaf388c4bab4c5..6551ada926b607b5d49f901402c26e314fbc45a4 100644 (file)
@@ -167,10 +167,11 @@ void bch2_flush_fsck_errs(struct bch_fs *);
 #define fsck_err_on(cond, c, _err_type, ...)                           \
        __fsck_err_on(cond, c, FSCK_CAN_FIX|FSCK_CAN_IGNORE, _err_type, __VA_ARGS__)
 
+enum bch_validate_flags;
 __printf(5, 6)
 int __bch2_bkey_fsck_err(struct bch_fs *,
                         struct bkey_s_c,
-                        enum bch_fsck_flags,
+                        enum bch_validate_flags,
                         enum bch_sb_error_id,
                         const char *, ...);
 
@@ -180,11 +181,7 @@ int __bch2_bkey_fsck_err(struct bch_fs *,
  */
 #define bkey_fsck_err(c, _err_type, _err_msg, ...)                     \
 do {                                                                   \
-       if ((flags & BCH_VALIDATE_silent)) {                            \
-               ret = -BCH_ERR_fsck_delete_bkey;                        \
-               goto fsck_err;                                          \
-       }                                                               \
-       int _ret = __bch2_bkey_fsck_err(c, k, FSCK_CAN_FIX|FSCK_AUTOFIX,\
+       int _ret = __bch2_bkey_fsck_err(c, k, flags,                    \
                                BCH_FSCK_ERR_##_err_type,               \
                                _err_msg, ##__VA_ARGS__);               \
        if (_ret != -BCH_ERR_fsck_fix &&                                \
index cc0d22085aef42d61711a02b0aea1d1cecb320f9..c4e91d1238496dd2194045b8746e4575bf5e4084 100644 (file)
@@ -978,31 +978,54 @@ bch2_extent_has_ptr(struct bkey_s_c k1, struct extent_ptr_decoded p1, struct bke
        return NULL;
 }
 
-void bch2_extent_ptr_set_cached(struct bkey_s k, struct bch_extent_ptr *ptr)
+static bool want_cached_ptr(struct bch_fs *c, struct bch_io_opts *opts,
+                           struct bch_extent_ptr *ptr)
+{
+       if (!opts->promote_target ||
+           !bch2_dev_in_target(c, ptr->dev, opts->promote_target))
+               return false;
+
+       struct bch_dev *ca = bch2_dev_rcu_noerror(c, ptr->dev);
+
+       return ca && bch2_dev_is_readable(ca) && !dev_ptr_stale_rcu(ca, ptr);
+}
+
+void bch2_extent_ptr_set_cached(struct bch_fs *c,
+                               struct bch_io_opts *opts,
+                               struct bkey_s k,
+                               struct bch_extent_ptr *ptr)
 {
        struct bkey_ptrs ptrs = bch2_bkey_ptrs(k);
        union bch_extent_entry *entry;
-       union bch_extent_entry *ec = NULL;
+       struct extent_ptr_decoded p;
 
-       bkey_extent_entry_for_each(ptrs, entry) {
+       rcu_read_lock();
+       if (!want_cached_ptr(c, opts, ptr)) {
+               bch2_bkey_drop_ptr_noerror(k, ptr);
+               goto out;
+       }
+
+       /*
+        * Stripes can't contain cached data, for - reasons.
+        *
+        * Possibly something we can fix in the future?
+        */
+       bkey_for_each_ptr_decode(k.k, ptrs, p, entry)
                if (&entry->ptr == ptr) {
-                       ptr->cached = true;
-                       if (ec)
-                               extent_entry_drop(k, ec);
-                       return;
+                       if (p.has_ec)
+                               bch2_bkey_drop_ptr_noerror(k, ptr);
+                       else
+                               ptr->cached = true;
+                       goto out;
                }
 
-               if (extent_entry_is_stripe_ptr(entry))
-                       ec = entry;
-               else if (extent_entry_is_ptr(entry))
-                       ec = NULL;
-       }
-
        BUG();
+out:
+       rcu_read_unlock();
 }
 
 /*
- * bch_extent_normalize - clean up an extent, dropping stale pointers etc.
+ * bch2_extent_normalize - clean up an extent, dropping stale pointers etc.
  *
  * Returns true if @k should be dropped entirely
  *
@@ -1016,8 +1039,39 @@ bool bch2_extent_normalize(struct bch_fs *c, struct bkey_s k)
        rcu_read_lock();
        bch2_bkey_drop_ptrs(k, ptr,
                ptr->cached &&
-               (ca = bch2_dev_rcu(c, ptr->dev)) &&
-               dev_ptr_stale_rcu(ca, ptr) > 0);
+               (!(ca = bch2_dev_rcu(c, ptr->dev)) ||
+                dev_ptr_stale_rcu(ca, ptr) > 0));
+       rcu_read_unlock();
+
+       return bkey_deleted(k.k);
+}
+
+/*
+ * bch2_extent_normalize_by_opts - clean up an extent, dropping stale pointers etc.
+ *
+ * Like bch2_extent_normalize(), but also only keeps a single cached pointer on
+ * the promote target.
+ */
+bool bch2_extent_normalize_by_opts(struct bch_fs *c,
+                                  struct bch_io_opts *opts,
+                                  struct bkey_s k)
+{
+       struct bkey_ptrs ptrs;
+       bool have_cached_ptr;
+
+       rcu_read_lock();
+restart_drop_ptrs:
+       ptrs = bch2_bkey_ptrs(k);
+       have_cached_ptr = false;
+
+       bkey_for_each_ptr(ptrs, ptr)
+               if (ptr->cached) {
+                       if (have_cached_ptr || !want_cached_ptr(c, opts, ptr)) {
+                               bch2_bkey_drop_ptr(k, ptr);
+                               goto restart_drop_ptrs;
+                       }
+                       have_cached_ptr = true;
+               }
        rcu_read_unlock();
 
        return bkey_deleted(k.k);
index ed5001dd662eb9397588c053113f76f144556677..bcffcf60aaaf8924a3754b734dafa679d31b5657 100644 (file)
@@ -686,15 +686,28 @@ bool bch2_extents_match(struct bkey_s_c, struct bkey_s_c);
 struct bch_extent_ptr *
 bch2_extent_has_ptr(struct bkey_s_c, struct extent_ptr_decoded, struct bkey_s);
 
-void bch2_extent_ptr_set_cached(struct bkey_s, struct bch_extent_ptr *);
+void bch2_extent_ptr_set_cached(struct bch_fs *, struct bch_io_opts *,
+                               struct bkey_s, struct bch_extent_ptr *);
 
+bool bch2_extent_normalize_by_opts(struct bch_fs *, struct bch_io_opts *, struct bkey_s);
 bool bch2_extent_normalize(struct bch_fs *, struct bkey_s);
+
 void bch2_extent_ptr_to_text(struct printbuf *out, struct bch_fs *, const struct bch_extent_ptr *);
 void bch2_bkey_ptrs_to_text(struct printbuf *, struct bch_fs *,
                            struct bkey_s_c);
 int bch2_bkey_ptrs_validate(struct bch_fs *, struct bkey_s_c,
                            enum bch_validate_flags);
 
+static inline bool bch2_extent_ptr_eq(struct bch_extent_ptr ptr1,
+                                     struct bch_extent_ptr ptr2)
+{
+       return (ptr1.cached     == ptr2.cached &&
+               ptr1.unwritten  == ptr2.unwritten &&
+               ptr1.offset     == ptr2.offset &&
+               ptr1.dev        == ptr2.dev &&
+               ptr1.dev        == ptr2.dev);
+}
+
 void bch2_ptr_swab(struct bkey_s);
 
 const struct bch_extent_rebalance *bch2_bkey_rebalance_opts(struct bkey_s_c);
index 48a1ab9a649bc11fea05f1aaed6b32cdfe772b36..95972809e76d7f5740b7bb007a370dbba7340c8a 100644 (file)
@@ -856,6 +856,12 @@ static int __bch2_buffered_write(struct bch_inode_info *inode,
                                folios_trunc(&fs, fi);
                                end = min(end, folio_end_pos(darray_last(fs)));
                        } else {
+                               if (!folio_test_uptodate(f)) {
+                                       ret = bch2_read_single_folio(f, mapping);
+                                       if (ret)
+                                               goto out;
+                               }
+
                                folios_trunc(&fs, fi + 1);
                                end = f_pos + f_reserved;
                        }
index ee1c0325f313048fa7ba738810444bc75caac442..6d3a05ae5da844ace2231957ba2ae5eac11f90b7 100644 (file)
@@ -369,6 +369,7 @@ static noinline void bch2_dio_write_flush(struct dio_write *dio)
 
 static __always_inline long bch2_dio_write_done(struct dio_write *dio)
 {
+       struct bch_fs *c = dio->op.c;
        struct kiocb *req = dio->req;
        struct bch_inode_info *inode = dio->inode;
        bool sync = dio->sync;
@@ -387,7 +388,7 @@ static __always_inline long bch2_dio_write_done(struct dio_write *dio)
        ret = dio->op.error ?: ((long) dio->written << 9);
        bio_put(&dio->op.wbio.bio);
 
-       bch2_write_ref_put(dio->op.c, BCH_WRITE_REF_dio_write);
+       bch2_write_ref_put(c, BCH_WRITE_REF_dio_write);
 
        /* inode->i_dio_count is our ref on inode and thus bch_fs */
        inode_dio_end(&inode->v);
index af3a24546aa370e8cc89be9616bb4f96aa740b77..1d4910ea0f1d63f14c556cec39560897388b86a1 100644 (file)
@@ -399,14 +399,17 @@ void bch2_folio_reservation_put(struct bch_fs *c,
        bch2_quota_reservation_put(c, inode, &res->quota);
 }
 
-int bch2_folio_reservation_get(struct bch_fs *c,
+static int __bch2_folio_reservation_get(struct bch_fs *c,
                        struct bch_inode_info *inode,
                        struct folio *folio,
                        struct bch2_folio_reservation *res,
-                       size_t offset, size_t len)
+                       size_t offset, size_t len,
+                       bool partial)
 {
        struct bch_folio *s = bch2_folio_create(folio, 0);
        unsigned i, disk_sectors = 0, quota_sectors = 0;
+       struct disk_reservation disk_res = {};
+       size_t reserved = len;
        int ret;
 
        if (!s)
@@ -422,48 +425,65 @@ int bch2_folio_reservation_get(struct bch_fs *c,
        }
 
        if (disk_sectors) {
-               ret = bch2_disk_reservation_add(c, &res->disk, disk_sectors, 0);
+               ret = bch2_disk_reservation_add(c, &disk_res, disk_sectors,
+                               partial ? BCH_DISK_RESERVATION_PARTIAL : 0);
                if (unlikely(ret))
                        return ret;
+
+               if (unlikely(disk_res.sectors != disk_sectors)) {
+                       disk_sectors = quota_sectors = 0;
+
+                       for (i = round_down(offset, block_bytes(c)) >> 9;
+                            i < round_up(offset + len, block_bytes(c)) >> 9;
+                            i++) {
+                               disk_sectors += sectors_to_reserve(&s->s[i], res->disk.nr_replicas);
+                               if (disk_sectors > disk_res.sectors) {
+                                       /*
+                                        * Make sure to get a reservation that's
+                                        * aligned to the filesystem blocksize:
+                                        */
+                                       unsigned reserved_offset = round_down(i << 9, block_bytes(c));
+                                       reserved = clamp(reserved_offset, offset, offset + len) - offset;
+
+                                       if (!reserved) {
+                                               bch2_disk_reservation_put(c, &disk_res);
+                                               return -BCH_ERR_ENOSPC_disk_reservation;
+                                       }
+                                       break;
+                               }
+                               quota_sectors += s->s[i].state == SECTOR_unallocated;
+                       }
+               }
        }
 
        if (quota_sectors) {
                ret = bch2_quota_reservation_add(c, inode, &res->quota, quota_sectors, true);
                if (unlikely(ret)) {
-                       struct disk_reservation tmp = { .sectors = disk_sectors };
-
-                       bch2_disk_reservation_put(c, &tmp);
-                       res->disk.sectors -= disk_sectors;
+                       bch2_disk_reservation_put(c, &disk_res);
                        return ret;
                }
        }
 
-       return 0;
+       res->disk.sectors += disk_res.sectors;
+       return partial ? reserved : 0;
 }
 
-ssize_t bch2_folio_reservation_get_partial(struct bch_fs *c,
+int bch2_folio_reservation_get(struct bch_fs *c,
                        struct bch_inode_info *inode,
                        struct folio *folio,
                        struct bch2_folio_reservation *res,
                        size_t offset, size_t len)
 {
-       size_t l, reserved = 0;
-       int ret;
-
-       while ((l = len - reserved)) {
-               while ((ret = bch2_folio_reservation_get(c, inode, folio, res, offset, l))) {
-                       if ((offset & (block_bytes(c) - 1)) + l <= block_bytes(c))
-                               return reserved ?: ret;
-
-                       len = reserved + l;
-                       l /= 2;
-               }
-
-               offset += l;
-               reserved += l;
-       }
+       return __bch2_folio_reservation_get(c, inode, folio, res, offset, len, false);
+}
 
-       return reserved;
+ssize_t bch2_folio_reservation_get_partial(struct bch_fs *c,
+                       struct bch_inode_info *inode,
+                       struct folio *folio,
+                       struct bch2_folio_reservation *res,
+                       size_t offset, size_t len)
+{
+       return __bch2_folio_reservation_get(c, inode, folio, res, offset, len, true);
 }
 
 static void bch2_clear_folio_bits(struct folio *folio)
index 71d0fa3875094b3b98d946273148f25cef5a778a..2456c41b215ee019bc359dab7d7b998a309219c9 100644 (file)
@@ -182,7 +182,7 @@ static int bch2_flush_inode(struct bch_fs *c,
 
        struct bch_inode_unpacked u;
        int ret = bch2_inode_find_by_inum(c, inode_inum(inode), &u) ?:
-                 bch2_journal_flush_seq(&c->journal, u.bi_journal_seq) ?:
+                 bch2_journal_flush_seq(&c->journal, u.bi_journal_seq, TASK_INTERRUPTIBLE) ?:
                  bch2_inode_flush_nocow_writes(c, inode);
        bch2_write_ref_put(c, BCH_WRITE_REF_fsync);
        return ret;
@@ -587,7 +587,7 @@ static noinline int __bchfs_fallocate(struct bch_inode_info *inode, int mode,
                        POS(inode->v.i_ino, start_sector),
                        BTREE_ITER_slots|BTREE_ITER_intent);
 
-       while (!ret && bkey_lt(iter.pos, end_pos)) {
+       while (!ret) {
                s64 i_sectors_delta = 0;
                struct quota_res quota_res = { 0 };
                struct bkey_s_c k;
@@ -598,6 +598,9 @@ static noinline int __bchfs_fallocate(struct bch_inode_info *inode, int mode,
 
                bch2_trans_begin(trans);
 
+               if (bkey_ge(iter.pos, end_pos))
+                       break;
+
                ret = bch2_subvolume_get_snapshot(trans,
                                        inode->ei_inum.subvol, &snapshot);
                if (ret)
@@ -634,12 +637,15 @@ static noinline int __bchfs_fallocate(struct bch_inode_info *inode, int mode,
                        if (bch2_clamp_data_hole(&inode->v,
                                                 &hole_start,
                                                 &hole_end,
-                                                opts.data_replicas, true))
+                                                opts.data_replicas, true)) {
                                ret = drop_locks_do(trans,
                                        (bch2_clamp_data_hole(&inode->v,
                                                              &hole_start,
                                                              &hole_end,
                                                              opts.data_replicas, false), 0));
+                               if (ret)
+                                       goto bkey_err;
+                       }
                        bch2_btree_iter_set_pos(&iter, POS(iter.pos.inode, hole_start));
 
                        if (ret)
@@ -667,10 +673,13 @@ static noinline int __bchfs_fallocate(struct bch_inode_info *inode, int mode,
                bch2_i_sectors_acct(c, inode, &quota_res, i_sectors_delta);
 
                if (bch2_mark_pagecache_reserved(inode, &hole_start,
-                                                iter.pos.offset, true))
-                       drop_locks_do(trans,
+                                                iter.pos.offset, true)) {
+                       ret = drop_locks_do(trans,
                                bch2_mark_pagecache_reserved(inode, &hole_start,
                                                             iter.pos.offset, false));
+                       if (ret)
+                               goto bkey_err;
+               }
 bkey_err:
                bch2_quota_reservation_put(c, inode, &quota_res);
                if (bch2_err_matches(ret, BCH_ERR_transaction_restart))
index 4a1bb07a2574481e9bbffcd4d32c7dbf7ffb3929..a41d0d8a2f7beb8c281f32489ba5b76b7cf1ba77 100644 (file)
@@ -157,6 +157,20 @@ static bool subvol_inum_eq(subvol_inum a, subvol_inum b)
        return a.subvol == b.subvol && a.inum == b.inum;
 }
 
+static u32 bch2_vfs_inode_hash_fn(const void *data, u32 len, u32 seed)
+{
+       const subvol_inum *inum = data;
+
+       return jhash(&inum->inum, sizeof(inum->inum), seed);
+}
+
+static u32 bch2_vfs_inode_obj_hash_fn(const void *data, u32 len, u32 seed)
+{
+       const struct bch_inode_info *inode = data;
+
+       return bch2_vfs_inode_hash_fn(&inode->ei_inum, sizeof(inode->ei_inum), seed);
+}
+
 static int bch2_vfs_inode_cmp_fn(struct rhashtable_compare_arg *arg,
                                 const void *obj)
 {
@@ -170,26 +184,111 @@ static const struct rhashtable_params bch2_vfs_inodes_params = {
        .head_offset            = offsetof(struct bch_inode_info, hash),
        .key_offset             = offsetof(struct bch_inode_info, ei_inum),
        .key_len                = sizeof(subvol_inum),
+       .hashfn                 = bch2_vfs_inode_hash_fn,
+       .obj_hashfn             = bch2_vfs_inode_obj_hash_fn,
        .obj_cmpfn              = bch2_vfs_inode_cmp_fn,
        .automatic_shrinking    = true,
 };
 
-static void __wait_on_freeing_inode(struct inode *inode)
+int bch2_inode_or_descendents_is_open(struct btree_trans *trans, struct bpos p)
 {
-       wait_queue_head_t *wq;
-       DEFINE_WAIT_BIT(wait, &inode->i_state, __I_NEW);
-       wq = bit_waitqueue(&inode->i_state, __I_NEW);
-       prepare_to_wait(wq, &wait.wq_entry, TASK_UNINTERRUPTIBLE);
-       spin_unlock(&inode->i_lock);
-       schedule();
-       finish_wait(wq, &wait.wq_entry);
+       struct bch_fs *c = trans->c;
+       struct rhashtable *ht = &c->vfs_inodes_table;
+       subvol_inum inum = (subvol_inum) { .inum = p.offset };
+       DARRAY(u32) subvols;
+       int ret = 0;
+
+       if (!test_bit(BCH_FS_started, &c->flags))
+               return false;
+
+       darray_init(&subvols);
+restart_from_top:
+
+       /*
+        * Tweaked version of __rhashtable_lookup(); we need to get a list of
+        * subvolumes in which the given inode number is open.
+        *
+        * For this to work, we don't include the subvolume ID in the key that
+        * we hash - all inodes with the same inode number regardless of
+        * subvolume will hash to the same slot.
+        *
+        * This will be less than ideal if the same file is ever open
+        * simultaneously in many different snapshots:
+        */
+       rcu_read_lock();
+       struct rhash_lock_head __rcu *const *bkt;
+       struct rhash_head *he;
+       unsigned int hash;
+       struct bucket_table *tbl = rht_dereference_rcu(ht->tbl, ht);
+restart:
+       hash = rht_key_hashfn(ht, tbl, &inum, bch2_vfs_inodes_params);
+       bkt = rht_bucket(tbl, hash);
+       do {
+               struct bch_inode_info *inode;
+
+               rht_for_each_entry_rcu_from(inode, he, rht_ptr_rcu(bkt), tbl, hash, hash) {
+                       if (inode->ei_inum.inum == inum.inum) {
+                               ret = darray_push_gfp(&subvols, inode->ei_inum.subvol,
+                                                     GFP_NOWAIT|__GFP_NOWARN);
+                               if (ret) {
+                                       rcu_read_unlock();
+                                       ret = darray_make_room(&subvols, 1);
+                                       if (ret)
+                                               goto err;
+                                       subvols.nr = 0;
+                                       goto restart_from_top;
+                               }
+                       }
+               }
+               /* An object might have been moved to a different hash chain,
+                * while we walk along it - better check and retry.
+                */
+       } while (he != RHT_NULLS_MARKER(bkt));
+
+       /* Ensure we see any new tables. */
+       smp_rmb();
+
+       tbl = rht_dereference_rcu(tbl->future_tbl, ht);
+       if (unlikely(tbl))
+               goto restart;
+       rcu_read_unlock();
+
+       darray_for_each(subvols, i) {
+               u32 snap;
+               ret = bch2_subvolume_get_snapshot(trans, *i, &snap);
+               if (ret)
+                       goto err;
+
+               ret = bch2_snapshot_is_ancestor(c, snap, p.snapshot);
+               if (ret)
+                       break;
+       }
+err:
+       darray_exit(&subvols);
+       return ret;
 }
 
-struct bch_inode_info *__bch2_inode_hash_find(struct bch_fs *c, subvol_inum inum)
+static struct bch_inode_info *__bch2_inode_hash_find(struct bch_fs *c, subvol_inum inum)
 {
        return rhashtable_lookup_fast(&c->vfs_inodes_table, &inum, bch2_vfs_inodes_params);
 }
 
+static void __wait_on_freeing_inode(struct bch_fs *c,
+                                   struct bch_inode_info *inode,
+                                   subvol_inum inum)
+{
+       wait_queue_head_t *wq;
+       struct wait_bit_queue_entry wait;
+
+       wq = inode_bit_waitqueue(&wait, &inode->v, __I_NEW);
+       prepare_to_wait(wq, &wait.wq_entry, TASK_UNINTERRUPTIBLE);
+       spin_unlock(&inode->v.i_lock);
+
+       if (__bch2_inode_hash_find(c, inum) == inode)
+               schedule_timeout(HZ * 10);
+       finish_wait(wq, &wait.wq_entry);
+}
+
 static struct bch_inode_info *bch2_inode_hash_find(struct bch_fs *c, struct btree_trans *trans,
                                                   subvol_inum inum)
 {
@@ -204,10 +303,10 @@ repeat:
                }
                if ((inode->v.i_state & (I_FREEING|I_WILL_FREE))) {
                        if (!trans) {
-                               __wait_on_freeing_inode(&inode->v);
+                               __wait_on_freeing_inode(c, inode, inum);
                        } else {
                                bch2_trans_unlock(trans);
-                               __wait_on_freeing_inode(&inode->v);
+                               __wait_on_freeing_inode(c, inode, inum);
                                int ret = bch2_trans_relock(trans);
                                if (ret)
                                        return ERR_PTR(ret);
@@ -232,6 +331,11 @@ static void bch2_inode_hash_remove(struct bch_fs *c, struct bch_inode_info *inod
                                        &inode->hash, bch2_vfs_inodes_params);
                BUG_ON(ret);
                inode->v.i_hash.pprev = NULL;
+               /*
+                * This pairs with the bch2_inode_hash_find() ->
+                * __wait_on_freeing_inode() path
+                */
+               inode_wake_up_bit(&inode->v, __I_NEW);
        }
 }
 
@@ -243,7 +347,8 @@ static struct bch_inode_info *bch2_inode_hash_insert(struct bch_fs *c,
 
        set_bit(EI_INODE_HASHED, &inode->ei_flags);
 retry:
-       if (unlikely(rhashtable_lookup_insert_fast(&c->vfs_inodes_table,
+       if (unlikely(rhashtable_lookup_insert_key(&c->vfs_inodes_table,
+                                       &inode->ei_inum,
                                        &inode->hash,
                                        bch2_vfs_inodes_params))) {
                old = bch2_inode_hash_find(c, trans, inode->ei_inum);
@@ -291,10 +396,10 @@ static struct inode *bch2_alloc_inode(struct super_block *sb)
        BUG();
 }
 
-static struct bch_inode_info *__bch2_new_inode(struct bch_fs *c)
+static struct bch_inode_info *__bch2_new_inode(struct bch_fs *c, gfp_t gfp)
 {
        struct bch_inode_info *inode = alloc_inode_sb(c->vfs_sb,
-                                               bch2_inode_cache, GFP_NOFS);
+                                               bch2_inode_cache, gfp);
        if (!inode)
                return NULL;
 
@@ -306,7 +411,7 @@ static struct bch_inode_info *__bch2_new_inode(struct bch_fs *c)
        mutex_init(&inode->ei_quota_lock);
        memset(&inode->ei_devs_need_flush, 0, sizeof(inode->ei_devs_need_flush));
 
-       if (unlikely(inode_init_always(c->vfs_sb, &inode->v))) {
+       if (unlikely(inode_init_always_gfp(c->vfs_sb, &inode->v, gfp))) {
                kmem_cache_free(bch2_inode_cache, inode);
                return NULL;
        }
@@ -319,12 +424,10 @@ static struct bch_inode_info *__bch2_new_inode(struct bch_fs *c)
  */
 static struct bch_inode_info *bch2_new_inode(struct btree_trans *trans)
 {
-       struct bch_inode_info *inode =
-               memalloc_flags_do(PF_MEMALLOC_NORECLAIM|PF_MEMALLOC_NOWARN,
-                                 __bch2_new_inode(trans->c));
+       struct bch_inode_info *inode = __bch2_new_inode(trans->c, GFP_NOWAIT);
 
        if (unlikely(!inode)) {
-               int ret = drop_locks_do(trans, (inode = __bch2_new_inode(trans->c)) ? 0 : -ENOMEM);
+               int ret = drop_locks_do(trans, (inode = __bch2_new_inode(trans->c, GFP_NOFS)) ? 0 : -ENOMEM);
                if (ret && inode) {
                        __destroy_inode(&inode->v);
                        kmem_cache_free(bch2_inode_cache, inode);
@@ -398,7 +501,7 @@ __bch2_create(struct mnt_idmap *idmap,
        if (ret)
                return ERR_PTR(ret);
 #endif
-       inode = __bch2_new_inode(c);
+       inode = __bch2_new_inode(c, GFP_NOFS);
        if (unlikely(!inode)) {
                inode = ERR_PTR(-ENOMEM);
                goto err;
@@ -553,7 +656,7 @@ static struct dentry *bch2_lookup(struct inode *vdir, struct dentry *dentry,
        struct bch_hash_info hash = bch2_hash_info_init(c, &dir->ei_inode);
 
        struct bch_inode_info *inode;
-       bch2_trans_do(c, NULL, NULL, 0,
+       bch2_trans_do(c,
                PTR_ERR_OR_ZERO(inode = bch2_lookup_trans(trans, inode_inum(dir),
                                                          &hash, &dentry->d_name)));
        if (IS_ERR(inode))
@@ -766,7 +869,7 @@ static int bch2_rename2(struct mnt_idmap *idmap,
        ret   = bch2_subvol_is_ro_trans(trans, src_dir->ei_inum.subvol) ?:
                bch2_subvol_is_ro_trans(trans, dst_dir->ei_inum.subvol);
        if (ret)
-               goto err;
+               goto err_tx_restart;
 
        if (inode_attr_changing(dst_dir, src_inode, Inode_opt_project)) {
                ret = bch2_fs_quota_transfer(c, src_inode,
@@ -1163,7 +1266,7 @@ static int bch2_fiemap(struct inode *vinode, struct fiemap_extent_info *info,
        bch2_trans_iter_init(trans, &iter, BTREE_ID_extents,
                             POS(ei->v.i_ino, start), 0);
 
-       while (true) {
+       while (!ret || bch2_err_matches(ret, BCH_ERR_transaction_restart)) {
                enum btree_id data_btree = BTREE_ID_extents;
 
                bch2_trans_begin(trans);
@@ -1171,14 +1274,14 @@ static int bch2_fiemap(struct inode *vinode, struct fiemap_extent_info *info,
                u32 snapshot;
                ret = bch2_subvolume_get_snapshot(trans, ei->ei_inum.subvol, &snapshot);
                if (ret)
-                       goto err;
+                       continue;
 
                bch2_btree_iter_set_snapshot(&iter, snapshot);
 
                k = bch2_btree_iter_peek_upto(&iter, end);
                ret = bkey_err(k);
                if (ret)
-                       goto err;
+                       continue;
 
                if (!k.k)
                        break;
@@ -1198,7 +1301,7 @@ static int bch2_fiemap(struct inode *vinode, struct fiemap_extent_info *info,
                ret = bch2_read_indirect_extent(trans, &data_btree,
                                        &offset_into_extent, &cur);
                if (ret)
-                       break;
+                       continue;
 
                k = bkey_i_to_s_c(cur.k);
                bch2_bkey_buf_realloc(&prev, c, k.k->u64s);
@@ -1226,10 +1329,6 @@ static int bch2_fiemap(struct inode *vinode, struct fiemap_extent_info *info,
 
                bch2_btree_iter_set_pos(&iter,
                        POS(iter.pos.inode, iter.pos.offset + sectors));
-err:
-               if (ret &&
-                   !bch2_err_matches(ret, BCH_ERR_transaction_restart))
-                       break;
        }
        bch2_trans_iter_exit(trans, &iter);
 
@@ -1937,7 +2036,7 @@ static int bch2_show_options(struct seq_file *seq, struct dentry *root)
        bch2_opts_to_text(&buf, c->opts, c, c->disk_sb.sb,
                          OPT_MOUNT, OPT_HIDDEN, OPT_SHOW_MOUNT_STYLE);
        printbuf_nul_terminate(&buf);
-       seq_puts(seq, buf.buf);
+       seq_printf(seq, ",%s", buf.buf);
 
        int ret = buf.allocation_failure ? -ENOMEM : 0;
        printbuf_exit(&buf);
index da74ecc236e7d619366c35cbc8b7445f18eb5374..59f9f7ae728d2a1f6cbf7516cd93c999b8005ad3 100644 (file)
@@ -54,8 +54,6 @@ static inline subvol_inum inode_inum(struct bch_inode_info *inode)
        return inode->ei_inum;
 }
 
-struct bch_inode_info *__bch2_inode_hash_find(struct bch_fs *, subvol_inum);
-
 /*
  * Set if we've gotten a btree error for this inode, and thus the vfs inode and
  * btree inode may be inconsistent:
@@ -148,6 +146,8 @@ struct bch_inode_info *
 __bch2_create(struct mnt_idmap *, struct bch_inode_info *,
              struct dentry *, umode_t, dev_t, subvol_inum, unsigned);
 
+int bch2_inode_or_descendents_is_open(struct btree_trans *trans, struct bpos p);
+
 int bch2_fs_quota_transfer(struct bch_fs *,
                           struct bch_inode_info *,
                           struct bch_qid,
@@ -198,10 +198,7 @@ int bch2_vfs_init(void);
 
 #define bch2_inode_update_after_write(_trans, _inode, _inode_u, _fields)       ({ do {} while (0); })
 
-static inline struct bch_inode_info *__bch2_inode_hash_find(struct bch_fs *c, subvol_inum inum)
-{
-       return NULL;
-}
+static inline int bch2_inode_or_descendents_is_open(struct btree_trans *trans, struct bpos p) { return 0; }
 
 static inline void bch2_evict_subvolume_inodes(struct bch_fs *c,
                                               snapshot_id_list *s) {}
index 0d8b782b63fb63045f64e93aa1295fb8497f7b10..75c8a97a6954c6a91f8a6b9d6d28f181ac69c8e4 100644 (file)
@@ -28,8 +28,8 @@ static bool inode_points_to_dirent(struct bch_inode_unpacked *inode,
                inode->bi_dir_offset    == d.k->p.offset;
 }
 
-static bool dirent_points_to_inode_nowarn(struct bkey_s_c_dirent d,
-                                  struct bch_inode_unpacked *inode)
+static int dirent_points_to_inode_nowarn(struct bkey_s_c_dirent d,
+                                        struct bch_inode_unpacked *inode)
 {
        if (d.v->d_type == DT_SUBVOL
            ? le32_to_cpu(d.v->d_child_subvol)  == inode->bi_subvol
@@ -137,16 +137,15 @@ found:
        return ret;
 }
 
-static int lookup_inode(struct btree_trans *trans, u64 inode_nr,
-                       struct bch_inode_unpacked *inode,
-                       u32 *snapshot)
+static int lookup_inode(struct btree_trans *trans, u64 inode_nr, u32 snapshot,
+                       struct bch_inode_unpacked *inode)
 {
        struct btree_iter iter;
        struct bkey_s_c k;
        int ret;
 
        k = bch2_bkey_get_iter(trans, &iter, BTREE_ID_inodes,
-                              SPOS(0, inode_nr, *snapshot), 0);
+                              SPOS(0, inode_nr, snapshot), 0);
        ret = bkey_err(k);
        if (ret)
                goto err;
@@ -154,8 +153,6 @@ static int lookup_inode(struct btree_trans *trans, u64 inode_nr,
        ret = bkey_is_inode(k.k)
                ? bch2_inode_unpack(k, inode)
                : -BCH_ERR_ENOENT_inode;
-       if (!ret)
-               *snapshot = iter.pos.snapshot;
 err:
        bch2_trans_iter_exit(trans, &iter);
        return ret;
@@ -250,8 +247,7 @@ static int lookup_lostfound(struct btree_trans *trans, u32 snapshot,
 
        struct bch_inode_unpacked root_inode;
        struct bch_hash_info root_hash_info;
-       u32 root_inode_snapshot = snapshot;
-       ret = lookup_inode(trans, root_inum.inum, &root_inode, &root_inode_snapshot);
+       ret = lookup_inode(trans, root_inum.inum, snapshot, &root_inode);
        bch_err_msg(c, ret, "looking up root inode %llu for subvol %u",
                    root_inum.inum, le32_to_cpu(st.master_subvol));
        if (ret)
@@ -277,17 +273,23 @@ static int lookup_lostfound(struct btree_trans *trans, u32 snapshot,
         * The bch2_check_dirents pass has already run, dangling dirents
         * shouldn't exist here:
         */
-       ret = lookup_inode(trans, inum, lostfound, &snapshot);
+       ret = lookup_inode(trans, inum, snapshot, lostfound);
        bch_err_msg(c, ret, "looking up lost+found %llu:%u in (root inode %llu, snapshot root %u)",
                    inum, snapshot, root_inum.inum, bch2_snapshot_root(c, snapshot));
        return ret;
 
 create_lostfound:
+       /*
+        * we always create lost+found in the root snapshot; we don't want
+        * different branches of the snapshot tree to have different lost+found
+        */
+       snapshot = le32_to_cpu(st.root_snapshot);
        /*
         * XXX: we could have a nicer log message here  if we had a nice way to
         * walk backpointers to print a path
         */
-       bch_notice(c, "creating lost+found in snapshot %u", le32_to_cpu(st.root_snapshot));
+       bch_notice(c, "creating lost+found in subvol %llu snapshot %u",
+                  root_inum.subvol, le32_to_cpu(st.root_snapshot));
 
        u64 now = bch2_current_time(c);
        struct btree_iter lostfound_iter = { NULL };
@@ -296,6 +298,7 @@ create_lostfound:
        bch2_inode_init_early(c, lostfound);
        bch2_inode_init_late(lostfound, now, 0, 0, S_IFDIR|0700, 0, &root_inode);
        lostfound->bi_dir = root_inode.bi_inum;
+       lostfound->bi_snapshot = le32_to_cpu(st.root_snapshot);
 
        root_inode.bi_nlink++;
 
@@ -323,19 +326,54 @@ err:
        return ret;
 }
 
-static int reattach_inode(struct btree_trans *trans,
-                         struct bch_inode_unpacked *inode,
-                         u32 inode_snapshot)
+static inline bool inode_should_reattach(struct bch_inode_unpacked *inode)
+{
+       if (inode->bi_inum == BCACHEFS_ROOT_INO &&
+           inode->bi_subvol == BCACHEFS_ROOT_SUBVOL)
+               return false;
+
+       return !inode->bi_dir && !(inode->bi_flags & BCH_INODE_unlinked);
+}
+
+static int maybe_delete_dirent(struct btree_trans *trans, struct bpos d_pos, u32 snapshot)
+{
+       struct btree_iter iter;
+       struct bkey_s_c k = bch2_bkey_get_iter(trans, &iter, BTREE_ID_dirents,
+                                       SPOS(d_pos.inode, d_pos.offset, snapshot),
+                                       BTREE_ITER_intent|
+                                       BTREE_ITER_with_updates);
+       int ret = bkey_err(k);
+       if (ret)
+               return ret;
+
+       if (bpos_eq(k.k->p, d_pos)) {
+               /*
+                * delet_at() doesn't work because the update path doesn't
+                * internally use BTREE_ITER_with_updates yet
+                */
+               struct bkey_i *k = bch2_trans_kmalloc(trans, sizeof(*k));
+               ret = PTR_ERR_OR_ZERO(k);
+               if (ret)
+                       goto err;
+
+               bkey_init(&k->k);
+               k->k.type = KEY_TYPE_whiteout;
+               k->k.p = iter.pos;
+               ret = bch2_trans_update(trans, &iter, k, BTREE_UPDATE_internal_snapshot_node);
+       }
+err:
+       bch2_trans_iter_exit(trans, &iter);
+       return ret;
+}
+
+static int reattach_inode(struct btree_trans *trans, struct bch_inode_unpacked *inode)
 {
        struct bch_fs *c = trans->c;
-       struct bch_hash_info dir_hash;
        struct bch_inode_unpacked lostfound;
        char name_buf[20];
-       struct qstr name;
-       u64 dir_offset = 0;
-       u32 dirent_snapshot = inode_snapshot;
        int ret;
 
+       u32 dirent_snapshot = inode->bi_snapshot;
        if (inode->bi_subvol) {
                inode->bi_parent_subvol = BCACHEFS_ROOT_SUBVOL;
 
@@ -354,17 +392,22 @@ static int reattach_inode(struct btree_trans *trans,
        if (ret)
                return ret;
 
-       if (S_ISDIR(inode->bi_mode)) {
-               lostfound.bi_nlink++;
+       lostfound.bi_nlink += S_ISDIR(inode->bi_mode);
 
-               ret = __bch2_fsck_write_inode(trans, &lostfound, U32_MAX);
-               if (ret)
-                       return ret;
+       /* ensure lost+found inode is also present in inode snapshot */
+       if (!inode->bi_subvol) {
+               BUG_ON(!bch2_snapshot_is_ancestor(c, inode->bi_snapshot, lostfound.bi_snapshot));
+               lostfound.bi_snapshot = inode->bi_snapshot;
        }
 
-       dir_hash = bch2_hash_info_init(c, &lostfound);
+       ret = __bch2_fsck_write_inode(trans, &lostfound);
+       if (ret)
+               return ret;
+
+       struct bch_hash_info dir_hash = bch2_hash_info_init(c, &lostfound);
+       struct qstr name = (struct qstr) QSTR(name_buf);
 
-       name = (struct qstr) QSTR(name_buf);
+       inode->bi_dir = lostfound.bi_inum;
 
        ret = bch2_dirent_create_snapshot(trans,
                                inode->bi_parent_subvol, lostfound.bi_inum,
@@ -373,17 +416,70 @@ static int reattach_inode(struct btree_trans *trans,
                                inode_d_type(inode),
                                &name,
                                inode->bi_subvol ?: inode->bi_inum,
-                               &dir_offset,
+                               &inode->bi_dir_offset,
                                STR_HASH_must_create);
        if (ret) {
                bch_err_msg(c, ret, "error creating dirent");
                return ret;
        }
 
-       inode->bi_dir           = lostfound.bi_inum;
-       inode->bi_dir_offset    = dir_offset;
+       ret = __bch2_fsck_write_inode(trans, inode);
+       if (ret)
+               return ret;
+
+       /*
+        * Fix up inodes in child snapshots: if they should also be reattached
+        * update the backpointer field, if they should not be we need to emit
+        * whiteouts for the dirent we just created.
+        */
+       if (!inode->bi_subvol && bch2_snapshot_is_leaf(c, inode->bi_snapshot) <= 0) {
+               snapshot_id_list whiteouts_done;
+               struct btree_iter iter;
+               struct bkey_s_c k;
+
+               darray_init(&whiteouts_done);
+
+               for_each_btree_key_reverse_norestart(trans, iter,
+                               BTREE_ID_inodes, SPOS(0, inode->bi_inum, inode->bi_snapshot - 1),
+                               BTREE_ITER_all_snapshots|BTREE_ITER_intent, k, ret) {
+                       if (k.k->p.offset != inode->bi_inum)
+                               break;
+
+                       if (!bkey_is_inode(k.k) ||
+                           !bch2_snapshot_is_ancestor(c, k.k->p.snapshot, inode->bi_snapshot) ||
+                           snapshot_list_has_ancestor(c, &whiteouts_done, k.k->p.snapshot))
+                               continue;
+
+                       struct bch_inode_unpacked child_inode;
+                       bch2_inode_unpack(k, &child_inode);
+
+                       if (!inode_should_reattach(&child_inode)) {
+                               ret = maybe_delete_dirent(trans,
+                                                         SPOS(lostfound.bi_inum, inode->bi_dir_offset,
+                                                              dirent_snapshot),
+                                                         k.k->p.snapshot);
+                               if (ret)
+                                       break;
+
+                               ret = snapshot_list_add(c, &whiteouts_done, k.k->p.snapshot);
+                               if (ret)
+                                       break;
+                       } else {
+                               iter.snapshot = k.k->p.snapshot;
+                               child_inode.bi_dir = inode->bi_dir;
+                               child_inode.bi_dir_offset = inode->bi_dir_offset;
+
+                               ret = bch2_inode_write_flags(trans, &iter, &child_inode,
+                                                            BTREE_UPDATE_internal_snapshot_node);
+                               if (ret)
+                                       break;
+                       }
+               }
+               darray_exit(&whiteouts_done);
+               bch2_trans_iter_exit(trans, &iter);
+       }
 
-       return __bch2_fsck_write_inode(trans, inode, inode_snapshot);
+       return ret;
 }
 
 static int remove_backpointer(struct btree_trans *trans,
@@ -422,7 +518,7 @@ static int reattach_subvol(struct btree_trans *trans, struct bkey_s_c_subvolume
        if (ret)
                return ret;
 
-       ret = reattach_inode(trans, &inode, le32_to_cpu(s.v->snapshot));
+       ret = reattach_inode(trans, &inode);
        bch_err_msg(c, ret, "reattaching inode %llu", inode.bi_inum);
        return ret;
 }
@@ -540,8 +636,9 @@ static int reconstruct_inode(struct btree_trans *trans, enum btree_id btree, u32
        bch2_inode_init_late(&new_inode, bch2_current_time(c), 0, 0, i_mode|0600, 0, NULL);
        new_inode.bi_size = i_size;
        new_inode.bi_inum = inum;
+       new_inode.bi_snapshot = snapshot;
 
-       return __bch2_fsck_write_inode(trans, &new_inode, snapshot);
+       return __bch2_fsck_write_inode(trans, &new_inode);
 }
 
 struct snapshots_seen {
@@ -832,35 +929,138 @@ static int get_visible_inodes(struct btree_trans *trans,
        return ret;
 }
 
-static int hash_redo_key(struct btree_trans *trans,
-                        const struct bch_hash_desc desc,
-                        struct bch_hash_info *hash_info,
-                        struct btree_iter *k_iter, struct bkey_s_c k)
+static int dirent_has_target(struct btree_trans *trans, struct bkey_s_c_dirent d)
 {
-       struct bkey_i *delete;
-       struct bkey_i *tmp;
+       if (d.v->d_type == DT_SUBVOL) {
+               u32 snap;
+               u64 inum;
+               int ret = subvol_lookup(trans, le32_to_cpu(d.v->d_child_subvol), &snap, &inum);
+               if (ret && !bch2_err_matches(ret, ENOENT))
+                       return ret;
+               return !ret;
+       } else {
+               struct btree_iter iter;
+               struct bkey_s_c k = bch2_bkey_get_iter(trans, &iter, BTREE_ID_inodes,
+                               SPOS(0, le64_to_cpu(d.v->d_inum), d.k->p.snapshot), 0);
+               int ret = bkey_err(k);
+               if (ret)
+                       return ret;
+
+               ret = bkey_is_inode(k.k);
+               bch2_trans_iter_exit(trans, &iter);
+               return ret;
+       }
+}
 
-       delete = bch2_trans_kmalloc(trans, sizeof(*delete));
-       if (IS_ERR(delete))
-               return PTR_ERR(delete);
+/*
+ * Prefer to delete the first one, since that will be the one at the wrong
+ * offset:
+ * return value: 0 -> delete k1, 1 -> delete k2
+ */
+static int hash_pick_winner(struct btree_trans *trans,
+                           const struct bch_hash_desc desc,
+                           struct bch_hash_info *hash_info,
+                           struct bkey_s_c k1,
+                           struct bkey_s_c k2)
+{
+       if (bkey_val_bytes(k1.k) == bkey_val_bytes(k2.k) &&
+           !memcmp(k1.v, k2.v, bkey_val_bytes(k1.k)))
+               return 0;
 
-       tmp = bch2_bkey_make_mut_noupdate(trans, k);
-       if (IS_ERR(tmp))
-               return PTR_ERR(tmp);
+       switch (desc.btree_id) {
+       case BTREE_ID_dirents: {
+               int ret = dirent_has_target(trans, bkey_s_c_to_dirent(k1));
+               if (ret < 0)
+                       return ret;
+               if (!ret)
+                       return 0;
 
-       bkey_init(&delete->k);
-       delete->k.p = k_iter->pos;
-       return  bch2_btree_iter_traverse(k_iter) ?:
-               bch2_trans_update(trans, k_iter, delete, 0) ?:
-               bch2_hash_set_in_snapshot(trans, desc, hash_info,
-                                      (subvol_inum) { 0, k.k->p.inode },
-                                      k.k->p.snapshot, tmp,
-                                      STR_HASH_must_create|
-                                      BTREE_UPDATE_internal_snapshot_node) ?:
-               bch2_trans_commit(trans, NULL, NULL, BCH_TRANS_COMMIT_no_enospc);
+               ret = dirent_has_target(trans, bkey_s_c_to_dirent(k2));
+               if (ret < 0)
+                       return ret;
+               if (!ret)
+                       return 1;
+               return 2;
+       }
+       default:
+               return 0;
+       }
+}
+
+static int fsck_update_backpointers(struct btree_trans *trans,
+                                   struct snapshots_seen *s,
+                                   const struct bch_hash_desc desc,
+                                   struct bch_hash_info *hash_info,
+                                   struct bkey_i *new)
+{
+       if (new->k.type != KEY_TYPE_dirent)
+               return 0;
+
+       struct bkey_i_dirent *d = bkey_i_to_dirent(new);
+       struct inode_walker target = inode_walker_init();
+       int ret = 0;
+
+       if (d->v.d_type == DT_SUBVOL) {
+               BUG();
+       } else {
+               ret = get_visible_inodes(trans, &target, s, le64_to_cpu(d->v.d_inum));
+               if (ret)
+                       goto err;
+
+               darray_for_each(target.inodes, i) {
+                       i->inode.bi_dir_offset = d->k.p.offset;
+                       ret = __bch2_fsck_write_inode(trans, &i->inode);
+                       if (ret)
+                               goto err;
+               }
+       }
+err:
+       inode_walker_exit(&target);
+       return ret;
+}
+
+static int fsck_rename_dirent(struct btree_trans *trans,
+                             struct snapshots_seen *s,
+                             const struct bch_hash_desc desc,
+                             struct bch_hash_info *hash_info,
+                             struct bkey_s_c_dirent old)
+{
+       struct qstr old_name = bch2_dirent_get_name(old);
+       struct bkey_i_dirent *new = bch2_trans_kmalloc(trans, bkey_bytes(old.k) + 32);
+       int ret = PTR_ERR_OR_ZERO(new);
+       if (ret)
+               return ret;
+
+       bkey_dirent_init(&new->k_i);
+       dirent_copy_target(new, old);
+       new->k.p = old.k->p;
+
+       for (unsigned i = 0; i < 1000; i++) {
+               unsigned len = sprintf(new->v.d_name, "%.*s.fsck_renamed-%u",
+                                      old_name.len, old_name.name, i);
+               unsigned u64s = BKEY_U64s + dirent_val_u64s(len);
+
+               if (u64s > U8_MAX)
+                       return -EINVAL;
+
+               new->k.u64s = u64s;
+
+               ret = bch2_hash_set_in_snapshot(trans, bch2_dirent_hash_desc, hash_info,
+                                               (subvol_inum) { 0, old.k->p.inode },
+                                               old.k->p.snapshot, &new->k_i,
+                                               BTREE_UPDATE_internal_snapshot_node);
+               if (!bch2_err_matches(ret, EEXIST))
+                       break;
+       }
+
+       if (ret)
+               return ret;
+
+       return fsck_update_backpointers(trans, s, desc, hash_info, &new->k_i);
 }
 
 static int hash_check_key(struct btree_trans *trans,
+                         struct snapshots_seen *s,
                          const struct bch_hash_desc desc,
                          struct bch_hash_info *hash_info,
                          struct btree_iter *k_iter, struct bkey_s_c hash_k)
@@ -889,16 +1089,9 @@ static int hash_check_key(struct btree_trans *trans,
                if (bkey_eq(k.k->p, hash_k.k->p))
                        break;
 
-               if (fsck_err_on(k.k->type == desc.key_type &&
-                               !desc.cmp_bkey(k, hash_k),
-                               trans, hash_table_key_duplicate,
-                               "duplicate hash table keys:\n%s",
-                               (printbuf_reset(&buf),
-                                bch2_bkey_val_to_text(&buf, c, hash_k),
-                                buf.buf))) {
-                       ret = bch2_hash_delete_at(trans, desc, hash_info, k_iter, 0) ?: 1;
-                       break;
-               }
+               if (k.k->type == desc.key_type &&
+                   !desc.cmp_bkey(k, hash_k))
+                       goto duplicate_entries;
 
                if (bkey_deleted(k.k)) {
                        bch2_trans_iter_exit(trans, &iter);
@@ -911,18 +1104,66 @@ out:
        return ret;
 bad_hash:
        if (fsck_err(trans, hash_table_key_wrong_offset,
-                    "hash table key at wrong offset: btree %s inode %llu offset %llu, hashed to %llu\n%s",
+                    "hash table key at wrong offset: btree %s inode %llu offset %llu, hashed to %llu\n  %s",
                     bch2_btree_id_str(desc.btree_id), hash_k.k->p.inode, hash_k.k->p.offset, hash,
                     (printbuf_reset(&buf),
                      bch2_bkey_val_to_text(&buf, c, hash_k), buf.buf))) {
-               ret = hash_redo_key(trans, desc, hash_info, k_iter, hash_k);
-               bch_err_fn(c, ret);
+               struct bkey_i *new = bch2_bkey_make_mut_noupdate(trans, hash_k);
+               if (IS_ERR(new))
+                       return PTR_ERR(new);
+
+               k = bch2_hash_set_or_get_in_snapshot(trans, &iter, desc, hash_info,
+                                      (subvol_inum) { 0, hash_k.k->p.inode },
+                                      hash_k.k->p.snapshot, new,
+                                      STR_HASH_must_create|
+                                      BTREE_ITER_with_updates|
+                                      BTREE_UPDATE_internal_snapshot_node);
+               ret = bkey_err(k);
                if (ret)
-                       return ret;
-               ret = -BCH_ERR_transaction_restart_nested;
+                       goto out;
+               if (k.k)
+                       goto duplicate_entries;
+
+               ret =   bch2_hash_delete_at(trans, desc, hash_info, k_iter,
+                                           BTREE_UPDATE_internal_snapshot_node) ?:
+                       fsck_update_backpointers(trans, s, desc, hash_info, new) ?:
+                       bch2_trans_commit(trans, NULL, NULL, BCH_TRANS_COMMIT_no_enospc) ?:
+                       -BCH_ERR_transaction_restart_nested;
+               goto out;
        }
 fsck_err:
        goto out;
+duplicate_entries:
+       ret = hash_pick_winner(trans, desc, hash_info, hash_k, k);
+       if (ret < 0)
+               goto out;
+
+       if (!fsck_err(trans, hash_table_key_duplicate,
+                     "duplicate hash table keys%s:\n%s",
+                     ret != 2 ? "" : ", both point to valid inodes",
+                     (printbuf_reset(&buf),
+                      bch2_bkey_val_to_text(&buf, c, hash_k),
+                      prt_newline(&buf),
+                      bch2_bkey_val_to_text(&buf, c, k),
+                      buf.buf)))
+               goto out;
+
+       switch (ret) {
+       case 0:
+               ret = bch2_hash_delete_at(trans, desc, hash_info, k_iter, 0);
+               break;
+       case 1:
+               ret = bch2_hash_delete_at(trans, desc, hash_info, &iter, 0);
+               break;
+       case 2:
+               ret = fsck_rename_dirent(trans, s, desc, hash_info, bkey_s_c_to_dirent(hash_k)) ?:
+                       bch2_hash_delete_at(trans, desc, hash_info, k_iter, 0);
+               goto out;
+       }
+
+       ret = bch2_trans_commit(trans, NULL, NULL, 0) ?:
+               -BCH_ERR_transaction_restart_nested;
+       goto out;
 }
 
 static struct bkey_s_c_dirent dirent_get_by_pos(struct btree_trans *trans,
@@ -988,7 +1229,6 @@ static int check_inode_dirent_inode(struct btree_trans *trans,
                 */
                inode->bi_dir = 0;
                inode->bi_dir_offset = 0;
-               inode->bi_flags &= ~BCH_INODE_backptr_untrusted;
                *write_inode = true;
        }
 
@@ -1000,30 +1240,40 @@ fsck_err:
        return ret;
 }
 
-static bool bch2_inode_is_open(struct bch_fs *c, struct bpos p)
+static int get_snapshot_root_inode(struct btree_trans *trans,
+                                  struct bch_inode_unpacked *root,
+                                  u64 inum)
 {
-       subvol_inum inum = {
-               .subvol = snapshot_t(c, p.snapshot)->subvol,
-               .inum   = p.offset,
-       };
+       struct btree_iter iter;
+       struct bkey_s_c k;
+       int ret = 0;
 
-       /* snapshot tree corruption, can't safely delete */
-       if (!inum.subvol) {
-               bch_warn_ratelimited(c, "%s(): snapshot %u has no subvol, unlinked but can't safely delete", __func__, p.snapshot);
-               return true;
+       for_each_btree_key_reverse_norestart(trans, iter, BTREE_ID_inodes,
+                                            SPOS(0, inum, U32_MAX),
+                                            BTREE_ITER_all_snapshots, k, ret) {
+               if (k.k->p.offset != inum)
+                       break;
+               if (bkey_is_inode(k.k))
+                       goto found_root;
        }
-
-       return __bch2_inode_hash_find(c, inum) != NULL;
+       if (ret)
+               goto err;
+       BUG();
+found_root:
+       BUG_ON(bch2_inode_unpack(k, root));
+err:
+       bch2_trans_iter_exit(trans, &iter);
+       return ret;
 }
 
 static int check_inode(struct btree_trans *trans,
                       struct btree_iter *iter,
                       struct bkey_s_c k,
-                      struct bch_inode_unpacked *prev,
-                      struct snapshots_seen *s,
-                      bool full)
+                      struct bch_inode_unpacked *snapshot_root,
+                      struct snapshots_seen *s)
 {
        struct bch_fs *c = trans->c;
+       struct printbuf buf = PRINTBUF;
        struct bch_inode_unpacked u;
        bool do_update = false;
        int ret;
@@ -1043,45 +1293,75 @@ static int check_inode(struct btree_trans *trans,
 
        BUG_ON(bch2_inode_unpack(k, &u));
 
-       if (!full &&
-           !(u.bi_flags & (BCH_INODE_i_size_dirty|
-                           BCH_INODE_i_sectors_dirty|
-                           BCH_INODE_unlinked)))
-               return 0;
-
-       if (prev->bi_inum != u.bi_inum)
-               *prev = u;
+       if (snapshot_root->bi_inum != u.bi_inum) {
+               ret = get_snapshot_root_inode(trans, snapshot_root, u.bi_inum);
+               if (ret)
+                       goto err;
+       }
 
-       if (fsck_err_on(prev->bi_hash_seed      != u.bi_hash_seed ||
-                       inode_d_type(prev)      != inode_d_type(&u),
+       if (fsck_err_on(u.bi_hash_seed          != snapshot_root->bi_hash_seed ||
+                       INODE_STR_HASH(&u)      != INODE_STR_HASH(snapshot_root),
                        trans, inode_snapshot_mismatch,
                        "inodes in different snapshots don't match")) {
-               bch_err(c, "repair not implemented yet");
-               return -BCH_ERR_fsck_repair_unimplemented;
+               u.bi_hash_seed = snapshot_root->bi_hash_seed;
+               SET_INODE_STR_HASH(&u, INODE_STR_HASH(snapshot_root));
+               do_update = true;
        }
 
-       if ((u.bi_flags & (BCH_INODE_i_size_dirty|BCH_INODE_unlinked)) &&
-           bch2_key_has_snapshot_overwrites(trans, BTREE_ID_inodes, k.k->p)) {
-               struct bpos new_min_pos;
-
-               ret = bch2_propagate_key_to_snapshot_leaves(trans, iter->btree_id, k, &new_min_pos);
+       if (u.bi_dir || u.bi_dir_offset) {
+               ret = check_inode_dirent_inode(trans, &u, &do_update);
                if (ret)
                        goto err;
+       }
 
-               u.bi_flags &= ~BCH_INODE_i_size_dirty|BCH_INODE_unlinked;
+       if (fsck_err_on(u.bi_dir && (u.bi_flags & BCH_INODE_unlinked),
+                       trans, inode_unlinked_but_has_dirent,
+                       "inode unlinked but has dirent\n%s",
+                       (printbuf_reset(&buf),
+                        bch2_inode_unpacked_to_text(&buf, &u),
+                        buf.buf))) {
+               u.bi_flags &= ~BCH_INODE_unlinked;
+               do_update = true;
+       }
 
-               ret = __bch2_fsck_write_inode(trans, &u, iter->pos.snapshot);
+       if (S_ISDIR(u.bi_mode) && (u.bi_flags & BCH_INODE_unlinked)) {
+               /* Check for this early so that check_unreachable_inode() will reattach it */
 
-               bch_err_msg(c, ret, "in fsck updating inode");
-               if (ret)
-                       return ret;
+               ret = bch2_empty_dir_snapshot(trans, k.k->p.offset, 0, k.k->p.snapshot);
+               if (ret && ret != -BCH_ERR_ENOTEMPTY_dir_not_empty)
+                       goto err;
 
-               if (!bpos_eq(new_min_pos, POS_MIN))
-                       bch2_btree_iter_set_pos(iter, bpos_predecessor(new_min_pos));
-               return 0;
+               fsck_err_on(ret, trans, inode_dir_unlinked_but_not_empty,
+                           "dir unlinked but not empty\n%s",
+                           (printbuf_reset(&buf),
+                            bch2_inode_unpacked_to_text(&buf, &u),
+                            buf.buf));
+               u.bi_flags &= ~BCH_INODE_unlinked;
+               do_update = true;
+               ret = 0;
+       }
+
+       ret = bch2_inode_has_child_snapshots(trans, k.k->p);
+       if (ret < 0)
+               goto err;
+
+       if (fsck_err_on(ret != !!(u.bi_flags & BCH_INODE_has_child_snapshot),
+                       trans, inode_has_child_snapshots_wrong,
+                       "inode has_child_snapshots flag wrong (should be %u)\n%s",
+                       ret,
+                       (printbuf_reset(&buf),
+                        bch2_inode_unpacked_to_text(&buf, &u),
+                        buf.buf))) {
+               if (ret)
+                       u.bi_flags |= BCH_INODE_has_child_snapshot;
+               else
+                       u.bi_flags &= ~BCH_INODE_has_child_snapshot;
+               do_update = true;
        }
+       ret = 0;
 
-       if (u.bi_flags & BCH_INODE_unlinked) {
+       if ((u.bi_flags & BCH_INODE_unlinked) &&
+           !(u.bi_flags & BCH_INODE_has_child_snapshot)) {
                if (!test_bit(BCH_FS_started, &c->flags)) {
                        /*
                         * If we're not in online fsck, don't delete unlinked
@@ -1095,7 +1375,7 @@ static int check_inode(struct btree_trans *trans,
                         */
                        ret = check_inode_deleted_list(trans, k.k->p);
                        if (ret < 0)
-                               return ret;
+                               goto err_noprint;
 
                        fsck_err_on(!ret,
                                    trans, unlinked_inode_not_on_deleted_list,
@@ -1106,83 +1386,22 @@ static int check_inode(struct btree_trans *trans,
                        if (ret)
                                goto err;
                } else {
-                       if (fsck_err_on(bch2_inode_is_open(c, k.k->p),
+                       ret = bch2_inode_or_descendents_is_open(trans, k.k->p);
+                       if (ret < 0)
+                               goto err;
+
+                       if (fsck_err_on(!ret,
                                        trans, inode_unlinked_and_not_open,
                                      "inode %llu%u unlinked and not open",
                                      u.bi_inum, u.bi_snapshot)) {
                                ret = bch2_inode_rm_snapshot(trans, u.bi_inum, iter->pos.snapshot);
                                bch_err_msg(c, ret, "in fsck deleting inode");
-                               return ret;
+                               goto err_noprint;
                        }
+                       ret = 0;
                }
        }
 
-       /* i_size_dirty is vestigal, since we now have logged ops for truncate * */
-       if (u.bi_flags & BCH_INODE_i_size_dirty &&
-           (!test_bit(BCH_FS_clean_recovery, &c->flags) ||
-            fsck_err(trans, inode_i_size_dirty_but_clean,
-                     "filesystem marked clean, but inode %llu has i_size dirty",
-                     u.bi_inum))) {
-               bch_verbose(c, "truncating inode %llu", u.bi_inum);
-
-               /*
-                * XXX: need to truncate partial blocks too here - or ideally
-                * just switch units to bytes and that issue goes away
-                */
-               ret = bch2_btree_delete_range_trans(trans, BTREE_ID_extents,
-                               SPOS(u.bi_inum, round_up(u.bi_size, block_bytes(c)) >> 9,
-                                    iter->pos.snapshot),
-                               POS(u.bi_inum, U64_MAX),
-                               0, NULL);
-               bch_err_msg(c, ret, "in fsck truncating inode");
-               if (ret)
-                       return ret;
-
-               /*
-                * We truncated without our normal sector accounting hook, just
-                * make sure we recalculate it:
-                */
-               u.bi_flags |= BCH_INODE_i_sectors_dirty;
-
-               u.bi_flags &= ~BCH_INODE_i_size_dirty;
-               do_update = true;
-       }
-
-       /* i_sectors_dirty is vestigal, i_sectors is always updated transactionally */
-       if (u.bi_flags & BCH_INODE_i_sectors_dirty &&
-           (!test_bit(BCH_FS_clean_recovery, &c->flags) ||
-            fsck_err(trans, inode_i_sectors_dirty_but_clean,
-                     "filesystem marked clean, but inode %llu has i_sectors dirty",
-                     u.bi_inum))) {
-               s64 sectors;
-
-               bch_verbose(c, "recounting sectors for inode %llu",
-                           u.bi_inum);
-
-               sectors = bch2_count_inode_sectors(trans, u.bi_inum, iter->pos.snapshot);
-               if (sectors < 0) {
-                       bch_err_msg(c, sectors, "in fsck recounting inode sectors");
-                       return sectors;
-               }
-
-               u.bi_sectors = sectors;
-               u.bi_flags &= ~BCH_INODE_i_sectors_dirty;
-               do_update = true;
-       }
-
-       if (u.bi_flags & BCH_INODE_backptr_untrusted) {
-               u.bi_dir = 0;
-               u.bi_dir_offset = 0;
-               u.bi_flags &= ~BCH_INODE_backptr_untrusted;
-               do_update = true;
-       }
-
-       if (u.bi_dir || u.bi_dir_offset) {
-               ret = check_inode_dirent_inode(trans, &u, &do_update);
-               if (ret)
-                       goto err;
-       }
-
        if (fsck_err_on(u.bi_parent_subvol &&
                        (u.bi_subvol == 0 ||
                         u.bi_subvol == BCACHEFS_ROOT_SUBVOL),
@@ -1224,21 +1443,22 @@ static int check_inode(struct btree_trans *trans,
        }
 do_update:
        if (do_update) {
-               ret = __bch2_fsck_write_inode(trans, &u, iter->pos.snapshot);
+               ret = __bch2_fsck_write_inode(trans, &u);
                bch_err_msg(c, ret, "in fsck updating inode");
                if (ret)
-                       return ret;
+                       goto err_noprint;
        }
 err:
 fsck_err:
        bch_err_fn(c, ret);
+err_noprint:
+       printbuf_exit(&buf);
        return ret;
 }
 
 int bch2_check_inodes(struct bch_fs *c)
 {
-       bool full = c->opts.fsck;
-       struct bch_inode_unpacked prev = { 0 };
+       struct bch_inode_unpacked snapshot_root = {};
        struct snapshots_seen s;
 
        snapshots_seen_init(&s);
@@ -1248,13 +1468,104 @@ int bch2_check_inodes(struct bch_fs *c)
                                POS_MIN,
                                BTREE_ITER_prefetch|BTREE_ITER_all_snapshots, k,
                                NULL, NULL, BCH_TRANS_COMMIT_no_enospc,
-                       check_inode(trans, &iter, k, &prev, &s, full)));
+                       check_inode(trans, &iter, k, &snapshot_root, &s)));
 
        snapshots_seen_exit(&s);
        bch_err_fn(c, ret);
        return ret;
 }
 
+static int find_oldest_inode_needs_reattach(struct btree_trans *trans,
+                                           struct bch_inode_unpacked *inode)
+{
+       struct bch_fs *c = trans->c;
+       struct btree_iter iter;
+       struct bkey_s_c k;
+       int ret = 0;
+
+       /*
+        * We look for inodes to reattach in natural key order, leaves first,
+        * but we should do the reattach at the oldest version that needs to be
+        * reattached:
+        */
+       for_each_btree_key_norestart(trans, iter,
+                                    BTREE_ID_inodes,
+                                    SPOS(0, inode->bi_inum, inode->bi_snapshot + 1),
+                                    BTREE_ITER_all_snapshots, k, ret) {
+               if (k.k->p.offset != inode->bi_inum)
+                       break;
+
+               if (!bch2_snapshot_is_ancestor(c, inode->bi_snapshot, k.k->p.snapshot))
+                       continue;
+
+               if (!bkey_is_inode(k.k))
+                       break;
+
+               struct bch_inode_unpacked parent_inode;
+               bch2_inode_unpack(k, &parent_inode);
+
+               if (!inode_should_reattach(&parent_inode))
+                       break;
+
+               *inode = parent_inode;
+       }
+       bch2_trans_iter_exit(trans, &iter);
+
+       return ret;
+}
+
+static int check_unreachable_inode(struct btree_trans *trans,
+                                  struct btree_iter *iter,
+                                  struct bkey_s_c k)
+{
+       struct printbuf buf = PRINTBUF;
+       int ret = 0;
+
+       if (!bkey_is_inode(k.k))
+               return 0;
+
+       struct bch_inode_unpacked inode;
+       BUG_ON(bch2_inode_unpack(k, &inode));
+
+       if (!inode_should_reattach(&inode))
+               return 0;
+
+       ret = find_oldest_inode_needs_reattach(trans, &inode);
+       if (ret)
+               return ret;
+
+       if (fsck_err(trans, inode_unreachable,
+                    "unreachable inode:\n%s",
+                    (bch2_inode_unpacked_to_text(&buf, &inode),
+                     buf.buf)))
+               ret = reattach_inode(trans, &inode);
+fsck_err:
+       printbuf_exit(&buf);
+       return ret;
+}
+
+/*
+ * Reattach unreachable (but not unlinked) inodes
+ *
+ * Run after check_inodes() and check_dirents(), so we node that inode
+ * backpointer fields point to valid dirents, and every inode that has a dirent
+ * that points to it has its backpointer field set - so we're just looking for
+ * non-unlinked inodes without backpointers:
+ *
+ * XXX: this is racy w.r.t. hardlink removal in online fsck
+ */
+int bch2_check_unreachable_inodes(struct bch_fs *c)
+{
+       int ret = bch2_trans_run(c,
+               for_each_btree_key_commit(trans, iter, BTREE_ID_inodes,
+                               POS_MIN,
+                               BTREE_ITER_prefetch|BTREE_ITER_all_snapshots, k,
+                               NULL, NULL, BCH_TRANS_COMMIT_no_enospc,
+                       check_unreachable_inode(trans, &iter, k)));
+       bch_err_fn(c, ret);
+       return ret;
+}
+
 static inline bool btree_matches_i_mode(enum btree_id btree, unsigned mode)
 {
        switch (btree) {
@@ -1347,7 +1658,7 @@ static int check_i_sectors_notnested(struct btree_trans *trans, struct inode_wal
                                w->last_pos.inode, i->snapshot,
                                i->inode.bi_sectors, i->count)) {
                        i->inode.bi_sectors = i->count;
-                       ret = bch2_fsck_write_inode(trans, &i->inode, i->snapshot);
+                       ret = bch2_fsck_write_inode(trans, &i->inode);
                        if (ret)
                                break;
                }
@@ -1657,8 +1968,7 @@ static int check_extent(struct btree_trans *trans, struct btree_iter *iter,
                            !key_visible_in_snapshot(c, s, i->snapshot, k.k->p.snapshot))
                                continue;
 
-                       if (fsck_err_on(!(i->inode.bi_flags & BCH_INODE_i_size_dirty) &&
-                                       k.k->p.offset > round_up(i->inode.bi_size, block_bytes(c)) >> 9 &&
+                       if (fsck_err_on(k.k->p.offset > round_up(i->inode.bi_size, block_bytes(c)) >> 9 &&
                                        !bkey_extent_is_reservation(k),
                                        trans, extent_past_end_of_inode,
                                        "extent type past end of inode %llu:%u, i_size %llu\n  %s",
@@ -1789,7 +2099,7 @@ static int check_subdir_count_notnested(struct btree_trans *trans, struct inode_
                                "directory %llu:%u with wrong i_nlink: got %u, should be %llu",
                                w->last_pos.inode, i->snapshot, i->inode.bi_nlink, i->count)) {
                        i->inode.bi_nlink = i->count;
-                       ret = bch2_fsck_write_inode(trans, &i->inode, i->snapshot);
+                       ret = bch2_fsck_write_inode(trans, &i->inode);
                        if (ret)
                                break;
                }
@@ -1810,8 +2120,7 @@ noinline_for_stack
 static int check_dirent_inode_dirent(struct btree_trans *trans,
                                   struct btree_iter *iter,
                                   struct bkey_s_c_dirent d,
-                                  struct bch_inode_unpacked *target,
-                                  u32 target_snapshot)
+                                  struct bch_inode_unpacked *target)
 {
        struct bch_fs *c = trans->c;
        struct printbuf buf = PRINTBUF;
@@ -1821,6 +2130,32 @@ static int check_dirent_inode_dirent(struct btree_trans *trans,
        if (inode_points_to_dirent(target, d))
                return 0;
 
+       if (!target->bi_dir &&
+           !target->bi_dir_offset) {
+               fsck_err_on(S_ISDIR(target->bi_mode),
+                           trans, inode_dir_missing_backpointer,
+                           "directory with missing backpointer\n%s",
+                           (printbuf_reset(&buf),
+                            bch2_bkey_val_to_text(&buf, c, d.s_c),
+                            prt_printf(&buf, "\n"),
+                            bch2_inode_unpacked_to_text(&buf, target),
+                            buf.buf));
+
+               fsck_err_on(target->bi_flags & BCH_INODE_unlinked,
+                           trans, inode_unlinked_but_has_dirent,
+                           "inode unlinked but has dirent\n%s",
+                           (printbuf_reset(&buf),
+                            bch2_bkey_val_to_text(&buf, c, d.s_c),
+                            prt_printf(&buf, "\n"),
+                            bch2_inode_unpacked_to_text(&buf, target),
+                            buf.buf));
+
+               target->bi_flags &= ~BCH_INODE_unlinked;
+               target->bi_dir          = d.k->p.inode;
+               target->bi_dir_offset   = d.k->p.offset;
+               return __bch2_fsck_write_inode(trans, target);
+       }
+
        if (bch2_inode_should_have_bp(target) &&
            !fsck_err(trans, inode_wrong_backpointer,
                      "dirent points to inode that does not point back:\n  %s",
@@ -1830,15 +2165,8 @@ static int check_dirent_inode_dirent(struct btree_trans *trans,
                       buf.buf)))
                goto err;
 
-       if (!target->bi_dir &&
-           !target->bi_dir_offset) {
-               target->bi_dir          = d.k->p.inode;
-               target->bi_dir_offset   = d.k->p.offset;
-               return __bch2_fsck_write_inode(trans, target, target_snapshot);
-       }
-
        struct bkey_s_c_dirent bp_dirent = dirent_get_by_pos(trans, &bp_iter,
-                             SPOS(target->bi_dir, target->bi_dir_offset, target_snapshot));
+                             SPOS(target->bi_dir, target->bi_dir_offset, target->bi_snapshot));
        ret = bkey_err(bp_dirent);
        if (ret && !bch2_err_matches(ret, ENOENT))
                goto err;
@@ -1851,14 +2179,14 @@ static int check_dirent_inode_dirent(struct btree_trans *trans,
                        "inode %llu:%u has wrong backpointer:\n"
                        "got       %llu:%llu\n"
                        "should be %llu:%llu",
-                       target->bi_inum, target_snapshot,
+                       target->bi_inum, target->bi_snapshot,
                        target->bi_dir,
                        target->bi_dir_offset,
                        d.k->p.inode,
                        d.k->p.offset)) {
                target->bi_dir          = d.k->p.inode;
                target->bi_dir_offset   = d.k->p.offset;
-               ret = __bch2_fsck_write_inode(trans, target, target_snapshot);
+               ret = __bch2_fsck_write_inode(trans, target);
                goto out;
        }
 
@@ -1873,7 +2201,7 @@ static int check_dirent_inode_dirent(struct btree_trans *trans,
                        trans, inode_dir_multiple_links,
                        "%s %llu:%u with multiple links\n%s",
                        S_ISDIR(target->bi_mode) ? "directory" : "subvolume",
-                       target->bi_inum, target_snapshot, buf.buf)) {
+                       target->bi_inum, target->bi_snapshot, buf.buf)) {
                ret = __remove_dirent(trans, d.k->p);
                goto out;
        }
@@ -1886,10 +2214,10 @@ static int check_dirent_inode_dirent(struct btree_trans *trans,
        if (fsck_err_on(backpointer_exists && !target->bi_nlink,
                        trans, inode_multiple_links_but_nlink_0,
                        "inode %llu:%u type %s has multiple links but i_nlink 0\n%s",
-                       target->bi_inum, target_snapshot, bch2_d_types[d.v->d_type], buf.buf)) {
+                       target->bi_inum, target->bi_snapshot, bch2_d_types[d.v->d_type], buf.buf)) {
                target->bi_nlink++;
                target->bi_flags &= ~BCH_INODE_unlinked;
-               ret = __bch2_fsck_write_inode(trans, target, target_snapshot);
+               ret = __bch2_fsck_write_inode(trans, target);
                if (ret)
                        goto err;
        }
@@ -1906,15 +2234,14 @@ noinline_for_stack
 static int check_dirent_target(struct btree_trans *trans,
                               struct btree_iter *iter,
                               struct bkey_s_c_dirent d,
-                              struct bch_inode_unpacked *target,
-                              u32 target_snapshot)
+                              struct bch_inode_unpacked *target)
 {
        struct bch_fs *c = trans->c;
        struct bkey_i_dirent *n;
        struct printbuf buf = PRINTBUF;
        int ret = 0;
 
-       ret = check_dirent_inode_dirent(trans, iter, d, target, target_snapshot);
+       ret = check_dirent_inode_dirent(trans, iter, d, target);
        if (ret)
                goto err;
 
@@ -2073,7 +2400,7 @@ static int check_dirent_to_subvol(struct btree_trans *trans, struct btree_iter *
        u64 target_inum = le64_to_cpu(s.v->inode);
        u32 target_snapshot = le32_to_cpu(s.v->snapshot);
 
-       ret = lookup_inode(trans, target_inum, &subvol_root, &target_snapshot);
+       ret = lookup_inode(trans, target_inum, target_snapshot, &subvol_root);
        if (ret && !bch2_err_matches(ret, ENOENT))
                goto err;
 
@@ -2089,13 +2416,13 @@ static int check_dirent_to_subvol(struct btree_trans *trans, struct btree_iter *
                        target_inum,
                        subvol_root.bi_parent_subvol, parent_subvol)) {
                subvol_root.bi_parent_subvol = parent_subvol;
-               ret = __bch2_fsck_write_inode(trans, &subvol_root, target_snapshot);
+               subvol_root.bi_snapshot = le32_to_cpu(s.v->snapshot);
+               ret = __bch2_fsck_write_inode(trans, &subvol_root);
                if (ret)
                        goto err;
        }
 
-       ret = check_dirent_target(trans, iter, d, &subvol_root,
-                                 target_snapshot);
+       ret = check_dirent_target(trans, iter, d, &subvol_root);
        if (ret)
                goto err;
 out:
@@ -2153,7 +2480,7 @@ static int check_dirent(struct btree_trans *trans, struct btree_iter *iter,
                *hash_info = bch2_hash_info_init(c, &i->inode);
        dir->first_this_inode = false;
 
-       ret = hash_check_key(trans, bch2_dirent_hash_desc, hash_info, iter, k);
+       ret = hash_check_key(trans, s, bch2_dirent_hash_desc, hash_info, iter, k);
        if (ret < 0)
                goto err;
        if (ret) {
@@ -2188,8 +2515,7 @@ static int check_dirent(struct btree_trans *trans, struct btree_iter *iter,
                }
 
                darray_for_each(target->inodes, i) {
-                       ret = check_dirent_target(trans, iter, d,
-                                                 &i->inode, i->snapshot);
+                       ret = check_dirent_target(trans, iter, d, &i->inode);
                        if (ret)
                                goto err;
                }
@@ -2268,7 +2594,7 @@ static int check_xattr(struct btree_trans *trans, struct btree_iter *iter,
                *hash_info = bch2_hash_info_init(c, &i->inode);
        inode->first_this_inode = false;
 
-       ret = hash_check_key(trans, bch2_xattr_hash_desc, hash_info, iter, k);
+       ret = hash_check_key(trans, NULL, bch2_xattr_hash_desc, hash_info, iter, k);
        bch_err_fn(c, ret);
        return ret;
 }
@@ -2330,7 +2656,7 @@ static int check_root_trans(struct btree_trans *trans)
                        goto err;
        }
 
-       ret = lookup_inode(trans, BCACHEFS_ROOT_INO, &root_inode, &snapshot);
+       ret = lookup_inode(trans, BCACHEFS_ROOT_INO, snapshot, &root_inode);
        if (ret && !bch2_err_matches(ret, ENOENT))
                return ret;
 
@@ -2343,8 +2669,9 @@ static int check_root_trans(struct btree_trans *trans)
                bch2_inode_init(c, &root_inode, 0, 0, S_IFDIR|0755,
                                0, NULL);
                root_inode.bi_inum = inum;
+               root_inode.bi_snapshot = snapshot;
 
-               ret = __bch2_fsck_write_inode(trans, &root_inode, snapshot);
+               ret = __bch2_fsck_write_inode(trans, &root_inode);
                bch_err_msg(c, ret, "writing root inode");
        }
 err:
@@ -2355,7 +2682,7 @@ fsck_err:
 /* Get root directory, create if it doesn't exist: */
 int bch2_check_root(struct bch_fs *c)
 {
-       int ret = bch2_trans_do(c, NULL, NULL, BCH_TRANS_COMMIT_no_enospc,
+       int ret = bch2_trans_commit_do(c, NULL, NULL, BCH_TRANS_COMMIT_no_enospc,
                check_root_trans(trans));
        bch_err_fn(c, ret);
        return ret;
@@ -2396,22 +2723,6 @@ static int check_subvol_path(struct btree_trans *trans, struct btree_iter *iter,
                if (ret)
                        break;
 
-               /*
-                * We've checked that inode backpointers point to valid dirents;
-                * here, it's sufficient to check that the subvolume root has a
-                * dirent:
-                */
-               if (fsck_err_on(!subvol_root.bi_dir,
-                               trans, subvol_unreachable,
-                               "unreachable subvolume %s",
-                               (bch2_bkey_val_to_text(&buf, c, s.s_c),
-                                prt_newline(&buf),
-                                bch2_inode_unpacked_to_text(&buf, &subvol_root),
-                                buf.buf))) {
-                       ret = reattach_subvol(trans, s);
-                       break;
-               }
-
                u32 parent = le32_to_cpu(s.v->fs_path_parent);
 
                if (darray_u32_has(&subvol_path, parent)) {
@@ -2472,12 +2783,6 @@ static bool path_is_dup(pathbuf *p, u64 inum, u32 snapshot)
        return false;
 }
 
-/*
- * Check that a given inode is reachable from its subvolume root - we already
- * verified subvolume connectivity:
- *
- * XXX: we should also be verifying that inodes are in the right subvolumes
- */
 static int check_path(struct btree_trans *trans, pathbuf *p, struct bkey_s_c inode_k)
 {
        struct bch_fs *c = trans->c;
@@ -2491,6 +2796,9 @@ static int check_path(struct btree_trans *trans, pathbuf *p, struct bkey_s_c ino
 
        BUG_ON(bch2_inode_unpack(inode_k, &inode));
 
+       if (!S_ISDIR(inode.bi_mode))
+               return 0;
+
        while (!inode.bi_subvol) {
                struct btree_iter dirent_iter;
                struct bkey_s_c_dirent d;
@@ -2505,21 +2813,15 @@ static int check_path(struct btree_trans *trans, pathbuf *p, struct bkey_s_c ino
                        bch2_trans_iter_exit(trans, &dirent_iter);
 
                if (bch2_err_matches(ret, ENOENT)) {
-                       ret = 0;
-                       if (fsck_err(trans, inode_unreachable,
-                                    "unreachable inode\n%s",
-                                    (printbuf_reset(&buf),
-                                     bch2_bkey_val_to_text(&buf, c, inode_k),
-                                     buf.buf)))
-                               ret = reattach_inode(trans, &inode, snapshot);
+                       printbuf_reset(&buf);
+                       bch2_bkey_val_to_text(&buf, c, inode_k);
+                       bch_err(c, "unreachable inode in check_directory_structure: %s\n%s",
+                               bch2_err_str(ret), buf.buf);
                        goto out;
                }
 
                bch2_trans_iter_exit(trans, &dirent_iter);
 
-               if (!S_ISDIR(inode.bi_mode))
-                       break;
-
                ret = darray_push(p, ((struct pathbuf_entry) {
                        .inum           = inode.bi_inum,
                        .snapshot       = snapshot,
@@ -2557,7 +2859,7 @@ static int check_path(struct btree_trans *trans, pathbuf *p, struct bkey_s_c ino
                                if (ret)
                                        break;
 
-                               ret = reattach_inode(trans, &inode, snapshot);
+                               ret = reattach_inode(trans, &inode);
                                bch_err_msg(c, ret, "reattaching inode %llu", inode.bi_inum);
                        }
                        break;
@@ -2572,9 +2874,8 @@ fsck_err:
 }
 
 /*
- * Check for unreachable inodes, as well as loops in the directory structure:
- * After bch2_check_dirents(), if an inode backpointer doesn't exist that means it's
- * unreachable:
+ * Check for loops in the directory structure: all other connectivity issues
+ * have been fixed by prior passes
  */
 int bch2_check_directory_structure(struct bch_fs *c)
 {
@@ -2702,6 +3003,10 @@ static int check_nlinks_find_hardlinks(struct bch_fs *c,
                        if (S_ISDIR(u.bi_mode))
                                continue;
 
+                       /*
+                        * Previous passes ensured that bi_nlink is nonzero if
+                        * it had multiple hardlinks:
+                        */
                        if (!u.bi_nlink)
                                continue;
 
@@ -2787,7 +3092,7 @@ static int check_nlinks_update_inode(struct btree_trans *trans, struct btree_ite
                        u.bi_inum, bch2_d_types[mode_to_type(u.bi_mode)],
                        bch2_inode_nlink_get(&u), link->count)) {
                bch2_inode_nlink_set(&u, link->count);
-               ret = __bch2_fsck_write_inode(trans, &u, k.k->p.snapshot);
+               ret = __bch2_fsck_write_inode(trans, &u);
        }
 fsck_err:
        return ret;
index a4ef9427178433bda33d500fe5f7551ff8fd1638..1cca31011530979b3fb103205090e3e252c9067c 100644 (file)
@@ -9,6 +9,7 @@ int bch2_check_dirents(struct bch_fs *);
 int bch2_check_xattrs(struct bch_fs *);
 int bch2_check_root(struct bch_fs *);
 int bch2_check_subvolume_structure(struct bch_fs *);
+int bch2_check_unreachable_inodes(struct bch_fs *);
 int bch2_check_directory_structure(struct bch_fs *);
 int bch2_check_nlinks(struct bch_fs *);
 int bch2_fix_reflink_p(struct bch_fs *);
index 753c208896c3be7417b7f8b7aefe5421c942df44..039cb7a22244dd033a35c3525b33cbe67eae2dc3 100644 (file)
@@ -12,6 +12,7 @@
 #include "error.h"
 #include "extents.h"
 #include "extent_update.h"
+#include "fs.h"
 #include "inode.h"
 #include "str_hash.h"
 #include "snapshot.h"
@@ -20,7 +21,7 @@
 
 #include <linux/random.h>
 
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #define x(name, ...)   #name,
 const char * const bch2_inode_opts[] = {
@@ -34,6 +35,8 @@ static const char * const bch2_inode_flag_strs[] = {
 };
 #undef  x
 
+static int delete_ancestor_snapshot_inodes(struct btree_trans *, struct bpos);
+
 static const u8 byte_table[8] = { 1, 2, 3, 4, 6, 8, 10, 13 };
 
 static int inode_decode_field(const u8 *in, const u8 *end,
@@ -160,8 +163,8 @@ static noinline int bch2_inode_unpack_v1(struct bkey_s_c_inode inode,
        unsigned fieldnr = 0, field_bits;
        int ret;
 
-#define x(_name, _bits)                                        \
-       if (fieldnr++ == INODE_NR_FIELDS(inode.v)) {                    \
+#define x(_name, _bits)                                                        \
+       if (fieldnr++ == INODEv1_NR_FIELDS(inode.v)) {                  \
                unsigned offset = offsetof(struct bch_inode_unpacked, _name);\
                memset((void *) unpacked + offset, 0,                   \
                       sizeof(*unpacked) - offset);                     \
@@ -280,6 +283,8 @@ static noinline int bch2_inode_unpack_slowpath(struct bkey_s_c k,
 {
        memset(unpacked, 0, sizeof(*unpacked));
 
+       unpacked->bi_snapshot = k.k->p.snapshot;
+
        switch (k.k->type) {
        case KEY_TYPE_inode: {
                struct bkey_s_c_inode inode = bkey_s_c_to_inode(k);
@@ -290,10 +295,10 @@ static noinline int bch2_inode_unpack_slowpath(struct bkey_s_c k,
                unpacked->bi_flags      = le32_to_cpu(inode.v->bi_flags);
                unpacked->bi_mode       = le16_to_cpu(inode.v->bi_mode);
 
-               if (INODE_NEW_VARINT(inode.v)) {
+               if (INODEv1_NEW_VARINT(inode.v)) {
                        return bch2_inode_unpack_v2(unpacked, inode.v->fields,
                                                    bkey_val_end(inode),
-                                                   INODE_NR_FIELDS(inode.v));
+                                                   INODEv1_NR_FIELDS(inode.v));
                } else {
                        return bch2_inode_unpack_v1(inode, unpacked);
                }
@@ -327,22 +332,20 @@ int bch2_inode_unpack(struct bkey_s_c k,
                : bch2_inode_unpack_slowpath(k, unpacked);
 }
 
-int bch2_inode_peek_nowarn(struct btree_trans *trans,
-                   struct btree_iter *iter,
-                   struct bch_inode_unpacked *inode,
-                   subvol_inum inum, unsigned flags)
+int __bch2_inode_peek(struct btree_trans *trans,
+                     struct btree_iter *iter,
+                     struct bch_inode_unpacked *inode,
+                     subvol_inum inum, unsigned flags,
+                     bool warn)
 {
-       struct bkey_s_c k;
        u32 snapshot;
-       int ret;
-
-       ret = bch2_subvolume_get_snapshot(trans, inum.subvol, &snapshot);
+       int ret = __bch2_subvolume_get_snapshot(trans, inum.subvol, &snapshot, warn);
        if (ret)
                return ret;
 
-       k = bch2_bkey_get_iter(trans, iter, BTREE_ID_inodes,
-                              SPOS(0, inum.inum, snapshot),
-                              flags|BTREE_ITER_cached);
+       struct bkey_s_c k = bch2_bkey_get_iter(trans, iter, BTREE_ID_inodes,
+                                              SPOS(0, inum.inum, snapshot),
+                                              flags|BTREE_ITER_cached);
        ret = bkey_err(k);
        if (ret)
                return ret;
@@ -357,20 +360,12 @@ int bch2_inode_peek_nowarn(struct btree_trans *trans,
 
        return 0;
 err:
+       if (warn)
+               bch_err_msg(trans->c, ret, "looking up inum %llu:%llu:", inum.subvol, inum.inum);
        bch2_trans_iter_exit(trans, iter);
        return ret;
 }
 
-int bch2_inode_peek(struct btree_trans *trans,
-                   struct btree_iter *iter,
-                   struct bch_inode_unpacked *inode,
-                   subvol_inum inum, unsigned flags)
-{
-       int ret = bch2_inode_peek_nowarn(trans, iter, inode, inum, flags);
-       bch_err_msg(trans->c, ret, "looking up inum %llu:%llu:", inum.subvol, inum.inum);
-       return ret;
-}
-
 int bch2_inode_write_flags(struct btree_trans *trans,
                     struct btree_iter *iter,
                     struct bch_inode_unpacked *inode,
@@ -387,9 +382,7 @@ int bch2_inode_write_flags(struct btree_trans *trans,
        return bch2_trans_update(trans, iter, &inode_p->inode.k_i, flags);
 }
 
-int __bch2_fsck_write_inode(struct btree_trans *trans,
-                        struct bch_inode_unpacked *inode,
-                        u32 snapshot)
+int __bch2_fsck_write_inode(struct btree_trans *trans, struct bch_inode_unpacked *inode)
 {
        struct bkey_inode_buf *inode_p =
                bch2_trans_kmalloc(trans, sizeof(*inode_p));
@@ -398,19 +391,17 @@ int __bch2_fsck_write_inode(struct btree_trans *trans,
                return PTR_ERR(inode_p);
 
        bch2_inode_pack(inode_p, inode);
-       inode_p->inode.k.p.snapshot = snapshot;
+       inode_p->inode.k.p.snapshot = inode->bi_snapshot;
 
        return bch2_btree_insert_nonextent(trans, BTREE_ID_inodes,
                                &inode_p->inode.k_i,
                                BTREE_UPDATE_internal_snapshot_node);
 }
 
-int bch2_fsck_write_inode(struct btree_trans *trans,
-                           struct bch_inode_unpacked *inode,
-                           u32 snapshot)
+int bch2_fsck_write_inode(struct btree_trans *trans, struct bch_inode_unpacked *inode)
 {
        int ret = commit_do(trans, NULL, NULL, BCH_TRANS_COMMIT_no_enospc,
-                           __bch2_fsck_write_inode(trans, inode, snapshot));
+                           __bch2_fsck_write_inode(trans, inode));
        bch_err_fn(trans->c, ret);
        return ret;
 }
@@ -482,10 +473,10 @@ int bch2_inode_validate(struct bch_fs *c, struct bkey_s_c k,
        struct bkey_s_c_inode inode = bkey_s_c_to_inode(k);
        int ret = 0;
 
-       bkey_fsck_err_on(INODE_STR_HASH(inode.v) >= BCH_STR_HASH_NR,
+       bkey_fsck_err_on(INODEv1_STR_HASH(inode.v) >= BCH_STR_HASH_NR,
                         c, inode_str_hash_invalid,
                         "invalid str hash type (%llu >= %u)",
-                        INODE_STR_HASH(inode.v), BCH_STR_HASH_NR);
+                        INODEv1_STR_HASH(inode.v), BCH_STR_HASH_NR);
 
        ret = __bch2_inode_validate(c, k, flags);
 fsck_err:
@@ -544,6 +535,10 @@ static void __bch2_inode_unpacked_to_text(struct printbuf *out,
        prt_printf(out, "(%x)\n", inode->bi_flags);
 
        prt_printf(out, "journal_seq=%llu\n",   inode->bi_journal_seq);
+       prt_printf(out, "hash_seed=%llx\n",     inode->bi_hash_seed);
+       prt_printf(out, "hash_type=");
+       bch2_prt_str_hash_type(out, INODE_STR_HASH(inode));
+       prt_newline(out);
        prt_printf(out, "bi_size=%llu\n",       inode->bi_size);
        prt_printf(out, "bi_sectors=%llu\n",    inode->bi_sectors);
        prt_printf(out, "bi_version=%llu\n",    inode->bi_version);
@@ -589,9 +584,137 @@ static inline u64 bkey_inode_flags(struct bkey_s_c k)
        }
 }
 
-static inline bool bkey_is_deleted_inode(struct bkey_s_c k)
+static inline void bkey_inode_flags_set(struct bkey_s k, u64 f)
+{
+       switch (k.k->type) {
+       case KEY_TYPE_inode:
+               bkey_s_to_inode(k).v->bi_flags = cpu_to_le32(f);
+               return;
+       case KEY_TYPE_inode_v2:
+               bkey_s_to_inode_v2(k).v->bi_flags = cpu_to_le64(f);
+               return;
+       case KEY_TYPE_inode_v3:
+               bkey_s_to_inode_v3(k).v->bi_flags = cpu_to_le64(f);
+               return;
+       default:
+               BUG();
+       }
+}
+
+static inline bool bkey_is_unlinked_inode(struct bkey_s_c k)
+{
+       unsigned f = bkey_inode_flags(k) & BCH_INODE_unlinked;
+
+       return (f & BCH_INODE_unlinked) && !(f & BCH_INODE_has_child_snapshot);
+}
+
+static struct bkey_s_c
+bch2_bkey_get_iter_snapshot_parent(struct btree_trans *trans, struct btree_iter *iter,
+                                  enum btree_id btree, struct bpos pos,
+                                  unsigned flags)
+{
+       struct bch_fs *c = trans->c;
+       struct bkey_s_c k;
+       int ret = 0;
+
+       for_each_btree_key_upto_norestart(trans, *iter, btree,
+                                         bpos_successor(pos),
+                                         SPOS(pos.inode, pos.offset, U32_MAX),
+                                         flags|BTREE_ITER_all_snapshots, k, ret)
+               if (bch2_snapshot_is_ancestor(c, pos.snapshot, k.k->p.snapshot))
+                       return k;
+
+       bch2_trans_iter_exit(trans, iter);
+       return ret ? bkey_s_c_err(ret) : bkey_s_c_null;
+}
+
+static struct bkey_s_c
+bch2_inode_get_iter_snapshot_parent(struct btree_trans *trans, struct btree_iter *iter,
+                                   struct bpos pos, unsigned flags)
+{
+       struct bkey_s_c k;
+again:
+       k = bch2_bkey_get_iter_snapshot_parent(trans, iter, BTREE_ID_inodes, pos, flags);
+       if (!k.k ||
+           bkey_err(k) ||
+           bkey_is_inode(k.k))
+               return k;
+
+       bch2_trans_iter_exit(trans, iter);
+       pos = k.k->p;
+       goto again;
+}
+
+int __bch2_inode_has_child_snapshots(struct btree_trans *trans, struct bpos pos)
+{
+       struct bch_fs *c = trans->c;
+       struct btree_iter iter;
+       struct bkey_s_c k;
+       int ret = 0;
+
+       for_each_btree_key_upto_norestart(trans, iter,
+                       BTREE_ID_inodes, POS(0, pos.offset), bpos_predecessor(pos),
+                       BTREE_ITER_all_snapshots|
+                       BTREE_ITER_with_updates, k, ret)
+               if (bch2_snapshot_is_ancestor(c, k.k->p.snapshot, pos.snapshot) &&
+                   bkey_is_inode(k.k)) {
+                       ret = 1;
+                       break;
+               }
+       bch2_trans_iter_exit(trans, &iter);
+       return ret;
+}
+
+static int update_inode_has_children(struct btree_trans *trans,
+                                    struct bkey_s k,
+                                    bool have_child)
+{
+       if (!have_child) {
+               int ret = bch2_inode_has_child_snapshots(trans, k.k->p);
+               if (ret)
+                       return ret < 0 ? ret : 0;
+       }
+
+       u64 f = bkey_inode_flags(k.s_c);
+       if (have_child != !!(f & BCH_INODE_has_child_snapshot))
+               bkey_inode_flags_set(k, f ^ BCH_INODE_has_child_snapshot);
+
+       return 0;
+}
+
+static int update_parent_inode_has_children(struct btree_trans *trans, struct bpos pos,
+                                           bool have_child)
 {
-       return bkey_inode_flags(k) & BCH_INODE_unlinked;
+       struct btree_iter iter;
+       struct bkey_s_c k = bch2_inode_get_iter_snapshot_parent(trans,
+                                               &iter, pos, BTREE_ITER_with_updates);
+       int ret = bkey_err(k);
+       if (ret)
+               return ret;
+       if (!k.k)
+               return 0;
+
+       if (!have_child) {
+               ret = bch2_inode_has_child_snapshots(trans, k.k->p);
+               if (ret) {
+                       ret = ret < 0 ? ret : 0;
+                       goto err;
+               }
+       }
+
+       u64 f = bkey_inode_flags(k);
+       if (have_child != !!(f & BCH_INODE_has_child_snapshot)) {
+               struct bkey_i *update = bch2_bkey_make_mut(trans, &iter, &k,
+                                            BTREE_UPDATE_internal_snapshot_node);
+               ret = PTR_ERR_OR_ZERO(update);
+               if (ret)
+                       goto err;
+
+               bkey_inode_flags_set(bkey_i_to_s(update), f ^ BCH_INODE_has_child_snapshot);
+       }
+err:
+       bch2_trans_iter_exit(trans, &iter);
+       return ret;
 }
 
 int bch2_trigger_inode(struct btree_trans *trans,
@@ -600,6 +723,8 @@ int bch2_trigger_inode(struct btree_trans *trans,
                       struct bkey_s new,
                       enum btree_iter_update_trigger_flags flags)
 {
+       struct bch_fs *c = trans->c;
+
        if ((flags & BTREE_TRIGGER_atomic) && (flags & BTREE_TRIGGER_insert)) {
                BUG_ON(!trans->journal_res.seq);
                bkey_s_to_inode_v3(new).v->bi_journal_seq = cpu_to_le64(trans->journal_res.seq);
@@ -613,13 +738,41 @@ int bch2_trigger_inode(struct btree_trans *trans,
                        return ret;
        }
 
-       int deleted_delta =     (int) bkey_is_deleted_inode(new.s_c) -
-                               (int) bkey_is_deleted_inode(old);
-       if ((flags & BTREE_TRIGGER_transactional) && deleted_delta) {
-               int ret = bch2_btree_bit_mod_buffered(trans, BTREE_ID_deleted_inodes,
-                                                     new.k->p, deleted_delta > 0);
-               if (ret)
-                       return ret;
+       if (flags & BTREE_TRIGGER_transactional) {
+               int unlinked_delta =    (int) bkey_is_unlinked_inode(new.s_c) -
+                                       (int) bkey_is_unlinked_inode(old);
+               if (unlinked_delta) {
+                       int ret = bch2_btree_bit_mod_buffered(trans, BTREE_ID_deleted_inodes,
+                                                             new.k->p, unlinked_delta > 0);
+                       if (ret)
+                               return ret;
+               }
+
+               /*
+                * If we're creating or deleting an inode at this snapshot ID,
+                * and there might be an inode in a parent snapshot ID, we might
+                * need to set or clear the has_child_snapshot flag on the
+                * parent.
+                */
+               int deleted_delta = (int) bkey_is_inode(new.k) -
+                                   (int) bkey_is_inode(old.k);
+               if (deleted_delta &&
+                   bch2_snapshot_parent(c, new.k->p.snapshot)) {
+                       int ret = update_parent_inode_has_children(trans, new.k->p,
+                                                                  deleted_delta > 0);
+                       if (ret)
+                               return ret;
+               }
+
+               /*
+                * When an inode is first updated in a new snapshot, we may need
+                * to clear has_child_snapshot
+                */
+               if (deleted_delta > 0) {
+                       int ret = update_inode_has_children(trans, new, false);
+                       if (ret)
+                               return ret;
+               }
        }
 
        return 0;
@@ -653,10 +806,8 @@ void bch2_inode_init_early(struct bch_fs *c,
 
        memset(inode_u, 0, sizeof(*inode_u));
 
-       /* ick */
-       inode_u->bi_flags |= str_hash << INODE_STR_HASH_OFFSET;
-       get_random_bytes(&inode_u->bi_hash_seed,
-                        sizeof(inode_u->bi_hash_seed));
+       SET_INODE_STR_HASH(inode_u, str_hash);
+       get_random_bytes(&inode_u->bi_hash_seed, sizeof(inode_u->bi_hash_seed));
 }
 
 void bch2_inode_init_late(struct bch_inode_unpacked *inode_u, u64 now,
@@ -902,6 +1053,11 @@ err:
        if (bch2_err_matches(ret, BCH_ERR_transaction_restart))
                goto retry;
 
+       if (ret)
+               goto err2;
+
+       ret = delete_ancestor_snapshot_inodes(trans, SPOS(0, inum.inum, snapshot));
+err2:
        bch2_trans_put(trans);
        return ret;
 }
@@ -935,8 +1091,7 @@ int bch2_inode_find_by_inum_trans(struct btree_trans *trans,
 int bch2_inode_find_by_inum(struct bch_fs *c, subvol_inum inum,
                            struct bch_inode_unpacked *inode)
 {
-       return bch2_trans_do(c, NULL, NULL, 0,
-               bch2_inode_find_by_inum_trans(trans, inum, inode));
+       return bch2_trans_do(c, bch2_inode_find_by_inum_trans(trans, inum, inode));
 }
 
 int bch2_inode_nlink_inc(struct bch_inode_unpacked *bi)
@@ -1006,7 +1161,7 @@ int bch2_inum_opts_get(struct btree_trans *trans, subvol_inum inum, struct bch_i
        return 0;
 }
 
-int bch2_inode_rm_snapshot(struct btree_trans *trans, u64 inum, u32 snapshot)
+static noinline int __bch2_inode_rm_snapshot(struct btree_trans *trans, u64 inum, u32 snapshot)
 {
        struct bch_fs *c = trans->c;
        struct btree_iter iter = { NULL };
@@ -1069,6 +1224,45 @@ err:
        return ret ?: -BCH_ERR_transaction_restart_nested;
 }
 
+/*
+ * After deleting an inode, there may be versions in older snapshots that should
+ * also be deleted - if they're not referenced by sibling snapshots and not open
+ * in other subvolumes:
+ */
+static int delete_ancestor_snapshot_inodes(struct btree_trans *trans, struct bpos pos)
+{
+       struct btree_iter iter;
+       struct bkey_s_c k;
+       int ret;
+next_parent:
+       ret = lockrestart_do(trans,
+               bkey_err(k = bch2_inode_get_iter_snapshot_parent(trans, &iter, pos, 0)));
+       if (ret || !k.k)
+               return ret;
+
+       bool unlinked = bkey_is_unlinked_inode(k);
+       pos = k.k->p;
+       bch2_trans_iter_exit(trans, &iter);
+
+       if (!unlinked)
+               return 0;
+
+       ret = lockrestart_do(trans, bch2_inode_or_descendents_is_open(trans, pos));
+       if (ret)
+               return ret < 0 ? ret : 0;
+
+       ret = __bch2_inode_rm_snapshot(trans, pos.offset, pos.snapshot);
+       if (ret)
+               return ret;
+       goto next_parent;
+}
+
+int bch2_inode_rm_snapshot(struct btree_trans *trans, u64 inum, u32 snapshot)
+{
+       return __bch2_inode_rm_snapshot(trans, inum, snapshot) ?:
+               delete_ancestor_snapshot_inodes(trans, SPOS(0, inum, snapshot));
+}
+
 static int may_delete_deleted_inode(struct btree_trans *trans,
                                    struct btree_iter *iter,
                                    struct bpos pos,
@@ -1078,6 +1272,7 @@ static int may_delete_deleted_inode(struct btree_trans *trans,
        struct btree_iter inode_iter;
        struct bkey_s_c k;
        struct bch_inode_unpacked inode;
+       struct printbuf buf = PRINTBUF;
        int ret;
 
        k = bch2_bkey_get_iter(trans, &inode_iter, BTREE_ID_inodes, pos, BTREE_ITER_cached);
@@ -1113,6 +1308,31 @@ static int may_delete_deleted_inode(struct btree_trans *trans,
                        pos.offset, pos.snapshot))
                goto delete;
 
+       if (fsck_err_on(inode.bi_flags & BCH_INODE_has_child_snapshot,
+                       trans, deleted_inode_has_child_snapshots,
+                       "inode with child snapshots %llu:%u in deleted_inodes btree",
+                       pos.offset, pos.snapshot))
+               goto delete;
+
+       ret = bch2_inode_has_child_snapshots(trans, k.k->p);
+       if (ret < 0)
+               goto out;
+
+       if (ret) {
+               if (fsck_err(trans, inode_has_child_snapshots_wrong,
+                            "inode has_child_snapshots flag wrong (should be set)\n%s",
+                            (printbuf_reset(&buf),
+                             bch2_inode_unpacked_to_text(&buf, &inode),
+                             buf.buf))) {
+                       inode.bi_flags |= BCH_INODE_has_child_snapshot;
+                       ret = __bch2_fsck_write_inode(trans, &inode);
+                       if (ret)
+                               goto out;
+               }
+               goto delete;
+
+       }
+
        if (test_bit(BCH_FS_clean_recovery, &c->flags) &&
            !fsck_err(trans, deleted_inode_but_clean,
                      "filesystem marked as clean but have deleted inode %llu:%u",
@@ -1121,33 +1341,11 @@ static int may_delete_deleted_inode(struct btree_trans *trans,
                goto out;
        }
 
-       if (bch2_snapshot_is_internal_node(c, pos.snapshot)) {
-               struct bpos new_min_pos;
-
-               ret = bch2_propagate_key_to_snapshot_leaves(trans, inode_iter.btree_id, k, &new_min_pos);
-               if (ret)
-                       goto out;
-
-               inode.bi_flags &= ~BCH_INODE_unlinked;
-
-               ret = bch2_inode_write_flags(trans, &inode_iter, &inode,
-                                            BTREE_UPDATE_internal_snapshot_node);
-               bch_err_msg(c, ret, "clearing inode unlinked flag");
-               if (ret)
-                       goto out;
-
-               /*
-                * We'll need another write buffer flush to pick up the new
-                * unlinked inodes in the snapshot leaves:
-                */
-               *need_another_pass = true;
-               goto out;
-       }
-
        ret = 1;
 out:
 fsck_err:
        bch2_trans_iter_exit(trans, &inode_iter);
+       printbuf_exit(&buf);
        return ret;
 delete:
        ret = bch2_btree_bit_mod_buffered(trans, BTREE_ID_deleted_inodes, pos, false);
index 695abd707cb6a5f508ad491e6ca4d1197bc8df40..eab82b5eb8977d8c6e8120b55fce870f8ffec26a 100644 (file)
@@ -5,6 +5,7 @@
 #include "bkey.h"
 #include "bkey_methods.h"
 #include "opts.h"
+#include "snapshot.h"
 
 enum bch_validate_flags;
 extern const char * const bch2_inode_opts[];
@@ -17,6 +18,15 @@ int bch2_inode_v3_validate(struct bch_fs *, struct bkey_s_c,
                          enum bch_validate_flags);
 void bch2_inode_to_text(struct printbuf *, struct bch_fs *, struct bkey_s_c);
 
+int __bch2_inode_has_child_snapshots(struct btree_trans *, struct bpos);
+
+static inline int bch2_inode_has_child_snapshots(struct btree_trans *trans, struct bpos pos)
+{
+       return bch2_snapshot_is_leaf(trans->c, pos.snapshot) <= 0
+               ? __bch2_inode_has_child_snapshots(trans, pos)
+               : 0;
+}
+
 int bch2_trigger_inode(struct btree_trans *, enum btree_id, unsigned,
                       struct bkey_s_c, struct bkey_s,
                       enum btree_iter_update_trigger_flags);
@@ -82,6 +92,7 @@ struct bch_inode_unpacked {
        BCH_INODE_FIELDS_v3()
 #undef  x
 };
+BITMASK(INODE_STR_HASH,        struct bch_inode_unpacked, bi_flags, 20, 24);
 
 struct bkey_inode_buf {
        struct bkey_i_inode_v3  inode;
@@ -97,10 +108,26 @@ struct bkey_i *bch2_inode_to_v3(struct btree_trans *, struct bkey_i *);
 
 void bch2_inode_unpacked_to_text(struct printbuf *, struct bch_inode_unpacked *);
 
-int bch2_inode_peek_nowarn(struct btree_trans *, struct btree_iter *,
-                   struct bch_inode_unpacked *, subvol_inum, unsigned);
-int bch2_inode_peek(struct btree_trans *, struct btree_iter *,
-                   struct bch_inode_unpacked *, subvol_inum, unsigned);
+int __bch2_inode_peek(struct btree_trans *, struct btree_iter *,
+                     struct bch_inode_unpacked *, subvol_inum, unsigned, bool);
+
+static inline int bch2_inode_peek_nowarn(struct btree_trans *trans,
+                                        struct btree_iter *iter,
+                                        struct bch_inode_unpacked *inode,
+                                        subvol_inum inum, unsigned flags)
+{
+       return __bch2_inode_peek(trans, iter, inode, inum, flags, false);
+}
+
+static inline int bch2_inode_peek(struct btree_trans *trans,
+                                 struct btree_iter *iter,
+                                 struct bch_inode_unpacked *inode,
+                                 subvol_inum inum, unsigned flags)
+{
+       return __bch2_inode_peek(trans, iter, inode, inum, flags, true);
+       int ret = bch2_inode_peek_nowarn(trans, iter, inode, inum, flags);
+       return ret;
+}
 
 int bch2_inode_write_flags(struct btree_trans *, struct btree_iter *,
                     struct bch_inode_unpacked *, enum btree_iter_update_trigger_flags);
@@ -112,8 +139,8 @@ static inline int bch2_inode_write(struct btree_trans *trans,
        return bch2_inode_write_flags(trans, iter, inode, 0);
 }
 
-int __bch2_fsck_write_inode(struct btree_trans *, struct bch_inode_unpacked *, u32);
-int bch2_fsck_write_inode(struct btree_trans *, struct bch_inode_unpacked *, u32);
+int __bch2_fsck_write_inode(struct btree_trans *, struct bch_inode_unpacked *);
+int bch2_fsck_write_inode(struct btree_trans *, struct bch_inode_unpacked *);
 
 void bch2_inode_init_early(struct bch_fs *,
                           struct bch_inode_unpacked *);
index 83d107331edf473ab5df16d9222c4a7e16c56c4a..7928d0c6954fa79951c1b7266255db4ccbe7047e 100644 (file)
@@ -133,7 +133,8 @@ enum inode_opt_id {
        x(i_size_dirty,                 5)      \
        x(i_sectors_dirty,              6)      \
        x(unlinked,                     7)      \
-       x(backptr_untrusted,            8)
+       x(backptr_untrusted,            8)      \
+       x(has_child_snapshot,           9)
 
 /* bits 20+ reserved for packed fields below: */
 
@@ -149,9 +150,9 @@ enum __bch_inode_flags {
 #undef x
 };
 
-LE32_BITMASK(INODE_STR_HASH,   struct bch_inode, bi_flags, 20, 24);
-LE32_BITMASK(INODE_NR_FIELDS,  struct bch_inode, bi_flags, 24, 31);
-LE32_BITMASK(INODE_NEW_VARINT, struct bch_inode, bi_flags, 31, 32);
+LE32_BITMASK(INODEv1_STR_HASH, struct bch_inode, bi_flags, 20, 24);
+LE32_BITMASK(INODEv1_NR_FIELDS,        struct bch_inode, bi_flags, 24, 31);
+LE32_BITMASK(INODEv1_NEW_VARINT,struct bch_inode, bi_flags, 31, 32);
 
 LE64_BITMASK(INODEv2_STR_HASH, struct bch_inode_v2, bi_flags, 20, 24);
 LE64_BITMASK(INODEv2_NR_FIELDS,        struct bch_inode_v2, bi_flags, 24, 31);
index 177ed331c00b1d4a05d5eb523e430732b251dd8d..f283051758d6d5fb1e6ecc9bb4acb9e6bf1a804d 100644 (file)
@@ -224,13 +224,14 @@ void bch2_logged_op_truncate_to_text(struct printbuf *out, struct bch_fs *c, str
 
 static int truncate_set_isize(struct btree_trans *trans,
                              subvol_inum inum,
-                             u64 new_i_size)
+                             u64 new_i_size,
+                             bool warn)
 {
        struct btree_iter iter = { NULL };
        struct bch_inode_unpacked inode_u;
        int ret;
 
-       ret   = bch2_inode_peek(trans, &iter, &inode_u, inum, BTREE_ITER_intent) ?:
+       ret   = __bch2_inode_peek(trans, &iter, &inode_u, inum, BTREE_ITER_intent, warn) ?:
                (inode_u.bi_size = new_i_size, 0) ?:
                bch2_inode_write(trans, &iter, &inode_u);
 
@@ -247,10 +248,11 @@ static int __bch2_resume_logged_op_truncate(struct btree_trans *trans,
        struct bkey_i_logged_op_truncate *op = bkey_i_to_logged_op_truncate(op_k);
        subvol_inum inum = { le32_to_cpu(op->v.subvol), le64_to_cpu(op->v.inum) };
        u64 new_i_size = le64_to_cpu(op->v.new_i_size);
+       bool warn_errors = i_sectors_delta != NULL;
        int ret;
 
        ret = commit_do(trans, NULL, NULL, BCH_TRANS_COMMIT_no_enospc,
-                       truncate_set_isize(trans, inum, new_i_size));
+                       truncate_set_isize(trans, inum, new_i_size, i_sectors_delta != NULL));
        if (ret)
                goto err;
 
@@ -263,8 +265,8 @@ static int __bch2_resume_logged_op_truncate(struct btree_trans *trans,
        if (bch2_err_matches(ret, BCH_ERR_transaction_restart))
                ret = 0;
 err:
-       bch2_logged_op_finish(trans, op_k);
-       bch_err_fn(c, ret);
+       if (warn_errors)
+               bch_err_fn(c, ret);
        return ret;
 }
 
@@ -288,9 +290,14 @@ int bch2_truncate(struct bch_fs *c, subvol_inum inum, u64 new_i_size, u64 *i_sec
         * resume only proceeding in one of the snapshots
         */
        down_read(&c->snapshot_create_lock);
-       int ret = bch2_trans_run(c,
-               bch2_logged_op_start(trans, &op.k_i) ?:
-               __bch2_resume_logged_op_truncate(trans, &op.k_i, i_sectors_delta));
+       struct btree_trans *trans = bch2_trans_get(c);
+       int ret = bch2_logged_op_start(trans, &op.k_i);
+       if (ret)
+               goto out;
+       ret = __bch2_resume_logged_op_truncate(trans, &op.k_i, i_sectors_delta);
+       ret = bch2_logged_op_finish(trans, &op.k_i) ?: ret;
+out:
+       bch2_trans_put(trans);
        up_read(&c->snapshot_create_lock);
 
        return ret;
@@ -308,7 +315,8 @@ void bch2_logged_op_finsert_to_text(struct printbuf *out, struct bch_fs *c, stru
        prt_printf(out, " src_offset=%llu",     le64_to_cpu(op.v->src_offset));
 }
 
-static int adjust_i_size(struct btree_trans *trans, subvol_inum inum, u64 offset, s64 len)
+static int adjust_i_size(struct btree_trans *trans, subvol_inum inum,
+                        u64 offset, s64 len, bool warn)
 {
        struct btree_iter iter;
        struct bch_inode_unpacked inode_u;
@@ -317,7 +325,7 @@ static int adjust_i_size(struct btree_trans *trans, subvol_inum inum, u64 offset
        offset  <<= 9;
        len     <<= 9;
 
-       ret = bch2_inode_peek(trans, &iter, &inode_u, inum, BTREE_ITER_intent);
+       ret = __bch2_inode_peek(trans, &iter, &inode_u, inum, BTREE_ITER_intent, warn);
        if (ret)
                return ret;
 
@@ -357,12 +365,22 @@ static int __bch2_resume_logged_op_finsert(struct btree_trans *trans,
        u64 len = abs(shift);
        u64 pos = le64_to_cpu(op->v.pos);
        bool insert = shift > 0;
+       u32 snapshot;
+       bool warn_errors = i_sectors_delta != NULL;
        int ret = 0;
 
        ret = bch2_inum_opts_get(trans, inum, &opts);
        if (ret)
                return ret;
 
+       /*
+        * check for missing subvolume before fpunch, as in resume we don't want
+        * it to be a fatal error
+        */
+       ret = lockrestart_do(trans, __bch2_subvolume_get_snapshot(trans, inum.subvol, &snapshot, warn_errors));
+       if (ret)
+               return ret;
+
        bch2_trans_iter_init(trans, &iter, BTREE_ID_extents,
                             POS(inum.inum, 0),
                             BTREE_ITER_intent);
@@ -373,7 +391,7 @@ case LOGGED_OP_FINSERT_start:
 
        if (insert) {
                ret = commit_do(trans, NULL, NULL, BCH_TRANS_COMMIT_no_enospc,
-                               adjust_i_size(trans, inum, src_offset, len) ?:
+                               adjust_i_size(trans, inum, src_offset, len, warn_errors) ?:
                                bch2_logged_op_update(trans, &op->k_i));
                if (ret)
                        goto err;
@@ -396,11 +414,11 @@ case LOGGED_OP_FINSERT_shift_extents:
                struct bkey_i delete, *copy;
                struct bkey_s_c k;
                struct bpos src_pos = POS(inum.inum, src_offset);
-               u32 snapshot;
 
                bch2_trans_begin(trans);
 
-               ret = bch2_subvolume_get_snapshot(trans, inum.subvol, &snapshot);
+               ret = __bch2_subvolume_get_snapshot(trans, inum.subvol, &snapshot,
+                                                   warn_errors);
                if (ret)
                        goto btree_err;
 
@@ -463,12 +481,12 @@ btree_err:
 
        if (!insert) {
                ret = commit_do(trans, NULL, NULL, BCH_TRANS_COMMIT_no_enospc,
-                               adjust_i_size(trans, inum, src_offset, shift) ?:
+                               adjust_i_size(trans, inum, src_offset, shift, warn_errors) ?:
                                bch2_logged_op_update(trans, &op->k_i));
        } else {
                /* We need an inode update to update bi_journal_seq for fsync: */
                ret = commit_do(trans, NULL, NULL, BCH_TRANS_COMMIT_no_enospc,
-                               adjust_i_size(trans, inum, 0, 0) ?:
+                               adjust_i_size(trans, inum, 0, 0, warn_errors) ?:
                                bch2_logged_op_update(trans, &op->k_i));
        }
 
@@ -477,9 +495,9 @@ case LOGGED_OP_FINSERT_finish:
        break;
        }
 err:
-       bch_err_fn(c, ret);
-       bch2_logged_op_finish(trans, op_k);
        bch2_trans_iter_exit(trans, &iter);
+       if (warn_errors)
+               bch_err_fn(c, ret);
        return ret;
 }
 
@@ -508,9 +526,14 @@ int bch2_fcollapse_finsert(struct bch_fs *c, subvol_inum inum,
         * resume only proceeding in one of the snapshots
         */
        down_read(&c->snapshot_create_lock);
-       int ret = bch2_trans_run(c,
-               bch2_logged_op_start(trans, &op.k_i) ?:
-               __bch2_resume_logged_op_finsert(trans, &op.k_i, i_sectors_delta));
+       struct btree_trans *trans = bch2_trans_get(c);
+       int ret = bch2_logged_op_start(trans, &op.k_i);
+       if (ret)
+               goto out;
+       ret = __bch2_resume_logged_op_finsert(trans, &op.k_i, i_sectors_delta);
+       ret = bch2_logged_op_finish(trans, &op.k_i) ?: ret;
+out:
+       bch2_trans_put(trans);
        up_read(&c->snapshot_create_lock);
 
        return ret;
index e4fc17c548fd556f056c01163a8bbddce3855421..fc246f342820f59437888547d0e4e1ca97d94141 100644 (file)
@@ -409,8 +409,8 @@ retry:
        bch2_trans_begin(trans);
        rbio->bio.bi_status = 0;
 
-       k = bch2_btree_iter_peek_slot(&iter);
-       if (bkey_err(k))
+       ret = lockrestart_do(trans, bkey_err(k = bch2_btree_iter_peek_slot(&iter)));
+       if (ret)
                goto err;
 
        bch2_bkey_buf_reassemble(&sk, c, k);
@@ -557,8 +557,8 @@ out:
 
 static noinline void bch2_rbio_narrow_crcs(struct bch_read_bio *rbio)
 {
-       bch2_trans_do(rbio->c, NULL, NULL, BCH_TRANS_COMMIT_no_enospc,
-                     __bch2_rbio_narrow_crcs(trans, rbio));
+       bch2_trans_commit_do(rbio->c, NULL, NULL, BCH_TRANS_COMMIT_no_enospc,
+                            __bch2_rbio_narrow_crcs(trans, rbio));
 }
 
 /* Inner part that may run in process context */
index b5fe9e0dc1557c7f52d18fbf60c791940043af32..8609e25e450f599006a480cc2044379781d7144f 100644 (file)
@@ -1437,7 +1437,7 @@ again:
                 * freeing up space on specific disks, which means that
                 * allocations for specific disks may hang arbitrarily long:
                 */
-               ret = bch2_trans_do(c, NULL, NULL, 0,
+               ret = bch2_trans_run(c, lockrestart_do(trans,
                        bch2_alloc_sectors_start_trans(trans,
                                op->target,
                                op->opts.erasure_code && !(op->flags & BCH_WRITE_CACHED),
@@ -1447,7 +1447,7 @@ again:
                                op->nr_replicas_required,
                                op->watermark,
                                op->flags,
-                               &op->cl, &wp));
+                               &op->cl, &wp)));
                if (unlikely(ret)) {
                        if (bch2_err_matches(ret, BCH_ERR_operation_blocked))
                                break;
index f5f7db50ca310c3a5d8fc39f25925f516230bc6d..2dc0d60c174509f20fdf1d89685c7074bf93c375 100644 (file)
@@ -603,6 +603,19 @@ int bch2_journal_res_get_slowpath(struct journal *j, struct journal_res *res,
 {
        int ret;
 
+       if (closure_wait_event_timeout(&j->async_wait,
+                  (ret = __journal_res_get(j, res, flags)) != -BCH_ERR_journal_res_get_blocked ||
+                  (flags & JOURNAL_RES_GET_NONBLOCK),
+                  HZ * 10))
+               return ret;
+
+       struct bch_fs *c = container_of(j, struct bch_fs, journal);
+       struct printbuf buf = PRINTBUF;
+       bch2_journal_debug_to_text(&buf, j);
+       bch_err(c, "Journal stuck? Waited for 10 seconds...\n%s",
+               buf.buf);
+       printbuf_exit(&buf);
+
        closure_wait_event(&j->async_wait,
                   (ret = __journal_res_get(j, res, flags)) != -BCH_ERR_journal_res_get_blocked ||
                   (flags & JOURNAL_RES_GET_NONBLOCK));
@@ -745,7 +758,7 @@ out:
        return ret;
 }
 
-int bch2_journal_flush_seq(struct journal *j, u64 seq)
+int bch2_journal_flush_seq(struct journal *j, u64 seq, unsigned task_state)
 {
        u64 start_time = local_clock();
        int ret, ret2;
@@ -756,7 +769,9 @@ int bch2_journal_flush_seq(struct journal *j, u64 seq)
        if (seq <= j->flushed_seq_ondisk)
                return 0;
 
-       ret = wait_event_interruptible(j->wait, (ret2 = bch2_journal_flush_seq_async(j, seq, NULL)));
+       ret = wait_event_state(j->wait,
+                              (ret2 = bch2_journal_flush_seq_async(j, seq, NULL)),
+                              task_state);
 
        if (!ret)
                bch2_time_stats_update(j->flush_seq_time, start_time);
@@ -775,7 +790,7 @@ void bch2_journal_flush_async(struct journal *j, struct closure *parent)
 
 int bch2_journal_flush(struct journal *j)
 {
-       return bch2_journal_flush_seq(j, atomic64_read(&j->seq));
+       return bch2_journal_flush_seq(j, atomic64_read(&j->seq), TASK_UNINTERRUPTIBLE);
 }
 
 /*
@@ -838,7 +853,7 @@ int bch2_journal_meta(struct journal *j)
 
        bch2_journal_res_put(j, &res);
 
-       return bch2_journal_flush_seq(j, res.seq);
+       return bch2_journal_flush_seq(j, res.seq, TASK_UNINTERRUPTIBLE);
 }
 
 /* block/unlock the journal: */
index 377a3750406e4c86d6da57716d9ef1d81f607dbf..2762be6f9814c9c0417d08279abc7d0e66d7de49 100644 (file)
@@ -401,7 +401,7 @@ void bch2_journal_entry_res_resize(struct journal *,
 int bch2_journal_flush_seq_async(struct journal *, u64, struct closure *);
 void bch2_journal_flush_async(struct journal *, struct closure *);
 
-int bch2_journal_flush_seq(struct journal *, u64);
+int bch2_journal_flush_seq(struct journal *, u64, unsigned);
 int bch2_journal_flush(struct journal *);
 bool bch2_journal_noflush_seq(struct journal *, u64);
 int bch2_journal_meta(struct journal *);
index 6f4a4e1083c9558cfe811617915e90f535f5cd2e..60e00702d1a46e41dc3cc0b5818fd108b8487ca6 100644 (file)
@@ -34,8 +34,6 @@ static int resume_logged_op(struct btree_trans *trans, struct btree_iter *iter,
                            struct bkey_s_c k)
 {
        struct bch_fs *c = trans->c;
-       const struct bch_logged_op_fn *fn = logged_op_fn(k.k->type);
-       struct bkey_buf sk;
        u32 restart_count = trans->restart_count;
        struct printbuf buf = PRINTBUF;
        int ret = 0;
@@ -46,13 +44,15 @@ static int resume_logged_op(struct btree_trans *trans, struct btree_iter *iter,
                    (bch2_bkey_val_to_text(&buf, c, k),
                     buf.buf));
 
-       if (!fn)
-               return 0;
-
+       struct bkey_buf sk;
        bch2_bkey_buf_init(&sk);
        bch2_bkey_buf_reassemble(&sk, c, k);
 
-       fn->resume(trans, sk.k);
+       const struct bch_logged_op_fn *fn = logged_op_fn(sk.k->k.type);
+       if (fn)
+               fn->resume(trans, sk.k);
+
+       ret = bch2_logged_op_finish(trans, sk.k);
 
        bch2_bkey_buf_exit(&sk, c);
 fsck_err:
@@ -93,7 +93,7 @@ int bch2_logged_op_start(struct btree_trans *trans, struct bkey_i *k)
                         __bch2_logged_op_start(trans, k));
 }
 
-void bch2_logged_op_finish(struct btree_trans *trans, struct bkey_i *k)
+int bch2_logged_op_finish(struct btree_trans *trans, struct bkey_i *k)
 {
        int ret = commit_do(trans, NULL, NULL, BCH_TRANS_COMMIT_no_enospc,
                            bch2_btree_delete(trans, BTREE_ID_logged_ops, k->k.p, 0));
@@ -113,4 +113,6 @@ void bch2_logged_op_finish(struct btree_trans *trans, struct bkey_i *k)
                                    buf.buf, bch2_err_str(ret));
                printbuf_exit(&buf);
        }
+
+       return ret;
 }
index 4d1e786a27a89fcf733d6cd937662274c885fdcc..30ae9ef737dd95a806d4d92cddf6defb361195fe 100644 (file)
@@ -15,6 +15,6 @@ static inline int bch2_logged_op_update(struct btree_trans *trans, struct bkey_i
 
 int bch2_resume_logged_ops(struct bch_fs *);
 int bch2_logged_op_start(struct btree_trans *, struct bkey_i *);
-void bch2_logged_op_finish(struct btree_trans *, struct bkey_i *);
+int bch2_logged_op_finish(struct btree_trans *, struct bkey_i *);
 
 #endif /* _BCACHEFS_LOGGED_OPS_H */
index 96f2f4f8c39787e79fc5f831d9a12edd4f0dae95..10857eccdeafe8f629eee8c2a2578862da749574 100644 (file)
@@ -2,6 +2,7 @@
 
 #include "bcachefs.h"
 #include "alloc_background.h"
+#include "bkey_buf.h"
 #include "btree_iter.h"
 #include "btree_update.h"
 #include "btree_write_buffer.h"
@@ -118,7 +119,7 @@ fsck_err:
 static int bch2_check_lru_key(struct btree_trans *trans,
                              struct btree_iter *lru_iter,
                              struct bkey_s_c lru_k,
-                             struct bpos *last_flushed_pos)
+                             struct bkey_buf *last_flushed)
 {
        struct bch_fs *c = trans->c;
        struct btree_iter iter;
@@ -132,11 +133,13 @@ static int bch2_check_lru_key(struct btree_trans *trans,
        u64 idx;
        int ret;
 
-       if (fsck_err_on(!bch2_dev_bucket_exists(c, alloc_pos),
+       struct bch_dev *ca = bch2_dev_bucket_tryget_noerror(c, alloc_pos);
+
+       if (fsck_err_on(!ca,
                        trans, lru_entry_to_invalid_bucket,
                        "lru key points to nonexistent device:bucket %llu:%llu",
                        alloc_pos.inode, alloc_pos.offset))
-               return bch2_btree_delete_at(trans, lru_iter, 0);
+               return bch2_btree_bit_mod_buffered(trans, BTREE_ID_lru, lru_iter->pos, false);
 
        k = bch2_bkey_get_iter(trans, &iter, BTREE_ID_alloc, alloc_pos, 0);
        ret = bkey_err(k);
@@ -150,18 +153,15 @@ static int bch2_check_lru_key(struct btree_trans *trans,
                idx = alloc_lru_idx_read(*a);
                break;
        case BCH_LRU_fragmentation:
-               idx = a->fragmentation_lru;
+               idx = alloc_lru_idx_fragmentation(*a, ca);
                break;
        }
 
        if (lru_k.k->type != KEY_TYPE_set ||
            lru_pos_time(lru_k.k->p) != idx) {
-               if (!bpos_eq(*last_flushed_pos, lru_k.k->p)) {
-                       *last_flushed_pos = lru_k.k->p;
-                       ret = bch2_btree_write_buffer_flush_sync(trans) ?:
-                               -BCH_ERR_transaction_restart_write_buffer_flush;
-                       goto out;
-               }
+               ret = bch2_btree_write_buffer_maybe_flush(trans, lru_k, last_flushed);
+               if (ret)
+                       goto err;
 
                if (fsck_err(trans, lru_entry_bad,
                             "incorrect lru entry: lru %s time %llu\n"
@@ -171,12 +171,12 @@ static int bch2_check_lru_key(struct btree_trans *trans,
                             lru_pos_time(lru_k.k->p),
                             (bch2_bkey_val_to_text(&buf1, c, lru_k), buf1.buf),
                             (bch2_bkey_val_to_text(&buf2, c, k), buf2.buf)))
-                       ret = bch2_btree_delete_at(trans, lru_iter, 0);
+                       ret = bch2_btree_bit_mod_buffered(trans, BTREE_ID_lru, lru_iter->pos, false);
        }
-out:
 err:
 fsck_err:
        bch2_trans_iter_exit(trans, &iter);
+       bch2_dev_put(ca);
        printbuf_exit(&buf2);
        printbuf_exit(&buf1);
        return ret;
@@ -184,12 +184,18 @@ fsck_err:
 
 int bch2_check_lrus(struct bch_fs *c)
 {
-       struct bpos last_flushed_pos = POS_MIN;
+       struct bkey_buf last_flushed;
+
+       bch2_bkey_buf_init(&last_flushed);
+       bkey_init(&last_flushed.k->k);
+
        int ret = bch2_trans_run(c,
                for_each_btree_key_commit(trans, iter,
                                BTREE_ID_lru, POS_MIN, BTREE_ITER_prefetch, k,
                                NULL, NULL, BCH_TRANS_COMMIT_no_enospc|BCH_TRANS_COMMIT_lazy_rw,
-                       bch2_check_lru_key(trans, &iter, k, &last_flushed_pos)));
+                       bch2_check_lru_key(trans, &iter, k, &last_flushed)));
+
+       bch2_bkey_buf_exit(&last_flushed, c);
        bch_err_fn(c, ret);
        return ret;
 
index 7d3920e03742deebce5798731c98a36ef1e9369d..0ef4a86850bbc8773b1315f4bb88bfd41c1b84a4 100644 (file)
@@ -266,7 +266,7 @@ int bch2_move_extent(struct moving_context *ctxt,
        if (!data_opts.rewrite_ptrs &&
            !data_opts.extra_replicas) {
                if (data_opts.kill_ptrs)
-                       return bch2_extent_drop_ptrs(trans, iter, k, data_opts);
+                       return bch2_extent_drop_ptrs(trans, iter, k, &io_opts, &data_opts);
                return 0;
        }
 
@@ -692,7 +692,7 @@ int bch2_evacuate_bucket(struct moving_context *ctxt,
        a = bch2_alloc_to_v4(k, &a_convert);
        dirty_sectors = bch2_bucket_sectors_dirty(*a);
        bucket_size = ca->mi.bucket_size;
-       fragmentation = a->fragmentation_lru;
+       fragmentation = alloc_lru_idx_fragmentation(*a, ca);
 
        ret = bch2_btree_write_buffer_tryflush(trans);
        bch_err_msg(c, ret, "flushing btree write buffer");
index d86565bf07c8c563cb5651d2ea7e585a3f2ff7df..d658be90f7378fb16831430fd96a8766a2978218 100644 (file)
@@ -73,6 +73,7 @@ move_bucket_in_flight_add(struct buckets_in_flight *list, struct move_bucket b)
 static int bch2_bucket_is_movable(struct btree_trans *trans,
                                  struct move_bucket *b, u64 time)
 {
+       struct bch_fs *c = trans->c;
        struct btree_iter iter;
        struct bkey_s_c k;
        struct bch_alloc_v4 _a;
@@ -90,14 +91,19 @@ static int bch2_bucket_is_movable(struct btree_trans *trans,
        if (ret)
                return ret;
 
+       struct bch_dev *ca = bch2_dev_tryget(c, k.k->p.inode);
+       if (!ca)
+               goto out;
+
        a = bch2_alloc_to_v4(k, &_a);
        b->k.gen        = a->gen;
        b->sectors      = bch2_bucket_sectors_dirty(*a);
+       u64 lru_idx     = alloc_lru_idx_fragmentation(*a, ca);
 
-       ret = data_type_movable(a->data_type) &&
-               a->fragmentation_lru &&
-               a->fragmentation_lru <= time;
+       ret = lru_idx && lru_idx <= time;
 
+       bch2_dev_put(ca);
+out:
        bch2_trans_iter_exit(trans, &iter);
        return ret;
 }
index 232be8a44051ffcf6b75951827c465b9aedfab61..6673cbd8bdb944c080e874bf504eaa39f2e4c3ca 100644 (file)
@@ -63,7 +63,7 @@ const char * const bch2_compression_opts[] = {
        NULL
 };
 
-const char * const bch2_str_hash_types[] = {
+const char * const __bch2_str_hash_types[] = {
        BCH_STR_HASH_TYPES()
        NULL
 };
@@ -115,6 +115,7 @@ PRT_STR_OPT_BOUNDSCHECKED(fs_usage_type,    enum bch_fs_usage_type);
 PRT_STR_OPT_BOUNDSCHECKED(data_type,           enum bch_data_type);
 PRT_STR_OPT_BOUNDSCHECKED(csum_type,           enum bch_csum_type);
 PRT_STR_OPT_BOUNDSCHECKED(compression_type,    enum bch_compression_type);
+PRT_STR_OPT_BOUNDSCHECKED(str_hash_type,       enum bch_str_hash_type);
 
 static int bch2_opt_fix_errors_parse(struct bch_fs *c, const char *val, u64 *res,
                                     struct printbuf *err)
@@ -427,7 +428,9 @@ void bch2_opt_to_text(struct printbuf *out,
                        prt_printf(out, "%lli", v);
                break;
        case BCH_OPT_STR:
-               if (flags & OPT_SHOW_FULL_LIST)
+               if (v < opt->min || v >= opt->max - 1)
+                       prt_printf(out, "(invalid option %lli)", v);
+               else if (flags & OPT_SHOW_FULL_LIST)
                        prt_string_option(out, opt->choices, v);
                else
                        prt_str(out, opt->choices[v]);
@@ -594,6 +597,9 @@ int bch2_parse_mount_opts(struct bch_fs *c, struct bch_opts *opts,
        copied_opts_start = copied_opts;
 
        while ((opt = strsep(&copied_opts, ",")) != NULL) {
+               if (!*opt)
+                       continue;
+
                name    = strsep(&opt, "=");
                val     = opt;
 
index cb2e244a24298393b0be3ee8fd4b4991d6bf93f4..23dda014e331b132d21511684cd6ba2e0e55ea82 100644 (file)
@@ -18,7 +18,7 @@ extern const char * const bch2_sb_compat[];
 extern const char * const __bch2_btree_ids[];
 extern const char * const bch2_csum_opts[];
 extern const char * const bch2_compression_opts[];
-extern const char * const bch2_str_hash_types[];
+extern const char * const __bch2_str_hash_types[];
 extern const char * const bch2_str_hash_opts[];
 extern const char * const __bch2_data_types[];
 extern const char * const bch2_member_states[];
@@ -29,6 +29,7 @@ void bch2_prt_fs_usage_type(struct printbuf *,                enum bch_fs_usage_type);
 void bch2_prt_data_type(struct printbuf *,             enum bch_data_type);
 void bch2_prt_csum_type(struct printbuf *,             enum bch_csum_type);
 void bch2_prt_compression_type(struct printbuf *,      enum bch_compression_type);
+void bch2_prt_str_hash_type(struct printbuf *,         enum bch_str_hash_type);
 
 static inline const char *bch2_d_type_str(unsigned d_type)
 {
index c32a05e252e2abcbcc073db148741b531d11dfe8..74f45a8162ad7f649a8157bf7ddfd54c73021061 100644 (file)
@@ -869,7 +869,7 @@ static int bch2_set_quota(struct super_block *sb, struct kqid qid,
        bkey_quota_init(&new_quota.k_i);
        new_quota.k.p = POS(qid.type, from_kqid(&init_user_ns, qid));
 
-       ret = bch2_trans_do(c, NULL, NULL, 0,
+       ret = bch2_trans_commit_do(c, NULL, NULL, 0,
                            bch2_set_quota_trans(trans, &new_quota, qdq)) ?:
                __bch2_quota_set(c, bkey_i_to_s_c(&new_quota.k_i), qdq);
 
index 2d299a37cf07d7ea07290e0d08b543925e06143a..cd6647374353fb167dfb075a58350f33429f6b9d 100644 (file)
@@ -70,7 +70,9 @@ err:
 
 int bch2_set_rebalance_needs_scan(struct bch_fs *c, u64 inum)
 {
-       int ret = bch2_trans_do(c, NULL, NULL, BCH_TRANS_COMMIT_no_enospc|BCH_TRANS_COMMIT_lazy_rw,
+       int ret = bch2_trans_commit_do(c, NULL, NULL,
+                                      BCH_TRANS_COMMIT_no_enospc|
+                                      BCH_TRANS_COMMIT_lazy_rw,
                            __bch2_set_rebalance_needs_scan(trans, inum));
        rebalance_wakeup(c);
        return ret;
index 6db72d3bad7db76bb5908d99c8b0a98236462cdd..32d15aacc06986d7ab01e41b5a18dc93ff7a35ef 100644 (file)
@@ -94,11 +94,10 @@ static void bch2_reconstruct_alloc(struct bch_fs *c)
        __set_bit_le64(BCH_FSCK_ERR_accounting_mismatch, ext->errors_silent);
        c->sb.compat &= ~(1ULL << BCH_COMPAT_alloc_info);
 
-       bch2_write_super(c);
-       mutex_unlock(&c->sb_lock);
-
        c->opts.recovery_passes |= bch2_recovery_passes_from_stable(le64_to_cpu(ext->recovery_passes_required[0]));
 
+       bch2_write_super(c);
+       mutex_unlock(&c->sb_lock);
 
        bch2_shoot_down_journal_keys(c, BTREE_ID_alloc,
                                     0, BTREE_MAX_DEPTH, POS_MIN, SPOS_MAX);
@@ -287,7 +286,8 @@ int bch2_journal_replay(struct bch_fs *c)
                                BCH_TRANS_COMMIT_no_enospc|
                                BCH_TRANS_COMMIT_journal_reclaim|
                                BCH_TRANS_COMMIT_skip_accounting_apply|
-                               BCH_TRANS_COMMIT_no_journal_res,
+                               BCH_TRANS_COMMIT_no_journal_res|
+                               BCH_WATERMARK_reclaim,
                             bch2_journal_replay_accounting_key(trans, k));
                if (bch2_fs_fatal_err_on(ret, c, "error replaying accounting; %s", bch2_err_str(ret)))
                        goto err;
@@ -1001,6 +1001,7 @@ int bch2_fs_initialize(struct bch_fs *c)
        struct bch_inode_unpacked root_inode, lostfound_inode;
        struct bkey_inode_buf packed_inode;
        struct qstr lostfound = QSTR("lost+found");
+       struct bch_member *m;
        int ret;
 
        bch_notice(c, "initializing new filesystem");
@@ -1017,6 +1018,14 @@ int bch2_fs_initialize(struct bch_fs *c)
                SET_BCH_SB_VERSION_UPGRADE_COMPLETE(c->disk_sb.sb, bcachefs_metadata_version_current);
                bch2_write_super(c);
        }
+
+       for_each_member_device(c, ca) {
+               m = bch2_members_v2_get_mut(c->disk_sb.sb, ca->dev_idx);
+               SET_BCH_MEMBER_FREESPACE_INITIALIZED(m, false);
+               ca->mi = bch2_mi_to_cpu(m);
+       }
+
+       bch2_write_super(c);
        mutex_unlock(&c->sb_lock);
 
        c->curr_recovery_pass = BCH_RECOVERY_PASS_NR;
@@ -1090,7 +1099,7 @@ int bch2_fs_initialize(struct bch_fs *c)
 
        bch2_inode_init_early(c, &lostfound_inode);
 
-       ret = bch2_trans_do(c, NULL, NULL, 0,
+       ret = bch2_trans_commit_do(c, NULL, NULL, 0,
                bch2_create_trans(trans,
                                  BCACHEFS_ROOT_SUBVOL_INUM,
                                  &root_inode, &lostfound_inode,
index 50406ce0e4ef12336a9ff65c8ecaa4e5871ccb9a..9d96c06e365c93700df5d056ea7e59973ffddd1d 100644 (file)
@@ -46,6 +46,7 @@
        x(check_dirents,                        27, PASS_FSCK)                  \
        x(check_xattrs,                         28, PASS_FSCK)                  \
        x(check_root,                           29, PASS_ONLINE|PASS_FSCK)      \
+       x(check_unreachable_inodes,             40, PASS_ONLINE|PASS_FSCK)      \
        x(check_subvolume_structure,            36, PASS_ONLINE|PASS_FSCK)      \
        x(check_directory_structure,            30, PASS_ONLINE|PASS_FSCK)      \
        x(check_nlinks,                         31, PASS_FSCK)                  \
index bcb3276747e0086a76e2e4c0db905ab2dc253fec..477ef0997949bf6dab11f739d0d547db92b6d3fb 100644 (file)
@@ -66,9 +66,9 @@ void bch2_replicas_entry_to_text(struct printbuf *out,
        prt_printf(out, "]");
 }
 
-static int bch2_replicas_entry_validate_locked(struct bch_replicas_entry_v1 *r,
-                                              struct bch_sb *sb,
-                                              struct printbuf *err)
+static int bch2_replicas_entry_sb_validate(struct bch_replicas_entry_v1 *r,
+                                          struct bch_sb *sb,
+                                          struct printbuf *err)
 {
        if (!r->nr_devs) {
                prt_printf(err, "no devices in entry ");
@@ -98,10 +98,28 @@ int bch2_replicas_entry_validate(struct bch_replicas_entry_v1 *r,
                                 struct bch_fs *c,
                                 struct printbuf *err)
 {
-       mutex_lock(&c->sb_lock);
-       int ret = bch2_replicas_entry_validate_locked(r, c->disk_sb.sb, err);
-       mutex_unlock(&c->sb_lock);
-       return ret;
+       if (!r->nr_devs) {
+               prt_printf(err, "no devices in entry ");
+               goto bad;
+       }
+
+       if (r->nr_required > 1 &&
+           r->nr_required >= r->nr_devs) {
+               prt_printf(err, "bad nr_required in entry ");
+               goto bad;
+       }
+
+       for (unsigned i = 0; i < r->nr_devs; i++)
+               if (r->devs[i] != BCH_SB_MEMBER_INVALID &&
+                   !bch2_dev_exists(c, r->devs[i])) {
+                       prt_printf(err, "invalid device %u in entry ", r->devs[i]);
+                       goto bad;
+               }
+
+       return 0;
+bad:
+       bch2_replicas_entry_to_text(err, r);
+       return -BCH_ERR_invalid_replicas_entry;
 }
 
 void bch2_cpu_replicas_to_text(struct printbuf *out,
@@ -686,7 +704,7 @@ static int bch2_cpu_replicas_validate(struct bch_replicas_cpu *cpu_r,
                struct bch_replicas_entry_v1 *e =
                        cpu_replicas_entry(cpu_r, i);
 
-               int ret = bch2_replicas_entry_validate_locked(e, sb, err);
+               int ret = bch2_replicas_entry_sb_validate(e, sb, err);
                if (ret)
                        return ret;
 
@@ -803,6 +821,11 @@ bool bch2_have_enough_devs(struct bch_fs *c, struct bch_devs_mask devs,
 
                rcu_read_lock();
                for (unsigned i = 0; i < e->nr_devs; i++) {
+                       if (e->devs[i] == BCH_SB_MEMBER_INVALID) {
+                               nr_failed++;
+                               continue;
+                       }
+
                        nr_online += test_bit(e->devs[i], devs.d);
 
                        struct bch_dev *ca = bch2_dev_rcu_noerror(c, e->devs[i]);
index 5102059a0f1dce162dc1df8cc2dcf458d7084f28..8767c33c2b513f87db7b58bcd179bdf7c3685e0a 100644 (file)
          BCH_FSCK_ERR_accounting_mismatch)                     \
        x(rebalance_work_acct_fix,                              \
          BIT_ULL(BCH_RECOVERY_PASS_check_allocations),         \
-         BCH_FSCK_ERR_accounting_mismatch)
+         BCH_FSCK_ERR_accounting_mismatch)                     \
+       x(inode_has_child_snapshots,                            \
+         BIT_ULL(BCH_RECOVERY_PASS_check_inodes),              \
+         BCH_FSCK_ERR_inode_has_child_snapshots_wrong)
 
 #define DOWNGRADE_TABLE()                                      \
        x(bucket_stripe_sectors,                                \
@@ -140,6 +143,9 @@ UPGRADE_TABLE()
 
 static int have_stripes(struct bch_fs *c)
 {
+       if (IS_ERR_OR_NULL(c->btree_roots_known[BTREE_ID_stripes].b))
+               return 0;
+
        return !btree_node_fake(c->btree_roots_known[BTREE_ID_stripes].b);
 }
 
index ed5dca5e11617287b74960eb34c3e3f5294896e1..937275d061fe0c0bee6deadb6e062f39ff0adfa7 100644 (file)
@@ -115,8 +115,8 @@ enum bch_fsck_flags {
        x(alloc_key_data_type_inconsistency,                    101,    0)              \
        x(alloc_key_to_missing_dev_bucket,                      102,    0)              \
        x(alloc_key_cached_inconsistency,                       103,    0)              \
-       x(alloc_key_cached_but_read_time_zero,                  104,    0)              \
-       x(alloc_key_to_missing_lru_entry,                       105,    0)              \
+       x(alloc_key_cached_but_read_time_zero,                  104,    FSCK_AUTOFIX)   \
+       x(alloc_key_to_missing_lru_entry,                       105,    FSCK_AUTOFIX)   \
        x(alloc_key_data_type_wrong,                            106,    FSCK_AUTOFIX)   \
        x(alloc_key_gen_wrong,                                  107,    FSCK_AUTOFIX)   \
        x(alloc_key_dirty_sectors_wrong,                        108,    FSCK_AUTOFIX)   \
@@ -129,20 +129,20 @@ enum bch_fsck_flags {
        x(freespace_key_wrong,                                  115,    0)              \
        x(freespace_hole_missing,                               116,    0)              \
        x(bucket_gens_val_size_bad,                             117,    0)              \
-       x(bucket_gens_key_wrong,                                118,    0)              \
-       x(bucket_gens_hole_wrong,                               119,    0)              \
-       x(bucket_gens_to_invalid_dev,                           120,    0)              \
-       x(bucket_gens_to_invalid_buckets,                       121,    0)              \
-       x(bucket_gens_nonzero_for_invalid_buckets,              122,    0)              \
+       x(bucket_gens_key_wrong,                                118,    FSCK_AUTOFIX)   \
+       x(bucket_gens_hole_wrong,                               119,    FSCK_AUTOFIX)   \
+       x(bucket_gens_to_invalid_dev,                           120,    FSCK_AUTOFIX)   \
+       x(bucket_gens_to_invalid_buckets,                       121,    FSCK_AUTOFIX)   \
+       x(bucket_gens_nonzero_for_invalid_buckets,              122,    FSCK_AUTOFIX)   \
        x(need_discard_freespace_key_to_invalid_dev_bucket,     123,    0)              \
        x(need_discard_freespace_key_bad,                       124,    0)              \
        x(backpointer_bucket_offset_wrong,                      125,    0)              \
        x(backpointer_to_missing_device,                        126,    0)              \
        x(backpointer_to_missing_alloc,                         127,    0)              \
        x(backpointer_to_missing_ptr,                           128,    0)              \
-       x(lru_entry_at_time_0,                                  129,    0)              \
-       x(lru_entry_to_invalid_bucket,                          130,    0)              \
-       x(lru_entry_bad,                                        131,    0)              \
+       x(lru_entry_at_time_0,                                  129,    FSCK_AUTOFIX)   \
+       x(lru_entry_to_invalid_bucket,                          130,    FSCK_AUTOFIX)   \
+       x(lru_entry_bad,                                        131,    FSCK_AUTOFIX)   \
        x(btree_ptr_val_too_big,                                132,    0)              \
        x(btree_ptr_v2_val_too_big,                             133,    0)              \
        x(btree_ptr_has_non_ptr,                                134,    0)              \
@@ -158,9 +158,9 @@ enum bch_fsck_flags {
        x(ptr_after_last_bucket,                                144,    0)              \
        x(ptr_before_first_bucket,                              145,    0)              \
        x(ptr_spans_multiple_buckets,                           146,    0)              \
-       x(ptr_to_missing_backpointer,                           147,    0)              \
-       x(ptr_to_missing_alloc_key,                             148,    0)              \
-       x(ptr_to_missing_replicas_entry,                        149,    0)              \
+       x(ptr_to_missing_backpointer,                           147,    FSCK_AUTOFIX)   \
+       x(ptr_to_missing_alloc_key,                             148,    FSCK_AUTOFIX)   \
+       x(ptr_to_missing_replicas_entry,                        149,    FSCK_AUTOFIX)   \
        x(ptr_to_missing_stripe,                                150,    0)              \
        x(ptr_to_incorrect_stripe,                              151,    0)              \
        x(ptr_gen_newer_than_bucket_gen,                        152,    0)              \
@@ -180,6 +180,7 @@ enum bch_fsck_flags {
        x(reflink_p_to_missing_reflink_v,                       166,    0)              \
        x(stripe_pos_bad,                                       167,    0)              \
        x(stripe_val_size_bad,                                  168,    0)              \
+       x(stripe_csum_granularity_bad,                          290,    0)              \
        x(stripe_sector_count_wrong,                            169,    0)              \
        x(snapshot_tree_pos_bad,                                170,    0)              \
        x(snapshot_tree_to_missing_snapshot,                    171,    0)              \
@@ -194,7 +195,7 @@ enum bch_fsck_flags {
        x(snapshot_skiplist_not_normalized,                     180,    0)              \
        x(snapshot_skiplist_bad,                                181,    0)              \
        x(snapshot_should_not_have_subvol,                      182,    0)              \
-       x(snapshot_to_bad_snapshot_tree,                        183,    0)              \
+       x(snapshot_to_bad_snapshot_tree,                        183,    FSCK_AUTOFIX)   \
        x(snapshot_bad_depth,                                   184,    0)              \
        x(snapshot_bad_skiplist,                                185,    0)              \
        x(subvol_pos_bad,                                       186,    0)              \
@@ -211,6 +212,7 @@ enum bch_fsck_flags {
        x(inode_unlinked_but_clean,                             197,    0)              \
        x(inode_unlinked_but_nlink_nonzero,                     198,    0)              \
        x(inode_unlinked_and_not_open,                          281,    0)              \
+       x(inode_unlinked_but_has_dirent,                        285,    0)              \
        x(inode_checksum_type_invalid,                          199,    0)              \
        x(inode_compression_type_invalid,                       200,    0)              \
        x(inode_subvol_root_but_not_dir,                        201,    0)              \
@@ -219,14 +221,18 @@ enum bch_fsck_flags {
        x(inode_i_sectors_wrong,                                204,    FSCK_AUTOFIX)   \
        x(inode_dir_wrong_nlink,                                205,    FSCK_AUTOFIX)   \
        x(inode_dir_multiple_links,                             206,    FSCK_AUTOFIX)   \
+       x(inode_dir_missing_backpointer,                        284,    FSCK_AUTOFIX)   \
+       x(inode_dir_unlinked_but_not_empty,                     286,    FSCK_AUTOFIX)   \
        x(inode_multiple_links_but_nlink_0,                     207,    FSCK_AUTOFIX)   \
        x(inode_wrong_backpointer,                              208,    FSCK_AUTOFIX)   \
        x(inode_wrong_nlink,                                    209,    FSCK_AUTOFIX)   \
+       x(inode_has_child_snapshots_wrong,                      287,    0)              \
        x(inode_unreachable,                                    210,    FSCK_AUTOFIX)   \
        x(deleted_inode_but_clean,                              211,    FSCK_AUTOFIX)   \
        x(deleted_inode_missing,                                212,    FSCK_AUTOFIX)   \
        x(deleted_inode_is_dir,                                 213,    FSCK_AUTOFIX)   \
        x(deleted_inode_not_unlinked,                           214,    FSCK_AUTOFIX)   \
+       x(deleted_inode_has_child_snapshots,                    288,    FSCK_AUTOFIX)   \
        x(extent_overlapping,                                   215,    0)              \
        x(key_in_missing_inode,                                 216,    0)              \
        x(key_in_wrong_inode_type,                              217,    0)              \
@@ -261,8 +267,8 @@ enum bch_fsck_flags {
        x(journal_entry_dup_same_device,                        246,    0)              \
        x(inode_bi_subvol_missing,                              247,    0)              \
        x(inode_bi_subvol_wrong,                                248,    0)              \
-       x(inode_points_to_missing_dirent,                       249,    0)              \
-       x(inode_points_to_wrong_dirent,                         250,    0)              \
+       x(inode_points_to_missing_dirent,                       249,    FSCK_AUTOFIX)   \
+       x(inode_points_to_wrong_dirent,                         250,    FSCK_AUTOFIX)   \
        x(inode_bi_parent_nonzero,                              251,    0)              \
        x(dirent_to_missing_parent_subvol,                      252,    0)              \
        x(dirent_not_visible_in_parent_subvol,                  253,    0)              \
@@ -286,6 +292,7 @@ enum bch_fsck_flags {
        x(alloc_key_stripe_sectors_wrong,                       271,    FSCK_AUTOFIX)   \
        x(accounting_mismatch,                                  272,    FSCK_AUTOFIX)   \
        x(accounting_replicas_not_marked,                       273,    0)              \
+       x(accounting_to_invalid_device,                         289,    0)              \
        x(invalid_btree_id,                                     274,    0)              \
        x(alloc_key_io_time_bad,                                275,    0)              \
        x(alloc_key_fragmentation_lru_wrong,                    276,    FSCK_AUTOFIX)   \
@@ -295,7 +302,7 @@ enum bch_fsck_flags {
        x(accounting_key_replicas_devs_unsorted,                280,    FSCK_AUTOFIX)   \
        x(accounting_key_version_0,                             282,    FSCK_AUTOFIX)   \
        x(logged_op_but_clean,                                  283,    FSCK_AUTOFIX)   \
-       x(MAX,                                                  284,    0)
+       x(MAX,                                                  291,    0)
 
 enum bch_sb_error_id {
 #define x(t, n, ...) BCH_FSCK_ERR_##t = n,
index 02bcde3c1b021dfcc858569323b2a9eb69659d3f..fb08dd680dacf82bca414f424024e4a00bf432de 100644 (file)
@@ -163,6 +163,11 @@ static int validate_member(struct printbuf *err,
                return -BCH_ERR_invalid_sb_members;
        }
 
+       if (m.btree_bitmap_shift >= 64) {
+               prt_printf(err, "device %u: invalid btree_bitmap_shift %u", i, m.btree_bitmap_shift);
+               return -BCH_ERR_invalid_sb_members;
+       }
+
        return 0;
 }
 
@@ -247,7 +252,10 @@ static void member_to_text(struct printbuf *out,
        prt_newline(out);
 
        prt_printf(out, "Btree allocated bitmap blocksize:\t");
-       prt_units_u64(out, 1ULL << m.btree_bitmap_shift);
+       if (m.btree_bitmap_shift < 64)
+               prt_units_u64(out, 1ULL << m.btree_bitmap_shift);
+       else
+               prt_printf(out, "(invalid shift %u)", m.btree_bitmap_shift);
        prt_newline(out);
 
        prt_printf(out, "Btree allocated bitmap:\t");
index dc1a27cc31cd4de56cdc2e44026e4be7b789c34f..a1cc44e66c7ed518a93faec7275277606bf76903 100644 (file)
@@ -45,7 +45,7 @@
  */
 
 #include <asm/byteorder.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include <linux/bitops.h>
 #include <linux/string.h>
 
index 1809442b00ee44699c9ca7f9b509ed3d3e01f7c2..ae57638506c3aaafb24c92f21c764a2d21ddcbe7 100644 (file)
@@ -905,12 +905,30 @@ static int check_snapshot_exists(struct btree_trans *trans, u32 id)
        if (bch2_snapshot_equiv(c, id))
                return 0;
 
-       /* 0 is an invalid tree ID */
+       /* Do we need to reconstruct the snapshot_tree entry as well? */
+       struct btree_iter iter;
+       struct bkey_s_c k;
+       int ret = 0;
        u32 tree_id = 0;
-       int ret = bch2_snapshot_tree_create(trans, id, 0, &tree_id);
+
+       for_each_btree_key_norestart(trans, iter, BTREE_ID_snapshot_trees, POS_MIN,
+                                    0, k, ret) {
+               if (le32_to_cpu(bkey_s_c_to_snapshot_tree(k).v->root_snapshot) == id) {
+                       tree_id = k.k->p.offset;
+                       break;
+               }
+       }
+       bch2_trans_iter_exit(trans, &iter);
+
        if (ret)
                return ret;
 
+       if (!tree_id) {
+               ret = bch2_snapshot_tree_create(trans, id, 0, &tree_id);
+               if (ret)
+                       return ret;
+       }
+
        struct bkey_i_snapshot *snapshot = bch2_trans_kmalloc(trans, sizeof(*snapshot));
        ret = PTR_ERR_OR_ZERO(snapshot);
        if (ret)
@@ -921,6 +939,16 @@ static int check_snapshot_exists(struct btree_trans *trans, u32 id)
        snapshot->v.tree        = cpu_to_le32(tree_id);
        snapshot->v.btime.lo    = cpu_to_le64(bch2_current_time(c));
 
+       for_each_btree_key_norestart(trans, iter, BTREE_ID_subvolumes, POS_MIN,
+                                    0, k, ret) {
+               if (le32_to_cpu(bkey_s_c_to_subvolume(k).v->snapshot) == id) {
+                       snapshot->v.subvol = cpu_to_le32(k.k->p.offset);
+                       SET_BCH_SNAPSHOT_SUBVOL(&snapshot->v, true);
+                       break;
+               }
+       }
+       bch2_trans_iter_exit(trans, &iter);
+
        return  bch2_btree_insert_trans(trans, BTREE_ID_snapshots, &snapshot->k_i, 0) ?:
                bch2_mark_snapshot(trans, BTREE_ID_snapshots, 0,
                                   bkey_s_c_null, bkey_i_to_s(&snapshot->k_i), 0) ?:
@@ -1732,103 +1760,6 @@ int __bch2_key_has_snapshot_overwrites(struct btree_trans *trans,
        return ret;
 }
 
-static u32 bch2_snapshot_smallest_child(struct bch_fs *c, u32 id)
-{
-       const struct snapshot_t *s = snapshot_t(c, id);
-
-       return s->children[1] ?: s->children[0];
-}
-
-static u32 bch2_snapshot_smallest_descendent(struct bch_fs *c, u32 id)
-{
-       u32 child;
-
-       while ((child = bch2_snapshot_smallest_child(c, id)))
-               id = child;
-       return id;
-}
-
-static int bch2_propagate_key_to_snapshot_leaf(struct btree_trans *trans,
-                                              enum btree_id btree,
-                                              struct bkey_s_c interior_k,
-                                              u32 leaf_id, struct bpos *new_min_pos)
-{
-       struct btree_iter iter;
-       struct bpos pos = interior_k.k->p;
-       struct bkey_s_c k;
-       struct bkey_i *new;
-       int ret;
-
-       pos.snapshot = leaf_id;
-
-       bch2_trans_iter_init(trans, &iter, btree, pos, BTREE_ITER_intent);
-       k = bch2_btree_iter_peek_slot(&iter);
-       ret = bkey_err(k);
-       if (ret)
-               goto out;
-
-       /* key already overwritten in this snapshot? */
-       if (k.k->p.snapshot != interior_k.k->p.snapshot)
-               goto out;
-
-       if (bpos_eq(*new_min_pos, POS_MIN)) {
-               *new_min_pos = k.k->p;
-               new_min_pos->snapshot = leaf_id;
-       }
-
-       new = bch2_bkey_make_mut_noupdate(trans, interior_k);
-       ret = PTR_ERR_OR_ZERO(new);
-       if (ret)
-               goto out;
-
-       new->k.p.snapshot = leaf_id;
-       ret = bch2_trans_update(trans, &iter, new, 0);
-out:
-       bch2_set_btree_iter_dontneed(&iter);
-       bch2_trans_iter_exit(trans, &iter);
-       return ret;
-}
-
-int bch2_propagate_key_to_snapshot_leaves(struct btree_trans *trans,
-                                         enum btree_id btree,
-                                         struct bkey_s_c k,
-                                         struct bpos *new_min_pos)
-{
-       struct bch_fs *c = trans->c;
-       struct bkey_buf sk;
-       u32 restart_count = trans->restart_count;
-       int ret = 0;
-
-       bch2_bkey_buf_init(&sk);
-       bch2_bkey_buf_reassemble(&sk, c, k);
-       k = bkey_i_to_s_c(sk.k);
-
-       *new_min_pos = POS_MIN;
-
-       for (u32 id = bch2_snapshot_smallest_descendent(c, k.k->p.snapshot);
-            id < k.k->p.snapshot;
-            id++) {
-               if (!bch2_snapshot_is_ancestor(c, id, k.k->p.snapshot) ||
-                   !bch2_snapshot_is_leaf(c, id))
-                       continue;
-again:
-               ret =   btree_trans_too_many_iters(trans) ?:
-                       bch2_propagate_key_to_snapshot_leaf(trans, btree, k, id, new_min_pos) ?:
-                       bch2_trans_commit(trans, NULL, NULL, 0);
-               if (ret && bch2_err_matches(ret, BCH_ERR_transaction_restart)) {
-                       bch2_trans_begin(trans);
-                       goto again;
-               }
-
-               if (ret)
-                       break;
-       }
-
-       bch2_bkey_buf_exit(&sk, c);
-
-       return ret ?: trans_was_restarted(trans, restart_count);
-}
-
 static int bch2_check_snapshot_needs_deletion(struct btree_trans *trans, struct bkey_s_c k)
 {
        struct bch_fs *c = trans->c;
index eb5ef64221d6e11b9adb47fc0f3ddabedb729914..29c94716293e1ace5639ad62dd2c598df458318f 100644 (file)
@@ -259,9 +259,6 @@ static inline int bch2_key_has_snapshot_overwrites(struct btree_trans *trans,
        return __bch2_key_has_snapshot_overwrites(trans, id, pos);
 }
 
-int bch2_propagate_key_to_snapshot_leaves(struct btree_trans *, enum btree_id,
-                                         struct bkey_s_c, struct bpos *);
-
 int bch2_snapshots_read(struct bch_fs *);
 void bch2_fs_snapshots_exit(struct bch_fs *);
 
index 215eed4cce6d2c4111980c56f88a2b6ec82f4fa2..ec2b1feea5204c9fa2fc709c50282286f0e976fa 100644 (file)
@@ -46,8 +46,7 @@ bch2_hash_info_init(struct bch_fs *c, const struct bch_inode_unpacked *bi)
 {
        /* XXX ick */
        struct bch_hash_info info = {
-               .type = (bi->bi_flags >> INODE_STR_HASH_OFFSET) &
-                       ~(~0U << INODE_STR_HASH_BITS),
+               .type = INODE_STR_HASH(bi),
                .siphash_key = { .k0 = bi->bi_hash_seed }
        };
 
@@ -253,19 +252,20 @@ int bch2_hash_needs_whiteout(struct btree_trans *trans,
 }
 
 static __always_inline
-int bch2_hash_set_in_snapshot(struct btree_trans *trans,
+struct bkey_s_c bch2_hash_set_or_get_in_snapshot(struct btree_trans *trans,
+                          struct btree_iter *iter,
                           const struct bch_hash_desc desc,
                           const struct bch_hash_info *info,
                           subvol_inum inum, u32 snapshot,
                           struct bkey_i *insert,
                           enum btree_iter_update_trigger_flags flags)
 {
-       struct btree_iter iter, slot = { NULL };
+       struct btree_iter slot = {};
        struct bkey_s_c k;
        bool found = false;
        int ret;
 
-       for_each_btree_key_upto_norestart(trans, iter, desc.btree_id,
+       for_each_btree_key_upto_norestart(trans, *iter, desc.btree_id,
                           SPOS(insert->k.p.inode,
                                desc.hash_bkey(info, bkey_i_to_s_c(insert)),
                                snapshot),
@@ -280,7 +280,7 @@ int bch2_hash_set_in_snapshot(struct btree_trans *trans,
                }
 
                if (!slot.path && !(flags & STR_HASH_must_replace))
-                       bch2_trans_copy_iter(&slot, &iter);
+                       bch2_trans_copy_iter(&slot, iter);
 
                if (k.k->type != KEY_TYPE_hash_whiteout)
                        goto not_found;
@@ -290,28 +290,49 @@ int bch2_hash_set_in_snapshot(struct btree_trans *trans,
                ret = -BCH_ERR_ENOSPC_str_hash_create;
 out:
        bch2_trans_iter_exit(trans, &slot);
-       bch2_trans_iter_exit(trans, &iter);
-
-       return ret;
+       bch2_trans_iter_exit(trans, iter);
+       return ret ? bkey_s_c_err(ret) : bkey_s_c_null;
 found:
        found = true;
 not_found:
-
-       if (!found && (flags & STR_HASH_must_replace)) {
+       if (found && (flags & STR_HASH_must_create)) {
+               bch2_trans_iter_exit(trans, &slot);
+               return k;
+       } else if (!found && (flags & STR_HASH_must_replace)) {
                ret = -BCH_ERR_ENOENT_str_hash_set_must_replace;
-       } else if (found && (flags & STR_HASH_must_create)) {
-               ret = -BCH_ERR_EEXIST_str_hash_set;
        } else {
                if (!found && slot.path)
-                       swap(iter, slot);
+                       swap(*iter, slot);
 
-               insert->k.p = iter.pos;
-               ret = bch2_trans_update(trans, &iter, insert, flags);
+               insert->k.p = iter->pos;
+               ret = bch2_trans_update(trans, iter, insert, flags);
        }
 
        goto out;
 }
 
+static __always_inline
+int bch2_hash_set_in_snapshot(struct btree_trans *trans,
+                          const struct bch_hash_desc desc,
+                          const struct bch_hash_info *info,
+                          subvol_inum inum, u32 snapshot,
+                          struct bkey_i *insert,
+                          enum btree_iter_update_trigger_flags flags)
+{
+       struct btree_iter iter;
+       struct bkey_s_c k = bch2_hash_set_or_get_in_snapshot(trans, &iter, desc, info, inum,
+                                                            snapshot, insert, flags);
+       int ret = bkey_err(k);
+       if (ret)
+               return ret;
+       if (k.k) {
+               bch2_trans_iter_exit(trans, &iter);
+               return -BCH_ERR_EEXIST_str_hash_set;
+       }
+
+       return 0;
+}
+
 static __always_inline
 int bch2_hash_set(struct btree_trans *trans,
                  const struct bch_hash_desc desc,
@@ -363,8 +384,11 @@ int bch2_hash_delete(struct btree_trans *trans,
        struct btree_iter iter;
        struct bkey_s_c k = bch2_hash_lookup(trans, &iter, desc, info, inum, key,
                                             BTREE_ITER_intent);
-       int ret = bkey_err(k) ?:
-                 bch2_hash_delete_at(trans, desc, info, &iter, 0);
+       int ret = bkey_err(k);
+       if (ret)
+               return ret;
+
+       ret = bch2_hash_delete_at(trans, desc, info, &iter, 0);
        bch2_trans_iter_exit(trans, &iter);
        return ret;
 }
index 6845dde1b3397a822d3fd2048e70df8df25d3c9f..80e5efaff524be09a421f5dc62c3032c52914b7a 100644 (file)
@@ -102,7 +102,8 @@ static int check_subvol(struct btree_trans *trans,
                                inode.bi_inum, inode.bi_snapshot,
                                inode.bi_subvol, subvol.k->p.offset)) {
                        inode.bi_subvol = subvol.k->p.offset;
-                       ret = __bch2_fsck_write_inode(trans, &inode, le32_to_cpu(subvol.v->snapshot));
+                       inode.bi_snapshot = le32_to_cpu(subvol.v->snapshot);
+                       ret = __bch2_fsck_write_inode(trans, &inode);
                        if (ret)
                                goto err;
                }
@@ -318,8 +319,7 @@ int bch2_subvol_is_ro_trans(struct btree_trans *trans, u32 subvol)
 
 int bch2_subvol_is_ro(struct bch_fs *c, u32 subvol)
 {
-       return bch2_trans_do(c, NULL, NULL, 0,
-               bch2_subvol_is_ro_trans(trans, subvol));
+       return bch2_trans_do(c, bch2_subvol_is_ro_trans(trans, subvol));
 }
 
 int bch2_snapshot_get_subvol(struct btree_trans *trans, u32 snapshot,
@@ -331,8 +331,8 @@ int bch2_snapshot_get_subvol(struct btree_trans *trans, u32 snapshot,
                bch2_subvolume_get(trans, le32_to_cpu(snap.subvol), true, 0, subvol);
 }
 
-int bch2_subvolume_get_snapshot(struct btree_trans *trans, u32 subvolid,
-                               u32 *snapid)
+int __bch2_subvolume_get_snapshot(struct btree_trans *trans, u32 subvolid,
+                                 u32 *snapid, bool warn)
 {
        struct btree_iter iter;
        struct bkey_s_c_subvolume subvol;
@@ -343,7 +343,8 @@ int bch2_subvolume_get_snapshot(struct btree_trans *trans, u32 subvolid,
                                          BTREE_ITER_cached|BTREE_ITER_with_updates,
                                          subvolume);
        ret = bkey_err(subvol);
-       bch2_fs_inconsistent_on(bch2_err_matches(ret, ENOENT), trans->c,
+
+       bch2_fs_inconsistent_on(warn && bch2_err_matches(ret, ENOENT), trans->c,
                                "missing subvolume %u", subvolid);
 
        if (likely(!ret))
@@ -352,6 +353,12 @@ int bch2_subvolume_get_snapshot(struct btree_trans *trans, u32 subvolid,
        return ret;
 }
 
+int bch2_subvolume_get_snapshot(struct btree_trans *trans, u32 subvolid,
+                               u32 *snapid)
+{
+       return __bch2_subvolume_get_snapshot(trans, subvolid, snapid, true);
+}
+
 static int bch2_subvolume_reparent(struct btree_trans *trans,
                                   struct btree_iter *iter,
                                   struct bkey_s_c k,
@@ -668,8 +675,8 @@ err:
 /* set bi_subvol on root inode */
 int bch2_fs_upgrade_for_subvolumes(struct bch_fs *c)
 {
-       int ret = bch2_trans_do(c, NULL, NULL, BCH_TRANS_COMMIT_lazy_rw,
-                               __bch2_fs_upgrade_for_subvolumes(trans));
+       int ret = bch2_trans_commit_do(c, NULL, NULL, BCH_TRANS_COMMIT_lazy_rw,
+                                      __bch2_fs_upgrade_for_subvolumes(trans));
        bch_err_fn(c, ret);
        return ret;
 }
index e62f876541fe256806c01f8e05b1c48c695046ec..f897d106e14260f7da3df25ecce3ad9d207de1f1 100644 (file)
@@ -26,6 +26,8 @@ int bch2_subvolume_trigger(struct btree_trans *, enum btree_id, unsigned,
 int bch2_subvol_has_children(struct btree_trans *, u32);
 int bch2_subvolume_get(struct btree_trans *, unsigned,
                       bool, int, struct bch_subvolume *);
+int __bch2_subvolume_get_snapshot(struct btree_trans *, u32,
+                                 u32 *, bool);
 int bch2_subvolume_get_snapshot(struct btree_trans *, u32, u32 *);
 
 int bch2_subvol_is_ro_trans(struct btree_trans *, u32);
index ce7410d72089226e4421ca452a2c47d8f0e8c132..7c71594f6a8bd369100a32539ec4f263d2c4ed50 100644 (file)
@@ -287,6 +287,11 @@ static int validate_sb_layout(struct bch_sb_layout *layout, struct printbuf *out
                return -BCH_ERR_invalid_sb_layout_nr_superblocks;
        }
 
+       if (layout->sb_max_size_bits > BCH_SB_LAYOUT_SIZE_BITS_MAX) {
+               prt_printf(out, "Invalid superblock layout: max_size_bits too high");
+               return -BCH_ERR_invalid_sb_layout_sb_max_size_bits;
+       }
+
        max_sectors = 1 << layout->sb_max_size_bits;
 
        prev_offset = le64_to_cpu(layout->sb_offset[0]);
index 873e4be7e1dc0c0e427c35eec1e1b8e66fe1cb17..657fd3759e7b06bb352f25eb80036d59f43901f5 100644 (file)
@@ -184,6 +184,7 @@ static DEFINE_MUTEX(bch_fs_list_lock);
 
 DECLARE_WAIT_QUEUE_HEAD(bch2_read_only_wait);
 
+static void bch2_dev_unlink(struct bch_dev *);
 static void bch2_dev_free(struct bch_dev *);
 static int bch2_dev_alloc(struct bch_fs *, unsigned);
 static int bch2_dev_sysfs_online(struct bch_fs *, struct bch_dev *);
@@ -620,9 +621,7 @@ void __bch2_fs_stop(struct bch_fs *c)
        up_write(&c->state_lock);
 
        for_each_member_device(c, ca)
-               if (ca->kobj.state_in_sysfs &&
-                   ca->disk_sb.bdev)
-                       sysfs_remove_link(bdev_kobj(ca->disk_sb.bdev), "bcachefs");
+               bch2_dev_unlink(ca);
 
        if (c->kobj.state_in_sysfs)
                kobject_del(&c->kobj);
@@ -1187,9 +1186,7 @@ static void bch2_dev_free(struct bch_dev *ca)
 {
        cancel_work_sync(&ca->io_error_work);
 
-       if (ca->kobj.state_in_sysfs &&
-           ca->disk_sb.bdev)
-               sysfs_remove_link(bdev_kobj(ca->disk_sb.bdev), "bcachefs");
+       bch2_dev_unlink(ca);
 
        if (ca->kobj.state_in_sysfs)
                kobject_del(&ca->kobj);
@@ -1226,10 +1223,7 @@ static void __bch2_dev_offline(struct bch_fs *c, struct bch_dev *ca)
        percpu_ref_kill(&ca->io_ref);
        wait_for_completion(&ca->io_ref_completion);
 
-       if (ca->kobj.state_in_sysfs) {
-               sysfs_remove_link(bdev_kobj(ca->disk_sb.bdev), "bcachefs");
-               sysfs_remove_link(&ca->kobj, "block");
-       }
+       bch2_dev_unlink(ca);
 
        bch2_free_super(&ca->disk_sb);
        bch2_dev_journal_exit(ca);
@@ -1251,6 +1245,26 @@ static void bch2_dev_io_ref_complete(struct percpu_ref *ref)
        complete(&ca->io_ref_completion);
 }
 
+static void bch2_dev_unlink(struct bch_dev *ca)
+{
+       struct kobject *b;
+
+       /*
+        * This is racy w.r.t. the underlying block device being hot-removed,
+        * which removes it from sysfs.
+        *
+        * It'd be lovely if we had a way to handle this race, but the sysfs
+        * code doesn't appear to provide a good method and block/holder.c is
+        * susceptible as well:
+        */
+       if (ca->kobj.state_in_sysfs &&
+           ca->disk_sb.bdev &&
+           (b = bdev_kobj(ca->disk_sb.bdev))->state_in_sysfs) {
+               sysfs_remove_link(b, "bcachefs");
+               sysfs_remove_link(&ca->kobj, "block");
+       }
+}
+
 static int bch2_dev_sysfs_online(struct bch_fs *c, struct bch_dev *ca)
 {
        int ret;
@@ -1958,7 +1972,7 @@ int bch2_dev_resize(struct bch_fs *c, struct bch_dev *ca, u64 nbuckets)
                };
                u64 v[3] = { nbuckets - old_nbuckets, 0, 0 };
 
-               ret   = bch2_trans_do(ca->fs, NULL, NULL, 0,
+               ret   = bch2_trans_commit_do(ca->fs, NULL, NULL, 0,
                                bch2_disk_accounting_mod(trans, &acc, v, ARRAY_SIZE(v), false)) ?:
                        bch2_dev_freespace_init(c, ca, old_nbuckets, nbuckets);
                if (ret)
index b2f209743afeb50861e772f3e714fb95823e8a6b..315038a0a92d4df9c945d59c82dbf77889496205 100644 (file)
@@ -450,7 +450,7 @@ static int insert_test_overlapping_extent(struct bch_fs *c, u64 inum, u64 start,
        k.k_i.k.p.snapshot = snapid;
        k.k_i.k.size = len;
 
-       ret = bch2_trans_do(c, NULL, NULL, 0,
+       ret = bch2_trans_commit_do(c, NULL, NULL, 0,
                bch2_btree_insert_nonextent(trans, BTREE_ID_extents, &k.k_i,
                                            BTREE_UPDATE_internal_snapshot_node));
        bch_err_fn(c, ret);
@@ -510,7 +510,7 @@ static int test_snapshots(struct bch_fs *c, u64 nr)
        if (ret)
                return ret;
 
-       ret = bch2_trans_do(c, NULL, NULL, 0,
+       ret = bch2_trans_commit_do(c, NULL, NULL, 0,
                      bch2_snapshot_node_create(trans, U32_MAX,
                                                snapids,
                                                snapid_subvols,
index 42f565c76181715e5e0b24e5a5df2dd14758b0b4..e0a876cbaa6b78eda3f9fe5d718b4fd609193330 100644 (file)
@@ -222,7 +222,7 @@ u64 bch2_read_flag_list(const char *opt, const char * const list[])
                        break;
                }
 
-               ret |= 1 << flag;
+               ret |= BIT_ULL(flag);
        }
 
        kfree(d);
index a9ebcd82c60254080c077d7fc4b907fb6634a424..6a78553d9b0cde0f02377a6de138b4353964fd52 100644 (file)
@@ -3,7 +3,7 @@
 #include <linux/bitops.h>
 #include <linux/math.h>
 #include <linux/string.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #ifdef CONFIG_VALGRIND
 #include <valgrind/memcheck.h>
index 56c8d3fe55a4ed065681a8111c1ba32de467ea5d..952aca400faf4f1a6f2d838b809a0a96c62ebd57 100644 (file)
@@ -330,7 +330,7 @@ static int bch2_xattr_get_handler(const struct xattr_handler *handler,
 {
        struct bch_inode_info *inode = to_bch_ei(vinode);
        struct bch_fs *c = inode->v.i_sb->s_fs_info;
-       int ret = bch2_trans_do(c, NULL, NULL, 0,
+       int ret = bch2_trans_do(c,
                bch2_xattr_get_trans(trans, inode, name, buffer, size, handler->flags));
 
        if (ret < 0 && bch2_err_matches(ret, ENOENT))
index cd6d5bbb4b9df5e0d9d95ad634ae599f6c171b00..390808ce935d50b94b73682bf0c5e7f6152697c4 100644 (file)
@@ -39,7 +39,7 @@
 #include <linux/vmalloc.h>
 
 #include <asm/byteorder.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include <asm/cacheflush.h>
 #include <asm/page.h>
 #include <asm/flat.h>
index 79026917db19dc2f70257ba3fc231c838a4c38a6..e3716516ca3876a60e9ab0fc6d1f7a2c159b0e1d 100644 (file)
@@ -3,7 +3,7 @@
  * Copyright (C) 2007 Oracle.  All rights reserved.
  */
 
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include "messages.h"
 #include "extent_io.h"
 #include "fs.h"
index b2eb9cde2c5ddb0a6ce641dca258aec13d796971..7a7e0ef69973a86cf05108d875ed1b97f3f99be8 100644 (file)
@@ -3,7 +3,7 @@
 #ifndef BTRFS_ACCESSORS_H
 #define BTRFS_ACCESSORS_H
 
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include <linux/stddef.h>
 #include <linux/types.h>
 #include <linux/align.h>
index e2f478ecd7fd8f6dafb12017727aacafcdbb8539..f8e1d5b2c5128a1825ab434bb3dee15dc72501f3 100644 (file)
@@ -3179,10 +3179,14 @@ void btrfs_backref_release_cache(struct btrfs_backref_cache *cache)
                btrfs_backref_cleanup_node(cache, node);
        }
 
-       cache->last_trans = 0;
-
-       for (i = 0; i < BTRFS_MAX_LEVEL; i++)
-               ASSERT(list_empty(&cache->pending[i]));
+       for (i = 0; i < BTRFS_MAX_LEVEL; i++) {
+               while (!list_empty(&cache->pending[i])) {
+                       node = list_first_entry(&cache->pending[i],
+                                               struct btrfs_backref_node,
+                                               list);
+                       btrfs_backref_cleanup_node(cache, node);
+               }
+       }
        ASSERT(list_empty(&cache->pending_edge));
        ASSERT(list_empty(&cache->useless_node));
        ASSERT(list_empty(&cache->changed));
index fec5c6cde0a7f121a128d4b45218074f3eb59e92..7e0f9600b80c43647c3fac55ddab013b510c2ad8 100644 (file)
@@ -49,6 +49,7 @@ void btrfs_bio_init(struct btrfs_bio *bbio, struct btrfs_fs_info *fs_info,
        bbio->end_io = end_io;
        bbio->private = private;
        atomic_set(&bbio->pending_ios, 1);
+       WRITE_ONCE(bbio->status, BLK_STS_OK);
 }
 
 /*
@@ -113,41 +114,29 @@ static void __btrfs_bio_end_io(struct btrfs_bio *bbio)
        }
 }
 
-static void btrfs_orig_write_end_io(struct bio *bio);
-
-static void btrfs_bbio_propagate_error(struct btrfs_bio *bbio,
-                                      struct btrfs_bio *orig_bbio)
-{
-       /*
-        * For writes we tolerate nr_mirrors - 1 write failures, so we can't
-        * just blindly propagate a write failure here.  Instead increment the
-        * error count in the original I/O context so that it is guaranteed to
-        * be larger than the error tolerance.
-        */
-       if (bbio->bio.bi_end_io == &btrfs_orig_write_end_io) {
-               struct btrfs_io_stripe *orig_stripe = orig_bbio->bio.bi_private;
-               struct btrfs_io_context *orig_bioc = orig_stripe->bioc;
-
-               atomic_add(orig_bioc->max_errors, &orig_bioc->error);
-       } else {
-               orig_bbio->bio.bi_status = bbio->bio.bi_status;
-       }
-}
-
 void btrfs_bio_end_io(struct btrfs_bio *bbio, blk_status_t status)
 {
        bbio->bio.bi_status = status;
        if (bbio->bio.bi_pool == &btrfs_clone_bioset) {
                struct btrfs_bio *orig_bbio = bbio->private;
 
-               if (bbio->bio.bi_status)
-                       btrfs_bbio_propagate_error(bbio, orig_bbio);
                btrfs_cleanup_bio(bbio);
                bbio = orig_bbio;
        }
 
-       if (atomic_dec_and_test(&bbio->pending_ios))
+       /*
+        * At this point, bbio always points to the original btrfs_bio. Save
+        * the first error in it.
+        */
+       if (status != BLK_STS_OK)
+               cmpxchg(&bbio->status, BLK_STS_OK, status);
+
+       if (atomic_dec_and_test(&bbio->pending_ios)) {
+               /* Load split bio's error which might be set above. */
+               if (status == BLK_STS_OK)
+                       bbio->bio.bi_status = READ_ONCE(bbio->status);
                __btrfs_bio_end_io(bbio);
+       }
 }
 
 static int next_repair_mirror(struct btrfs_failed_bio *fbio, int cur_mirror)
index e4861234074588ce0d8debd8b28bc241e498e35c..e2fe16074ad6558cd7e604cd0aab0ac0fae4a68d 100644 (file)
@@ -79,6 +79,9 @@ struct btrfs_bio {
        /* File system that this I/O operates on. */
        struct btrfs_fs_info *fs_info;
 
+       /* Save the first error status of split bio. */
+       blk_status_t status;
+
        /*
         * This member must come last, bio_alloc_bioset will allocate enough
         * bytes for entire btrfs_bio but relies on bio being last.
index 7980b2e33a9216203a5cdf1687000aefd2953603..4423d8b716a58fa0ce1098efff83c0d741e52491 100644 (file)
@@ -3819,6 +3819,8 @@ void btrfs_free_reserved_bytes(struct btrfs_block_group *cache,
        spin_lock(&cache->lock);
        if (cache->ro)
                space_info->bytes_readonly += num_bytes;
+       else if (btrfs_is_zoned(cache->fs_info))
+               space_info->bytes_zone_unusable += num_bytes;
        cache->reserved -= num_bytes;
        space_info->bytes_reserved -= num_bytes;
        space_info->max_extent_size = 0;
index b95ef44c326bd37413cd1f6efd68a21385097228..968dae953948200c545699d54b142715bf369ca9 100644 (file)
@@ -763,12 +763,12 @@ static struct extent_map *defrag_lookup_extent(struct inode *inode, u64 start,
         * We can get a merged extent, in that case, we need to re-search
         * tree to get the original em for defrag.
         *
-        * If @newer_than is 0 or em::generation < newer_than, we can trust
-        * this em, as either we don't care about the generation, or the
-        * merged extent map will be rejected anyway.
+        * This is because even if we have adjacent extents that are contiguous
+        * and compatible (same type and flags), we still want to defrag them
+        * so that we use less metadata (extent items in the extent tree and
+        * file extent items in the inode's subvolume tree).
         */
-       if (em && (em->flags & EXTENT_FLAG_MERGED) &&
-           newer_than && em->generation >= newer_than) {
+       if (em && (em->flags & EXTENT_FLAG_MERGED)) {
                free_extent_map(em);
                em = NULL;
        }
index ad9ef8312e41618f8aba5f89356909faa0f119e2..115b90d29b1d8e84706b763f3fc589fbf38b4885 100644 (file)
@@ -840,6 +840,8 @@ static void init_delayed_ref_head(struct btrfs_delayed_ref_head *head_ref,
  * helper function to actually insert a head node into the rbtree.
  * this does all the dirty work in terms of maintaining the correct
  * overall modification count.
+ *
+ * Returns an error pointer in case of an error.
  */
 static noinline struct btrfs_delayed_ref_head *
 add_delayed_ref_head(struct btrfs_trans_handle *trans,
@@ -847,6 +849,7 @@ add_delayed_ref_head(struct btrfs_trans_handle *trans,
                     struct btrfs_qgroup_extent_record *qrecord,
                     int action, bool *qrecord_inserted_ret)
 {
+       struct btrfs_fs_info *fs_info = trans->fs_info;
        struct btrfs_delayed_ref_head *existing;
        struct btrfs_delayed_ref_root *delayed_refs;
        bool qrecord_inserted = false;
@@ -857,18 +860,21 @@ add_delayed_ref_head(struct btrfs_trans_handle *trans,
        if (qrecord) {
                int ret;
 
-               ret = btrfs_qgroup_trace_extent_nolock(trans->fs_info,
-                                                      delayed_refs, qrecord);
+               ret = btrfs_qgroup_trace_extent_nolock(fs_info, delayed_refs, qrecord);
                if (ret) {
                        /* Clean up if insertion fails or item exists. */
-                       xa_release(&delayed_refs->dirty_extents, qrecord->bytenr);
+                       xa_release(&delayed_refs->dirty_extents,
+                                  qrecord->bytenr >> fs_info->sectorsize_bits);
+                       /* Caller responsible for freeing qrecord on error. */
+                       if (ret < 0)
+                               return ERR_PTR(ret);
                        kfree(qrecord);
                } else {
                        qrecord_inserted = true;
                }
        }
 
-       trace_add_delayed_ref_head(trans->fs_info, head_ref, action);
+       trace_add_delayed_ref_head(fs_info, head_ref, action);
 
        existing = htree_insert(&delayed_refs->href_root,
                                &head_ref->href_node);
@@ -890,8 +896,7 @@ add_delayed_ref_head(struct btrfs_trans_handle *trans,
                if (head_ref->is_data && head_ref->ref_mod < 0) {
                        delayed_refs->pending_csums += head_ref->num_bytes;
                        trans->delayed_ref_csum_deletions +=
-                               btrfs_csum_bytes_to_leaves(trans->fs_info,
-                                                          head_ref->num_bytes);
+                               btrfs_csum_bytes_to_leaves(fs_info, head_ref->num_bytes);
                }
                delayed_refs->num_heads++;
                delayed_refs->num_heads_ready++;
@@ -1000,27 +1005,36 @@ static int add_delayed_ref(struct btrfs_trans_handle *trans,
        struct btrfs_fs_info *fs_info = trans->fs_info;
        struct btrfs_delayed_ref_node *node;
        struct btrfs_delayed_ref_head *head_ref;
+       struct btrfs_delayed_ref_head *new_head_ref;
        struct btrfs_delayed_ref_root *delayed_refs;
        struct btrfs_qgroup_extent_record *record = NULL;
        bool qrecord_inserted;
        int action = generic_ref->action;
        bool merged;
+       int ret;
 
        node = kmem_cache_alloc(btrfs_delayed_ref_node_cachep, GFP_NOFS);
        if (!node)
                return -ENOMEM;
 
        head_ref = kmem_cache_alloc(btrfs_delayed_ref_head_cachep, GFP_NOFS);
-       if (!head_ref)
+       if (!head_ref) {
+               ret = -ENOMEM;
                goto free_node;
+       }
 
        if (btrfs_qgroup_full_accounting(fs_info) && !generic_ref->skip_qgroup) {
                record = kzalloc(sizeof(*record), GFP_NOFS);
-               if (!record)
+               if (!record) {
+                       ret = -ENOMEM;
                        goto free_head_ref;
+               }
                if (xa_reserve(&trans->transaction->delayed_refs.dirty_extents,
-                              generic_ref->bytenr, GFP_NOFS))
+                              generic_ref->bytenr >> fs_info->sectorsize_bits,
+                              GFP_NOFS)) {
+                       ret = -ENOMEM;
                        goto free_record;
+               }
        }
 
        init_delayed_ref_common(fs_info, node, generic_ref);
@@ -1034,8 +1048,14 @@ static int add_delayed_ref(struct btrfs_trans_handle *trans,
         * insert both the head node and the new ref without dropping
         * the spin lock
         */
-       head_ref = add_delayed_ref_head(trans, head_ref, record,
-                                       action, &qrecord_inserted);
+       new_head_ref = add_delayed_ref_head(trans, head_ref, record,
+                                           action, &qrecord_inserted);
+       if (IS_ERR(new_head_ref)) {
+               spin_unlock(&delayed_refs->lock);
+               ret = PTR_ERR(new_head_ref);
+               goto free_record;
+       }
+       head_ref = new_head_ref;
 
        merged = insert_delayed_ref(trans, head_ref, node);
        spin_unlock(&delayed_refs->lock);
@@ -1063,7 +1083,7 @@ free_head_ref:
        kmem_cache_free(btrfs_delayed_ref_head_cachep, head_ref);
 free_node:
        kmem_cache_free(btrfs_delayed_ref_node_cachep, node);
-       return -ENOMEM;
+       return ret;
 }
 
 /*
@@ -1094,6 +1114,7 @@ int btrfs_add_delayed_extent_op(struct btrfs_trans_handle *trans,
                                struct btrfs_delayed_extent_op *extent_op)
 {
        struct btrfs_delayed_ref_head *head_ref;
+       struct btrfs_delayed_ref_head *head_ref_ret;
        struct btrfs_delayed_ref_root *delayed_refs;
        struct btrfs_ref generic_ref = {
                .type = BTRFS_REF_METADATA,
@@ -1113,11 +1134,15 @@ int btrfs_add_delayed_extent_op(struct btrfs_trans_handle *trans,
        delayed_refs = &trans->transaction->delayed_refs;
        spin_lock(&delayed_refs->lock);
 
-       add_delayed_ref_head(trans, head_ref, NULL, BTRFS_UPDATE_DELAYED_HEAD,
-                            NULL);
-
+       head_ref_ret = add_delayed_ref_head(trans, head_ref, NULL,
+                                           BTRFS_UPDATE_DELAYED_HEAD, NULL);
        spin_unlock(&delayed_refs->lock);
 
+       if (IS_ERR(head_ref_ret)) {
+               kmem_cache_free(btrfs_delayed_ref_head_cachep, head_ref);
+               return PTR_ERR(head_ref_ret);
+       }
+
        /*
         * Need to update the delayed_refs_rsv with any changes we may have
         * made.
index 085f30968abaeab2894e191830b980d153c9e401..352921e76c7424a4724ed537b2cc003d190be398 100644 (file)
@@ -202,7 +202,15 @@ struct btrfs_delayed_ref_root {
        /* head ref rbtree */
        struct rb_root_cached href_root;
 
-       /* Track dirty extent records. */
+       /*
+        * Track dirty extent records.
+        * The keys correspond to the logical address of the extent ("bytenr")
+        * right shifted by fs_info->sectorsize_bits. This is both to get a more
+        * dense index space (optimizes xarray structure) and because indexes in
+        * xarrays are of "unsigned long" type, meaning they are 32 bits wide on
+        * 32 bits platforms, limiting the extent range to 4G which is too low
+        * and makes it unusable (truncated index values) on 32 bits platforms.
+        */
        struct xarray dirty_extents;
 
        /* this spin lock protects the rbtree and the entries inside */
index 001c0c2f872c9925c77ce506236bd9d1f0b58418..1e8cd7c9472e1d357bea3be3bc62fc14ca0f3878 100644 (file)
@@ -347,8 +347,8 @@ btrfs_search_dir_index_item(struct btrfs_root *root, struct btrfs_path *path,
                        return di;
        }
        /* Adjust return code if the key was not found in the next leaf. */
-       if (ret > 0)
-               ret = 0;
+       if (ret >= 0)
+               ret = -ENOENT;
 
        return ERR_PTR(ret);
 }
index 25d768e67e37248ecf742bf4cc64ba4581dbd68f..b11bfe68dd65fb723308f4ee71e11500b315e2f8 100644 (file)
@@ -17,7 +17,7 @@
 #include <linux/error-injection.h>
 #include <linux/crc32c.h>
 #include <linux/sched/mm.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include <crypto/hash.h>
 #include "ctree.h"
 #include "disk-io.h"
@@ -1959,7 +1959,7 @@ static void btrfs_init_qgroup(struct btrfs_fs_info *fs_info)
        fs_info->qgroup_seq = 1;
        fs_info->qgroup_ulist = NULL;
        fs_info->qgroup_rescan_running = false;
-       fs_info->qgroup_drop_subtree_thres = BTRFS_MAX_LEVEL;
+       fs_info->qgroup_drop_subtree_thres = BTRFS_QGROUP_DROP_SUBTREE_THRES_DEFAULT;
        mutex_init(&fs_info->qgroup_rescan_lock);
 }
 
@@ -4255,6 +4255,17 @@ void __cold close_ctree(struct btrfs_fs_info *fs_info)
        /* clear out the rbtree of defraggable inodes */
        btrfs_cleanup_defrag_inodes(fs_info);
 
+       /*
+        * Wait for any fixup workers to complete.
+        * If we don't wait for them here and they are still running by the time
+        * we call kthread_stop() against the cleaner kthread further below, we
+        * get an use-after-free on the cleaner because the fixup worker adds an
+        * inode to the list of delayed iputs and then attempts to wakeup the
+        * cleaner kthread, which was already stopped and destroyed. We parked
+        * already the cleaner, but below we run all pending delayed iputs.
+        */
+       btrfs_flush_workqueue(fs_info->fixup_workers);
+
        /*
         * After we parked the cleaner kthread, ordered extents may have
         * completed and created new delayed iputs. If one of the async reclaim
index a5966324607d49b73ec35bcaa685b8c1ad4b913e..d9f511babd89ab5636e4aa1101c5ac7ad9dac1d9 100644 (file)
@@ -1300,13 +1300,29 @@ static int btrfs_issue_discard(struct block_device *bdev, u64 start, u64 len,
                bytes_left = end - start;
        }
 
-       if (bytes_left) {
+       while (bytes_left) {
+               u64 bytes_to_discard = min(BTRFS_MAX_DISCARD_CHUNK_SIZE, bytes_left);
+
                ret = blkdev_issue_discard(bdev, start >> SECTOR_SHIFT,
-                                          bytes_left >> SECTOR_SHIFT,
+                                          bytes_to_discard >> SECTOR_SHIFT,
                                           GFP_NOFS);
-               if (!ret)
-                       *discarded_bytes += bytes_left;
+
+               if (ret) {
+                       if (ret != -EOPNOTSUPP)
+                               break;
+                       continue;
+               }
+
+               start += bytes_to_discard;
+               bytes_left -= bytes_to_discard;
+               *discarded_bytes += bytes_to_discard;
+
+               if (btrfs_trim_interrupted()) {
+                       ret = -ERESTARTSYS;
+                       break;
+               }
        }
+
        return ret;
 }
 
@@ -6459,7 +6475,7 @@ static int btrfs_trim_free_extents(struct btrfs_device *device, u64 *trimmed)
                start += len;
                *trimmed += bytes;
 
-               if (fatal_signal_pending(current)) {
+               if (btrfs_trim_interrupted()) {
                        ret = -ERESTARTSYS;
                        break;
                }
index 39c9677c47d5a8155d545ec00baf7444d5c6a6df..872cca54cc6ce41bd0f6f5809b1a5671e6187239 100644 (file)
@@ -262,22 +262,23 @@ static noinline int lock_delalloc_folios(struct inode *inode,
 
                for (i = 0; i < found_folios; i++) {
                        struct folio *folio = fbatch.folios[i];
-                       u32 len = end + 1 - start;
+                       u64 range_start;
+                       u32 range_len;
 
                        if (folio == locked_folio)
                                continue;
 
-                       if (btrfs_folio_start_writer_lock(fs_info, folio, start,
-                                                         len))
-                               goto out;
-
+                       folio_lock(folio);
                        if (!folio_test_dirty(folio) || folio->mapping != mapping) {
-                               btrfs_folio_end_writer_lock(fs_info, folio, start,
-                                                           len);
+                               folio_unlock(folio);
                                goto out;
                        }
+                       range_start = max_t(u64, folio_pos(folio), start);
+                       range_len = min_t(u64, folio_pos(folio) + folio_size(folio),
+                                         end + 1) - range_start;
+                       btrfs_folio_set_writer_lock(fs_info, folio, range_start, range_len);
 
-                       processed_end = folio_pos(folio) + folio_size(folio) - 1;
+                       processed_end = range_start + range_len - 1;
                }
                folio_batch_release(&fbatch);
                cond_resched();
@@ -1306,6 +1307,13 @@ static int submit_one_sector(struct btrfs_inode *inode,
        free_extent_map(em);
        em = NULL;
 
+       /*
+        * Although the PageDirty bit is cleared before entering this
+        * function, subpage dirty bit is not cleared.
+        * So clear subpage dirty bit here so next time we won't submit
+        * a folio for a range already written to disk.
+        */
+       btrfs_folio_clear_dirty(fs_info, folio, filepos, sectorsize);
        btrfs_set_range_writeback(inode, filepos, filepos + sectorsize - 1);
        /*
         * Above call should set the whole folio with writeback flag, even
@@ -1315,13 +1323,6 @@ static int submit_one_sector(struct btrfs_inode *inode,
         */
        ASSERT(folio_test_writeback(folio));
 
-       /*
-        * Although the PageDirty bit is cleared before entering this
-        * function, subpage dirty bit is not cleared.
-        * So clear subpage dirty bit here so next time we won't submit
-        * folio for range already written to disk.
-        */
-       btrfs_folio_clear_dirty(fs_info, folio, filepos, sectorsize);
        submit_extent_folio(bio_ctrl, disk_bytenr, folio,
                            sectorsize, filepos - folio_pos(folio));
        return 0;
index 25d191f1ac10f49b8b51dd24ab1e6edaf4b7de75..1d93e1202c33944bffcb659bbc85ae649eb0d739 100644 (file)
@@ -230,7 +230,12 @@ static bool mergeable_maps(const struct extent_map *prev, const struct extent_ma
        if (extent_map_end(prev) != next->start)
                return false;
 
-       if (prev->flags != next->flags)
+       /*
+        * The merged flag is not an on-disk flag, it just indicates we had the
+        * extent maps of 2 (or more) adjacent extents merged, so factor it out.
+        */
+       if ((prev->flags & ~EXTENT_FLAG_MERGED) !=
+           (next->flags & ~EXTENT_FLAG_MERGED))
                return false;
 
        if (next->disk_bytenr < EXTENT_MAP_LAST_BYTE - 1)
@@ -243,13 +248,19 @@ static bool mergeable_maps(const struct extent_map *prev, const struct extent_ma
 /*
  * Handle the on-disk data extents merge for @prev and @next.
  *
+ * @prev:    left extent to merge
+ * @next:    right extent to merge
+ * @merged:  the extent we will not discard after the merge; updated with new values
+ *
+ * After this, one of the two extents is the new merged extent and the other is
+ * removed from the tree and likely freed. Note that @merged is one of @prev/@next
+ * so there is const/non-const aliasing occurring here.
+ *
  * Only touches disk_bytenr/disk_num_bytes/offset/ram_bytes.
  * For now only uncompressed regular extent can be merged.
- *
- * @prev and @next will be both updated to point to the new merged range.
- * Thus one of them should be removed by the caller.
  */
-static void merge_ondisk_extents(struct extent_map *prev, struct extent_map *next)
+static void merge_ondisk_extents(const struct extent_map *prev, const struct extent_map *next,
+                                struct extent_map *merged)
 {
        u64 new_disk_bytenr;
        u64 new_disk_num_bytes;
@@ -284,15 +295,10 @@ static void merge_ondisk_extents(struct extent_map *prev, struct extent_map *nex
                             new_disk_bytenr;
        new_offset = prev->disk_bytenr + prev->offset - new_disk_bytenr;
 
-       prev->disk_bytenr = new_disk_bytenr;
-       prev->disk_num_bytes = new_disk_num_bytes;
-       prev->ram_bytes = new_disk_num_bytes;
-       prev->offset = new_offset;
-
-       next->disk_bytenr = new_disk_bytenr;
-       next->disk_num_bytes = new_disk_num_bytes;
-       next->ram_bytes = new_disk_num_bytes;
-       next->offset = new_offset;
+       merged->disk_bytenr = new_disk_bytenr;
+       merged->disk_num_bytes = new_disk_num_bytes;
+       merged->ram_bytes = new_disk_num_bytes;
+       merged->offset = new_offset;
 }
 
 static void dump_extent_map(struct btrfs_fs_info *fs_info, const char *prefix,
@@ -361,7 +367,7 @@ static void try_merge_map(struct btrfs_inode *inode, struct extent_map *em)
                        em->generation = max(em->generation, merge->generation);
 
                        if (em->disk_bytenr < EXTENT_MAP_LAST_BYTE)
-                               merge_ondisk_extents(merge, em);
+                               merge_ondisk_extents(merge, em, em);
                        em->flags |= EXTENT_FLAG_MERGED;
 
                        validate_extent_map(fs_info, em);
@@ -378,7 +384,7 @@ static void try_merge_map(struct btrfs_inode *inode, struct extent_map *em)
        if (rb && can_merge_extent_map(merge) && mergeable_maps(em, merge)) {
                em->len += merge->len;
                if (em->disk_bytenr < EXTENT_MAP_LAST_BYTE)
-                       merge_ondisk_extents(em, merge);
+                       merge_ondisk_extents(em, merge, em);
                validate_extent_map(fs_info, em);
                rb_erase(&merge->rb_node, &tree->root);
                RB_CLEAR_NODE(&merge->rb_node);
index eaa1dbd313528cf33ea44f7c2bb5cde0701d70ca..f4bcb25306606ab6020619797c0f763bb3771a89 100644 (file)
@@ -3809,7 +3809,7 @@ next:
                if (async && *total_trimmed)
                        break;
 
-               if (fatal_signal_pending(current)) {
+               if (btrfs_trim_interrupted()) {
                        ret = -ERESTARTSYS;
                        break;
                }
@@ -4000,7 +4000,7 @@ next:
                }
                block_group->discard_cursor = start;
 
-               if (fatal_signal_pending(current)) {
+               if (btrfs_trim_interrupted()) {
                        if (start != offset)
                                reset_trimming_bitmap(ctl, offset);
                        ret = -ERESTARTSYS;
index 83774bfd7b3bb09119d0258900b0514307e5536b..9f1dbfdee8cabfef7e6aa87928c2c3ccdcea950f 100644 (file)
@@ -10,6 +10,7 @@
 #include <linux/list.h>
 #include <linux/spinlock.h>
 #include <linux/mutex.h>
+#include <linux/freezer.h>
 #include "fs.h"
 
 struct inode;
@@ -56,6 +57,11 @@ static inline bool btrfs_free_space_trimming_bitmap(
        return (info->trim_state == BTRFS_TRIM_STATE_TRIMMING);
 }
 
+static inline bool btrfs_trim_interrupted(void)
+{
+       return fatal_signal_pending(current) || freezing(current);
+}
+
 /*
  * Deltas are an effective way to populate global statistics.  Give macro names
  * to make it clear what we're doing.  An example is discard_extents in
index edac499fd83d29181f8374b4f505cd177ded7018..da51edbad6a00d5460964ed2a26a39cdf0cba098 100644 (file)
@@ -32,7 +32,7 @@
 #include <linux/migrate.h>
 #include <linux/sched/mm.h>
 #include <linux/iomap.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include <linux/fsverity.h>
 #include "misc.h"
 #include "ctree.h"
@@ -3111,6 +3111,11 @@ int btrfs_finish_one_ordered(struct btrfs_ordered_extent *ordered_extent)
                ret = btrfs_update_inode_fallback(trans, inode);
                if (ret) /* -ENOMEM or corruption */
                        btrfs_abort_transaction(trans, ret);
+
+               ret = btrfs_insert_raid_extent(trans, ordered_extent);
+               if (ret)
+                       btrfs_abort_transaction(trans, ret);
+
                goto out;
        }
 
@@ -4363,11 +4368,8 @@ static int btrfs_unlink_subvol(struct btrfs_trans_handle *trans,
         */
        if (btrfs_ino(inode) == BTRFS_EMPTY_SUBVOL_DIR_OBJECTID) {
                di = btrfs_search_dir_index_item(root, path, dir_ino, &fname.disk_name);
-               if (IS_ERR_OR_NULL(di)) {
-                       if (!di)
-                               ret = -ENOENT;
-                       else
-                               ret = PTR_ERR(di);
+               if (IS_ERR(di)) {
+                       ret = PTR_ERR(di);
                        btrfs_abort_transaction(trans, ret);
                        goto out;
                }
index 77752eec125d939afd3b61a584499b32e75b0347..363fd28c026880525b0c014e3bd10fa8d23900f8 100644 (file)
@@ -239,7 +239,8 @@ void __cold _btrfs_printk(const struct btrfs_fs_info *fs_info, const char *fmt,
        vaf.fmt = fmt;
        vaf.va = &args;
 
-       if (__ratelimit(ratelimit)) {
+       /* Do not ratelimit if CONFIG_BTRFS_DEBUG is enabled. */
+       if (IS_ENABLED(CONFIG_BTRFS_DEBUG) || __ratelimit(ratelimit)) {
                if (fs_info) {
                        char statestr[STATE_STRING_BUF_LEN];
 
index c297909f15061829ccfc7a595a55bcf2197b4f8f..a0e8deca87a7a6967f4a637f675193ab7cf22275 100644 (file)
@@ -1407,7 +1407,7 @@ int btrfs_quota_disable(struct btrfs_fs_info *fs_info)
        fs_info->quota_root = NULL;
        fs_info->qgroup_flags &= ~BTRFS_QGROUP_STATUS_FLAG_ON;
        fs_info->qgroup_flags &= ~BTRFS_QGROUP_STATUS_FLAG_SIMPLE_MODE;
-       fs_info->qgroup_drop_subtree_thres = BTRFS_MAX_LEVEL;
+       fs_info->qgroup_drop_subtree_thres = BTRFS_QGROUP_DROP_SUBTREE_THRES_DEFAULT;
        spin_unlock(&fs_info->qgroup_lock);
 
        btrfs_free_qgroup_config(fs_info);
@@ -2005,16 +2005,26 @@ int btrfs_qgroup_trace_extent_nolock(struct btrfs_fs_info *fs_info,
                                struct btrfs_qgroup_extent_record *record)
 {
        struct btrfs_qgroup_extent_record *existing, *ret;
-       unsigned long bytenr = record->bytenr;
+       const unsigned long index = (record->bytenr >> fs_info->sectorsize_bits);
 
        if (!btrfs_qgroup_full_accounting(fs_info))
                return 1;
 
+#if BITS_PER_LONG == 32
+       if (record->bytenr >= MAX_LFS_FILESIZE) {
+               btrfs_err_rl(fs_info,
+"qgroup record for extent at %llu is beyond 32bit page cache and xarray index limit",
+                            record->bytenr);
+               btrfs_err_32bit_limit(fs_info);
+               return -EOVERFLOW;
+       }
+#endif
+
        lockdep_assert_held(&delayed_refs->lock);
        trace_btrfs_qgroup_trace_extent(fs_info, record);
 
        xa_lock(&delayed_refs->dirty_extents);
-       existing = xa_load(&delayed_refs->dirty_extents, bytenr);
+       existing = xa_load(&delayed_refs->dirty_extents, index);
        if (existing) {
                if (record->data_rsv && !existing->data_rsv) {
                        existing->data_rsv = record->data_rsv;
@@ -2024,7 +2034,7 @@ int btrfs_qgroup_trace_extent_nolock(struct btrfs_fs_info *fs_info,
                return 1;
        }
 
-       ret = __xa_store(&delayed_refs->dirty_extents, record->bytenr, record, GFP_ATOMIC);
+       ret = __xa_store(&delayed_refs->dirty_extents, index, record, GFP_ATOMIC);
        xa_unlock(&delayed_refs->dirty_extents);
        if (xa_is_err(ret)) {
                qgroup_mark_inconsistent(fs_info);
@@ -2129,6 +2139,7 @@ int btrfs_qgroup_trace_extent(struct btrfs_trans_handle *trans, u64 bytenr,
        struct btrfs_fs_info *fs_info = trans->fs_info;
        struct btrfs_qgroup_extent_record *record;
        struct btrfs_delayed_ref_root *delayed_refs;
+       const unsigned long index = (bytenr >> fs_info->sectorsize_bits);
        int ret;
 
        if (!btrfs_qgroup_full_accounting(fs_info) || bytenr == 0 || num_bytes == 0)
@@ -2137,7 +2148,7 @@ int btrfs_qgroup_trace_extent(struct btrfs_trans_handle *trans, u64 bytenr,
        if (!record)
                return -ENOMEM;
 
-       if (xa_reserve(&trans->transaction->delayed_refs.dirty_extents, bytenr, GFP_NOFS)) {
+       if (xa_reserve(&trans->transaction->delayed_refs.dirty_extents, index, GFP_NOFS)) {
                kfree(record);
                return -ENOMEM;
        }
@@ -2152,7 +2163,7 @@ int btrfs_qgroup_trace_extent(struct btrfs_trans_handle *trans, u64 bytenr,
        spin_unlock(&delayed_refs->lock);
        if (ret) {
                /* Clean up if insertion fails or item exists. */
-               xa_release(&delayed_refs->dirty_extents, record->bytenr);
+               xa_release(&delayed_refs->dirty_extents, index);
                kfree(record);
                return 0;
        }
index 98adf4ec7b0172837e5490cb1b1ca712f88a8962..c229256d6fd510db270b56773ed908764c938094 100644 (file)
@@ -121,6 +121,8 @@ struct btrfs_inode;
 #define BTRFS_QGROUP_RUNTIME_FLAG_CANCEL_RESCAN                (1ULL << 63)
 #define BTRFS_QGROUP_RUNTIME_FLAG_NO_ACCOUNTING                (1ULL << 62)
 
+#define BTRFS_QGROUP_DROP_SUBTREE_THRES_DEFAULT                (3)
+
 /*
  * Record a dirty extent, and info qgroup to update quota on it
  */
index ea4ed85919ec8f4ee8575d8123c0e9f31c29d92e..f3834f8d26b456ac016254ba8f5517156901e87f 100644 (file)
@@ -232,70 +232,6 @@ static struct btrfs_backref_node *walk_down_backref(
        return NULL;
 }
 
-static void update_backref_node(struct btrfs_backref_cache *cache,
-                               struct btrfs_backref_node *node, u64 bytenr)
-{
-       struct rb_node *rb_node;
-       rb_erase(&node->rb_node, &cache->rb_root);
-       node->bytenr = bytenr;
-       rb_node = rb_simple_insert(&cache->rb_root, node->bytenr, &node->rb_node);
-       if (rb_node)
-               btrfs_backref_panic(cache->fs_info, bytenr, -EEXIST);
-}
-
-/*
- * update backref cache after a transaction commit
- */
-static int update_backref_cache(struct btrfs_trans_handle *trans,
-                               struct btrfs_backref_cache *cache)
-{
-       struct btrfs_backref_node *node;
-       int level = 0;
-
-       if (cache->last_trans == 0) {
-               cache->last_trans = trans->transid;
-               return 0;
-       }
-
-       if (cache->last_trans == trans->transid)
-               return 0;
-
-       /*
-        * detached nodes are used to avoid unnecessary backref
-        * lookup. transaction commit changes the extent tree.
-        * so the detached nodes are no longer useful.
-        */
-       while (!list_empty(&cache->detached)) {
-               node = list_entry(cache->detached.next,
-                                 struct btrfs_backref_node, list);
-               btrfs_backref_cleanup_node(cache, node);
-       }
-
-       while (!list_empty(&cache->changed)) {
-               node = list_entry(cache->changed.next,
-                                 struct btrfs_backref_node, list);
-               list_del_init(&node->list);
-               BUG_ON(node->pending);
-               update_backref_node(cache, node, node->new_bytenr);
-       }
-
-       /*
-        * some nodes can be left in the pending list if there were
-        * errors during processing the pending nodes.
-        */
-       for (level = 0; level < BTRFS_MAX_LEVEL; level++) {
-               list_for_each_entry(node, &cache->pending[level], list) {
-                       BUG_ON(!node->pending);
-                       if (node->bytenr == node->new_bytenr)
-                               continue;
-                       update_backref_node(cache, node, node->new_bytenr);
-               }
-       }
-
-       cache->last_trans = 0;
-       return 1;
-}
-
 static bool reloc_root_is_dead(const struct btrfs_root *root)
 {
        /*
@@ -551,9 +487,6 @@ static int clone_backref_node(struct btrfs_trans_handle *trans,
        struct btrfs_backref_edge *new_edge;
        struct rb_node *rb_node;
 
-       if (cache->last_trans > 0)
-               update_backref_cache(trans, cache);
-
        rb_node = rb_simple_search(&cache->rb_root, src->commit_root->start);
        if (rb_node) {
                node = rb_entry(rb_node, struct btrfs_backref_node, rb_node);
@@ -923,7 +856,7 @@ int btrfs_update_reloc_root(struct btrfs_trans_handle *trans,
        btrfs_grab_root(reloc_root);
 
        /* root->reloc_root will stay until current relocation finished */
-       if (fs_info->reloc_ctl->merge_reloc_tree &&
+       if (fs_info->reloc_ctl && fs_info->reloc_ctl->merge_reloc_tree &&
            btrfs_root_refs(root_item) == 0) {
                set_bit(BTRFS_ROOT_DEAD_RELOC_TREE, &root->state);
                /*
@@ -3698,11 +3631,9 @@ static noinline_for_stack int relocate_block_group(struct reloc_control *rc)
                        break;
                }
 restart:
-               if (update_backref_cache(trans, &rc->backref_cache)) {
-                       btrfs_end_transaction(trans);
-                       trans = NULL;
-                       continue;
-               }
+               if (rc->backref_cache.last_trans != trans->transid)
+                       btrfs_backref_release_cache(&rc->backref_cache);
+               rc->backref_cache.last_trans = trans->transid;
 
                ret = find_next_extent(rc, path, &key);
                if (ret < 0)
index 7f48ba6c1c77a0862932bdeffdf7b350267ca544..b068469871f8e554aca9688048344f3c9d4e0ac7 100644 (file)
@@ -346,8 +346,10 @@ struct name_cache_entry {
        u64 parent_gen;
        int ret;
        int need_later_update;
+       /* Name length without NUL terminator. */
        int name_len;
-       char name[] __counted_by(name_len);
+       /* Not NUL terminated. */
+       char name[] __counted_by(name_len) __nonstring;
 };
 
 /* See the comment at lru_cache.h about struct btrfs_lru_cache_entry. */
@@ -2388,7 +2390,7 @@ out_cache:
        /*
         * Store the result of the lookup in the name cache.
         */
-       nce = kmalloc(sizeof(*nce) + fs_path_len(dest) + 1, GFP_KERNEL);
+       nce = kmalloc(sizeof(*nce) + fs_path_len(dest), GFP_KERNEL);
        if (!nce) {
                ret = -ENOMEM;
                goto out;
@@ -2400,7 +2402,7 @@ out_cache:
        nce->parent_gen = *parent_gen;
        nce->name_len = fs_path_len(dest);
        nce->ret = ret;
-       strcpy(nce->name, dest->start);
+       memcpy(nce->name, dest->start, nce->name_len);
 
        if (ino < sctx->send_progress)
                nce->need_later_update = 0;
@@ -6187,8 +6189,29 @@ static int send_write_or_clone(struct send_ctx *sctx,
        if (ret < 0)
                return ret;
 
-       if (clone_root->offset + num_bytes == info.size)
+       if (clone_root->offset + num_bytes == info.size) {
+               /*
+                * The final size of our file matches the end offset, but it may
+                * be that its current size is larger, so we have to truncate it
+                * to any value between the start offset of the range and the
+                * final i_size, otherwise the clone operation is invalid
+                * because it's unaligned and it ends before the current EOF.
+                * We do this truncate to the final i_size when we finish
+                * processing the inode, but it's too late by then. And here we
+                * truncate to the start offset of the range because it's always
+                * sector size aligned while if it were the final i_size it
+                * would result in dirtying part of a page, filling part of a
+                * page with zeroes and then having the clone operation at the
+                * receiver trigger IO and wait for it due to the dirty page.
+                */
+               if (sctx->parent_root != NULL) {
+                       ret = send_truncate(sctx, sctx->cur_ino,
+                                           sctx->cur_inode_gen, offset);
+                       if (ret < 0)
+                               return ret;
+               }
                goto clone_data;
+       }
 
 write_data:
        ret = send_extent_data(sctx, path, offset, num_bytes);
@@ -7167,13 +7190,11 @@ static int changed_extent(struct send_ctx *sctx,
 
 static int changed_verity(struct send_ctx *sctx, enum btrfs_compare_tree_result result)
 {
-       int ret = 0;
-
        if (!sctx->cur_inode_new_gen && !sctx->cur_inode_deleted) {
                if (result == BTRFS_COMPARE_TREE_NEW)
                        sctx->cur_inode_needs_verity = true;
        }
-       return ret;
+       return 0;
 }
 
 static int dir_changed(struct send_ctx *sctx, u64 dir)
index 98fa0f382480a2a51420d586b1e2a2fa6c58d025..926d7a9ed99df01ad474ba3d2f1a83e55b7c6575 100644 (file)
@@ -340,6 +340,15 @@ static int btrfs_parse_param(struct fs_context *fc, struct fs_parameter *param)
                fallthrough;
        case Opt_compress:
        case Opt_compress_type:
+               /*
+                * Provide the same semantics as older kernels that don't use fs
+                * context, specifying the "compress" option clears
+                * "force-compress" without the need to pass
+                * "compress-force=[no|none]" before specifying "compress".
+                */
+               if (opt != Opt_compress_force && opt != Opt_compress_force_type)
+                       btrfs_clear_opt(ctx->mount_opt, FORCE_COMPRESS);
+
                if (opt == Opt_compress || opt == Opt_compress_force) {
                        ctx->compress_type = BTRFS_COMPRESS_ZLIB;
                        ctx->compress_level = BTRFS_ZLIB_DEFAULT_LEVEL;
@@ -1498,8 +1507,7 @@ static int btrfs_reconfigure(struct fs_context *fc)
        sync_filesystem(sb);
        set_bit(BTRFS_FS_STATE_REMOUNTING, &fs_info->fs_state);
 
-       if (!mount_reconfigure &&
-           !btrfs_check_options(fs_info, &ctx->mount_opt, fc->sb_flags))
+       if (!btrfs_check_options(fs_info, &ctx->mount_opt, fc->sb_flags))
                return -EINVAL;
 
        ret = btrfs_check_features(fs_info, !(fc->sb_flags & SB_RDONLY));
index e2ed2a791f8f0327ac7dfad046dab223eb4630ea..9637c7cdc0cf92cd57b0ad634df7739bb97364c3 100644 (file)
@@ -1374,7 +1374,7 @@ static noinline int add_inode_ref(struct btrfs_trans_handle *trans,
        struct inode *inode = NULL;
        unsigned long ref_ptr;
        unsigned long ref_end;
-       struct fscrypt_str name;
+       struct fscrypt_str name = { 0 };
        int ret;
        int log_ref_ver = 0;
        u64 parent_objectid;
@@ -1845,7 +1845,7 @@ static noinline int replay_one_name(struct btrfs_trans_handle *trans,
                                    struct btrfs_dir_item *di,
                                    struct btrfs_key *key)
 {
-       struct fscrypt_str name;
+       struct fscrypt_str name = { 0 };
        struct btrfs_dir_item *dir_dst_di;
        struct btrfs_dir_item *index_dst_di;
        bool dir_dst_matches = false;
@@ -2125,7 +2125,7 @@ static noinline int check_item_in_log(struct btrfs_trans_handle *trans,
        struct extent_buffer *eb;
        int slot;
        struct btrfs_dir_item *di;
-       struct fscrypt_str name;
+       struct fscrypt_str name = { 0 };
        struct inode *inode = NULL;
        struct btrfs_key location;
 
index c6399513c66fff62ccf1838d1c21e153e2964837..aca2861f21877c3ca92b6fea591f62f53cae7088 100644 (file)
@@ -5,7 +5,7 @@
 
 #include <linux/kthread.h>
 #include <linux/uuid.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include "messages.h"
 #include "ctree.h"
 #include "transaction.h"
index 8f340ad1d938456df052c377b18f0dcbb85dbc49..eb51b609190fb54667b1162a86ec748401cb839f 100644 (file)
@@ -1105,6 +1105,7 @@ static void btrfs_close_one_device(struct btrfs_device *device)
        if (device->bdev) {
                fs_devices->open_devices--;
                device->bdev = NULL;
+               device->bdev_file = NULL;
        }
        clear_bit(BTRFS_DEV_STATE_WRITEABLE, &device->dev_state);
        btrfs_destroy_dev_zone_info(device);
index 03d2d60afe0cfaaa2f27afbd5088fa03cf2d651a..4481575dd70f354b211b32ab589f81a3f52b8476 100644 (file)
@@ -30,6 +30,12 @@ struct btrfs_zoned_device_info;
 
 #define BTRFS_MAX_DATA_CHUNK_SIZE      (10ULL * SZ_1G)
 
+/*
+ * Arbitratry maximum size of one discard request to limit potentially long time
+ * spent in blkdev_issue_discard().
+ */
+#define BTRFS_MAX_DISCARD_CHUNK_SIZE   (SZ_1G)
+
 extern struct mutex uuid_mutex;
 
 #define BTRFS_STRIPE_LEN               SZ_64K
index 7fa2920632ba683c09975584c7b1e0dcad9a94db..69d03feea4e0ecfc84784943950b2bd39178bed8 100644 (file)
@@ -1340,7 +1340,7 @@ static int btrfs_load_zone_info(struct btrfs_fs_info *fs_info, int zone_idx,
        switch (zone.cond) {
        case BLK_ZONE_COND_OFFLINE:
        case BLK_ZONE_COND_READONLY:
-               btrfs_err(fs_info,
+               btrfs_err_in_rcu(fs_info,
                "zoned: offline/readonly zone %llu on device %s (devid %llu)",
                          (info->physical >> device->zone_info->zone_size_shift),
                          rcu_str_deref(device->name), device->devid);
index f53977169db48c873cf97758644128228cc230ad..2b3f9935dbb44dddc871623ca712315aab1eede6 100644 (file)
@@ -595,14 +595,12 @@ static bool cachefiles_open_file(struct cachefiles_object *object,
         * write and readdir but not lookup or open).
         */
        touch_atime(&file->f_path);
-       dput(dentry);
        return true;
 
 check_failed:
        fscache_cookie_lookup_negative(object->cookie);
        cachefiles_unmark_inode_in_use(object, file);
        fput(file);
-       dput(dentry);
        if (ret == -ESTALE)
                return cachefiles_create_file(object);
        return false;
@@ -611,7 +609,6 @@ error_fput:
        fput(file);
 error:
        cachefiles_do_unmark_inode_in_use(object, d_inode(dentry));
-       dput(dentry);
        return false;
 }
 
@@ -654,7 +651,9 @@ bool cachefiles_look_up_object(struct cachefiles_object *object)
                goto new_file;
        }
 
-       if (!cachefiles_open_file(object, dentry))
+       ret = cachefiles_open_file(object, dentry);
+       dput(dentry);
+       if (!ret)
                return false;
 
        _leave(" = t [%lu]", file_inode(object->file)->i_ino);
index 53fef258c2bc6ab961cf8fb44e59869c1a29737e..c2a9e2cc03de93327496ddef44f3c2d772f243b7 100644 (file)
@@ -489,8 +489,11 @@ static int ceph_init_request(struct netfs_io_request *rreq, struct file *file)
        rreq->io_streams[0].sreq_max_len = fsc->mount_options->rsize;
 
 out:
-       if (ret < 0)
+       if (ret < 0) {
+               if (got)
+                       ceph_put_cap_refs(ceph_inode(inode), got);
                kfree(priv);
+       }
 
        return ret;
 }
@@ -2145,7 +2148,7 @@ static int __ceph_pool_perm_get(struct ceph_inode_info *ci,
        }
 
        pool_ns_len = pool_ns ? pool_ns->len : 0;
-       perm = kmalloc(sizeof(*perm) + pool_ns_len + 1, GFP_NOFS);
+       perm = kmalloc(struct_size(perm, pool_ns, pool_ns_len + 1), GFP_NOFS);
        if (!perm) {
                err = -ENOMEM;
                goto out_unlock;
index a79f163ae4ed2ce1962289478b348c53a338a8c0..44451749c5446b55d6ff14d79703fc6ce78d014a 100644 (file)
@@ -3,7 +3,7 @@
 
 #include <linux/exportfs.h>
 #include <linux/slab.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #include "super.h"
 #include "mds_client.h"
index 2508aa8950b7325ca578de00fe87b87a243aef84..037eac35a9e02ae27f0261e1cba97fb4e596c2f3 100644 (file)
@@ -5,7 +5,7 @@
 #include <linux/ceph/ceph_debug.h>
 #include <linux/ceph/osd_client.h>
 
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include <linux/backing-dev.h>
 #include <linux/completion.h>
 #include <linux/exportfs.h>
index 6681a71625f0a32d9f7779728edbc6452cdc22a5..206835e31efa6626c0ce2070afb501d44ef34c87 100644 (file)
@@ -18,7 +18,7 @@
  * information about these ioctls.
  */
 
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include <crypto/skcipher.h>
 #include <linux/key-type.h>
 #include <linux/random.h>
index becb4a6920c6aa1fc0aadb909abefbd8dddd866f..21b47402b3dca4684f5caff34d68cfd0df993080 100644 (file)
--- a/fs/dax.c
+++ b/fs/dax.c
@@ -1262,35 +1262,46 @@ static s64 dax_unshare_iter(struct iomap_iter *iter)
 {
        struct iomap *iomap = &iter->iomap;
        const struct iomap *srcmap = iomap_iter_srcmap(iter);
-       loff_t pos = iter->pos;
-       loff_t length = iomap_length(iter);
+       loff_t copy_pos = iter->pos;
+       u64 copy_len = iomap_length(iter);
+       u32 mod;
        int id = 0;
        s64 ret = 0;
        void *daddr = NULL, *saddr = NULL;
 
-       /* don't bother with blocks that are not shared to start with */
-       if (!(iomap->flags & IOMAP_F_SHARED))
-               return length;
+       if (!iomap_want_unshare_iter(iter))
+               return iomap_length(iter);
+
+       /*
+        * Extend the file range to be aligned to fsblock/pagesize, because
+        * we need to copy entire blocks, not just the byte range specified.
+        * Invalidate the mapping because we're about to CoW.
+        */
+       mod = offset_in_page(copy_pos);
+       if (mod) {
+               copy_len += mod;
+               copy_pos -= mod;
+       }
+
+       mod = offset_in_page(copy_pos + copy_len);
+       if (mod)
+               copy_len += PAGE_SIZE - mod;
+
+       invalidate_inode_pages2_range(iter->inode->i_mapping,
+                                     copy_pos >> PAGE_SHIFT,
+                                     (copy_pos + copy_len - 1) >> PAGE_SHIFT);
 
        id = dax_read_lock();
-       ret = dax_iomap_direct_access(iomap, pos, length, &daddr, NULL);
+       ret = dax_iomap_direct_access(iomap, copy_pos, copy_len, &daddr, NULL);
        if (ret < 0)
                goto out_unlock;
 
-       /* zero the distance if srcmap is HOLE or UNWRITTEN */
-       if (srcmap->flags & IOMAP_F_SHARED || srcmap->type == IOMAP_UNWRITTEN) {
-               memset(daddr, 0, length);
-               dax_flush(iomap->dax_dev, daddr, length);
-               ret = length;
-               goto out_unlock;
-       }
-
-       ret = dax_iomap_direct_access(srcmap, pos, length, &saddr, NULL);
+       ret = dax_iomap_direct_access(srcmap, copy_pos, copy_len, &saddr, NULL);
        if (ret < 0)
                goto out_unlock;
 
-       if (copy_mc_to_kernel(daddr, saddr, length) == 0)
-               ret = length;
+       if (copy_mc_to_kernel(daddr, saddr, copy_len) == 0)
+               ret = iomap_length(iter);
        else
                ret = -EIO;
 
@@ -1305,11 +1316,15 @@ int dax_file_unshare(struct inode *inode, loff_t pos, loff_t len,
        struct iomap_iter iter = {
                .inode          = inode,
                .pos            = pos,
-               .len            = len,
                .flags          = IOMAP_WRITE | IOMAP_UNSHARE | IOMAP_DAX,
        };
+       loff_t size = i_size_read(inode);
        int ret;
 
+       if (pos < 0 || pos >= size)
+               return 0;
+
+       iter.len = min(len, size - pos);
        while ((ret = iomap_iter(&iter, ops)) > 0)
                iter.processed = dax_unshare_iter(&iter);
        return ret;
index d39a1a69feccdf20ca2b4c69311d499a91276f68..827278525fd96455a47b89f44618cf24db16f7fb 100644 (file)
@@ -21,7 +21,7 @@
 #include <linux/file.h>
 #include <linux/scatterlist.h>
 #include <linux/slab.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include <linux/kernel.h>
 #include <linux/xattr.h>
 #include "ecryptfs_kernel.h"
index 5ed1e4cf6c0b4ecbf4efd55169374a3d4fca3e87..cbdf82f0183f3d2f21125667efd6864480b7e650 100644 (file)
@@ -21,7 +21,7 @@
 #include <linux/posix_acl.h>
 #include <linux/posix_acl_xattr.h>
 #include <linux/fileattr.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include "ecryptfs_kernel.h"
 
 static int lock_parent(struct dentry *dentry,
index 287e5d407f08f74bac322531d2481e3a6abdda56..ceda5555971a2ffae0f04709bf02ff31ddec849e 100644 (file)
@@ -19,7 +19,7 @@
 #include <linux/scatterlist.h>
 #include <linux/slab.h>
 #include <linux/xattr.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include "ecryptfs_kernel.h"
 
 /*
index 666873f745dab2c8ca926e8b7d4a6afef3a1d50f..bed3dbe5b7cb8bbc21dcceed4c6978e9f0940028 100644 (file)
@@ -191,10 +191,14 @@ static int erofs_init_device(struct erofs_buf *buf, struct super_block *sb,
                if (IS_ERR(file))
                        return PTR_ERR(file);
 
-               dif->file = file;
-               if (!erofs_is_fileio_mode(sbi))
+               if (!erofs_is_fileio_mode(sbi)) {
                        dif->dax_dev = fs_dax_get_by_bdev(file_bdev(file),
                                        &dif->dax_part_off, NULL, NULL);
+               } else if (!S_ISREG(file_inode(file)->i_mode)) {
+                       fput(file);
+                       return -EINVAL;
+               }
+               dif->file = file;
        }
 
        dif->blocks = le32_to_cpu(dis->blocks);
@@ -705,7 +709,9 @@ static int erofs_fc_get_tree(struct fs_context *fc)
        if (IS_ENABLED(CONFIG_EROFS_FS_ONDEMAND) && sbi->fsid)
                return get_tree_nodev(fc, erofs_fc_fill_super);
 
-       ret = get_tree_bdev(fc, erofs_fc_fill_super);
+       ret = get_tree_bdev_flags(fc, erofs_fc_fill_super,
+               IS_ENABLED(CONFIG_EROFS_FS_BACKED_BY_FILE) ?
+                       GET_TREE_BDEV_QUIET_LOOKUP : 0);
 #ifdef CONFIG_EROFS_FS_BACKED_BY_FILE
        if (ret == -ENOTBLK) {
                if (!fc->source)
@@ -714,7 +720,10 @@ static int erofs_fc_get_tree(struct fs_context *fc)
                if (IS_ERR(sbi->fdev))
                        return PTR_ERR(sbi->fdev);
 
-               return get_tree_nodev(fc, erofs_fc_fill_super);
+               if (S_ISREG(file_inode(sbi->fdev)->i_mode) &&
+                   sbi->fdev->f_mapping->a_ops->read_folio)
+                       return get_tree_nodev(fc, erofs_fc_fill_super);
+               fput(sbi->fdev);
        }
 #endif
        return ret;
index 8936790618c699e84e1c875c2fa9fbe436486ce3..a569ff9dfd04424596e79b59c578b349fea07680 100644 (file)
@@ -710,24 +710,6 @@ static int z_erofs_attach_page(struct z_erofs_decompress_frontend *fe,
        return ret;
 }
 
-static void z_erofs_try_to_claim_pcluster(struct z_erofs_decompress_frontend *f)
-{
-       struct z_erofs_pcluster *pcl = f->pcl;
-       z_erofs_next_pcluster_t *owned_head = &f->owned_head;
-
-       /* type 1, nil pcluster (this pcluster doesn't belong to any chain.) */
-       if (cmpxchg(&pcl->next, Z_EROFS_PCLUSTER_NIL,
-                   *owned_head) == Z_EROFS_PCLUSTER_NIL) {
-               *owned_head = &pcl->next;
-               /* so we can attach this pcluster to our submission chain. */
-               f->mode = Z_EROFS_PCLUSTER_FOLLOWED;
-               return;
-       }
-
-       /* type 2, it belongs to an ongoing chain */
-       f->mode = Z_EROFS_PCLUSTER_INFLIGHT;
-}
-
 static int z_erofs_register_pcluster(struct z_erofs_decompress_frontend *fe)
 {
        struct erofs_map_blocks *map = &fe->map;
@@ -803,7 +785,6 @@ static int z_erofs_pcluster_begin(struct z_erofs_decompress_frontend *fe)
        int ret;
 
        DBG_BUGON(fe->pcl);
-
        /* must be Z_EROFS_PCLUSTER_TAIL or pointed to previous pcluster */
        DBG_BUGON(fe->owned_head == Z_EROFS_PCLUSTER_NIL);
 
@@ -823,7 +804,15 @@ static int z_erofs_pcluster_begin(struct z_erofs_decompress_frontend *fe)
 
        if (ret == -EEXIST) {
                mutex_lock(&fe->pcl->lock);
-               z_erofs_try_to_claim_pcluster(fe);
+               /* check if this pcluster hasn't been linked into any chain. */
+               if (cmpxchg(&fe->pcl->next, Z_EROFS_PCLUSTER_NIL,
+                           fe->owned_head) == Z_EROFS_PCLUSTER_NIL) {
+                       /* .. so it can be attached to our submission chain */
+                       fe->owned_head = &fe->pcl->next;
+                       fe->mode = Z_EROFS_PCLUSTER_FOLLOWED;
+               } else {        /* otherwise, it belongs to an inflight chain */
+                       fe->mode = Z_EROFS_PCLUSTER_INFLIGHT;
+               }
        } else if (ret) {
                return ret;
        }
index e980e29873a56e4b5d70e3873d04adc958b54259..a076cca1f54734b607e05cd75f1106560537d2a2 100644 (file)
@@ -4,14 +4,12 @@
  *             https://www.huawei.com/
  */
 #include "internal.h"
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include <trace/events/erofs.h>
 
 struct z_erofs_maprecorder {
        struct inode *inode;
        struct erofs_map_blocks *map;
-       void *kaddr;
-
        unsigned long lcn;
        /* compression extent information gathered */
        u8  type, headtype;
@@ -33,14 +31,11 @@ static int z_erofs_load_full_lcluster(struct z_erofs_maprecorder *m,
        struct z_erofs_lcluster_index *di;
        unsigned int advise;
 
-       m->kaddr = erofs_read_metabuf(&m->map->buf, inode->i_sb,
-                                     pos, EROFS_KMAP);
-       if (IS_ERR(m->kaddr))
-               return PTR_ERR(m->kaddr);
-
-       m->nextpackoff = pos + sizeof(struct z_erofs_lcluster_index);
+       di = erofs_read_metabuf(&m->map->buf, inode->i_sb, pos, EROFS_KMAP);
+       if (IS_ERR(di))
+               return PTR_ERR(di);
        m->lcn = lcn;
-       di = m->kaddr;
+       m->nextpackoff = pos + sizeof(struct z_erofs_lcluster_index);
 
        advise = le16_to_cpu(di->di_advise);
        m->type = advise & Z_EROFS_LI_LCLUSTER_TYPE_MASK;
@@ -53,8 +48,7 @@ static int z_erofs_load_full_lcluster(struct z_erofs_maprecorder *m,
                                DBG_BUGON(1);
                                return -EFSCORRUPTED;
                        }
-                       m->compressedblks = m->delta[0] &
-                               ~Z_EROFS_LI_D0_CBLKCNT;
+                       m->compressedblks = m->delta[0] & ~Z_EROFS_LI_D0_CBLKCNT;
                        m->delta[0] = 1;
                }
                m->delta[1] = le16_to_cpu(di->di_u.delta[1]);
@@ -110,9 +104,9 @@ static int unpack_compacted_index(struct z_erofs_maprecorder *m,
        struct erofs_inode *const vi = EROFS_I(m->inode);
        const unsigned int lclusterbits = vi->z_logical_clusterbits;
        unsigned int vcnt, lo, lobits, encodebits, nblk, bytes;
-       int i;
-       u8 *in, type;
        bool big_pcluster;
+       u8 *in, type;
+       int i;
 
        if (1 << amortizedshift == 4 && lclusterbits <= 14)
                vcnt = 2;
@@ -121,6 +115,10 @@ static int unpack_compacted_index(struct z_erofs_maprecorder *m,
        else
                return -EOPNOTSUPP;
 
+       in = erofs_read_metabuf(&m->map->buf, m->inode->i_sb, pos, EROFS_KMAP);
+       if (IS_ERR(in))
+               return PTR_ERR(in);
+
        /* it doesn't equal to round_up(..) */
        m->nextpackoff = round_down(pos, vcnt << amortizedshift) +
                         (vcnt << amortizedshift);
@@ -128,9 +126,7 @@ static int unpack_compacted_index(struct z_erofs_maprecorder *m,
        lobits = max(lclusterbits, ilog2(Z_EROFS_LI_D0_CBLKCNT) + 1U);
        encodebits = ((vcnt << amortizedshift) - sizeof(__le32)) * 8 / vcnt;
        bytes = pos & ((vcnt << amortizedshift) - 1);
-
-       in = m->kaddr - bytes;
-
+       in -= bytes;
        i = bytes >> amortizedshift;
 
        lo = decode_compactedbits(lobits, in, encodebits * i, &type);
@@ -255,10 +251,6 @@ static int z_erofs_load_compact_lcluster(struct z_erofs_maprecorder *m,
        amortizedshift = 2;
 out:
        pos += lcn * (1 << amortizedshift);
-       m->kaddr = erofs_read_metabuf(&m->map->buf, inode->i_sb,
-                                     pos, EROFS_KMAP);
-       if (IS_ERR(m->kaddr))
-               return PTR_ERR(m->kaddr);
        return unpack_compacted_index(m, amortizedshift, pos, lookahead);
 }
 
index 7cc200d898211032e8cd0aa68c74faa23bc47444..d5ce0ae660ba4655b7be8f3c8904fcba05dfbb51 100644 (file)
@@ -11,7 +11,7 @@
  */
 
 #include <linux/slab.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include <linux/buffer_head.h>
 
 #include "exfat_raw.h"
index 56b870d9cc0deffd26169bb915179851655d33f8..773c320d68f3f2bb2d0de9a051cdbb3de9e132eb 100644 (file)
@@ -4,7 +4,7 @@
  */
 
 #include <linux/slab.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include <linux/buffer_head.h>
 #include <linux/blkdev.h>
 
index 1ac011088ce76eb4a4ea568d8d8460b5930fbb64..d47896a895965b7ed57b89f75ca53a757c74777a 100644 (file)
@@ -6,7 +6,7 @@
 #include <linux/string.h>
 #include <linux/slab.h>
 #include <linux/buffer_head.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #include "exfat_raw.h"
 #include "exfat_fs.h"
index eaa5f5b51f500bf6de3ccd97f1f75c64bfa3907b..b33664f6ce2abdc16a0b0b165a833ebb6eda0092 100644 (file)
@@ -379,7 +379,7 @@ void ext4_fc_mark_ineligible(struct super_block *sb, int reason, handle_t *handl
  */
 static int ext4_fc_track_template(
        handle_t *handle, struct inode *inode,
-       int (*__fc_track_fn)(struct inode *, void *, bool),
+       int (*__fc_track_fn)(handle_t *handle, struct inode *, void *, bool),
        void *args, int enqueue)
 {
        bool update = false;
@@ -396,7 +396,7 @@ static int ext4_fc_track_template(
                ext4_fc_reset_inode(inode);
                ei->i_sync_tid = tid;
        }
-       ret = __fc_track_fn(inode, args, update);
+       ret = __fc_track_fn(handle, inode, args, update);
        mutex_unlock(&ei->i_fc_lock);
 
        if (!enqueue)
@@ -420,7 +420,8 @@ struct __track_dentry_update_args {
 };
 
 /* __track_fn for directory entry updates. Called with ei->i_fc_lock. */
-static int __track_dentry_update(struct inode *inode, void *arg, bool update)
+static int __track_dentry_update(handle_t *handle, struct inode *inode,
+                                void *arg, bool update)
 {
        struct ext4_fc_dentry_update *node;
        struct ext4_inode_info *ei = EXT4_I(inode);
@@ -435,14 +436,14 @@ static int __track_dentry_update(struct inode *inode, void *arg, bool update)
 
        if (IS_ENCRYPTED(dir)) {
                ext4_fc_mark_ineligible(sb, EXT4_FC_REASON_ENCRYPTED_FILENAME,
-                                       NULL);
+                                       handle);
                mutex_lock(&ei->i_fc_lock);
                return -EOPNOTSUPP;
        }
 
        node = kmem_cache_alloc(ext4_fc_dentry_cachep, GFP_NOFS);
        if (!node) {
-               ext4_fc_mark_ineligible(sb, EXT4_FC_REASON_NOMEM, NULL);
+               ext4_fc_mark_ineligible(sb, EXT4_FC_REASON_NOMEM, handle);
                mutex_lock(&ei->i_fc_lock);
                return -ENOMEM;
        }
@@ -454,7 +455,7 @@ static int __track_dentry_update(struct inode *inode, void *arg, bool update)
                node->fcd_name.name = kmalloc(dentry->d_name.len, GFP_NOFS);
                if (!node->fcd_name.name) {
                        kmem_cache_free(ext4_fc_dentry_cachep, node);
-                       ext4_fc_mark_ineligible(sb, EXT4_FC_REASON_NOMEM, NULL);
+                       ext4_fc_mark_ineligible(sb, EXT4_FC_REASON_NOMEM, handle);
                        mutex_lock(&ei->i_fc_lock);
                        return -ENOMEM;
                }
@@ -576,7 +577,8 @@ void ext4_fc_track_create(handle_t *handle, struct dentry *dentry)
 }
 
 /* __track_fn for inode tracking */
-static int __track_inode(struct inode *inode, void *arg, bool update)
+static int __track_inode(handle_t *handle, struct inode *inode, void *arg,
+                        bool update)
 {
        if (update)
                return -EEXIST;
@@ -614,7 +616,8 @@ struct __track_range_args {
 };
 
 /* __track_fn for tracking data updates */
-static int __track_range(struct inode *inode, void *arg, bool update)
+static int __track_range(handle_t *handle, struct inode *inode, void *arg,
+                        bool update)
 {
        struct ext4_inode_info *ei = EXT4_I(inode);
        ext4_lblk_t oldstart;
index e04eb08b90601e935f7337a6e482f7bea90634b9..a2704f064361066bbf551aa911c71583a1dfe1a6 100644 (file)
@@ -230,8 +230,8 @@ struct ext4_new_flex_group_data {
 #define MAX_RESIZE_BG                          16384
 
 /*
- * alloc_flex_gd() allocates a ext4_new_flex_group_data with size of
- * @flexbg_size.
+ * alloc_flex_gd() allocates an ext4_new_flex_group_data that satisfies the
+ * resizing from @o_group to @n_group, its size is typically @flexbg_size.
  *
  * Returns NULL on failure otherwise address of the allocated structure.
  */
@@ -239,25 +239,27 @@ static struct ext4_new_flex_group_data *alloc_flex_gd(unsigned int flexbg_size,
                                ext4_group_t o_group, ext4_group_t n_group)
 {
        ext4_group_t last_group;
+       unsigned int max_resize_bg;
        struct ext4_new_flex_group_data *flex_gd;
 
        flex_gd = kmalloc(sizeof(*flex_gd), GFP_NOFS);
        if (flex_gd == NULL)
                goto out3;
 
-       if (unlikely(flexbg_size > MAX_RESIZE_BG))
-               flex_gd->resize_bg = MAX_RESIZE_BG;
-       else
-               flex_gd->resize_bg = flexbg_size;
+       max_resize_bg = umin(flexbg_size, MAX_RESIZE_BG);
+       flex_gd->resize_bg = max_resize_bg;
 
        /* Avoid allocating large 'groups' array if not needed */
        last_group = o_group | (flex_gd->resize_bg - 1);
        if (n_group <= last_group)
-               flex_gd->resize_bg = 1 << fls(n_group - o_group + 1);
+               flex_gd->resize_bg = 1 << fls(n_group - o_group);
        else if (n_group - last_group < flex_gd->resize_bg)
-               flex_gd->resize_bg = 1 << max(fls(last_group - o_group + 1),
+               flex_gd->resize_bg = 1 << max(fls(last_group - o_group),
                                              fls(n_group - last_group));
 
+       if (WARN_ON_ONCE(flex_gd->resize_bg > max_resize_bg))
+               flex_gd->resize_bg = max_resize_bg;
+
        flex_gd->groups = kmalloc_array(flex_gd->resize_bg,
                                        sizeof(struct ext4_new_group_data),
                                        GFP_NOFS);
index e0e1956dcdd397d61b2c0700b130afcc61fa883e..7647e9f6e1903add24cfe83bad2beaf657aacd6e 100644 (file)
@@ -2559,6 +2559,8 @@ retry:
 
                error = ext4_xattr_set_handle(handle, inode, name_index, name,
                                              value, value_len, flags);
+               ext4_fc_mark_ineligible(inode->i_sb, EXT4_FC_REASON_XATTR,
+                                       handle);
                error2 = ext4_journal_stop(handle);
                if (error == -ENOSPC &&
                    ext4_should_retry_alloc(sb, &retries))
@@ -2566,7 +2568,6 @@ retry:
                if (error == 0)
                        error = error2;
        }
-       ext4_fc_mark_ineligible(inode->i_sb, EXT4_FC_REASON_XATTR, NULL);
 
        return error;
 }
index 1136539a57a888e8399c938e957057259d31b84f..47a5c806cf162805491f03dda685946bc24b4a45 100644 (file)
@@ -5,7 +5,7 @@
  * Copyright (c) 2012 Samsung Electronics Co., Ltd.
  *             http://www.samsung.com/
  */
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include <linux/fs.h>
 #include <linux/f2fs_fs.h>
 #include <linux/sched/signal.h>
index 9ae54c4c72fe92323ff7c8a84182968a5faa5673..321d8ffbab6e4bd6cd202d5d34a8ad87b7ac3137 100644 (file)
@@ -4647,7 +4647,8 @@ static ssize_t f2fs_file_read_iter(struct kiocb *iocb, struct iov_iter *to)
                                        iov_iter_count(to), READ);
 
        /* In LFS mode, if there is inflight dio, wait for its completion */
-       if (f2fs_lfs_mode(F2FS_I_SB(inode)))
+       if (f2fs_lfs_mode(F2FS_I_SB(inode)) &&
+           get_pages(F2FS_I_SB(inode), F2FS_DIO_WRITE))
                inode_dio_wait(inode);
 
        if (f2fs_should_use_dio(inode, iocb, to)) {
index 9756f0f2b7f7dc2091adcd5462cbe7a669d4a5e0..e4d81b8705d1e6450c606197b7e74a95d3a789df 100644 (file)
@@ -5,7 +5,7 @@
  * Copyright (c) 2012 Samsung Electronics Co., Ltd.
  *             http://www.samsung.com/
  */
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include <linux/fs.h>
 #include <linux/f2fs_fs.h>
 #include <linux/sched/mm.h>
index 75722bbd6b5fbeabb1022dba9947b8eff722469b..3852bb66358cc141bd2ba4d5d5b5f3516c753f23 100644 (file)
@@ -19,7 +19,7 @@
 #include <linux/uio.h>
 #include <linux/blkdev.h>
 #include <linux/backing-dev.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include <linux/random.h>
 #include <linux/iversion.h>
 #include "fat.h"
index 6423e1dedf1471e14c5a68ad1acb0100e57eb824..15bf32c21ac0db8b32810bf27aede68bfa2c667a 100644 (file)
@@ -1037,7 +1037,7 @@ error_inode:
        if (corrupt < 0) {
                fat_fs_error(new_dir->i_sb,
                             "%s: Filesystem corrupted (i_pos %lld)",
-                            __func__, sinfo.i_pos);
+                            __func__, new_i_pos);
        }
        goto out;
 }
index 5125607d040a2ff073e170d043124db5f444a90a..eb093e73697206c99f290fd9bea1e9e5fba52beb 100644 (file)
--- a/fs/file.c
+++ b/fs/file.c
@@ -272,59 +272,45 @@ static inline bool fd_is_open(unsigned int fd, const struct fdtable *fdt)
        return test_bit(fd, fdt->open_fds);
 }
 
-static unsigned int count_open_files(struct fdtable *fdt)
-{
-       unsigned int size = fdt->max_fds;
-       unsigned int i;
-
-       /* Find the last open fd */
-       for (i = size / BITS_PER_LONG; i > 0; ) {
-               if (fdt->open_fds[--i])
-                       break;
-       }
-       i = (i + 1) * BITS_PER_LONG;
-       return i;
-}
-
 /*
  * Note that a sane fdtable size always has to be a multiple of
  * BITS_PER_LONG, since we have bitmaps that are sized by this.
  *
- * 'max_fds' will normally already be properly aligned, but it
- * turns out that in the close_range() -> __close_range() ->
- * unshare_fd() -> dup_fd() -> sane_fdtable_size() we can end
- * up having a 'max_fds' value that isn't already aligned.
- *
- * Rather than make close_range() have to worry about this,
- * just make that BITS_PER_LONG alignment be part of a sane
- * fdtable size. Becuase that's really what it is.
+ * punch_hole is optional - when close_range() is asked to unshare
+ * and close, we don't need to copy descriptors in that range, so
+ * a smaller cloned descriptor table might suffice if the last
+ * currently opened descriptor falls into that range.
  */
-static unsigned int sane_fdtable_size(struct fdtable *fdt, unsigned int max_fds)
+static unsigned int sane_fdtable_size(struct fdtable *fdt, struct fd_range *punch_hole)
 {
-       unsigned int count;
-
-       count = count_open_files(fdt);
-       if (max_fds < NR_OPEN_DEFAULT)
-               max_fds = NR_OPEN_DEFAULT;
-       return ALIGN(min(count, max_fds), BITS_PER_LONG);
+       unsigned int last = find_last_bit(fdt->open_fds, fdt->max_fds);
+
+       if (last == fdt->max_fds)
+               return NR_OPEN_DEFAULT;
+       if (punch_hole && punch_hole->to >= last && punch_hole->from <= last) {
+               last = find_last_bit(fdt->open_fds, punch_hole->from);
+               if (last == punch_hole->from)
+                       return NR_OPEN_DEFAULT;
+       }
+       return ALIGN(last + 1, BITS_PER_LONG);
 }
 
 /*
- * Allocate a new files structure and copy contents from the
- * passed in files structure.
- * errorp will be valid only when the returned files_struct is NULL.
+ * Allocate a new descriptor table and copy contents from the passed in
+ * instance.  Returns a pointer to cloned table on success, ERR_PTR()
+ * on failure.  For 'punch_hole' see sane_fdtable_size().
  */
-struct files_struct *dup_fd(struct files_struct *oldf, unsigned int max_fds, int *errorp)
+struct files_struct *dup_fd(struct files_struct *oldf, struct fd_range *punch_hole)
 {
        struct files_struct *newf;
        struct file **old_fds, **new_fds;
        unsigned int open_files, i;
        struct fdtable *old_fdt, *new_fdt;
+       int error;
 
-       *errorp = -ENOMEM;
        newf = kmem_cache_alloc(files_cachep, GFP_KERNEL);
        if (!newf)
-               goto out;
+               return ERR_PTR(-ENOMEM);
 
        atomic_set(&newf->count, 1);
 
@@ -341,7 +327,7 @@ struct files_struct *dup_fd(struct files_struct *oldf, unsigned int max_fds, int
 
        spin_lock(&oldf->file_lock);
        old_fdt = files_fdtable(oldf);
-       open_files = sane_fdtable_size(old_fdt, max_fds);
+       open_files = sane_fdtable_size(old_fdt, punch_hole);
 
        /*
         * Check whether we need to allocate a larger fd array and fd set.
@@ -354,14 +340,14 @@ struct files_struct *dup_fd(struct files_struct *oldf, unsigned int max_fds, int
 
                new_fdt = alloc_fdtable(open_files - 1);
                if (!new_fdt) {
-                       *errorp = -ENOMEM;
+                       error = -ENOMEM;
                        goto out_release;
                }
 
                /* beyond sysctl_nr_open; nothing to do */
                if (unlikely(new_fdt->max_fds < open_files)) {
                        __free_fdtable(new_fdt);
-                       *errorp = -EMFILE;
+                       error = -EMFILE;
                        goto out_release;
                }
 
@@ -372,7 +358,7 @@ struct files_struct *dup_fd(struct files_struct *oldf, unsigned int max_fds, int
                 */
                spin_lock(&oldf->file_lock);
                old_fdt = files_fdtable(oldf);
-               open_files = sane_fdtable_size(old_fdt, max_fds);
+               open_files = sane_fdtable_size(old_fdt, punch_hole);
        }
 
        copy_fd_bitmaps(new_fdt, old_fdt, open_files / BITS_PER_LONG);
@@ -406,8 +392,7 @@ struct files_struct *dup_fd(struct files_struct *oldf, unsigned int max_fds, int
 
 out_release:
        kmem_cache_free(files_cachep, newf);
-out:
-       return NULL;
+       return ERR_PTR(error);
 }
 
 static struct fdtable *close_files(struct files_struct * files)
@@ -748,37 +733,25 @@ int __close_range(unsigned fd, unsigned max_fd, unsigned int flags)
        if (fd > max_fd)
                return -EINVAL;
 
-       if (flags & CLOSE_RANGE_UNSHARE) {
-               int ret;
-               unsigned int max_unshare_fds = NR_OPEN_MAX;
+       if ((flags & CLOSE_RANGE_UNSHARE) && atomic_read(&cur_fds->count) > 1) {
+               struct fd_range range = {fd, max_fd}, *punch_hole = &range;
 
                /*
                 * If the caller requested all fds to be made cloexec we always
                 * copy all of the file descriptors since they still want to
                 * use them.
                 */
-               if (!(flags & CLOSE_RANGE_CLOEXEC)) {
-                       /*
-                        * If the requested range is greater than the current
-                        * maximum, we're closing everything so only copy all
-                        * file descriptors beneath the lowest file descriptor.
-                        */
-                       rcu_read_lock();
-                       if (max_fd >= last_fd(files_fdtable(cur_fds)))
-                               max_unshare_fds = fd;
-                       rcu_read_unlock();
-               }
-
-               ret = unshare_fd(CLONE_FILES, max_unshare_fds, &fds);
-               if (ret)
-                       return ret;
+               if (flags & CLOSE_RANGE_CLOEXEC)
+                       punch_hole = NULL;
 
+               fds = dup_fd(cur_fds, punch_hole);
+               if (IS_ERR(fds))
+                       return PTR_ERR(fds);
                /*
                 * We used to share our file descriptor table, and have now
                 * created a private one, make sure we're using it below.
                 */
-               if (fds)
-                       swap(cur_fds, fds);
+               swap(cur_fds, fds);
        }
 
        if (flags & CLOSE_RANGE_CLOEXEC)
index f33fbce86ae08936ab70b661b38b65588e89fd22..dafdf766b1d535e0e3e90586ae2bf4efae1abf9f 100644 (file)
@@ -2288,6 +2288,13 @@ static int fuse_writepages_fill(struct folio *folio,
        struct folio *tmp_folio;
        int err;
 
+       if (!data->ff) {
+               err = -EIO;
+               data->ff = fuse_write_file_get(fi);
+               if (!data->ff)
+                       goto out_unlock;
+       }
+
        if (wpa && fuse_writepage_need_send(fc, &folio->page, ap, data)) {
                fuse_writepages_send(data);
                data->wpa = NULL;
@@ -2351,13 +2358,13 @@ static int fuse_writepages(struct address_space *mapping,
                           struct writeback_control *wbc)
 {
        struct inode *inode = mapping->host;
-       struct fuse_inode *fi = get_fuse_inode(inode);
        struct fuse_conn *fc = get_fuse_conn(inode);
        struct fuse_fill_wb_data data;
        int err;
 
+       err = -EIO;
        if (fuse_is_bad(inode))
-               return -EIO;
+               goto out;
 
        if (wbc->sync_mode == WB_SYNC_NONE &&
            fc->num_background >= fc->congestion_threshold)
@@ -2365,9 +2372,7 @@ static int fuse_writepages(struct address_space *mapping,
 
        data.inode = inode;
        data.wpa = NULL;
-       data.ff = fuse_write_file_get(fi);
-       if (!data.ff)
-               return -EIO;
+       data.ff = NULL;
 
        err = -ENOMEM;
        data.orig_pages = kcalloc(fc->max_pages,
@@ -2381,10 +2386,11 @@ static int fuse_writepages(struct address_space *mapping,
                WARN_ON(!data.wpa->ia.ap.num_pages);
                fuse_writepages_send(&data);
        }
+       if (data.ff)
+               fuse_file_put(data.ff, false);
 
        kfree(data.orig_pages);
 out:
-       fuse_file_put(data.ff, false);
        return err;
 }
 
index 62aee8289d11053e9ad66155c20b9ff9c5c92f96..bbac547dfcb3c8b976206814b5da4b1dfa847891 100644 (file)
@@ -18,11 +18,11 @@ static void fuse_file_accessed(struct file *file)
        fuse_invalidate_atime(inode);
 }
 
-static void fuse_file_modified(struct file *file)
+static void fuse_passthrough_end_write(struct file *file, loff_t pos, ssize_t ret)
 {
        struct inode *inode = file_inode(file);
 
-       fuse_invalidate_attr_mask(inode, FUSE_STATX_MODSIZE);
+       fuse_write_update_attr(inode, pos, ret);
 }
 
 ssize_t fuse_passthrough_read_iter(struct kiocb *iocb, struct iov_iter *iter)
@@ -63,7 +63,7 @@ ssize_t fuse_passthrough_write_iter(struct kiocb *iocb,
        struct backing_file_ctx ctx = {
                .cred = ff->cred,
                .user_file = file,
-               .end_write = fuse_file_modified,
+               .end_write = fuse_passthrough_end_write,
        };
 
        pr_debug("%s: backing_file=0x%p, pos=%lld, len=%zu\n", __func__,
@@ -110,7 +110,7 @@ ssize_t fuse_passthrough_splice_write(struct pipe_inode_info *pipe,
        struct backing_file_ctx ctx = {
                .cred = ff->cred,
                .user_file = out,
-               .end_write = fuse_file_modified,
+               .end_write = fuse_passthrough_end_write,
        };
 
        pr_debug("%s: backing_file=0x%p, pos=%lld, len=%zu, flags=0x%x\n", __func__,
@@ -234,7 +234,6 @@ int fuse_backing_open(struct fuse_conn *fc, struct fuse_backing_map *map)
                goto out;
 
        backing_sb = file_inode(file)->i_sb;
-       pr_info("%s: %x:%pD %i\n", __func__, backing_sb->s_dev, file, backing_sb->s_stack_depth);
        res = -ELOOP;
        if (backing_sb->s_stack_depth >= fc->max_stack_depth)
                goto out_fput;
index ce9346099c72dc89b15a24d7be67a076923ebfcc..9592ffcb44e5ea0be17eb07cc9ad69f1d404968a 100644 (file)
@@ -12,7 +12,7 @@
 #include <linux/fs.h>
 #include <linux/blkdev.h>
 #include <linux/cdrom.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #include "hfsplus_fs.h"
 #include "hfsplus_raw.h"
index f5a2476c47bf62415b11dd421df9ba1a42b27720..237c1c23e8550bf6b9ec003737429427aade4832 100644 (file)
@@ -21,7 +21,7 @@
 #include <linux/slab.h>
 #include <linux/sched/signal.h>
 #include <linux/blkdev.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #include "hpfs.h"
 
index 471ae4a315498fc4aeb55c23bf47bd9513e34ad0..8dabb224f941c0b95e7a0e154592bb9137e5bc2c 100644 (file)
@@ -146,14 +146,16 @@ static int no_open(struct inode *inode, struct file *file)
 }
 
 /**
- * inode_init_always - perform inode structure initialisation
+ * inode_init_always_gfp - perform inode structure initialisation
  * @sb: superblock inode belongs to
  * @inode: inode to initialise
+ * @gfp: allocation flags
  *
  * These are initializations that need to be done on every inode
  * allocation as the fields are not initialised by slab allocation.
+ * If there are additional allocations required @gfp is used.
  */
-int inode_init_always(struct super_block *sb, struct inode *inode)
+int inode_init_always_gfp(struct super_block *sb, struct inode *inode, gfp_t gfp)
 {
        static const struct inode_operations empty_iops;
        static const struct file_operations no_open_fops = {.open = no_open};
@@ -230,14 +232,14 @@ int inode_init_always(struct super_block *sb, struct inode *inode)
 #endif
        inode->i_flctx = NULL;
 
-       if (unlikely(security_inode_alloc(inode)))
+       if (unlikely(security_inode_alloc(inode, gfp)))
                return -ENOMEM;
 
        this_cpu_inc(nr_inodes);
 
        return 0;
 }
-EXPORT_SYMBOL(inode_init_always);
+EXPORT_SYMBOL(inode_init_always_gfp);
 
 void free_inode_nonrcu(struct inode *inode)
 {
index 11ea747228aeec11a8e67af844fad383df674371..ef0b68bccbb6126e136bffd3d6558a78bc8fc1e4 100644 (file)
@@ -1145,10 +1145,36 @@ static void iomap_write_delalloc_scan(struct inode *inode,
 }
 
 /*
+ * When a short write occurs, the filesystem might need to use ->iomap_end
+ * to remove space reservations created in ->iomap_begin.
+ *
+ * For filesystems that use delayed allocation, there can be dirty pages over
+ * the delalloc extent outside the range of a short write but still within the
+ * delalloc extent allocated for this iomap if the write raced with page
+ * faults.
+ *
  * Punch out all the delalloc blocks in the range given except for those that
  * have dirty data still pending in the page cache - those are going to be
  * written and so must still retain the delalloc backing for writeback.
  *
+ * The punch() callback *must* only punch delalloc extents in the range passed
+ * to it. It must skip over all other types of extents in the range and leave
+ * them completely unchanged. It must do this punch atomically with respect to
+ * other extent modifications.
+ *
+ * The punch() callback may be called with a folio locked to prevent writeback
+ * extent allocation racing at the edge of the range we are currently punching.
+ * The locked folio may or may not cover the range being punched, so it is not
+ * safe for the punch() callback to lock folios itself.
+ *
+ * Lock order is:
+ *
+ * inode->i_rwsem (shared or exclusive)
+ *   inode->i_mapping->invalidate_lock (exclusive)
+ *     folio_lock()
+ *       ->punch
+ *         internal filesystem allocation lock
+ *
  * As we are scanning the page cache for data, we don't need to reimplement the
  * wheel - mapping_seek_hole_data() does exactly what we need to identify the
  * start and end of data ranges correctly even for sub-folio block sizes. This
@@ -1177,7 +1203,7 @@ static void iomap_write_delalloc_scan(struct inode *inode,
  * require sprinkling this code with magic "+ 1" and "- 1" arithmetic and expose
  * the code to subtle off-by-one bugs....
  */
-static void iomap_write_delalloc_release(struct inode *inode, loff_t start_byte,
+void iomap_write_delalloc_release(struct inode *inode, loff_t start_byte,
                loff_t end_byte, unsigned flags, struct iomap *iomap,
                iomap_punch_t punch)
 {
@@ -1185,12 +1211,13 @@ static void iomap_write_delalloc_release(struct inode *inode, loff_t start_byte,
        loff_t scan_end_byte = min(i_size_read(inode), end_byte);
 
        /*
-        * Lock the mapping to avoid races with page faults re-instantiating
-        * folios and dirtying them via ->page_mkwrite whilst we walk the
-        * cache and perform delalloc extent removal. Failing to do this can
-        * leave dirty pages with no space reservation in the cache.
+        * The caller must hold invalidate_lock to avoid races with page faults
+        * re-instantiating folios and dirtying them via ->page_mkwrite whilst
+        * we walk the cache and perform delalloc extent removal.  Failing to do
+        * this can leave dirty pages with no space reservation in the cache.
         */
-       filemap_invalidate_lock(inode->i_mapping);
+       lockdep_assert_held_write(&inode->i_mapping->invalidate_lock);
+
        while (start_byte < scan_end_byte) {
                loff_t          data_end;
 
@@ -1207,7 +1234,7 @@ static void iomap_write_delalloc_release(struct inode *inode, loff_t start_byte,
                if (start_byte == -ENXIO || start_byte == scan_end_byte)
                        break;
                if (WARN_ON_ONCE(start_byte < 0))
-                       goto out_unlock;
+                       return;
                WARN_ON_ONCE(start_byte < punch_start_byte);
                WARN_ON_ONCE(start_byte > scan_end_byte);
 
@@ -1218,7 +1245,7 @@ static void iomap_write_delalloc_release(struct inode *inode, loff_t start_byte,
                data_end = mapping_seek_hole_data(inode->i_mapping, start_byte,
                                scan_end_byte, SEEK_HOLE);
                if (WARN_ON_ONCE(data_end < 0))
-                       goto out_unlock;
+                       return;
 
                /*
                 * If we race with post-direct I/O invalidation of the page cache,
@@ -1240,74 +1267,8 @@ static void iomap_write_delalloc_release(struct inode *inode, loff_t start_byte,
        if (punch_start_byte < end_byte)
                punch(inode, punch_start_byte, end_byte - punch_start_byte,
                                iomap);
-out_unlock:
-       filemap_invalidate_unlock(inode->i_mapping);
-}
-
-/*
- * When a short write occurs, the filesystem may need to remove reserved space
- * that was allocated in ->iomap_begin from it's ->iomap_end method. For
- * filesystems that use delayed allocation, we need to punch out delalloc
- * extents from the range that are not dirty in the page cache. As the write can
- * race with page faults, there can be dirty pages over the delalloc extent
- * outside the range of a short write but still within the delalloc extent
- * allocated for this iomap.
- *
- * This function uses [start_byte, end_byte) intervals (i.e. open ended) to
- * simplify range iterations.
- *
- * The punch() callback *must* only punch delalloc extents in the range passed
- * to it. It must skip over all other types of extents in the range and leave
- * them completely unchanged. It must do this punch atomically with respect to
- * other extent modifications.
- *
- * The punch() callback may be called with a folio locked to prevent writeback
- * extent allocation racing at the edge of the range we are currently punching.
- * The locked folio may or may not cover the range being punched, so it is not
- * safe for the punch() callback to lock folios itself.
- *
- * Lock order is:
- *
- * inode->i_rwsem (shared or exclusive)
- *   inode->i_mapping->invalidate_lock (exclusive)
- *     folio_lock()
- *       ->punch
- *         internal filesystem allocation lock
- */
-void iomap_file_buffered_write_punch_delalloc(struct inode *inode,
-               loff_t pos, loff_t length, ssize_t written, unsigned flags,
-               struct iomap *iomap, iomap_punch_t punch)
-{
-       loff_t                  start_byte;
-       loff_t                  end_byte;
-       unsigned int            blocksize = i_blocksize(inode);
-
-       if (iomap->type != IOMAP_DELALLOC)
-               return;
-
-       /* If we didn't reserve the blocks, we're not allowed to punch them. */
-       if (!(iomap->flags & IOMAP_F_NEW))
-               return;
-
-       /*
-        * start_byte refers to the first unused block after a short write. If
-        * nothing was written, round offset down to point at the first block in
-        * the range.
-        */
-       if (unlikely(!written))
-               start_byte = round_down(pos, blocksize);
-       else
-               start_byte = round_up(pos + written, blocksize);
-       end_byte = round_up(pos + length, blocksize);
-
-       /* Nothing to do if we've written the entire delalloc extent */
-       if (start_byte >= end_byte)
-               return;
-
-       iomap_write_delalloc_release(inode, start_byte, end_byte, flags, iomap,
-                       punch);
 }
-EXPORT_SYMBOL_GPL(iomap_file_buffered_write_punch_delalloc);
+EXPORT_SYMBOL_GPL(iomap_write_delalloc_release);
 
 static loff_t iomap_unshare_iter(struct iomap_iter *iter)
 {
@@ -1316,21 +1277,7 @@ static loff_t iomap_unshare_iter(struct iomap_iter *iter)
        loff_t length = iomap_length(iter);
        loff_t written = 0;
 
-       /* Don't bother with blocks that are not shared to start with. */
-       if (!(iomap->flags & IOMAP_F_SHARED))
-               return length;
-
-       /*
-        * Don't bother with holes or unwritten extents.
-        *
-        * Note that we use srcmap directly instead of iomap_iter_srcmap as
-        * unsharing requires providing a separate source map, and the presence
-        * of one is a good indicator that unsharing is needed, unlike
-        * IOMAP_F_SHARED which can be set for any data that goes into the COW
-        * fork for XFS.
-        */
-       if (iter->srcmap.type == IOMAP_HOLE ||
-           iter->srcmap.type == IOMAP_UNWRITTEN)
+       if (!iomap_want_unshare_iter(iter))
                return length;
 
        do {
@@ -1374,11 +1321,15 @@ iomap_file_unshare(struct inode *inode, loff_t pos, loff_t len,
        struct iomap_iter iter = {
                .inode          = inode,
                .pos            = pos,
-               .len            = len,
                .flags          = IOMAP_WRITE | IOMAP_UNSHARE,
        };
+       loff_t size = i_size_read(inode);
        int ret;
 
+       if (pos < 0 || pos >= size)
+               return 0;
+
+       iter.len = min(len, size - pos);
        while ((ret = iomap_iter(&iter, ops)) > 0)
                iter.processed = iomap_unshare_iter(&iter);
        return ret;
index dcdc191ed1834876beda8b1f1eb6e27217fbf753..2d55207c9a9902e6f04578a69883ea3f444f67b5 100644 (file)
@@ -3,7 +3,7 @@
 #include <linux/buffer_head.h>
 #include <linux/exportfs.h>
 #include <linux/iso_fs.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 enum isofs_file_format {
        isofs_file_normal = 0,
index 974ecf5e0d9522cce2d889c2304afce2e2fbc534..3ab410059dc202a3e50bdbf505b690093ed18631 100644 (file)
@@ -187,7 +187,7 @@ int dbMount(struct inode *ipbmap)
        }
 
        bmp->db_numag = le32_to_cpu(dbmp_le->dn_numag);
-       if (!bmp->db_numag || bmp->db_numag >= MAXAG) {
+       if (!bmp->db_numag || bmp->db_numag > MAXAG) {
                err = -EINVAL;
                goto err_release_metapage;
        }
index 87a0f207df0b94088736496701516e771b0b3f98..b8fc732e1c677063a0d0a1385a64ce22fe216ae4 100644 (file)
@@ -18,7 +18,7 @@
 #include <linux/sunrpc/svc.h>
 #include <linux/lockd/lockd.h>
 
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #include "netns.h"
 
index 93c377816d75d08f6624c958a3114a73b9ce977c..d26f5e6d2ca35f83205aa24ac4955c7f5ec937f5 100644 (file)
@@ -3944,7 +3944,9 @@ struct mnt_namespace *copy_mnt_ns(unsigned long flags, struct mnt_namespace *ns,
        new = copy_tree(old, old->mnt.mnt_root, copy_flags);
        if (IS_ERR(new)) {
                namespace_unlock();
-               free_mnt_ns(new_ns);
+               ns_free_inum(&new_ns->ns);
+               dec_mnt_namespaces(new_ns->ucounts);
+               mnt_ns_release(new_ns);
                return ERR_CAST(new);
        }
        if (user_ns != ns->user_ns) {
index c40e226053ccc235b2b0ff8bbc95299f6b246b1b..af46a598f4d7c7a5946719b93453195e996791ab 100644 (file)
@@ -67,7 +67,8 @@ static int netfs_begin_cache_read(struct netfs_io_request *rreq, struct netfs_in
  * Decant the list of folios to read into a rolling buffer.
  */
 static size_t netfs_load_buffer_from_ra(struct netfs_io_request *rreq,
-                                       struct folio_queue *folioq)
+                                       struct folio_queue *folioq,
+                                       struct folio_batch *put_batch)
 {
        unsigned int order, nr;
        size_t size = 0;
@@ -82,6 +83,9 @@ static size_t netfs_load_buffer_from_ra(struct netfs_io_request *rreq,
                order = folio_order(folio);
                folioq->orders[i] = order;
                size += PAGE_SIZE << order;
+
+               if (!folio_batch_add(put_batch, folio))
+                       folio_batch_release(put_batch);
        }
 
        for (int i = nr; i < folioq_nr_slots(folioq); i++)
@@ -120,6 +124,9 @@ static ssize_t netfs_prepare_read_iterator(struct netfs_io_subrequest *subreq)
                 * that we will need to release later - but we don't want to do
                 * that until after we've started the I/O.
                 */
+               struct folio_batch put_batch;
+
+               folio_batch_init(&put_batch);
                while (rreq->submitted < subreq->start + rsize) {
                        struct folio_queue *tail = rreq->buffer_tail, *new;
                        size_t added;
@@ -132,10 +139,11 @@ static ssize_t netfs_prepare_read_iterator(struct netfs_io_subrequest *subreq)
                        new->prev = tail;
                        tail->next = new;
                        rreq->buffer_tail = new;
-                       added = netfs_load_buffer_from_ra(rreq, new);
+                       added = netfs_load_buffer_from_ra(rreq, new, &put_batch);
                        rreq->iter.count += added;
                        rreq->submitted += added;
                }
+               folio_batch_release(&put_batch);
        }
 
        subreq->len = rsize;
@@ -348,6 +356,7 @@ static int netfs_wait_for_read(struct netfs_io_request *rreq)
 static int netfs_prime_buffer(struct netfs_io_request *rreq)
 {
        struct folio_queue *folioq;
+       struct folio_batch put_batch;
        size_t added;
 
        folioq = kmalloc(sizeof(*folioq), GFP_KERNEL);
@@ -360,39 +369,14 @@ static int netfs_prime_buffer(struct netfs_io_request *rreq)
        rreq->submitted = rreq->start;
        iov_iter_folio_queue(&rreq->iter, ITER_DEST, folioq, 0, 0, 0);
 
-       added = netfs_load_buffer_from_ra(rreq, folioq);
+       folio_batch_init(&put_batch);
+       added = netfs_load_buffer_from_ra(rreq, folioq, &put_batch);
+       folio_batch_release(&put_batch);
        rreq->iter.count += added;
        rreq->submitted += added;
        return 0;
 }
 
-/*
- * Drop the ref on each folio that we inherited from the VM readahead code.  We
- * still have the folio locks to pin the page until we complete the I/O.
- *
- * Note that we can't just release the batch in each queue struct as we use the
- * occupancy count in other places.
- */
-static void netfs_put_ra_refs(struct folio_queue *folioq)
-{
-       struct folio_batch fbatch;
-
-       folio_batch_init(&fbatch);
-       while (folioq) {
-               for (unsigned int slot = 0; slot < folioq_count(folioq); slot++) {
-                       struct folio *folio = folioq_folio(folioq, slot);
-                       if (!folio)
-                               continue;
-                       trace_netfs_folio(folio, netfs_folio_trace_read_put);
-                       if (!folio_batch_add(&fbatch, folio))
-                               folio_batch_release(&fbatch);
-               }
-               folioq = folioq->next;
-       }
-
-       folio_batch_release(&fbatch);
-}
-
 /**
  * netfs_readahead - Helper to manage a read request
  * @ractl: The description of the readahead request
@@ -436,9 +420,6 @@ void netfs_readahead(struct readahead_control *ractl)
                goto cleanup_free;
        netfs_read_to_pagecache(rreq);
 
-       /* Release the folio refs whilst we're waiting for the I/O. */
-       netfs_put_ra_refs(rreq->buffer);
-
        netfs_put_request(rreq, true, netfs_rreq_trace_put_return);
        return;
 
index 21eab56ee2f94f2d9a87ac11f99888cbe1da83fc..2249ecd09d0a8dd5cb31dfec798cc24c3ea1d411 100644 (file)
@@ -109,6 +109,7 @@ int netfs_start_io_write(struct inode *inode)
                up_write(&inode->i_rwsem);
                return -ERESTARTSYS;
        }
+       downgrade_write(&inode->i_rwsem);
        return 0;
 }
 EXPORT_SYMBOL(netfs_start_io_write);
@@ -123,7 +124,7 @@ EXPORT_SYMBOL(netfs_start_io_write);
 void netfs_end_io_write(struct inode *inode)
        __releases(inode->i_rwsem)
 {
-       up_write(&inode->i_rwsem);
+       up_read(&inode->i_rwsem);
 }
 EXPORT_SYMBOL(netfs_end_io_write);
 
index 63280791de3b3882b1187456566705b996275ddc..78fe5796b2b2f7fc31547ae2ae6b2d686cc3a111 100644 (file)
@@ -102,7 +102,7 @@ void netfs_clear_buffer(struct netfs_io_request *rreq)
 
        while ((p = rreq->buffer)) {
                rreq->buffer = p->next;
-               for (int slot = 0; slot < folioq_nr_slots(p); slot++) {
+               for (int slot = 0; slot < folioq_count(p); slot++) {
                        struct folio *folio = folioq_folio(p, slot);
                        if (!folio)
                                continue;
index b18c65ba55806c4d09b6e7c303a80fc300b56c2d..3cbb289535a85ad79a30e0425cc049465c5c8d47 100644 (file)
@@ -77,6 +77,8 @@ static void netfs_unlock_read_folio(struct netfs_io_subrequest *subreq,
                        folio_unlock(folio);
                }
        }
+
+       folioq_clear(folioq, slot);
 }
 
 /*
index 0929d9fd4ce7c8d1482786a1bdc15fd3cd1fcfd9..bf6d507578e531ff8d4ff1c5a8ec2e6682edf964 100644 (file)
@@ -317,6 +317,7 @@ static int netfs_write_folio(struct netfs_io_request *wreq,
        struct netfs_io_stream *stream;
        struct netfs_group *fgroup; /* TODO: Use this with ceph */
        struct netfs_folio *finfo;
+       size_t iter_off = 0;
        size_t fsize = folio_size(folio), flen = fsize, foff = 0;
        loff_t fpos = folio_pos(folio), i_size;
        bool to_eof = false, streamw = false;
@@ -472,7 +473,12 @@ static int netfs_write_folio(struct netfs_io_request *wreq,
                if (choose_s < 0)
                        break;
                stream = &wreq->io_streams[choose_s];
-               wreq->io_iter.iov_offset = stream->submit_off;
+
+               /* Advance the iterator(s). */
+               if (stream->submit_off > iter_off) {
+                       iov_iter_advance(&wreq->io_iter, stream->submit_off - iter_off);
+                       iter_off = stream->submit_off;
+               }
 
                atomic64_set(&wreq->issued_to, fpos + stream->submit_off);
                stream->submit_extendable_to = fsize - stream->submit_off;
@@ -487,8 +493,8 @@ static int netfs_write_folio(struct netfs_io_request *wreq,
                        debug = true;
        }
 
-       wreq->io_iter.iov_offset = 0;
-       iov_iter_advance(&wreq->io_iter, fsize);
+       if (fsize > iter_off)
+               iov_iter_advance(&wreq->io_iter, fsize - iter_off);
        atomic64_set(&wreq->issued_to, fpos + fsize);
 
        if (!debug)
@@ -502,6 +508,30 @@ static int netfs_write_folio(struct netfs_io_request *wreq,
        return 0;
 }
 
+/*
+ * End the issuing of writes, letting the collector know we're done.
+ */
+static void netfs_end_issue_write(struct netfs_io_request *wreq)
+{
+       bool needs_poke = true;
+
+       smp_wmb(); /* Write subreq lists before ALL_QUEUED. */
+       set_bit(NETFS_RREQ_ALL_QUEUED, &wreq->flags);
+
+       for (int s = 0; s < NR_IO_STREAMS; s++) {
+               struct netfs_io_stream *stream = &wreq->io_streams[s];
+
+               if (!stream->active)
+                       continue;
+               if (!list_empty(&stream->subrequests))
+                       needs_poke = false;
+               netfs_issue_write(wreq, stream);
+       }
+
+       if (needs_poke)
+               netfs_wake_write_collector(wreq, false);
+}
+
 /*
  * Write some of the pending data back to the server
  */
@@ -553,10 +583,7 @@ int netfs_writepages(struct address_space *mapping,
                        break;
        } while ((folio = writeback_iter(mapping, wbc, folio, &error)));
 
-       for (int s = 0; s < NR_IO_STREAMS; s++)
-               netfs_issue_write(wreq, &wreq->io_streams[s]);
-       smp_wmb(); /* Write lists before ALL_QUEUED. */
-       set_bit(NETFS_RREQ_ALL_QUEUED, &wreq->flags);
+       netfs_end_issue_write(wreq);
 
        mutex_unlock(&ictx->wb_lock);
 
@@ -644,10 +671,7 @@ int netfs_end_writethrough(struct netfs_io_request *wreq, struct writeback_contr
        if (writethrough_cache)
                netfs_write_folio(wreq, wbc, writethrough_cache);
 
-       netfs_issue_write(wreq, &wreq->io_streams[0]);
-       netfs_issue_write(wreq, &wreq->io_streams[1]);
-       smp_wmb(); /* Write lists before ALL_QUEUED. */
-       set_bit(NETFS_RREQ_ALL_QUEUED, &wreq->flags);
+       netfs_end_issue_write(wreq);
 
        mutex_unlock(&ictx->wb_lock);
 
@@ -693,13 +717,7 @@ int netfs_unbuffered_write(struct netfs_io_request *wreq, bool may_wait, size_t
                        break;
        }
 
-       netfs_issue_write(wreq, upload);
-
-       smp_wmb(); /* Write lists before ALL_QUEUED. */
-       set_bit(NETFS_RREQ_ALL_QUEUED, &wreq->flags);
-       if (list_empty(&upload->subrequests))
-               netfs_wake_write_collector(wreq, false);
-
+       netfs_end_issue_write(wreq);
        _leave(" = %d", error);
        return error;
 }
index 6df77f008d3fada0066275fda0625e6c51368a56..fdeb0b34a3d39b6ce02d083318918c8493a9e469 100644 (file)
@@ -375,6 +375,8 @@ static __be32 decode_rc_list(struct xdr_stream *xdr,
 
        rc_list->rcl_nrefcalls = ntohl(*p++);
        if (rc_list->rcl_nrefcalls) {
+               if (unlikely(rc_list->rcl_nrefcalls > xdr->buf->len))
+                       goto out;
                p = xdr_inline_decode(xdr,
                             rc_list->rcl_nrefcalls * 2 * sizeof(uint32_t));
                if (unlikely(p == NULL))
index a1d21c4be0ac77baf5361926d255175e44fdb2d9..114282398716c3877ef0f49c3e50bc5a471ec388 100644 (file)
@@ -996,6 +996,7 @@ struct nfs_server *nfs_alloc_server(void)
        INIT_LIST_HEAD(&server->layouts);
        INIT_LIST_HEAD(&server->state_owners_lru);
        INIT_LIST_HEAD(&server->ss_copies);
+       INIT_LIST_HEAD(&server->ss_src_copies);
 
        atomic_set(&server->active, 0);
 
index 20cb2008f9e4696b05284eab6a0fa578eaa39626..035ba52742a5047e5102095bb006b26633242df9 100644 (file)
@@ -1001,6 +1001,11 @@ void nfs_delegation_mark_returned(struct inode *inode,
        }
 
        nfs_mark_delegation_revoked(delegation);
+       clear_bit(NFS_DELEGATION_RETURNING, &delegation->flags);
+       spin_unlock(&delegation->lock);
+       if (nfs_detach_delegation(NFS_I(inode), delegation, NFS_SERVER(inode)))
+               nfs_put_delegation(delegation);
+       goto out_rcu_unlock;
 
 out_clear_returning:
        clear_bit(NFS_DELEGATION_RETURNING, &delegation->flags);
index c29cdf51c458be9865e2b9f6d0e7b5f73fb4622d..d0aa680ec8168b7d281e46db64af68860a846a72 100644 (file)
@@ -18,7 +18,6 @@
 #include <net/addrconf.h>
 #include <linux/nfs_common.h>
 #include <linux/nfslocalio.h>
-#include <linux/module.h>
 #include <linux/bvec.h>
 
 #include <linux/nfs.h>
@@ -341,7 +340,7 @@ nfs_local_pgio_release(struct nfs_local_kiocb *iocb)
 {
        struct nfs_pgio_header *hdr = iocb->hdr;
 
-       nfs_to->nfsd_file_put_local(iocb->localio);
+       nfs_to_nfsd_file_put_local(iocb->localio);
        nfs_local_iocb_free(iocb);
        nfs_local_hdr_release(hdr, hdr->task.tk_ops);
 }
@@ -622,7 +621,7 @@ int nfs_local_doio(struct nfs_client *clp, struct nfsd_file *localio,
        }
 out:
        if (status != 0) {
-               nfs_to->nfsd_file_put_local(localio);
+               nfs_to_nfsd_file_put_local(localio);
                hdr->task.tk_status = status;
                nfs_local_hdr_release(hdr, call_ops);
        }
@@ -673,7 +672,7 @@ nfs_local_release_commit_data(struct nfsd_file *localio,
                struct nfs_commit_data *data,
                const struct rpc_call_ops *call_ops)
 {
-       nfs_to->nfsd_file_put_local(localio);
+       nfs_to_nfsd_file_put_local(localio);
        call_ops->rpc_call_done(&data->task, data);
        call_ops->rpc_release(data);
 }
index 28704f924612c4e5866470865c3ba7b03d1df929..531c9c20ef1d1b383b28d00b7dc8d890990ff2c9 100644 (file)
@@ -218,7 +218,7 @@ static int handle_async_copy(struct nfs42_copy_res *res,
 
        if (dst_server != src_server) {
                spin_lock(&src_server->nfs_client->cl_lock);
-               list_add_tail(&copy->src_copies, &src_server->ss_copies);
+               list_add_tail(&copy->src_copies, &src_server->ss_src_copies);
                spin_unlock(&src_server->nfs_client->cl_lock);
        }
 
index 581864a15888cc917e4cb9092d492e1aa2684f71..dafd61186557f8f4577235af852ab96f3da4c10b 100644 (file)
@@ -1585,7 +1585,7 @@ static void nfs42_complete_copies(struct nfs4_state_owner *sp, struct nfs4_state
                        complete(&copy->completion);
                }
        }
-       list_for_each_entry(copy, &sp->so_server->ss_copies, src_copies) {
+       list_for_each_entry(copy, &sp->so_server->ss_src_copies, src_copies) {
                if ((test_bit(NFS_CLNT_SRC_SSC_COPY_STATE, &state->flags) &&
                                !nfs4_stateid_match_other(&state->stateid,
                                &copy->parent_src_state->stateid)))
index 42b479b9191f42447f0f05795c31f4e0bb0327bf..5c8ce5066c166c2c68e988a12f393db6440e52a5 100644 (file)
@@ -142,8 +142,11 @@ struct nfsd_file *nfs_open_local_fh(nfs_uuid_t *uuid,
        /* We have an implied reference to net thanks to nfsd_serv_try_get */
        localio = nfs_to->nfsd_open_local_fh(net, uuid->dom, rpc_clnt,
                                             cred, nfs_fh, fmode);
-       if (IS_ERR(localio))
+       if (IS_ERR(localio)) {
+               rcu_read_lock();
                nfs_to->nfsd_serv_put(net);
+               rcu_read_unlock();
+       }
        return localio;
 }
 EXPORT_SYMBOL_GPL(nfs_open_local_fh);
index 19bb88c7eebd9b7621398d46ff9a971b55037781..2e6783f63712454509c526969a622040985da577 100644 (file)
@@ -398,7 +398,7 @@ nfsd_file_put(struct nfsd_file *nf)
  * reference to the associated nn->nfsd_serv.
  */
 void
-nfsd_file_put_local(struct nfsd_file *nf)
+nfsd_file_put_local(struct nfsd_file *nf) __must_hold(rcu)
 {
        struct net *net = nf->nf_net;
 
@@ -751,7 +751,7 @@ nfsd_file_cache_init(void)
 
        ret = rhltable_init(&nfsd_file_rhltable, &nfsd_file_rhash_params);
        if (ret)
-               return ret;
+               goto out;
 
        ret = -ENOMEM;
        nfsd_file_slab = KMEM_CACHE(nfsd_file, 0);
@@ -792,7 +792,7 @@ nfsd_file_cache_init(void)
        }
 
        nfsd_file_fsnotify_group = fsnotify_alloc_group(&nfsd_file_fsnotify_ops,
-                                                       FSNOTIFY_GROUP_NOFS);
+                                                       0);
        if (IS_ERR(nfsd_file_fsnotify_group)) {
                pr_err("nfsd: unable to create fsnotify group: %ld\n",
                        PTR_ERR(nfsd_file_fsnotify_group));
@@ -803,6 +803,8 @@ nfsd_file_cache_init(void)
 
        INIT_DELAYED_WORK(&nfsd_filecache_laundrette, nfsd_file_gc_worker);
 out:
+       if (ret)
+               clear_bit(NFSD_FILE_CACHE_UP, &nfsd_file_flags);
        return ret;
 out_notifier:
        lease_unregister_notifier(&nfsd_file_lease_notifier);
index 291e9c69cae48a14a1e083dfefeb22da0f2155b6..f441cb9f74d56cb91534ef81f4130aa176771992 100644 (file)
@@ -53,7 +53,7 @@ void nfsd_localio_ops_init(void)
  *
  * On successful return, returned nfsd_file will have its nf_net member
  * set. Caller (NFS client) is responsible for calling nfsd_serv_put and
- * nfsd_file_put (via nfs_to->nfsd_file_put_local).
+ * nfsd_file_put (via nfs_to_nfsd_file_put_local).
  */
 struct nfsd_file *
 nfsd_open_local_fh(struct net *net, struct auth_domain *dom,
index b5a6bf4f459fb2309a0ccc9f585c5d6318ceedf1..d32f2dfd148fe3080006eb6346be7a69065a04f9 100644 (file)
@@ -1841,14 +1841,12 @@ nfsd4_copy(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
                if (!async_copy)
                        goto out_err;
                async_copy->cp_nn = nn;
+               INIT_LIST_HEAD(&async_copy->copies);
+               refcount_set(&async_copy->refcount, 1);
                /* Arbitrary cap on number of pending async copy operations */
                if (atomic_inc_return(&nn->pending_async_copies) >
-                               (int)rqstp->rq_pool->sp_nrthreads) {
-                       atomic_dec(&nn->pending_async_copies);
+                               (int)rqstp->rq_pool->sp_nrthreads)
                        goto out_err;
-               }
-               INIT_LIST_HEAD(&async_copy->copies);
-               refcount_set(&async_copy->refcount, 1);
                async_copy->cp_src = kmalloc(sizeof(*async_copy->cp_src), GFP_KERNEL);
                if (!async_copy->cp_src)
                        goto out_err;
index ac1859c7cc9dc7684eb47f4ce025c3fc56e02701..551d2958ec2905be51b4a96414a15a5e4f87f9ea 100644 (file)
@@ -1359,21 +1359,47 @@ static void destroy_delegation(struct nfs4_delegation *dp)
                destroy_unhashed_deleg(dp);
 }
 
+/**
+ * revoke_delegation - perform nfs4 delegation structure cleanup
+ * @dp: pointer to the delegation
+ *
+ * This function assumes that it's called either from the administrative
+ * interface (nfsd4_revoke_states()) that's revoking a specific delegation
+ * stateid or it's called from a laundromat thread (nfsd4_landromat()) that
+ * determined that this specific state has expired and needs to be revoked
+ * (both mark state with the appropriate stid sc_status mode). It is also
+ * assumed that a reference was taken on the @dp state.
+ *
+ * If this function finds that the @dp state is SC_STATUS_FREED it means
+ * that a FREE_STATEID operation for this stateid has been processed and
+ * we can proceed to removing it from recalled list. However, if @dp state
+ * isn't marked SC_STATUS_FREED, it means we need place it on the cl_revoked
+ * list and wait for the FREE_STATEID to arrive from the client. At the same
+ * time, we need to mark it as SC_STATUS_FREEABLE to indicate to the
+ * nfsd4_free_stateid() function that this stateid has already been added
+ * to the cl_revoked list and that nfsd4_free_stateid() is now responsible
+ * for removing it from the list. Inspection of where the delegation state
+ * in the revocation process is protected by the clp->cl_lock.
+ */
 static void revoke_delegation(struct nfs4_delegation *dp)
 {
        struct nfs4_client *clp = dp->dl_stid.sc_client;
 
        WARN_ON(!list_empty(&dp->dl_recall_lru));
+       WARN_ON_ONCE(!(dp->dl_stid.sc_status &
+                    (SC_STATUS_REVOKED | SC_STATUS_ADMIN_REVOKED)));
 
        trace_nfsd_stid_revoke(&dp->dl_stid);
 
-       if (dp->dl_stid.sc_status &
-           (SC_STATUS_REVOKED | SC_STATUS_ADMIN_REVOKED)) {
-               spin_lock(&clp->cl_lock);
-               refcount_inc(&dp->dl_stid.sc_count);
-               list_add(&dp->dl_recall_lru, &clp->cl_revoked);
-               spin_unlock(&clp->cl_lock);
+       spin_lock(&clp->cl_lock);
+       if (dp->dl_stid.sc_status & SC_STATUS_FREED) {
+               list_del_init(&dp->dl_recall_lru);
+               goto out;
        }
+       list_add(&dp->dl_recall_lru, &clp->cl_revoked);
+       dp->dl_stid.sc_status |= SC_STATUS_FREEABLE;
+out:
+       spin_unlock(&clp->cl_lock);
        destroy_unhashed_deleg(dp);
 }
 
@@ -1780,6 +1806,7 @@ void nfsd4_revoke_states(struct net *net, struct super_block *sb)
                                        mutex_unlock(&stp->st_mutex);
                                        break;
                                case SC_TYPE_DELEG:
+                                       refcount_inc(&stid->sc_count);
                                        dp = delegstateid(stid);
                                        spin_lock(&state_lock);
                                        if (!unhash_delegation_locked(
@@ -6545,6 +6572,7 @@ nfs4_laundromat(struct nfsd_net *nn)
                dp = list_entry (pos, struct nfs4_delegation, dl_recall_lru);
                if (!state_expired(&lt, dp->dl_time))
                        break;
+               refcount_inc(&dp->dl_stid.sc_count);
                unhash_delegation_locked(dp, SC_STATUS_REVOKED);
                list_add(&dp->dl_recall_lru, &reaplist);
        }
@@ -7154,9 +7182,12 @@ nfsd4_free_stateid(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
        switch (s->sc_type) {
        case SC_TYPE_DELEG:
                if (s->sc_status & SC_STATUS_REVOKED) {
+                       s->sc_status |= SC_STATUS_CLOSED;
                        spin_unlock(&s->sc_lock);
                        dp = delegstateid(s);
-                       list_del_init(&dp->dl_recall_lru);
+                       if (s->sc_status & SC_STATUS_FREEABLE)
+                               list_del_init(&dp->dl_recall_lru);
+                       s->sc_status |= SC_STATUS_FREED;
                        spin_unlock(&cl->cl_lock);
                        nfs4_put_stid(s);
                        ret = nfs_ok;
@@ -7486,7 +7517,9 @@ nfsd4_delegreturn(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
        if ((status = fh_verify(rqstp, &cstate->current_fh, S_IFREG, 0)))
                return status;
 
-       status = nfsd4_lookup_stateid(cstate, stateid, SC_TYPE_DELEG, 0, &s, nn);
+       status = nfsd4_lookup_stateid(cstate, stateid, SC_TYPE_DELEG,
+                                     SC_STATUS_REVOKED | SC_STATUS_FREEABLE,
+                                     &s, nn);
        if (status)
                goto out;
        dp = delegstateid(s);
@@ -8683,7 +8716,7 @@ nfs4_state_shutdown_net(struct net *net)
        struct nfsd_net *nn = net_generic(net, nfsd_net_id);
 
        shrinker_free(nn->nfsd_client_shrinker);
-       cancel_work(&nn->nfsd_shrinker_work);
+       cancel_work_sync(&nn->nfsd_shrinker_work);
        cancel_delayed_work_sync(&nn->laundromat_work);
        locks_end_grace(&nn->nfsd4_manager);
 
index e236135ddc63fd1f0173b5bec05234c02127e224..49e2f32102ab59b8a973f1a82bf6aa33e7e3b3cc 100644 (file)
@@ -214,14 +214,14 @@ int nfsd_minorversion(struct nfsd_net *nn, u32 minorversion, enum vers_op change
        return 0;
 }
 
-bool nfsd_serv_try_get(struct net *net)
+bool nfsd_serv_try_get(struct net *net) __must_hold(rcu)
 {
        struct nfsd_net *nn = net_generic(net, nfsd_net_id);
 
        return (nn && percpu_ref_tryget_live(&nn->nfsd_serv_ref));
 }
 
-void nfsd_serv_put(struct net *net)
+void nfsd_serv_put(struct net *net) __must_hold(rcu)
 {
        struct nfsd_net *nn = net_generic(net, nfsd_net_id);
 
@@ -434,6 +434,9 @@ static void nfsd_shutdown_net(struct net *net)
 {
        struct nfsd_net *nn = net_generic(net, nfsd_net_id);
 
+       if (!nn->nfsd_net_up)
+               return;
+       nfsd_export_flush(net);
        nfs4_state_shutdown_net(net);
        nfsd_reply_cache_shutdown(nn);
        nfsd_file_cache_shutdown_net(net);
@@ -549,11 +552,8 @@ void nfsd_destroy_serv(struct net *net)
         * other initialization has been done except the rpcb information.
         */
        svc_rpcb_cleanup(serv, net);
-       if (!nn->nfsd_net_up)
-               return;
 
        nfsd_shutdown_net(net);
-       nfsd_export_flush(net);
        svc_destroy(&serv);
 }
 
index 79c743c01a47bb1d91130708b65b75b92c697aae..35b3564c065fa97b9fd399d455d3dcec932a1767 100644 (file)
@@ -114,6 +114,8 @@ struct nfs4_stid {
 /* For a deleg stateid kept around only to process free_stateid's: */
 #define SC_STATUS_REVOKED      BIT(1)
 #define SC_STATUS_ADMIN_REVOKED        BIT(2)
+#define SC_STATUS_FREEABLE     BIT(3)
+#define SC_STATUS_FREED                BIT(4)
        unsigned short          sc_status;
 
        struct list_head        sc_cp_list;
index c625966cfcf35ebc47248a6826306162b45cded5..b8470d4cbe99e92009467cd546e60a18559fbaf2 100644 (file)
@@ -1113,7 +1113,7 @@ TRACE_EVENT(nfsd_file_acquire,
        ),
 
        TP_fast_assign(
-               __entry->xid = be32_to_cpu(rqstp->rq_xid);
+               __entry->xid = rqstp ? be32_to_cpu(rqstp->rq_xid) : 0;
                __entry->inode = inode;
                __entry->may_flags = may_flags;
                __entry->nf_ref = nf ? refcount_read(&nf->nf_ref) : 0;
@@ -1147,7 +1147,7 @@ TRACE_EVENT(nfsd_file_insert_err,
                __field(long, error)
        ),
        TP_fast_assign(
-               __entry->xid = be32_to_cpu(rqstp->rq_xid);
+               __entry->xid = rqstp ? be32_to_cpu(rqstp->rq_xid) : 0;
                __entry->inode = inode;
                __entry->may_flags = may_flags;
                __entry->error = error;
@@ -1177,7 +1177,7 @@ TRACE_EVENT(nfsd_file_cons_err,
                __field(const void *, nf_file)
        ),
        TP_fast_assign(
-               __entry->xid = be32_to_cpu(rqstp->rq_xid);
+               __entry->xid = rqstp ? be32_to_cpu(rqstp->rq_xid) : 0;
                __entry->inode = inode;
                __entry->may_flags = may_flags;
                __entry->nf_ref = refcount_read(&nf->nf_ref);
index fe5b1a30c509dbfc642efd7ea81789aa2dfed9fc..a8602729586ab7b9058fd6726e9e5f6436be307b 100644 (file)
@@ -289,7 +289,7 @@ static int nilfs_readdir(struct file *file, struct dir_context *ctx)
  * The folio is mapped and unlocked.  When the caller is finished with
  * the entry, it should call folio_release_kmap().
  *
- * On failure, returns NULL and the caller should ignore foliop.
+ * On failure, returns an error pointer and the caller should ignore foliop.
  */
 struct nilfs_dir_entry *nilfs_find_entry(struct inode *dir,
                const struct qstr *qstr, struct folio **foliop)
@@ -312,22 +312,24 @@ struct nilfs_dir_entry *nilfs_find_entry(struct inode *dir,
        do {
                char *kaddr = nilfs_get_folio(dir, n, foliop);
 
-               if (!IS_ERR(kaddr)) {
-                       de = (struct nilfs_dir_entry *)kaddr;
-                       kaddr += nilfs_last_byte(dir, n) - reclen;
-                       while ((char *) de <= kaddr) {
-                               if (de->rec_len == 0) {
-                                       nilfs_error(dir->i_sb,
-                                               "zero-length directory entry");
-                                       folio_release_kmap(*foliop, kaddr);
-                                       goto out;
-                               }
-                               if (nilfs_match(namelen, name, de))
-                                       goto found;
-                               de = nilfs_next_entry(de);
+               if (IS_ERR(kaddr))
+                       return ERR_CAST(kaddr);
+
+               de = (struct nilfs_dir_entry *)kaddr;
+               kaddr += nilfs_last_byte(dir, n) - reclen;
+               while ((char *)de <= kaddr) {
+                       if (de->rec_len == 0) {
+                               nilfs_error(dir->i_sb,
+                                           "zero-length directory entry");
+                               folio_release_kmap(*foliop, kaddr);
+                               goto out;
                        }
-                       folio_release_kmap(*foliop, kaddr);
+                       if (nilfs_match(namelen, name, de))
+                               goto found;
+                       de = nilfs_next_entry(de);
                }
+               folio_release_kmap(*foliop, kaddr);
+
                if (++n >= npages)
                        n = 0;
                /* next folio is past the blocks we've got */
@@ -340,7 +342,7 @@ struct nilfs_dir_entry *nilfs_find_entry(struct inode *dir,
                }
        } while (n != start);
 out:
-       return NULL;
+       return ERR_PTR(-ENOENT);
 
 found:
        ei->i_dir_start_lookup = n;
@@ -384,18 +386,18 @@ fail:
        return NULL;
 }
 
-ino_t nilfs_inode_by_name(struct inode *dir, const struct qstr *qstr)
+int nilfs_inode_by_name(struct inode *dir, const struct qstr *qstr, ino_t *ino)
 {
-       ino_t res = 0;
        struct nilfs_dir_entry *de;
        struct folio *folio;
 
        de = nilfs_find_entry(dir, qstr, &folio);
-       if (de) {
-               res = le64_to_cpu(de->inode);
-               folio_release_kmap(folio, de);
-       }
-       return res;
+       if (IS_ERR(de))
+               return PTR_ERR(de);
+
+       *ino = le64_to_cpu(de->inode);
+       folio_release_kmap(folio, de);
+       return 0;
 }
 
 void nilfs_set_link(struct inode *dir, struct nilfs_dir_entry *de,
index c950139db6ef0d416366939cc7f04d9c227357d5..4905063790c57816fd9bb7683f656adf2a366662 100644 (file)
@@ -55,12 +55,20 @@ nilfs_lookup(struct inode *dir, struct dentry *dentry, unsigned int flags)
 {
        struct inode *inode;
        ino_t ino;
+       int res;
 
        if (dentry->d_name.len > NILFS_NAME_LEN)
                return ERR_PTR(-ENAMETOOLONG);
 
-       ino = nilfs_inode_by_name(dir, &dentry->d_name);
-       inode = ino ? nilfs_iget(dir->i_sb, NILFS_I(dir)->i_root, ino) : NULL;
+       res = nilfs_inode_by_name(dir, &dentry->d_name, &ino);
+       if (res) {
+               if (res != -ENOENT)
+                       return ERR_PTR(res);
+               inode = NULL;
+       } else {
+               inode = nilfs_iget(dir->i_sb, NILFS_I(dir)->i_root, ino);
+       }
+
        return d_splice_alias(inode, dentry);
 }
 
@@ -263,10 +271,11 @@ static int nilfs_do_unlink(struct inode *dir, struct dentry *dentry)
        struct folio *folio;
        int err;
 
-       err = -ENOENT;
        de = nilfs_find_entry(dir, &dentry->d_name, &folio);
-       if (!de)
+       if (IS_ERR(de)) {
+               err = PTR_ERR(de);
                goto out;
+       }
 
        inode = d_inode(dentry);
        err = -EIO;
@@ -362,10 +371,11 @@ static int nilfs_rename(struct mnt_idmap *idmap,
        if (unlikely(err))
                return err;
 
-       err = -ENOENT;
        old_de = nilfs_find_entry(old_dir, &old_dentry->d_name, &old_folio);
-       if (!old_de)
+       if (IS_ERR(old_de)) {
+               err = PTR_ERR(old_de);
                goto out;
+       }
 
        if (S_ISDIR(old_inode->i_mode)) {
                err = -EIO;
@@ -382,10 +392,12 @@ static int nilfs_rename(struct mnt_idmap *idmap,
                if (dir_de && !nilfs_empty_dir(new_inode))
                        goto out_dir;
 
-               err = -ENOENT;
-               new_de = nilfs_find_entry(new_dir, &new_dentry->d_name, &new_folio);
-               if (!new_de)
+               new_de = nilfs_find_entry(new_dir, &new_dentry->d_name,
+                                         &new_folio);
+               if (IS_ERR(new_de)) {
+                       err = PTR_ERR(new_de);
                        goto out_dir;
+               }
                nilfs_set_link(new_dir, new_de, new_folio, old_inode);
                folio_release_kmap(new_folio, new_de);
                nilfs_mark_inode_dirty(new_dir);
@@ -440,12 +452,13 @@ out:
  */
 static struct dentry *nilfs_get_parent(struct dentry *child)
 {
-       unsigned long ino;
+       ino_t ino;
+       int res;
        struct nilfs_root *root;
 
-       ino = nilfs_inode_by_name(d_inode(child), &dotdot_name);
-       if (!ino)
-               return ERR_PTR(-ENOENT);
+       res = nilfs_inode_by_name(d_inode(child), &dotdot_name, &ino);
+       if (res)
+               return ERR_PTR(res);
 
        root = NILFS_I(d_inode(child))->i_root;
 
index fb1c4c5bae7c1109a72049d8b2bed85bfd6a3d18..45d03826eaf157f3f74f5239f6d2ba094eec6282 100644 (file)
@@ -254,7 +254,7 @@ static inline __u32 nilfs_mask_flags(umode_t mode, __u32 flags)
 
 /* dir.c */
 int nilfs_add_link(struct dentry *, struct inode *);
-ino_t nilfs_inode_by_name(struct inode *, const struct qstr *);
+int nilfs_inode_by_name(struct inode *dir, const struct qstr *qstr, ino_t *ino);
 int nilfs_make_empty(struct inode *, struct inode *);
 struct nilfs_dir_entry *nilfs_find_entry(struct inode *, const struct qstr *,
                struct folio **);
index 9c0b7cddeaaeedf3e6197a1ddc9a8833857b2ec6..10def4b55995631b0e01905d5a1b1d97be10d65a 100644 (file)
@@ -77,7 +77,8 @@ void nilfs_forget_buffer(struct buffer_head *bh)
        const unsigned long clear_bits =
                (BIT(BH_Uptodate) | BIT(BH_Dirty) | BIT(BH_Mapped) |
                 BIT(BH_Async_Write) | BIT(BH_NILFS_Volatile) |
-                BIT(BH_NILFS_Checked) | BIT(BH_NILFS_Redirected));
+                BIT(BH_NILFS_Checked) | BIT(BH_NILFS_Redirected) |
+                BIT(BH_Delay));
 
        lock_buffer(bh);
        set_mask_bits(&bh->b_state, clear_bits, 0);
@@ -400,13 +401,15 @@ void nilfs_clear_folio_dirty(struct folio *folio)
 
        folio_clear_uptodate(folio);
        folio_clear_mappedtodisk(folio);
+       folio_clear_checked(folio);
 
        head = folio_buffers(folio);
        if (head) {
                const unsigned long clear_bits =
                        (BIT(BH_Uptodate) | BIT(BH_Dirty) | BIT(BH_Mapped) |
                         BIT(BH_Async_Write) | BIT(BH_NILFS_Volatile) |
-                        BIT(BH_NILFS_Checked) | BIT(BH_NILFS_Redirected));
+                        BIT(BH_NILFS_Checked) | BIT(BH_NILFS_Redirected) |
+                        BIT(BH_Delay));
 
                bh = head;
                do {
index d4564b79d7bf90f55287ab55971d10f83ee62ab6..b81c298e4966ec2f2cc8b10dd0b7f0b0492b9faf 100644 (file)
@@ -13,7 +13,7 @@
 #include <linux/fs.h>
 #include <linux/module.h>
 #include <linux/slab.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include "nls_ucs2_utils.h"
 
 MODULE_DESCRIPTION("NLS UCS-2");
index 46440fbb8662d69fd5bdc49a88aaaeaf5c4fe27d..d5dbef7f5c95bb522c69b42982a0e728bc75b5f9 100644 (file)
@@ -406,8 +406,7 @@ static int __init dnotify_init(void)
                                          SLAB_PANIC|SLAB_ACCOUNT);
        dnotify_mark_cache = KMEM_CACHE(dnotify_mark, SLAB_PANIC|SLAB_ACCOUNT);
 
-       dnotify_group = fsnotify_alloc_group(&dnotify_fsnotify_ops,
-                                            FSNOTIFY_GROUP_NOFS);
+       dnotify_group = fsnotify_alloc_group(&dnotify_fsnotify_ops, 0);
        if (IS_ERR(dnotify_group))
                panic("unable to allocate fsnotify group for dnotify\n");
        dnotify_sysctl_init();
index 13454e5fd3fb424366342673de395040aa51d918..9644bc72e4573b18c523f212ec68d97a9386eb44 100644 (file)
@@ -1480,7 +1480,7 @@ SYSCALL_DEFINE2(fanotify_init, unsigned int, flags, unsigned int, event_f_flags)
 
        /* fsnotify_alloc_group takes a ref.  Dropped in fanotify_release */
        group = fsnotify_alloc_group(&fanotify_fsnotify_ops,
-                                    FSNOTIFY_GROUP_USER | FSNOTIFY_GROUP_NOFS);
+                                    FSNOTIFY_GROUP_USER);
        if (IS_ERR(group)) {
                return PTR_ERR(group);
        }
index 272c8a1dab3c27768f7da01a564c95e6059d90d3..82ae8254c068be5b4b1186a5d97ff41c1d627ae3 100644 (file)
@@ -183,8 +183,10 @@ static bool fsnotify_event_needs_parent(struct inode *inode, __u32 mnt_mask,
        BUILD_BUG_ON(FS_EVENTS_POSS_ON_CHILD & ~FS_EVENTS_POSS_TO_PARENT);
 
        /* Did either inode/sb/mount subscribe for events with parent/name? */
-       marks_mask |= fsnotify_parent_needed_mask(inode->i_fsnotify_mask);
-       marks_mask |= fsnotify_parent_needed_mask(inode->i_sb->s_fsnotify_mask);
+       marks_mask |= fsnotify_parent_needed_mask(
+                               READ_ONCE(inode->i_fsnotify_mask));
+       marks_mask |= fsnotify_parent_needed_mask(
+                               READ_ONCE(inode->i_sb->s_fsnotify_mask));
        marks_mask |= fsnotify_parent_needed_mask(mnt_mask);
 
        /* Did they subscribe for this event with parent/name info? */
@@ -195,8 +197,8 @@ static bool fsnotify_event_needs_parent(struct inode *inode, __u32 mnt_mask,
 static inline bool fsnotify_object_watched(struct inode *inode, __u32 mnt_mask,
                                           __u32 mask)
 {
-       __u32 marks_mask = inode->i_fsnotify_mask | mnt_mask |
-                          inode->i_sb->s_fsnotify_mask;
+       __u32 marks_mask = READ_ONCE(inode->i_fsnotify_mask) | mnt_mask |
+                          READ_ONCE(inode->i_sb->s_fsnotify_mask);
 
        return mask & marks_mask & ALL_FSNOTIFY_EVENTS;
 }
@@ -213,7 +215,8 @@ int __fsnotify_parent(struct dentry *dentry, __u32 mask, const void *data,
                      int data_type)
 {
        const struct path *path = fsnotify_data_path(data, data_type);
-       __u32 mnt_mask = path ? real_mount(path->mnt)->mnt_fsnotify_mask : 0;
+       __u32 mnt_mask = path ?
+               READ_ONCE(real_mount(path->mnt)->mnt_fsnotify_mask) : 0;
        struct inode *inode = d_inode(dentry);
        struct dentry *parent;
        bool parent_watched = dentry->d_flags & DCACHE_FSNOTIFY_PARENT_WATCHED;
@@ -557,13 +560,13 @@ int fsnotify(__u32 mask, const void *data, int data_type, struct inode *dir,
            (!inode2 || !inode2->i_fsnotify_marks))
                return 0;
 
-       marks_mask = sb->s_fsnotify_mask;
+       marks_mask = READ_ONCE(sb->s_fsnotify_mask);
        if (mnt)
-               marks_mask |= mnt->mnt_fsnotify_mask;
+               marks_mask |= READ_ONCE(mnt->mnt_fsnotify_mask);
        if (inode)
-               marks_mask |= inode->i_fsnotify_mask;
+               marks_mask |= READ_ONCE(inode->i_fsnotify_mask);
        if (inode2)
-               marks_mask |= inode2->i_fsnotify_mask;
+               marks_mask |= READ_ONCE(inode2->i_fsnotify_mask);
 
 
        /*
index 1de6631a3925ee99266fe5516de5c3669c8385b3..18446b7b0d495d64af470e0b598c6f2c492939ce 100644 (file)
@@ -115,7 +115,6 @@ static struct fsnotify_group *__fsnotify_alloc_group(
                                const struct fsnotify_ops *ops,
                                int flags, gfp_t gfp)
 {
-       static struct lock_class_key nofs_marks_lock;
        struct fsnotify_group *group;
 
        group = kzalloc(sizeof(struct fsnotify_group), gfp);
@@ -136,16 +135,6 @@ static struct fsnotify_group *__fsnotify_alloc_group(
 
        group->ops = ops;
        group->flags = flags;
-       /*
-        * For most backends, eviction of inode with a mark is not expected,
-        * because marks hold a refcount on the inode against eviction.
-        *
-        * Use a different lockdep class for groups that support evictable
-        * inode marks, because with evictable marks, mark_mutex is NOT
-        * fs-reclaim safe - the mutex is taken when evicting inodes.
-        */
-       if (flags & FSNOTIFY_GROUP_NOFS)
-               lockdep_set_class(&group->mark_mutex, &nofs_marks_lock);
 
        return group;
 }
index c7e451d5bd5168749ed753391ea20451eaaa5dfb..0794dcaf1e471e278e5aa82257ca38cd50c6b453 100644 (file)
@@ -569,7 +569,7 @@ static int inotify_update_existing_watch(struct fsnotify_group *group,
                /* more bits in old than in new? */
                int dropped = (old_mask & ~new_mask);
                /* more bits in this fsn_mark than the inode's mask? */
-               int do_inode = (new_mask & ~inode->i_fsnotify_mask);
+               int do_inode = (new_mask & ~READ_ONCE(inode->i_fsnotify_mask));
 
                /* update the inode with this new fsn_mark */
                if (dropped || do_inode)
index 5e170e71308868c7ab352847b524e8f6a4fb22cb..c45b222cf9c11c5479016fdbb8b0b90de699a63b 100644 (file)
@@ -128,7 +128,7 @@ __u32 fsnotify_conn_mask(struct fsnotify_mark_connector *conn)
        if (WARN_ON(!fsnotify_valid_obj_type(conn->type)))
                return 0;
 
-       return *fsnotify_conn_mask_p(conn);
+       return READ_ONCE(*fsnotify_conn_mask_p(conn));
 }
 
 static void fsnotify_get_sb_watched_objects(struct super_block *sb)
@@ -245,7 +245,11 @@ static void *__fsnotify_recalc_mask(struct fsnotify_mark_connector *conn)
                    !(mark->flags & FSNOTIFY_MARK_FLAG_NO_IREF))
                        want_iref = true;
        }
-       *fsnotify_conn_mask_p(conn) = new_mask;
+       /*
+        * We use WRITE_ONCE() to prevent silly compiler optimizations from
+        * confusing readers not holding conn->lock with partial updates.
+        */
+       WRITE_ONCE(*fsnotify_conn_mask_p(conn), new_mask);
 
        return fsnotify_update_iref(conn, want_iref);
 }
index 6ede3e924deca55dccdd5f6223b04d7150a7bc45..0763202d00c9924579934160b0555d2d9ded8615 100644 (file)
@@ -976,15 +976,17 @@ int attr_data_get_block(struct ntfs_inode *ni, CLST vcn, CLST clen, CLST *lcn,
                goto out;
 
        /* Check for compressed frame. */
-       err = attr_is_frame_compressed(ni, attr, vcn >> NTFS_LZNT_CUNIT, &hint);
+       err = attr_is_frame_compressed(ni, attr_b, vcn >> NTFS_LZNT_CUNIT,
+                                      &hint);
        if (err)
                goto out;
 
        if (hint) {
                /* if frame is compressed - don't touch it. */
                *lcn = COMPRESSED_LCN;
-               *len = hint;
-               err = -EOPNOTSUPP;
+               /* length to the end of frame. */
+               *len = NTFS_LZNT_CLUSTERS - (vcn & (NTFS_LZNT_CLUSTERS - 1));
+               err = 0;
                goto out;
        }
 
@@ -1027,16 +1029,16 @@ int attr_data_get_block(struct ntfs_inode *ni, CLST vcn, CLST clen, CLST *lcn,
 
                /* Check if 'vcn' and 'vcn0' in different attribute segments. */
                if (vcn < svcn || evcn1 <= vcn) {
-                       /* Load attribute for truncated vcn. */
-                       attr = ni_find_attr(ni, attr_b, &le, ATTR_DATA, NULL, 0,
-                                           &vcn, &mi);
-                       if (!attr) {
+                       struct ATTRIB *attr2;
+                       /* Load runs for truncated vcn. */
+                       attr2 = ni_find_attr(ni, attr_b, &le_b, ATTR_DATA, NULL,
+                                            0, &vcn, &mi);
+                       if (!attr2) {
                                err = -EINVAL;
                                goto out;
                        }
-                       svcn = le64_to_cpu(attr->nres.svcn);
-                       evcn1 = le64_to_cpu(attr->nres.evcn) + 1;
-                       err = attr_load_runs(attr, ni, run, NULL);
+                       evcn1 = le64_to_cpu(attr2->nres.evcn) + 1;
+                       err = attr_load_runs(attr2, ni, run, NULL);
                        if (err)
                                goto out;
                }
@@ -1517,6 +1519,9 @@ out:
 
 /*
  * attr_is_frame_compressed - Used to detect compressed frame.
+ *
+ * attr - base (primary) attribute segment.
+ * Only base segments contains valid 'attr->nres.c_unit'
  */
 int attr_is_frame_compressed(struct ntfs_inode *ni, struct ATTRIB *attr,
                             CLST frame, CLST *clst_data)
@@ -2600,3 +2605,74 @@ int attr_force_nonresident(struct ntfs_inode *ni)
 
        return err;
 }
+
+/*
+ * Change the compression of data attribute
+ */
+int attr_set_compress(struct ntfs_inode *ni, bool compr)
+{
+       struct ATTRIB *attr;
+       struct mft_inode *mi;
+
+       attr = ni_find_attr(ni, NULL, NULL, ATTR_DATA, NULL, 0, NULL, &mi);
+       if (!attr)
+               return -ENOENT;
+
+       if (is_attr_compressed(attr) == !!compr) {
+               /* Already required compressed state. */
+               return 0;
+       }
+
+       if (attr->non_res) {
+               u16 run_off;
+               u32 run_size;
+               char *run;
+
+               if (attr->nres.data_size) {
+                       /*
+                        * There are rare cases when it possible to change
+                        * compress state without big changes.
+                        * TODO: Process these cases.
+                        */
+                       return -EOPNOTSUPP;
+               }
+
+               run_off = le16_to_cpu(attr->nres.run_off);
+               run_size = le32_to_cpu(attr->size) - run_off;
+               run = Add2Ptr(attr, run_off);
+
+               if (!compr) {
+                       /* remove field 'attr->nres.total_size'. */
+                       memmove(run - 8, run, run_size);
+                       run_off -= 8;
+               }
+
+               if (!mi_resize_attr(mi, attr, compr ? +8 : -8)) {
+                       /*
+                        * Ignore rare case when there are no 8 bytes in record with attr.
+                        * TODO: split attribute.
+                        */
+                       return -EOPNOTSUPP;
+               }
+
+               if (compr) {
+                       /* Make a gap for 'attr->nres.total_size'. */
+                       memmove(run + 8, run, run_size);
+                       run_off += 8;
+                       attr->nres.total_size = attr->nres.alloc_size;
+               }
+               attr->nres.run_off = cpu_to_le16(run_off);
+       }
+
+       /* Update data attribute flags. */
+       if (compr) {
+               attr->flags |= ATTR_FLAG_COMPRESSED;
+               attr->nres.c_unit = NTFS_LZNT_CUNIT;
+       } else {
+               attr->flags &= ~ATTR_FLAG_COMPRESSED;
+               attr->nres.c_unit = 0;
+       }
+       mi->dirty = true;
+
+       return 0;
+}
index 9f4bd8d260901ca4fd4db97aea3687459e4ebc1a..a4d74bed74fab07f27a5e9143f4443499b3fa882 100644 (file)
@@ -382,59 +382,6 @@ bool al_remove_le(struct ntfs_inode *ni, struct ATTR_LIST_ENTRY *le)
        return true;
 }
 
-/*
- * al_delete_le - Delete first le from the list which matches its parameters.
- */
-bool al_delete_le(struct ntfs_inode *ni, enum ATTR_TYPE type, CLST vcn,
-                 const __le16 *name, u8 name_len, const struct MFT_REF *ref)
-{
-       u16 size;
-       struct ATTR_LIST_ENTRY *le;
-       size_t off;
-       typeof(ni->attr_list) *al = &ni->attr_list;
-
-       /* Scan forward to the first le that matches the input. */
-       le = al_find_ex(ni, NULL, type, name, name_len, &vcn);
-       if (!le)
-               return false;
-
-       off = PtrOffset(al->le, le);
-
-next:
-       if (off >= al->size)
-               return false;
-       if (le->type != type)
-               return false;
-       if (le->name_len != name_len)
-               return false;
-       if (name_len && ntfs_cmp_names(le_name(le), name_len, name, name_len,
-                                      ni->mi.sbi->upcase, true))
-               return false;
-       if (le64_to_cpu(le->vcn) != vcn)
-               return false;
-
-       /*
-        * The caller specified a segment reference, so we have to
-        * scan through the matching entries until we find that segment
-        * reference or we run of matching entries.
-        */
-       if (ref && memcmp(ref, &le->ref, sizeof(*ref))) {
-               off += le16_to_cpu(le->size);
-               le = Add2Ptr(al->le, off);
-               goto next;
-       }
-
-       /* Save on stack the size of 'le'. */
-       size = le16_to_cpu(le->size);
-       /* Delete the le. */
-       memmove(le, Add2Ptr(le, size), al->size - (off + size));
-
-       al->size -= size;
-       al->dirty = true;
-
-       return true;
-}
-
 int al_update(struct ntfs_inode *ni, int sync)
 {
        int err;
index 6202895a454294e0d14ab252f8eac09500859217..e370eaf9bfe2ed8db6e4b22d92c633d4ffab6858 100644 (file)
@@ -82,13 +82,14 @@ int ntfs_fileattr_set(struct mnt_idmap *idmap, struct dentry *dentry,
                      struct fileattr *fa)
 {
        struct inode *inode = d_inode(dentry);
+       struct ntfs_inode *ni = ntfs_i(inode);
        u32 flags = fa->flags;
        unsigned int new_fl = 0;
 
        if (fileattr_has_fsx(fa))
                return -EOPNOTSUPP;
 
-       if (flags & ~(FS_IMMUTABLE_FL | FS_APPEND_FL))
+       if (flags & ~(FS_IMMUTABLE_FL | FS_APPEND_FL | FS_COMPR_FL))
                return -EOPNOTSUPP;
 
        if (flags & FS_IMMUTABLE_FL)
@@ -97,6 +98,15 @@ int ntfs_fileattr_set(struct mnt_idmap *idmap, struct dentry *dentry,
        if (flags & FS_APPEND_FL)
                new_fl |= S_APPEND;
 
+       /* Allowed to change compression for empty files and for directories only. */
+       if (!is_dedup(ni) && !is_encrypted(ni) &&
+           (S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode))) {
+               /* Change compress state. */
+               int err = ni_set_compress(inode, flags & FS_COMPR_FL);
+               if (err)
+                       return err;
+       }
+
        inode_set_flags(inode, new_fl, S_IMMUTABLE | S_APPEND);
 
        inode_set_ctime_current(inode);
@@ -407,6 +417,42 @@ static int ntfs_extend(struct inode *inode, loff_t pos, size_t count,
                err = 0;
        }
 
+       if (file && is_sparsed(ni)) {
+               /*
+                * This code optimizes large writes to sparse file.
+                * TODO: merge this fragment with fallocate fragment.
+                */
+               struct ntfs_sb_info *sbi = ni->mi.sbi;
+               CLST vcn = pos >> sbi->cluster_bits;
+               CLST cend = bytes_to_cluster(sbi, end);
+               CLST cend_v = bytes_to_cluster(sbi, ni->i_valid);
+               CLST lcn, clen;
+               bool new;
+
+               if (cend_v > cend)
+                       cend_v = cend;
+
+               /*
+                * Allocate and zero new clusters.
+                * Zeroing these clusters may be too long.
+                */
+               for (; vcn < cend_v; vcn += clen) {
+                       err = attr_data_get_block(ni, vcn, cend_v - vcn, &lcn,
+                                                 &clen, &new, true);
+                       if (err)
+                               goto out;
+               }
+               /*
+                * Allocate but not zero new clusters.
+                */
+               for (; vcn < cend; vcn += clen) {
+                       err = attr_data_get_block(ni, vcn, cend - vcn, &lcn,
+                                                 &clen, &new, false);
+                       if (err)
+                               goto out;
+               }
+       }
+
        inode_set_mtime_to_ts(inode, inode_set_ctime_current(inode));
        mark_inode_dirty(inode);
 
@@ -483,7 +529,7 @@ static int ntfs_truncate(struct inode *inode, loff_t new_size)
 }
 
 /*
- * ntfs_fallocate
+ * ntfs_fallocate - file_operations::ntfs_fallocate
  *
  * Preallocate space for a file. This implements ntfs's fallocate file
  * operation, which gets called from sys_fallocate system call. User
@@ -618,6 +664,8 @@ static long ntfs_fallocate(struct file *file, int mode, loff_t vbo, loff_t len)
                ni_lock(ni);
                err = attr_collapse_range(ni, vbo, len);
                ni_unlock(ni);
+               if (err)
+                       goto out;
        } else if (mode & FALLOC_FL_INSERT_RANGE) {
                /* Check new size. */
                err = inode_newsize_ok(inode, new_size);
@@ -740,10 +788,10 @@ out:
 }
 
 /*
- * ntfs3_setattr - inode_operations::setattr
+ * ntfs_setattr - inode_operations::setattr
  */
-int ntfs3_setattr(struct mnt_idmap *idmap, struct dentry *dentry,
-                 struct iattr *attr)
+int ntfs_setattr(struct mnt_idmap *idmap, struct dentry *dentry,
+                struct iattr *attr)
 {
        struct inode *inode = d_inode(dentry);
        struct ntfs_inode *ni = ntfs_i(inode);
@@ -803,10 +851,12 @@ out:
        return err;
 }
 
-static ssize_t ntfs_file_read_iter(struct kiocb *iocb, struct iov_iter *iter)
+/*
+ * check_read_restriction:
+ * common code for ntfs_file_read_iter and ntfs_file_splice_read
+ */
+static int check_read_restriction(struct inode *inode)
 {
-       struct file *file = iocb->ki_filp;
-       struct inode *inode = file_inode(file);
        struct ntfs_inode *ni = ntfs_i(inode);
 
        if (unlikely(ntfs3_forced_shutdown(inode->i_sb)))
@@ -817,11 +867,6 @@ static ssize_t ntfs_file_read_iter(struct kiocb *iocb, struct iov_iter *iter)
                return -EOPNOTSUPP;
        }
 
-       if (is_compressed(ni) && (iocb->ki_flags & IOCB_DIRECT)) {
-               ntfs_inode_warn(inode, "direct i/o + compressed not supported");
-               return -EOPNOTSUPP;
-       }
-
 #ifndef CONFIG_NTFS3_LZX_XPRESS
        if (ni->ni_flags & NI_FLAG_COMPRESSED_MASK) {
                ntfs_inode_warn(
@@ -836,37 +881,44 @@ static ssize_t ntfs_file_read_iter(struct kiocb *iocb, struct iov_iter *iter)
                return -EOPNOTSUPP;
        }
 
-       return generic_file_read_iter(iocb, iter);
+       return 0;
 }
 
-static ssize_t ntfs_file_splice_read(struct file *in, loff_t *ppos,
-                                    struct pipe_inode_info *pipe, size_t len,
-                                    unsigned int flags)
+/*
+ * ntfs_file_read_iter - file_operations::read_iter
+ */
+static ssize_t ntfs_file_read_iter(struct kiocb *iocb, struct iov_iter *iter)
 {
-       struct inode *inode = file_inode(in);
+       struct file *file = iocb->ki_filp;
+       struct inode *inode = file_inode(file);
        struct ntfs_inode *ni = ntfs_i(inode);
+       ssize_t err;
 
-       if (unlikely(ntfs3_forced_shutdown(inode->i_sb)))
-               return -EIO;
+       err = check_read_restriction(inode);
+       if (err)
+               return err;
 
-       if (is_encrypted(ni)) {
-               ntfs_inode_warn(inode, "encrypted i/o not supported");
+       if (is_compressed(ni) && (iocb->ki_flags & IOCB_DIRECT)) {
+               ntfs_inode_warn(inode, "direct i/o + compressed not supported");
                return -EOPNOTSUPP;
        }
 
-#ifndef CONFIG_NTFS3_LZX_XPRESS
-       if (ni->ni_flags & NI_FLAG_COMPRESSED_MASK) {
-               ntfs_inode_warn(
-                       inode,
-                       "activate CONFIG_NTFS3_LZX_XPRESS to read external compressed files");
-               return -EOPNOTSUPP;
-       }
-#endif
+       return generic_file_read_iter(iocb, iter);
+}
 
-       if (is_dedup(ni)) {
-               ntfs_inode_warn(inode, "read deduplicated not supported");
-               return -EOPNOTSUPP;
-       }
+/*
+ * ntfs_file_splice_read - file_operations::splice_read
+ */
+static ssize_t ntfs_file_splice_read(struct file *in, loff_t *ppos,
+                                    struct pipe_inode_info *pipe, size_t len,
+                                    unsigned int flags)
+{
+       struct inode *inode = file_inode(in);
+       ssize_t err;
+
+       err = check_read_restriction(inode);
+       if (err)
+               return err;
 
        return filemap_splice_read(in, ppos, pipe, len, flags);
 }
@@ -1134,14 +1186,11 @@ out:
 }
 
 /*
- * ntfs_file_write_iter - file_operations::write_iter
+ * check_write_restriction:
+ * common code for ntfs_file_write_iter and ntfs_file_splice_write
  */
-static ssize_t ntfs_file_write_iter(struct kiocb *iocb, struct iov_iter *from)
+static int check_write_restriction(struct inode *inode)
 {
-       struct file *file = iocb->ki_filp;
-       struct inode *inode = file_inode(file);
-       ssize_t ret;
-       int err;
        struct ntfs_inode *ni = ntfs_i(inode);
 
        if (unlikely(ntfs3_forced_shutdown(inode->i_sb)))
@@ -1152,13 +1201,31 @@ static ssize_t ntfs_file_write_iter(struct kiocb *iocb, struct iov_iter *from)
                return -EOPNOTSUPP;
        }
 
-       if (is_compressed(ni) && (iocb->ki_flags & IOCB_DIRECT)) {
-               ntfs_inode_warn(inode, "direct i/o + compressed not supported");
+       if (is_dedup(ni)) {
+               ntfs_inode_warn(inode, "write into deduplicated not supported");
                return -EOPNOTSUPP;
        }
 
-       if (is_dedup(ni)) {
-               ntfs_inode_warn(inode, "write into deduplicated not supported");
+       return 0;
+}
+
+/*
+ * ntfs_file_write_iter - file_operations::write_iter
+ */
+static ssize_t ntfs_file_write_iter(struct kiocb *iocb, struct iov_iter *from)
+{
+       struct file *file = iocb->ki_filp;
+       struct inode *inode = file_inode(file);
+       struct ntfs_inode *ni = ntfs_i(inode);
+       ssize_t ret;
+       int err;
+
+       err = check_write_restriction(inode);
+       if (err)
+               return err;
+
+       if (is_compressed(ni) && (iocb->ki_flags & IOCB_DIRECT)) {
+               ntfs_inode_warn(inode, "direct i/o + compressed not supported");
                return -EOPNOTSUPP;
        }
 
@@ -1246,7 +1313,14 @@ static int ntfs_file_release(struct inode *inode, struct file *file)
        /* If we are last writer on the inode, drop the block reservation. */
        if (sbi->options->prealloc &&
            ((file->f_mode & FMODE_WRITE) &&
-            atomic_read(&inode->i_writecount) == 1)) {
+            atomic_read(&inode->i_writecount) == 1)
+          /*
+           * The only file when inode->i_fop = &ntfs_file_operations and
+           * init_rwsem(&ni->file.run_lock) is not called explicitly is MFT.
+           *
+           * Add additional check here.
+           */
+           && inode->i_ino != MFT_REC_MFT) {
                ni_lock(ni);
                down_write(&ni->file.run_lock);
 
@@ -1282,10 +1356,27 @@ int ntfs_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo,
        return err;
 }
 
+/*
+ * ntfs_file_splice_write - file_operations::splice_write
+ */
+static ssize_t ntfs_file_splice_write(struct pipe_inode_info *pipe,
+                                     struct file *file, loff_t *ppos,
+                                     size_t len, unsigned int flags)
+{
+       ssize_t err;
+       struct inode *inode = file_inode(file);
+
+       err = check_write_restriction(inode);
+       if (err)
+               return err;
+
+       return iter_file_splice_write(pipe, file, ppos, len, flags);
+}
+
 // clang-format off
 const struct inode_operations ntfs_file_inode_operations = {
        .getattr        = ntfs_getattr,
-       .setattr        = ntfs3_setattr,
+       .setattr        = ntfs_setattr,
        .listxattr      = ntfs_listxattr,
        .get_acl        = ntfs_get_acl,
        .set_acl        = ntfs_set_acl,
@@ -1303,10 +1394,10 @@ const struct file_operations ntfs_file_operations = {
        .compat_ioctl   = ntfs_compat_ioctl,
 #endif
        .splice_read    = ntfs_file_splice_read,
+       .splice_write   = ntfs_file_splice_write,
        .mmap           = ntfs_file_mmap,
        .open           = ntfs_file_open,
        .fsync          = generic_file_fsync,
-       .splice_write   = iter_file_splice_write,
        .fallocate      = ntfs_fallocate,
        .release        = ntfs_file_release,
 };
index a469c608a39488bc5695043994e4a19a7b611435..41c7ffad27901627102f9bd9f3b2ce218ddb6b0e 100644 (file)
@@ -102,7 +102,9 @@ void ni_clear(struct ntfs_inode *ni)
 {
        struct rb_node *node;
 
-       if (!ni->vfs_inode.i_nlink && ni->mi.mrec && is_rec_inuse(ni->mi.mrec))
+       if (!ni->vfs_inode.i_nlink && ni->mi.mrec &&
+           is_rec_inuse(ni->mi.mrec) &&
+           !(ni->mi.sbi->flags & NTFS_FLAGS_LOG_REPLAYING))
                ni_delete_all(ni);
 
        al_destroy(ni);
@@ -1900,13 +1902,13 @@ enum REPARSE_SIGN ni_parse_reparse(struct ntfs_inode *ni, struct ATTRIB *attr,
 
 /*
  * fiemap_fill_next_extent_k - a copy of fiemap_fill_next_extent
- * but it accepts kernel address for fi_extents_start
+ * but it uses 'fe_k' instead of fieinfo->fi_extents_start
  */
 static int fiemap_fill_next_extent_k(struct fiemap_extent_info *fieinfo,
-                                    u64 logical, u64 phys, u64 len, u32 flags)
+                                    struct fiemap_extent *fe_k, u64 logical,
+                                    u64 phys, u64 len, u32 flags)
 {
        struct fiemap_extent extent;
-       struct fiemap_extent __user *dest = fieinfo->fi_extents_start;
 
        /* only count the extents */
        if (fieinfo->fi_extents_max == 0) {
@@ -1930,8 +1932,7 @@ static int fiemap_fill_next_extent_k(struct fiemap_extent_info *fieinfo,
        extent.fe_length = len;
        extent.fe_flags = flags;
 
-       dest += fieinfo->fi_extents_mapped;
-       memcpy(dest, &extent, sizeof(extent));
+       memcpy(fe_k + fieinfo->fi_extents_mapped, &extent, sizeof(extent));
 
        fieinfo->fi_extents_mapped++;
        if (fieinfo->fi_extents_mapped == fieinfo->fi_extents_max)
@@ -1949,7 +1950,6 @@ int ni_fiemap(struct ntfs_inode *ni, struct fiemap_extent_info *fieinfo,
              __u64 vbo, __u64 len)
 {
        int err = 0;
-       struct fiemap_extent __user *fe_u = fieinfo->fi_extents_start;
        struct fiemap_extent *fe_k = NULL;
        struct ntfs_sb_info *sbi = ni->mi.sbi;
        u8 cluster_bits = sbi->cluster_bits;
@@ -2008,7 +2008,6 @@ int ni_fiemap(struct ntfs_inode *ni, struct fiemap_extent_info *fieinfo,
                err = -ENOMEM;
                goto out;
        }
-       fieinfo->fi_extents_start = fe_k;
 
        end = vbo + len;
        alloc_size = le64_to_cpu(attr->nres.alloc_size);
@@ -2098,8 +2097,8 @@ int ni_fiemap(struct ntfs_inode *ni, struct fiemap_extent_info *fieinfo,
                        if (vbo + dlen >= end)
                                flags |= FIEMAP_EXTENT_LAST;
 
-                       err = fiemap_fill_next_extent_k(fieinfo, vbo, lbo, dlen,
-                                                       flags);
+                       err = fiemap_fill_next_extent_k(fieinfo, fe_k, vbo, lbo,
+                                                       dlen, flags);
 
                        if (err < 0)
                                break;
@@ -2120,7 +2119,7 @@ int ni_fiemap(struct ntfs_inode *ni, struct fiemap_extent_info *fieinfo,
                if (vbo + bytes >= end)
                        flags |= FIEMAP_EXTENT_LAST;
 
-               err = fiemap_fill_next_extent_k(fieinfo, vbo, lbo, bytes,
+               err = fiemap_fill_next_extent_k(fieinfo, fe_k, vbo, lbo, bytes,
                                                flags);
                if (err < 0)
                        break;
@@ -2137,15 +2136,13 @@ int ni_fiemap(struct ntfs_inode *ni, struct fiemap_extent_info *fieinfo,
        /*
         * Copy to user memory out of lock
         */
-       if (copy_to_user(fe_u, fe_k,
+       if (copy_to_user(fieinfo->fi_extents_start, fe_k,
                         fieinfo->fi_extents_max *
                                 sizeof(struct fiemap_extent))) {
                err = -EFAULT;
        }
 
 out:
-       /* Restore original pointer. */
-       fieinfo->fi_extents_start = fe_u;
        kfree(fe_k);
        return err;
 }
@@ -3455,3 +3452,75 @@ out:
 
        return 0;
 }
+
+/*
+ * ni_set_compress
+ *
+ * Helper for 'ntfs_fileattr_set'.
+ * Changes compression for empty files and directories only.
+ */
+int ni_set_compress(struct inode *inode, bool compr)
+{
+       int err;
+       struct ntfs_inode *ni = ntfs_i(inode);
+       struct ATTR_STD_INFO *std;
+       const char *bad_inode;
+
+       if (is_compressed(ni) == !!compr)
+               return 0;
+
+       if (is_sparsed(ni)) {
+               /* sparse and compress not compatible. */
+               return -EOPNOTSUPP;
+       }
+
+       if (!S_ISREG(inode->i_mode) && !S_ISDIR(inode->i_mode)) {
+               /*Skip other inodes. (symlink,fifo,...) */
+               return -EOPNOTSUPP;
+       }
+
+       bad_inode = NULL;
+
+       ni_lock(ni);
+
+       std = ni_std(ni);
+       if (!std) {
+               bad_inode = "no std";
+               goto out;
+       }
+
+       if (S_ISREG(inode->i_mode)) {
+               err = attr_set_compress(ni, compr);
+               if (err) {
+                       if (err == -ENOENT) {
+                               /* Fix on the fly? */
+                               /* Each file must contain data attribute. */
+                               bad_inode = "no data attribute";
+                       }
+                       goto out;
+               }
+       }
+
+       ni->std_fa = std->fa;
+       if (compr)
+               std->fa |= FILE_ATTRIBUTE_COMPRESSED;
+       else
+               std->fa &= ~FILE_ATTRIBUTE_COMPRESSED;
+
+       if (ni->std_fa != std->fa) {
+               ni->std_fa = std->fa;
+               ni->mi.dirty = true;
+       }
+       /* update duplicate information and directory entries in ni_write_inode.*/
+       ni->ni_flags |= NI_FLAG_UPDATE_PARENT;
+       err = 0;
+
+out:
+       ni_unlock(ni);
+       if (bad_inode) {
+               ntfs_bad_inode(inode, bad_inode);
+               err = -EINVAL;
+       }
+
+       return err;
+}
index c64dd114ac652f236353b5affd73c271b76a47d9..d0d530f4e2b95efa6f9cdc51b6328655304bdfc7 100644 (file)
@@ -609,14 +609,29 @@ static inline void add_client(struct CLIENT_REC *ca, u16 index, __le16 *head)
        *head = cpu_to_le16(index);
 }
 
+/*
+ * Enumerate restart table.
+ *
+ * @t - table to enumerate.
+ * @c - current enumerated element.
+ *
+ * enumeration starts with @c == NULL
+ * returns next element or NULL
+ */
 static inline void *enum_rstbl(struct RESTART_TABLE *t, void *c)
 {
        __le32 *e;
        u32 bprt;
-       u16 rsize = t ? le16_to_cpu(t->size) : 0;
+       u16 rsize;
+
+       if (!t)
+               return NULL;
+
+       rsize = le16_to_cpu(t->size);
 
        if (!c) {
-               if (!t || !t->total)
+               /* start enumeration. */
+               if (!t->total)
                        return NULL;
                e = Add2Ptr(t, sizeof(struct RESTART_TABLE));
        } else {
index f672072e6bd464bff3b9e97609889cd536d637a5..be04d2845bb7bc6abf0e58816edce1862059efdb 100644 (file)
@@ -536,11 +536,15 @@ struct inode *ntfs_iget5(struct super_block *sb, const struct MFT_REF *ref,
        if (inode->i_state & I_NEW)
                inode = ntfs_read_mft(inode, name, ref);
        else if (ref->seq != ntfs_i(inode)->mi.mrec->seq) {
-               /* Inode overlaps? */
-               _ntfs_bad_inode(inode);
+               /*
+                * Sequence number is not expected.
+                * Looks like inode was reused but caller uses the old reference
+                */
+               iput(inode);
+               inode = ERR_PTR(-ESTALE);
        }
 
-       if (IS_ERR(inode) && name)
+       if (IS_ERR(inode))
                ntfs_set_state(sb->s_fs_info, NTFS_DIRTY_ERROR);
 
        return inode;
@@ -605,7 +609,8 @@ static noinline int ntfs_get_block_vbo(struct inode *inode, u64 vbo,
 
        bytes = ((u64)len << cluster_bits) - off;
 
-       if (lcn == SPARSE_LCN) {
+       if (lcn >= sbi->used.bitmap.nbits) {
+               /* This case includes resident/compressed/sparse. */
                if (!create) {
                        if (bh->b_size > bytes)
                                bh->b_size = bytes;
@@ -1672,7 +1677,10 @@ out6:
        attr = ni_find_attr(ni, NULL, NULL, ATTR_EA, NULL, 0, NULL, NULL);
        if (attr && attr->non_res) {
                /* Delete ATTR_EA, if non-resident. */
-               attr_set_size(ni, ATTR_EA, NULL, 0, NULL, 0, NULL, false, NULL);
+               struct runs_tree run;
+               run_init(&run);
+               attr_set_size(ni, ATTR_EA, NULL, 0, &run, 0, NULL, false, NULL);
+               run_close(&run);
        }
 
        if (rp_inserted)
@@ -2076,7 +2084,7 @@ static const char *ntfs_get_link(struct dentry *de, struct inode *inode,
 // clang-format off
 const struct inode_operations ntfs_link_inode_operations = {
        .get_link       = ntfs_get_link,
-       .setattr        = ntfs3_setattr,
+       .setattr        = ntfs_setattr,
        .listxattr      = ntfs_listxattr,
 };
 
index dd7ced000d0e755ca1b337273dab7577c194a7c4..f0cad9c4a289485ec165e84b87919e0152f987cb 100644 (file)
@@ -12,7 +12,7 @@
 #include <linux/compiler.h>
 #include <linux/types.h>
 #include <linux/slab.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 
 /* "Force inline" macro (not required, but helpful for performance)  */
index 6b16f07073c12cf349cfa1cfe6bcbf0168b38d28..4d5701024f8309ca18b498147e35c60321f65e46 100644 (file)
@@ -512,8 +512,7 @@ static int lzx_decompress_block(const struct lzx_decompressor *d,
                         * the same code.  (For R0, the swap is a no-op.)
                         */
                        match_offset = recent_offsets[offset_slot];
-                       recent_offsets[offset_slot] = recent_offsets[0];
-                       recent_offsets[0] = match_offset;
+                       swap(recent_offsets[offset_slot], recent_offsets[0]);
                } else {
                        /* Explicit offset  */
 
index 4aae598d6d884625ca264f3e6c74bdf201505e54..fdc9b2ebf3410e9ae888a5f738190a89d223cfe5 100644 (file)
@@ -236,6 +236,9 @@ static inline ssize_t decompress_chunk(u8 *unc, u8 *unc_end, const u8 *cmpr,
 
        /* Do decompression until pointers are inside range. */
        while (up < unc_end && cmpr < cmpr_end) {
+               // return err if more than LZNT_CHUNK_SIZE bytes are written
+               if (up - unc > LZNT_CHUNK_SIZE)
+                       return -EINVAL;
                /* Correct index */
                while (unc + s_max_off[index] < up)
                        index += 1;
index f16d318c4372a4c446a08cd82a6fcbb0b31e9c40..abf7e81584a9b27e1d7c193ffdfab04417e9e75b 100644 (file)
@@ -81,7 +81,7 @@ static struct dentry *ntfs_lookup(struct inode *dir, struct dentry *dentry,
                if (err < 0)
                        inode = ERR_PTR(err);
                else {
-                       ni_lock(ni);
+                       ni_lock_dir(ni);
                        inode = dir_search_u(dir, uni, NULL);
                        ni_unlock(ni);
                }
@@ -395,7 +395,7 @@ static int ntfs_d_hash(const struct dentry *dentry, struct qstr *name)
        /*
         * Try slow way with current upcase table
         */
-       uni = __getname();
+       uni = kmem_cache_alloc(names_cachep, GFP_NOWAIT);
        if (!uni)
                return -ENOMEM;
 
@@ -417,7 +417,7 @@ static int ntfs_d_hash(const struct dentry *dentry, struct qstr *name)
        err = 0;
 
 out:
-       __putname(uni);
+       kmem_cache_free(names_cachep, uni);
        return err;
 }
 
@@ -503,7 +503,7 @@ const struct inode_operations ntfs_dir_inode_operations = {
        .rename         = ntfs_rename,
        .get_acl        = ntfs_get_acl,
        .set_acl        = ntfs_set_acl,
-       .setattr        = ntfs3_setattr,
+       .setattr        = ntfs_setattr,
        .getattr        = ntfs_getattr,
        .listxattr      = ntfs_listxattr,
        .fiemap         = ntfs_fiemap,
@@ -512,7 +512,7 @@ const struct inode_operations ntfs_dir_inode_operations = {
 };
 
 const struct inode_operations ntfs_special_inode_operations = {
-       .setattr        = ntfs3_setattr,
+       .setattr        = ntfs_setattr,
        .getattr        = ntfs_getattr,
        .listxattr      = ntfs_listxattr,
        .get_acl        = ntfs_get_acl,
index 584f814715f49fa90370475606347c249e9f1252..26e1e1379c04e24ed55580d042c2d78a50f86f8a 100644 (file)
@@ -334,7 +334,7 @@ struct mft_inode {
 
 /* Nested class for ntfs_inode::ni_lock. */
 enum ntfs_inode_mutex_lock_class {
-       NTFS_INODE_MUTEX_DIRTY,
+       NTFS_INODE_MUTEX_DIRTY = 1,
        NTFS_INODE_MUTEX_SECURITY,
        NTFS_INODE_MUTEX_OBJID,
        NTFS_INODE_MUTEX_REPARSE,
@@ -453,6 +453,7 @@ int attr_collapse_range(struct ntfs_inode *ni, u64 vbo, u64 bytes);
 int attr_insert_range(struct ntfs_inode *ni, u64 vbo, u64 bytes);
 int attr_punch_hole(struct ntfs_inode *ni, u64 vbo, u64 bytes, u32 *frame_size);
 int attr_force_nonresident(struct ntfs_inode *ni);
+int attr_set_compress(struct ntfs_inode *ni, bool compr);
 
 /* Functions from attrlist.c */
 void al_destroy(struct ntfs_inode *ni);
@@ -471,8 +472,6 @@ int al_add_le(struct ntfs_inode *ni, enum ATTR_TYPE type, const __le16 *name,
              u8 name_len, CLST svcn, __le16 id, const struct MFT_REF *ref,
              struct ATTR_LIST_ENTRY **new_le);
 bool al_remove_le(struct ntfs_inode *ni, struct ATTR_LIST_ENTRY *le);
-bool al_delete_le(struct ntfs_inode *ni, enum ATTR_TYPE type, CLST vcn,
-                 const __le16 *name, u8 name_len, const struct MFT_REF *ref);
 int al_update(struct ntfs_inode *ni, int sync);
 static inline size_t al_aligned(size_t size)
 {
@@ -502,8 +501,8 @@ int ntfs_fileattr_set(struct mnt_idmap *idmap, struct dentry *dentry,
                      struct fileattr *fa);
 int ntfs_getattr(struct mnt_idmap *idmap, const struct path *path,
                 struct kstat *stat, u32 request_mask, u32 flags);
-int ntfs3_setattr(struct mnt_idmap *idmap, struct dentry *dentry,
-                 struct iattr *attr);
+int ntfs_setattr(struct mnt_idmap *idmap, struct dentry *dentry,
+                struct iattr *attr);
 int ntfs_file_open(struct inode *inode, struct file *file);
 int ntfs_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo,
                __u64 start, __u64 len);
@@ -588,6 +587,7 @@ int ni_rename(struct ntfs_inode *dir_ni, struct ntfs_inode *new_dir_ni,
              bool *is_bad);
 
 bool ni_is_dirty(struct inode *inode);
+int ni_set_compress(struct inode *inode, bool compr);
 
 /* Globals from fslog.c */
 bool check_index_header(const struct INDEX_HDR *hdr, size_t bytes);
index 6c76503edc200da63711188a24102213e9b33454..f810f0419d25ea130fd9c01100f9f6258faa5108 100644 (file)
@@ -223,29 +223,21 @@ struct ATTRIB *mi_enum_attr(struct mft_inode *mi, struct ATTRIB *attr)
                prev_type = 0;
                attr = Add2Ptr(rec, off);
        } else {
-               /* Check if input attr inside record. */
+               /*
+                * We don't need to check previous attr here. There is
+                * a bounds checking in the previous round.
+                */
                off = PtrOffset(rec, attr);
-               if (off >= used)
-                       return NULL;
 
                asize = le32_to_cpu(attr->size);
-               if (asize < SIZEOF_RESIDENT) {
-                       /* Impossible 'cause we should not return such attribute. */
-                       return NULL;
-               }
-
-               /* Overflow check. */
-               if (off + asize < off)
-                       return NULL;
 
                prev_type = le32_to_cpu(attr->type);
                attr = Add2Ptr(attr, asize);
                off += asize;
        }
 
-       asize = le32_to_cpu(attr->size);
-
        /* Can we use the first field (attr->type). */
+       /* NOTE: this code also checks attr->size availability. */
        if (off + 8 > used) {
                static_assert(ALIGN(sizeof(enum ATTR_TYPE), 8) == 8);
                return NULL;
@@ -265,6 +257,8 @@ struct ATTRIB *mi_enum_attr(struct mft_inode *mi, struct ATTRIB *attr)
        if (t32 < prev_type)
                return NULL;
 
+       asize = le32_to_cpu(attr->size);
+
        /* Check overflow and boundary. */
        if (off + asize < off || off + asize > used)
                return NULL;
@@ -293,6 +287,10 @@ struct ATTRIB *mi_enum_attr(struct mft_inode *mi, struct ATTRIB *attr)
        if (attr->non_res != 1)
                return NULL;
 
+       /* Can we use memory including attr->nres.valid_size? */
+       if (asize < SIZEOF_NONRESIDENT)
+               return NULL;
+
        t16 = le16_to_cpu(attr->nres.run_off);
        if (t16 > asize)
                return NULL;
@@ -319,7 +317,8 @@ struct ATTRIB *mi_enum_attr(struct mft_inode *mi, struct ATTRIB *attr)
 
        if (!attr->nres.svcn && is_attr_ext(attr)) {
                /* First segment of sparse/compressed attribute */
-               if (asize + 8 < SIZEOF_NONRESIDENT_EX)
+               /* Can we use memory including attr->nres.total_size? */
+               if (asize < SIZEOF_NONRESIDENT_EX)
                        return NULL;
 
                tot_size = le64_to_cpu(attr->nres.total_size);
@@ -329,10 +328,10 @@ struct ATTRIB *mi_enum_attr(struct mft_inode *mi, struct ATTRIB *attr)
                if (tot_size > alloc_size)
                        return NULL;
        } else {
-               if (asize + 8 < SIZEOF_NONRESIDENT)
+               if (attr->nres.c_unit)
                        return NULL;
 
-               if (attr->nres.c_unit)
+               if (alloc_size > mi->sbi->volume.size)
                        return NULL;
        }
 
index cb8cf0161177b944bbafb5eb96297f607620343c..58e988cd80490dff9b9930a0783d6e1b06fb99f0 100644 (file)
@@ -959,7 +959,7 @@ int run_unpack(struct runs_tree *run, struct ntfs_sb_info *sbi, CLST ino,
                 * Large positive number requires to store 5 bytes
                 * e.g.: 05 FF 7E FF FF 00 00 00
                 */
-               if (size_size > 8)
+               if (size_size > sizeof(len))
                        return -EINVAL;
 
                len = run_unpack_s64(run_buf, size_size, 0);
@@ -971,7 +971,7 @@ int run_unpack(struct runs_tree *run, struct ntfs_sb_info *sbi, CLST ino,
 
                if (!offset_size)
                        lcn = SPARSE_LCN64;
-               else if (offset_size <= 8) {
+               else if (offset_size <= sizeof(s64)) {
                        s64 dlcn;
 
                        /* Initial value of dlcn is -1 or 0. */
@@ -984,8 +984,10 @@ int run_unpack(struct runs_tree *run, struct ntfs_sb_info *sbi, CLST ino,
                                return -EINVAL;
                        lcn = prev_lcn + dlcn;
                        prev_lcn = lcn;
-               } else
+               } else {
+                       /* The size of 'dlcn' can't be > 8. */
                        return -EINVAL;
+               }
 
                next_vcn = vcn64 + len;
                /* Check boundary. */
index a8758b85803f4460f4558d6a0a06b4801b153984..6a0f6b0a3ab2a529d6f37a7e6ddf0b12b27d117f 100644 (file)
@@ -90,7 +90,7 @@ void ntfs_printk(const struct super_block *sb, const char *fmt, ...)
        level = printk_get_level(fmt);
        vaf.fmt = printk_skip_level(fmt);
        vaf.va = &args;
-       printk("%c%cntfs3: %s: %pV\n", KERN_SOH_ASCII, level, sb->s_id, &vaf);
+       printk("%c%cntfs3(%s): %pV\n", KERN_SOH_ASCII, level, sb->s_id, &vaf);
 
        va_end(args);
 }
@@ -124,10 +124,15 @@ void ntfs_inode_printk(struct inode *inode, const char *fmt, ...)
                struct dentry *de = d_find_alias(inode);
 
                if (de) {
+                       int len;
                        spin_lock(&de->d_lock);
-                       snprintf(name, sizeof(s_name_buf), " \"%s\"",
-                                de->d_name.name);
+                       len = snprintf(name, sizeof(s_name_buf), " \"%s\"",
+                                      de->d_name.name);
                        spin_unlock(&de->d_lock);
+                       if (len <= 0)
+                               name[0] = 0;
+                       else if (len >= sizeof(s_name_buf))
+                               name[sizeof(s_name_buf) - 1] = 0;
                } else {
                        name[0] = 0;
                }
@@ -140,7 +145,7 @@ void ntfs_inode_printk(struct inode *inode, const char *fmt, ...)
        vaf.fmt = printk_skip_level(fmt);
        vaf.va = &args;
 
-       printk("%c%cntfs3: %s: ino=%lx,%s %pV\n", KERN_SOH_ASCII, level,
+       printk("%c%cntfs3(%s): ino=%lx,%s %pV\n", KERN_SOH_ASCII, level,
               sb->s_id, inode->i_ino, name ? name : "", &vaf);
 
        va_end(args);
@@ -259,23 +264,23 @@ enum Opt {
 
 // clang-format off
 static const struct fs_parameter_spec ntfs_fs_parameters[] = {
-       fsparam_uid("uid",                      Opt_uid),
-       fsparam_gid("gid",                      Opt_gid),
-       fsparam_u32oct("umask",                 Opt_umask),
-       fsparam_u32oct("dmask",                 Opt_dmask),
-       fsparam_u32oct("fmask",                 Opt_fmask),
-       fsparam_flag_no("sys_immutable",        Opt_immutable),
-       fsparam_flag_no("discard",              Opt_discard),
-       fsparam_flag_no("force",                Opt_force),
-       fsparam_flag_no("sparse",               Opt_sparse),
-       fsparam_flag_no("hidden",               Opt_nohidden),
-       fsparam_flag_no("hide_dot_files",       Opt_hide_dot_files),
-       fsparam_flag_no("windows_names",        Opt_windows_names),
-       fsparam_flag_no("showmeta",             Opt_showmeta),
-       fsparam_flag_no("acl",                  Opt_acl),
-       fsparam_string("iocharset",             Opt_iocharset),
-       fsparam_flag_no("prealloc",             Opt_prealloc),
-       fsparam_flag_no("case",         Opt_nocase),
+       fsparam_uid("uid",              Opt_uid),
+       fsparam_gid("gid",              Opt_gid),
+       fsparam_u32oct("umask",         Opt_umask),
+       fsparam_u32oct("dmask",         Opt_dmask),
+       fsparam_u32oct("fmask",         Opt_fmask),
+       fsparam_flag("sys_immutable",   Opt_immutable),
+       fsparam_flag("discard",         Opt_discard),
+       fsparam_flag("force",           Opt_force),
+       fsparam_flag("sparse",          Opt_sparse),
+       fsparam_flag("nohidden",        Opt_nohidden),
+       fsparam_flag("hide_dot_files",  Opt_hide_dot_files),
+       fsparam_flag("windows_names",   Opt_windows_names),
+       fsparam_flag("showmeta",        Opt_showmeta),
+       fsparam_flag("acl",             Opt_acl),
+       fsparam_string("iocharset",     Opt_iocharset),
+       fsparam_flag("prealloc",        Opt_prealloc),
+       fsparam_flag("nocase",          Opt_nocase),
        {}
 };
 // clang-format on
@@ -345,28 +350,28 @@ static int ntfs_fs_parse_param(struct fs_context *fc,
                opts->fmask = 1;
                break;
        case Opt_immutable:
-               opts->sys_immutable = result.negated ? 0 : 1;
+               opts->sys_immutable = 1;
                break;
        case Opt_discard:
-               opts->discard = result.negated ? 0 : 1;
+               opts->discard = 1;
                break;
        case Opt_force:
-               opts->force = result.negated ? 0 : 1;
+               opts->force = 1;
                break;
        case Opt_sparse:
-               opts->sparse = result.negated ? 0 : 1;
+               opts->sparse = 1;
                break;
        case Opt_nohidden:
-               opts->nohidden = result.negated ? 1 : 0;
+               opts->nohidden = 1;
                break;
        case Opt_hide_dot_files:
-               opts->hide_dot_files = result.negated ? 0 : 1;
+               opts->hide_dot_files = 1;
                break;
        case Opt_windows_names:
-               opts->windows_names = result.negated ? 0 : 1;
+               opts->windows_names = 1;
                break;
        case Opt_showmeta:
-               opts->showmeta = result.negated ? 0 : 1;
+               opts->showmeta = 1;
                break;
        case Opt_acl:
                if (!result.negated)
@@ -385,10 +390,10 @@ static int ntfs_fs_parse_param(struct fs_context *fc,
                param->string = NULL;
                break;
        case Opt_prealloc:
-               opts->prealloc = result.negated ? 0 : 1;
+               opts->prealloc = 1;
                break;
        case Opt_nocase:
-               opts->nocase = result.negated ? 1 : 0;
+               opts->nocase = 1;
                break;
        default:
                /* Should not be here unless we forget add case. */
@@ -1491,11 +1496,10 @@ static int ntfs_fill_super(struct super_block *sb, struct fs_context *fc)
 
 #ifdef __BIG_ENDIAN
        {
-               const __le16 *src = sbi->upcase;
                u16 *dst = sbi->upcase;
 
                for (i = 0; i < 0x10000; i++)
-                       *dst++ = le16_to_cpu(*src++);
+                       __swab16s(dst++);
        }
 #endif
 
index 0703e1ae32b2e035fcdfb763702da4111999bc08..e0055dcf8fe38ef845e97b871b8da8ba3bf258b1 100644 (file)
@@ -705,7 +705,7 @@ int ntfs_init_acl(struct mnt_idmap *idmap, struct inode *inode,
 #endif
 
 /*
- * ntfs_acl_chmod - Helper for ntfs3_setattr().
+ * ntfs_acl_chmod - Helper for ntfs_setattr().
  */
 int ntfs_acl_chmod(struct mnt_idmap *idmap, struct dentry *dentry)
 {
index ad131a2fc58e4014c57629932b8b8bc772660abb..06af21982c16aba9d7970d43c0c4ffd860ab0aa0 100644 (file)
@@ -1129,9 +1129,12 @@ int ocfs2_setattr(struct mnt_idmap *idmap, struct dentry *dentry,
        trace_ocfs2_setattr(inode, dentry,
                            (unsigned long long)OCFS2_I(inode)->ip_blkno,
                            dentry->d_name.len, dentry->d_name.name,
-                           attr->ia_valid, attr->ia_mode,
-                           from_kuid(&init_user_ns, attr->ia_uid),
-                           from_kgid(&init_user_ns, attr->ia_gid));
+                           attr->ia_valid,
+                               attr->ia_valid & ATTR_MODE ? attr->ia_mode : 0,
+                               attr->ia_valid & ATTR_UID ?
+                                       from_kuid(&init_user_ns, attr->ia_uid) : 0,
+                               attr->ia_valid & ATTR_GID ?
+                                       from_kgid(&init_user_ns, attr->ia_gid) : 0);
 
        /* ensuring we don't even attempt to truncate a symlink */
        if (S_ISLNK(inode->i_mode))
@@ -1784,6 +1787,14 @@ int ocfs2_remove_inode_range(struct inode *inode,
                return 0;
 
        if (OCFS2_I(inode)->ip_dyn_features & OCFS2_INLINE_DATA_FL) {
+               int id_count = ocfs2_max_inline_data_with_xattr(inode->i_sb, di);
+
+               if (byte_start > id_count || byte_start + byte_len > id_count) {
+                       ret = -EINVAL;
+                       mlog_errno(ret);
+                       goto out;
+               }
+
                ret = ocfs2_truncate_inline(inode, di_bh, byte_start,
                                            byte_start + byte_len, 0);
                if (ret) {
index acaeb3e25c88ecdd635619872eea8ebe23622349..5da4df2f9b18a637ed83cde8f2fe52f9034f5290 100644 (file)
--- a/fs/open.c
+++ b/fs/open.c
@@ -1457,6 +1457,8 @@ SYSCALL_DEFINE4(openat2, int, dfd, const char __user *, filename,
 
        if (unlikely(usize < OPEN_HOW_SIZE_VER0))
                return -EINVAL;
+       if (unlikely(usize > PAGE_SIZE))
+               return -E2BIG;
 
        err = copy_struct_from_user(&tmp, sizeof(tmp), how, usize);
        if (err)
index e2df7eeadc7aa2bb6d15ff6b3c363655bd333469..3d4b883a76605c659d2c28209fc0fa9e2f046d8c 100644 (file)
@@ -53,7 +53,7 @@
 #include <linux/exportfs.h>
 #include <linux/hashtable.h>
 
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #include "orangefs-dev-proto.h"
 
index 4504493b20beda381683c1485a8bcaac0ab7da7f..4444c78e2e0c34e8a498538c1280284d477595af 100644 (file)
@@ -231,6 +231,11 @@ static void ovl_file_modified(struct file *file)
        ovl_copyattr(file_inode(file));
 }
 
+static void ovl_file_end_write(struct file *file, loff_t pos, ssize_t ret)
+{
+       ovl_file_modified(file);
+}
+
 static void ovl_file_accessed(struct file *file)
 {
        struct inode *inode, *upperinode;
@@ -294,7 +299,7 @@ static ssize_t ovl_write_iter(struct kiocb *iocb, struct iov_iter *iter)
        struct backing_file_ctx ctx = {
                .cred = ovl_creds(inode->i_sb),
                .user_file = file,
-               .end_write = ovl_file_modified,
+               .end_write = ovl_file_end_write,
        };
 
        if (!iov_iter_count(iter))
@@ -364,7 +369,7 @@ static ssize_t ovl_splice_write(struct pipe_inode_info *pipe, struct file *out,
        struct backing_file_ctx ctx = {
                .cred = ovl_creds(inode->i_sb),
                .user_file = out,
-               .end_write = ovl_file_modified,
+               .end_write = ovl_file_end_write,
        };
 
        inode_lock(inode);
index 7ffdc88dfb527d9cf8a133955c9379f8f89a1788..80675b6bf88459c22787edaa68db360bdc0d0782 100644 (file)
@@ -120,6 +120,7 @@ static long pidfd_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
        struct nsproxy *nsp __free(put_nsproxy) = NULL;
        struct pid *pid = pidfd_pid(file);
        struct ns_common *ns_common = NULL;
+       struct pid_namespace *pid_ns;
 
        if (arg)
                return -EINVAL;
@@ -202,7 +203,9 @@ static long pidfd_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
        case PIDFD_GET_PID_NAMESPACE:
                if (IS_ENABLED(CONFIG_PID_NS)) {
                        rcu_read_lock();
-                       ns_common = to_ns_common( get_pid_ns(task_active_pid_ns(task)));
+                       pid_ns = task_active_pid_ns(task);
+                       if (pid_ns)
+                               ns_common = to_ns_common(get_pid_ns(pid_ns));
                        rcu_read_unlock();
                }
                break;
index 1f54a54bfb91304914d90d1730588e4876aa4236..5e391cbca7a3be0cb02f55e96d6728ad98e3ea16 100644 (file)
@@ -77,7 +77,7 @@ static int seq_fdinfo_open(struct inode *inode, struct file *file)
        return single_open(file, seq_show, inode);
 }
 
-/**
+/*
  * Shared /proc/pid/fdinfo and /proc/pid/fdinfo/fd permission helper to ensure
  * that the current task has PTRACE_MODE_READ in addition to the normal
  * POSIX-like checks.
index 7d0acdad74e2ffd916b3e3b8deb51918dfad67cb..51446c59388f10761bc95b4378a5d1c074b0556d 100644 (file)
@@ -50,6 +50,20 @@ static struct proc_dir_entry *proc_root_kcore;
 #define        kc_offset_to_vaddr(o) ((o) + PAGE_OFFSET)
 #endif
 
+#ifndef kc_xlate_dev_mem_ptr
+#define kc_xlate_dev_mem_ptr kc_xlate_dev_mem_ptr
+static inline void *kc_xlate_dev_mem_ptr(phys_addr_t phys)
+{
+       return __va(phys);
+}
+#endif
+#ifndef kc_unxlate_dev_mem_ptr
+#define kc_unxlate_dev_mem_ptr kc_unxlate_dev_mem_ptr
+static inline void kc_unxlate_dev_mem_ptr(phys_addr_t phys, void *virt)
+{
+}
+#endif
+
 static LIST_HEAD(kclist_head);
 static DECLARE_RWSEM(kclist_lock);
 static int kcore_need_update = 1;
@@ -471,6 +485,8 @@ static ssize_t read_kcore_iter(struct kiocb *iocb, struct iov_iter *iter)
        while (buflen) {
                struct page *page;
                unsigned long pfn;
+               phys_addr_t phys;
+               void *__start;
 
                /*
                 * If this is the first iteration or the address is not within
@@ -537,7 +553,8 @@ static ssize_t read_kcore_iter(struct kiocb *iocb, struct iov_iter *iter)
                        }
                        break;
                case KCORE_RAM:
-                       pfn = __pa(start) >> PAGE_SHIFT;
+                       phys = __pa(start);
+                       pfn =  phys >> PAGE_SHIFT;
                        page = pfn_to_online_page(pfn);
 
                        /*
@@ -557,13 +574,28 @@ static ssize_t read_kcore_iter(struct kiocb *iocb, struct iov_iter *iter)
                        fallthrough;
                case KCORE_VMEMMAP:
                case KCORE_TEXT:
+                       if (m->type == KCORE_RAM) {
+                               __start = kc_xlate_dev_mem_ptr(phys);
+                               if (!__start) {
+                                       ret = -ENOMEM;
+                                       if (iov_iter_zero(tsz, iter) != tsz)
+                                               ret = -EFAULT;
+                                       goto out;
+                               }
+                       } else {
+                               __start = (void *)start;
+                       }
+
                        /*
                         * Sadly we must use a bounce buffer here to be able to
                         * make use of copy_from_kernel_nofault(), as these
                         * memory regions might not always be mapped on all
                         * architectures.
                         */
-                       if (copy_from_kernel_nofault(buf, (void *)start, tsz)) {
+                       ret = copy_from_kernel_nofault(buf, __start, tsz);
+                       if (m->type == KCORE_RAM)
+                               kc_unxlate_dev_mem_ptr(phys, __start);
+                       if (ret) {
                                if (iov_iter_zero(tsz, iter) != tsz) {
                                        ret = -EFAULT;
                                        goto out;
index 72f14fd59c2d01aaeac216cdd24c8006e2f875b5..e52bd96137a62e78badbbf7a42e522f4a871e1fe 100644 (file)
@@ -909,8 +909,15 @@ static void show_smap_vma_flags(struct seq_file *m, struct vm_area_struct *vma)
 {
        /*
         * Don't forget to update Documentation/ on changes.
+        *
+        * The length of the second argument of mnemonics[]
+        * needs to be 3 instead of previously set 2
+        * (i.e. from [BITS_PER_LONG][2] to [BITS_PER_LONG][3])
+        * to avoid spurious
+        * -Werror=unterminated-string-initialization warning
+        *  with GCC 15
         */
-       static const char mnemonics[BITS_PER_LONG][2] = {
+       static const char mnemonics[BITS_PER_LONG][3] = {
                /*
                 * In case if we meet a flag we don't know about.
                 */
@@ -987,11 +994,8 @@ static void show_smap_vma_flags(struct seq_file *m, struct vm_area_struct *vma)
        for (i = 0; i < BITS_PER_LONG; i++) {
                if (!mnemonics[i][0])
                        continue;
-               if (vma->vm_flags & (1UL << i)) {
-                       seq_putc(m, mnemonics[i][0]);
-                       seq_putc(m, mnemonics[i][1]);
-                       seq_putc(m, ' ');
-               }
+               if (vma->vm_flags & (1UL << i))
+                       seq_printf(m, "%s ", mnemonics[i]);
        }
        seq_putc(m, '\n');
 }
index 72c53129c952de64bb6daab1767e60144b2c9264..d39ee5f6c075049bc43827671b24b5ff9807e75c 100644 (file)
@@ -12,7 +12,7 @@
 #include <linux/highmem.h>
 #include <linux/slab.h>
 #include <linux/uaccess.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include <linux/buffer_head.h>
 #include <linux/mpage.h>
 #include <linux/writeback.h>
index f0e1f29f20ee39f72dc87b211edc01ca2af4694b..12fc20af8e17bbaeccc4d78fdbc8389942997916 100644 (file)
@@ -11,7 +11,7 @@
 #include <linux/sched.h>
 #include <linux/bug.h>
 #include <linux/workqueue.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include <linux/bitops.h>
 #include <linux/proc_fs.h>
 #include <linux/buffer_head.h>
index 79d99a9139441e5d241c32392ba82be799ef3191..4cc6e0896fad37c3a50ee7bca838f5dfbf4ea848 100644 (file)
@@ -484,10 +484,21 @@ cifsConvertToUTF16(__le16 *target, const char *source, int srclen,
                        /**
                         * Remap spaces and periods found at the end of every
                         * component of the path. The special cases of '.' and
-                        * '..' do not need to be dealt with explicitly because
-                        * they are addressed in namei.c:link_path_walk().
+                        * '..' are need to be handled because of symlinks.
+                        * They are treated as non-end-of-string to avoid
+                        * remapping and breaking symlinks pointing to . or ..
                         **/
-                       if ((i == srclen - 1) || (source[i+1] == '\\'))
+                       if ((i == 0 || source[i-1] == '\\') &&
+                           source[i] == '.' &&
+                           (i == srclen-1 || source[i+1] == '\\'))
+                               end_of_string = false; /* "." case */
+                       else if (i >= 1 &&
+                                (i == 1 || source[i-2] == '\\') &&
+                                source[i-1] == '.' &&
+                                source[i] == '.' &&
+                                (i == srclen-1 || source[i+1] == '\\'))
+                               end_of_string = false; /* ".." case */
+                       else if ((i == srclen - 1) || (source[i+1] == '\\'))
                                end_of_string = true;
                        else
                                end_of_string = false;
index 6529478b7f48922944f6df1f4fc082e78fd11966..31b51a8fc256115bcb0b84898d1092b92e51ab34 100644 (file)
@@ -55,7 +55,7 @@ struct smb3_sd {
 #define ACL_CONTROL_SI 0x0800  /* SACL Auto-Inherited */
 #define ACL_CONTROL_DI 0x0400  /* DACL Auto-Inherited */
 #define ACL_CONTROL_SC 0x0200  /* SACL computed through inheritance */
-#define ACL_CONTROL_DC 0x0100  /* DACL computed through inheritence */
+#define ACL_CONTROL_DC 0x0100  /* DACL computed through inheritance */
 #define ACL_CONTROL_SS 0x0080  /* Create server ACL */
 #define ACL_CONTROL_DT 0x0040  /* DACL provided by trusted source */
 #define ACL_CONTROL_SD 0x0020  /* SACL defaulted */
index 2d851f596a727ef5e4b426944b99f1bb4474d184..7a43daacc81595f3897db6c1f7f68ee47f313363 100644 (file)
@@ -239,7 +239,7 @@ int cifs_verify_signature(struct smb_rqst *rqst,
                cifs_dbg(FYI, "dummy signature received for smb command 0x%x\n",
                         cifs_pdu->Command);
 
-       /* save off the origiginal signature so we can modify the smb and check
+       /* save off the original signature so we can modify the smb and check
                its signature against what the server sent */
        memcpy(server_response_sig, cifs_pdu->Signature.SecuritySignature, 8);
 
@@ -700,6 +700,7 @@ cifs_crypto_secmech_release(struct TCP_Server_Info *server)
        cifs_free_hash(&server->secmech.aes_cmac);
        cifs_free_hash(&server->secmech.hmacsha256);
        cifs_free_hash(&server->secmech.md5);
+       cifs_free_hash(&server->secmech.sha512);
 
        if (!SERVER_IS_CHAN(server)) {
                if (server->secmech.enc) {
index 2a2523c93944de68e82528f485de5ae19d7d23d8..20cafdff5081068dfbc2cddf4e51588d453d10c2 100644 (file)
@@ -161,7 +161,7 @@ __u32 cifs_lock_secret;
 
 /*
  * Bumps refcount for cifs super block.
- * Note that it should be only called if a referece to VFS super block is
+ * Note that it should be only called if a reference to VFS super block is
  * already held, e.g. in open-type syscalls context. Otherwise it can race with
  * atomic_dec_and_test in deactivate_locked_super.
  */
@@ -289,7 +289,7 @@ static void cifs_kill_sb(struct super_block *sb)
        struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
 
        /*
-        * We ned to release all dentries for the cached directories
+        * We need to release all dentries for the cached directories
         * before we kill the sb.
         */
        if (cifs_sb->root) {
@@ -313,8 +313,17 @@ cifs_statfs(struct dentry *dentry, struct kstatfs *buf)
        struct TCP_Server_Info *server = tcon->ses->server;
        unsigned int xid;
        int rc = 0;
+       const char *full_path;
+       void *page;
 
        xid = get_xid();
+       page = alloc_dentry_path();
+
+       full_path = build_path_from_dentry(dentry, page);
+       if (IS_ERR(full_path)) {
+               rc = PTR_ERR(full_path);
+               goto statfs_out;
+       }
 
        if (le32_to_cpu(tcon->fsAttrInfo.MaxPathNameComponentLength) > 0)
                buf->f_namelen =
@@ -330,8 +339,10 @@ cifs_statfs(struct dentry *dentry, struct kstatfs *buf)
        buf->f_ffree = 0;       /* unlimited */
 
        if (server->ops->queryfs)
-               rc = server->ops->queryfs(xid, tcon, cifs_sb, buf);
+               rc = server->ops->queryfs(xid, tcon, full_path, cifs_sb, buf);
 
+statfs_out:
+       free_dentry_path(page);
        free_xid(xid);
        return rc;
 }
@@ -1769,7 +1780,7 @@ static int cifs_init_netfs(void)
 nomem_subreqpool:
        kmem_cache_destroy(cifs_io_subrequest_cachep);
 nomem_subreq:
-       mempool_destroy(&cifs_io_request_pool);
+       mempool_exit(&cifs_io_request_pool);
 nomem_reqpool:
        kmem_cache_destroy(cifs_io_request_cachep);
 nomem_req:
index 315aac5dec0515930385353b72fbf597b71106b3..5041b1ffc244b0ecb0e9d05268ff0a678070c815 100644 (file)
@@ -180,6 +180,7 @@ struct session_key {
 struct cifs_secmech {
        struct shash_desc *md5; /* md5 hash function, for CIFS/SMB1 signatures */
        struct shash_desc *hmacsha256; /* hmac-sha256 hash function, for SMB2 signatures */
+       struct shash_desc *sha512; /* sha512 hash function, for SMB3.1.1 preauth hash */
        struct shash_desc *aes_cmac; /* block-cipher based MAC function, for SMB3 signatures */
 
        struct crypto_aead *enc; /* smb3 encryption AEAD TFM (AES-CCM and AES-GCM) */
@@ -480,7 +481,7 @@ struct smb_version_operations {
                        __u16 net_fid, struct cifsInodeInfo *cifs_inode);
        /* query remote filesystem */
        int (*queryfs)(const unsigned int, struct cifs_tcon *,
-                      struct cifs_sb_info *, struct kstatfs *);
+                      const char *, struct cifs_sb_info *, struct kstatfs *);
        /* send mandatory brlock to the server */
        int (*mand_lock)(const unsigned int, struct cifsFileInfo *, __u64,
                         __u64, __u32, int, int, bool);
@@ -774,7 +775,7 @@ struct TCP_Server_Info {
        } compression;
        __u16   signing_algorithm;
        __le16  cipher_type;
-        /* save initital negprot hash */
+        /* save initial negprot hash */
        __u8    preauth_sha_hash[SMB2_PREAUTH_HASH_SIZE];
        bool    signing_negotiated; /* true if valid signing context rcvd from server */
        bool    posix_ext_supported;
index c3b6263060b0acb90fd7a672160b06c7b881ec3e..ee78bb6741d62ff66a87dcece79d960399fbf539 100644 (file)
@@ -10,7 +10,7 @@
 #define _CIFSPDU_H
 
 #include <net/sock.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include "../common/smbfsctl.h"
 
 #define CIFS_PROT   0
@@ -781,7 +781,7 @@ typedef struct smb_com_logoff_andx_rsp {
        __u16 ByteCount;
 } __attribute__((packed)) LOGOFF_ANDX_RSP;
 
-typedef union smb_com_tree_disconnect {        /* as an altetnative can use flag on
+typedef union smb_com_tree_disconnect {        /* as an alternative can use flag on
                                        tree_connect PDU to effect disconnect */
                                        /* tdis is probably simplest SMB PDU */
        struct {
@@ -2406,7 +2406,7 @@ struct cifs_posix_ace { /* access control entry (ACE) */
        __le64 cifs_uid; /* or gid */
 } __attribute__((packed));
 
-struct cifs_posix_acl { /* access conrol list  (ACL) */
+struct cifs_posix_acl { /* access control list  (ACL) */
        __le16  version;
        __le16  access_entry_count;  /* access ACL - count of entries */
        __le16  default_entry_count; /* default ACL - count of entries */
index 68c716e6261b3abd40173dc08a30ca08183df0aa..1d3470bca45edda942514c9bcf5ef098bb80b416 100644 (file)
@@ -252,10 +252,6 @@ extern int cifs_read_from_socket(struct TCP_Server_Info *server, char *buf,
                                 unsigned int to_read);
 extern ssize_t cifs_discard_from_socket(struct TCP_Server_Info *server,
                                        size_t to_read);
-extern int cifs_read_page_from_socket(struct TCP_Server_Info *server,
-                                       struct page *page,
-                                       unsigned int page_offset,
-                                       unsigned int to_read);
 int cifs_read_iter_from_socket(struct TCP_Server_Info *server,
                               struct iov_iter *iter,
                               unsigned int to_read);
@@ -623,8 +619,6 @@ enum securityEnum cifs_select_sectype(struct TCP_Server_Info *,
 int cifs_alloc_hash(const char *name, struct shash_desc **sdesc);
 void cifs_free_hash(struct shash_desc **sdesc);
 
-struct cifs_chan *
-cifs_ses_find_chan(struct cifs_ses *ses, struct TCP_Server_Info *server);
 int cifs_try_adding_channels(struct cifs_ses *ses);
 bool is_server_using_iface(struct TCP_Server_Info *server,
                           struct cifs_server_iface *iface);
@@ -640,9 +634,6 @@ cifs_chan_set_in_reconnect(struct cifs_ses *ses,
 void
 cifs_chan_clear_in_reconnect(struct cifs_ses *ses,
                               struct TCP_Server_Info *server);
-bool
-cifs_chan_in_reconnect(struct cifs_ses *ses,
-                         struct TCP_Server_Info *server);
 void
 cifs_chan_set_need_reconnect(struct cifs_ses *ses,
                             struct TCP_Server_Info *server);
index 131f20b91c3e1f3dd20c8dbab90aa22f8295162a..c6f15dbe860a41692af2d89a1c1cb4dc95c5a68e 100644 (file)
@@ -1215,7 +1215,7 @@ openRetry:
        req->CreateDisposition = cpu_to_le32(disposition);
        req->CreateOptions = cpu_to_le32(create_options & CREATE_OPTIONS_MASK);
 
-       /* BB Expirement with various impersonation levels and verify */
+       /* BB Experiment with various impersonation levels and verify */
        req->ImpersonationLevel = cpu_to_le32(SECURITY_IMPERSONATION);
        req->SecurityFlags = SECURITY_CONTEXT_TRACKING|SECURITY_EFFECTIVE_ONLY;
 
@@ -3018,7 +3018,7 @@ static void cifs_init_ace(struct cifs_posix_ace *cifs_ace,
 
 /**
  * posix_acl_to_cifs - convert ACLs from POSIX ACL to cifs format
- * @parm_data: ACLs in cifs format to conver to
+ * @parm_data: ACLs in cifs format to convert to
  * @acl: ACLs in POSIX ACL format to convert from
  * @acl_type: the type of POSIX ACLs stored in @acl
  *
@@ -3995,7 +3995,7 @@ findFirstRetry:
                name_len =
                    cifsConvertToUTF16((__le16 *) pSMB->FileName, searchName,
                                       PATH_MAX, nls_codepage, remap);
-               /* We can not add the asterik earlier in case
+               /* We can not add the asterisk earlier in case
                it got remapped to 0xF03A as if it were part of the
                directory name instead of a wildcard */
                name_len *= 2;
index 63b5a55b7a57514199a2f8947c1bacdc1f42a5ad..766b4de13da76a5c171b32194dad8b0cafeb0f02 100644 (file)
@@ -166,7 +166,6 @@ static int collect_sample(const struct iov_iter *iter, ssize_t max, u8 *sample)
        loff_t start = iter->xarray_start + iter->iov_offset;
        pgoff_t last, index = start / PAGE_SIZE;
        size_t len, off, foff;
-       ssize_t ret = 0;
        void *p;
        int s = 0;
 
@@ -193,9 +192,6 @@ static int collect_sample(const struct iov_iter *iter, ssize_t max, u8 *sample)
                                memcpy(&sample[s], p, len2);
                                kunmap_local(p);
 
-                               if (ret < 0)
-                                       return ret;
-
                                s += len2;
 
                                if (len2 < SZ_2K || s >= max - SZ_2K)
index 553e253ada29d7457482396d3926b8f9f6af8d9b..96e8a8057a7721233dc49d3388d5e40b8a1bab5b 100644 (file)
@@ -9,7 +9,7 @@
 #include <linux/slab.h>
 #include <linux/sizes.h>
 #include <linux/count_zeros.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #include "lz77.h"
 
index adf8758847f63f92ae69ddb84d35f5e631634ff6..15d94ac4095ea8ba572d475ecdbd6609da2207cf 100644 (file)
@@ -794,18 +794,6 @@ cifs_discard_from_socket(struct TCP_Server_Info *server, size_t to_read)
        return cifs_readv_from_socket(server, &smb_msg);
 }
 
-int
-cifs_read_page_from_socket(struct TCP_Server_Info *server, struct page *page,
-       unsigned int page_offset, unsigned int to_read)
-{
-       struct msghdr smb_msg = {};
-       struct bio_vec bv;
-
-       bvec_set_page(&bv, page, to_read, page_offset);
-       iov_iter_bvec(&smb_msg.msg_iter, ITER_DEST, &bv, 1, to_read);
-       return cifs_readv_from_socket(server, &smb_msg);
-}
-
 int
 cifs_read_iter_from_socket(struct TCP_Server_Info *server, struct iov_iter *iter,
                           unsigned int to_read)
index 78b59c4ef3ce7f22fed25ef87e96e3602861a6f2..a58a3333ecc300ab1974c9ea85ab637af81d64e1 100644 (file)
@@ -2502,7 +2502,7 @@ refind_writable:
                        }
                }
        }
-       /* couldn't find useable FH with same pid, try any available */
+       /* couldn't find usable FH with same pid, try any available */
        if (!any_available) {
                any_available = true;
                goto refind_writable;
index 28c4e576d460aa2b91eccfab9fb9386a21f187ff..5c5a52019efada1c09997be00d8fe32d6364eb12 100644 (file)
@@ -920,8 +920,15 @@ static int smb3_reconfigure(struct fs_context *fc)
        else  {
                kfree_sensitive(ses->password);
                ses->password = kstrdup(ctx->password, GFP_KERNEL);
+               if (!ses->password)
+                       return -ENOMEM;
                kfree_sensitive(ses->password2);
                ses->password2 = kstrdup(ctx->password2, GFP_KERNEL);
+               if (!ses->password2) {
+                       kfree_sensitive(ses->password);
+                       ses->password = NULL;
+                       return -ENOMEM;
+               }
        }
        STEAL_STRING(cifs_sb, ctx, domainname);
        STEAL_STRING(cifs_sb, ctx, nodename);
index 69f9d938b336a7599f951fde4502ad86d69fd60e..890d6d9d4a592f754fae6c75d74accdac442096d 100644 (file)
@@ -260,7 +260,7 @@ struct smb3_fs_context {
        unsigned int min_offload;
        unsigned int retrans;
        bool sockopt_tcp_nodelay:1;
-       /* attribute cache timemout for files and directories in jiffies */
+       /* attribute cache timeout for files and directories in jiffies */
        unsigned long acregmax;
        unsigned long acdirmax;
        /* timeout for deferred close of files in jiffies */
index 647f9bedd9fc44c9225f2494c6913a795c2fd6ad..eff3f57235eef3212fa9f7e510335baeecda4485 100644 (file)
@@ -629,10 +629,16 @@ cifs_sfu_type(struct cifs_fattr *fattr, const char *path,
                                                                               &symlink_len_utf16,
                                                                               &symlink_buf_utf16,
                                                                               &buf_type);
+                                       /*
+                                        * Check that read buffer has valid length and does not
+                                        * contain UTF-16 null codepoint (via UniStrnlen() call)
+                                        * because Linux cannot process symlink with null byte.
+                                        */
                                        if ((rc == 0) &&
                                            (symlink_len_utf16 > 0) &&
                                            (symlink_len_utf16 < fattr->cf_eof-8 + 1) &&
-                                           (symlink_len_utf16 % 2 == 0)) {
+                                           (symlink_len_utf16 % 2 == 0) &&
+                                           (UniStrnlen((wchar_t *)symlink_buf_utf16, symlink_len_utf16/2) == symlink_len_utf16/2)) {
                                                fattr->cf_symlink_target =
                                                        cifs_strndup_from_utf16(symlink_buf_utf16,
                                                                                symlink_len_utf16,
index 054f10ebf65a5e03bdb947bf5eff734a9e71633e..4373dd64b66d4f2f704dce56b889f2c9cc86880e 100644 (file)
@@ -254,7 +254,7 @@ free_rsp_buf(int resp_buftype, void *rsp)
 }
 
 /* NB: MID can not be set if treeCon not passed in, in that
-   case it is responsbility of caller to set the mid */
+   case it is responsibility of caller to set the mid */
 void
 header_assemble(struct smb_hdr *buffer, char smb_command /* command */ ,
                const struct cifs_tcon *treeCon, int word_count
index 1b52e6ac431cb045e2495bc7437760217d107865..2a8d71221e5e71d03ca97a7097a8ed5e876fec28 100644 (file)
@@ -1003,7 +1003,7 @@ struct timespec64 cnvrtDosUnixTm(__le16 le_date, __le16 le_time, int offset)
         year is 2**7, the last year is 1980+127, which means we need only
         consider 2 special case years, ie the years 2000 and 2100, and only
         adjust for the lack of leap year for the year 2100, as 2000 was a
-        leap year (divisable by 400) */
+        leap year (divisible by 400) */
        if (year >= 120)  /* the year 2100 */
                days = days - 1;  /* do not count leap year for the year 2100 */
 
index ebe1cb30e18ed4119bbd8100ca6a8b8f852aeff8..b3a8f9c6fcff6f42621d24285152e65746f6a896 100644 (file)
@@ -553,7 +553,7 @@ static void cifs_fill_dirent_std(struct cifs_dirent *de,
                const FIND_FILE_STANDARD_INFO *info)
 {
        de->name = &info->FileName[0];
-       /* one byte length, no endianess conversion */
+       /* one byte length, no endianness conversion */
        de->namelen = info->FileNameLength;
        de->resume_key = info->ResumeKey;
 }
@@ -815,7 +815,7 @@ static bool emit_cached_dirents(struct cached_dirents *cde,
                 * However, this sequence of ->pos values may have holes
                 * in it, for example dot-dirs returned from the server
                 * are suppressed.
-                * Handle this bu forcing ctx->pos to be the same as the
+                * Handle this by forcing ctx->pos to be the same as the
                 * ->pos of the current dirent we emit from the cache.
                 * This means that when we emit these entries from the cache
                 * we now emit them with the same ->pos value as in the
index 3b48a093cfb1f816efc221f57849caa9b7f54e9f..74abbdf5026c73ec1e271fc176ab45a661fb1819 100644 (file)
 #include "fs_context.h"
 #include "reparse.h"
 
+static int detect_directory_symlink_target(struct cifs_sb_info *cifs_sb,
+                                          const unsigned int xid,
+                                          const char *full_path,
+                                          const char *symname,
+                                          bool *directory);
+
 int smb2_create_reparse_symlink(const unsigned int xid, struct inode *inode,
                                struct dentry *dentry, struct cifs_tcon *tcon,
                                const char *full_path, const char *symname)
@@ -24,6 +30,7 @@ int smb2_create_reparse_symlink(const unsigned int xid, struct inode *inode,
        struct inode *new;
        struct kvec iov;
        __le16 *path;
+       bool directory;
        char *sym, sep = CIFS_DIR_SEP(cifs_sb);
        u16 len, plen;
        int rc = 0;
@@ -45,6 +52,18 @@ int smb2_create_reparse_symlink(const unsigned int xid, struct inode *inode,
                goto out;
        }
 
+       /*
+        * SMB distinguish between symlink to directory and symlink to file.
+        * They cannot be exchanged (symlink of file type which points to
+        * directory cannot be resolved and vice-versa). Try to detect if
+        * the symlink target could be a directory or not. When detection
+        * fails then treat symlink as a file (non-directory) symlink.
+        */
+       directory = false;
+       rc = detect_directory_symlink_target(cifs_sb, xid, full_path, symname, &directory);
+       if (rc < 0)
+               goto out;
+
        plen = 2 * UniStrnlen((wchar_t *)path, PATH_MAX);
        len = sizeof(*buf) + plen * 2;
        buf = kzalloc(len, GFP_KERNEL);
@@ -69,7 +88,8 @@ int smb2_create_reparse_symlink(const unsigned int xid, struct inode *inode,
        iov.iov_base = buf;
        iov.iov_len = len;
        new = smb2_get_reparse_inode(&data, inode->i_sb, xid,
-                                    tcon, full_path, &iov, NULL);
+                                    tcon, full_path, directory,
+                                    &iov, NULL);
        if (!IS_ERR(new))
                d_instantiate(dentry, new);
        else
@@ -81,6 +101,144 @@ out:
        return rc;
 }
 
+static int detect_directory_symlink_target(struct cifs_sb_info *cifs_sb,
+                                          const unsigned int xid,
+                                          const char *full_path,
+                                          const char *symname,
+                                          bool *directory)
+{
+       char sep = CIFS_DIR_SEP(cifs_sb);
+       struct cifs_open_parms oparms;
+       struct tcon_link *tlink;
+       struct cifs_tcon *tcon;
+       const char *basename;
+       struct cifs_fid fid;
+       char *resolved_path;
+       int full_path_len;
+       int basename_len;
+       int symname_len;
+       char *path_sep;
+       __u32 oplock;
+       int open_rc;
+
+       /*
+        * First do some simple check. If the original Linux symlink target ends
+        * with slash, or last path component is dot or dot-dot then it is for
+        * sure symlink to the directory.
+        */
+       basename = kbasename(symname);
+       basename_len = strlen(basename);
+       if (basename_len == 0 || /* symname ends with slash */
+           (basename_len == 1 && basename[0] == '.') || /* last component is "." */
+           (basename_len == 2 && basename[0] == '.' && basename[1] == '.')) { /* or ".." */
+               *directory = true;
+               return 0;
+       }
+
+       /*
+        * For absolute symlinks it is not possible to determinate
+        * if it should point to directory or file.
+        */
+       if (symname[0] == '/') {
+               cifs_dbg(FYI,
+                        "%s: cannot determinate if the symlink target path '%s' "
+                        "is directory or not, creating '%s' as file symlink\n",
+                        __func__, symname, full_path);
+               return 0;
+       }
+
+       /*
+        * If it was not detected as directory yet and the symlink is relative
+        * then try to resolve the path on the SMB server, check if the path
+        * exists and determinate if it is a directory or not.
+        */
+
+       full_path_len = strlen(full_path);
+       symname_len = strlen(symname);
+
+       tlink = cifs_sb_tlink(cifs_sb);
+       if (IS_ERR(tlink))
+               return PTR_ERR(tlink);
+
+       resolved_path = kzalloc(full_path_len + symname_len + 1, GFP_KERNEL);
+       if (!resolved_path) {
+               cifs_put_tlink(tlink);
+               return -ENOMEM;
+       }
+
+       /*
+        * Compose the resolved SMB symlink path from the SMB full path
+        * and Linux target symlink path.
+        */
+       memcpy(resolved_path, full_path, full_path_len+1);
+       path_sep = strrchr(resolved_path, sep);
+       if (path_sep)
+               path_sep++;
+       else
+               path_sep = resolved_path;
+       memcpy(path_sep, symname, symname_len+1);
+       if (sep == '\\')
+               convert_delimiter(path_sep, sep);
+
+       tcon = tlink_tcon(tlink);
+       oparms = CIFS_OPARMS(cifs_sb, tcon, resolved_path,
+                            FILE_READ_ATTRIBUTES, FILE_OPEN, 0, ACL_NO_MODE);
+       oparms.fid = &fid;
+
+       /* Try to open as a directory (NOT_FILE) */
+       oplock = 0;
+       oparms.create_options = cifs_create_options(cifs_sb,
+                                                   CREATE_NOT_FILE | OPEN_REPARSE_POINT);
+       open_rc = tcon->ses->server->ops->open(xid, &oparms, &oplock, NULL);
+       if (open_rc == 0) {
+               /* Successful open means that the target path is definitely a directory. */
+               *directory = true;
+               tcon->ses->server->ops->close(xid, tcon, &fid);
+       } else if (open_rc == -ENOTDIR) {
+               /* -ENOTDIR means that the target path is definitely a file. */
+               *directory = false;
+       } else if (open_rc == -ENOENT) {
+               /* -ENOENT means that the target path does not exist. */
+               cifs_dbg(FYI,
+                        "%s: symlink target path '%s' does not exist, "
+                        "creating '%s' as file symlink\n",
+                        __func__, symname, full_path);
+       } else {
+               /* Try to open as a file (NOT_DIR) */
+               oplock = 0;
+               oparms.create_options = cifs_create_options(cifs_sb,
+                                                           CREATE_NOT_DIR | OPEN_REPARSE_POINT);
+               open_rc = tcon->ses->server->ops->open(xid, &oparms, &oplock, NULL);
+               if (open_rc == 0) {
+                       /* Successful open means that the target path is definitely a file. */
+                       *directory = false;
+                       tcon->ses->server->ops->close(xid, tcon, &fid);
+               } else if (open_rc == -EISDIR) {
+                       /* -EISDIR means that the target path is definitely a directory. */
+                       *directory = true;
+               } else {
+                       /*
+                        * This code branch is called when we do not have a permission to
+                        * open the resolved_path or some other client/process denied
+                        * opening the resolved_path.
+                        *
+                        * TODO: Try to use ops->query_dir_first on the parent directory
+                        * of resolved_path, search for basename of resolved_path and
+                        * check if the ATTR_DIRECTORY is set in fi.Attributes. In some
+                        * case this could work also when opening of the path is denied.
+                        */
+                       cifs_dbg(FYI,
+                                "%s: cannot determinate if the symlink target path '%s' "
+                                "is directory or not, creating '%s' as file symlink\n",
+                                __func__, symname, full_path);
+               }
+       }
+
+       kfree(resolved_path);
+       cifs_put_tlink(tlink);
+       return 0;
+}
+
 static int nfs_set_reparse_buf(struct reparse_posix_data *buf,
                               mode_t mode, dev_t dev,
                               struct kvec *iov)
@@ -137,7 +295,7 @@ static int mknod_nfs(unsigned int xid, struct inode *inode,
        };
 
        new = smb2_get_reparse_inode(&data, inode->i_sb, xid,
-                                    tcon, full_path, &iov, NULL);
+                                    tcon, full_path, false, &iov, NULL);
        if (!IS_ERR(new))
                d_instantiate(dentry, new);
        else
@@ -283,7 +441,7 @@ static int mknod_wsl(unsigned int xid, struct inode *inode,
        data.wsl.eas_len = len;
 
        new = smb2_get_reparse_inode(&data, inode->i_sb,
-                                    xid, tcon, full_path,
+                                    xid, tcon, full_path, false,
                                     &reparse_iov, &xattr_iov);
        if (!IS_ERR(new))
                d_instantiate(dentry, new);
@@ -320,22 +478,51 @@ static int parse_reparse_posix(struct reparse_posix_data *buf,
        unsigned int len;
        u64 type;
 
+       len = le16_to_cpu(buf->ReparseDataLength);
+       if (len < sizeof(buf->InodeType)) {
+               cifs_dbg(VFS, "srv returned malformed nfs buffer\n");
+               return -EIO;
+       }
+
+       len -= sizeof(buf->InodeType);
+
        switch ((type = le64_to_cpu(buf->InodeType))) {
        case NFS_SPECFILE_LNK:
-               len = le16_to_cpu(buf->ReparseDataLength);
+               if (len == 0 || (len % 2)) {
+                       cifs_dbg(VFS, "srv returned malformed nfs symlink buffer\n");
+                       return -EIO;
+               }
+               /*
+                * Check that buffer does not contain UTF-16 null codepoint
+                * because Linux cannot process symlink with null byte.
+                */
+               if (UniStrnlen((wchar_t *)buf->DataBuffer, len/2) != len/2) {
+                       cifs_dbg(VFS, "srv returned null byte in nfs symlink target location\n");
+                       return -EIO;
+               }
                data->symlink_target = cifs_strndup_from_utf16(buf->DataBuffer,
                                                               len, true,
                                                               cifs_sb->local_nls);
                if (!data->symlink_target)
                        return -ENOMEM;
-               convert_delimiter(data->symlink_target, '/');
                cifs_dbg(FYI, "%s: target path: %s\n",
                         __func__, data->symlink_target);
                break;
        case NFS_SPECFILE_CHR:
        case NFS_SPECFILE_BLK:
+               /* DataBuffer for block and char devices contains two 32-bit numbers */
+               if (len != 8) {
+                       cifs_dbg(VFS, "srv returned malformed nfs buffer for type: 0x%llx\n", type);
+                       return -EIO;
+               }
+               break;
        case NFS_SPECFILE_FIFO:
        case NFS_SPECFILE_SOCK:
+               /* DataBuffer for fifos and sockets is empty */
+               if (len != 0) {
+                       cifs_dbg(VFS, "srv returned malformed nfs buffer for type: 0x%llx\n", type);
+                       return -EIO;
+               }
                break;
        default:
                cifs_dbg(VFS, "%s: unhandled inode type: 0x%llx\n",
@@ -482,12 +669,18 @@ bool cifs_reparse_point_to_fattr(struct cifs_sb_info *cifs_sb,
        u32 tag = data->reparse.tag;
 
        if (tag == IO_REPARSE_TAG_NFS && buf) {
+               if (le16_to_cpu(buf->ReparseDataLength) < sizeof(buf->InodeType))
+                       return false;
                switch (le64_to_cpu(buf->InodeType)) {
                case NFS_SPECFILE_CHR:
+                       if (le16_to_cpu(buf->ReparseDataLength) != sizeof(buf->InodeType) + 8)
+                               return false;
                        fattr->cf_mode |= S_IFCHR;
                        fattr->cf_rdev = reparse_mkdev(buf->DataBuffer);
                        break;
                case NFS_SPECFILE_BLK:
+                       if (le16_to_cpu(buf->ReparseDataLength) != sizeof(buf->InodeType) + 8)
+                               return false;
                        fattr->cf_mode |= S_IFBLK;
                        fattr->cf_rdev = reparse_mkdev(buf->DataBuffer);
                        break;
index 03c0b484a4b5ae289556934f53eea0b4fe2f5ef1..c88e9657f47a8d80b10396ffe4826b948ef05c08 100644 (file)
@@ -115,18 +115,6 @@ cifs_chan_clear_in_reconnect(struct cifs_ses *ses,
        ses->chans[chan_index].in_reconnect = false;
 }
 
-bool
-cifs_chan_in_reconnect(struct cifs_ses *ses,
-                         struct TCP_Server_Info *server)
-{
-       unsigned int chan_index = cifs_ses_get_chan_index(ses, server);
-
-       if (chan_index == CIFS_INVAL_CHAN_INDEX)
-               return true;    /* err on the safer side */
-
-       return CIFS_CHAN_IN_RECONNECT(ses, chan_index);
-}
-
 void
 cifs_chan_set_need_reconnect(struct cifs_ses *ses,
                             struct TCP_Server_Info *server)
@@ -487,26 +475,6 @@ cifs_chan_update_iface(struct cifs_ses *ses, struct TCP_Server_Info *server)
        spin_unlock(&ses->chan_lock);
 }
 
-/*
- * If server is a channel of ses, return the corresponding enclosing
- * cifs_chan otherwise return NULL.
- */
-struct cifs_chan *
-cifs_ses_find_chan(struct cifs_ses *ses, struct TCP_Server_Info *server)
-{
-       int i;
-
-       spin_lock(&ses->chan_lock);
-       for (i = 0; i < ses->chan_count; i++) {
-               if (ses->chans[i].server == server) {
-                       spin_unlock(&ses->chan_lock);
-                       return &ses->chans[i];
-               }
-       }
-       spin_unlock(&ses->chan_lock);
-       return NULL;
-}
-
 static int
 cifs_ses_add_channel(struct cifs_ses *ses,
                     struct cifs_server_iface *iface)
@@ -624,7 +592,7 @@ cifs_ses_add_channel(struct cifs_ses *ses,
         * to sign packets before we generate the channel signing key
         * (we sign with the session key)
         */
-       rc = smb3_crypto_shash_allocate(chan->server);
+       rc = smb311_crypto_shash_allocate(chan->server);
        if (rc) {
                cifs_dbg(VFS, "%s: crypto alloc failed\n", __func__);
                mutex_unlock(&ses->session_mutex);
index e03c91a49650fd46cb84dc20b549574d05f9d168..9a6ece66c4d34ef7cc068d1ba94aca62a92a3a0f 100644 (file)
@@ -909,7 +909,7 @@ cifs_oplock_response(struct cifs_tcon *tcon, __u64 persistent_fid,
 
 static int
 cifs_queryfs(const unsigned int xid, struct cifs_tcon *tcon,
-            struct cifs_sb_info *cifs_sb, struct kstatfs *buf)
+            const char *path, struct cifs_sb_info *cifs_sb, struct kstatfs *buf)
 {
        int rc = -EOPNOTSUPP;
 
index b992117377e9207215f16bc1560ad466447c143a..e49d0c25eb0384e04a0c5663029d20a76752887e 100644 (file)
@@ -1198,6 +1198,7 @@ struct inode *smb2_get_reparse_inode(struct cifs_open_info_data *data,
                                     const unsigned int xid,
                                     struct cifs_tcon *tcon,
                                     const char *full_path,
+                                    bool directory,
                                     struct kvec *reparse_iov,
                                     struct kvec *xattr_iov)
 {
@@ -1205,16 +1206,19 @@ struct inode *smb2_get_reparse_inode(struct cifs_open_info_data *data,
        struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
        struct cifsFileInfo *cfile;
        struct inode *new = NULL;
+       int out_buftype[4] = {};
+       struct kvec out_iov[4] = {};
        struct kvec in_iov[2];
        int cmds[2];
        int rc;
+       int i;
 
        oparms = CIFS_OPARMS(cifs_sb, tcon, full_path,
                             SYNCHRONIZE | DELETE |
                             FILE_READ_ATTRIBUTES |
                             FILE_WRITE_ATTRIBUTES,
                             FILE_CREATE,
-                            CREATE_NOT_DIR | OPEN_REPARSE_POINT,
+                            (directory ? CREATE_NOT_FILE : CREATE_NOT_DIR) | OPEN_REPARSE_POINT,
                             ACL_NO_MODE);
        if (xattr_iov)
                oparms.ea_cctx = xattr_iov;
@@ -1228,7 +1232,7 @@ struct inode *smb2_get_reparse_inode(struct cifs_open_info_data *data,
                cmds[1] = SMB2_OP_POSIX_QUERY_INFO;
                cifs_get_writable_path(tcon, full_path, FIND_WR_ANY, &cfile);
                rc = smb2_compound_op(xid, tcon, cifs_sb, full_path, &oparms,
-                                     in_iov, cmds, 2, cfile, NULL, NULL, NULL);
+                                     in_iov, cmds, 2, cfile, out_iov, out_buftype, NULL);
                if (!rc) {
                        rc = smb311_posix_get_inode_info(&new, full_path,
                                                         data, sb, xid);
@@ -1237,12 +1241,29 @@ struct inode *smb2_get_reparse_inode(struct cifs_open_info_data *data,
                cmds[1] = SMB2_OP_QUERY_INFO;
                cifs_get_writable_path(tcon, full_path, FIND_WR_ANY, &cfile);
                rc = smb2_compound_op(xid, tcon, cifs_sb, full_path, &oparms,
-                                     in_iov, cmds, 2, cfile, NULL, NULL, NULL);
+                                     in_iov, cmds, 2, cfile, out_iov, out_buftype, NULL);
                if (!rc) {
                        rc = cifs_get_inode_info(&new, full_path,
                                                 data, sb, xid, NULL);
                }
        }
+
+
+       /*
+        * If CREATE was successful but SMB2_OP_SET_REPARSE failed then
+        * remove the intermediate object created by CREATE. Otherwise
+        * empty object stay on the server when reparse call failed.
+        */
+       if (rc &&
+           out_iov[0].iov_base != NULL && out_buftype[0] != CIFS_NO_BUFFER &&
+           ((struct smb2_hdr *)out_iov[0].iov_base)->Status == STATUS_SUCCESS &&
+           (out_iov[1].iov_base == NULL || out_buftype[1] == CIFS_NO_BUFFER ||
+            ((struct smb2_hdr *)out_iov[1].iov_base)->Status != STATUS_SUCCESS))
+               smb2_unlink(xid, tcon, full_path, cifs_sb, NULL);
+
+       for (i = 0; i < ARRAY_SIZE(out_buftype); i++)
+               free_rsp_buf(out_buftype[i], out_iov[i].iov_base);
+
        return rc ? ERR_PTR(rc) : new;
 }
 
index bdeb12ff53e3c0247a736e7b3aa9e03082395d76..f3c4b70b77b94f3797362ecc0fdb32608f87aea5 100644 (file)
@@ -906,41 +906,41 @@ smb311_update_preauth_hash(struct cifs_ses *ses, struct TCP_Server_Info *server,
                || (hdr->Status !=
                    cpu_to_le32(NT_STATUS_MORE_PROCESSING_REQUIRED))))
                return 0;
+
 ok:
-       rc = cifs_alloc_hash("sha512", &sha512);
-       if (rc) {
-               cifs_dbg(VFS, "%s: Could not allocate SHA512 shash, rc=%d\n", __func__, rc);
+       rc = smb311_crypto_shash_allocate(server);
+       if (rc)
                return rc;
-       }
 
+       sha512 = server->secmech.sha512;
        rc = crypto_shash_init(sha512);
        if (rc) {
-               cifs_dbg(VFS, "%s: Could not init SHA512 shash, rc=%d\n", __func__, rc);
-               goto err_free;
+               cifs_dbg(VFS, "%s: Could not init sha512 shash\n", __func__);
+               return rc;
        }
 
        rc = crypto_shash_update(sha512, ses->preauth_sha_hash,
                                 SMB2_PREAUTH_HASH_SIZE);
        if (rc) {
-               cifs_dbg(VFS, "%s: Could not update SHA512 shash, rc=%d\n", __func__, rc);
-               goto err_free;
+               cifs_dbg(VFS, "%s: Could not update sha512 shash\n", __func__);
+               return rc;
        }
 
        for (i = 0; i < nvec; i++) {
                rc = crypto_shash_update(sha512, iov[i].iov_base, iov[i].iov_len);
                if (rc) {
-                       cifs_dbg(VFS, "%s: Could not update SHA512 shash, rc=%d\n", __func__, rc);
-                       goto err_free;
+                       cifs_dbg(VFS, "%s: Could not update sha512 shash\n",
+                                __func__);
+                       return rc;
                }
        }
 
        rc = crypto_shash_final(sha512, ses->preauth_sha_hash);
        if (rc) {
-               cifs_dbg(VFS, "%s: Could not finalize SHA12 shash, rc=%d\n", __func__, rc);
-               goto err_free;
+               cifs_dbg(VFS, "%s: Could not finalize sha512 shash\n",
+                        __func__);
+               return rc;
        }
-err_free:
-       cifs_free_hash(&sha512);
 
        return 0;
 }
index 177173072bfa9e9731de498cdd5d7e7f0ea7ae36..24a2aa04a1086cb67e7be151ca6e2f69d560b164 100644 (file)
@@ -1158,7 +1158,7 @@ smb2_set_ea(const unsigned int xid, struct cifs_tcon *tcon,
        struct cifs_fid fid;
        unsigned int size[1];
        void *data[1];
-       struct smb2_file_full_ea_info *ea = NULL;
+       struct smb2_file_full_ea_info *ea;
        struct smb2_query_info_rsp *rsp;
        int rc, used_len = 0;
        int retries = 0, cur_sleep = 1;
@@ -1179,6 +1179,7 @@ replay_again:
        if (!utf16_path)
                return -ENOMEM;
 
+       ea = NULL;
        resp_buftype[0] = resp_buftype[1] = resp_buftype[2] = CIFS_NO_BUFFER;
        vars = kzalloc(sizeof(*vars), GFP_KERNEL);
        if (!vars) {
@@ -2177,7 +2178,7 @@ smb3_enum_snapshots(const unsigned int xid, struct cifs_tcon *tcon,
                        NULL, 0 /* no input data */, max_response_size,
                        (char **)&retbuf,
                        &ret_data_len);
-       cifs_dbg(FYI, "enum snaphots ioctl returned %d and ret buflen is %d\n",
+       cifs_dbg(FYI, "enum snapshots ioctl returned %d and ret buflen is %d\n",
                        rc, ret_data_len);
        if (rc)
                return rc;
@@ -2838,7 +2839,7 @@ out_free_path:
 
 static int
 smb2_queryfs(const unsigned int xid, struct cifs_tcon *tcon,
-            struct cifs_sb_info *cifs_sb, struct kstatfs *buf)
+            const char *path, struct cifs_sb_info *cifs_sb, struct kstatfs *buf)
 {
        struct smb2_query_info_rsp *rsp;
        struct smb2_fs_full_size_info *info = NULL;
@@ -2847,7 +2848,7 @@ smb2_queryfs(const unsigned int xid, struct cifs_tcon *tcon,
        int rc;
 
 
-       rc = smb2_query_info_compound(xid, tcon, "",
+       rc = smb2_query_info_compound(xid, tcon, path,
                                      FILE_READ_ATTRIBUTES,
                                      FS_FULL_SIZE_INFORMATION,
                                      SMB2_O_INFO_FILESYSTEM,
@@ -2875,28 +2876,33 @@ qfs_exit:
 
 static int
 smb311_queryfs(const unsigned int xid, struct cifs_tcon *tcon,
-              struct cifs_sb_info *cifs_sb, struct kstatfs *buf)
+              const char *path, struct cifs_sb_info *cifs_sb, struct kstatfs *buf)
 {
        int rc;
-       __le16 srch_path = 0; /* Null - open root of share */
+       __le16 *utf16_path = NULL;
        u8 oplock = SMB2_OPLOCK_LEVEL_NONE;
        struct cifs_open_parms oparms;
        struct cifs_fid fid;
 
        if (!tcon->posix_extensions)
-               return smb2_queryfs(xid, tcon, cifs_sb, buf);
+               return smb2_queryfs(xid, tcon, path, cifs_sb, buf);
 
        oparms = (struct cifs_open_parms) {
                .tcon = tcon,
-               .path = "",
+               .path = path,
                .desired_access = FILE_READ_ATTRIBUTES,
                .disposition = FILE_OPEN,
                .create_options = cifs_create_options(cifs_sb, 0),
                .fid = &fid,
        };
 
-       rc = SMB2_open(xid, &oparms, &srch_path, &oplock, NULL, NULL,
+       utf16_path = cifs_convert_path_to_utf16(path, cifs_sb);
+       if (utf16_path == NULL)
+               return -ENOMEM;
+
+       rc = SMB2_open(xid, &oparms, utf16_path, &oplock, NULL, NULL,
                       NULL, NULL);
+       kfree(utf16_path);
        if (rc)
                return rc;
 
@@ -3583,7 +3589,7 @@ static long smb3_simple_falloc(struct file *file, struct cifs_tcon *tcon,
                /*
                 * At this point, we are trying to fallocate an internal
                 * regions of a sparse file. Since smb2 does not have a
-                * fallocate command we have two otions on how to emulate this.
+                * fallocate command we have two options on how to emulate this.
                 * We can either turn the entire file to become non-sparse
                 * which we only do if the fallocate is for virtually
                 * the whole file,  or we can overwrite the region with zeroes
index 02828b9c3cb32abe5f06c0080cbde82c096f8ac4..6584b5cddc280ab3a43f206511e1516cc3e67dc4 100644 (file)
@@ -2986,7 +2986,7 @@ replay_again:
 
        SMB2_close(xid, tcon, rsp->PersistentFileId, rsp->VolatileFileId);
 
-       /* Eventually save off posix specific response info and timestaps */
+       /* Eventually save off posix specific response info and timestamps */
 
 err_free_rsp_buf:
        free_rsp_buf(resp_buftype, rsp);
@@ -3313,6 +3313,15 @@ SMB2_ioctl_init(struct cifs_tcon *tcon, struct TCP_Server_Info *server,
                return rc;
 
        if (indatalen) {
+               unsigned int len;
+
+               if (WARN_ON_ONCE(smb3_encryption_required(tcon) &&
+                                (check_add_overflow(total_len - 1,
+                                                    ALIGN(indatalen, 8), &len) ||
+                                 len > MAX_CIFS_SMALL_BUFFER_SIZE))) {
+                       cifs_small_buf_release(req);
+                       return -EIO;
+               }
                /*
                 * indatalen is usually small at a couple of bytes max, so
                 * just allocate through generic pool
@@ -4581,7 +4590,7 @@ smb2_readv_callback(struct mid_q_entry *mid)
        }
 #ifdef CONFIG_CIFS_SMB_DIRECT
        /*
-        * If this rdata has a memmory registered, the MR can be freed
+        * If this rdata has a memory registered, the MR can be freed
         * MR needs to be freed as soon as I/O finishes to prevent deadlock
         * because they have limited number and are used for future I/Os
         */
index 56a896ff7cd9f33e2e165f0d762358cf85fb0836..6f9885e4f66ca523b7d3af5c4a171daf5b565294 100644 (file)
@@ -61,6 +61,7 @@ struct inode *smb2_get_reparse_inode(struct cifs_open_info_data *data,
                                     const unsigned int xid,
                                     struct cifs_tcon *tcon,
                                     const char *full_path,
+                                    bool directory,
                                     struct kvec *reparse_iov,
                                     struct kvec *xattr_iov);
 int smb2_query_reparse_point(const unsigned int xid,
@@ -291,7 +292,7 @@ extern int smb2_validate_and_copy_iov(unsigned int offset,
 extern void smb2_copy_fs_info_to_kstatfs(
         struct smb2_fs_full_size_info *pfs_inf,
         struct kstatfs *kst);
-extern int smb3_crypto_shash_allocate(struct TCP_Server_Info *server);
+extern int smb311_crypto_shash_allocate(struct TCP_Server_Info *server);
 extern int smb311_update_preauth_hash(struct cifs_ses *ses,
                                      struct TCP_Server_Info *server,
                                      struct kvec *iov, int nvec);
index f7e04c40d22e0a5b9589d2e0a847bebcee77547e..b486b14bb3306fa228b7c243a5f1a509096df652 100644 (file)
@@ -26,7 +26,8 @@
 #include "../common/smb2status.h"
 #include "smb2glob.h"
 
-int smb3_crypto_shash_allocate(struct TCP_Server_Info *server)
+static int
+smb3_crypto_shash_allocate(struct TCP_Server_Info *server)
 {
        struct cifs_secmech *p = &server->secmech;
        int rc;
@@ -45,6 +46,33 @@ err:
        return rc;
 }
 
+int
+smb311_crypto_shash_allocate(struct TCP_Server_Info *server)
+{
+       struct cifs_secmech *p = &server->secmech;
+       int rc = 0;
+
+       rc = cifs_alloc_hash("hmac(sha256)", &p->hmacsha256);
+       if (rc)
+               return rc;
+
+       rc = cifs_alloc_hash("cmac(aes)", &p->aes_cmac);
+       if (rc)
+               goto err;
+
+       rc = cifs_alloc_hash("sha512", &p->sha512);
+       if (rc)
+               goto err;
+
+       return 0;
+
+err:
+       cifs_free_hash(&p->aes_cmac);
+       cifs_free_hash(&p->hmacsha256);
+       return rc;
+}
+
+
 static
 int smb2_get_sign_key(__u64 ses_id, struct TCP_Server_Info *server, u8 *key)
 {
@@ -668,7 +696,7 @@ smb2_verify_signature(struct smb_rqst *rqst, struct TCP_Server_Info *server)
                         shdr->Command);
 
        /*
-        * Save off the origiginal signature so we can modify the smb and check
+        * Save off the original signature so we can modify the smb and check
         * our calculated signature against what the server sent.
         */
        memcpy(server_response_sig, shdr->Signature, SMB2_SIGNATURE_SIZE);
index 0c64b37e2660729218197fa252a9b4468c754886..b0b7254661e926cff37f565c48b8df0788ee7fb8 100644 (file)
@@ -219,7 +219,7 @@ static int smbd_conn_upcall(
 
        case RDMA_CM_EVENT_DEVICE_REMOVAL:
        case RDMA_CM_EVENT_DISCONNECTED:
-               /* This happenes when we fail the negotiation */
+               /* This happens when we fail the negotiation */
                if (info->transport_status == SMBD_NEGOTIATE_FAILED) {
                        info->transport_status = SMBD_DISCONNECTED;
                        wake_up(&info->conn_wait);
@@ -1344,7 +1344,7 @@ void smbd_destroy(struct TCP_Server_Info *server)
         * are not locked by srv_mutex. It is possible some processes are
         * blocked on transport srv_mutex while holding memory registration.
         * Release the transport srv_mutex to allow them to hit the failure
-        * path when sending data, and then release memory registartions.
+        * path when sending data, and then release memory registrations.
         */
        log_rdma_event(INFO, "freeing mr list\n");
        wake_up_interruptible_all(&info->wait_mr);
index 83f239f376f06d855ad1ce469badec38e9ea5264..c08e3665150d74c326cd49b307d4edc969c6e937 100644 (file)
@@ -111,7 +111,7 @@ struct smbd_connection {
        /* Used by transport to wait until all MRs are returned */
        wait_queue_head_t wait_for_mr_cleanup;
 
-       /* Activity accoutning */
+       /* Activity accounting */
        atomic_t send_pending;
        wait_queue_head_t wait_send_pending;
        wait_queue_head_t wait_post_send;
index a94d658b88e86bdcfc7ab2c0a7ca2832d9c37552..4b379e84c46b945382a5f6a03e62172946ca0ce8 100644 (file)
 /* Used by the DFS filter See MS-DFSC */
 #define IO_REPARSE_TAG_DFSR          0x80000012
 #define IO_REPARSE_TAG_FILTER_MANAGER 0x8000000B
-/* See section MS-FSCC 2.1.2.4 */
+/* Native SMB symlinks since Windows Vista, see MS-FSCC 2.1.2.4 */
 #define IO_REPARSE_TAG_SYMLINK       0xA000000C
 #define IO_REPARSE_TAG_DEDUP         0x80000013
 #define IO_REPARSE_APPXSTREAM       0xC0000014
-/* NFS symlinks, Win 8/SMB3 and later */
+/* NFS special files used by Windows NFS server since Windows Server 2012, see MS-FSCC 2.1.2.6 */
 #define IO_REPARSE_TAG_NFS           0x80000014
 /*
  * AzureFileSync - see
  * https://docs.microsoft.com/en-us/azure/storage/files/storage-sync-cloud-tiering
  */
 #define IO_REPARSE_TAG_AZ_FILE_SYNC  0x8000001e
+/* Native Win32 AF_UNIX sockets since Windows 10 April 2018 Update, used also by WSL */
+#define IO_REPARSE_TAG_AF_UNIX       0x80000023
 /* WSL reparse tags */
 #define IO_REPARSE_TAG_LX_SYMLINK    0xA000001D
-#define IO_REPARSE_TAG_AF_UNIX      0x80000023
 #define IO_REPARSE_TAG_LX_FIFO      0x80000024
 #define IO_REPARSE_TAG_LX_CHR       0x80000025
 #define IO_REPARSE_TAG_LX_BLK       0x80000026
index 09b20039636e7528a11efa2148b95ba0f17226e3..611716bc8f27c1701458536c0b37d73849e995c8 100644 (file)
@@ -512,6 +512,7 @@ int ksmbd_krb5_authenticate(struct ksmbd_session *sess, char *in_blob,
                            int in_len, char *out_blob, int *out_len)
 {
        struct ksmbd_spnego_authen_response *resp;
+       struct ksmbd_login_response_ext *resp_ext = NULL;
        struct ksmbd_user *user = NULL;
        int retval;
 
@@ -540,7 +541,10 @@ int ksmbd_krb5_authenticate(struct ksmbd_session *sess, char *in_blob,
                goto out;
        }
 
-       user = ksmbd_alloc_user(&resp->login_response);
+       if (resp->login_response.status & KSMBD_USER_FLAG_EXTENSION)
+               resp_ext = ksmbd_ipc_login_request_ext(resp->login_response.account);
+
+       user = ksmbd_alloc_user(&resp->login_response, resp_ext);
        if (!user) {
                ksmbd_debug(AUTH, "login failure\n");
                retval = -ENOMEM;
index 38e6fd2da3b80648aaf827625dc66b5db04bcd31..3d01d9d15293416d0ff283aace3c2ac9f53ac27e 100644 (file)
@@ -51,6 +51,9 @@
  *  - KSMBD_EVENT_SPNEGO_AUTHEN_REQUEST/RESPONSE(ksmbd_spnego_authen_request/response)
  *    This event is to make kerberos authentication to be processed in
  *    userspace.
+ *
+ *  - KSMBD_EVENT_LOGIN_REQUEST_EXT/RESPONSE_EXT(ksmbd_login_request_ext/response_ext)
+ *    This event is to get user account extension info to user IPC daemon.
  */
 
 #define KSMBD_GENL_NAME                "SMBD_GENL"
@@ -145,6 +148,16 @@ struct ksmbd_login_response {
        __u32   reserved[16];                   /* Reserved room */
 };
 
+/*
+ * IPC user login response extension.
+ */
+struct ksmbd_login_response_ext {
+       __u32   handle;
+       __s32   ngroups;                        /* supplementary group count */
+       __s8    reserved[128];                  /* Reserved room */
+       __s8    ____payload[];
+};
+
 /*
  * IPC request to fetch net share config.
  */
@@ -306,6 +319,9 @@ enum ksmbd_event {
        KSMBD_EVENT_SPNEGO_AUTHEN_REQUEST,
        KSMBD_EVENT_SPNEGO_AUTHEN_RESPONSE      = 15,
 
+       KSMBD_EVENT_LOGIN_REQUEST_EXT,
+       KSMBD_EVENT_LOGIN_RESPONSE_EXT,
+
        __KSMBD_EVENT_MAX,
        KSMBD_EVENT_MAX = __KSMBD_EVENT_MAX - 1
 };
@@ -336,6 +352,7 @@ enum KSMBD_TREE_CONN_STATUS {
 #define KSMBD_USER_FLAG_BAD_USER       BIT(3)
 #define KSMBD_USER_FLAG_GUEST_ACCOUNT  BIT(4)
 #define KSMBD_USER_FLAG_DELAY_SESSION  BIT(5)
+#define KSMBD_USER_FLAG_EXTENSION      BIT(6)
 
 /*
  * Share config flags.
index 279d00feff2168cde8e936f6e89f716fdf11fe28..421a4a95e216aa5b1c2517c40fdc811a3da1014c 100644 (file)
@@ -12,6 +12,7 @@
 struct ksmbd_user *ksmbd_login_user(const char *account)
 {
        struct ksmbd_login_response *resp;
+       struct ksmbd_login_response_ext *resp_ext = NULL;
        struct ksmbd_user *user = NULL;
 
        resp = ksmbd_ipc_login_request(account);
@@ -21,15 +22,19 @@ struct ksmbd_user *ksmbd_login_user(const char *account)
        if (!(resp->status & KSMBD_USER_FLAG_OK))
                goto out;
 
-       user = ksmbd_alloc_user(resp);
+       if (resp->status & KSMBD_USER_FLAG_EXTENSION)
+               resp_ext = ksmbd_ipc_login_request_ext(account);
+
+       user = ksmbd_alloc_user(resp, resp_ext);
 out:
        kvfree(resp);
        return user;
 }
 
-struct ksmbd_user *ksmbd_alloc_user(struct ksmbd_login_response *resp)
+struct ksmbd_user *ksmbd_alloc_user(struct ksmbd_login_response *resp,
+               struct ksmbd_login_response_ext *resp_ext)
 {
-       struct ksmbd_user *user = NULL;
+       struct ksmbd_user *user;
 
        user = kmalloc(sizeof(struct ksmbd_user), GFP_KERNEL);
        if (!user)
@@ -44,18 +49,42 @@ struct ksmbd_user *ksmbd_alloc_user(struct ksmbd_login_response *resp)
        if (user->passkey)
                memcpy(user->passkey, resp->hash, resp->hash_sz);
 
-       if (!user->name || !user->passkey) {
-               kfree(user->name);
-               kfree(user->passkey);
-               kfree(user);
-               user = NULL;
+       user->ngroups = 0;
+       user->sgid = NULL;
+
+       if (!user->name || !user->passkey)
+               goto err_free;
+
+       if (resp_ext) {
+               if (resp_ext->ngroups > NGROUPS_MAX) {
+                       pr_err("ngroups(%u) from login response exceeds max groups(%d)\n",
+                                       resp_ext->ngroups, NGROUPS_MAX);
+                       goto err_free;
+               }
+
+               user->sgid = kmemdup(resp_ext->____payload,
+                                    resp_ext->ngroups * sizeof(gid_t),
+                                    GFP_KERNEL);
+               if (!user->sgid)
+                       goto err_free;
+
+               user->ngroups = resp_ext->ngroups;
+               ksmbd_debug(SMB, "supplementary groups : %d\n", user->ngroups);
        }
+
        return user;
+
+err_free:
+       kfree(user->name);
+       kfree(user->passkey);
+       kfree(user);
+       return NULL;
 }
 
 void ksmbd_free_user(struct ksmbd_user *user)
 {
        ksmbd_ipc_logout_request(user->name, user->flags);
+       kfree(user->sgid);
        kfree(user->name);
        kfree(user->passkey);
        kfree(user);
index e068a19fd90493001fb5fd28a0a88cfd8a35e3d6..8c227b8d495431150a55ea91086951dc486f0c9b 100644 (file)
@@ -18,6 +18,8 @@ struct ksmbd_user {
 
        size_t                  passkey_sz;
        char                    *passkey;
+       int                     ngroups;
+       gid_t                   *sgid;
 };
 
 static inline bool user_guest(struct ksmbd_user *user)
@@ -60,7 +62,8 @@ static inline unsigned int user_gid(struct ksmbd_user *user)
 }
 
 struct ksmbd_user *ksmbd_login_user(const char *account);
-struct ksmbd_user *ksmbd_alloc_user(struct ksmbd_login_response *resp);
+struct ksmbd_user *ksmbd_alloc_user(struct ksmbd_login_response *resp,
+               struct ksmbd_login_response_ext *resp_ext);
 void ksmbd_free_user(struct ksmbd_user *user);
 int ksmbd_anonymous_user(struct ksmbd_user *user);
 bool ksmbd_compare_user(struct ksmbd_user *u1, struct ksmbd_user *u2);
index 99416ce9f50183dec9bb1da9fc495b0255396c0c..1e4624e9d434ab1d38767bf9a43453af5618167c 100644 (file)
@@ -177,9 +177,10 @@ static void ksmbd_expire_session(struct ksmbd_conn *conn)
 
        down_write(&conn->session_lock);
        xa_for_each(&conn->sessions, id, sess) {
-               if (sess->state != SMB2_SESSION_VALID ||
-                   time_after(jiffies,
-                              sess->last_active + SMB2_SESSION_TIMEOUT)) {
+               if (atomic_read(&sess->refcnt) == 0 &&
+                   (sess->state != SMB2_SESSION_VALID ||
+                    time_after(jiffies,
+                              sess->last_active + SMB2_SESSION_TIMEOUT))) {
                        xa_erase(&conn->sessions, sess->id);
                        hash_del(&sess->hlist);
                        ksmbd_session_destroy(sess);
@@ -269,8 +270,6 @@ struct ksmbd_session *ksmbd_session_lookup_slowpath(unsigned long long id)
 
        down_read(&sessions_table_lock);
        sess = __session_lookup(id);
-       if (sess)
-               sess->last_active = jiffies;
        up_read(&sessions_table_lock);
 
        return sess;
@@ -289,6 +288,22 @@ struct ksmbd_session *ksmbd_session_lookup_all(struct ksmbd_conn *conn,
        return sess;
 }
 
+void ksmbd_user_session_get(struct ksmbd_session *sess)
+{
+       atomic_inc(&sess->refcnt);
+}
+
+void ksmbd_user_session_put(struct ksmbd_session *sess)
+{
+       if (!sess)
+               return;
+
+       if (atomic_read(&sess->refcnt) <= 0)
+               WARN_ON(1);
+       else
+               atomic_dec(&sess->refcnt);
+}
+
 struct preauth_session *ksmbd_preauth_session_alloc(struct ksmbd_conn *conn,
                                                    u64 sess_id)
 {
@@ -393,6 +408,7 @@ static struct ksmbd_session *__session_create(int protocol)
        xa_init(&sess->rpc_handle_list);
        sess->sequence_number = 1;
        rwlock_init(&sess->tree_conns_lock);
+       atomic_set(&sess->refcnt, 1);
 
        ret = __init_smb2_session(sess);
        if (ret)
index dc9fded2cd4379a66342e3c3f87aa1423400ac1f..c1c4b20bd5c6cfd2f95b6fdf08fe4309fc9029f1 100644 (file)
@@ -61,6 +61,8 @@ struct ksmbd_session {
        struct ksmbd_file_table         file_table;
        unsigned long                   last_active;
        rwlock_t                        tree_conns_lock;
+
+       atomic_t                        refcnt;
 };
 
 static inline int test_session_flag(struct ksmbd_session *sess, int bit)
@@ -104,4 +106,6 @@ void ksmbd_release_tree_conn_id(struct ksmbd_session *sess, int id);
 int ksmbd_session_rpc_open(struct ksmbd_session *sess, char *rpc_name);
 void ksmbd_session_rpc_close(struct ksmbd_session *sess, int id);
 int ksmbd_session_rpc_method(struct ksmbd_session *sess, int id);
+void ksmbd_user_session_get(struct ksmbd_session *sess);
+void ksmbd_user_session_put(struct ksmbd_session *sess);
 #endif /* __USER_SESSION_MANAGEMENT_H__ */
index 231d2d224656b250eb539115e9f56f2f1902a495..9670c97f14b3ef745a063b538881c4ec60d950ed 100644 (file)
@@ -238,6 +238,8 @@ static void __handle_ksmbd_work(struct ksmbd_work *work,
        } while (is_chained == true);
 
 send:
+       if (work->sess)
+               ksmbd_user_session_put(work->sess);
        if (work->tcon)
                ksmbd_tree_connect_put(work->tcon);
        smb3_preauth_hash_rsp(work);
index 7460089c186f08241b0b2c823e99578fdff7e01e..599118aed20539aeb35f6e5ff7dccb52fa2b66f3 100644 (file)
@@ -605,8 +605,10 @@ int smb2_check_user_session(struct ksmbd_work *work)
 
        /* Check for validity of user session */
        work->sess = ksmbd_session_lookup_all(conn, sess_id);
-       if (work->sess)
+       if (work->sess) {
+               ksmbd_user_session_get(work->sess);
                return 1;
+       }
        ksmbd_debug(SMB, "Invalid user session, Uid %llu\n", sess_id);
        return -ENOENT;
 }
@@ -1740,6 +1742,7 @@ int smb2_sess_setup(struct ksmbd_work *work)
                }
 
                conn->binding = true;
+               ksmbd_user_session_get(sess);
        } else if ((conn->dialect < SMB30_PROT_ID ||
                    server_conf.flags & KSMBD_GLOBAL_FLAG_SMB3_MULTICHANNEL) &&
                   (req->Flags & SMB2_SESSION_REQ_FLAG_BINDING)) {
@@ -1766,6 +1769,7 @@ int smb2_sess_setup(struct ksmbd_work *work)
                }
 
                conn->binding = false;
+               ksmbd_user_session_get(sess);
        }
        work->sess = sess;
 
@@ -2228,7 +2232,9 @@ int smb2_session_logoff(struct ksmbd_work *work)
        }
 
        ksmbd_destroy_file_table(&sess->file_table);
+       down_write(&conn->session_lock);
        sess->state = SMB2_SESSION_EXPIRED;
+       up_write(&conn->session_lock);
 
        ksmbd_free_user(sess->user);
        sess->user = NULL;
@@ -4883,7 +4889,7 @@ static void get_file_alternate_info(struct ksmbd_work *work,
        spin_unlock(&dentry->d_lock);
        file_info->FileNameLength = cpu_to_le32(conv_len);
        rsp->OutputBufferLength =
-               cpu_to_le32(sizeof(struct smb2_file_alt_name_info) + conv_len);
+               cpu_to_le32(struct_size(file_info, FileName, conv_len));
 }
 
 static int get_file_stream_info(struct ksmbd_work *work,
@@ -7562,7 +7568,6 @@ static int fsctl_copychunk(struct ksmbd_work *work,
        ci_rsp->TotalBytesWritten =
                cpu_to_le32(ksmbd_server_side_copy_max_total_size());
 
-       chunks = (struct srv_copychunk *)&ci_req->Chunks[0];
        chunk_count = le32_to_cpu(ci_req->ChunkCount);
        if (chunk_count == 0)
                goto out;
@@ -7570,12 +7575,12 @@ static int fsctl_copychunk(struct ksmbd_work *work,
 
        /* verify the SRV_COPYCHUNK_COPY packet */
        if (chunk_count > ksmbd_server_side_copy_max_chunk_count() ||
-           input_count < offsetof(struct copychunk_ioctl_req, Chunks) +
-            chunk_count * sizeof(struct srv_copychunk)) {
+           input_count < struct_size(ci_req, Chunks, chunk_count)) {
                rsp->hdr.Status = STATUS_INVALID_PARAMETER;
                return -EINVAL;
        }
 
+       chunks = &ci_req->Chunks[0];
        for (i = 0; i < chunk_count; i++) {
                if (le32_to_cpu(chunks[i].Length) == 0 ||
                    le32_to_cpu(chunks[i].Length) > ksmbd_server_side_copy_max_chunk_size())
index 73aff20e22d014ff129efda0f28ba53b0da87502..649dacf7e8c4935b62216ba58ee6810bda0ac3b1 100644 (file)
@@ -190,13 +190,6 @@ struct resume_key_ioctl_rsp {
        __u8 Context[4]; /* ignored, Windows sets to 4 bytes of zero */
 } __packed;
 
-struct copychunk_ioctl_req {
-       __le64 ResumeKey[3];
-       __le32 ChunkCount;
-       __le32 Reserved;
-       __u8 Chunks[]; /* array of srv_copychunk */
-} __packed;
-
 struct srv_copychunk {
        __le64 SourceOffset;
        __le64 TargetOffset;
@@ -204,6 +197,13 @@ struct srv_copychunk {
        __le32 Reserved;
 } __packed;
 
+struct copychunk_ioctl_req {
+       __le64 ResumeKey[3];
+       __le32 ChunkCount;
+       __le32 Reserved;
+       struct srv_copychunk Chunks[] __counted_by_le(ChunkCount);
+} __packed;
+
 struct copychunk_ioctl_rsp {
        __le32 ChunksWritten;
        __le32 ChunkBytesWritten;
index 5b8d75e78ffb87a60b4259d72dded4395dfa8561..a2ebbe604c8c7cfc4601eb3bf9accfb7467e10fa 100644 (file)
@@ -736,13 +736,15 @@ int __ksmbd_override_fsids(struct ksmbd_work *work,
                struct ksmbd_share_config *share)
 {
        struct ksmbd_session *sess = work->sess;
+       struct ksmbd_user *user = sess->user;
        struct cred *cred;
        struct group_info *gi;
        unsigned int uid;
        unsigned int gid;
+       int i;
 
-       uid = user_uid(sess->user);
-       gid = user_gid(sess->user);
+       uid = user_uid(user);
+       gid = user_gid(user);
        if (share->force_uid != KSMBD_SHARE_INVALID_UID)
                uid = share->force_uid;
        if (share->force_gid != KSMBD_SHARE_INVALID_GID)
@@ -755,11 +757,18 @@ int __ksmbd_override_fsids(struct ksmbd_work *work,
        cred->fsuid = make_kuid(&init_user_ns, uid);
        cred->fsgid = make_kgid(&init_user_ns, gid);
 
-       gi = groups_alloc(0);
+       gi = groups_alloc(user->ngroups);
        if (!gi) {
                abort_creds(cred);
                return -ENOMEM;
        }
+
+       for (i = 0; i < user->ngroups; i++)
+               gi->gid[i] = make_kgid(&init_user_ns, user->sgid[i]);
+
+       if (user->ngroups)
+               groups_sort(gi);
+
        set_groups(cred, gi);
        put_group_info(gi);
 
index 8752ac82c557bf92985bd4d87a3e37f4cd4a60dc..2f27afb695f62e5f081356139fb9968a73648dc0 100644 (file)
@@ -120,6 +120,12 @@ static const struct nla_policy ksmbd_nl_policy[KSMBD_EVENT_MAX + 1] = {
        },
        [KSMBD_EVENT_SPNEGO_AUTHEN_RESPONSE] = {
        },
+       [KSMBD_EVENT_LOGIN_REQUEST_EXT] = {
+               .len = sizeof(struct ksmbd_login_request),
+       },
+       [KSMBD_EVENT_LOGIN_RESPONSE_EXT] = {
+               .len = sizeof(struct ksmbd_login_response_ext),
+       },
 };
 
 static struct genl_ops ksmbd_genl_ops[] = {
@@ -187,6 +193,14 @@ static struct genl_ops ksmbd_genl_ops[] = {
                .cmd    = KSMBD_EVENT_SPNEGO_AUTHEN_RESPONSE,
                .doit   = handle_generic_event,
        },
+       {
+               .cmd    = KSMBD_EVENT_LOGIN_REQUEST_EXT,
+               .doit   = handle_unsupported_event,
+       },
+       {
+               .cmd    = KSMBD_EVENT_LOGIN_RESPONSE_EXT,
+               .doit   = handle_generic_event,
+       },
 };
 
 static struct genl_family ksmbd_genl_family = {
@@ -198,7 +212,7 @@ static struct genl_family ksmbd_genl_family = {
        .module         = THIS_MODULE,
        .ops            = ksmbd_genl_ops,
        .n_ops          = ARRAY_SIZE(ksmbd_genl_ops),
-       .resv_start_op  = KSMBD_EVENT_SPNEGO_AUTHEN_RESPONSE + 1,
+       .resv_start_op  = KSMBD_EVENT_LOGIN_RESPONSE_EXT + 1,
 };
 
 static void ksmbd_nl_init_fixup(void)
@@ -459,16 +473,24 @@ static int ipc_validate_msg(struct ipc_msg_table_entry *entry)
 {
        unsigned int msg_sz = entry->msg_sz;
 
-       if (entry->type == KSMBD_EVENT_RPC_REQUEST) {
+       switch (entry->type) {
+       case KSMBD_EVENT_RPC_REQUEST:
+       {
                struct ksmbd_rpc_command *resp = entry->response;
 
                msg_sz = sizeof(struct ksmbd_rpc_command) + resp->payload_sz;
-       } else if (entry->type == KSMBD_EVENT_SPNEGO_AUTHEN_REQUEST) {
+               break;
+       }
+       case KSMBD_EVENT_SPNEGO_AUTHEN_REQUEST:
+       {
                struct ksmbd_spnego_authen_response *resp = entry->response;
 
                msg_sz = sizeof(struct ksmbd_spnego_authen_response) +
                                resp->session_key_len + resp->spnego_blob_len;
-       } else if (entry->type == KSMBD_EVENT_SHARE_CONFIG_REQUEST) {
+               break;
+       }
+       case KSMBD_EVENT_SHARE_CONFIG_REQUEST:
+       {
                struct ksmbd_share_config_response *resp = entry->response;
 
                if (resp->payload_sz) {
@@ -478,6 +500,17 @@ static int ipc_validate_msg(struct ipc_msg_table_entry *entry)
                        msg_sz = sizeof(struct ksmbd_share_config_response) +
                                        resp->payload_sz;
                }
+               break;
+       }
+       case KSMBD_EVENT_LOGIN_REQUEST_EXT:
+       {
+               struct ksmbd_login_response_ext *resp = entry->response;
+
+               if (resp->ngroups) {
+                       msg_sz = sizeof(struct ksmbd_login_response_ext) +
+                                       resp->ngroups * sizeof(gid_t);
+               }
+       }
        }
 
        return entry->msg_sz != msg_sz ? -EINVAL : 0;
@@ -560,6 +593,29 @@ struct ksmbd_login_response *ksmbd_ipc_login_request(const char *account)
        return resp;
 }
 
+struct ksmbd_login_response_ext *ksmbd_ipc_login_request_ext(const char *account)
+{
+       struct ksmbd_ipc_msg *msg;
+       struct ksmbd_login_request *req;
+       struct ksmbd_login_response_ext *resp;
+
+       if (strlen(account) >= KSMBD_REQ_MAX_ACCOUNT_NAME_SZ)
+               return NULL;
+
+       msg = ipc_msg_alloc(sizeof(struct ksmbd_login_request));
+       if (!msg)
+               return NULL;
+
+       msg->type = KSMBD_EVENT_LOGIN_REQUEST_EXT;
+       req = (struct ksmbd_login_request *)msg->payload;
+       req->handle = ksmbd_acquire_id(&ipc_ida);
+       strscpy(req->account, account, KSMBD_REQ_MAX_ACCOUNT_NAME_SZ);
+       resp = ipc_msg_send_request(msg, req->handle);
+       ipc_msg_handle_free(req->handle);
+       ipc_msg_free(msg);
+       return resp;
+}
+
 struct ksmbd_spnego_authen_response *
 ksmbd_ipc_spnego_authen_request(const char *spnego_blob, int blob_len)
 {
index 5e5b90a0c1879c3656b5e91a84210f296a99b6d5..d9b6737f8cd03d49c657edcee859b9a1b5f2a99d 100644 (file)
@@ -12,6 +12,8 @@
 
 struct ksmbd_login_response *
 ksmbd_ipc_login_request(const char *account);
+struct ksmbd_login_response_ext *
+ksmbd_ipc_login_request_ext(const char *account);
 
 struct ksmbd_session;
 struct ksmbd_share_config;
index 44c87e300c161a01b3812eae7795f8c600b458fc..17c76713c6d08617d0edea67543da3994328f58f 100644 (file)
@@ -1405,8 +1405,8 @@ static int smb_direct_rdma_xmit(struct smb_direct_transport *t,
        /* build rdma_rw_ctx for each descriptor */
        desc_buf = buf;
        for (i = 0; i < desc_num; i++) {
-               msg = kzalloc(offsetof(struct smb_direct_rdma_rw_msg, sg_list) +
-                             sizeof(struct scatterlist) * SG_CHUNK_SIZE, GFP_KERNEL);
+               msg = kzalloc(struct_size(msg, sg_list, SG_CHUNK_SIZE),
+                             GFP_KERNEL);
                if (!msg) {
                        ret = -ENOMEM;
                        goto out;
index 43ed29ee44ead6ef691dcecb0dd5fe9674bade30..217106ff7b8287a7e334c9235aae2d7ea397edd0 100644 (file)
@@ -8,7 +8,7 @@
  */
 #include <linux/fs.h>
 #include <linux/slab.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include "glob.h"
 #include "unicode.h"
 #include "smb_common.h"
index 1db230432960dca184f4b0ac61aa3553e15bdef9..c9c7223bc2a2e9cb5391a1b3a291f724416289c2 100644 (file)
@@ -1596,13 +1596,14 @@ int setup_bdev_super(struct super_block *sb, int sb_flags,
 EXPORT_SYMBOL_GPL(setup_bdev_super);
 
 /**
- * get_tree_bdev - Get a superblock based on a single block device
+ * get_tree_bdev_flags - Get a superblock based on a single block device
  * @fc: The filesystem context holding the parameters
  * @fill_super: Helper to initialise a new superblock
+ * @flags: GET_TREE_BDEV_* flags
  */
-int get_tree_bdev(struct fs_context *fc,
-               int (*fill_super)(struct super_block *,
-                                 struct fs_context *))
+int get_tree_bdev_flags(struct fs_context *fc,
+               int (*fill_super)(struct super_block *sb,
+                                 struct fs_context *fc), unsigned int flags)
 {
        struct super_block *s;
        int error = 0;
@@ -1613,10 +1614,10 @@ int get_tree_bdev(struct fs_context *fc,
 
        error = lookup_bdev(fc->source, &dev);
        if (error) {
-               errorf(fc, "%s: Can't lookup blockdev", fc->source);
+               if (!(flags & GET_TREE_BDEV_QUIET_LOOKUP))
+                       errorf(fc, "%s: Can't lookup blockdev", fc->source);
                return error;
        }
-
        fc->sb_flags |= SB_NOSEC;
        s = sget_dev(fc, dev);
        if (IS_ERR(s))
@@ -1644,6 +1645,19 @@ int get_tree_bdev(struct fs_context *fc,
        fc->root = dget(s->s_root);
        return 0;
 }
+EXPORT_SYMBOL_GPL(get_tree_bdev_flags);
+
+/**
+ * get_tree_bdev - Get a superblock based on a single block device
+ * @fc: The filesystem context holding the parameters
+ * @fill_super: Helper to initialise a new superblock
+ */
+int get_tree_bdev(struct fs_context *fc,
+               int (*fill_super)(struct super_block *,
+                                 struct fs_context *))
+{
+       return get_tree_bdev_flags(fc, fill_super, 0);
+}
 EXPORT_SYMBOL(get_tree_bdev);
 
 static int test_bdev_super(struct super_block *s, void *data)
index d8fc11765d6127473356241a1ffe0af84808b9cf..807c493ed0cd5ae442055a60ed82c433cb656ad5 100644 (file)
@@ -370,6 +370,7 @@ static void udf_table_free_blocks(struct super_block *sb,
        struct extent_position oepos, epos;
        int8_t etype;
        struct udf_inode_info *iinfo;
+       int ret = 0;
 
        mutex_lock(&sbi->s_alloc_mutex);
        iinfo = UDF_I(table);
@@ -383,8 +384,12 @@ static void udf_table_free_blocks(struct super_block *sb,
        epos.block = oepos.block = iinfo->i_location;
        epos.bh = oepos.bh = NULL;
 
-       while (count &&
-              (etype = udf_next_aext(table, &epos, &eloc, &elen, 1)) != -1) {
+       while (count) {
+               ret = udf_next_aext(table, &epos, &eloc, &elen, &etype, 1);
+               if (ret < 0)
+                       goto error_return;
+               if (ret == 0)
+                       break;
                if (((eloc.logicalBlockNum +
                        (elen >> sb->s_blocksize_bits)) == start)) {
                        if ((0x3FFFFFFF - elen) <
@@ -459,11 +464,8 @@ static void udf_table_free_blocks(struct super_block *sb,
                        adsize = sizeof(struct short_ad);
                else if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_LONG)
                        adsize = sizeof(struct long_ad);
-               else {
-                       brelse(oepos.bh);
-                       brelse(epos.bh);
+               else
                        goto error_return;
-               }
 
                if (epos.offset + (2 * adsize) > sb->s_blocksize) {
                        /* Steal a block from the extent being free'd */
@@ -479,10 +481,10 @@ static void udf_table_free_blocks(struct super_block *sb,
                        __udf_add_aext(table, &epos, &eloc, elen, 1);
        }
 
+error_return:
        brelse(epos.bh);
        brelse(oepos.bh);
 
-error_return:
        mutex_unlock(&sbi->s_alloc_mutex);
        return;
 }
@@ -498,6 +500,7 @@ static int udf_table_prealloc_blocks(struct super_block *sb,
        struct extent_position epos;
        int8_t etype = -1;
        struct udf_inode_info *iinfo;
+       int ret = 0;
 
        if (first_block >= sbi->s_partmaps[partition].s_partition_len)
                return 0;
@@ -516,11 +519,14 @@ static int udf_table_prealloc_blocks(struct super_block *sb,
        epos.bh = NULL;
        eloc.logicalBlockNum = 0xFFFFFFFF;
 
-       while (first_block != eloc.logicalBlockNum &&
-              (etype = udf_next_aext(table, &epos, &eloc, &elen, 1)) != -1) {
+       while (first_block != eloc.logicalBlockNum) {
+               ret = udf_next_aext(table, &epos, &eloc, &elen, &etype, 1);
+               if (ret < 0)
+                       goto err_out;
+               if (ret == 0)
+                       break;
                udf_debug("eloc=%u, elen=%u, first_block=%u\n",
                          eloc.logicalBlockNum, elen, first_block);
-               ; /* empty loop body */
        }
 
        if (first_block == eloc.logicalBlockNum) {
@@ -539,6 +545,7 @@ static int udf_table_prealloc_blocks(struct super_block *sb,
                alloc_count = 0;
        }
 
+err_out:
        brelse(epos.bh);
 
        if (alloc_count)
@@ -560,6 +567,7 @@ static udf_pblk_t udf_table_new_block(struct super_block *sb,
        struct extent_position epos, goal_epos;
        int8_t etype;
        struct udf_inode_info *iinfo = UDF_I(table);
+       int ret = 0;
 
        *err = -ENOSPC;
 
@@ -583,8 +591,10 @@ static udf_pblk_t udf_table_new_block(struct super_block *sb,
        epos.block = iinfo->i_location;
        epos.bh = goal_epos.bh = NULL;
 
-       while (spread &&
-              (etype = udf_next_aext(table, &epos, &eloc, &elen, 1)) != -1) {
+       while (spread) {
+               ret = udf_next_aext(table, &epos, &eloc, &elen, &etype, 1);
+               if (ret <= 0)
+                       break;
                if (goal >= eloc.logicalBlockNum) {
                        if (goal < eloc.logicalBlockNum +
                                        (elen >> sb->s_blocksize_bits))
@@ -612,9 +622,11 @@ static udf_pblk_t udf_table_new_block(struct super_block *sb,
 
        brelse(epos.bh);
 
-       if (spread == 0xFFFFFFFF) {
+       if (ret < 0 || spread == 0xFFFFFFFF) {
                brelse(goal_epos.bh);
                mutex_unlock(&sbi->s_alloc_mutex);
+               if (ret < 0)
+                       *err = ret;
                return 0;
        }
 
index 93153665eb374741a868580690825180c0b3121e..632453aa38934a0b58b420717ec0674c85627ce5 100644 (file)
@@ -166,13 +166,19 @@ static struct buffer_head *udf_fiiter_bread_blk(struct udf_fileident_iter *iter)
  */
 static int udf_fiiter_advance_blk(struct udf_fileident_iter *iter)
 {
+       int8_t etype = -1;
+       int err = 0;
+
        iter->loffset++;
        if (iter->loffset < DIV_ROUND_UP(iter->elen, 1<<iter->dir->i_blkbits))
                return 0;
 
        iter->loffset = 0;
-       if (udf_next_aext(iter->dir, &iter->epos, &iter->eloc, &iter->elen, 1)
-                       != (EXT_RECORDED_ALLOCATED >> 30)) {
+       err = udf_next_aext(iter->dir, &iter->epos, &iter->eloc,
+                           &iter->elen, &etype, 1);
+       if (err < 0)
+               return err;
+       else if (err == 0 || etype != (EXT_RECORDED_ALLOCATED >> 30)) {
                if (iter->pos == iter->dir->i_size) {
                        iter->elen = 0;
                        return 0;
@@ -240,6 +246,7 @@ int udf_fiiter_init(struct udf_fileident_iter *iter, struct inode *dir,
 {
        struct udf_inode_info *iinfo = UDF_I(dir);
        int err = 0;
+       int8_t etype;
 
        iter->dir = dir;
        iter->bh[0] = iter->bh[1] = NULL;
@@ -259,9 +266,9 @@ int udf_fiiter_init(struct udf_fileident_iter *iter, struct inode *dir,
                goto out;
        }
 
-       if (inode_bmap(dir, iter->pos >> dir->i_blkbits, &iter->epos,
-                      &iter->eloc, &iter->elen, &iter->loffset) !=
-           (EXT_RECORDED_ALLOCATED >> 30)) {
+       err = inode_bmap(dir, iter->pos >> dir->i_blkbits, &iter->epos,
+                        &iter->eloc, &iter->elen, &iter->loffset, &etype);
+       if (err <= 0 || etype != (EXT_RECORDED_ALLOCATED >> 30)) {
                if (pos == dir->i_size)
                        return 0;
                udf_err(dir->i_sb,
@@ -457,6 +464,7 @@ int udf_fiiter_append_blk(struct udf_fileident_iter *iter)
        sector_t block;
        uint32_t old_elen = iter->elen;
        int err;
+       int8_t etype;
 
        if (WARN_ON_ONCE(iinfo->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB))
                return -EINVAL;
@@ -471,8 +479,9 @@ int udf_fiiter_append_blk(struct udf_fileident_iter *iter)
                udf_fiiter_update_elen(iter, old_elen);
                return err;
        }
-       if (inode_bmap(iter->dir, block, &iter->epos, &iter->eloc, &iter->elen,
-                      &iter->loffset) != (EXT_RECORDED_ALLOCATED >> 30)) {
+       err = inode_bmap(iter->dir, block, &iter->epos, &iter->eloc, &iter->elen,
+                  &iter->loffset, &etype);
+       if (err <= 0 || etype != (EXT_RECORDED_ALLOCATED >> 30)) {
                udf_err(iter->dir->i_sb,
                        "block %llu not allocated in directory (ino %lu)\n",
                        (unsigned long long)block, iter->dir->i_ino);
index eaee57b91c6c6a82c9718d7658c0206d3a907e6c..70c907fe8af9eb742e510163f1c23c54b87a2108 100644 (file)
@@ -404,7 +404,7 @@ struct udf_map_rq {
 
 static int udf_map_block(struct inode *inode, struct udf_map_rq *map)
 {
-       int err;
+       int ret;
        struct udf_inode_info *iinfo = UDF_I(inode);
 
        if (WARN_ON_ONCE(iinfo->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB))
@@ -416,18 +416,24 @@ static int udf_map_block(struct inode *inode, struct udf_map_rq *map)
                uint32_t elen;
                sector_t offset;
                struct extent_position epos = {};
+               int8_t etype;
 
                down_read(&iinfo->i_data_sem);
-               if (inode_bmap(inode, map->lblk, &epos, &eloc, &elen, &offset)
-                               == (EXT_RECORDED_ALLOCATED >> 30)) {
+               ret = inode_bmap(inode, map->lblk, &epos, &eloc, &elen, &offset,
+                                &etype);
+               if (ret < 0)
+                       goto out_read;
+               if (ret > 0 && etype == (EXT_RECORDED_ALLOCATED >> 30)) {
                        map->pblk = udf_get_lb_pblock(inode->i_sb, &eloc,
                                                        offset);
                        map->oflags |= UDF_BLK_MAPPED;
+                       ret = 0;
                }
+out_read:
                up_read(&iinfo->i_data_sem);
                brelse(epos.bh);
 
-               return 0;
+               return ret;
        }
 
        down_write(&iinfo->i_data_sem);
@@ -438,9 +444,9 @@ static int udf_map_block(struct inode *inode, struct udf_map_rq *map)
        if (((loff_t)map->lblk) << inode->i_blkbits >= iinfo->i_lenExtents)
                udf_discard_prealloc(inode);
        udf_clear_extent_cache(inode);
-       err = inode_getblk(inode, map);
+       ret = inode_getblk(inode, map);
        up_write(&iinfo->i_data_sem);
-       return err;
+       return ret;
 }
 
 static int __udf_get_block(struct inode *inode, sector_t block,
@@ -543,6 +549,7 @@ static int udf_do_extend_file(struct inode *inode,
        } else {
                struct kernel_lb_addr tmploc;
                uint32_t tmplen;
+               int8_t tmptype;
 
                udf_write_aext(inode, last_pos, &last_ext->extLocation,
                                last_ext->extLength, 1);
@@ -552,8 +559,12 @@ static int udf_do_extend_file(struct inode *inode,
                 * more extents, we may need to enter possible following
                 * empty indirect extent.
                 */
-               if (new_block_bytes)
-                       udf_next_aext(inode, last_pos, &tmploc, &tmplen, 0);
+               if (new_block_bytes) {
+                       err = udf_next_aext(inode, last_pos, &tmploc, &tmplen,
+                                           &tmptype, 0);
+                       if (err < 0)
+                               goto out_err;
+               }
        }
        iinfo->i_lenExtents += add;
 
@@ -657,8 +668,10 @@ static int udf_extend_file(struct inode *inode, loff_t newsize)
         */
        udf_discard_prealloc(inode);
 
-       etype = inode_bmap(inode, first_block, &epos, &eloc, &elen, &offset);
-       within_last_ext = (etype != -1);
+       err = inode_bmap(inode, first_block, &epos, &eloc, &elen, &offset, &etype);
+       if (err < 0)
+               goto out;
+       within_last_ext = (err == 1);
        /* We don't expect extents past EOF... */
        WARN_ON_ONCE(within_last_ext &&
                     elen > ((loff_t)offset + 1) << inode->i_blkbits);
@@ -672,8 +685,10 @@ static int udf_extend_file(struct inode *inode, loff_t newsize)
                extent.extLength = EXT_NOT_RECORDED_NOT_ALLOCATED;
        } else {
                epos.offset -= adsize;
-               etype = udf_next_aext(inode, &epos, &extent.extLocation,
-                                     &extent.extLength, 0);
+               err = udf_next_aext(inode, &epos, &extent.extLocation,
+                                   &extent.extLength, &etype, 0);
+               if (err <= 0)
+                       goto out;
                extent.extLength |= etype << 30;
        }
 
@@ -710,11 +725,11 @@ static int inode_getblk(struct inode *inode, struct udf_map_rq *map)
        loff_t lbcount = 0, b_off = 0;
        udf_pblk_t newblocknum;
        sector_t offset = 0;
-       int8_t etype;
+       int8_t etype, tmpetype;
        struct udf_inode_info *iinfo = UDF_I(inode);
        udf_pblk_t goal = 0, pgoal = iinfo->i_location.logicalBlockNum;
        int lastblock = 0;
-       bool isBeyondEOF;
+       bool isBeyondEOF = false;
        int ret = 0;
 
        prev_epos.offset = udf_file_entry_alloc_offset(inode);
@@ -746,9 +761,13 @@ static int inode_getblk(struct inode *inode, struct udf_map_rq *map)
                prev_epos.offset = cur_epos.offset;
                cur_epos.offset = next_epos.offset;
 
-               etype = udf_next_aext(inode, &next_epos, &eloc, &elen, 1);
-               if (etype == -1)
+               ret = udf_next_aext(inode, &next_epos, &eloc, &elen, &etype, 1);
+               if (ret < 0) {
+                       goto out_free;
+               } else if (ret == 0) {
+                       isBeyondEOF = true;
                        break;
+               }
 
                c = !c;
 
@@ -769,13 +788,17 @@ static int inode_getblk(struct inode *inode, struct udf_map_rq *map)
         * Move prev_epos and cur_epos into indirect extent if we are at
         * the pointer to it
         */
-       udf_next_aext(inode, &prev_epos, &tmpeloc, &tmpelen, 0);
-       udf_next_aext(inode, &cur_epos, &tmpeloc, &tmpelen, 0);
+       ret = udf_next_aext(inode, &prev_epos, &tmpeloc, &tmpelen, &tmpetype, 0);
+       if (ret < 0)
+               goto out_free;
+       ret = udf_next_aext(inode, &cur_epos, &tmpeloc, &tmpelen, &tmpetype, 0);
+       if (ret < 0)
+               goto out_free;
 
        /* if the extent is allocated and recorded, return the block
           if the extent is not a multiple of the blocksize, round up */
 
-       if (etype == (EXT_RECORDED_ALLOCATED >> 30)) {
+       if (!isBeyondEOF && etype == (EXT_RECORDED_ALLOCATED >> 30)) {
                if (elen & (inode->i_sb->s_blocksize - 1)) {
                        elen = EXT_RECORDED_ALLOCATED |
                                ((elen + inode->i_sb->s_blocksize - 1) &
@@ -791,10 +814,9 @@ static int inode_getblk(struct inode *inode, struct udf_map_rq *map)
        }
 
        /* Are we beyond EOF and preallocated extent? */
-       if (etype == -1) {
+       if (isBeyondEOF) {
                loff_t hole_len;
 
-               isBeyondEOF = true;
                if (count) {
                        if (c)
                                laarr[0] = laarr[1];
@@ -830,7 +852,6 @@ static int inode_getblk(struct inode *inode, struct udf_map_rq *map)
                endnum = c + 1;
                lastblock = 1;
        } else {
-               isBeyondEOF = false;
                endnum = startnum = ((count > 2) ? 2 : count);
 
                /* if the current extent is in position 0,
@@ -844,15 +865,17 @@ static int inode_getblk(struct inode *inode, struct udf_map_rq *map)
 
                /* if the current block is located in an extent,
                   read the next extent */
-               etype = udf_next_aext(inode, &next_epos, &eloc, &elen, 0);
-               if (etype != -1) {
+               ret = udf_next_aext(inode, &next_epos, &eloc, &elen, &etype, 0);
+               if (ret > 0) {
                        laarr[c + 1].extLength = (etype << 30) | elen;
                        laarr[c + 1].extLocation = eloc;
                        count++;
                        startnum++;
                        endnum++;
-               } else
+               } else if (ret == 0)
                        lastblock = 1;
+               else
+                       goto out_free;
        }
 
        /* if the current extent is not recorded but allocated, get the
@@ -1170,6 +1193,7 @@ static int udf_update_extents(struct inode *inode, struct kernel_long_ad *laarr,
        int start = 0, i;
        struct kernel_lb_addr tmploc;
        uint32_t tmplen;
+       int8_t tmpetype;
        int err;
 
        if (startnum > endnum) {
@@ -1187,14 +1211,19 @@ static int udf_update_extents(struct inode *inode, struct kernel_long_ad *laarr,
                         */
                        if (err < 0)
                                return err;
-                       udf_next_aext(inode, epos, &laarr[i].extLocation,
-                                     &laarr[i].extLength, 1);
+                       err = udf_next_aext(inode, epos, &laarr[i].extLocation,
+                                     &laarr[i].extLength, &tmpetype, 1);
+                       if (err < 0)
+                               return err;
                        start++;
                }
        }
 
        for (i = start; i < endnum; i++) {
-               udf_next_aext(inode, epos, &tmploc, &tmplen, 0);
+               err = udf_next_aext(inode, epos, &tmploc, &tmplen, &tmpetype, 0);
+               if (err < 0)
+                       return err;
+
                udf_write_aext(inode, epos, &laarr[i].extLocation,
                               laarr[i].extLength, 1);
        }
@@ -1953,6 +1982,7 @@ int udf_setup_indirect_aext(struct inode *inode, udf_pblk_t block,
        struct extent_position nepos;
        struct kernel_lb_addr neloc;
        int ver, adsize;
+       int err = 0;
 
        if (UDF_I(inode)->i_alloc_type == ICBTAG_FLAG_AD_SHORT)
                adsize = sizeof(struct short_ad);
@@ -1997,10 +2027,12 @@ int udf_setup_indirect_aext(struct inode *inode, udf_pblk_t block,
        if (epos->offset + adsize > sb->s_blocksize) {
                struct kernel_lb_addr cp_loc;
                uint32_t cp_len;
-               int cp_type;
+               int8_t cp_type;
 
                epos->offset -= adsize;
-               cp_type = udf_current_aext(inode, epos, &cp_loc, &cp_len, 0);
+               err = udf_current_aext(inode, epos, &cp_loc, &cp_len, &cp_type, 0);
+               if (err <= 0)
+                       goto err_out;
                cp_len |= ((uint32_t)cp_type) << 30;
 
                __udf_add_aext(inode, &nepos, &cp_loc, cp_len, 1);
@@ -2015,6 +2047,9 @@ int udf_setup_indirect_aext(struct inode *inode, udf_pblk_t block,
        *epos = nepos;
 
        return 0;
+err_out:
+       brelse(bh);
+       return err;
 }
 
 /*
@@ -2160,21 +2195,30 @@ void udf_write_aext(struct inode *inode, struct extent_position *epos,
  */
 #define UDF_MAX_INDIR_EXTS 16
 
-int8_t udf_next_aext(struct inode *inode, struct extent_position *epos,
-                    struct kernel_lb_addr *eloc, uint32_t *elen, int inc)
+/*
+ * Returns 1 on success, -errno on error, 0 on hit EOF.
+ */
+int udf_next_aext(struct inode *inode, struct extent_position *epos,
+                 struct kernel_lb_addr *eloc, uint32_t *elen, int8_t *etype,
+                 int inc)
 {
-       int8_t etype;
        unsigned int indirections = 0;
+       int ret = 0;
+       udf_pblk_t block;
 
-       while ((etype = udf_current_aext(inode, epos, eloc, elen, inc)) ==
-              (EXT_NEXT_EXTENT_ALLOCDESCS >> 30)) {
-               udf_pblk_t block;
+       while (1) {
+               ret = udf_current_aext(inode, epos, eloc, elen,
+                                      etype, inc);
+               if (ret <= 0)
+                       return ret;
+               if (*etype != (EXT_NEXT_EXTENT_ALLOCDESCS >> 30))
+                       return ret;
 
                if (++indirections > UDF_MAX_INDIR_EXTS) {
                        udf_err(inode->i_sb,
                                "too many indirect extents in inode %lu\n",
                                inode->i_ino);
-                       return -1;
+                       return -EFSCORRUPTED;
                }
 
                epos->block = *eloc;
@@ -2184,18 +2228,19 @@ int8_t udf_next_aext(struct inode *inode, struct extent_position *epos,
                epos->bh = sb_bread(inode->i_sb, block);
                if (!epos->bh) {
                        udf_debug("reading block %u failed!\n", block);
-                       return -1;
+                       return -EIO;
                }
        }
-
-       return etype;
 }
 
-int8_t udf_current_aext(struct inode *inode, struct extent_position *epos,
-                       struct kernel_lb_addr *eloc, uint32_t *elen, int inc)
+/*
+ * Returns 1 on success, -errno on error, 0 on hit EOF.
+ */
+int udf_current_aext(struct inode *inode, struct extent_position *epos,
+                    struct kernel_lb_addr *eloc, uint32_t *elen, int8_t *etype,
+                    int inc)
 {
        int alen;
-       int8_t etype;
        uint8_t *ptr;
        struct short_ad *sad;
        struct long_ad *lad;
@@ -2210,20 +2255,23 @@ int8_t udf_current_aext(struct inode *inode, struct extent_position *epos,
                alen = udf_file_entry_alloc_offset(inode) +
                                                        iinfo->i_lenAlloc;
        } else {
+               struct allocExtDesc *header =
+                       (struct allocExtDesc *)epos->bh->b_data;
+
                if (!epos->offset)
                        epos->offset = sizeof(struct allocExtDesc);
                ptr = epos->bh->b_data + epos->offset;
-               alen = sizeof(struct allocExtDesc) +
-                       le32_to_cpu(((struct allocExtDesc *)epos->bh->b_data)->
-                                                       lengthAllocDescs);
+               if (check_add_overflow(sizeof(struct allocExtDesc),
+                               le32_to_cpu(header->lengthAllocDescs), &alen))
+                       return -1;
        }
 
        switch (iinfo->i_alloc_type) {
        case ICBTAG_FLAG_AD_SHORT:
                sad = udf_get_fileshortad(ptr, alen, &epos->offset, inc);
                if (!sad)
-                       return -1;
-               etype = le32_to_cpu(sad->extLength) >> 30;
+                       return 0;
+               *etype = le32_to_cpu(sad->extLength) >> 30;
                eloc->logicalBlockNum = le32_to_cpu(sad->extPosition);
                eloc->partitionReferenceNum =
                                iinfo->i_location.partitionReferenceNum;
@@ -2232,17 +2280,17 @@ int8_t udf_current_aext(struct inode *inode, struct extent_position *epos,
        case ICBTAG_FLAG_AD_LONG:
                lad = udf_get_filelongad(ptr, alen, &epos->offset, inc);
                if (!lad)
-                       return -1;
-               etype = le32_to_cpu(lad->extLength) >> 30;
+                       return 0;
+               *etype = le32_to_cpu(lad->extLength) >> 30;
                *eloc = lelb_to_cpu(lad->extLocation);
                *elen = le32_to_cpu(lad->extLength) & UDF_EXTENT_LENGTH_MASK;
                break;
        default:
                udf_debug("alloc_type = %u unsupported\n", iinfo->i_alloc_type);
-               return -1;
+               return -EINVAL;
        }
 
-       return etype;
+       return 1;
 }
 
 static int udf_insert_aext(struct inode *inode, struct extent_position epos,
@@ -2251,20 +2299,24 @@ static int udf_insert_aext(struct inode *inode, struct extent_position epos,
        struct kernel_lb_addr oeloc;
        uint32_t oelen;
        int8_t etype;
-       int err;
+       int ret;
 
        if (epos.bh)
                get_bh(epos.bh);
 
-       while ((etype = udf_next_aext(inode, &epos, &oeloc, &oelen, 0)) != -1) {
+       while (1) {
+               ret = udf_next_aext(inode, &epos, &oeloc, &oelen, &etype, 0);
+               if (ret <= 0)
+                       break;
                udf_write_aext(inode, &epos, &neloc, nelen, 1);
                neloc = oeloc;
                nelen = (etype << 30) | oelen;
        }
-       err = udf_add_aext(inode, &epos, &neloc, nelen, 1);
+       if (ret == 0)
+               ret = udf_add_aext(inode, &epos, &neloc, nelen, 1);
        brelse(epos.bh);
 
-       return err;
+       return ret;
 }
 
 int8_t udf_delete_aext(struct inode *inode, struct extent_position epos)
@@ -2276,6 +2328,7 @@ int8_t udf_delete_aext(struct inode *inode, struct extent_position epos)
        struct udf_inode_info *iinfo;
        struct kernel_lb_addr eloc;
        uint32_t elen;
+       int ret;
 
        if (epos.bh) {
                get_bh(epos.bh);
@@ -2291,10 +2344,18 @@ int8_t udf_delete_aext(struct inode *inode, struct extent_position epos)
                adsize = 0;
 
        oepos = epos;
-       if (udf_next_aext(inode, &epos, &eloc, &elen, 1) == -1)
+       if (udf_next_aext(inode, &epos, &eloc, &elen, &etype, 1) <= 0)
                return -1;
 
-       while ((etype = udf_next_aext(inode, &epos, &eloc, &elen, 1)) != -1) {
+       while (1) {
+               ret = udf_next_aext(inode, &epos, &eloc, &elen, &etype, 1);
+               if (ret < 0) {
+                       brelse(epos.bh);
+                       brelse(oepos.bh);
+                       return -1;
+               }
+               if (ret == 0)
+                       break;
                udf_write_aext(inode, &oepos, &eloc, (etype << 30) | elen, 1);
                if (oepos.bh != epos.bh) {
                        oepos.block = epos.block;
@@ -2351,14 +2412,17 @@ int8_t udf_delete_aext(struct inode *inode, struct extent_position epos)
        return (elen >> 30);
 }
 
-int8_t inode_bmap(struct inode *inode, sector_t block,
-                 struct extent_position *pos, struct kernel_lb_addr *eloc,
-                 uint32_t *elen, sector_t *offset)
+/*
+ * Returns 1 on success, -errno on error, 0 on hit EOF.
+ */
+int inode_bmap(struct inode *inode, sector_t block, struct extent_position *pos,
+              struct kernel_lb_addr *eloc, uint32_t *elen, sector_t *offset,
+              int8_t *etype)
 {
        unsigned char blocksize_bits = inode->i_sb->s_blocksize_bits;
        loff_t lbcount = 0, bcount = (loff_t) block << blocksize_bits;
-       int8_t etype;
        struct udf_inode_info *iinfo;
+       int err = 0;
 
        iinfo = UDF_I(inode);
        if (!udf_read_extent_cache(inode, bcount, &lbcount, pos)) {
@@ -2368,11 +2432,13 @@ int8_t inode_bmap(struct inode *inode, sector_t block,
        }
        *elen = 0;
        do {
-               etype = udf_next_aext(inode, pos, eloc, elen, 1);
-               if (etype == -1) {
-                       *offset = (bcount - lbcount) >> blocksize_bits;
-                       iinfo->i_lenExtents = lbcount;
-                       return -1;
+               err = udf_next_aext(inode, pos, eloc, elen, etype, 1);
+               if (err <= 0) {
+                       if (err == 0) {
+                               *offset = (bcount - lbcount) >> blocksize_bits;
+                               iinfo->i_lenExtents = lbcount;
+                       }
+                       return err;
                }
                lbcount += *elen;
        } while (lbcount <= bcount);
@@ -2380,5 +2446,5 @@ int8_t inode_bmap(struct inode *inode, sector_t block,
        udf_update_extent_cache(inode, lbcount - *elen, pos);
        *offset = (bcount + *elen - lbcount) >> blocksize_bits;
 
-       return etype;
+       return 1;
 }
index af877991edc13acb1c91b47c7bc4eb1f63d7e8f9..2b85c9501bed89a3e4e07d4ee26f8949078c4223 100644 (file)
@@ -282,9 +282,11 @@ static uint32_t udf_try_read_meta(struct inode *inode, uint32_t block,
        sector_t ext_offset;
        struct extent_position epos = {};
        uint32_t phyblock;
+       int8_t etype;
+       int err = 0;
 
-       if (inode_bmap(inode, block, &epos, &eloc, &elen, &ext_offset) !=
-                                               (EXT_RECORDED_ALLOCATED >> 30))
+       err = inode_bmap(inode, block, &epos, &eloc, &elen, &ext_offset, &etype);
+       if (err <= 0 || etype != (EXT_RECORDED_ALLOCATED >> 30))
                phyblock = 0xFFFFFFFF;
        else {
                map = &UDF_SB(sb)->s_partmaps[partition];
index 3460ecc826d16233bd1a2a8e230b3b76de12a289..1c8a736b33097e1b6aa3d26ba35a822de8969d56 100644 (file)
@@ -2482,13 +2482,14 @@ static unsigned int udf_count_free_table(struct super_block *sb,
        uint32_t elen;
        struct kernel_lb_addr eloc;
        struct extent_position epos;
+       int8_t etype;
 
        mutex_lock(&UDF_SB(sb)->s_alloc_mutex);
        epos.block = UDF_I(table)->i_location;
        epos.offset = sizeof(struct unallocSpaceEntry);
        epos.bh = NULL;
 
-       while (udf_next_aext(table, &epos, &eloc, &elen, 1) != -1)
+       while (udf_next_aext(table, &epos, &eloc, &elen, &etype, 1) > 0)
                accum += (elen >> table->i_sb->s_blocksize_bits);
 
        brelse(epos.bh);
index a686c10fd709d18f5ba5842e4fa5b0b96a5cd29d..4f33a4a4888613b5f7a9d00d7e01565af9cc2e07 100644 (file)
@@ -69,6 +69,7 @@ void udf_truncate_tail_extent(struct inode *inode)
        int8_t etype = -1, netype;
        int adsize;
        struct udf_inode_info *iinfo = UDF_I(inode);
+       int ret;
 
        if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB ||
            inode->i_size == iinfo->i_lenExtents)
@@ -85,7 +86,10 @@ void udf_truncate_tail_extent(struct inode *inode)
                BUG();
 
        /* Find the last extent in the file */
-       while ((netype = udf_next_aext(inode, &epos, &eloc, &elen, 1)) != -1) {
+       while (1) {
+               ret = udf_next_aext(inode, &epos, &eloc, &elen, &netype, 1);
+               if (ret <= 0)
+                       break;
                etype = netype;
                lbcount += elen;
                if (lbcount > inode->i_size) {
@@ -101,7 +105,8 @@ void udf_truncate_tail_extent(struct inode *inode)
                        epos.offset -= adsize;
                        extent_trunc(inode, &epos, &eloc, etype, elen, nelen);
                        epos.offset += adsize;
-                       if (udf_next_aext(inode, &epos, &eloc, &elen, 1) != -1)
+                       if (udf_next_aext(inode, &epos, &eloc, &elen,
+                                         &netype, 1) > 0)
                                udf_err(inode->i_sb,
                                        "Extent after EOF in inode %u\n",
                                        (unsigned)inode->i_ino);
@@ -110,7 +115,8 @@ void udf_truncate_tail_extent(struct inode *inode)
        }
        /* This inode entry is in-memory only and thus we don't have to mark
         * the inode dirty */
-       iinfo->i_lenExtents = inode->i_size;
+       if (ret == 0)
+               iinfo->i_lenExtents = inode->i_size;
        brelse(epos.bh);
 }
 
@@ -124,6 +130,8 @@ void udf_discard_prealloc(struct inode *inode)
        int8_t etype = -1;
        struct udf_inode_info *iinfo = UDF_I(inode);
        int bsize = i_blocksize(inode);
+       int8_t tmpetype = -1;
+       int ret;
 
        if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB ||
            ALIGN(inode->i_size, bsize) == ALIGN(iinfo->i_lenExtents, bsize))
@@ -132,15 +140,23 @@ void udf_discard_prealloc(struct inode *inode)
        epos.block = iinfo->i_location;
 
        /* Find the last extent in the file */
-       while (udf_next_aext(inode, &epos, &eloc, &elen, 0) != -1) {
+       while (1) {
+               ret = udf_next_aext(inode, &epos, &eloc, &elen, &tmpetype, 0);
+               if (ret < 0)
+                       goto out;
+               if (ret == 0)
+                       break;
                brelse(prev_epos.bh);
                prev_epos = epos;
                if (prev_epos.bh)
                        get_bh(prev_epos.bh);
 
-               etype = udf_next_aext(inode, &epos, &eloc, &elen, 1);
+               ret = udf_next_aext(inode, &epos, &eloc, &elen, &etype, 1);
+               if (ret < 0)
+                       goto out;
                lbcount += elen;
        }
+
        if (etype == (EXT_NOT_RECORDED_ALLOCATED >> 30)) {
                lbcount -= elen;
                udf_delete_aext(inode, prev_epos);
@@ -150,6 +166,7 @@ void udf_discard_prealloc(struct inode *inode)
        /* This inode entry is in-memory only and thus we don't have to mark
         * the inode dirty */
        iinfo->i_lenExtents = lbcount;
+out:
        brelse(epos.bh);
        brelse(prev_epos.bh);
 }
@@ -188,6 +205,7 @@ int udf_truncate_extents(struct inode *inode)
        loff_t byte_offset;
        int adsize;
        struct udf_inode_info *iinfo = UDF_I(inode);
+       int ret = 0;
 
        if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_SHORT)
                adsize = sizeof(struct short_ad);
@@ -196,10 +214,12 @@ int udf_truncate_extents(struct inode *inode)
        else
                BUG();
 
-       etype = inode_bmap(inode, first_block, &epos, &eloc, &elen, &offset);
+       ret = inode_bmap(inode, first_block, &epos, &eloc, &elen, &offset, &etype);
+       if (ret < 0)
+               return ret;
        byte_offset = (offset << sb->s_blocksize_bits) +
                (inode->i_size & (sb->s_blocksize - 1));
-       if (etype == -1) {
+       if (ret == 0) {
                /* We should extend the file? */
                WARN_ON(byte_offset);
                return 0;
@@ -217,8 +237,8 @@ int udf_truncate_extents(struct inode *inode)
        else
                lenalloc -= sizeof(struct allocExtDesc);
 
-       while ((etype = udf_current_aext(inode, &epos, &eloc,
-                                        &elen, 0)) != -1) {
+       while ((ret = udf_current_aext(inode, &epos, &eloc,
+                                      &elen, &etype, 0)) > 0) {
                if (etype == (EXT_NEXT_EXTENT_ALLOCDESCS >> 30)) {
                        udf_write_aext(inode, &epos, &neloc, nelen, 0);
                        if (indirect_ext_len) {
@@ -253,6 +273,11 @@ int udf_truncate_extents(struct inode *inode)
                }
        }
 
+       if (ret < 0) {
+               brelse(epos.bh);
+               return ret;
+       }
+
        if (indirect_ext_len) {
                BUG_ON(!epos.bh);
                udf_free_blocks(sb, NULL, &epos.block, 0, indirect_ext_len);
index 88692512a466871409e861dd9daaf60488a18bee..d159f20d61e89a293623ea182a7d507aa615781f 100644 (file)
@@ -157,8 +157,9 @@ extern struct buffer_head *udf_bread(struct inode *inode, udf_pblk_t block,
 extern int udf_setsize(struct inode *, loff_t);
 extern void udf_evict_inode(struct inode *);
 extern int udf_write_inode(struct inode *, struct writeback_control *wbc);
-extern int8_t inode_bmap(struct inode *, sector_t, struct extent_position *,
-                        struct kernel_lb_addr *, uint32_t *, sector_t *);
+extern int inode_bmap(struct inode *inode, sector_t block,
+                     struct extent_position *pos, struct kernel_lb_addr *eloc,
+                     uint32_t *elen, sector_t *offset, int8_t *etype);
 int udf_get_block(struct inode *, sector_t, struct buffer_head *, int);
 extern int udf_setup_indirect_aext(struct inode *inode, udf_pblk_t block,
                                   struct extent_position *epos);
@@ -169,10 +170,12 @@ extern int udf_add_aext(struct inode *, struct extent_position *,
 extern void udf_write_aext(struct inode *, struct extent_position *,
                           struct kernel_lb_addr *, uint32_t, int);
 extern int8_t udf_delete_aext(struct inode *, struct extent_position);
-extern int8_t udf_next_aext(struct inode *, struct extent_position *,
-                           struct kernel_lb_addr *, uint32_t *, int);
-extern int8_t udf_current_aext(struct inode *, struct extent_position *,
-                              struct kernel_lb_addr *, uint32_t *, int);
+extern int udf_next_aext(struct inode *inode, struct extent_position *epos,
+                        struct kernel_lb_addr *eloc, uint32_t *elen,
+                        int8_t *etype, int inc);
+extern int udf_current_aext(struct inode *inode, struct extent_position *epos,
+                           struct kernel_lb_addr *eloc, uint32_t *elen,
+                           int8_t *etype, int inc);
 extern void udf_update_extra_perms(struct inode *inode, umode_t mode);
 
 /* misc.c */
index 24bd12186647d4c5396c9242e8014d4b3ac92e90..c8390976ab6a117083c58dcd1cc05bfc5ca82886 100644 (file)
@@ -307,7 +307,7 @@ static int ufs_rename(struct mnt_idmap *idmap, struct inode *old_dir,
                if (old_dir != new_dir)
                        ufs_set_link(old_inode, dir_de, dir_folio, new_dir, 0);
                else
-                       folio_release_kmap(dir_folio, new_dir);
+                       folio_release_kmap(dir_folio, dir_de);
                inode_dec_link_count(old_dir);
        }
        return 0;
index 77b685db827511a4fac03142370a25dbb104c768..b2bd08250c7a09ce5281959ab00f5ee9bc37aa67 100644 (file)
@@ -2230,75 +2230,6 @@ static void nfdicf_init(void)
                file_fail(fold_name);
 }
 
-static void ignore_init(void)
-{
-       FILE *file;
-       unsigned int unichar;
-       unsigned int first;
-       unsigned int last;
-       unsigned int *um;
-       int count;
-       int ret;
-
-       if (verbose > 0)
-               printf("Parsing %s\n", prop_name);
-       file = fopen(prop_name, "r");
-       if (!file)
-               open_fail(prop_name, errno);
-       assert(file);
-       count = 0;
-       while (fgets(line, LINESIZE, file)) {
-               ret = sscanf(line, "%X..%X ; %s # ", &first, &last, buf0);
-               if (ret == 3) {
-                       if (strcmp(buf0, "Default_Ignorable_Code_Point"))
-                               continue;
-                       if (!utf32valid(first) || !utf32valid(last))
-                               line_fail(prop_name, line);
-                       for (unichar = first; unichar <= last; unichar++) {
-                               free(unicode_data[unichar].utf32nfdi);
-                               um = malloc(sizeof(unsigned int));
-                               *um = 0;
-                               unicode_data[unichar].utf32nfdi = um;
-                               free(unicode_data[unichar].utf32nfdicf);
-                               um = malloc(sizeof(unsigned int));
-                               *um = 0;
-                               unicode_data[unichar].utf32nfdicf = um;
-                               count++;
-                       }
-                       if (verbose > 1)
-                               printf(" %X..%X Default_Ignorable_Code_Point\n",
-                                       first, last);
-                       continue;
-               }
-               ret = sscanf(line, "%X ; %s # ", &unichar, buf0);
-               if (ret == 2) {
-                       if (strcmp(buf0, "Default_Ignorable_Code_Point"))
-                               continue;
-                       if (!utf32valid(unichar))
-                               line_fail(prop_name, line);
-                       free(unicode_data[unichar].utf32nfdi);
-                       um = malloc(sizeof(unsigned int));
-                       *um = 0;
-                       unicode_data[unichar].utf32nfdi = um;
-                       free(unicode_data[unichar].utf32nfdicf);
-                       um = malloc(sizeof(unsigned int));
-                       *um = 0;
-                       unicode_data[unichar].utf32nfdicf = um;
-                       if (verbose > 1)
-                               printf(" %X Default_Ignorable_Code_Point\n",
-                                       unichar);
-                       count++;
-                       continue;
-               }
-       }
-       fclose(file);
-
-       if (verbose > 0)
-               printf("Found %d entries\n", count);
-       if (count == 0)
-               file_fail(prop_name);
-}
-
 static void corrections_init(void)
 {
        FILE *file;
@@ -3411,7 +3342,6 @@ int main(int argc, char *argv[])
        ccc_init();
        nfdi_init();
        nfdicf_init();
-       ignore_init();
        corrections_init();
        hangul_decompose();
        nfdi_decompose();
index dafa5fed761d83bc5f9f1390c61b28de6e4a43a7..ac2da4ba2dc0f9e1d0fac456265720dc23798639 100644 (file)
@@ -82,58 +82,58 @@ static const struct utf8data utf8nfdidata[] = {
        { 0xc0100, 20736 }
 };
 
-static const unsigned char utf8data[64256] = {
+static const unsigned char utf8data[64080] = {
        /* nfdicf_30100 */
-       0xd7,0x07,0x66,0x84,0x0c,0x01,0x00,0xc6,0xd5,0x16,0xe4,0x99,0x1a,0xe3,0x63,0x15,
-       0xe2,0x4c,0x0e,0xc1,0xe0,0x4e,0x0d,0xcf,0x86,0x65,0x2d,0x0d,0x01,0x00,0xd4,0xb8,
-       0xd3,0x27,0xe2,0x89,0xa3,0xe1,0xce,0x35,0xe0,0x2c,0x22,0xcf,0x86,0xc5,0xe4,0x15,
-       0x6d,0xe3,0x60,0x68,0xe2,0xf6,0x65,0xe1,0x29,0x65,0xe0,0xee,0x64,0xcf,0x86,0xe5,
-       0xb3,0x64,0x64,0x96,0x64,0x0b,0x00,0xd2,0x0e,0xe1,0xb5,0x3c,0xe0,0xba,0xa3,0xcf,
-       0x86,0xcf,0x06,0x01,0x00,0xd1,0x0c,0xe0,0x1e,0xa9,0xcf,0x86,0xcf,0x06,0x02,0xff,
+       0xd7,0x07,0x66,0x84,0x0c,0x01,0x00,0xc6,0xd5,0x16,0xe4,0x96,0x1a,0xe3,0x60,0x15,
+       0xe2,0x49,0x0e,0xc1,0xe0,0x4b,0x0d,0xcf,0x86,0x65,0x2d,0x0d,0x01,0x00,0xd4,0xb8,
+       0xd3,0x27,0xe2,0x03,0xa3,0xe1,0xcb,0x35,0xe0,0x29,0x22,0xcf,0x86,0xc5,0xe4,0xfa,
+       0x6c,0xe3,0x45,0x68,0xe2,0xdb,0x65,0xe1,0x0e,0x65,0xe0,0xd3,0x64,0xcf,0x86,0xe5,
+       0x98,0x64,0x64,0x7b,0x64,0x0b,0x00,0xd2,0x0e,0xe1,0xb3,0x3c,0xe0,0x34,0xa3,0xcf,
+       0x86,0xcf,0x06,0x01,0x00,0xd1,0x0c,0xe0,0x98,0xa8,0xcf,0x86,0xcf,0x06,0x02,0xff,
        0xff,0xd0,0x08,0xcf,0x86,0xcf,0x06,0x01,0x00,0xcf,0x86,0xd5,0x06,0xcf,0x06,0x01,
-       0x00,0xe4,0xe1,0x45,0xe3,0x3b,0x45,0xd2,0x06,0xcf,0x06,0x01,0x00,0xe1,0x87,0xad,
-       0xd0,0x21,0xcf,0x86,0xe5,0x81,0xaa,0xe4,0x00,0xaa,0xe3,0xbf,0xa9,0xe2,0x9e,0xa9,
-       0xe1,0x8d,0xa9,0x10,0x08,0x01,0xff,0xe8,0xb1,0x88,0x00,0x01,0xff,0xe6,0x9b,0xb4,
-       0x00,0xcf,0x86,0xe5,0x63,0xac,0xd4,0x19,0xe3,0xa2,0xab,0xe2,0x81,0xab,0xe1,0x70,
-       0xab,0x10,0x08,0x01,0xff,0xe9,0xb9,0xbf,0x00,0x01,0xff,0xe8,0xab,0x96,0x00,0xe3,
-       0x09,0xac,0xe2,0xe8,0xab,0xe1,0xd7,0xab,0x10,0x08,0x01,0xff,0xe7,0xb8,0xb7,0x00,
-       0x01,0xff,0xe9,0x9b,0xbb,0x00,0x83,0xe2,0x19,0xfa,0xe1,0xf2,0xf6,0xe0,0x6f,0xf5,
-       0xcf,0x86,0xd5,0x31,0xc4,0xe3,0x54,0x4e,0xe2,0xf5,0x4c,0xe1,0xa4,0xcc,0xe0,0x9c,
-       0x4b,0xcf,0x86,0xe5,0x8e,0x49,0xe4,0xaf,0x46,0xe3,0x11,0xbd,0xe2,0x68,0xbc,0xe1,
-       0x43,0xbc,0xe0,0x1c,0xbc,0xcf,0x86,0xe5,0xe9,0xbb,0x94,0x07,0x63,0xd4,0xbb,0x07,
-       0x00,0x07,0x00,0xe4,0xdb,0xf4,0xd3,0x08,0xcf,0x86,0xcf,0x06,0x05,0x00,0xd2,0x0b,
-       0xe1,0xea,0xe1,0xcf,0x86,0xcf,0x06,0x05,0x00,0xd1,0x0e,0xe0,0xd9,0xe2,0xcf,0x86,
-       0xe5,0x9e,0xe2,0xcf,0x06,0x11,0x00,0xd0,0x0b,0xcf,0x86,0xe5,0xd9,0xe2,0xcf,0x06,
-       0x13,0x00,0xcf,0x86,0xd5,0x06,0xcf,0x06,0x00,0x00,0xe4,0x74,0xf4,0xe3,0x5d,0xf3,
-       0xd2,0xa0,0xe1,0x13,0xe7,0xd0,0x21,0xcf,0x86,0xe5,0x14,0xe4,0xe4,0x90,0xe3,0xe3,
-       0x4e,0xe3,0xe2,0x2d,0xe3,0xe1,0x1b,0xe3,0x10,0x08,0x05,0xff,0xe4,0xb8,0xbd,0x00,
-       0x05,0xff,0xe4,0xb8,0xb8,0x00,0xcf,0x86,0xd5,0x1c,0xe4,0x70,0xe5,0xe3,0x2f,0xe5,
-       0xe2,0x0e,0xe5,0xe1,0xfd,0xe4,0x10,0x08,0x05,0xff,0xe5,0x92,0xa2,0x00,0x05,0xff,
-       0xe5,0x93,0xb6,0x00,0xd4,0x34,0xd3,0x18,0xe2,0xf7,0xe5,0xe1,0xe6,0xe5,0x10,0x09,
-       0x05,0xff,0xf0,0xa1,0x9a,0xa8,0x00,0x05,0xff,0xf0,0xa1,0x9b,0xaa,0x00,0xe2,0x17,
-       0xe6,0x91,0x11,0x10,0x09,0x05,0xff,0xf0,0xa1,0x8d,0xaa,0x00,0x05,0xff,0xe5,0xac,
-       0x88,0x00,0x05,0xff,0xe5,0xac,0xbe,0x00,0xe3,0x5d,0xe6,0xd2,0x14,0xe1,0x2c,0xe6,
+       0x00,0xe4,0xdf,0x45,0xe3,0x39,0x45,0xd2,0x06,0xcf,0x06,0x01,0x00,0xe1,0x01,0xad,
+       0xd0,0x21,0xcf,0x86,0xe5,0xfb,0xa9,0xe4,0x7a,0xa9,0xe3,0x39,0xa9,0xe2,0x18,0xa9,
+       0xe1,0x07,0xa9,0x10,0x08,0x01,0xff,0xe8,0xb1,0x88,0x00,0x01,0xff,0xe6,0x9b,0xb4,
+       0x00,0xcf,0x86,0xe5,0xdd,0xab,0xd4,0x19,0xe3,0x1c,0xab,0xe2,0xfb,0xaa,0xe1,0xea,
+       0xaa,0x10,0x08,0x01,0xff,0xe9,0xb9,0xbf,0x00,0x01,0xff,0xe8,0xab,0x96,0x00,0xe3,
+       0x83,0xab,0xe2,0x62,0xab,0xe1,0x51,0xab,0x10,0x08,0x01,0xff,0xe7,0xb8,0xb7,0x00,
+       0x01,0xff,0xe9,0x9b,0xbb,0x00,0x83,0xe2,0x68,0xf9,0xe1,0x52,0xf6,0xe0,0xcf,0xf4,
+       0xcf,0x86,0xd5,0x31,0xc4,0xe3,0x51,0x4e,0xe2,0xf2,0x4c,0xe1,0x09,0xcc,0xe0,0x99,
+       0x4b,0xcf,0x86,0xe5,0x8b,0x49,0xe4,0xac,0x46,0xe3,0x76,0xbc,0xe2,0xcd,0xbb,0xe1,
+       0xa8,0xbb,0xe0,0x81,0xbb,0xcf,0x86,0xe5,0x4e,0xbb,0x94,0x07,0x63,0x39,0xbb,0x07,
+       0x00,0x07,0x00,0xe4,0x3b,0xf4,0xd3,0x08,0xcf,0x86,0xcf,0x06,0x05,0x00,0xd2,0x0b,
+       0xe1,0x4a,0xe1,0xcf,0x86,0xcf,0x06,0x05,0x00,0xd1,0x0e,0xe0,0x39,0xe2,0xcf,0x86,
+       0xe5,0xfe,0xe1,0xcf,0x06,0x11,0x00,0xd0,0x0b,0xcf,0x86,0xe5,0x39,0xe2,0xcf,0x06,
+       0x13,0x00,0xcf,0x86,0xd5,0x06,0xcf,0x06,0x00,0x00,0xe4,0xd4,0xf3,0xe3,0xbd,0xf2,
+       0xd2,0xa0,0xe1,0x73,0xe6,0xd0,0x21,0xcf,0x86,0xe5,0x74,0xe3,0xe4,0xf0,0xe2,0xe3,
+       0xae,0xe2,0xe2,0x8d,0xe2,0xe1,0x7b,0xe2,0x10,0x08,0x05,0xff,0xe4,0xb8,0xbd,0x00,
+       0x05,0xff,0xe4,0xb8,0xb8,0x00,0xcf,0x86,0xd5,0x1c,0xe4,0xd0,0xe4,0xe3,0x8f,0xe4,
+       0xe2,0x6e,0xe4,0xe1,0x5d,0xe4,0x10,0x08,0x05,0xff,0xe5,0x92,0xa2,0x00,0x05,0xff,
+       0xe5,0x93,0xb6,0x00,0xd4,0x34,0xd3,0x18,0xe2,0x57,0xe5,0xe1,0x46,0xe5,0x10,0x09,
+       0x05,0xff,0xf0,0xa1,0x9a,0xa8,0x00,0x05,0xff,0xf0,0xa1,0x9b,0xaa,0x00,0xe2,0x77,
+       0xe5,0x91,0x11,0x10,0x09,0x05,0xff,0xf0,0xa1,0x8d,0xaa,0x00,0x05,0xff,0xe5,0xac,
+       0x88,0x00,0x05,0xff,0xe5,0xac,0xbe,0x00,0xe3,0xbd,0xe5,0xd2,0x14,0xe1,0x8c,0xe5,
        0x10,0x08,0x05,0xff,0xe5,0xaf,0xb3,0x00,0x05,0xff,0xf0,0xa1,0xac,0x98,0x00,0xe1,
-       0x38,0xe6,0x10,0x08,0x05,0xff,0xe5,0xbc,0xb3,0x00,0x05,0xff,0xe5,0xb0,0xa2,0x00,
-       0xd1,0xd5,0xd0,0x6a,0xcf,0x86,0xe5,0x8d,0xeb,0xd4,0x19,0xe3,0xc6,0xea,0xe2,0xa4,
-       0xea,0xe1,0x93,0xea,0x10,0x08,0x05,0xff,0xe6,0xb4,0xbe,0x00,0x05,0xff,0xe6,0xb5,
-       0xb7,0x00,0xd3,0x18,0xe2,0x10,0xeb,0xe1,0xff,0xea,0x10,0x09,0x05,0xff,0xf0,0xa3,
-       0xbd,0x9e,0x00,0x05,0xff,0xf0,0xa3,0xbe,0x8e,0x00,0xd2,0x13,0xe1,0x28,0xeb,0x10,
+       0x98,0xe5,0x10,0x08,0x05,0xff,0xe5,0xbc,0xb3,0x00,0x05,0xff,0xe5,0xb0,0xa2,0x00,
+       0xd1,0xd5,0xd0,0x6a,0xcf,0x86,0xe5,0xed,0xea,0xd4,0x19,0xe3,0x26,0xea,0xe2,0x04,
+       0xea,0xe1,0xf3,0xe9,0x10,0x08,0x05,0xff,0xe6,0xb4,0xbe,0x00,0x05,0xff,0xe6,0xb5,
+       0xb7,0x00,0xd3,0x18,0xe2,0x70,0xea,0xe1,0x5f,0xea,0x10,0x09,0x05,0xff,0xf0,0xa3,
+       0xbd,0x9e,0x00,0x05,0xff,0xf0,0xa3,0xbe,0x8e,0x00,0xd2,0x13,0xe1,0x88,0xea,0x10,
        0x08,0x05,0xff,0xe7,0x81,0xbd,0x00,0x05,0xff,0xe7,0x81,0xb7,0x00,0xd1,0x11,0x10,
        0x08,0x05,0xff,0xe7,0x85,0x85,0x00,0x05,0xff,0xf0,0xa4,0x89,0xa3,0x00,0x10,0x08,
-       0x05,0xff,0xe7,0x86,0x9c,0x00,0x05,0xff,0xe4,0x8e,0xab,0x00,0xcf,0x86,0xe5,0x2a,
-       0xed,0xd4,0x1a,0xe3,0x62,0xec,0xe2,0x48,0xec,0xe1,0x35,0xec,0x10,0x08,0x05,0xff,
-       0xe7,0x9b,0xb4,0x00,0x05,0xff,0xf0,0xa5,0x83,0xb3,0x00,0xd3,0x16,0xe2,0xaa,0xec,
-       0xe1,0x98,0xec,0x10,0x08,0x05,0xff,0xe7,0xa3,0x8c,0x00,0x05,0xff,0xe4,0x83,0xa3,
-       0x00,0xd2,0x13,0xe1,0xc6,0xec,0x10,0x08,0x05,0xff,0xe4,0x84,0xaf,0x00,0x05,0xff,
+       0x05,0xff,0xe7,0x86,0x9c,0x00,0x05,0xff,0xe4,0x8e,0xab,0x00,0xcf,0x86,0xe5,0x8a,
+       0xec,0xd4,0x1a,0xe3,0xc2,0xeb,0xe2,0xa8,0xeb,0xe1,0x95,0xeb,0x10,0x08,0x05,0xff,
+       0xe7,0x9b,0xb4,0x00,0x05,0xff,0xf0,0xa5,0x83,0xb3,0x00,0xd3,0x16,0xe2,0x0a,0xec,
+       0xe1,0xf8,0xeb,0x10,0x08,0x05,0xff,0xe7,0xa3,0x8c,0x00,0x05,0xff,0xe4,0x83,0xa3,
+       0x00,0xd2,0x13,0xe1,0x26,0xec,0x10,0x08,0x05,0xff,0xe4,0x84,0xaf,0x00,0x05,0xff,
        0xe7,0xa9,0x80,0x00,0xd1,0x12,0x10,0x09,0x05,0xff,0xf0,0xa5,0xa5,0xbc,0x00,0x05,
        0xff,0xf0,0xa5,0xaa,0xa7,0x00,0x10,0x09,0x05,0xff,0xf0,0xa5,0xaa,0xa7,0x00,0x05,
-       0xff,0xe7,0xaa,0xae,0x00,0xe0,0xdc,0xef,0xcf,0x86,0xd5,0x1d,0xe4,0x51,0xee,0xe3,
-       0x0d,0xee,0xe2,0xeb,0xed,0xe1,0xda,0xed,0x10,0x09,0x05,0xff,0xf0,0xa3,0x8d,0x9f,
-       0x00,0x05,0xff,0xe4,0x8f,0x95,0x00,0xd4,0x19,0xe3,0xf8,0xee,0xe2,0xd4,0xee,0xe1,
-       0xc3,0xee,0x10,0x08,0x05,0xff,0xe8,0x8d,0x93,0x00,0x05,0xff,0xe8,0x8f,0x8a,0x00,
-       0xd3,0x18,0xe2,0x43,0xef,0xe1,0x32,0xef,0x10,0x09,0x05,0xff,0xf0,0xa6,0xbe,0xb1,
-       0x00,0x05,0xff,0xf0,0xa7,0x83,0x92,0x00,0xd2,0x13,0xe1,0x5b,0xef,0x10,0x08,0x05,
+       0xff,0xe7,0xaa,0xae,0x00,0xe0,0x3c,0xef,0xcf,0x86,0xd5,0x1d,0xe4,0xb1,0xed,0xe3,
+       0x6d,0xed,0xe2,0x4b,0xed,0xe1,0x3a,0xed,0x10,0x09,0x05,0xff,0xf0,0xa3,0x8d,0x9f,
+       0x00,0x05,0xff,0xe4,0x8f,0x95,0x00,0xd4,0x19,0xe3,0x58,0xee,0xe2,0x34,0xee,0xe1,
+       0x23,0xee,0x10,0x08,0x05,0xff,0xe8,0x8d,0x93,0x00,0x05,0xff,0xe8,0x8f,0x8a,0x00,
+       0xd3,0x18,0xe2,0xa3,0xee,0xe1,0x92,0xee,0x10,0x09,0x05,0xff,0xf0,0xa6,0xbe,0xb1,
+       0x00,0x05,0xff,0xf0,0xa7,0x83,0x92,0x00,0xd2,0x13,0xe1,0xbb,0xee,0x10,0x08,0x05,
        0xff,0xe8,0x9a,0x88,0x00,0x05,0xff,0xe8,0x9c,0x8e,0x00,0xd1,0x10,0x10,0x08,0x05,
        0xff,0xe8,0x9c,0xa8,0x00,0x05,0xff,0xe8,0x9d,0xab,0x00,0x10,0x08,0x05,0xff,0xe8,
        0x9e,0x86,0x00,0x05,0xff,0xe4,0xb5,0x97,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
@@ -141,152 +141,152 @@ static const unsigned char utf8data[64256] = {
        0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
        /* nfdi_30100 */
-       0x57,0x04,0x01,0x00,0xc6,0xd5,0x16,0xe4,0xc2,0x59,0xe3,0xfb,0x54,0xe2,0x74,0x4f,
-       0xc1,0xe0,0xa0,0x4d,0xcf,0x86,0x65,0x84,0x4d,0x01,0x00,0xd4,0xb8,0xd3,0x27,0xe2,
-       0x0c,0xa0,0xe1,0xdf,0x8d,0xe0,0x39,0x71,0xcf,0x86,0xc5,0xe4,0x98,0x69,0xe3,0xe3,
-       0x64,0xe2,0x79,0x62,0xe1,0xac,0x61,0xe0,0x71,0x61,0xcf,0x86,0xe5,0x36,0x61,0x64,
-       0x19,0x61,0x0b,0x00,0xd2,0x0e,0xe1,0xc2,0xa0,0xe0,0x3d,0xa0,0xcf,0x86,0xcf,0x06,
-       0x01,0x00,0xd1,0x0c,0xe0,0xa1,0xa5,0xcf,0x86,0xcf,0x06,0x02,0xff,0xff,0xd0,0x08,
-       0xcf,0x86,0xcf,0x06,0x01,0x00,0xcf,0x86,0xd5,0x06,0xcf,0x06,0x01,0x00,0xe4,0x9e,
-       0xb6,0xe3,0x18,0xae,0xd2,0x06,0xcf,0x06,0x01,0x00,0xe1,0x0a,0xaa,0xd0,0x21,0xcf,
-       0x86,0xe5,0x04,0xa7,0xe4,0x83,0xa6,0xe3,0x42,0xa6,0xe2,0x21,0xa6,0xe1,0x10,0xa6,
-       0x10,0x08,0x01,0xff,0xe8,0xb1,0x88,0x00,0x01,0xff,0xe6,0x9b,0xb4,0x00,0xcf,0x86,
-       0xe5,0xe6,0xa8,0xd4,0x19,0xe3,0x25,0xa8,0xe2,0x04,0xa8,0xe1,0xf3,0xa7,0x10,0x08,
-       0x01,0xff,0xe9,0xb9,0xbf,0x00,0x01,0xff,0xe8,0xab,0x96,0x00,0xe3,0x8c,0xa8,0xe2,
-       0x6b,0xa8,0xe1,0x5a,0xa8,0x10,0x08,0x01,0xff,0xe7,0xb8,0xb7,0x00,0x01,0xff,0xe9,
-       0x9b,0xbb,0x00,0x83,0xe2,0x9c,0xf6,0xe1,0x75,0xf3,0xe0,0xf2,0xf1,0xcf,0x86,0xd5,
-       0x31,0xc4,0xe3,0x6d,0xcc,0xe2,0x46,0xca,0xe1,0x27,0xc9,0xe0,0xb7,0xbf,0xcf,0x86,
-       0xe5,0xaa,0xbb,0xe4,0xa3,0xba,0xe3,0x94,0xb9,0xe2,0xeb,0xb8,0xe1,0xc6,0xb8,0xe0,
-       0x9f,0xb8,0xcf,0x86,0xe5,0x6c,0xb8,0x94,0x07,0x63,0x57,0xb8,0x07,0x00,0x07,0x00,
-       0xe4,0x5e,0xf1,0xd3,0x08,0xcf,0x86,0xcf,0x06,0x05,0x00,0xd2,0x0b,0xe1,0x6d,0xde,
-       0xcf,0x86,0xcf,0x06,0x05,0x00,0xd1,0x0e,0xe0,0x5c,0xdf,0xcf,0x86,0xe5,0x21,0xdf,
-       0xcf,0x06,0x11,0x00,0xd0,0x0b,0xcf,0x86,0xe5,0x5c,0xdf,0xcf,0x06,0x13,0x00,0xcf,
-       0x86,0xd5,0x06,0xcf,0x06,0x00,0x00,0xe4,0xf7,0xf0,0xe3,0xe0,0xef,0xd2,0xa0,0xe1,
-       0x96,0xe3,0xd0,0x21,0xcf,0x86,0xe5,0x97,0xe0,0xe4,0x13,0xe0,0xe3,0xd1,0xdf,0xe2,
-       0xb0,0xdf,0xe1,0x9e,0xdf,0x10,0x08,0x05,0xff,0xe4,0xb8,0xbd,0x00,0x05,0xff,0xe4,
-       0xb8,0xb8,0x00,0xcf,0x86,0xd5,0x1c,0xe4,0xf3,0xe1,0xe3,0xb2,0xe1,0xe2,0x91,0xe1,
-       0xe1,0x80,0xe1,0x10,0x08,0x05,0xff,0xe5,0x92,0xa2,0x00,0x05,0xff,0xe5,0x93,0xb6,
-       0x00,0xd4,0x34,0xd3,0x18,0xe2,0x7a,0xe2,0xe1,0x69,0xe2,0x10,0x09,0x05,0xff,0xf0,
-       0xa1,0x9a,0xa8,0x00,0x05,0xff,0xf0,0xa1,0x9b,0xaa,0x00,0xe2,0x9a,0xe2,0x91,0x11,
-       0x10,0x09,0x05,0xff,0xf0,0xa1,0x8d,0xaa,0x00,0x05,0xff,0xe5,0xac,0x88,0x00,0x05,
-       0xff,0xe5,0xac,0xbe,0x00,0xe3,0xe0,0xe2,0xd2,0x14,0xe1,0xaf,0xe2,0x10,0x08,0x05,
-       0xff,0xe5,0xaf,0xb3,0x00,0x05,0xff,0xf0,0xa1,0xac,0x98,0x00,0xe1,0xbb,0xe2,0x10,
-       0x08,0x05,0xff,0xe5,0xbc,0xb3,0x00,0x05,0xff,0xe5,0xb0,0xa2,0x00,0xd1,0xd5,0xd0,
-       0x6a,0xcf,0x86,0xe5,0x10,0xe8,0xd4,0x19,0xe3,0x49,0xe7,0xe2,0x27,0xe7,0xe1,0x16,
-       0xe7,0x10,0x08,0x05,0xff,0xe6,0xb4,0xbe,0x00,0x05,0xff,0xe6,0xb5,0xb7,0x00,0xd3,
-       0x18,0xe2,0x93,0xe7,0xe1,0x82,0xe7,0x10,0x09,0x05,0xff,0xf0,0xa3,0xbd,0x9e,0x00,
-       0x05,0xff,0xf0,0xa3,0xbe,0x8e,0x00,0xd2,0x13,0xe1,0xab,0xe7,0x10,0x08,0x05,0xff,
-       0xe7,0x81,0xbd,0x00,0x05,0xff,0xe7,0x81,0xb7,0x00,0xd1,0x11,0x10,0x08,0x05,0xff,
-       0xe7,0x85,0x85,0x00,0x05,0xff,0xf0,0xa4,0x89,0xa3,0x00,0x10,0x08,0x05,0xff,0xe7,
-       0x86,0x9c,0x00,0x05,0xff,0xe4,0x8e,0xab,0x00,0xcf,0x86,0xe5,0xad,0xe9,0xd4,0x1a,
-       0xe3,0xe5,0xe8,0xe2,0xcb,0xe8,0xe1,0xb8,0xe8,0x10,0x08,0x05,0xff,0xe7,0x9b,0xb4,
-       0x00,0x05,0xff,0xf0,0xa5,0x83,0xb3,0x00,0xd3,0x16,0xe2,0x2d,0xe9,0xe1,0x1b,0xe9,
-       0x10,0x08,0x05,0xff,0xe7,0xa3,0x8c,0x00,0x05,0xff,0xe4,0x83,0xa3,0x00,0xd2,0x13,
-       0xe1,0x49,0xe9,0x10,0x08,0x05,0xff,0xe4,0x84,0xaf,0x00,0x05,0xff,0xe7,0xa9,0x80,
-       0x00,0xd1,0x12,0x10,0x09,0x05,0xff,0xf0,0xa5,0xa5,0xbc,0x00,0x05,0xff,0xf0,0xa5,
-       0xaa,0xa7,0x00,0x10,0x09,0x05,0xff,0xf0,0xa5,0xaa,0xa7,0x00,0x05,0xff,0xe7,0xaa,
-       0xae,0x00,0xe0,0x5f,0xec,0xcf,0x86,0xd5,0x1d,0xe4,0xd4,0xea,0xe3,0x90,0xea,0xe2,
-       0x6e,0xea,0xe1,0x5d,0xea,0x10,0x09,0x05,0xff,0xf0,0xa3,0x8d,0x9f,0x00,0x05,0xff,
-       0xe4,0x8f,0x95,0x00,0xd4,0x19,0xe3,0x7b,0xeb,0xe2,0x57,0xeb,0xe1,0x46,0xeb,0x10,
-       0x08,0x05,0xff,0xe8,0x8d,0x93,0x00,0x05,0xff,0xe8,0x8f,0x8a,0x00,0xd3,0x18,0xe2,
-       0xc6,0xeb,0xe1,0xb5,0xeb,0x10,0x09,0x05,0xff,0xf0,0xa6,0xbe,0xb1,0x00,0x05,0xff,
-       0xf0,0xa7,0x83,0x92,0x00,0xd2,0x13,0xe1,0xde,0xeb,0x10,0x08,0x05,0xff,0xe8,0x9a,
-       0x88,0x00,0x05,0xff,0xe8,0x9c,0x8e,0x00,0xd1,0x10,0x10,0x08,0x05,0xff,0xe8,0x9c,
-       0xa8,0x00,0x05,0xff,0xe8,0x9d,0xab,0x00,0x10,0x08,0x05,0xff,0xe8,0x9e,0x86,0x00,
-       0x05,0xff,0xe4,0xb5,0x97,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+       0x57,0x04,0x01,0x00,0xc6,0xd5,0x13,0xe4,0xa8,0x59,0xe3,0xe2,0x54,0xe2,0x5b,0x4f,
+       0xc1,0xe0,0x87,0x4d,0xcf,0x06,0x01,0x00,0xd4,0xb8,0xd3,0x27,0xe2,0x89,0x9f,0xe1,
+       0x91,0x8d,0xe0,0x21,0x71,0xcf,0x86,0xc5,0xe4,0x80,0x69,0xe3,0xcb,0x64,0xe2,0x61,
+       0x62,0xe1,0x94,0x61,0xe0,0x59,0x61,0xcf,0x86,0xe5,0x1e,0x61,0x64,0x01,0x61,0x0b,
+       0x00,0xd2,0x0e,0xe1,0x3f,0xa0,0xe0,0xba,0x9f,0xcf,0x86,0xcf,0x06,0x01,0x00,0xd1,
+       0x0c,0xe0,0x1e,0xa5,0xcf,0x86,0xcf,0x06,0x02,0xff,0xff,0xd0,0x08,0xcf,0x86,0xcf,
+       0x06,0x01,0x00,0xcf,0x86,0xd5,0x06,0xcf,0x06,0x01,0x00,0xe4,0x1b,0xb6,0xe3,0x95,
+       0xad,0xd2,0x06,0xcf,0x06,0x01,0x00,0xe1,0x87,0xa9,0xd0,0x21,0xcf,0x86,0xe5,0x81,
+       0xa6,0xe4,0x00,0xa6,0xe3,0xbf,0xa5,0xe2,0x9e,0xa5,0xe1,0x8d,0xa5,0x10,0x08,0x01,
+       0xff,0xe8,0xb1,0x88,0x00,0x01,0xff,0xe6,0x9b,0xb4,0x00,0xcf,0x86,0xe5,0x63,0xa8,
+       0xd4,0x19,0xe3,0xa2,0xa7,0xe2,0x81,0xa7,0xe1,0x70,0xa7,0x10,0x08,0x01,0xff,0xe9,
+       0xb9,0xbf,0x00,0x01,0xff,0xe8,0xab,0x96,0x00,0xe3,0x09,0xa8,0xe2,0xe8,0xa7,0xe1,
+       0xd7,0xa7,0x10,0x08,0x01,0xff,0xe7,0xb8,0xb7,0x00,0x01,0xff,0xe9,0x9b,0xbb,0x00,
+       0x83,0xe2,0xee,0xf5,0xe1,0xd8,0xf2,0xe0,0x55,0xf1,0xcf,0x86,0xd5,0x31,0xc4,0xe3,
+       0xd5,0xcb,0xe2,0xae,0xc9,0xe1,0x8f,0xc8,0xe0,0x1f,0xbf,0xcf,0x86,0xe5,0x12,0xbb,
+       0xe4,0x0b,0xba,0xe3,0xfc,0xb8,0xe2,0x53,0xb8,0xe1,0x2e,0xb8,0xe0,0x07,0xb8,0xcf,
+       0x86,0xe5,0xd4,0xb7,0x94,0x07,0x63,0xbf,0xb7,0x07,0x00,0x07,0x00,0xe4,0xc1,0xf0,
+       0xd3,0x08,0xcf,0x86,0xcf,0x06,0x05,0x00,0xd2,0x0b,0xe1,0xd0,0xdd,0xcf,0x86,0xcf,
+       0x06,0x05,0x00,0xd1,0x0e,0xe0,0xbf,0xde,0xcf,0x86,0xe5,0x84,0xde,0xcf,0x06,0x11,
+       0x00,0xd0,0x0b,0xcf,0x86,0xe5,0xbf,0xde,0xcf,0x06,0x13,0x00,0xcf,0x86,0xd5,0x06,
+       0xcf,0x06,0x00,0x00,0xe4,0x5a,0xf0,0xe3,0x43,0xef,0xd2,0xa0,0xe1,0xf9,0xe2,0xd0,
+       0x21,0xcf,0x86,0xe5,0xfa,0xdf,0xe4,0x76,0xdf,0xe3,0x34,0xdf,0xe2,0x13,0xdf,0xe1,
+       0x01,0xdf,0x10,0x08,0x05,0xff,0xe4,0xb8,0xbd,0x00,0x05,0xff,0xe4,0xb8,0xb8,0x00,
+       0xcf,0x86,0xd5,0x1c,0xe4,0x56,0xe1,0xe3,0x15,0xe1,0xe2,0xf4,0xe0,0xe1,0xe3,0xe0,
+       0x10,0x08,0x05,0xff,0xe5,0x92,0xa2,0x00,0x05,0xff,0xe5,0x93,0xb6,0x00,0xd4,0x34,
+       0xd3,0x18,0xe2,0xdd,0xe1,0xe1,0xcc,0xe1,0x10,0x09,0x05,0xff,0xf0,0xa1,0x9a,0xa8,
+       0x00,0x05,0xff,0xf0,0xa1,0x9b,0xaa,0x00,0xe2,0xfd,0xe1,0x91,0x11,0x10,0x09,0x05,
+       0xff,0xf0,0xa1,0x8d,0xaa,0x00,0x05,0xff,0xe5,0xac,0x88,0x00,0x05,0xff,0xe5,0xac,
+       0xbe,0x00,0xe3,0x43,0xe2,0xd2,0x14,0xe1,0x12,0xe2,0x10,0x08,0x05,0xff,0xe5,0xaf,
+       0xb3,0x00,0x05,0xff,0xf0,0xa1,0xac,0x98,0x00,0xe1,0x1e,0xe2,0x10,0x08,0x05,0xff,
+       0xe5,0xbc,0xb3,0x00,0x05,0xff,0xe5,0xb0,0xa2,0x00,0xd1,0xd5,0xd0,0x6a,0xcf,0x86,
+       0xe5,0x73,0xe7,0xd4,0x19,0xe3,0xac,0xe6,0xe2,0x8a,0xe6,0xe1,0x79,0xe6,0x10,0x08,
+       0x05,0xff,0xe6,0xb4,0xbe,0x00,0x05,0xff,0xe6,0xb5,0xb7,0x00,0xd3,0x18,0xe2,0xf6,
+       0xe6,0xe1,0xe5,0xe6,0x10,0x09,0x05,0xff,0xf0,0xa3,0xbd,0x9e,0x00,0x05,0xff,0xf0,
+       0xa3,0xbe,0x8e,0x00,0xd2,0x13,0xe1,0x0e,0xe7,0x10,0x08,0x05,0xff,0xe7,0x81,0xbd,
+       0x00,0x05,0xff,0xe7,0x81,0xb7,0x00,0xd1,0x11,0x10,0x08,0x05,0xff,0xe7,0x85,0x85,
+       0x00,0x05,0xff,0xf0,0xa4,0x89,0xa3,0x00,0x10,0x08,0x05,0xff,0xe7,0x86,0x9c,0x00,
+       0x05,0xff,0xe4,0x8e,0xab,0x00,0xcf,0x86,0xe5,0x10,0xe9,0xd4,0x1a,0xe3,0x48,0xe8,
+       0xe2,0x2e,0xe8,0xe1,0x1b,0xe8,0x10,0x08,0x05,0xff,0xe7,0x9b,0xb4,0x00,0x05,0xff,
+       0xf0,0xa5,0x83,0xb3,0x00,0xd3,0x16,0xe2,0x90,0xe8,0xe1,0x7e,0xe8,0x10,0x08,0x05,
+       0xff,0xe7,0xa3,0x8c,0x00,0x05,0xff,0xe4,0x83,0xa3,0x00,0xd2,0x13,0xe1,0xac,0xe8,
+       0x10,0x08,0x05,0xff,0xe4,0x84,0xaf,0x00,0x05,0xff,0xe7,0xa9,0x80,0x00,0xd1,0x12,
+       0x10,0x09,0x05,0xff,0xf0,0xa5,0xa5,0xbc,0x00,0x05,0xff,0xf0,0xa5,0xaa,0xa7,0x00,
+       0x10,0x09,0x05,0xff,0xf0,0xa5,0xaa,0xa7,0x00,0x05,0xff,0xe7,0xaa,0xae,0x00,0xe0,
+       0xc2,0xeb,0xcf,0x86,0xd5,0x1d,0xe4,0x37,0xea,0xe3,0xf3,0xe9,0xe2,0xd1,0xe9,0xe1,
+       0xc0,0xe9,0x10,0x09,0x05,0xff,0xf0,0xa3,0x8d,0x9f,0x00,0x05,0xff,0xe4,0x8f,0x95,
+       0x00,0xd4,0x19,0xe3,0xde,0xea,0xe2,0xba,0xea,0xe1,0xa9,0xea,0x10,0x08,0x05,0xff,
+       0xe8,0x8d,0x93,0x00,0x05,0xff,0xe8,0x8f,0x8a,0x00,0xd3,0x18,0xe2,0x29,0xeb,0xe1,
+       0x18,0xeb,0x10,0x09,0x05,0xff,0xf0,0xa6,0xbe,0xb1,0x00,0x05,0xff,0xf0,0xa7,0x83,
+       0x92,0x00,0xd2,0x13,0xe1,0x41,0xeb,0x10,0x08,0x05,0xff,0xe8,0x9a,0x88,0x00,0x05,
+       0xff,0xe8,0x9c,0x8e,0x00,0xd1,0x10,0x10,0x08,0x05,0xff,0xe8,0x9c,0xa8,0x00,0x05,
+       0xff,0xe8,0x9d,0xab,0x00,0x10,0x08,0x05,0xff,0xe8,0x9e,0x86,0x00,0x05,0xff,0xe4,
+       0xb5,0x97,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
        /* nfdicf_30200 */
-       0xd7,0x07,0x66,0x84,0x05,0x01,0x00,0xc6,0xd5,0x16,0xe4,0x99,0x13,0xe3,0x63,0x0e,
-       0xe2,0x4c,0x07,0xc1,0xe0,0x4e,0x06,0xcf,0x86,0x65,0x2d,0x06,0x01,0x00,0xd4,0x2a,
-       0xe3,0xd0,0x35,0xe2,0x88,0x9c,0xe1,0xcd,0x2e,0xe0,0x2b,0x1b,0xcf,0x86,0xc5,0xe4,
-       0x14,0x66,0xe3,0x5f,0x61,0xe2,0xf5,0x5e,0xe1,0x28,0x5e,0xe0,0xed,0x5d,0xcf,0x86,
-       0xe5,0xb2,0x5d,0x64,0x95,0x5d,0x0b,0x00,0x83,0xe2,0xa7,0xf3,0xe1,0x80,0xf0,0xe0,
-       0xfd,0xee,0xcf,0x86,0xd5,0x31,0xc4,0xe3,0xe2,0x47,0xe2,0x83,0x46,0xe1,0x32,0xc6,
-       0xe0,0x2a,0x45,0xcf,0x86,0xe5,0x1c,0x43,0xe4,0x3d,0x40,0xe3,0x9f,0xb6,0xe2,0xf6,
-       0xb5,0xe1,0xd1,0xb5,0xe0,0xaa,0xb5,0xcf,0x86,0xe5,0x77,0xb5,0x94,0x07,0x63,0x62,
-       0xb5,0x07,0x00,0x07,0x00,0xe4,0x69,0xee,0xd3,0x08,0xcf,0x86,0xcf,0x06,0x05,0x00,
-       0xd2,0x0b,0xe1,0x78,0xdb,0xcf,0x86,0xcf,0x06,0x05,0x00,0xd1,0x0e,0xe0,0x67,0xdc,
-       0xcf,0x86,0xe5,0x2c,0xdc,0xcf,0x06,0x11,0x00,0xd0,0x0b,0xcf,0x86,0xe5,0x67,0xdc,
-       0xcf,0x06,0x13,0x00,0xcf,0x86,0xd5,0x06,0xcf,0x06,0x00,0x00,0xe4,0x02,0xee,0xe3,
-       0xeb,0xec,0xd2,0xa0,0xe1,0xa1,0xe0,0xd0,0x21,0xcf,0x86,0xe5,0xa2,0xdd,0xe4,0x1e,
-       0xdd,0xe3,0xdc,0xdc,0xe2,0xbb,0xdc,0xe1,0xa9,0xdc,0x10,0x08,0x05,0xff,0xe4,0xb8,
-       0xbd,0x00,0x05,0xff,0xe4,0xb8,0xb8,0x00,0xcf,0x86,0xd5,0x1c,0xe4,0xfe,0xde,0xe3,
-       0xbd,0xde,0xe2,0x9c,0xde,0xe1,0x8b,0xde,0x10,0x08,0x05,0xff,0xe5,0x92,0xa2,0x00,
-       0x05,0xff,0xe5,0x93,0xb6,0x00,0xd4,0x34,0xd3,0x18,0xe2,0x85,0xdf,0xe1,0x74,0xdf,
+       0xd7,0x07,0x66,0x84,0x05,0x01,0x00,0xc6,0xd5,0x16,0xe4,0x96,0x13,0xe3,0x60,0x0e,
+       0xe2,0x49,0x07,0xc1,0xe0,0x4b,0x06,0xcf,0x86,0x65,0x2d,0x06,0x01,0x00,0xd4,0x2a,
+       0xe3,0xce,0x35,0xe2,0x02,0x9c,0xe1,0xca,0x2e,0xe0,0x28,0x1b,0xcf,0x86,0xc5,0xe4,
+       0xf9,0x65,0xe3,0x44,0x61,0xe2,0xda,0x5e,0xe1,0x0d,0x5e,0xe0,0xd2,0x5d,0xcf,0x86,
+       0xe5,0x97,0x5d,0x64,0x7a,0x5d,0x0b,0x00,0x83,0xe2,0xf6,0xf2,0xe1,0xe0,0xef,0xe0,
+       0x5d,0xee,0xcf,0x86,0xd5,0x31,0xc4,0xe3,0xdf,0x47,0xe2,0x80,0x46,0xe1,0x97,0xc5,
+       0xe0,0x27,0x45,0xcf,0x86,0xe5,0x19,0x43,0xe4,0x3a,0x40,0xe3,0x04,0xb6,0xe2,0x5b,
+       0xb5,0xe1,0x36,0xb5,0xe0,0x0f,0xb5,0xcf,0x86,0xe5,0xdc,0xb4,0x94,0x07,0x63,0xc7,
+       0xb4,0x07,0x00,0x07,0x00,0xe4,0xc9,0xed,0xd3,0x08,0xcf,0x86,0xcf,0x06,0x05,0x00,
+       0xd2,0x0b,0xe1,0xd8,0xda,0xcf,0x86,0xcf,0x06,0x05,0x00,0xd1,0x0e,0xe0,0xc7,0xdb,
+       0xcf,0x86,0xe5,0x8c,0xdb,0xcf,0x06,0x11,0x00,0xd0,0x0b,0xcf,0x86,0xe5,0xc7,0xdb,
+       0xcf,0x06,0x13,0x00,0xcf,0x86,0xd5,0x06,0xcf,0x06,0x00,0x00,0xe4,0x62,0xed,0xe3,
+       0x4b,0xec,0xd2,0xa0,0xe1,0x01,0xe0,0xd0,0x21,0xcf,0x86,0xe5,0x02,0xdd,0xe4,0x7e,
+       0xdc,0xe3,0x3c,0xdc,0xe2,0x1b,0xdc,0xe1,0x09,0xdc,0x10,0x08,0x05,0xff,0xe4,0xb8,
+       0xbd,0x00,0x05,0xff,0xe4,0xb8,0xb8,0x00,0xcf,0x86,0xd5,0x1c,0xe4,0x5e,0xde,0xe3,
+       0x1d,0xde,0xe2,0xfc,0xdd,0xe1,0xeb,0xdd,0x10,0x08,0x05,0xff,0xe5,0x92,0xa2,0x00,
+       0x05,0xff,0xe5,0x93,0xb6,0x00,0xd4,0x34,0xd3,0x18,0xe2,0xe5,0xde,0xe1,0xd4,0xde,
        0x10,0x09,0x05,0xff,0xf0,0xa1,0x9a,0xa8,0x00,0x05,0xff,0xf0,0xa1,0x9b,0xaa,0x00,
-       0xe2,0xa5,0xdf,0x91,0x11,0x10,0x09,0x05,0xff,0xf0,0xa1,0x8d,0xaa,0x00,0x05,0xff,
-       0xe5,0xac,0x88,0x00,0x05,0xff,0xe5,0xac,0xbe,0x00,0xe3,0xeb,0xdf,0xd2,0x14,0xe1,
-       0xba,0xdf,0x10,0x08,0x05,0xff,0xe5,0xaf,0xb3,0x00,0x05,0xff,0xf0,0xa1,0xac,0x98,
-       0x00,0xe1,0xc6,0xdf,0x10,0x08,0x05,0xff,0xe5,0xbc,0xb3,0x00,0x05,0xff,0xe5,0xb0,
-       0xa2,0x00,0xd1,0xd5,0xd0,0x6a,0xcf,0x86,0xe5,0x1b,0xe5,0xd4,0x19,0xe3,0x54,0xe4,
-       0xe2,0x32,0xe4,0xe1,0x21,0xe4,0x10,0x08,0x05,0xff,0xe6,0xb4,0xbe,0x00,0x05,0xff,
-       0xe6,0xb5,0xb7,0x00,0xd3,0x18,0xe2,0x9e,0xe4,0xe1,0x8d,0xe4,0x10,0x09,0x05,0xff,
-       0xf0,0xa3,0xbd,0x9e,0x00,0x05,0xff,0xf0,0xa3,0xbe,0x8e,0x00,0xd2,0x13,0xe1,0xb6,
+       0xe2,0x05,0xdf,0x91,0x11,0x10,0x09,0x05,0xff,0xf0,0xa1,0x8d,0xaa,0x00,0x05,0xff,
+       0xe5,0xac,0x88,0x00,0x05,0xff,0xe5,0xac,0xbe,0x00,0xe3,0x4b,0xdf,0xd2,0x14,0xe1,
+       0x1a,0xdf,0x10,0x08,0x05,0xff,0xe5,0xaf,0xb3,0x00,0x05,0xff,0xf0,0xa1,0xac,0x98,
+       0x00,0xe1,0x26,0xdf,0x10,0x08,0x05,0xff,0xe5,0xbc,0xb3,0x00,0x05,0xff,0xe5,0xb0,
+       0xa2,0x00,0xd1,0xd5,0xd0,0x6a,0xcf,0x86,0xe5,0x7b,0xe4,0xd4,0x19,0xe3,0xb4,0xe3,
+       0xe2,0x92,0xe3,0xe1,0x81,0xe3,0x10,0x08,0x05,0xff,0xe6,0xb4,0xbe,0x00,0x05,0xff,
+       0xe6,0xb5,0xb7,0x00,0xd3,0x18,0xe2,0xfe,0xe3,0xe1,0xed,0xe3,0x10,0x09,0x05,0xff,
+       0xf0,0xa3,0xbd,0x9e,0x00,0x05,0xff,0xf0,0xa3,0xbe,0x8e,0x00,0xd2,0x13,0xe1,0x16,
        0xe4,0x10,0x08,0x05,0xff,0xe7,0x81,0xbd,0x00,0x05,0xff,0xe7,0x81,0xb7,0x00,0xd1,
        0x11,0x10,0x08,0x05,0xff,0xe7,0x85,0x85,0x00,0x05,0xff,0xf0,0xa4,0x89,0xa3,0x00,
        0x10,0x08,0x05,0xff,0xe7,0x86,0x9c,0x00,0x05,0xff,0xe4,0x8e,0xab,0x00,0xcf,0x86,
-       0xe5,0xb8,0xe6,0xd4,0x1a,0xe3,0xf0,0xe5,0xe2,0xd6,0xe5,0xe1,0xc3,0xe5,0x10,0x08,
+       0xe5,0x18,0xe6,0xd4,0x1a,0xe3,0x50,0xe5,0xe2,0x36,0xe5,0xe1,0x23,0xe5,0x10,0x08,
        0x05,0xff,0xe7,0x9b,0xb4,0x00,0x05,0xff,0xf0,0xa5,0x83,0xb3,0x00,0xd3,0x16,0xe2,
-       0x38,0xe6,0xe1,0x26,0xe6,0x10,0x08,0x05,0xff,0xe7,0xa3,0x8c,0x00,0x05,0xff,0xe4,
-       0x83,0xa3,0x00,0xd2,0x13,0xe1,0x54,0xe6,0x10,0x08,0x05,0xff,0xe4,0x84,0xaf,0x00,
+       0x98,0xe5,0xe1,0x86,0xe5,0x10,0x08,0x05,0xff,0xe7,0xa3,0x8c,0x00,0x05,0xff,0xe4,
+       0x83,0xa3,0x00,0xd2,0x13,0xe1,0xb4,0xe5,0x10,0x08,0x05,0xff,0xe4,0x84,0xaf,0x00,
        0x05,0xff,0xe7,0xa9,0x80,0x00,0xd1,0x12,0x10,0x09,0x05,0xff,0xf0,0xa5,0xa5,0xbc,
        0x00,0x05,0xff,0xf0,0xa5,0xaa,0xa7,0x00,0x10,0x09,0x05,0xff,0xf0,0xa5,0xaa,0xa7,
-       0x00,0x05,0xff,0xe7,0xaa,0xae,0x00,0xe0,0x6a,0xe9,0xcf,0x86,0xd5,0x1d,0xe4,0xdf,
-       0xe7,0xe3,0x9b,0xe7,0xe2,0x79,0xe7,0xe1,0x68,0xe7,0x10,0x09,0x05,0xff,0xf0,0xa3,
-       0x8d,0x9f,0x00,0x05,0xff,0xe4,0x8f,0x95,0x00,0xd4,0x19,0xe3,0x86,0xe8,0xe2,0x62,
-       0xe8,0xe1,0x51,0xe8,0x10,0x08,0x05,0xff,0xe8,0x8d,0x93,0x00,0x05,0xff,0xe8,0x8f,
-       0x8a,0x00,0xd3,0x18,0xe2,0xd1,0xe8,0xe1,0xc0,0xe8,0x10,0x09,0x05,0xff,0xf0,0xa6,
-       0xbe,0xb1,0x00,0x05,0xff,0xf0,0xa7,0x83,0x92,0x00,0xd2,0x13,0xe1,0xe9,0xe8,0x10,
+       0x00,0x05,0xff,0xe7,0xaa,0xae,0x00,0xe0,0xca,0xe8,0xcf,0x86,0xd5,0x1d,0xe4,0x3f,
+       0xe7,0xe3,0xfb,0xe6,0xe2,0xd9,0xe6,0xe1,0xc8,0xe6,0x10,0x09,0x05,0xff,0xf0,0xa3,
+       0x8d,0x9f,0x00,0x05,0xff,0xe4,0x8f,0x95,0x00,0xd4,0x19,0xe3,0xe6,0xe7,0xe2,0xc2,
+       0xe7,0xe1,0xb1,0xe7,0x10,0x08,0x05,0xff,0xe8,0x8d,0x93,0x00,0x05,0xff,0xe8,0x8f,
+       0x8a,0x00,0xd3,0x18,0xe2,0x31,0xe8,0xe1,0x20,0xe8,0x10,0x09,0x05,0xff,0xf0,0xa6,
+       0xbe,0xb1,0x00,0x05,0xff,0xf0,0xa7,0x83,0x92,0x00,0xd2,0x13,0xe1,0x49,0xe8,0x10,
        0x08,0x05,0xff,0xe8,0x9a,0x88,0x00,0x05,0xff,0xe8,0x9c,0x8e,0x00,0xd1,0x10,0x10,
        0x08,0x05,0xff,0xe8,0x9c,0xa8,0x00,0x05,0xff,0xe8,0x9d,0xab,0x00,0x10,0x08,0x05,
        0xff,0xe8,0x9e,0x86,0x00,0x05,0xff,0xe4,0xb5,0x97,0x00,0x00,0x00,0x00,0x00,0x00,
        /* nfdi_30200 */
-       0x57,0x04,0x01,0x00,0xc6,0xd5,0x16,0xe4,0x82,0x53,0xe3,0xbb,0x4e,0xe2,0x34,0x49,
-       0xc1,0xe0,0x60,0x47,0xcf,0x86,0x65,0x44,0x47,0x01,0x00,0xd4,0x2a,0xe3,0x1c,0x9a,
-       0xe2,0xcb,0x99,0xe1,0x9e,0x87,0xe0,0xf8,0x6a,0xcf,0x86,0xc5,0xe4,0x57,0x63,0xe3,
-       0xa2,0x5e,0xe2,0x38,0x5c,0xe1,0x6b,0x5b,0xe0,0x30,0x5b,0xcf,0x86,0xe5,0xf5,0x5a,
-       0x64,0xd8,0x5a,0x0b,0x00,0x83,0xe2,0xea,0xf0,0xe1,0xc3,0xed,0xe0,0x40,0xec,0xcf,
-       0x86,0xd5,0x31,0xc4,0xe3,0xbb,0xc6,0xe2,0x94,0xc4,0xe1,0x75,0xc3,0xe0,0x05,0xba,
-       0xcf,0x86,0xe5,0xf8,0xb5,0xe4,0xf1,0xb4,0xe3,0xe2,0xb3,0xe2,0x39,0xb3,0xe1,0x14,
-       0xb3,0xe0,0xed,0xb2,0xcf,0x86,0xe5,0xba,0xb2,0x94,0x07,0x63,0xa5,0xb2,0x07,0x00,
-       0x07,0x00,0xe4,0xac,0xeb,0xd3,0x08,0xcf,0x86,0xcf,0x06,0x05,0x00,0xd2,0x0b,0xe1,
-       0xbb,0xd8,0xcf,0x86,0xcf,0x06,0x05,0x00,0xd1,0x0e,0xe0,0xaa,0xd9,0xcf,0x86,0xe5,
-       0x6f,0xd9,0xcf,0x06,0x11,0x00,0xd0,0x0b,0xcf,0x86,0xe5,0xaa,0xd9,0xcf,0x06,0x13,
-       0x00,0xcf,0x86,0xd5,0x06,0xcf,0x06,0x00,0x00,0xe4,0x45,0xeb,0xe3,0x2e,0xea,0xd2,
-       0xa0,0xe1,0xe4,0xdd,0xd0,0x21,0xcf,0x86,0xe5,0xe5,0xda,0xe4,0x61,0xda,0xe3,0x1f,
-       0xda,0xe2,0xfe,0xd9,0xe1,0xec,0xd9,0x10,0x08,0x05,0xff,0xe4,0xb8,0xbd,0x00,0x05,
-       0xff,0xe4,0xb8,0xb8,0x00,0xcf,0x86,0xd5,0x1c,0xe4,0x41,0xdc,0xe3,0x00,0xdc,0xe2,
-       0xdf,0xdb,0xe1,0xce,0xdb,0x10,0x08,0x05,0xff,0xe5,0x92,0xa2,0x00,0x05,0xff,0xe5,
-       0x93,0xb6,0x00,0xd4,0x34,0xd3,0x18,0xe2,0xc8,0xdc,0xe1,0xb7,0xdc,0x10,0x09,0x05,
-       0xff,0xf0,0xa1,0x9a,0xa8,0x00,0x05,0xff,0xf0,0xa1,0x9b,0xaa,0x00,0xe2,0xe8,0xdc,
-       0x91,0x11,0x10,0x09,0x05,0xff,0xf0,0xa1,0x8d,0xaa,0x00,0x05,0xff,0xe5,0xac,0x88,
-       0x00,0x05,0xff,0xe5,0xac,0xbe,0x00,0xe3,0x2e,0xdd,0xd2,0x14,0xe1,0xfd,0xdc,0x10,
-       0x08,0x05,0xff,0xe5,0xaf,0xb3,0x00,0x05,0xff,0xf0,0xa1,0xac,0x98,0x00,0xe1,0x09,
-       0xdd,0x10,0x08,0x05,0xff,0xe5,0xbc,0xb3,0x00,0x05,0xff,0xe5,0xb0,0xa2,0x00,0xd1,
-       0xd5,0xd0,0x6a,0xcf,0x86,0xe5,0x5e,0xe2,0xd4,0x19,0xe3,0x97,0xe1,0xe2,0x75,0xe1,
-       0xe1,0x64,0xe1,0x10,0x08,0x05,0xff,0xe6,0xb4,0xbe,0x00,0x05,0xff,0xe6,0xb5,0xb7,
-       0x00,0xd3,0x18,0xe2,0xe1,0xe1,0xe1,0xd0,0xe1,0x10,0x09,0x05,0xff,0xf0,0xa3,0xbd,
-       0x9e,0x00,0x05,0xff,0xf0,0xa3,0xbe,0x8e,0x00,0xd2,0x13,0xe1,0xf9,0xe1,0x10,0x08,
-       0x05,0xff,0xe7,0x81,0xbd,0x00,0x05,0xff,0xe7,0x81,0xb7,0x00,0xd1,0x11,0x10,0x08,
-       0x05,0xff,0xe7,0x85,0x85,0x00,0x05,0xff,0xf0,0xa4,0x89,0xa3,0x00,0x10,0x08,0x05,
-       0xff,0xe7,0x86,0x9c,0x00,0x05,0xff,0xe4,0x8e,0xab,0x00,0xcf,0x86,0xe5,0xfb,0xe3,
-       0xd4,0x1a,0xe3,0x33,0xe3,0xe2,0x19,0xe3,0xe1,0x06,0xe3,0x10,0x08,0x05,0xff,0xe7,
-       0x9b,0xb4,0x00,0x05,0xff,0xf0,0xa5,0x83,0xb3,0x00,0xd3,0x16,0xe2,0x7b,0xe3,0xe1,
-       0x69,0xe3,0x10,0x08,0x05,0xff,0xe7,0xa3,0x8c,0x00,0x05,0xff,0xe4,0x83,0xa3,0x00,
-       0xd2,0x13,0xe1,0x97,0xe3,0x10,0x08,0x05,0xff,0xe4,0x84,0xaf,0x00,0x05,0xff,0xe7,
-       0xa9,0x80,0x00,0xd1,0x12,0x10,0x09,0x05,0xff,0xf0,0xa5,0xa5,0xbc,0x00,0x05,0xff,
-       0xf0,0xa5,0xaa,0xa7,0x00,0x10,0x09,0x05,0xff,0xf0,0xa5,0xaa,0xa7,0x00,0x05,0xff,
-       0xe7,0xaa,0xae,0x00,0xe0,0xad,0xe6,0xcf,0x86,0xd5,0x1d,0xe4,0x22,0xe5,0xe3,0xde,
-       0xe4,0xe2,0xbc,0xe4,0xe1,0xab,0xe4,0x10,0x09,0x05,0xff,0xf0,0xa3,0x8d,0x9f,0x00,
-       0x05,0xff,0xe4,0x8f,0x95,0x00,0xd4,0x19,0xe3,0xc9,0xe5,0xe2,0xa5,0xe5,0xe1,0x94,
-       0xe5,0x10,0x08,0x05,0xff,0xe8,0x8d,0x93,0x00,0x05,0xff,0xe8,0x8f,0x8a,0x00,0xd3,
-       0x18,0xe2,0x14,0xe6,0xe1,0x03,0xe6,0x10,0x09,0x05,0xff,0xf0,0xa6,0xbe,0xb1,0x00,
-       0x05,0xff,0xf0,0xa7,0x83,0x92,0x00,0xd2,0x13,0xe1,0x2c,0xe6,0x10,0x08,0x05,0xff,
-       0xe8,0x9a,0x88,0x00,0x05,0xff,0xe8,0x9c,0x8e,0x00,0xd1,0x10,0x10,0x08,0x05,0xff,
-       0xe8,0x9c,0xa8,0x00,0x05,0xff,0xe8,0x9d,0xab,0x00,0x10,0x08,0x05,0xff,0xe8,0x9e,
-       0x86,0x00,0x05,0xff,0xe4,0xb5,0x97,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+       0x57,0x04,0x01,0x00,0xc6,0xd5,0x13,0xe4,0x68,0x53,0xe3,0xa2,0x4e,0xe2,0x1b,0x49,
+       0xc1,0xe0,0x47,0x47,0xcf,0x06,0x01,0x00,0xd4,0x2a,0xe3,0x99,0x99,0xe2,0x48,0x99,
+       0xe1,0x50,0x87,0xe0,0xe0,0x6a,0xcf,0x86,0xc5,0xe4,0x3f,0x63,0xe3,0x8a,0x5e,0xe2,
+       0x20,0x5c,0xe1,0x53,0x5b,0xe0,0x18,0x5b,0xcf,0x86,0xe5,0xdd,0x5a,0x64,0xc0,0x5a,
+       0x0b,0x00,0x83,0xe2,0x3c,0xf0,0xe1,0x26,0xed,0xe0,0xa3,0xeb,0xcf,0x86,0xd5,0x31,
+       0xc4,0xe3,0x23,0xc6,0xe2,0xfc,0xc3,0xe1,0xdd,0xc2,0xe0,0x6d,0xb9,0xcf,0x86,0xe5,
+       0x60,0xb5,0xe4,0x59,0xb4,0xe3,0x4a,0xb3,0xe2,0xa1,0xb2,0xe1,0x7c,0xb2,0xe0,0x55,
+       0xb2,0xcf,0x86,0xe5,0x22,0xb2,0x94,0x07,0x63,0x0d,0xb2,0x07,0x00,0x07,0x00,0xe4,
+       0x0f,0xeb,0xd3,0x08,0xcf,0x86,0xcf,0x06,0x05,0x00,0xd2,0x0b,0xe1,0x1e,0xd8,0xcf,
+       0x86,0xcf,0x06,0x05,0x00,0xd1,0x0e,0xe0,0x0d,0xd9,0xcf,0x86,0xe5,0xd2,0xd8,0xcf,
+       0x06,0x11,0x00,0xd0,0x0b,0xcf,0x86,0xe5,0x0d,0xd9,0xcf,0x06,0x13,0x00,0xcf,0x86,
+       0xd5,0x06,0xcf,0x06,0x00,0x00,0xe4,0xa8,0xea,0xe3,0x91,0xe9,0xd2,0xa0,0xe1,0x47,
+       0xdd,0xd0,0x21,0xcf,0x86,0xe5,0x48,0xda,0xe4,0xc4,0xd9,0xe3,0x82,0xd9,0xe2,0x61,
+       0xd9,0xe1,0x4f,0xd9,0x10,0x08,0x05,0xff,0xe4,0xb8,0xbd,0x00,0x05,0xff,0xe4,0xb8,
+       0xb8,0x00,0xcf,0x86,0xd5,0x1c,0xe4,0xa4,0xdb,0xe3,0x63,0xdb,0xe2,0x42,0xdb,0xe1,
+       0x31,0xdb,0x10,0x08,0x05,0xff,0xe5,0x92,0xa2,0x00,0x05,0xff,0xe5,0x93,0xb6,0x00,
+       0xd4,0x34,0xd3,0x18,0xe2,0x2b,0xdc,0xe1,0x1a,0xdc,0x10,0x09,0x05,0xff,0xf0,0xa1,
+       0x9a,0xa8,0x00,0x05,0xff,0xf0,0xa1,0x9b,0xaa,0x00,0xe2,0x4b,0xdc,0x91,0x11,0x10,
+       0x09,0x05,0xff,0xf0,0xa1,0x8d,0xaa,0x00,0x05,0xff,0xe5,0xac,0x88,0x00,0x05,0xff,
+       0xe5,0xac,0xbe,0x00,0xe3,0x91,0xdc,0xd2,0x14,0xe1,0x60,0xdc,0x10,0x08,0x05,0xff,
+       0xe5,0xaf,0xb3,0x00,0x05,0xff,0xf0,0xa1,0xac,0x98,0x00,0xe1,0x6c,0xdc,0x10,0x08,
+       0x05,0xff,0xe5,0xbc,0xb3,0x00,0x05,0xff,0xe5,0xb0,0xa2,0x00,0xd1,0xd5,0xd0,0x6a,
+       0xcf,0x86,0xe5,0xc1,0xe1,0xd4,0x19,0xe3,0xfa,0xe0,0xe2,0xd8,0xe0,0xe1,0xc7,0xe0,
+       0x10,0x08,0x05,0xff,0xe6,0xb4,0xbe,0x00,0x05,0xff,0xe6,0xb5,0xb7,0x00,0xd3,0x18,
+       0xe2,0x44,0xe1,0xe1,0x33,0xe1,0x10,0x09,0x05,0xff,0xf0,0xa3,0xbd,0x9e,0x00,0x05,
+       0xff,0xf0,0xa3,0xbe,0x8e,0x00,0xd2,0x13,0xe1,0x5c,0xe1,0x10,0x08,0x05,0xff,0xe7,
+       0x81,0xbd,0x00,0x05,0xff,0xe7,0x81,0xb7,0x00,0xd1,0x11,0x10,0x08,0x05,0xff,0xe7,
+       0x85,0x85,0x00,0x05,0xff,0xf0,0xa4,0x89,0xa3,0x00,0x10,0x08,0x05,0xff,0xe7,0x86,
+       0x9c,0x00,0x05,0xff,0xe4,0x8e,0xab,0x00,0xcf,0x86,0xe5,0x5e,0xe3,0xd4,0x1a,0xe3,
+       0x96,0xe2,0xe2,0x7c,0xe2,0xe1,0x69,0xe2,0x10,0x08,0x05,0xff,0xe7,0x9b,0xb4,0x00,
+       0x05,0xff,0xf0,0xa5,0x83,0xb3,0x00,0xd3,0x16,0xe2,0xde,0xe2,0xe1,0xcc,0xe2,0x10,
+       0x08,0x05,0xff,0xe7,0xa3,0x8c,0x00,0x05,0xff,0xe4,0x83,0xa3,0x00,0xd2,0x13,0xe1,
+       0xfa,0xe2,0x10,0x08,0x05,0xff,0xe4,0x84,0xaf,0x00,0x05,0xff,0xe7,0xa9,0x80,0x00,
+       0xd1,0x12,0x10,0x09,0x05,0xff,0xf0,0xa5,0xa5,0xbc,0x00,0x05,0xff,0xf0,0xa5,0xaa,
+       0xa7,0x00,0x10,0x09,0x05,0xff,0xf0,0xa5,0xaa,0xa7,0x00,0x05,0xff,0xe7,0xaa,0xae,
+       0x00,0xe0,0x10,0xe6,0xcf,0x86,0xd5,0x1d,0xe4,0x85,0xe4,0xe3,0x41,0xe4,0xe2,0x1f,
+       0xe4,0xe1,0x0e,0xe4,0x10,0x09,0x05,0xff,0xf0,0xa3,0x8d,0x9f,0x00,0x05,0xff,0xe4,
+       0x8f,0x95,0x00,0xd4,0x19,0xe3,0x2c,0xe5,0xe2,0x08,0xe5,0xe1,0xf7,0xe4,0x10,0x08,
+       0x05,0xff,0xe8,0x8d,0x93,0x00,0x05,0xff,0xe8,0x8f,0x8a,0x00,0xd3,0x18,0xe2,0x77,
+       0xe5,0xe1,0x66,0xe5,0x10,0x09,0x05,0xff,0xf0,0xa6,0xbe,0xb1,0x00,0x05,0xff,0xf0,
+       0xa7,0x83,0x92,0x00,0xd2,0x13,0xe1,0x8f,0xe5,0x10,0x08,0x05,0xff,0xe8,0x9a,0x88,
+       0x00,0x05,0xff,0xe8,0x9c,0x8e,0x00,0xd1,0x10,0x10,0x08,0x05,0xff,0xe8,0x9c,0xa8,
+       0x00,0x05,0xff,0xe8,0x9d,0xab,0x00,0x10,0x08,0x05,0xff,0xe8,0x9e,0x86,0x00,0x05,
+       0xff,0xe4,0xb5,0x97,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
        /* nfdicf_c0100 */
        0xd7,0xb0,0x56,0x04,0x01,0x00,0x95,0xa8,0xd4,0x5e,0xd3,0x2e,0xd2,0x16,0xd1,0x0a,
        0x10,0x04,0x01,0x00,0x01,0xff,0x61,0x00,0x10,0x06,0x01,0xff,0x62,0x00,0x01,0xff,
@@ -299,3184 +299,3174 @@ static const unsigned char utf8data[64256] = {
        0xd1,0x0c,0x10,0x06,0x01,0xff,0x74,0x00,0x01,0xff,0x75,0x00,0x10,0x06,0x01,0xff,
        0x76,0x00,0x01,0xff,0x77,0x00,0x92,0x16,0xd1,0x0c,0x10,0x06,0x01,0xff,0x78,0x00,
        0x01,0xff,0x79,0x00,0x10,0x06,0x01,0xff,0x7a,0x00,0x01,0x00,0x01,0x00,0x01,0x00,
-       0xc6,0xe5,0xf9,0x14,0xe4,0x6f,0x0d,0xe3,0x39,0x08,0xe2,0x22,0x01,0xc1,0xd0,0x24,
-       0xcf,0x86,0x55,0x04,0x01,0x00,0xd4,0x07,0x63,0xd8,0x43,0x01,0x00,0x93,0x13,0x52,
-       0x04,0x01,0x00,0x91,0x0b,0x10,0x04,0x01,0x00,0x01,0xff,0xce,0xbc,0x00,0x01,0x00,
-       0x01,0x00,0xcf,0x86,0xe5,0xb3,0x44,0xd4,0x7f,0xd3,0x3f,0xd2,0x20,0xd1,0x10,0x10,
-       0x08,0x01,0xff,0x61,0xcc,0x80,0x00,0x01,0xff,0x61,0xcc,0x81,0x00,0x10,0x08,0x01,
-       0xff,0x61,0xcc,0x82,0x00,0x01,0xff,0x61,0xcc,0x83,0x00,0xd1,0x10,0x10,0x08,0x01,
-       0xff,0x61,0xcc,0x88,0x00,0x01,0xff,0x61,0xcc,0x8a,0x00,0x10,0x07,0x01,0xff,0xc3,
-       0xa6,0x00,0x01,0xff,0x63,0xcc,0xa7,0x00,0xd2,0x20,0xd1,0x10,0x10,0x08,0x01,0xff,
-       0x65,0xcc,0x80,0x00,0x01,0xff,0x65,0xcc,0x81,0x00,0x10,0x08,0x01,0xff,0x65,0xcc,
-       0x82,0x00,0x01,0xff,0x65,0xcc,0x88,0x00,0xd1,0x10,0x10,0x08,0x01,0xff,0x69,0xcc,
-       0x80,0x00,0x01,0xff,0x69,0xcc,0x81,0x00,0x10,0x08,0x01,0xff,0x69,0xcc,0x82,0x00,
-       0x01,0xff,0x69,0xcc,0x88,0x00,0xd3,0x3b,0xd2,0x1f,0xd1,0x0f,0x10,0x07,0x01,0xff,
-       0xc3,0xb0,0x00,0x01,0xff,0x6e,0xcc,0x83,0x00,0x10,0x08,0x01,0xff,0x6f,0xcc,0x80,
-       0x00,0x01,0xff,0x6f,0xcc,0x81,0x00,0xd1,0x10,0x10,0x08,0x01,0xff,0x6f,0xcc,0x82,
-       0x00,0x01,0xff,0x6f,0xcc,0x83,0x00,0x10,0x08,0x01,0xff,0x6f,0xcc,0x88,0x00,0x01,
-       0x00,0xd2,0x1f,0xd1,0x0f,0x10,0x07,0x01,0xff,0xc3,0xb8,0x00,0x01,0xff,0x75,0xcc,
-       0x80,0x00,0x10,0x08,0x01,0xff,0x75,0xcc,0x81,0x00,0x01,0xff,0x75,0xcc,0x82,0x00,
-       0xd1,0x10,0x10,0x08,0x01,0xff,0x75,0xcc,0x88,0x00,0x01,0xff,0x79,0xcc,0x81,0x00,
-       0x10,0x07,0x01,0xff,0xc3,0xbe,0x00,0x01,0xff,0x73,0x73,0x00,0xe1,0xd4,0x03,0xe0,
-       0xeb,0x01,0xcf,0x86,0xd5,0xfb,0xd4,0x80,0xd3,0x40,0xd2,0x20,0xd1,0x10,0x10,0x08,
-       0x01,0xff,0x61,0xcc,0x84,0x00,0x01,0xff,0x61,0xcc,0x84,0x00,0x10,0x08,0x01,0xff,
-       0x61,0xcc,0x86,0x00,0x01,0xff,0x61,0xcc,0x86,0x00,0xd1,0x10,0x10,0x08,0x01,0xff,
-       0x61,0xcc,0xa8,0x00,0x01,0xff,0x61,0xcc,0xa8,0x00,0x10,0x08,0x01,0xff,0x63,0xcc,
-       0x81,0x00,0x01,0xff,0x63,0xcc,0x81,0x00,0xd2,0x20,0xd1,0x10,0x10,0x08,0x01,0xff,
-       0x63,0xcc,0x82,0x00,0x01,0xff,0x63,0xcc,0x82,0x00,0x10,0x08,0x01,0xff,0x63,0xcc,
-       0x87,0x00,0x01,0xff,0x63,0xcc,0x87,0x00,0xd1,0x10,0x10,0x08,0x01,0xff,0x63,0xcc,
-       0x8c,0x00,0x01,0xff,0x63,0xcc,0x8c,0x00,0x10,0x08,0x01,0xff,0x64,0xcc,0x8c,0x00,
-       0x01,0xff,0x64,0xcc,0x8c,0x00,0xd3,0x3b,0xd2,0x1b,0xd1,0x0b,0x10,0x07,0x01,0xff,
-       0xc4,0x91,0x00,0x01,0x00,0x10,0x08,0x01,0xff,0x65,0xcc,0x84,0x00,0x01,0xff,0x65,
-       0xcc,0x84,0x00,0xd1,0x10,0x10,0x08,0x01,0xff,0x65,0xcc,0x86,0x00,0x01,0xff,0x65,
-       0xcc,0x86,0x00,0x10,0x08,0x01,0xff,0x65,0xcc,0x87,0x00,0x01,0xff,0x65,0xcc,0x87,
-       0x00,0xd2,0x20,0xd1,0x10,0x10,0x08,0x01,0xff,0x65,0xcc,0xa8,0x00,0x01,0xff,0x65,
-       0xcc,0xa8,0x00,0x10,0x08,0x01,0xff,0x65,0xcc,0x8c,0x00,0x01,0xff,0x65,0xcc,0x8c,
-       0x00,0xd1,0x10,0x10,0x08,0x01,0xff,0x67,0xcc,0x82,0x00,0x01,0xff,0x67,0xcc,0x82,
-       0x00,0x10,0x08,0x01,0xff,0x67,0xcc,0x86,0x00,0x01,0xff,0x67,0xcc,0x86,0x00,0xd4,
-       0x7b,0xd3,0x3b,0xd2,0x20,0xd1,0x10,0x10,0x08,0x01,0xff,0x67,0xcc,0x87,0x00,0x01,
-       0xff,0x67,0xcc,0x87,0x00,0x10,0x08,0x01,0xff,0x67,0xcc,0xa7,0x00,0x01,0xff,0x67,
-       0xcc,0xa7,0x00,0xd1,0x10,0x10,0x08,0x01,0xff,0x68,0xcc,0x82,0x00,0x01,0xff,0x68,
-       0xcc,0x82,0x00,0x10,0x07,0x01,0xff,0xc4,0xa7,0x00,0x01,0x00,0xd2,0x20,0xd1,0x10,
-       0x10,0x08,0x01,0xff,0x69,0xcc,0x83,0x00,0x01,0xff,0x69,0xcc,0x83,0x00,0x10,0x08,
-       0x01,0xff,0x69,0xcc,0x84,0x00,0x01,0xff,0x69,0xcc,0x84,0x00,0xd1,0x10,0x10,0x08,
-       0x01,0xff,0x69,0xcc,0x86,0x00,0x01,0xff,0x69,0xcc,0x86,0x00,0x10,0x08,0x01,0xff,
-       0x69,0xcc,0xa8,0x00,0x01,0xff,0x69,0xcc,0xa8,0x00,0xd3,0x37,0xd2,0x17,0xd1,0x0c,
-       0x10,0x08,0x01,0xff,0x69,0xcc,0x87,0x00,0x01,0x00,0x10,0x07,0x01,0xff,0xc4,0xb3,
-       0x00,0x01,0x00,0xd1,0x10,0x10,0x08,0x01,0xff,0x6a,0xcc,0x82,0x00,0x01,0xff,0x6a,
-       0xcc,0x82,0x00,0x10,0x08,0x01,0xff,0x6b,0xcc,0xa7,0x00,0x01,0xff,0x6b,0xcc,0xa7,
-       0x00,0xd2,0x1c,0xd1,0x0c,0x10,0x04,0x01,0x00,0x01,0xff,0x6c,0xcc,0x81,0x00,0x10,
-       0x08,0x01,0xff,0x6c,0xcc,0x81,0x00,0x01,0xff,0x6c,0xcc,0xa7,0x00,0xd1,0x10,0x10,
-       0x08,0x01,0xff,0x6c,0xcc,0xa7,0x00,0x01,0xff,0x6c,0xcc,0x8c,0x00,0x10,0x08,0x01,
-       0xff,0x6c,0xcc,0x8c,0x00,0x01,0xff,0xc5,0x80,0x00,0xcf,0x86,0xd5,0xed,0xd4,0x72,
-       0xd3,0x37,0xd2,0x17,0xd1,0x0b,0x10,0x04,0x01,0x00,0x01,0xff,0xc5,0x82,0x00,0x10,
-       0x04,0x01,0x00,0x01,0xff,0x6e,0xcc,0x81,0x00,0xd1,0x10,0x10,0x08,0x01,0xff,0x6e,
-       0xcc,0x81,0x00,0x01,0xff,0x6e,0xcc,0xa7,0x00,0x10,0x08,0x01,0xff,0x6e,0xcc,0xa7,
-       0x00,0x01,0xff,0x6e,0xcc,0x8c,0x00,0xd2,0x1b,0xd1,0x10,0x10,0x08,0x01,0xff,0x6e,
-       0xcc,0x8c,0x00,0x01,0xff,0xca,0xbc,0x6e,0x00,0x10,0x07,0x01,0xff,0xc5,0x8b,0x00,
-       0x01,0x00,0xd1,0x10,0x10,0x08,0x01,0xff,0x6f,0xcc,0x84,0x00,0x01,0xff,0x6f,0xcc,
-       0x84,0x00,0x10,0x08,0x01,0xff,0x6f,0xcc,0x86,0x00,0x01,0xff,0x6f,0xcc,0x86,0x00,
-       0xd3,0x3b,0xd2,0x1b,0xd1,0x10,0x10,0x08,0x01,0xff,0x6f,0xcc,0x8b,0x00,0x01,0xff,
-       0x6f,0xcc,0x8b,0x00,0x10,0x07,0x01,0xff,0xc5,0x93,0x00,0x01,0x00,0xd1,0x10,0x10,
-       0x08,0x01,0xff,0x72,0xcc,0x81,0x00,0x01,0xff,0x72,0xcc,0x81,0x00,0x10,0x08,0x01,
-       0xff,0x72,0xcc,0xa7,0x00,0x01,0xff,0x72,0xcc,0xa7,0x00,0xd2,0x20,0xd1,0x10,0x10,
-       0x08,0x01,0xff,0x72,0xcc,0x8c,0x00,0x01,0xff,0x72,0xcc,0x8c,0x00,0x10,0x08,0x01,
-       0xff,0x73,0xcc,0x81,0x00,0x01,0xff,0x73,0xcc,0x81,0x00,0xd1,0x10,0x10,0x08,0x01,
-       0xff,0x73,0xcc,0x82,0x00,0x01,0xff,0x73,0xcc,0x82,0x00,0x10,0x08,0x01,0xff,0x73,
-       0xcc,0xa7,0x00,0x01,0xff,0x73,0xcc,0xa7,0x00,0xd4,0x7b,0xd3,0x3b,0xd2,0x20,0xd1,
-       0x10,0x10,0x08,0x01,0xff,0x73,0xcc,0x8c,0x00,0x01,0xff,0x73,0xcc,0x8c,0x00,0x10,
-       0x08,0x01,0xff,0x74,0xcc,0xa7,0x00,0x01,0xff,0x74,0xcc,0xa7,0x00,0xd1,0x10,0x10,
-       0x08,0x01,0xff,0x74,0xcc,0x8c,0x00,0x01,0xff,0x74,0xcc,0x8c,0x00,0x10,0x07,0x01,
-       0xff,0xc5,0xa7,0x00,0x01,0x00,0xd2,0x20,0xd1,0x10,0x10,0x08,0x01,0xff,0x75,0xcc,
-       0x83,0x00,0x01,0xff,0x75,0xcc,0x83,0x00,0x10,0x08,0x01,0xff,0x75,0xcc,0x84,0x00,
-       0x01,0xff,0x75,0xcc,0x84,0x00,0xd1,0x10,0x10,0x08,0x01,0xff,0x75,0xcc,0x86,0x00,
-       0x01,0xff,0x75,0xcc,0x86,0x00,0x10,0x08,0x01,0xff,0x75,0xcc,0x8a,0x00,0x01,0xff,
-       0x75,0xcc,0x8a,0x00,0xd3,0x40,0xd2,0x20,0xd1,0x10,0x10,0x08,0x01,0xff,0x75,0xcc,
-       0x8b,0x00,0x01,0xff,0x75,0xcc,0x8b,0x00,0x10,0x08,0x01,0xff,0x75,0xcc,0xa8,0x00,
-       0x01,0xff,0x75,0xcc,0xa8,0x00,0xd1,0x10,0x10,0x08,0x01,0xff,0x77,0xcc,0x82,0x00,
-       0x01,0xff,0x77,0xcc,0x82,0x00,0x10,0x08,0x01,0xff,0x79,0xcc,0x82,0x00,0x01,0xff,
-       0x79,0xcc,0x82,0x00,0xd2,0x20,0xd1,0x10,0x10,0x08,0x01,0xff,0x79,0xcc,0x88,0x00,
-       0x01,0xff,0x7a,0xcc,0x81,0x00,0x10,0x08,0x01,0xff,0x7a,0xcc,0x81,0x00,0x01,0xff,
-       0x7a,0xcc,0x87,0x00,0xd1,0x10,0x10,0x08,0x01,0xff,0x7a,0xcc,0x87,0x00,0x01,0xff,
-       0x7a,0xcc,0x8c,0x00,0x10,0x08,0x01,0xff,0x7a,0xcc,0x8c,0x00,0x01,0xff,0x73,0x00,
-       0xe0,0x65,0x01,0xcf,0x86,0xd5,0xb4,0xd4,0x5a,0xd3,0x2f,0xd2,0x16,0xd1,0x0b,0x10,
-       0x04,0x01,0x00,0x01,0xff,0xc9,0x93,0x00,0x10,0x07,0x01,0xff,0xc6,0x83,0x00,0x01,
-       0x00,0xd1,0x0b,0x10,0x07,0x01,0xff,0xc6,0x85,0x00,0x01,0x00,0x10,0x07,0x01,0xff,
-       0xc9,0x94,0x00,0x01,0xff,0xc6,0x88,0x00,0xd2,0x19,0xd1,0x0b,0x10,0x04,0x01,0x00,
-       0x01,0xff,0xc9,0x96,0x00,0x10,0x07,0x01,0xff,0xc9,0x97,0x00,0x01,0xff,0xc6,0x8c,
-       0x00,0x51,0x04,0x01,0x00,0x10,0x07,0x01,0xff,0xc7,0x9d,0x00,0x01,0xff,0xc9,0x99,
-       0x00,0xd3,0x32,0xd2,0x19,0xd1,0x0e,0x10,0x07,0x01,0xff,0xc9,0x9b,0x00,0x01,0xff,
-       0xc6,0x92,0x00,0x10,0x04,0x01,0x00,0x01,0xff,0xc9,0xa0,0x00,0xd1,0x0b,0x10,0x07,
-       0x01,0xff,0xc9,0xa3,0x00,0x01,0x00,0x10,0x07,0x01,0xff,0xc9,0xa9,0x00,0x01,0xff,
-       0xc9,0xa8,0x00,0xd2,0x0f,0x91,0x0b,0x10,0x07,0x01,0xff,0xc6,0x99,0x00,0x01,0x00,
-       0x01,0x00,0xd1,0x0e,0x10,0x07,0x01,0xff,0xc9,0xaf,0x00,0x01,0xff,0xc9,0xb2,0x00,
-       0x10,0x04,0x01,0x00,0x01,0xff,0xc9,0xb5,0x00,0xd4,0x5d,0xd3,0x34,0xd2,0x1b,0xd1,
-       0x10,0x10,0x08,0x01,0xff,0x6f,0xcc,0x9b,0x00,0x01,0xff,0x6f,0xcc,0x9b,0x00,0x10,
-       0x07,0x01,0xff,0xc6,0xa3,0x00,0x01,0x00,0xd1,0x0b,0x10,0x07,0x01,0xff,0xc6,0xa5,
-       0x00,0x01,0x00,0x10,0x07,0x01,0xff,0xca,0x80,0x00,0x01,0xff,0xc6,0xa8,0x00,0xd2,
-       0x0f,0x91,0x0b,0x10,0x04,0x01,0x00,0x01,0xff,0xca,0x83,0x00,0x01,0x00,0xd1,0x0b,
-       0x10,0x07,0x01,0xff,0xc6,0xad,0x00,0x01,0x00,0x10,0x07,0x01,0xff,0xca,0x88,0x00,
-       0x01,0xff,0x75,0xcc,0x9b,0x00,0xd3,0x33,0xd2,0x1d,0xd1,0x0f,0x10,0x08,0x01,0xff,
-       0x75,0xcc,0x9b,0x00,0x01,0xff,0xca,0x8a,0x00,0x10,0x07,0x01,0xff,0xca,0x8b,0x00,
-       0x01,0xff,0xc6,0xb4,0x00,0xd1,0x0b,0x10,0x04,0x01,0x00,0x01,0xff,0xc6,0xb6,0x00,
-       0x10,0x04,0x01,0x00,0x01,0xff,0xca,0x92,0x00,0xd2,0x0f,0x91,0x0b,0x10,0x07,0x01,
-       0xff,0xc6,0xb9,0x00,0x01,0x00,0x01,0x00,0x91,0x0b,0x10,0x07,0x01,0xff,0xc6,0xbd,
-       0x00,0x01,0x00,0x01,0x00,0xcf,0x86,0xd5,0xd4,0xd4,0x44,0xd3,0x16,0x52,0x04,0x01,
-       0x00,0x51,0x07,0x01,0xff,0xc7,0x86,0x00,0x10,0x04,0x01,0x00,0x01,0xff,0xc7,0x89,
-       0x00,0xd2,0x12,0x91,0x0b,0x10,0x07,0x01,0xff,0xc7,0x89,0x00,0x01,0x00,0x01,0xff,
-       0xc7,0x8c,0x00,0xd1,0x0c,0x10,0x04,0x01,0x00,0x01,0xff,0x61,0xcc,0x8c,0x00,0x10,
-       0x08,0x01,0xff,0x61,0xcc,0x8c,0x00,0x01,0xff,0x69,0xcc,0x8c,0x00,0xd3,0x46,0xd2,
-       0x20,0xd1,0x10,0x10,0x08,0x01,0xff,0x69,0xcc,0x8c,0x00,0x01,0xff,0x6f,0xcc,0x8c,
-       0x00,0x10,0x08,0x01,0xff,0x6f,0xcc,0x8c,0x00,0x01,0xff,0x75,0xcc,0x8c,0x00,0xd1,
-       0x12,0x10,0x08,0x01,0xff,0x75,0xcc,0x8c,0x00,0x01,0xff,0x75,0xcc,0x88,0xcc,0x84,
-       0x00,0x10,0x0a,0x01,0xff,0x75,0xcc,0x88,0xcc,0x84,0x00,0x01,0xff,0x75,0xcc,0x88,
-       0xcc,0x81,0x00,0xd2,0x28,0xd1,0x14,0x10,0x0a,0x01,0xff,0x75,0xcc,0x88,0xcc,0x81,
-       0x00,0x01,0xff,0x75,0xcc,0x88,0xcc,0x8c,0x00,0x10,0x0a,0x01,0xff,0x75,0xcc,0x88,
-       0xcc,0x8c,0x00,0x01,0xff,0x75,0xcc,0x88,0xcc,0x80,0x00,0xd1,0x0e,0x10,0x0a,0x01,
-       0xff,0x75,0xcc,0x88,0xcc,0x80,0x00,0x01,0x00,0x10,0x0a,0x01,0xff,0x61,0xcc,0x88,
-       0xcc,0x84,0x00,0x01,0xff,0x61,0xcc,0x88,0xcc,0x84,0x00,0xd4,0x87,0xd3,0x41,0xd2,
-       0x26,0xd1,0x14,0x10,0x0a,0x01,0xff,0x61,0xcc,0x87,0xcc,0x84,0x00,0x01,0xff,0x61,
-       0xcc,0x87,0xcc,0x84,0x00,0x10,0x09,0x01,0xff,0xc3,0xa6,0xcc,0x84,0x00,0x01,0xff,
-       0xc3,0xa6,0xcc,0x84,0x00,0xd1,0x0b,0x10,0x07,0x01,0xff,0xc7,0xa5,0x00,0x01,0x00,
-       0x10,0x08,0x01,0xff,0x67,0xcc,0x8c,0x00,0x01,0xff,0x67,0xcc,0x8c,0x00,0xd2,0x20,
-       0xd1,0x10,0x10,0x08,0x01,0xff,0x6b,0xcc,0x8c,0x00,0x01,0xff,0x6b,0xcc,0x8c,0x00,
-       0x10,0x08,0x01,0xff,0x6f,0xcc,0xa8,0x00,0x01,0xff,0x6f,0xcc,0xa8,0x00,0xd1,0x14,
-       0x10,0x0a,0x01,0xff,0x6f,0xcc,0xa8,0xcc,0x84,0x00,0x01,0xff,0x6f,0xcc,0xa8,0xcc,
-       0x84,0x00,0x10,0x09,0x01,0xff,0xca,0x92,0xcc,0x8c,0x00,0x01,0xff,0xca,0x92,0xcc,
-       0x8c,0x00,0xd3,0x38,0xd2,0x1a,0xd1,0x0f,0x10,0x08,0x01,0xff,0x6a,0xcc,0x8c,0x00,
-       0x01,0xff,0xc7,0xb3,0x00,0x10,0x07,0x01,0xff,0xc7,0xb3,0x00,0x01,0x00,0xd1,0x10,
-       0x10,0x08,0x01,0xff,0x67,0xcc,0x81,0x00,0x01,0xff,0x67,0xcc,0x81,0x00,0x10,0x07,
-       0x04,0xff,0xc6,0x95,0x00,0x04,0xff,0xc6,0xbf,0x00,0xd2,0x24,0xd1,0x10,0x10,0x08,
-       0x04,0xff,0x6e,0xcc,0x80,0x00,0x04,0xff,0x6e,0xcc,0x80,0x00,0x10,0x0a,0x01,0xff,
-       0x61,0xcc,0x8a,0xcc,0x81,0x00,0x01,0xff,0x61,0xcc,0x8a,0xcc,0x81,0x00,0xd1,0x12,
-       0x10,0x09,0x01,0xff,0xc3,0xa6,0xcc,0x81,0x00,0x01,0xff,0xc3,0xa6,0xcc,0x81,0x00,
-       0x10,0x09,0x01,0xff,0xc3,0xb8,0xcc,0x81,0x00,0x01,0xff,0xc3,0xb8,0xcc,0x81,0x00,
-       0xe2,0x31,0x02,0xe1,0xc3,0x44,0xe0,0xc8,0x01,0xcf,0x86,0xd5,0xfb,0xd4,0x80,0xd3,
-       0x40,0xd2,0x20,0xd1,0x10,0x10,0x08,0x01,0xff,0x61,0xcc,0x8f,0x00,0x01,0xff,0x61,
-       0xcc,0x8f,0x00,0x10,0x08,0x01,0xff,0x61,0xcc,0x91,0x00,0x01,0xff,0x61,0xcc,0x91,
-       0x00,0xd1,0x10,0x10,0x08,0x01,0xff,0x65,0xcc,0x8f,0x00,0x01,0xff,0x65,0xcc,0x8f,
-       0x00,0x10,0x08,0x01,0xff,0x65,0xcc,0x91,0x00,0x01,0xff,0x65,0xcc,0x91,0x00,0xd2,
-       0x20,0xd1,0x10,0x10,0x08,0x01,0xff,0x69,0xcc,0x8f,0x00,0x01,0xff,0x69,0xcc,0x8f,
-       0x00,0x10,0x08,0x01,0xff,0x69,0xcc,0x91,0x00,0x01,0xff,0x69,0xcc,0x91,0x00,0xd1,
-       0x10,0x10,0x08,0x01,0xff,0x6f,0xcc,0x8f,0x00,0x01,0xff,0x6f,0xcc,0x8f,0x00,0x10,
-       0x08,0x01,0xff,0x6f,0xcc,0x91,0x00,0x01,0xff,0x6f,0xcc,0x91,0x00,0xd3,0x40,0xd2,
-       0x20,0xd1,0x10,0x10,0x08,0x01,0xff,0x72,0xcc,0x8f,0x00,0x01,0xff,0x72,0xcc,0x8f,
-       0x00,0x10,0x08,0x01,0xff,0x72,0xcc,0x91,0x00,0x01,0xff,0x72,0xcc,0x91,0x00,0xd1,
-       0x10,0x10,0x08,0x01,0xff,0x75,0xcc,0x8f,0x00,0x01,0xff,0x75,0xcc,0x8f,0x00,0x10,
-       0x08,0x01,0xff,0x75,0xcc,0x91,0x00,0x01,0xff,0x75,0xcc,0x91,0x00,0xd2,0x20,0xd1,
-       0x10,0x10,0x08,0x04,0xff,0x73,0xcc,0xa6,0x00,0x04,0xff,0x73,0xcc,0xa6,0x00,0x10,
-       0x08,0x04,0xff,0x74,0xcc,0xa6,0x00,0x04,0xff,0x74,0xcc,0xa6,0x00,0xd1,0x0b,0x10,
-       0x07,0x04,0xff,0xc8,0x9d,0x00,0x04,0x00,0x10,0x08,0x04,0xff,0x68,0xcc,0x8c,0x00,
-       0x04,0xff,0x68,0xcc,0x8c,0x00,0xd4,0x79,0xd3,0x31,0xd2,0x16,0xd1,0x0b,0x10,0x07,
-       0x06,0xff,0xc6,0x9e,0x00,0x07,0x00,0x10,0x07,0x04,0xff,0xc8,0xa3,0x00,0x04,0x00,
-       0xd1,0x0b,0x10,0x07,0x04,0xff,0xc8,0xa5,0x00,0x04,0x00,0x10,0x08,0x04,0xff,0x61,
-       0xcc,0x87,0x00,0x04,0xff,0x61,0xcc,0x87,0x00,0xd2,0x24,0xd1,0x10,0x10,0x08,0x04,
-       0xff,0x65,0xcc,0xa7,0x00,0x04,0xff,0x65,0xcc,0xa7,0x00,0x10,0x0a,0x04,0xff,0x6f,
-       0xcc,0x88,0xcc,0x84,0x00,0x04,0xff,0x6f,0xcc,0x88,0xcc,0x84,0x00,0xd1,0x14,0x10,
-       0x0a,0x04,0xff,0x6f,0xcc,0x83,0xcc,0x84,0x00,0x04,0xff,0x6f,0xcc,0x83,0xcc,0x84,
-       0x00,0x10,0x08,0x04,0xff,0x6f,0xcc,0x87,0x00,0x04,0xff,0x6f,0xcc,0x87,0x00,0xd3,
-       0x27,0xe2,0x21,0x43,0xd1,0x14,0x10,0x0a,0x04,0xff,0x6f,0xcc,0x87,0xcc,0x84,0x00,
-       0x04,0xff,0x6f,0xcc,0x87,0xcc,0x84,0x00,0x10,0x08,0x04,0xff,0x79,0xcc,0x84,0x00,
-       0x04,0xff,0x79,0xcc,0x84,0x00,0xd2,0x13,0x51,0x04,0x08,0x00,0x10,0x08,0x08,0xff,
-       0xe2,0xb1,0xa5,0x00,0x08,0xff,0xc8,0xbc,0x00,0xd1,0x0b,0x10,0x04,0x08,0x00,0x08,
-       0xff,0xc6,0x9a,0x00,0x10,0x08,0x08,0xff,0xe2,0xb1,0xa6,0x00,0x08,0x00,0xcf,0x86,
-       0x95,0x5f,0x94,0x5b,0xd3,0x2f,0xd2,0x16,0xd1,0x0b,0x10,0x04,0x08,0x00,0x08,0xff,
-       0xc9,0x82,0x00,0x10,0x04,0x09,0x00,0x09,0xff,0xc6,0x80,0x00,0xd1,0x0e,0x10,0x07,
-       0x09,0xff,0xca,0x89,0x00,0x09,0xff,0xca,0x8c,0x00,0x10,0x07,0x09,0xff,0xc9,0x87,
-       0x00,0x09,0x00,0xd2,0x16,0xd1,0x0b,0x10,0x07,0x09,0xff,0xc9,0x89,0x00,0x09,0x00,
-       0x10,0x07,0x09,0xff,0xc9,0x8b,0x00,0x09,0x00,0xd1,0x0b,0x10,0x07,0x09,0xff,0xc9,
-       0x8d,0x00,0x09,0x00,0x10,0x07,0x09,0xff,0xc9,0x8f,0x00,0x09,0x00,0x01,0x00,0x01,
-       0x00,0xd1,0x8b,0xd0,0x0c,0xcf,0x86,0xe5,0x10,0x43,0x64,0xef,0x42,0x01,0xe6,0xcf,
-       0x86,0xd5,0x2a,0xe4,0x99,0x43,0xe3,0x7f,0x43,0xd2,0x11,0xe1,0x5e,0x43,0x10,0x07,
-       0x01,0xff,0xcc,0x80,0x00,0x01,0xff,0xcc,0x81,0x00,0xe1,0x65,0x43,0x10,0x09,0x01,
-       0xff,0xcc,0x88,0xcc,0x81,0x00,0x01,0xff,0xce,0xb9,0x00,0xd4,0x0f,0x93,0x0b,0x92,
-       0x07,0x61,0xab,0x43,0x01,0xea,0x06,0xe6,0x06,0xe6,0xd3,0x2c,0xd2,0x16,0xd1,0x0b,
-       0x10,0x07,0x0a,0xff,0xcd,0xb1,0x00,0x0a,0x00,0x10,0x07,0x0a,0xff,0xcd,0xb3,0x00,
-       0x0a,0x00,0xd1,0x0b,0x10,0x07,0x01,0xff,0xca,0xb9,0x00,0x01,0x00,0x10,0x07,0x0a,
-       0xff,0xcd,0xb7,0x00,0x0a,0x00,0xd2,0x07,0x61,0x97,0x43,0x00,0x00,0x51,0x04,0x09,
-       0x00,0x10,0x06,0x01,0xff,0x3b,0x00,0x10,0xff,0xcf,0xb3,0x00,0xe0,0x31,0x01,0xcf,
-       0x86,0xd5,0xd3,0xd4,0x5f,0xd3,0x21,0x52,0x04,0x00,0x00,0xd1,0x0d,0x10,0x04,0x01,
-       0x00,0x01,0xff,0xc2,0xa8,0xcc,0x81,0x00,0x10,0x09,0x01,0xff,0xce,0xb1,0xcc,0x81,
-       0x00,0x01,0xff,0xc2,0xb7,0x00,0xd2,0x1f,0xd1,0x12,0x10,0x09,0x01,0xff,0xce,0xb5,
-       0xcc,0x81,0x00,0x01,0xff,0xce,0xb7,0xcc,0x81,0x00,0x10,0x09,0x01,0xff,0xce,0xb9,
-       0xcc,0x81,0x00,0x00,0x00,0xd1,0x0d,0x10,0x09,0x01,0xff,0xce,0xbf,0xcc,0x81,0x00,
-       0x00,0x00,0x10,0x09,0x01,0xff,0xcf,0x85,0xcc,0x81,0x00,0x01,0xff,0xcf,0x89,0xcc,
-       0x81,0x00,0xd3,0x3c,0xd2,0x20,0xd1,0x12,0x10,0x0b,0x01,0xff,0xce,0xb9,0xcc,0x88,
-       0xcc,0x81,0x00,0x01,0xff,0xce,0xb1,0x00,0x10,0x07,0x01,0xff,0xce,0xb2,0x00,0x01,
-       0xff,0xce,0xb3,0x00,0xd1,0x0e,0x10,0x07,0x01,0xff,0xce,0xb4,0x00,0x01,0xff,0xce,
-       0xb5,0x00,0x10,0x07,0x01,0xff,0xce,0xb6,0x00,0x01,0xff,0xce,0xb7,0x00,0xd2,0x1c,
-       0xd1,0x0e,0x10,0x07,0x01,0xff,0xce,0xb8,0x00,0x01,0xff,0xce,0xb9,0x00,0x10,0x07,
-       0x01,0xff,0xce,0xba,0x00,0x01,0xff,0xce,0xbb,0x00,0xd1,0x0e,0x10,0x07,0x01,0xff,
-       0xce,0xbc,0x00,0x01,0xff,0xce,0xbd,0x00,0x10,0x07,0x01,0xff,0xce,0xbe,0x00,0x01,
-       0xff,0xce,0xbf,0x00,0xe4,0x85,0x43,0xd3,0x35,0xd2,0x19,0xd1,0x0e,0x10,0x07,0x01,
-       0xff,0xcf,0x80,0x00,0x01,0xff,0xcf,0x81,0x00,0x10,0x04,0x00,0x00,0x01,0xff,0xcf,
-       0x83,0x00,0xd1,0x0e,0x10,0x07,0x01,0xff,0xcf,0x84,0x00,0x01,0xff,0xcf,0x85,0x00,
-       0x10,0x07,0x01,0xff,0xcf,0x86,0x00,0x01,0xff,0xcf,0x87,0x00,0xe2,0x2b,0x43,0xd1,
-       0x0e,0x10,0x07,0x01,0xff,0xcf,0x88,0x00,0x01,0xff,0xcf,0x89,0x00,0x10,0x09,0x01,
-       0xff,0xce,0xb9,0xcc,0x88,0x00,0x01,0xff,0xcf,0x85,0xcc,0x88,0x00,0xcf,0x86,0xd5,
-       0x94,0xd4,0x3c,0xd3,0x13,0x92,0x0f,0x51,0x04,0x01,0x00,0x10,0x07,0x01,0xff,0xcf,
-       0x83,0x00,0x01,0x00,0x01,0x00,0xd2,0x07,0x61,0x3a,0x43,0x01,0x00,0xd1,0x12,0x10,
-       0x09,0x01,0xff,0xce,0xbf,0xcc,0x81,0x00,0x01,0xff,0xcf,0x85,0xcc,0x81,0x00,0x10,
-       0x09,0x01,0xff,0xcf,0x89,0xcc,0x81,0x00,0x0a,0xff,0xcf,0x97,0x00,0xd3,0x2c,0xd2,
-       0x11,0xe1,0x46,0x43,0x10,0x07,0x01,0xff,0xce,0xb2,0x00,0x01,0xff,0xce,0xb8,0x00,
-       0xd1,0x10,0x10,0x09,0x01,0xff,0xcf,0x92,0xcc,0x88,0x00,0x01,0xff,0xcf,0x86,0x00,
-       0x10,0x07,0x01,0xff,0xcf,0x80,0x00,0x04,0x00,0xd2,0x16,0xd1,0x0b,0x10,0x07,0x06,
-       0xff,0xcf,0x99,0x00,0x06,0x00,0x10,0x07,0x01,0xff,0xcf,0x9b,0x00,0x04,0x00,0xd1,
-       0x0b,0x10,0x07,0x01,0xff,0xcf,0x9d,0x00,0x04,0x00,0x10,0x07,0x01,0xff,0xcf,0x9f,
-       0x00,0x04,0x00,0xd4,0x58,0xd3,0x2c,0xd2,0x16,0xd1,0x0b,0x10,0x07,0x01,0xff,0xcf,
-       0xa1,0x00,0x04,0x00,0x10,0x07,0x01,0xff,0xcf,0xa3,0x00,0x01,0x00,0xd1,0x0b,0x10,
-       0x07,0x01,0xff,0xcf,0xa5,0x00,0x01,0x00,0x10,0x07,0x01,0xff,0xcf,0xa7,0x00,0x01,
-       0x00,0xd2,0x16,0xd1,0x0b,0x10,0x07,0x01,0xff,0xcf,0xa9,0x00,0x01,0x00,0x10,0x07,
-       0x01,0xff,0xcf,0xab,0x00,0x01,0x00,0xd1,0x0b,0x10,0x07,0x01,0xff,0xcf,0xad,0x00,
-       0x01,0x00,0x10,0x07,0x01,0xff,0xcf,0xaf,0x00,0x01,0x00,0xd3,0x2b,0xd2,0x12,0x91,
-       0x0e,0x10,0x07,0x01,0xff,0xce,0xba,0x00,0x01,0xff,0xcf,0x81,0x00,0x01,0x00,0xd1,
-       0x0e,0x10,0x07,0x05,0xff,0xce,0xb8,0x00,0x05,0xff,0xce,0xb5,0x00,0x10,0x04,0x06,
-       0x00,0x07,0xff,0xcf,0xb8,0x00,0xd2,0x16,0xd1,0x0b,0x10,0x04,0x07,0x00,0x07,0xff,
-       0xcf,0xb2,0x00,0x10,0x07,0x07,0xff,0xcf,0xbb,0x00,0x07,0x00,0xd1,0x0b,0x10,0x04,
-       0x08,0x00,0x08,0xff,0xcd,0xbb,0x00,0x10,0x07,0x08,0xff,0xcd,0xbc,0x00,0x08,0xff,
-       0xcd,0xbd,0x00,0xe3,0xed,0x46,0xe2,0x3d,0x05,0xe1,0x27,0x02,0xe0,0x66,0x01,0xcf,
-       0x86,0xd5,0xf0,0xd4,0x7e,0xd3,0x40,0xd2,0x22,0xd1,0x12,0x10,0x09,0x04,0xff,0xd0,
-       0xb5,0xcc,0x80,0x00,0x01,0xff,0xd0,0xb5,0xcc,0x88,0x00,0x10,0x07,0x01,0xff,0xd1,
-       0x92,0x00,0x01,0xff,0xd0,0xb3,0xcc,0x81,0x00,0xd1,0x0e,0x10,0x07,0x01,0xff,0xd1,
-       0x94,0x00,0x01,0xff,0xd1,0x95,0x00,0x10,0x07,0x01,0xff,0xd1,0x96,0x00,0x01,0xff,
-       0xd1,0x96,0xcc,0x88,0x00,0xd2,0x1c,0xd1,0x0e,0x10,0x07,0x01,0xff,0xd1,0x98,0x00,
-       0x01,0xff,0xd1,0x99,0x00,0x10,0x07,0x01,0xff,0xd1,0x9a,0x00,0x01,0xff,0xd1,0x9b,
-       0x00,0xd1,0x12,0x10,0x09,0x01,0xff,0xd0,0xba,0xcc,0x81,0x00,0x04,0xff,0xd0,0xb8,
-       0xcc,0x80,0x00,0x10,0x09,0x01,0xff,0xd1,0x83,0xcc,0x86,0x00,0x01,0xff,0xd1,0x9f,
-       0x00,0xd3,0x38,0xd2,0x1c,0xd1,0x0e,0x10,0x07,0x01,0xff,0xd0,0xb0,0x00,0x01,0xff,
-       0xd0,0xb1,0x00,0x10,0x07,0x01,0xff,0xd0,0xb2,0x00,0x01,0xff,0xd0,0xb3,0x00,0xd1,
-       0x0e,0x10,0x07,0x01,0xff,0xd0,0xb4,0x00,0x01,0xff,0xd0,0xb5,0x00,0x10,0x07,0x01,
-       0xff,0xd0,0xb6,0x00,0x01,0xff,0xd0,0xb7,0x00,0xd2,0x1e,0xd1,0x10,0x10,0x07,0x01,
-       0xff,0xd0,0xb8,0x00,0x01,0xff,0xd0,0xb8,0xcc,0x86,0x00,0x10,0x07,0x01,0xff,0xd0,
-       0xba,0x00,0x01,0xff,0xd0,0xbb,0x00,0xd1,0x0e,0x10,0x07,0x01,0xff,0xd0,0xbc,0x00,
-       0x01,0xff,0xd0,0xbd,0x00,0x10,0x07,0x01,0xff,0xd0,0xbe,0x00,0x01,0xff,0xd0,0xbf,
-       0x00,0xe4,0x25,0x42,0xd3,0x38,0xd2,0x1c,0xd1,0x0e,0x10,0x07,0x01,0xff,0xd1,0x80,
-       0x00,0x01,0xff,0xd1,0x81,0x00,0x10,0x07,0x01,0xff,0xd1,0x82,0x00,0x01,0xff,0xd1,
-       0x83,0x00,0xd1,0x0e,0x10,0x07,0x01,0xff,0xd1,0x84,0x00,0x01,0xff,0xd1,0x85,0x00,
-       0x10,0x07,0x01,0xff,0xd1,0x86,0x00,0x01,0xff,0xd1,0x87,0x00,0xd2,0x1c,0xd1,0x0e,
-       0x10,0x07,0x01,0xff,0xd1,0x88,0x00,0x01,0xff,0xd1,0x89,0x00,0x10,0x07,0x01,0xff,
-       0xd1,0x8a,0x00,0x01,0xff,0xd1,0x8b,0x00,0xd1,0x0e,0x10,0x07,0x01,0xff,0xd1,0x8c,
-       0x00,0x01,0xff,0xd1,0x8d,0x00,0x10,0x07,0x01,0xff,0xd1,0x8e,0x00,0x01,0xff,0xd1,
-       0x8f,0x00,0xcf,0x86,0xd5,0x07,0x64,0xcf,0x41,0x01,0x00,0xd4,0x58,0xd3,0x2c,0xd2,
-       0x16,0xd1,0x0b,0x10,0x07,0x01,0xff,0xd1,0xa1,0x00,0x01,0x00,0x10,0x07,0x01,0xff,
-       0xd1,0xa3,0x00,0x01,0x00,0xd1,0x0b,0x10,0x07,0x01,0xff,0xd1,0xa5,0x00,0x01,0x00,
-       0x10,0x07,0x01,0xff,0xd1,0xa7,0x00,0x01,0x00,0xd2,0x16,0xd1,0x0b,0x10,0x07,0x01,
-       0xff,0xd1,0xa9,0x00,0x01,0x00,0x10,0x07,0x01,0xff,0xd1,0xab,0x00,0x01,0x00,0xd1,
-       0x0b,0x10,0x07,0x01,0xff,0xd1,0xad,0x00,0x01,0x00,0x10,0x07,0x01,0xff,0xd1,0xaf,
-       0x00,0x01,0x00,0xd3,0x33,0xd2,0x16,0xd1,0x0b,0x10,0x07,0x01,0xff,0xd1,0xb1,0x00,
-       0x01,0x00,0x10,0x07,0x01,0xff,0xd1,0xb3,0x00,0x01,0x00,0xd1,0x0b,0x10,0x07,0x01,
-       0xff,0xd1,0xb5,0x00,0x01,0x00,0x10,0x09,0x01,0xff,0xd1,0xb5,0xcc,0x8f,0x00,0x01,
-       0xff,0xd1,0xb5,0xcc,0x8f,0x00,0xd2,0x16,0xd1,0x0b,0x10,0x07,0x01,0xff,0xd1,0xb9,
-       0x00,0x01,0x00,0x10,0x07,0x01,0xff,0xd1,0xbb,0x00,0x01,0x00,0xd1,0x0b,0x10,0x07,
-       0x01,0xff,0xd1,0xbd,0x00,0x01,0x00,0x10,0x07,0x01,0xff,0xd1,0xbf,0x00,0x01,0x00,
-       0xe0,0x41,0x01,0xcf,0x86,0xd5,0x8e,0xd4,0x36,0xd3,0x11,0xe2,0x91,0x41,0xe1,0x88,
-       0x41,0x10,0x07,0x01,0xff,0xd2,0x81,0x00,0x01,0x00,0xd2,0x0f,0x51,0x04,0x04,0x00,
-       0x10,0x07,0x06,0xff,0xd2,0x8b,0x00,0x06,0x00,0xd1,0x0b,0x10,0x07,0x04,0xff,0xd2,
-       0x8d,0x00,0x04,0x00,0x10,0x07,0x04,0xff,0xd2,0x8f,0x00,0x04,0x00,0xd3,0x2c,0xd2,
-       0x16,0xd1,0x0b,0x10,0x07,0x01,0xff,0xd2,0x91,0x00,0x01,0x00,0x10,0x07,0x01,0xff,
-       0xd2,0x93,0x00,0x01,0x00,0xd1,0x0b,0x10,0x07,0x01,0xff,0xd2,0x95,0x00,0x01,0x00,
-       0x10,0x07,0x01,0xff,0xd2,0x97,0x00,0x01,0x00,0xd2,0x16,0xd1,0x0b,0x10,0x07,0x01,
-       0xff,0xd2,0x99,0x00,0x01,0x00,0x10,0x07,0x01,0xff,0xd2,0x9b,0x00,0x01,0x00,0xd1,
-       0x0b,0x10,0x07,0x01,0xff,0xd2,0x9d,0x00,0x01,0x00,0x10,0x07,0x01,0xff,0xd2,0x9f,
-       0x00,0x01,0x00,0xd4,0x58,0xd3,0x2c,0xd2,0x16,0xd1,0x0b,0x10,0x07,0x01,0xff,0xd2,
-       0xa1,0x00,0x01,0x00,0x10,0x07,0x01,0xff,0xd2,0xa3,0x00,0x01,0x00,0xd1,0x0b,0x10,
-       0x07,0x01,0xff,0xd2,0xa5,0x00,0x01,0x00,0x10,0x07,0x01,0xff,0xd2,0xa7,0x00,0x01,
-       0x00,0xd2,0x16,0xd1,0x0b,0x10,0x07,0x01,0xff,0xd2,0xa9,0x00,0x01,0x00,0x10,0x07,
-       0x01,0xff,0xd2,0xab,0x00,0x01,0x00,0xd1,0x0b,0x10,0x07,0x01,0xff,0xd2,0xad,0x00,
-       0x01,0x00,0x10,0x07,0x01,0xff,0xd2,0xaf,0x00,0x01,0x00,0xd3,0x2c,0xd2,0x16,0xd1,
-       0x0b,0x10,0x07,0x01,0xff,0xd2,0xb1,0x00,0x01,0x00,0x10,0x07,0x01,0xff,0xd2,0xb3,
-       0x00,0x01,0x00,0xd1,0x0b,0x10,0x07,0x01,0xff,0xd2,0xb5,0x00,0x01,0x00,0x10,0x07,
-       0x01,0xff,0xd2,0xb7,0x00,0x01,0x00,0xd2,0x16,0xd1,0x0b,0x10,0x07,0x01,0xff,0xd2,
-       0xb9,0x00,0x01,0x00,0x10,0x07,0x01,0xff,0xd2,0xbb,0x00,0x01,0x00,0xd1,0x0b,0x10,
-       0x07,0x01,0xff,0xd2,0xbd,0x00,0x01,0x00,0x10,0x07,0x01,0xff,0xd2,0xbf,0x00,0x01,
-       0x00,0xcf,0x86,0xd5,0xdc,0xd4,0x5a,0xd3,0x36,0xd2,0x20,0xd1,0x10,0x10,0x07,0x01,
-       0xff,0xd3,0x8f,0x00,0x01,0xff,0xd0,0xb6,0xcc,0x86,0x00,0x10,0x09,0x01,0xff,0xd0,
-       0xb6,0xcc,0x86,0x00,0x01,0xff,0xd3,0x84,0x00,0xd1,0x0b,0x10,0x04,0x01,0x00,0x06,
-       0xff,0xd3,0x86,0x00,0x10,0x04,0x06,0x00,0x01,0xff,0xd3,0x88,0x00,0xd2,0x16,0xd1,
-       0x0b,0x10,0x04,0x01,0x00,0x06,0xff,0xd3,0x8a,0x00,0x10,0x04,0x06,0x00,0x01,0xff,
-       0xd3,0x8c,0x00,0xe1,0x69,0x40,0x10,0x04,0x01,0x00,0x06,0xff,0xd3,0x8e,0x00,0xd3,
-       0x41,0xd2,0x24,0xd1,0x12,0x10,0x09,0x01,0xff,0xd0,0xb0,0xcc,0x86,0x00,0x01,0xff,
-       0xd0,0xb0,0xcc,0x86,0x00,0x10,0x09,0x01,0xff,0xd0,0xb0,0xcc,0x88,0x00,0x01,0xff,
-       0xd0,0xb0,0xcc,0x88,0x00,0xd1,0x0b,0x10,0x07,0x01,0xff,0xd3,0x95,0x00,0x01,0x00,
-       0x10,0x09,0x01,0xff,0xd0,0xb5,0xcc,0x86,0x00,0x01,0xff,0xd0,0xb5,0xcc,0x86,0x00,
-       0xd2,0x1d,0xd1,0x0b,0x10,0x07,0x01,0xff,0xd3,0x99,0x00,0x01,0x00,0x10,0x09,0x01,
-       0xff,0xd3,0x99,0xcc,0x88,0x00,0x01,0xff,0xd3,0x99,0xcc,0x88,0x00,0xd1,0x12,0x10,
-       0x09,0x01,0xff,0xd0,0xb6,0xcc,0x88,0x00,0x01,0xff,0xd0,0xb6,0xcc,0x88,0x00,0x10,
-       0x09,0x01,0xff,0xd0,0xb7,0xcc,0x88,0x00,0x01,0xff,0xd0,0xb7,0xcc,0x88,0x00,0xd4,
-       0x82,0xd3,0x41,0xd2,0x1d,0xd1,0x0b,0x10,0x07,0x01,0xff,0xd3,0xa1,0x00,0x01,0x00,
-       0x10,0x09,0x01,0xff,0xd0,0xb8,0xcc,0x84,0x00,0x01,0xff,0xd0,0xb8,0xcc,0x84,0x00,
-       0xd1,0x12,0x10,0x09,0x01,0xff,0xd0,0xb8,0xcc,0x88,0x00,0x01,0xff,0xd0,0xb8,0xcc,
-       0x88,0x00,0x10,0x09,0x01,0xff,0xd0,0xbe,0xcc,0x88,0x00,0x01,0xff,0xd0,0xbe,0xcc,
-       0x88,0x00,0xd2,0x1d,0xd1,0x0b,0x10,0x07,0x01,0xff,0xd3,0xa9,0x00,0x01,0x00,0x10,
-       0x09,0x01,0xff,0xd3,0xa9,0xcc,0x88,0x00,0x01,0xff,0xd3,0xa9,0xcc,0x88,0x00,0xd1,
-       0x12,0x10,0x09,0x04,0xff,0xd1,0x8d,0xcc,0x88,0x00,0x04,0xff,0xd1,0x8d,0xcc,0x88,
-       0x00,0x10,0x09,0x01,0xff,0xd1,0x83,0xcc,0x84,0x00,0x01,0xff,0xd1,0x83,0xcc,0x84,
-       0x00,0xd3,0x41,0xd2,0x24,0xd1,0x12,0x10,0x09,0x01,0xff,0xd1,0x83,0xcc,0x88,0x00,
-       0x01,0xff,0xd1,0x83,0xcc,0x88,0x00,0x10,0x09,0x01,0xff,0xd1,0x83,0xcc,0x8b,0x00,
-       0x01,0xff,0xd1,0x83,0xcc,0x8b,0x00,0xd1,0x12,0x10,0x09,0x01,0xff,0xd1,0x87,0xcc,
-       0x88,0x00,0x01,0xff,0xd1,0x87,0xcc,0x88,0x00,0x10,0x07,0x08,0xff,0xd3,0xb7,0x00,
-       0x08,0x00,0xd2,0x1d,0xd1,0x12,0x10,0x09,0x01,0xff,0xd1,0x8b,0xcc,0x88,0x00,0x01,
-       0xff,0xd1,0x8b,0xcc,0x88,0x00,0x10,0x07,0x09,0xff,0xd3,0xbb,0x00,0x09,0x00,0xd1,
-       0x0b,0x10,0x07,0x09,0xff,0xd3,0xbd,0x00,0x09,0x00,0x10,0x07,0x09,0xff,0xd3,0xbf,
-       0x00,0x09,0x00,0xe1,0x26,0x02,0xe0,0x78,0x01,0xcf,0x86,0xd5,0xb0,0xd4,0x58,0xd3,
-       0x2c,0xd2,0x16,0xd1,0x0b,0x10,0x07,0x06,0xff,0xd4,0x81,0x00,0x06,0x00,0x10,0x07,
-       0x06,0xff,0xd4,0x83,0x00,0x06,0x00,0xd1,0x0b,0x10,0x07,0x06,0xff,0xd4,0x85,0x00,
-       0x06,0x00,0x10,0x07,0x06,0xff,0xd4,0x87,0x00,0x06,0x00,0xd2,0x16,0xd1,0x0b,0x10,
-       0x07,0x06,0xff,0xd4,0x89,0x00,0x06,0x00,0x10,0x07,0x06,0xff,0xd4,0x8b,0x00,0x06,
-       0x00,0xd1,0x0b,0x10,0x07,0x06,0xff,0xd4,0x8d,0x00,0x06,0x00,0x10,0x07,0x06,0xff,
-       0xd4,0x8f,0x00,0x06,0x00,0xd3,0x2c,0xd2,0x16,0xd1,0x0b,0x10,0x07,0x09,0xff,0xd4,
-       0x91,0x00,0x09,0x00,0x10,0x07,0x09,0xff,0xd4,0x93,0x00,0x09,0x00,0xd1,0x0b,0x10,
-       0x07,0x0a,0xff,0xd4,0x95,0x00,0x0a,0x00,0x10,0x07,0x0a,0xff,0xd4,0x97,0x00,0x0a,
-       0x00,0xd2,0x16,0xd1,0x0b,0x10,0x07,0x0a,0xff,0xd4,0x99,0x00,0x0a,0x00,0x10,0x07,
-       0x0a,0xff,0xd4,0x9b,0x00,0x0a,0x00,0xd1,0x0b,0x10,0x07,0x0a,0xff,0xd4,0x9d,0x00,
-       0x0a,0x00,0x10,0x07,0x0a,0xff,0xd4,0x9f,0x00,0x0a,0x00,0xd4,0x58,0xd3,0x2c,0xd2,
-       0x16,0xd1,0x0b,0x10,0x07,0x0a,0xff,0xd4,0xa1,0x00,0x0a,0x00,0x10,0x07,0x0a,0xff,
-       0xd4,0xa3,0x00,0x0a,0x00,0xd1,0x0b,0x10,0x07,0x0b,0xff,0xd4,0xa5,0x00,0x0b,0x00,
-       0x10,0x07,0x0c,0xff,0xd4,0xa7,0x00,0x0c,0x00,0xd2,0x16,0xd1,0x0b,0x10,0x07,0x10,
-       0xff,0xd4,0xa9,0x00,0x10,0x00,0x10,0x07,0x10,0xff,0xd4,0xab,0x00,0x10,0x00,0xd1,
-       0x0b,0x10,0x07,0x10,0xff,0xd4,0xad,0x00,0x10,0x00,0x10,0x07,0x10,0xff,0xd4,0xaf,
-       0x00,0x10,0x00,0xd3,0x35,0xd2,0x19,0xd1,0x0b,0x10,0x04,0x00,0x00,0x01,0xff,0xd5,
-       0xa1,0x00,0x10,0x07,0x01,0xff,0xd5,0xa2,0x00,0x01,0xff,0xd5,0xa3,0x00,0xd1,0x0e,
-       0x10,0x07,0x01,0xff,0xd5,0xa4,0x00,0x01,0xff,0xd5,0xa5,0x00,0x10,0x07,0x01,0xff,
-       0xd5,0xa6,0x00,0x01,0xff,0xd5,0xa7,0x00,0xd2,0x1c,0xd1,0x0e,0x10,0x07,0x01,0xff,
-       0xd5,0xa8,0x00,0x01,0xff,0xd5,0xa9,0x00,0x10,0x07,0x01,0xff,0xd5,0xaa,0x00,0x01,
-       0xff,0xd5,0xab,0x00,0xd1,0x0e,0x10,0x07,0x01,0xff,0xd5,0xac,0x00,0x01,0xff,0xd5,
-       0xad,0x00,0x10,0x07,0x01,0xff,0xd5,0xae,0x00,0x01,0xff,0xd5,0xaf,0x00,0xcf,0x86,
-       0xe5,0x08,0x3f,0xd4,0x70,0xd3,0x38,0xd2,0x1c,0xd1,0x0e,0x10,0x07,0x01,0xff,0xd5,
-       0xb0,0x00,0x01,0xff,0xd5,0xb1,0x00,0x10,0x07,0x01,0xff,0xd5,0xb2,0x00,0x01,0xff,
-       0xd5,0xb3,0x00,0xd1,0x0e,0x10,0x07,0x01,0xff,0xd5,0xb4,0x00,0x01,0xff,0xd5,0xb5,
-       0x00,0x10,0x07,0x01,0xff,0xd5,0xb6,0x00,0x01,0xff,0xd5,0xb7,0x00,0xd2,0x1c,0xd1,
-       0x0e,0x10,0x07,0x01,0xff,0xd5,0xb8,0x00,0x01,0xff,0xd5,0xb9,0x00,0x10,0x07,0x01,
-       0xff,0xd5,0xba,0x00,0x01,0xff,0xd5,0xbb,0x00,0xd1,0x0e,0x10,0x07,0x01,0xff,0xd5,
-       0xbc,0x00,0x01,0xff,0xd5,0xbd,0x00,0x10,0x07,0x01,0xff,0xd5,0xbe,0x00,0x01,0xff,
-       0xd5,0xbf,0x00,0xe3,0x87,0x3e,0xd2,0x1c,0xd1,0x0e,0x10,0x07,0x01,0xff,0xd6,0x80,
-       0x00,0x01,0xff,0xd6,0x81,0x00,0x10,0x07,0x01,0xff,0xd6,0x82,0x00,0x01,0xff,0xd6,
-       0x83,0x00,0xd1,0x0e,0x10,0x07,0x01,0xff,0xd6,0x84,0x00,0x01,0xff,0xd6,0x85,0x00,
-       0x10,0x07,0x01,0xff,0xd6,0x86,0x00,0x00,0x00,0xe0,0x2f,0x3f,0xcf,0x86,0xe5,0xc0,
-       0x3e,0xe4,0x97,0x3e,0xe3,0x76,0x3e,0x52,0x04,0x01,0x00,0x51,0x04,0x01,0x00,0x10,
-       0x04,0x01,0x00,0x01,0xff,0xd5,0xa5,0xd6,0x82,0x00,0xe4,0x3e,0x25,0xe3,0xc3,0x1a,
-       0xe2,0x7b,0x81,0xe1,0xc0,0x13,0xd0,0x1e,0xcf,0x86,0xc5,0xe4,0x08,0x4b,0xe3,0x53,
-       0x46,0xe2,0xe9,0x43,0xe1,0x1c,0x43,0xe0,0xe1,0x42,0xcf,0x86,0xe5,0xa6,0x42,0x64,
-       0x89,0x42,0x0b,0x00,0xcf,0x86,0xe5,0xfa,0x01,0xe4,0x03,0x56,0xe3,0x76,0x01,0xe2,
-       0x8e,0x53,0xd1,0x0c,0xe0,0xef,0x52,0xcf,0x86,0x65,0x8d,0x52,0x04,0x00,0xe0,0x0d,
-       0x01,0xcf,0x86,0xd5,0x0a,0xe4,0x10,0x53,0x63,0xff,0x52,0x0a,0x00,0xd4,0x80,0xd3,
-       0x40,0xd2,0x20,0xd1,0x10,0x10,0x08,0x01,0xff,0xe2,0xb4,0x80,0x00,0x01,0xff,0xe2,
-       0xb4,0x81,0x00,0x10,0x08,0x01,0xff,0xe2,0xb4,0x82,0x00,0x01,0xff,0xe2,0xb4,0x83,
-       0x00,0xd1,0x10,0x10,0x08,0x01,0xff,0xe2,0xb4,0x84,0x00,0x01,0xff,0xe2,0xb4,0x85,
-       0x00,0x10,0x08,0x01,0xff,0xe2,0xb4,0x86,0x00,0x01,0xff,0xe2,0xb4,0x87,0x00,0xd2,
-       0x20,0xd1,0x10,0x10,0x08,0x01,0xff,0xe2,0xb4,0x88,0x00,0x01,0xff,0xe2,0xb4,0x89,
-       0x00,0x10,0x08,0x01,0xff,0xe2,0xb4,0x8a,0x00,0x01,0xff,0xe2,0xb4,0x8b,0x00,0xd1,
-       0x10,0x10,0x08,0x01,0xff,0xe2,0xb4,0x8c,0x00,0x01,0xff,0xe2,0xb4,0x8d,0x00,0x10,
-       0x08,0x01,0xff,0xe2,0xb4,0x8e,0x00,0x01,0xff,0xe2,0xb4,0x8f,0x00,0xd3,0x40,0xd2,
-       0x20,0xd1,0x10,0x10,0x08,0x01,0xff,0xe2,0xb4,0x90,0x00,0x01,0xff,0xe2,0xb4,0x91,
-       0x00,0x10,0x08,0x01,0xff,0xe2,0xb4,0x92,0x00,0x01,0xff,0xe2,0xb4,0x93,0x00,0xd1,
-       0x10,0x10,0x08,0x01,0xff,0xe2,0xb4,0x94,0x00,0x01,0xff,0xe2,0xb4,0x95,0x00,0x10,
-       0x08,0x01,0xff,0xe2,0xb4,0x96,0x00,0x01,0xff,0xe2,0xb4,0x97,0x00,0xd2,0x20,0xd1,
-       0x10,0x10,0x08,0x01,0xff,0xe2,0xb4,0x98,0x00,0x01,0xff,0xe2,0xb4,0x99,0x00,0x10,
-       0x08,0x01,0xff,0xe2,0xb4,0x9a,0x00,0x01,0xff,0xe2,0xb4,0x9b,0x00,0xd1,0x10,0x10,
-       0x08,0x01,0xff,0xe2,0xb4,0x9c,0x00,0x01,0xff,0xe2,0xb4,0x9d,0x00,0x10,0x08,0x01,
-       0xff,0xe2,0xb4,0x9e,0x00,0x01,0xff,0xe2,0xb4,0x9f,0x00,0xcf,0x86,0xe5,0x42,0x52,
-       0x94,0x50,0xd3,0x3c,0xd2,0x20,0xd1,0x10,0x10,0x08,0x01,0xff,0xe2,0xb4,0xa0,0x00,
-       0x01,0xff,0xe2,0xb4,0xa1,0x00,0x10,0x08,0x01,0xff,0xe2,0xb4,0xa2,0x00,0x01,0xff,
-       0xe2,0xb4,0xa3,0x00,0xd1,0x10,0x10,0x08,0x01,0xff,0xe2,0xb4,0xa4,0x00,0x01,0xff,
-       0xe2,0xb4,0xa5,0x00,0x10,0x04,0x00,0x00,0x0d,0xff,0xe2,0xb4,0xa7,0x00,0x52,0x04,
-       0x00,0x00,0x91,0x0c,0x10,0x04,0x00,0x00,0x0d,0xff,0xe2,0xb4,0xad,0x00,0x00,0x00,
-       0x01,0x00,0xd2,0x1b,0xe1,0xfc,0x52,0xe0,0xad,0x52,0xcf,0x86,0x95,0x0f,0x94,0x0b,
-       0x93,0x07,0x62,0x92,0x52,0x04,0x00,0x04,0x00,0x04,0x00,0x04,0x00,0xd1,0x13,0xe0,
-       0xd3,0x53,0xcf,0x86,0x95,0x0a,0xe4,0xa8,0x53,0x63,0x97,0x53,0x04,0x00,0x04,0x00,
-       0xd0,0x0d,0xcf,0x86,0x95,0x07,0x64,0x22,0x54,0x08,0x00,0x04,0x00,0xcf,0x86,0x55,
-       0x04,0x04,0x00,0x54,0x04,0x04,0x00,0xd3,0x07,0x62,0x2f,0x54,0x04,0x00,0xd2,0x20,
-       0xd1,0x10,0x10,0x08,0x11,0xff,0xe1,0x8f,0xb0,0x00,0x11,0xff,0xe1,0x8f,0xb1,0x00,
-       0x10,0x08,0x11,0xff,0xe1,0x8f,0xb2,0x00,0x11,0xff,0xe1,0x8f,0xb3,0x00,0x91,0x10,
-       0x10,0x08,0x11,0xff,0xe1,0x8f,0xb4,0x00,0x11,0xff,0xe1,0x8f,0xb5,0x00,0x00,0x00,
-       0xd4,0x1c,0xe3,0xe0,0x56,0xe2,0x17,0x56,0xe1,0xda,0x55,0xe0,0xbb,0x55,0xcf,0x86,
-       0x95,0x0a,0xe4,0xa4,0x55,0x63,0x88,0x55,0x04,0x00,0x04,0x00,0xe3,0xd2,0x01,0xe2,
-       0x2b,0x5a,0xd1,0x0c,0xe0,0x4c,0x59,0xcf,0x86,0x65,0x25,0x59,0x0a,0x00,0xe0,0x9c,
-       0x59,0xcf,0x86,0xd5,0xc5,0xd4,0x45,0xd3,0x31,0xd2,0x1c,0xd1,0x0e,0x10,0x07,0x12,
-       0xff,0xd0,0xb2,0x00,0x12,0xff,0xd0,0xb4,0x00,0x10,0x07,0x12,0xff,0xd0,0xbe,0x00,
-       0x12,0xff,0xd1,0x81,0x00,0x51,0x07,0x12,0xff,0xd1,0x82,0x00,0x10,0x07,0x12,0xff,
-       0xd1,0x8a,0x00,0x12,0xff,0xd1,0xa3,0x00,0x92,0x10,0x91,0x0c,0x10,0x08,0x12,0xff,
-       0xea,0x99,0x8b,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xd3,0x40,0xd2,0x20,0xd1,0x10,
-       0x10,0x08,0x14,0xff,0xe1,0x83,0x90,0x00,0x14,0xff,0xe1,0x83,0x91,0x00,0x10,0x08,
-       0x14,0xff,0xe1,0x83,0x92,0x00,0x14,0xff,0xe1,0x83,0x93,0x00,0xd1,0x10,0x10,0x08,
-       0x14,0xff,0xe1,0x83,0x94,0x00,0x14,0xff,0xe1,0x83,0x95,0x00,0x10,0x08,0x14,0xff,
-       0xe1,0x83,0x96,0x00,0x14,0xff,0xe1,0x83,0x97,0x00,0xd2,0x20,0xd1,0x10,0x10,0x08,
-       0x14,0xff,0xe1,0x83,0x98,0x00,0x14,0xff,0xe1,0x83,0x99,0x00,0x10,0x08,0x14,0xff,
-       0xe1,0x83,0x9a,0x00,0x14,0xff,0xe1,0x83,0x9b,0x00,0xd1,0x10,0x10,0x08,0x14,0xff,
-       0xe1,0x83,0x9c,0x00,0x14,0xff,0xe1,0x83,0x9d,0x00,0x10,0x08,0x14,0xff,0xe1,0x83,
-       0x9e,0x00,0x14,0xff,0xe1,0x83,0x9f,0x00,0xd4,0x80,0xd3,0x40,0xd2,0x20,0xd1,0x10,
-       0x10,0x08,0x14,0xff,0xe1,0x83,0xa0,0x00,0x14,0xff,0xe1,0x83,0xa1,0x00,0x10,0x08,
-       0x14,0xff,0xe1,0x83,0xa2,0x00,0x14,0xff,0xe1,0x83,0xa3,0x00,0xd1,0x10,0x10,0x08,
-       0x14,0xff,0xe1,0x83,0xa4,0x00,0x14,0xff,0xe1,0x83,0xa5,0x00,0x10,0x08,0x14,0xff,
-       0xe1,0x83,0xa6,0x00,0x14,0xff,0xe1,0x83,0xa7,0x00,0xd2,0x20,0xd1,0x10,0x10,0x08,
-       0x14,0xff,0xe1,0x83,0xa8,0x00,0x14,0xff,0xe1,0x83,0xa9,0x00,0x10,0x08,0x14,0xff,
-       0xe1,0x83,0xaa,0x00,0x14,0xff,0xe1,0x83,0xab,0x00,0xd1,0x10,0x10,0x08,0x14,0xff,
-       0xe1,0x83,0xac,0x00,0x14,0xff,0xe1,0x83,0xad,0x00,0x10,0x08,0x14,0xff,0xe1,0x83,
-       0xae,0x00,0x14,0xff,0xe1,0x83,0xaf,0x00,0xd3,0x40,0xd2,0x20,0xd1,0x10,0x10,0x08,
-       0x14,0xff,0xe1,0x83,0xb0,0x00,0x14,0xff,0xe1,0x83,0xb1,0x00,0x10,0x08,0x14,0xff,
-       0xe1,0x83,0xb2,0x00,0x14,0xff,0xe1,0x83,0xb3,0x00,0xd1,0x10,0x10,0x08,0x14,0xff,
-       0xe1,0x83,0xb4,0x00,0x14,0xff,0xe1,0x83,0xb5,0x00,0x10,0x08,0x14,0xff,0xe1,0x83,
-       0xb6,0x00,0x14,0xff,0xe1,0x83,0xb7,0x00,0xd2,0x1c,0xd1,0x10,0x10,0x08,0x14,0xff,
-       0xe1,0x83,0xb8,0x00,0x14,0xff,0xe1,0x83,0xb9,0x00,0x10,0x08,0x14,0xff,0xe1,0x83,
-       0xba,0x00,0x00,0x00,0xd1,0x0c,0x10,0x04,0x00,0x00,0x14,0xff,0xe1,0x83,0xbd,0x00,
-       0x10,0x08,0x14,0xff,0xe1,0x83,0xbe,0x00,0x14,0xff,0xe1,0x83,0xbf,0x00,0xe2,0x9d,
-       0x08,0xe1,0x48,0x04,0xe0,0x1c,0x02,0xcf,0x86,0xe5,0x11,0x01,0xd4,0x84,0xd3,0x40,
-       0xd2,0x20,0xd1,0x10,0x10,0x08,0x01,0xff,0x61,0xcc,0xa5,0x00,0x01,0xff,0x61,0xcc,
-       0xa5,0x00,0x10,0x08,0x01,0xff,0x62,0xcc,0x87,0x00,0x01,0xff,0x62,0xcc,0x87,0x00,
-       0xd1,0x10,0x10,0x08,0x01,0xff,0x62,0xcc,0xa3,0x00,0x01,0xff,0x62,0xcc,0xa3,0x00,
-       0x10,0x08,0x01,0xff,0x62,0xcc,0xb1,0x00,0x01,0xff,0x62,0xcc,0xb1,0x00,0xd2,0x24,
-       0xd1,0x14,0x10,0x0a,0x01,0xff,0x63,0xcc,0xa7,0xcc,0x81,0x00,0x01,0xff,0x63,0xcc,
-       0xa7,0xcc,0x81,0x00,0x10,0x08,0x01,0xff,0x64,0xcc,0x87,0x00,0x01,0xff,0x64,0xcc,
-       0x87,0x00,0xd1,0x10,0x10,0x08,0x01,0xff,0x64,0xcc,0xa3,0x00,0x01,0xff,0x64,0xcc,
-       0xa3,0x00,0x10,0x08,0x01,0xff,0x64,0xcc,0xb1,0x00,0x01,0xff,0x64,0xcc,0xb1,0x00,
-       0xd3,0x48,0xd2,0x20,0xd1,0x10,0x10,0x08,0x01,0xff,0x64,0xcc,0xa7,0x00,0x01,0xff,
-       0x64,0xcc,0xa7,0x00,0x10,0x08,0x01,0xff,0x64,0xcc,0xad,0x00,0x01,0xff,0x64,0xcc,
-       0xad,0x00,0xd1,0x14,0x10,0x0a,0x01,0xff,0x65,0xcc,0x84,0xcc,0x80,0x00,0x01,0xff,
-       0x65,0xcc,0x84,0xcc,0x80,0x00,0x10,0x0a,0x01,0xff,0x65,0xcc,0x84,0xcc,0x81,0x00,
-       0x01,0xff,0x65,0xcc,0x84,0xcc,0x81,0x00,0xd2,0x20,0xd1,0x10,0x10,0x08,0x01,0xff,
-       0x65,0xcc,0xad,0x00,0x01,0xff,0x65,0xcc,0xad,0x00,0x10,0x08,0x01,0xff,0x65,0xcc,
-       0xb0,0x00,0x01,0xff,0x65,0xcc,0xb0,0x00,0xd1,0x14,0x10,0x0a,0x01,0xff,0x65,0xcc,
-       0xa7,0xcc,0x86,0x00,0x01,0xff,0x65,0xcc,0xa7,0xcc,0x86,0x00,0x10,0x08,0x01,0xff,
-       0x66,0xcc,0x87,0x00,0x01,0xff,0x66,0xcc,0x87,0x00,0xd4,0x84,0xd3,0x40,0xd2,0x20,
-       0xd1,0x10,0x10,0x08,0x01,0xff,0x67,0xcc,0x84,0x00,0x01,0xff,0x67,0xcc,0x84,0x00,
-       0x10,0x08,0x01,0xff,0x68,0xcc,0x87,0x00,0x01,0xff,0x68,0xcc,0x87,0x00,0xd1,0x10,
-       0x10,0x08,0x01,0xff,0x68,0xcc,0xa3,0x00,0x01,0xff,0x68,0xcc,0xa3,0x00,0x10,0x08,
-       0x01,0xff,0x68,0xcc,0x88,0x00,0x01,0xff,0x68,0xcc,0x88,0x00,0xd2,0x20,0xd1,0x10,
-       0x10,0x08,0x01,0xff,0x68,0xcc,0xa7,0x00,0x01,0xff,0x68,0xcc,0xa7,0x00,0x10,0x08,
-       0x01,0xff,0x68,0xcc,0xae,0x00,0x01,0xff,0x68,0xcc,0xae,0x00,0xd1,0x10,0x10,0x08,
-       0x01,0xff,0x69,0xcc,0xb0,0x00,0x01,0xff,0x69,0xcc,0xb0,0x00,0x10,0x0a,0x01,0xff,
-       0x69,0xcc,0x88,0xcc,0x81,0x00,0x01,0xff,0x69,0xcc,0x88,0xcc,0x81,0x00,0xd3,0x40,
-       0xd2,0x20,0xd1,0x10,0x10,0x08,0x01,0xff,0x6b,0xcc,0x81,0x00,0x01,0xff,0x6b,0xcc,
-       0x81,0x00,0x10,0x08,0x01,0xff,0x6b,0xcc,0xa3,0x00,0x01,0xff,0x6b,0xcc,0xa3,0x00,
-       0xd1,0x10,0x10,0x08,0x01,0xff,0x6b,0xcc,0xb1,0x00,0x01,0xff,0x6b,0xcc,0xb1,0x00,
-       0x10,0x08,0x01,0xff,0x6c,0xcc,0xa3,0x00,0x01,0xff,0x6c,0xcc,0xa3,0x00,0xd2,0x24,
-       0xd1,0x14,0x10,0x0a,0x01,0xff,0x6c,0xcc,0xa3,0xcc,0x84,0x00,0x01,0xff,0x6c,0xcc,
-       0xa3,0xcc,0x84,0x00,0x10,0x08,0x01,0xff,0x6c,0xcc,0xb1,0x00,0x01,0xff,0x6c,0xcc,
-       0xb1,0x00,0xd1,0x10,0x10,0x08,0x01,0xff,0x6c,0xcc,0xad,0x00,0x01,0xff,0x6c,0xcc,
-       0xad,0x00,0x10,0x08,0x01,0xff,0x6d,0xcc,0x81,0x00,0x01,0xff,0x6d,0xcc,0x81,0x00,
-       0xcf,0x86,0xe5,0x15,0x01,0xd4,0x88,0xd3,0x40,0xd2,0x20,0xd1,0x10,0x10,0x08,0x01,
-       0xff,0x6d,0xcc,0x87,0x00,0x01,0xff,0x6d,0xcc,0x87,0x00,0x10,0x08,0x01,0xff,0x6d,
-       0xcc,0xa3,0x00,0x01,0xff,0x6d,0xcc,0xa3,0x00,0xd1,0x10,0x10,0x08,0x01,0xff,0x6e,
-       0xcc,0x87,0x00,0x01,0xff,0x6e,0xcc,0x87,0x00,0x10,0x08,0x01,0xff,0x6e,0xcc,0xa3,
-       0x00,0x01,0xff,0x6e,0xcc,0xa3,0x00,0xd2,0x20,0xd1,0x10,0x10,0x08,0x01,0xff,0x6e,
-       0xcc,0xb1,0x00,0x01,0xff,0x6e,0xcc,0xb1,0x00,0x10,0x08,0x01,0xff,0x6e,0xcc,0xad,
-       0x00,0x01,0xff,0x6e,0xcc,0xad,0x00,0xd1,0x14,0x10,0x0a,0x01,0xff,0x6f,0xcc,0x83,
-       0xcc,0x81,0x00,0x01,0xff,0x6f,0xcc,0x83,0xcc,0x81,0x00,0x10,0x0a,0x01,0xff,0x6f,
-       0xcc,0x83,0xcc,0x88,0x00,0x01,0xff,0x6f,0xcc,0x83,0xcc,0x88,0x00,0xd3,0x48,0xd2,
-       0x28,0xd1,0x14,0x10,0x0a,0x01,0xff,0x6f,0xcc,0x84,0xcc,0x80,0x00,0x01,0xff,0x6f,
-       0xcc,0x84,0xcc,0x80,0x00,0x10,0x0a,0x01,0xff,0x6f,0xcc,0x84,0xcc,0x81,0x00,0x01,
-       0xff,0x6f,0xcc,0x84,0xcc,0x81,0x00,0xd1,0x10,0x10,0x08,0x01,0xff,0x70,0xcc,0x81,
-       0x00,0x01,0xff,0x70,0xcc,0x81,0x00,0x10,0x08,0x01,0xff,0x70,0xcc,0x87,0x00,0x01,
-       0xff,0x70,0xcc,0x87,0x00,0xd2,0x20,0xd1,0x10,0x10,0x08,0x01,0xff,0x72,0xcc,0x87,
-       0x00,0x01,0xff,0x72,0xcc,0x87,0x00,0x10,0x08,0x01,0xff,0x72,0xcc,0xa3,0x00,0x01,
-       0xff,0x72,0xcc,0xa3,0x00,0xd1,0x14,0x10,0x0a,0x01,0xff,0x72,0xcc,0xa3,0xcc,0x84,
-       0x00,0x01,0xff,0x72,0xcc,0xa3,0xcc,0x84,0x00,0x10,0x08,0x01,0xff,0x72,0xcc,0xb1,
-       0x00,0x01,0xff,0x72,0xcc,0xb1,0x00,0xd4,0x8c,0xd3,0x48,0xd2,0x20,0xd1,0x10,0x10,
-       0x08,0x01,0xff,0x73,0xcc,0x87,0x00,0x01,0xff,0x73,0xcc,0x87,0x00,0x10,0x08,0x01,
-       0xff,0x73,0xcc,0xa3,0x00,0x01,0xff,0x73,0xcc,0xa3,0x00,0xd1,0x14,0x10,0x0a,0x01,
-       0xff,0x73,0xcc,0x81,0xcc,0x87,0x00,0x01,0xff,0x73,0xcc,0x81,0xcc,0x87,0x00,0x10,
-       0x0a,0x01,0xff,0x73,0xcc,0x8c,0xcc,0x87,0x00,0x01,0xff,0x73,0xcc,0x8c,0xcc,0x87,
-       0x00,0xd2,0x24,0xd1,0x14,0x10,0x0a,0x01,0xff,0x73,0xcc,0xa3,0xcc,0x87,0x00,0x01,
-       0xff,0x73,0xcc,0xa3,0xcc,0x87,0x00,0x10,0x08,0x01,0xff,0x74,0xcc,0x87,0x00,0x01,
-       0xff,0x74,0xcc,0x87,0x00,0xd1,0x10,0x10,0x08,0x01,0xff,0x74,0xcc,0xa3,0x00,0x01,
-       0xff,0x74,0xcc,0xa3,0x00,0x10,0x08,0x01,0xff,0x74,0xcc,0xb1,0x00,0x01,0xff,0x74,
-       0xcc,0xb1,0x00,0xd3,0x40,0xd2,0x20,0xd1,0x10,0x10,0x08,0x01,0xff,0x74,0xcc,0xad,
-       0x00,0x01,0xff,0x74,0xcc,0xad,0x00,0x10,0x08,0x01,0xff,0x75,0xcc,0xa4,0x00,0x01,
-       0xff,0x75,0xcc,0xa4,0x00,0xd1,0x10,0x10,0x08,0x01,0xff,0x75,0xcc,0xb0,0x00,0x01,
-       0xff,0x75,0xcc,0xb0,0x00,0x10,0x08,0x01,0xff,0x75,0xcc,0xad,0x00,0x01,0xff,0x75,
-       0xcc,0xad,0x00,0xd2,0x28,0xd1,0x14,0x10,0x0a,0x01,0xff,0x75,0xcc,0x83,0xcc,0x81,
-       0x00,0x01,0xff,0x75,0xcc,0x83,0xcc,0x81,0x00,0x10,0x0a,0x01,0xff,0x75,0xcc,0x84,
-       0xcc,0x88,0x00,0x01,0xff,0x75,0xcc,0x84,0xcc,0x88,0x00,0xd1,0x10,0x10,0x08,0x01,
-       0xff,0x76,0xcc,0x83,0x00,0x01,0xff,0x76,0xcc,0x83,0x00,0x10,0x08,0x01,0xff,0x76,
-       0xcc,0xa3,0x00,0x01,0xff,0x76,0xcc,0xa3,0x00,0xe0,0x11,0x02,0xcf,0x86,0xd5,0xe2,
-       0xd4,0x80,0xd3,0x40,0xd2,0x20,0xd1,0x10,0x10,0x08,0x01,0xff,0x77,0xcc,0x80,0x00,
-       0x01,0xff,0x77,0xcc,0x80,0x00,0x10,0x08,0x01,0xff,0x77,0xcc,0x81,0x00,0x01,0xff,
-       0x77,0xcc,0x81,0x00,0xd1,0x10,0x10,0x08,0x01,0xff,0x77,0xcc,0x88,0x00,0x01,0xff,
-       0x77,0xcc,0x88,0x00,0x10,0x08,0x01,0xff,0x77,0xcc,0x87,0x00,0x01,0xff,0x77,0xcc,
-       0x87,0x00,0xd2,0x20,0xd1,0x10,0x10,0x08,0x01,0xff,0x77,0xcc,0xa3,0x00,0x01,0xff,
-       0x77,0xcc,0xa3,0x00,0x10,0x08,0x01,0xff,0x78,0xcc,0x87,0x00,0x01,0xff,0x78,0xcc,
-       0x87,0x00,0xd1,0x10,0x10,0x08,0x01,0xff,0x78,0xcc,0x88,0x00,0x01,0xff,0x78,0xcc,
-       0x88,0x00,0x10,0x08,0x01,0xff,0x79,0xcc,0x87,0x00,0x01,0xff,0x79,0xcc,0x87,0x00,
-       0xd3,0x33,0xd2,0x20,0xd1,0x10,0x10,0x08,0x01,0xff,0x7a,0xcc,0x82,0x00,0x01,0xff,
-       0x7a,0xcc,0x82,0x00,0x10,0x08,0x01,0xff,0x7a,0xcc,0xa3,0x00,0x01,0xff,0x7a,0xcc,
-       0xa3,0x00,0xe1,0x12,0x59,0x10,0x08,0x01,0xff,0x7a,0xcc,0xb1,0x00,0x01,0xff,0x7a,
-       0xcc,0xb1,0x00,0xd2,0x20,0xd1,0x10,0x10,0x08,0x01,0xff,0x77,0xcc,0x8a,0x00,0x01,
-       0xff,0x79,0xcc,0x8a,0x00,0x10,0x08,0x01,0xff,0x61,0xca,0xbe,0x00,0x02,0xff,0x73,
-       0xcc,0x87,0x00,0x51,0x04,0x0a,0x00,0x10,0x07,0x0a,0xff,0x73,0x73,0x00,0x0a,0x00,
-       0xd4,0x98,0xd3,0x48,0xd2,0x20,0xd1,0x10,0x10,0x08,0x01,0xff,0x61,0xcc,0xa3,0x00,
-       0x01,0xff,0x61,0xcc,0xa3,0x00,0x10,0x08,0x01,0xff,0x61,0xcc,0x89,0x00,0x01,0xff,
-       0x61,0xcc,0x89,0x00,0xd1,0x14,0x10,0x0a,0x01,0xff,0x61,0xcc,0x82,0xcc,0x81,0x00,
-       0x01,0xff,0x61,0xcc,0x82,0xcc,0x81,0x00,0x10,0x0a,0x01,0xff,0x61,0xcc,0x82,0xcc,
-       0x80,0x00,0x01,0xff,0x61,0xcc,0x82,0xcc,0x80,0x00,0xd2,0x28,0xd1,0x14,0x10,0x0a,
-       0x01,0xff,0x61,0xcc,0x82,0xcc,0x89,0x00,0x01,0xff,0x61,0xcc,0x82,0xcc,0x89,0x00,
-       0x10,0x0a,0x01,0xff,0x61,0xcc,0x82,0xcc,0x83,0x00,0x01,0xff,0x61,0xcc,0x82,0xcc,
-       0x83,0x00,0xd1,0x14,0x10,0x0a,0x01,0xff,0x61,0xcc,0xa3,0xcc,0x82,0x00,0x01,0xff,
-       0x61,0xcc,0xa3,0xcc,0x82,0x00,0x10,0x0a,0x01,0xff,0x61,0xcc,0x86,0xcc,0x81,0x00,
-       0x01,0xff,0x61,0xcc,0x86,0xcc,0x81,0x00,0xd3,0x50,0xd2,0x28,0xd1,0x14,0x10,0x0a,
-       0x01,0xff,0x61,0xcc,0x86,0xcc,0x80,0x00,0x01,0xff,0x61,0xcc,0x86,0xcc,0x80,0x00,
-       0x10,0x0a,0x01,0xff,0x61,0xcc,0x86,0xcc,0x89,0x00,0x01,0xff,0x61,0xcc,0x86,0xcc,
-       0x89,0x00,0xd1,0x14,0x10,0x0a,0x01,0xff,0x61,0xcc,0x86,0xcc,0x83,0x00,0x01,0xff,
-       0x61,0xcc,0x86,0xcc,0x83,0x00,0x10,0x0a,0x01,0xff,0x61,0xcc,0xa3,0xcc,0x86,0x00,
-       0x01,0xff,0x61,0xcc,0xa3,0xcc,0x86,0x00,0xd2,0x20,0xd1,0x10,0x10,0x08,0x01,0xff,
-       0x65,0xcc,0xa3,0x00,0x01,0xff,0x65,0xcc,0xa3,0x00,0x10,0x08,0x01,0xff,0x65,0xcc,
-       0x89,0x00,0x01,0xff,0x65,0xcc,0x89,0x00,0xd1,0x10,0x10,0x08,0x01,0xff,0x65,0xcc,
-       0x83,0x00,0x01,0xff,0x65,0xcc,0x83,0x00,0x10,0x0a,0x01,0xff,0x65,0xcc,0x82,0xcc,
-       0x81,0x00,0x01,0xff,0x65,0xcc,0x82,0xcc,0x81,0x00,0xcf,0x86,0xe5,0x31,0x01,0xd4,
-       0x90,0xd3,0x50,0xd2,0x28,0xd1,0x14,0x10,0x0a,0x01,0xff,0x65,0xcc,0x82,0xcc,0x80,
-       0x00,0x01,0xff,0x65,0xcc,0x82,0xcc,0x80,0x00,0x10,0x0a,0x01,0xff,0x65,0xcc,0x82,
-       0xcc,0x89,0x00,0x01,0xff,0x65,0xcc,0x82,0xcc,0x89,0x00,0xd1,0x14,0x10,0x0a,0x01,
-       0xff,0x65,0xcc,0x82,0xcc,0x83,0x00,0x01,0xff,0x65,0xcc,0x82,0xcc,0x83,0x00,0x10,
-       0x0a,0x01,0xff,0x65,0xcc,0xa3,0xcc,0x82,0x00,0x01,0xff,0x65,0xcc,0xa3,0xcc,0x82,
-       0x00,0xd2,0x20,0xd1,0x10,0x10,0x08,0x01,0xff,0x69,0xcc,0x89,0x00,0x01,0xff,0x69,
-       0xcc,0x89,0x00,0x10,0x08,0x01,0xff,0x69,0xcc,0xa3,0x00,0x01,0xff,0x69,0xcc,0xa3,
-       0x00,0xd1,0x10,0x10,0x08,0x01,0xff,0x6f,0xcc,0xa3,0x00,0x01,0xff,0x6f,0xcc,0xa3,
-       0x00,0x10,0x08,0x01,0xff,0x6f,0xcc,0x89,0x00,0x01,0xff,0x6f,0xcc,0x89,0x00,0xd3,
-       0x50,0xd2,0x28,0xd1,0x14,0x10,0x0a,0x01,0xff,0x6f,0xcc,0x82,0xcc,0x81,0x00,0x01,
-       0xff,0x6f,0xcc,0x82,0xcc,0x81,0x00,0x10,0x0a,0x01,0xff,0x6f,0xcc,0x82,0xcc,0x80,
-       0x00,0x01,0xff,0x6f,0xcc,0x82,0xcc,0x80,0x00,0xd1,0x14,0x10,0x0a,0x01,0xff,0x6f,
-       0xcc,0x82,0xcc,0x89,0x00,0x01,0xff,0x6f,0xcc,0x82,0xcc,0x89,0x00,0x10,0x0a,0x01,
-       0xff,0x6f,0xcc,0x82,0xcc,0x83,0x00,0x01,0xff,0x6f,0xcc,0x82,0xcc,0x83,0x00,0xd2,
-       0x28,0xd1,0x14,0x10,0x0a,0x01,0xff,0x6f,0xcc,0xa3,0xcc,0x82,0x00,0x01,0xff,0x6f,
-       0xcc,0xa3,0xcc,0x82,0x00,0x10,0x0a,0x01,0xff,0x6f,0xcc,0x9b,0xcc,0x81,0x00,0x01,
-       0xff,0x6f,0xcc,0x9b,0xcc,0x81,0x00,0xd1,0x14,0x10,0x0a,0x01,0xff,0x6f,0xcc,0x9b,
-       0xcc,0x80,0x00,0x01,0xff,0x6f,0xcc,0x9b,0xcc,0x80,0x00,0x10,0x0a,0x01,0xff,0x6f,
-       0xcc,0x9b,0xcc,0x89,0x00,0x01,0xff,0x6f,0xcc,0x9b,0xcc,0x89,0x00,0xd4,0x98,0xd3,
-       0x48,0xd2,0x28,0xd1,0x14,0x10,0x0a,0x01,0xff,0x6f,0xcc,0x9b,0xcc,0x83,0x00,0x01,
-       0xff,0x6f,0xcc,0x9b,0xcc,0x83,0x00,0x10,0x0a,0x01,0xff,0x6f,0xcc,0x9b,0xcc,0xa3,
-       0x00,0x01,0xff,0x6f,0xcc,0x9b,0xcc,0xa3,0x00,0xd1,0x10,0x10,0x08,0x01,0xff,0x75,
-       0xcc,0xa3,0x00,0x01,0xff,0x75,0xcc,0xa3,0x00,0x10,0x08,0x01,0xff,0x75,0xcc,0x89,
-       0x00,0x01,0xff,0x75,0xcc,0x89,0x00,0xd2,0x28,0xd1,0x14,0x10,0x0a,0x01,0xff,0x75,
-       0xcc,0x9b,0xcc,0x81,0x00,0x01,0xff,0x75,0xcc,0x9b,0xcc,0x81,0x00,0x10,0x0a,0x01,
-       0xff,0x75,0xcc,0x9b,0xcc,0x80,0x00,0x01,0xff,0x75,0xcc,0x9b,0xcc,0x80,0x00,0xd1,
-       0x14,0x10,0x0a,0x01,0xff,0x75,0xcc,0x9b,0xcc,0x89,0x00,0x01,0xff,0x75,0xcc,0x9b,
-       0xcc,0x89,0x00,0x10,0x0a,0x01,0xff,0x75,0xcc,0x9b,0xcc,0x83,0x00,0x01,0xff,0x75,
-       0xcc,0x9b,0xcc,0x83,0x00,0xd3,0x44,0xd2,0x24,0xd1,0x14,0x10,0x0a,0x01,0xff,0x75,
-       0xcc,0x9b,0xcc,0xa3,0x00,0x01,0xff,0x75,0xcc,0x9b,0xcc,0xa3,0x00,0x10,0x08,0x01,
-       0xff,0x79,0xcc,0x80,0x00,0x01,0xff,0x79,0xcc,0x80,0x00,0xd1,0x10,0x10,0x08,0x01,
-       0xff,0x79,0xcc,0xa3,0x00,0x01,0xff,0x79,0xcc,0xa3,0x00,0x10,0x08,0x01,0xff,0x79,
-       0xcc,0x89,0x00,0x01,0xff,0x79,0xcc,0x89,0x00,0xd2,0x1c,0xd1,0x10,0x10,0x08,0x01,
-       0xff,0x79,0xcc,0x83,0x00,0x01,0xff,0x79,0xcc,0x83,0x00,0x10,0x08,0x0a,0xff,0xe1,
-       0xbb,0xbb,0x00,0x0a,0x00,0xd1,0x0c,0x10,0x08,0x0a,0xff,0xe1,0xbb,0xbd,0x00,0x0a,
-       0x00,0x10,0x08,0x0a,0xff,0xe1,0xbb,0xbf,0x00,0x0a,0x00,0xe1,0xbf,0x02,0xe0,0xa1,
-       0x01,0xcf,0x86,0xd5,0xc6,0xd4,0x6c,0xd3,0x18,0xe2,0x0e,0x59,0xe1,0xf7,0x58,0x10,
-       0x09,0x01,0xff,0xce,0xb1,0xcc,0x93,0x00,0x01,0xff,0xce,0xb1,0xcc,0x94,0x00,0xd2,
-       0x28,0xd1,0x12,0x10,0x09,0x01,0xff,0xce,0xb1,0xcc,0x93,0x00,0x01,0xff,0xce,0xb1,
-       0xcc,0x94,0x00,0x10,0x0b,0x01,0xff,0xce,0xb1,0xcc,0x93,0xcc,0x80,0x00,0x01,0xff,
-       0xce,0xb1,0xcc,0x94,0xcc,0x80,0x00,0xd1,0x16,0x10,0x0b,0x01,0xff,0xce,0xb1,0xcc,
-       0x93,0xcc,0x81,0x00,0x01,0xff,0xce,0xb1,0xcc,0x94,0xcc,0x81,0x00,0x10,0x0b,0x01,
-       0xff,0xce,0xb1,0xcc,0x93,0xcd,0x82,0x00,0x01,0xff,0xce,0xb1,0xcc,0x94,0xcd,0x82,
-       0x00,0xd3,0x18,0xe2,0x4a,0x59,0xe1,0x33,0x59,0x10,0x09,0x01,0xff,0xce,0xb5,0xcc,
-       0x93,0x00,0x01,0xff,0xce,0xb5,0xcc,0x94,0x00,0xd2,0x28,0xd1,0x12,0x10,0x09,0x01,
-       0xff,0xce,0xb5,0xcc,0x93,0x00,0x01,0xff,0xce,0xb5,0xcc,0x94,0x00,0x10,0x0b,0x01,
-       0xff,0xce,0xb5,0xcc,0x93,0xcc,0x80,0x00,0x01,0xff,0xce,0xb5,0xcc,0x94,0xcc,0x80,
-       0x00,0x91,0x16,0x10,0x0b,0x01,0xff,0xce,0xb5,0xcc,0x93,0xcc,0x81,0x00,0x01,0xff,
-       0xce,0xb5,0xcc,0x94,0xcc,0x81,0x00,0x00,0x00,0xd4,0x6c,0xd3,0x18,0xe2,0x74,0x59,
-       0xe1,0x5d,0x59,0x10,0x09,0x01,0xff,0xce,0xb7,0xcc,0x93,0x00,0x01,0xff,0xce,0xb7,
-       0xcc,0x94,0x00,0xd2,0x28,0xd1,0x12,0x10,0x09,0x01,0xff,0xce,0xb7,0xcc,0x93,0x00,
-       0x01,0xff,0xce,0xb7,0xcc,0x94,0x00,0x10,0x0b,0x01,0xff,0xce,0xb7,0xcc,0x93,0xcc,
-       0x80,0x00,0x01,0xff,0xce,0xb7,0xcc,0x94,0xcc,0x80,0x00,0xd1,0x16,0x10,0x0b,0x01,
-       0xff,0xce,0xb7,0xcc,0x93,0xcc,0x81,0x00,0x01,0xff,0xce,0xb7,0xcc,0x94,0xcc,0x81,
-       0x00,0x10,0x0b,0x01,0xff,0xce,0xb7,0xcc,0x93,0xcd,0x82,0x00,0x01,0xff,0xce,0xb7,
-       0xcc,0x94,0xcd,0x82,0x00,0xd3,0x18,0xe2,0xb0,0x59,0xe1,0x99,0x59,0x10,0x09,0x01,
-       0xff,0xce,0xb9,0xcc,0x93,0x00,0x01,0xff,0xce,0xb9,0xcc,0x94,0x00,0xd2,0x28,0xd1,
-       0x12,0x10,0x09,0x01,0xff,0xce,0xb9,0xcc,0x93,0x00,0x01,0xff,0xce,0xb9,0xcc,0x94,
-       0x00,0x10,0x0b,0x01,0xff,0xce,0xb9,0xcc,0x93,0xcc,0x80,0x00,0x01,0xff,0xce,0xb9,
-       0xcc,0x94,0xcc,0x80,0x00,0xd1,0x16,0x10,0x0b,0x01,0xff,0xce,0xb9,0xcc,0x93,0xcc,
-       0x81,0x00,0x01,0xff,0xce,0xb9,0xcc,0x94,0xcc,0x81,0x00,0x10,0x0b,0x01,0xff,0xce,
-       0xb9,0xcc,0x93,0xcd,0x82,0x00,0x01,0xff,0xce,0xb9,0xcc,0x94,0xcd,0x82,0x00,0xcf,
-       0x86,0xd5,0xac,0xd4,0x5a,0xd3,0x18,0xe2,0xed,0x59,0xe1,0xd6,0x59,0x10,0x09,0x01,
-       0xff,0xce,0xbf,0xcc,0x93,0x00,0x01,0xff,0xce,0xbf,0xcc,0x94,0x00,0xd2,0x28,0xd1,
-       0x12,0x10,0x09,0x01,0xff,0xce,0xbf,0xcc,0x93,0x00,0x01,0xff,0xce,0xbf,0xcc,0x94,
-       0x00,0x10,0x0b,0x01,0xff,0xce,0xbf,0xcc,0x93,0xcc,0x80,0x00,0x01,0xff,0xce,0xbf,
-       0xcc,0x94,0xcc,0x80,0x00,0x91,0x16,0x10,0x0b,0x01,0xff,0xce,0xbf,0xcc,0x93,0xcc,
-       0x81,0x00,0x01,0xff,0xce,0xbf,0xcc,0x94,0xcc,0x81,0x00,0x00,0x00,0xd3,0x18,0xe2,
-       0x17,0x5a,0xe1,0x00,0x5a,0x10,0x09,0x01,0xff,0xcf,0x85,0xcc,0x93,0x00,0x01,0xff,
-       0xcf,0x85,0xcc,0x94,0x00,0xd2,0x1c,0xd1,0x0d,0x10,0x04,0x00,0x00,0x01,0xff,0xcf,
-       0x85,0xcc,0x94,0x00,0x10,0x04,0x00,0x00,0x01,0xff,0xcf,0x85,0xcc,0x94,0xcc,0x80,
-       0x00,0xd1,0x0f,0x10,0x04,0x00,0x00,0x01,0xff,0xcf,0x85,0xcc,0x94,0xcc,0x81,0x00,
-       0x10,0x04,0x00,0x00,0x01,0xff,0xcf,0x85,0xcc,0x94,0xcd,0x82,0x00,0xe4,0xd3,0x5a,
-       0xd3,0x18,0xe2,0x52,0x5a,0xe1,0x3b,0x5a,0x10,0x09,0x01,0xff,0xcf,0x89,0xcc,0x93,
-       0x00,0x01,0xff,0xcf,0x89,0xcc,0x94,0x00,0xd2,0x28,0xd1,0x12,0x10,0x09,0x01,0xff,
-       0xcf,0x89,0xcc,0x93,0x00,0x01,0xff,0xcf,0x89,0xcc,0x94,0x00,0x10,0x0b,0x01,0xff,
-       0xcf,0x89,0xcc,0x93,0xcc,0x80,0x00,0x01,0xff,0xcf,0x89,0xcc,0x94,0xcc,0x80,0x00,
-       0xd1,0x16,0x10,0x0b,0x01,0xff,0xcf,0x89,0xcc,0x93,0xcc,0x81,0x00,0x01,0xff,0xcf,
-       0x89,0xcc,0x94,0xcc,0x81,0x00,0x10,0x0b,0x01,0xff,0xcf,0x89,0xcc,0x93,0xcd,0x82,
-       0x00,0x01,0xff,0xcf,0x89,0xcc,0x94,0xcd,0x82,0x00,0xe0,0xd9,0x02,0xcf,0x86,0xe5,
-       0x91,0x01,0xd4,0xc8,0xd3,0x64,0xd2,0x30,0xd1,0x16,0x10,0x0b,0x01,0xff,0xce,0xb1,
-       0xcc,0x93,0xce,0xb9,0x00,0x01,0xff,0xce,0xb1,0xcc,0x94,0xce,0xb9,0x00,0x10,0x0d,
-       0x01,0xff,0xce,0xb1,0xcc,0x93,0xcc,0x80,0xce,0xb9,0x00,0x01,0xff,0xce,0xb1,0xcc,
-       0x94,0xcc,0x80,0xce,0xb9,0x00,0xd1,0x1a,0x10,0x0d,0x01,0xff,0xce,0xb1,0xcc,0x93,
-       0xcc,0x81,0xce,0xb9,0x00,0x01,0xff,0xce,0xb1,0xcc,0x94,0xcc,0x81,0xce,0xb9,0x00,
-       0x10,0x0d,0x01,0xff,0xce,0xb1,0xcc,0x93,0xcd,0x82,0xce,0xb9,0x00,0x01,0xff,0xce,
-       0xb1,0xcc,0x94,0xcd,0x82,0xce,0xb9,0x00,0xd2,0x30,0xd1,0x16,0x10,0x0b,0x01,0xff,
-       0xce,0xb1,0xcc,0x93,0xce,0xb9,0x00,0x01,0xff,0xce,0xb1,0xcc,0x94,0xce,0xb9,0x00,
-       0x10,0x0d,0x01,0xff,0xce,0xb1,0xcc,0x93,0xcc,0x80,0xce,0xb9,0x00,0x01,0xff,0xce,
-       0xb1,0xcc,0x94,0xcc,0x80,0xce,0xb9,0x00,0xd1,0x1a,0x10,0x0d,0x01,0xff,0xce,0xb1,
-       0xcc,0x93,0xcc,0x81,0xce,0xb9,0x00,0x01,0xff,0xce,0xb1,0xcc,0x94,0xcc,0x81,0xce,
-       0xb9,0x00,0x10,0x0d,0x01,0xff,0xce,0xb1,0xcc,0x93,0xcd,0x82,0xce,0xb9,0x00,0x01,
-       0xff,0xce,0xb1,0xcc,0x94,0xcd,0x82,0xce,0xb9,0x00,0xd3,0x64,0xd2,0x30,0xd1,0x16,
-       0x10,0x0b,0x01,0xff,0xce,0xb7,0xcc,0x93,0xce,0xb9,0x00,0x01,0xff,0xce,0xb7,0xcc,
-       0x94,0xce,0xb9,0x00,0x10,0x0d,0x01,0xff,0xce,0xb7,0xcc,0x93,0xcc,0x80,0xce,0xb9,
-       0x00,0x01,0xff,0xce,0xb7,0xcc,0x94,0xcc,0x80,0xce,0xb9,0x00,0xd1,0x1a,0x10,0x0d,
-       0x01,0xff,0xce,0xb7,0xcc,0x93,0xcc,0x81,0xce,0xb9,0x00,0x01,0xff,0xce,0xb7,0xcc,
-       0x94,0xcc,0x81,0xce,0xb9,0x00,0x10,0x0d,0x01,0xff,0xce,0xb7,0xcc,0x93,0xcd,0x82,
-       0xce,0xb9,0x00,0x01,0xff,0xce,0xb7,0xcc,0x94,0xcd,0x82,0xce,0xb9,0x00,0xd2,0x30,
-       0xd1,0x16,0x10,0x0b,0x01,0xff,0xce,0xb7,0xcc,0x93,0xce,0xb9,0x00,0x01,0xff,0xce,
-       0xb7,0xcc,0x94,0xce,0xb9,0x00,0x10,0x0d,0x01,0xff,0xce,0xb7,0xcc,0x93,0xcc,0x80,
-       0xce,0xb9,0x00,0x01,0xff,0xce,0xb7,0xcc,0x94,0xcc,0x80,0xce,0xb9,0x00,0xd1,0x1a,
-       0x10,0x0d,0x01,0xff,0xce,0xb7,0xcc,0x93,0xcc,0x81,0xce,0xb9,0x00,0x01,0xff,0xce,
-       0xb7,0xcc,0x94,0xcc,0x81,0xce,0xb9,0x00,0x10,0x0d,0x01,0xff,0xce,0xb7,0xcc,0x93,
-       0xcd,0x82,0xce,0xb9,0x00,0x01,0xff,0xce,0xb7,0xcc,0x94,0xcd,0x82,0xce,0xb9,0x00,
-       0xd4,0xc8,0xd3,0x64,0xd2,0x30,0xd1,0x16,0x10,0x0b,0x01,0xff,0xcf,0x89,0xcc,0x93,
-       0xce,0xb9,0x00,0x01,0xff,0xcf,0x89,0xcc,0x94,0xce,0xb9,0x00,0x10,0x0d,0x01,0xff,
-       0xcf,0x89,0xcc,0x93,0xcc,0x80,0xce,0xb9,0x00,0x01,0xff,0xcf,0x89,0xcc,0x94,0xcc,
-       0x80,0xce,0xb9,0x00,0xd1,0x1a,0x10,0x0d,0x01,0xff,0xcf,0x89,0xcc,0x93,0xcc,0x81,
-       0xce,0xb9,0x00,0x01,0xff,0xcf,0x89,0xcc,0x94,0xcc,0x81,0xce,0xb9,0x00,0x10,0x0d,
-       0x01,0xff,0xcf,0x89,0xcc,0x93,0xcd,0x82,0xce,0xb9,0x00,0x01,0xff,0xcf,0x89,0xcc,
-       0x94,0xcd,0x82,0xce,0xb9,0x00,0xd2,0x30,0xd1,0x16,0x10,0x0b,0x01,0xff,0xcf,0x89,
-       0xcc,0x93,0xce,0xb9,0x00,0x01,0xff,0xcf,0x89,0xcc,0x94,0xce,0xb9,0x00,0x10,0x0d,
-       0x01,0xff,0xcf,0x89,0xcc,0x93,0xcc,0x80,0xce,0xb9,0x00,0x01,0xff,0xcf,0x89,0xcc,
-       0x94,0xcc,0x80,0xce,0xb9,0x00,0xd1,0x1a,0x10,0x0d,0x01,0xff,0xcf,0x89,0xcc,0x93,
-       0xcc,0x81,0xce,0xb9,0x00,0x01,0xff,0xcf,0x89,0xcc,0x94,0xcc,0x81,0xce,0xb9,0x00,
-       0x10,0x0d,0x01,0xff,0xcf,0x89,0xcc,0x93,0xcd,0x82,0xce,0xb9,0x00,0x01,0xff,0xcf,
-       0x89,0xcc,0x94,0xcd,0x82,0xce,0xb9,0x00,0xd3,0x49,0xd2,0x26,0xd1,0x12,0x10,0x09,
-       0x01,0xff,0xce,0xb1,0xcc,0x86,0x00,0x01,0xff,0xce,0xb1,0xcc,0x84,0x00,0x10,0x0b,
-       0x01,0xff,0xce,0xb1,0xcc,0x80,0xce,0xb9,0x00,0x01,0xff,0xce,0xb1,0xce,0xb9,0x00,
-       0xd1,0x0f,0x10,0x0b,0x01,0xff,0xce,0xb1,0xcc,0x81,0xce,0xb9,0x00,0x00,0x00,0x10,
-       0x09,0x01,0xff,0xce,0xb1,0xcd,0x82,0x00,0x01,0xff,0xce,0xb1,0xcd,0x82,0xce,0xb9,
-       0x00,0xd2,0x24,0xd1,0x12,0x10,0x09,0x01,0xff,0xce,0xb1,0xcc,0x86,0x00,0x01,0xff,
-       0xce,0xb1,0xcc,0x84,0x00,0x10,0x09,0x01,0xff,0xce,0xb1,0xcc,0x80,0x00,0x01,0xff,
-       0xce,0xb1,0xcc,0x81,0x00,0xe1,0xf3,0x5a,0x10,0x09,0x01,0xff,0xce,0xb1,0xce,0xb9,
-       0x00,0x01,0x00,0xcf,0x86,0xd5,0xbd,0xd4,0x7e,0xd3,0x44,0xd2,0x21,0xd1,0x0d,0x10,
-       0x04,0x01,0x00,0x01,0xff,0xc2,0xa8,0xcd,0x82,0x00,0x10,0x0b,0x01,0xff,0xce,0xb7,
-       0xcc,0x80,0xce,0xb9,0x00,0x01,0xff,0xce,0xb7,0xce,0xb9,0x00,0xd1,0x0f,0x10,0x0b,
-       0x01,0xff,0xce,0xb7,0xcc,0x81,0xce,0xb9,0x00,0x00,0x00,0x10,0x09,0x01,0xff,0xce,
-       0xb7,0xcd,0x82,0x00,0x01,0xff,0xce,0xb7,0xcd,0x82,0xce,0xb9,0x00,0xd2,0x24,0xd1,
-       0x12,0x10,0x09,0x01,0xff,0xce,0xb5,0xcc,0x80,0x00,0x01,0xff,0xce,0xb5,0xcc,0x81,
-       0x00,0x10,0x09,0x01,0xff,0xce,0xb7,0xcc,0x80,0x00,0x01,0xff,0xce,0xb7,0xcc,0x81,
-       0x00,0xe1,0x02,0x5b,0x10,0x09,0x01,0xff,0xce,0xb7,0xce,0xb9,0x00,0x01,0xff,0xe1,
-       0xbe,0xbf,0xcc,0x80,0x00,0xd3,0x18,0xe2,0x28,0x5b,0xe1,0x11,0x5b,0x10,0x09,0x01,
-       0xff,0xce,0xb9,0xcc,0x86,0x00,0x01,0xff,0xce,0xb9,0xcc,0x84,0x00,0xe2,0x4c,0x5b,
-       0xd1,0x12,0x10,0x09,0x01,0xff,0xce,0xb9,0xcc,0x86,0x00,0x01,0xff,0xce,0xb9,0xcc,
-       0x84,0x00,0x10,0x09,0x01,0xff,0xce,0xb9,0xcc,0x80,0x00,0x01,0xff,0xce,0xb9,0xcc,
-       0x81,0x00,0xd4,0x51,0xd3,0x18,0xe2,0x6f,0x5b,0xe1,0x58,0x5b,0x10,0x09,0x01,0xff,
-       0xcf,0x85,0xcc,0x86,0x00,0x01,0xff,0xcf,0x85,0xcc,0x84,0x00,0xd2,0x24,0xd1,0x12,
-       0x10,0x09,0x01,0xff,0xcf,0x85,0xcc,0x86,0x00,0x01,0xff,0xcf,0x85,0xcc,0x84,0x00,
-       0x10,0x09,0x01,0xff,0xcf,0x85,0xcc,0x80,0x00,0x01,0xff,0xcf,0x85,0xcc,0x81,0x00,
-       0xe1,0x8f,0x5b,0x10,0x09,0x01,0xff,0xcf,0x81,0xcc,0x94,0x00,0x01,0xff,0xc2,0xa8,
-       0xcc,0x80,0x00,0xd3,0x3b,0xd2,0x18,0x51,0x04,0x00,0x00,0x10,0x0b,0x01,0xff,0xcf,
-       0x89,0xcc,0x80,0xce,0xb9,0x00,0x01,0xff,0xcf,0x89,0xce,0xb9,0x00,0xd1,0x0f,0x10,
-       0x0b,0x01,0xff,0xcf,0x89,0xcc,0x81,0xce,0xb9,0x00,0x00,0x00,0x10,0x09,0x01,0xff,
-       0xcf,0x89,0xcd,0x82,0x00,0x01,0xff,0xcf,0x89,0xcd,0x82,0xce,0xb9,0x00,0xd2,0x24,
-       0xd1,0x12,0x10,0x09,0x01,0xff,0xce,0xbf,0xcc,0x80,0x00,0x01,0xff,0xce,0xbf,0xcc,
-       0x81,0x00,0x10,0x09,0x01,0xff,0xcf,0x89,0xcc,0x80,0x00,0x01,0xff,0xcf,0x89,0xcc,
-       0x81,0x00,0xe1,0x99,0x5b,0x10,0x09,0x01,0xff,0xcf,0x89,0xce,0xb9,0x00,0x01,0xff,
-       0xc2,0xb4,0x00,0xe0,0x0c,0x68,0xcf,0x86,0xe5,0x23,0x02,0xe4,0x25,0x01,0xe3,0x85,
-       0x5e,0xd2,0x2a,0xe1,0x5f,0x5c,0xe0,0xdd,0x5b,0xcf,0x86,0xe5,0xbb,0x5b,0x94,0x1b,
-       0xe3,0xa4,0x5b,0x92,0x14,0x91,0x10,0x10,0x08,0x01,0xff,0xe2,0x80,0x82,0x00,0x01,
-       0xff,0xe2,0x80,0x83,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0xd1,0xd6,0xd0,0x46,0xcf,
-       0x86,0x55,0x04,0x01,0x00,0xd4,0x29,0xd3,0x13,0x52,0x04,0x01,0x00,0x51,0x04,0x01,
-       0x00,0x10,0x07,0x01,0xff,0xcf,0x89,0x00,0x01,0x00,0x92,0x12,0x51,0x04,0x01,0x00,
-       0x10,0x06,0x01,0xff,0x6b,0x00,0x01,0xff,0x61,0xcc,0x8a,0x00,0x01,0x00,0xe3,0x25,
-       0x5d,0x92,0x10,0x51,0x04,0x01,0x00,0x10,0x08,0x01,0xff,0xe2,0x85,0x8e,0x00,0x01,
-       0x00,0x01,0x00,0xcf,0x86,0xd5,0x0a,0xe4,0x42,0x5d,0x63,0x2d,0x5d,0x06,0x00,0x94,
-       0x80,0xd3,0x40,0xd2,0x20,0xd1,0x10,0x10,0x08,0x01,0xff,0xe2,0x85,0xb0,0x00,0x01,
-       0xff,0xe2,0x85,0xb1,0x00,0x10,0x08,0x01,0xff,0xe2,0x85,0xb2,0x00,0x01,0xff,0xe2,
-       0x85,0xb3,0x00,0xd1,0x10,0x10,0x08,0x01,0xff,0xe2,0x85,0xb4,0x00,0x01,0xff,0xe2,
-       0x85,0xb5,0x00,0x10,0x08,0x01,0xff,0xe2,0x85,0xb6,0x00,0x01,0xff,0xe2,0x85,0xb7,
-       0x00,0xd2,0x20,0xd1,0x10,0x10,0x08,0x01,0xff,0xe2,0x85,0xb8,0x00,0x01,0xff,0xe2,
-       0x85,0xb9,0x00,0x10,0x08,0x01,0xff,0xe2,0x85,0xba,0x00,0x01,0xff,0xe2,0x85,0xbb,
-       0x00,0xd1,0x10,0x10,0x08,0x01,0xff,0xe2,0x85,0xbc,0x00,0x01,0xff,0xe2,0x85,0xbd,
-       0x00,0x10,0x08,0x01,0xff,0xe2,0x85,0xbe,0x00,0x01,0xff,0xe2,0x85,0xbf,0x00,0x01,
-       0x00,0xe0,0x34,0x5d,0xcf,0x86,0xe5,0x13,0x5d,0xe4,0xf2,0x5c,0xe3,0xe1,0x5c,0xe2,
-       0xd4,0x5c,0x51,0x04,0x01,0x00,0x10,0x04,0x01,0x00,0x04,0xff,0xe2,0x86,0x84,0x00,
-       0xe3,0x23,0x61,0xe2,0xf0,0x60,0xd1,0x0c,0xe0,0x9d,0x60,0xcf,0x86,0x65,0x7e,0x60,
-       0x01,0x00,0xd0,0x62,0xcf,0x86,0x55,0x04,0x01,0x00,0x54,0x04,0x01,0x00,0xd3,0x18,
-       0x52,0x04,0x01,0x00,0x51,0x04,0x01,0x00,0x10,0x08,0x01,0xff,0xe2,0x93,0x90,0x00,
-       0x01,0xff,0xe2,0x93,0x91,0x00,0xd2,0x20,0xd1,0x10,0x10,0x08,0x01,0xff,0xe2,0x93,
-       0x92,0x00,0x01,0xff,0xe2,0x93,0x93,0x00,0x10,0x08,0x01,0xff,0xe2,0x93,0x94,0x00,
-       0x01,0xff,0xe2,0x93,0x95,0x00,0xd1,0x10,0x10,0x08,0x01,0xff,0xe2,0x93,0x96,0x00,
-       0x01,0xff,0xe2,0x93,0x97,0x00,0x10,0x08,0x01,0xff,0xe2,0x93,0x98,0x00,0x01,0xff,
-       0xe2,0x93,0x99,0x00,0xcf,0x86,0xe5,0x57,0x60,0x94,0x80,0xd3,0x40,0xd2,0x20,0xd1,
-       0x10,0x10,0x08,0x01,0xff,0xe2,0x93,0x9a,0x00,0x01,0xff,0xe2,0x93,0x9b,0x00,0x10,
-       0x08,0x01,0xff,0xe2,0x93,0x9c,0x00,0x01,0xff,0xe2,0x93,0x9d,0x00,0xd1,0x10,0x10,
-       0x08,0x01,0xff,0xe2,0x93,0x9e,0x00,0x01,0xff,0xe2,0x93,0x9f,0x00,0x10,0x08,0x01,
-       0xff,0xe2,0x93,0xa0,0x00,0x01,0xff,0xe2,0x93,0xa1,0x00,0xd2,0x20,0xd1,0x10,0x10,
-       0x08,0x01,0xff,0xe2,0x93,0xa2,0x00,0x01,0xff,0xe2,0x93,0xa3,0x00,0x10,0x08,0x01,
-       0xff,0xe2,0x93,0xa4,0x00,0x01,0xff,0xe2,0x93,0xa5,0x00,0xd1,0x10,0x10,0x08,0x01,
-       0xff,0xe2,0x93,0xa6,0x00,0x01,0xff,0xe2,0x93,0xa7,0x00,0x10,0x08,0x01,0xff,0xe2,
-       0x93,0xa8,0x00,0x01,0xff,0xe2,0x93,0xa9,0x00,0x01,0x00,0xd4,0x0c,0xe3,0x33,0x62,
-       0xe2,0x2c,0x62,0xcf,0x06,0x04,0x00,0xe3,0x0c,0x65,0xe2,0xff,0x63,0xe1,0x2e,0x02,
-       0xe0,0x84,0x01,0xcf,0x86,0xe5,0x01,0x01,0xd4,0x80,0xd3,0x40,0xd2,0x20,0xd1,0x10,
-       0x10,0x08,0x08,0xff,0xe2,0xb0,0xb0,0x00,0x08,0xff,0xe2,0xb0,0xb1,0x00,0x10,0x08,
-       0x08,0xff,0xe2,0xb0,0xb2,0x00,0x08,0xff,0xe2,0xb0,0xb3,0x00,0xd1,0x10,0x10,0x08,
-       0x08,0xff,0xe2,0xb0,0xb4,0x00,0x08,0xff,0xe2,0xb0,0xb5,0x00,0x10,0x08,0x08,0xff,
-       0xe2,0xb0,0xb6,0x00,0x08,0xff,0xe2,0xb0,0xb7,0x00,0xd2,0x20,0xd1,0x10,0x10,0x08,
-       0x08,0xff,0xe2,0xb0,0xb8,0x00,0x08,0xff,0xe2,0xb0,0xb9,0x00,0x10,0x08,0x08,0xff,
-       0xe2,0xb0,0xba,0x00,0x08,0xff,0xe2,0xb0,0xbb,0x00,0xd1,0x10,0x10,0x08,0x08,0xff,
-       0xe2,0xb0,0xbc,0x00,0x08,0xff,0xe2,0xb0,0xbd,0x00,0x10,0x08,0x08,0xff,0xe2,0xb0,
-       0xbe,0x00,0x08,0xff,0xe2,0xb0,0xbf,0x00,0xd3,0x40,0xd2,0x20,0xd1,0x10,0x10,0x08,
-       0x08,0xff,0xe2,0xb1,0x80,0x00,0x08,0xff,0xe2,0xb1,0x81,0x00,0x10,0x08,0x08,0xff,
-       0xe2,0xb1,0x82,0x00,0x08,0xff,0xe2,0xb1,0x83,0x00,0xd1,0x10,0x10,0x08,0x08,0xff,
-       0xe2,0xb1,0x84,0x00,0x08,0xff,0xe2,0xb1,0x85,0x00,0x10,0x08,0x08,0xff,0xe2,0xb1,
-       0x86,0x00,0x08,0xff,0xe2,0xb1,0x87,0x00,0xd2,0x20,0xd1,0x10,0x10,0x08,0x08,0xff,
-       0xe2,0xb1,0x88,0x00,0x08,0xff,0xe2,0xb1,0x89,0x00,0x10,0x08,0x08,0xff,0xe2,0xb1,
-       0x8a,0x00,0x08,0xff,0xe2,0xb1,0x8b,0x00,0xd1,0x10,0x10,0x08,0x08,0xff,0xe2,0xb1,
-       0x8c,0x00,0x08,0xff,0xe2,0xb1,0x8d,0x00,0x10,0x08,0x08,0xff,0xe2,0xb1,0x8e,0x00,
-       0x08,0xff,0xe2,0xb1,0x8f,0x00,0x94,0x7c,0xd3,0x40,0xd2,0x20,0xd1,0x10,0x10,0x08,
-       0x08,0xff,0xe2,0xb1,0x90,0x00,0x08,0xff,0xe2,0xb1,0x91,0x00,0x10,0x08,0x08,0xff,
-       0xe2,0xb1,0x92,0x00,0x08,0xff,0xe2,0xb1,0x93,0x00,0xd1,0x10,0x10,0x08,0x08,0xff,
-       0xe2,0xb1,0x94,0x00,0x08,0xff,0xe2,0xb1,0x95,0x00,0x10,0x08,0x08,0xff,0xe2,0xb1,
-       0x96,0x00,0x08,0xff,0xe2,0xb1,0x97,0x00,0xd2,0x20,0xd1,0x10,0x10,0x08,0x08,0xff,
-       0xe2,0xb1,0x98,0x00,0x08,0xff,0xe2,0xb1,0x99,0x00,0x10,0x08,0x08,0xff,0xe2,0xb1,
-       0x9a,0x00,0x08,0xff,0xe2,0xb1,0x9b,0x00,0xd1,0x10,0x10,0x08,0x08,0xff,0xe2,0xb1,
-       0x9c,0x00,0x08,0xff,0xe2,0xb1,0x9d,0x00,0x10,0x08,0x08,0xff,0xe2,0xb1,0x9e,0x00,
-       0x00,0x00,0x08,0x00,0xcf,0x86,0xd5,0x07,0x64,0xef,0x61,0x08,0x00,0xd4,0x63,0xd3,
-       0x32,0xd2,0x1b,0xd1,0x0c,0x10,0x08,0x09,0xff,0xe2,0xb1,0xa1,0x00,0x09,0x00,0x10,
-       0x07,0x09,0xff,0xc9,0xab,0x00,0x09,0xff,0xe1,0xb5,0xbd,0x00,0xd1,0x0b,0x10,0x07,
-       0x09,0xff,0xc9,0xbd,0x00,0x09,0x00,0x10,0x04,0x09,0x00,0x09,0xff,0xe2,0xb1,0xa8,
-       0x00,0xd2,0x18,0xd1,0x0c,0x10,0x04,0x09,0x00,0x09,0xff,0xe2,0xb1,0xaa,0x00,0x10,
-       0x04,0x09,0x00,0x09,0xff,0xe2,0xb1,0xac,0x00,0xd1,0x0b,0x10,0x04,0x09,0x00,0x0a,
-       0xff,0xc9,0x91,0x00,0x10,0x07,0x0a,0xff,0xc9,0xb1,0x00,0x0a,0xff,0xc9,0x90,0x00,
-       0xd3,0x27,0xd2,0x17,0xd1,0x0b,0x10,0x07,0x0b,0xff,0xc9,0x92,0x00,0x0a,0x00,0x10,
-       0x08,0x0a,0xff,0xe2,0xb1,0xb3,0x00,0x0a,0x00,0x91,0x0c,0x10,0x04,0x09,0x00,0x09,
-       0xff,0xe2,0xb1,0xb6,0x00,0x09,0x00,0x52,0x04,0x0a,0x00,0x51,0x04,0x0a,0x00,0x10,
-       0x07,0x0b,0xff,0xc8,0xbf,0x00,0x0b,0xff,0xc9,0x80,0x00,0xe0,0x83,0x01,0xcf,0x86,
-       0xd5,0xc0,0xd4,0x60,0xd3,0x30,0xd2,0x18,0xd1,0x0c,0x10,0x08,0x08,0xff,0xe2,0xb2,
-       0x81,0x00,0x08,0x00,0x10,0x08,0x08,0xff,0xe2,0xb2,0x83,0x00,0x08,0x00,0xd1,0x0c,
-       0x10,0x08,0x08,0xff,0xe2,0xb2,0x85,0x00,0x08,0x00,0x10,0x08,0x08,0xff,0xe2,0xb2,
-       0x87,0x00,0x08,0x00,0xd2,0x18,0xd1,0x0c,0x10,0x08,0x08,0xff,0xe2,0xb2,0x89,0x00,
-       0x08,0x00,0x10,0x08,0x08,0xff,0xe2,0xb2,0x8b,0x00,0x08,0x00,0xd1,0x0c,0x10,0x08,
-       0x08,0xff,0xe2,0xb2,0x8d,0x00,0x08,0x00,0x10,0x08,0x08,0xff,0xe2,0xb2,0x8f,0x00,
-       0x08,0x00,0xd3,0x30,0xd2,0x18,0xd1,0x0c,0x10,0x08,0x08,0xff,0xe2,0xb2,0x91,0x00,
-       0x08,0x00,0x10,0x08,0x08,0xff,0xe2,0xb2,0x93,0x00,0x08,0x00,0xd1,0x0c,0x10,0x08,
-       0x08,0xff,0xe2,0xb2,0x95,0x00,0x08,0x00,0x10,0x08,0x08,0xff,0xe2,0xb2,0x97,0x00,
-       0x08,0x00,0xd2,0x18,0xd1,0x0c,0x10,0x08,0x08,0xff,0xe2,0xb2,0x99,0x00,0x08,0x00,
-       0x10,0x08,0x08,0xff,0xe2,0xb2,0x9b,0x00,0x08,0x00,0xd1,0x0c,0x10,0x08,0x08,0xff,
-       0xe2,0xb2,0x9d,0x00,0x08,0x00,0x10,0x08,0x08,0xff,0xe2,0xb2,0x9f,0x00,0x08,0x00,
-       0xd4,0x60,0xd3,0x30,0xd2,0x18,0xd1,0x0c,0x10,0x08,0x08,0xff,0xe2,0xb2,0xa1,0x00,
-       0x08,0x00,0x10,0x08,0x08,0xff,0xe2,0xb2,0xa3,0x00,0x08,0x00,0xd1,0x0c,0x10,0x08,
-       0x08,0xff,0xe2,0xb2,0xa5,0x00,0x08,0x00,0x10,0x08,0x08,0xff,0xe2,0xb2,0xa7,0x00,
-       0x08,0x00,0xd2,0x18,0xd1,0x0c,0x10,0x08,0x08,0xff,0xe2,0xb2,0xa9,0x00,0x08,0x00,
-       0x10,0x08,0x08,0xff,0xe2,0xb2,0xab,0x00,0x08,0x00,0xd1,0x0c,0x10,0x08,0x08,0xff,
-       0xe2,0xb2,0xad,0x00,0x08,0x00,0x10,0x08,0x08,0xff,0xe2,0xb2,0xaf,0x00,0x08,0x00,
-       0xd3,0x30,0xd2,0x18,0xd1,0x0c,0x10,0x08,0x08,0xff,0xe2,0xb2,0xb1,0x00,0x08,0x00,
-       0x10,0x08,0x08,0xff,0xe2,0xb2,0xb3,0x00,0x08,0x00,0xd1,0x0c,0x10,0x08,0x08,0xff,
-       0xe2,0xb2,0xb5,0x00,0x08,0x00,0x10,0x08,0x08,0xff,0xe2,0xb2,0xb7,0x00,0x08,0x00,
-       0xd2,0x18,0xd1,0x0c,0x10,0x08,0x08,0xff,0xe2,0xb2,0xb9,0x00,0x08,0x00,0x10,0x08,
-       0x08,0xff,0xe2,0xb2,0xbb,0x00,0x08,0x00,0xd1,0x0c,0x10,0x08,0x08,0xff,0xe2,0xb2,
-       0xbd,0x00,0x08,0x00,0x10,0x08,0x08,0xff,0xe2,0xb2,0xbf,0x00,0x08,0x00,0xcf,0x86,
-       0xd5,0xc0,0xd4,0x60,0xd3,0x30,0xd2,0x18,0xd1,0x0c,0x10,0x08,0x08,0xff,0xe2,0xb3,
-       0x81,0x00,0x08,0x00,0x10,0x08,0x08,0xff,0xe2,0xb3,0x83,0x00,0x08,0x00,0xd1,0x0c,
-       0x10,0x08,0x08,0xff,0xe2,0xb3,0x85,0x00,0x08,0x00,0x10,0x08,0x08,0xff,0xe2,0xb3,
-       0x87,0x00,0x08,0x00,0xd2,0x18,0xd1,0x0c,0x10,0x08,0x08,0xff,0xe2,0xb3,0x89,0x00,
-       0x08,0x00,0x10,0x08,0x08,0xff,0xe2,0xb3,0x8b,0x00,0x08,0x00,0xd1,0x0c,0x10,0x08,
-       0x08,0xff,0xe2,0xb3,0x8d,0x00,0x08,0x00,0x10,0x08,0x08,0xff,0xe2,0xb3,0x8f,0x00,
-       0x08,0x00,0xd3,0x30,0xd2,0x18,0xd1,0x0c,0x10,0x08,0x08,0xff,0xe2,0xb3,0x91,0x00,
-       0x08,0x00,0x10,0x08,0x08,0xff,0xe2,0xb3,0x93,0x00,0x08,0x00,0xd1,0x0c,0x10,0x08,
-       0x08,0xff,0xe2,0xb3,0x95,0x00,0x08,0x00,0x10,0x08,0x08,0xff,0xe2,0xb3,0x97,0x00,
-       0x08,0x00,0xd2,0x18,0xd1,0x0c,0x10,0x08,0x08,0xff,0xe2,0xb3,0x99,0x00,0x08,0x00,
-       0x10,0x08,0x08,0xff,0xe2,0xb3,0x9b,0x00,0x08,0x00,0xd1,0x0c,0x10,0x08,0x08,0xff,
-       0xe2,0xb3,0x9d,0x00,0x08,0x00,0x10,0x08,0x08,0xff,0xe2,0xb3,0x9f,0x00,0x08,0x00,
-       0xd4,0x3b,0xd3,0x1c,0x92,0x18,0xd1,0x0c,0x10,0x08,0x08,0xff,0xe2,0xb3,0xa1,0x00,
-       0x08,0x00,0x10,0x08,0x08,0xff,0xe2,0xb3,0xa3,0x00,0x08,0x00,0x08,0x00,0xd2,0x10,
-       0x51,0x04,0x08,0x00,0x10,0x04,0x08,0x00,0x0b,0xff,0xe2,0xb3,0xac,0x00,0xe1,0x3b,
-       0x5f,0x10,0x04,0x0b,0x00,0x0b,0xff,0xe2,0xb3,0xae,0x00,0xe3,0x40,0x5f,0x92,0x10,
-       0x51,0x04,0x0b,0xe6,0x10,0x08,0x0d,0xff,0xe2,0xb3,0xb3,0x00,0x0d,0x00,0x00,0x00,
-       0xe2,0x98,0x08,0xd1,0x0b,0xe0,0x11,0x67,0xcf,0x86,0xcf,0x06,0x01,0x00,0xe0,0x65,
-       0x6c,0xcf,0x86,0xe5,0xa7,0x05,0xd4,0x06,0xcf,0x06,0x04,0x00,0xd3,0x0c,0xe2,0xf8,
-       0x67,0xe1,0x8f,0x67,0xcf,0x06,0x04,0x00,0xe2,0xdb,0x01,0xe1,0x26,0x01,0xd0,0x09,
-       0xcf,0x86,0x65,0xf4,0x67,0x0a,0x00,0xcf,0x86,0xd5,0xc0,0xd4,0x60,0xd3,0x30,0xd2,
-       0x18,0xd1,0x0c,0x10,0x08,0x0a,0xff,0xea,0x99,0x81,0x00,0x0a,0x00,0x10,0x08,0x0a,
-       0xff,0xea,0x99,0x83,0x00,0x0a,0x00,0xd1,0x0c,0x10,0x08,0x0a,0xff,0xea,0x99,0x85,
-       0x00,0x0a,0x00,0x10,0x08,0x0a,0xff,0xea,0x99,0x87,0x00,0x0a,0x00,0xd2,0x18,0xd1,
-       0x0c,0x10,0x08,0x0a,0xff,0xea,0x99,0x89,0x00,0x0a,0x00,0x10,0x08,0x0a,0xff,0xea,
-       0x99,0x8b,0x00,0x0a,0x00,0xd1,0x0c,0x10,0x08,0x0a,0xff,0xea,0x99,0x8d,0x00,0x0a,
-       0x00,0x10,0x08,0x0a,0xff,0xea,0x99,0x8f,0x00,0x0a,0x00,0xd3,0x30,0xd2,0x18,0xd1,
-       0x0c,0x10,0x08,0x0a,0xff,0xea,0x99,0x91,0x00,0x0a,0x00,0x10,0x08,0x0a,0xff,0xea,
-       0x99,0x93,0x00,0x0a,0x00,0xd1,0x0c,0x10,0x08,0x0a,0xff,0xea,0x99,0x95,0x00,0x0a,
-       0x00,0x10,0x08,0x0a,0xff,0xea,0x99,0x97,0x00,0x0a,0x00,0xd2,0x18,0xd1,0x0c,0x10,
-       0x08,0x0a,0xff,0xea,0x99,0x99,0x00,0x0a,0x00,0x10,0x08,0x0a,0xff,0xea,0x99,0x9b,
-       0x00,0x0a,0x00,0xd1,0x0c,0x10,0x08,0x0a,0xff,0xea,0x99,0x9d,0x00,0x0a,0x00,0x10,
-       0x08,0x0a,0xff,0xea,0x99,0x9f,0x00,0x0a,0x00,0xe4,0x5d,0x67,0xd3,0x30,0xd2,0x18,
-       0xd1,0x0c,0x10,0x08,0x0c,0xff,0xea,0x99,0xa1,0x00,0x0c,0x00,0x10,0x08,0x0a,0xff,
-       0xea,0x99,0xa3,0x00,0x0a,0x00,0xd1,0x0c,0x10,0x08,0x0a,0xff,0xea,0x99,0xa5,0x00,
-       0x0a,0x00,0x10,0x08,0x0a,0xff,0xea,0x99,0xa7,0x00,0x0a,0x00,0xd2,0x18,0xd1,0x0c,
-       0x10,0x08,0x0a,0xff,0xea,0x99,0xa9,0x00,0x0a,0x00,0x10,0x08,0x0a,0xff,0xea,0x99,
-       0xab,0x00,0x0a,0x00,0xe1,0x0c,0x67,0x10,0x08,0x0a,0xff,0xea,0x99,0xad,0x00,0x0a,
-       0x00,0xe0,0x35,0x67,0xcf,0x86,0x95,0xab,0xd4,0x60,0xd3,0x30,0xd2,0x18,0xd1,0x0c,
-       0x10,0x08,0x0a,0xff,0xea,0x9a,0x81,0x00,0x0a,0x00,0x10,0x08,0x0a,0xff,0xea,0x9a,
-       0x83,0x00,0x0a,0x00,0xd1,0x0c,0x10,0x08,0x0a,0xff,0xea,0x9a,0x85,0x00,0x0a,0x00,
-       0x10,0x08,0x0a,0xff,0xea,0x9a,0x87,0x00,0x0a,0x00,0xd2,0x18,0xd1,0x0c,0x10,0x08,
-       0x0a,0xff,0xea,0x9a,0x89,0x00,0x0a,0x00,0x10,0x08,0x0a,0xff,0xea,0x9a,0x8b,0x00,
-       0x0a,0x00,0xd1,0x0c,0x10,0x08,0x0a,0xff,0xea,0x9a,0x8d,0x00,0x0a,0x00,0x10,0x08,
-       0x0a,0xff,0xea,0x9a,0x8f,0x00,0x0a,0x00,0xd3,0x30,0xd2,0x18,0xd1,0x0c,0x10,0x08,
-       0x0a,0xff,0xea,0x9a,0x91,0x00,0x0a,0x00,0x10,0x08,0x0a,0xff,0xea,0x9a,0x93,0x00,
-       0x0a,0x00,0xd1,0x0c,0x10,0x08,0x0a,0xff,0xea,0x9a,0x95,0x00,0x0a,0x00,0x10,0x08,
-       0x0a,0xff,0xea,0x9a,0x97,0x00,0x0a,0x00,0xe2,0x92,0x66,0xd1,0x0c,0x10,0x08,0x10,
-       0xff,0xea,0x9a,0x99,0x00,0x10,0x00,0x10,0x08,0x10,0xff,0xea,0x9a,0x9b,0x00,0x10,
-       0x00,0x0b,0x00,0xe1,0x10,0x02,0xd0,0xb9,0xcf,0x86,0xd5,0x07,0x64,0x9e,0x66,0x08,
-       0x00,0xd4,0x58,0xd3,0x28,0xd2,0x10,0x51,0x04,0x09,0x00,0x10,0x08,0x0a,0xff,0xea,
-       0x9c,0xa3,0x00,0x0a,0x00,0xd1,0x0c,0x10,0x08,0x0a,0xff,0xea,0x9c,0xa5,0x00,0x0a,
-       0x00,0x10,0x08,0x0a,0xff,0xea,0x9c,0xa7,0x00,0x0a,0x00,0xd2,0x18,0xd1,0x0c,0x10,
-       0x08,0x0a,0xff,0xea,0x9c,0xa9,0x00,0x0a,0x00,0x10,0x08,0x0a,0xff,0xea,0x9c,0xab,
-       0x00,0x0a,0x00,0xd1,0x0c,0x10,0x08,0x0a,0xff,0xea,0x9c,0xad,0x00,0x0a,0x00,0x10,
-       0x08,0x0a,0xff,0xea,0x9c,0xaf,0x00,0x0a,0x00,0xd3,0x28,0xd2,0x10,0x51,0x04,0x0a,
-       0x00,0x10,0x08,0x0a,0xff,0xea,0x9c,0xb3,0x00,0x0a,0x00,0xd1,0x0c,0x10,0x08,0x0a,
-       0xff,0xea,0x9c,0xb5,0x00,0x0a,0x00,0x10,0x08,0x0a,0xff,0xea,0x9c,0xb7,0x00,0x0a,
-       0x00,0xd2,0x18,0xd1,0x0c,0x10,0x08,0x0a,0xff,0xea,0x9c,0xb9,0x00,0x0a,0x00,0x10,
-       0x08,0x0a,0xff,0xea,0x9c,0xbb,0x00,0x0a,0x00,0xd1,0x0c,0x10,0x08,0x0a,0xff,0xea,
-       0x9c,0xbd,0x00,0x0a,0x00,0x10,0x08,0x0a,0xff,0xea,0x9c,0xbf,0x00,0x0a,0x00,0xcf,
-       0x86,0xd5,0xc0,0xd4,0x60,0xd3,0x30,0xd2,0x18,0xd1,0x0c,0x10,0x08,0x0a,0xff,0xea,
-       0x9d,0x81,0x00,0x0a,0x00,0x10,0x08,0x0a,0xff,0xea,0x9d,0x83,0x00,0x0a,0x00,0xd1,
-       0x0c,0x10,0x08,0x0a,0xff,0xea,0x9d,0x85,0x00,0x0a,0x00,0x10,0x08,0x0a,0xff,0xea,
-       0x9d,0x87,0x00,0x0a,0x00,0xd2,0x18,0xd1,0x0c,0x10,0x08,0x0a,0xff,0xea,0x9d,0x89,
-       0x00,0x0a,0x00,0x10,0x08,0x0a,0xff,0xea,0x9d,0x8b,0x00,0x0a,0x00,0xd1,0x0c,0x10,
-       0x08,0x0a,0xff,0xea,0x9d,0x8d,0x00,0x0a,0x00,0x10,0x08,0x0a,0xff,0xea,0x9d,0x8f,
-       0x00,0x0a,0x00,0xd3,0x30,0xd2,0x18,0xd1,0x0c,0x10,0x08,0x0a,0xff,0xea,0x9d,0x91,
-       0x00,0x0a,0x00,0x10,0x08,0x0a,0xff,0xea,0x9d,0x93,0x00,0x0a,0x00,0xd1,0x0c,0x10,
-       0x08,0x0a,0xff,0xea,0x9d,0x95,0x00,0x0a,0x00,0x10,0x08,0x0a,0xff,0xea,0x9d,0x97,
-       0x00,0x0a,0x00,0xd2,0x18,0xd1,0x0c,0x10,0x08,0x0a,0xff,0xea,0x9d,0x99,0x00,0x0a,
-       0x00,0x10,0x08,0x0a,0xff,0xea,0x9d,0x9b,0x00,0x0a,0x00,0xd1,0x0c,0x10,0x08,0x0a,
-       0xff,0xea,0x9d,0x9d,0x00,0x0a,0x00,0x10,0x08,0x0a,0xff,0xea,0x9d,0x9f,0x00,0x0a,
-       0x00,0xd4,0x60,0xd3,0x30,0xd2,0x18,0xd1,0x0c,0x10,0x08,0x0a,0xff,0xea,0x9d,0xa1,
-       0x00,0x0a,0x00,0x10,0x08,0x0a,0xff,0xea,0x9d,0xa3,0x00,0x0a,0x00,0xd1,0x0c,0x10,
-       0x08,0x0a,0xff,0xea,0x9d,0xa5,0x00,0x0a,0x00,0x10,0x08,0x0a,0xff,0xea,0x9d,0xa7,
-       0x00,0x0a,0x00,0xd2,0x18,0xd1,0x0c,0x10,0x08,0x0a,0xff,0xea,0x9d,0xa9,0x00,0x0a,
-       0x00,0x10,0x08,0x0a,0xff,0xea,0x9d,0xab,0x00,0x0a,0x00,0xd1,0x0c,0x10,0x08,0x0a,
-       0xff,0xea,0x9d,0xad,0x00,0x0a,0x00,0x10,0x08,0x0a,0xff,0xea,0x9d,0xaf,0x00,0x0a,
-       0x00,0x53,0x04,0x0a,0x00,0xd2,0x18,0xd1,0x0c,0x10,0x04,0x0a,0x00,0x0a,0xff,0xea,
-       0x9d,0xba,0x00,0x10,0x04,0x0a,0x00,0x0a,0xff,0xea,0x9d,0xbc,0x00,0xd1,0x0c,0x10,
-       0x04,0x0a,0x00,0x0a,0xff,0xe1,0xb5,0xb9,0x00,0x10,0x08,0x0a,0xff,0xea,0x9d,0xbf,
-       0x00,0x0a,0x00,0xe0,0x71,0x01,0xcf,0x86,0xd5,0xa6,0xd4,0x4e,0xd3,0x30,0xd2,0x18,
-       0xd1,0x0c,0x10,0x08,0x0a,0xff,0xea,0x9e,0x81,0x00,0x0a,0x00,0x10,0x08,0x0a,0xff,
-       0xea,0x9e,0x83,0x00,0x0a,0x00,0xd1,0x0c,0x10,0x08,0x0a,0xff,0xea,0x9e,0x85,0x00,
-       0x0a,0x00,0x10,0x08,0x0a,0xff,0xea,0x9e,0x87,0x00,0x0a,0x00,0xd2,0x10,0x51,0x04,
-       0x0a,0x00,0x10,0x04,0x0a,0x00,0x0a,0xff,0xea,0x9e,0x8c,0x00,0xe1,0x9a,0x64,0x10,
-       0x04,0x0a,0x00,0x0c,0xff,0xc9,0xa5,0x00,0xd3,0x28,0xd2,0x18,0xd1,0x0c,0x10,0x08,
-       0x0c,0xff,0xea,0x9e,0x91,0x00,0x0c,0x00,0x10,0x08,0x0d,0xff,0xea,0x9e,0x93,0x00,
-       0x0d,0x00,0x51,0x04,0x10,0x00,0x10,0x08,0x10,0xff,0xea,0x9e,0x97,0x00,0x10,0x00,
-       0xd2,0x18,0xd1,0x0c,0x10,0x08,0x10,0xff,0xea,0x9e,0x99,0x00,0x10,0x00,0x10,0x08,
-       0x10,0xff,0xea,0x9e,0x9b,0x00,0x10,0x00,0xd1,0x0c,0x10,0x08,0x10,0xff,0xea,0x9e,
-       0x9d,0x00,0x10,0x00,0x10,0x08,0x10,0xff,0xea,0x9e,0x9f,0x00,0x10,0x00,0xd4,0x63,
-       0xd3,0x30,0xd2,0x18,0xd1,0x0c,0x10,0x08,0x0c,0xff,0xea,0x9e,0xa1,0x00,0x0c,0x00,
-       0x10,0x08,0x0c,0xff,0xea,0x9e,0xa3,0x00,0x0c,0x00,0xd1,0x0c,0x10,0x08,0x0c,0xff,
-       0xea,0x9e,0xa5,0x00,0x0c,0x00,0x10,0x08,0x0c,0xff,0xea,0x9e,0xa7,0x00,0x0c,0x00,
-       0xd2,0x1a,0xd1,0x0c,0x10,0x08,0x0c,0xff,0xea,0x9e,0xa9,0x00,0x0c,0x00,0x10,0x07,
-       0x0d,0xff,0xc9,0xa6,0x00,0x10,0xff,0xc9,0x9c,0x00,0xd1,0x0e,0x10,0x07,0x10,0xff,
-       0xc9,0xa1,0x00,0x10,0xff,0xc9,0xac,0x00,0x10,0x07,0x12,0xff,0xc9,0xaa,0x00,0x14,
-       0x00,0xd3,0x35,0xd2,0x1d,0xd1,0x0e,0x10,0x07,0x10,0xff,0xca,0x9e,0x00,0x10,0xff,
-       0xca,0x87,0x00,0x10,0x07,0x11,0xff,0xca,0x9d,0x00,0x11,0xff,0xea,0xad,0x93,0x00,
-       0xd1,0x0c,0x10,0x08,0x11,0xff,0xea,0x9e,0xb5,0x00,0x11,0x00,0x10,0x08,0x11,0xff,
-       0xea,0x9e,0xb7,0x00,0x11,0x00,0xd2,0x18,0xd1,0x0c,0x10,0x08,0x14,0xff,0xea,0x9e,
-       0xb9,0x00,0x14,0x00,0x10,0x08,0x15,0xff,0xea,0x9e,0xbb,0x00,0x15,0x00,0xd1,0x0c,
-       0x10,0x08,0x15,0xff,0xea,0x9e,0xbd,0x00,0x15,0x00,0x10,0x08,0x15,0xff,0xea,0x9e,
-       0xbf,0x00,0x15,0x00,0xcf,0x86,0xe5,0xd4,0x63,0x94,0x2f,0x93,0x2b,0xd2,0x10,0x51,
-       0x04,0x00,0x00,0x10,0x08,0x15,0xff,0xea,0x9f,0x83,0x00,0x15,0x00,0xd1,0x0f,0x10,
-       0x08,0x15,0xff,0xea,0x9e,0x94,0x00,0x15,0xff,0xca,0x82,0x00,0x10,0x08,0x15,0xff,
-       0xe1,0xb6,0x8e,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe4,0xb4,0x66,0xd3,0x1d,0xe2,
-       0x5b,0x64,0xe1,0x0a,0x64,0xe0,0xf7,0x63,0xcf,0x86,0xe5,0xd8,0x63,0x94,0x0b,0x93,
-       0x07,0x62,0xc3,0x63,0x08,0x00,0x08,0x00,0x08,0x00,0xd2,0x0f,0xe1,0x5a,0x65,0xe0,
-       0x27,0x65,0xcf,0x86,0x65,0x0c,0x65,0x0a,0x00,0xd1,0xab,0xd0,0x1a,0xcf,0x86,0xe5,
-       0x17,0x66,0xe4,0xfa,0x65,0xe3,0xe1,0x65,0xe2,0xd4,0x65,0x91,0x08,0x10,0x04,0x00,
-       0x00,0x0c,0x00,0x0c,0x00,0xcf,0x86,0x55,0x04,0x10,0x00,0xd4,0x0b,0x93,0x07,0x62,
-       0x27,0x66,0x11,0x00,0x00,0x00,0xd3,0x40,0xd2,0x20,0xd1,0x10,0x10,0x08,0x11,0xff,
-       0xe1,0x8e,0xa0,0x00,0x11,0xff,0xe1,0x8e,0xa1,0x00,0x10,0x08,0x11,0xff,0xe1,0x8e,
-       0xa2,0x00,0x11,0xff,0xe1,0x8e,0xa3,0x00,0xd1,0x10,0x10,0x08,0x11,0xff,0xe1,0x8e,
-       0xa4,0x00,0x11,0xff,0xe1,0x8e,0xa5,0x00,0x10,0x08,0x11,0xff,0xe1,0x8e,0xa6,0x00,
-       0x11,0xff,0xe1,0x8e,0xa7,0x00,0xd2,0x20,0xd1,0x10,0x10,0x08,0x11,0xff,0xe1,0x8e,
-       0xa8,0x00,0x11,0xff,0xe1,0x8e,0xa9,0x00,0x10,0x08,0x11,0xff,0xe1,0x8e,0xaa,0x00,
-       0x11,0xff,0xe1,0x8e,0xab,0x00,0xd1,0x10,0x10,0x08,0x11,0xff,0xe1,0x8e,0xac,0x00,
-       0x11,0xff,0xe1,0x8e,0xad,0x00,0x10,0x08,0x11,0xff,0xe1,0x8e,0xae,0x00,0x11,0xff,
-       0xe1,0x8e,0xaf,0x00,0xe0,0xb2,0x65,0xcf,0x86,0xe5,0x01,0x01,0xd4,0x80,0xd3,0x40,
-       0xd2,0x20,0xd1,0x10,0x10,0x08,0x11,0xff,0xe1,0x8e,0xb0,0x00,0x11,0xff,0xe1,0x8e,
-       0xb1,0x00,0x10,0x08,0x11,0xff,0xe1,0x8e,0xb2,0x00,0x11,0xff,0xe1,0x8e,0xb3,0x00,
-       0xd1,0x10,0x10,0x08,0x11,0xff,0xe1,0x8e,0xb4,0x00,0x11,0xff,0xe1,0x8e,0xb5,0x00,
-       0x10,0x08,0x11,0xff,0xe1,0x8e,0xb6,0x00,0x11,0xff,0xe1,0x8e,0xb7,0x00,0xd2,0x20,
-       0xd1,0x10,0x10,0x08,0x11,0xff,0xe1,0x8e,0xb8,0x00,0x11,0xff,0xe1,0x8e,0xb9,0x00,
-       0x10,0x08,0x11,0xff,0xe1,0x8e,0xba,0x00,0x11,0xff,0xe1,0x8e,0xbb,0x00,0xd1,0x10,
-       0x10,0x08,0x11,0xff,0xe1,0x8e,0xbc,0x00,0x11,0xff,0xe1,0x8e,0xbd,0x00,0x10,0x08,
-       0x11,0xff,0xe1,0x8e,0xbe,0x00,0x11,0xff,0xe1,0x8e,0xbf,0x00,0xd3,0x40,0xd2,0x20,
-       0xd1,0x10,0x10,0x08,0x11,0xff,0xe1,0x8f,0x80,0x00,0x11,0xff,0xe1,0x8f,0x81,0x00,
-       0x10,0x08,0x11,0xff,0xe1,0x8f,0x82,0x00,0x11,0xff,0xe1,0x8f,0x83,0x00,0xd1,0x10,
-       0x10,0x08,0x11,0xff,0xe1,0x8f,0x84,0x00,0x11,0xff,0xe1,0x8f,0x85,0x00,0x10,0x08,
-       0x11,0xff,0xe1,0x8f,0x86,0x00,0x11,0xff,0xe1,0x8f,0x87,0x00,0xd2,0x20,0xd1,0x10,
-       0x10,0x08,0x11,0xff,0xe1,0x8f,0x88,0x00,0x11,0xff,0xe1,0x8f,0x89,0x00,0x10,0x08,
-       0x11,0xff,0xe1,0x8f,0x8a,0x00,0x11,0xff,0xe1,0x8f,0x8b,0x00,0xd1,0x10,0x10,0x08,
-       0x11,0xff,0xe1,0x8f,0x8c,0x00,0x11,0xff,0xe1,0x8f,0x8d,0x00,0x10,0x08,0x11,0xff,
-       0xe1,0x8f,0x8e,0x00,0x11,0xff,0xe1,0x8f,0x8f,0x00,0xd4,0x80,0xd3,0x40,0xd2,0x20,
-       0xd1,0x10,0x10,0x08,0x11,0xff,0xe1,0x8f,0x90,0x00,0x11,0xff,0xe1,0x8f,0x91,0x00,
-       0x10,0x08,0x11,0xff,0xe1,0x8f,0x92,0x00,0x11,0xff,0xe1,0x8f,0x93,0x00,0xd1,0x10,
-       0x10,0x08,0x11,0xff,0xe1,0x8f,0x94,0x00,0x11,0xff,0xe1,0x8f,0x95,0x00,0x10,0x08,
-       0x11,0xff,0xe1,0x8f,0x96,0x00,0x11,0xff,0xe1,0x8f,0x97,0x00,0xd2,0x20,0xd1,0x10,
-       0x10,0x08,0x11,0xff,0xe1,0x8f,0x98,0x00,0x11,0xff,0xe1,0x8f,0x99,0x00,0x10,0x08,
-       0x11,0xff,0xe1,0x8f,0x9a,0x00,0x11,0xff,0xe1,0x8f,0x9b,0x00,0xd1,0x10,0x10,0x08,
-       0x11,0xff,0xe1,0x8f,0x9c,0x00,0x11,0xff,0xe1,0x8f,0x9d,0x00,0x10,0x08,0x11,0xff,
-       0xe1,0x8f,0x9e,0x00,0x11,0xff,0xe1,0x8f,0x9f,0x00,0xd3,0x40,0xd2,0x20,0xd1,0x10,
-       0x10,0x08,0x11,0xff,0xe1,0x8f,0xa0,0x00,0x11,0xff,0xe1,0x8f,0xa1,0x00,0x10,0x08,
-       0x11,0xff,0xe1,0x8f,0xa2,0x00,0x11,0xff,0xe1,0x8f,0xa3,0x00,0xd1,0x10,0x10,0x08,
-       0x11,0xff,0xe1,0x8f,0xa4,0x00,0x11,0xff,0xe1,0x8f,0xa5,0x00,0x10,0x08,0x11,0xff,
-       0xe1,0x8f,0xa6,0x00,0x11,0xff,0xe1,0x8f,0xa7,0x00,0xd2,0x20,0xd1,0x10,0x10,0x08,
-       0x11,0xff,0xe1,0x8f,0xa8,0x00,0x11,0xff,0xe1,0x8f,0xa9,0x00,0x10,0x08,0x11,0xff,
-       0xe1,0x8f,0xaa,0x00,0x11,0xff,0xe1,0x8f,0xab,0x00,0xd1,0x10,0x10,0x08,0x11,0xff,
-       0xe1,0x8f,0xac,0x00,0x11,0xff,0xe1,0x8f,0xad,0x00,0x10,0x08,0x11,0xff,0xe1,0x8f,
-       0xae,0x00,0x11,0xff,0xe1,0x8f,0xaf,0x00,0xd1,0x0c,0xe0,0xeb,0x63,0xcf,0x86,0xcf,
-       0x06,0x02,0xff,0xff,0xd0,0x08,0xcf,0x86,0xcf,0x06,0x01,0x00,0xcf,0x86,0xd5,0x06,
-       0xcf,0x06,0x01,0x00,0xd4,0xae,0xd3,0x09,0xe2,0x54,0x64,0xcf,0x06,0x01,0x00,0xd2,
-       0x27,0xe1,0x1f,0x70,0xe0,0x26,0x6e,0xcf,0x86,0xe5,0x3f,0x6d,0xe4,0xce,0x6c,0xe3,
-       0x99,0x6c,0xe2,0x78,0x6c,0xe1,0x67,0x6c,0x10,0x08,0x01,0xff,0xe5,0x88,0x87,0x00,
-       0x01,0xff,0xe5,0xba,0xa6,0x00,0xe1,0x74,0x74,0xe0,0xe8,0x73,0xcf,0x86,0xe5,0x22,
-       0x73,0xd4,0x3b,0x93,0x37,0xd2,0x1d,0xd1,0x0e,0x10,0x07,0x01,0xff,0x66,0x66,0x00,
-       0x01,0xff,0x66,0x69,0x00,0x10,0x07,0x01,0xff,0x66,0x6c,0x00,0x01,0xff,0x66,0x66,
-       0x69,0x00,0xd1,0x0f,0x10,0x08,0x01,0xff,0x66,0x66,0x6c,0x00,0x01,0xff,0x73,0x74,
-       0x00,0x10,0x07,0x01,0xff,0x73,0x74,0x00,0x00,0x00,0x00,0x00,0xe3,0xc8,0x72,0xd2,
-       0x11,0x51,0x04,0x00,0x00,0x10,0x04,0x00,0x00,0x01,0xff,0xd5,0xb4,0xd5,0xb6,0x00,
-       0xd1,0x12,0x10,0x09,0x01,0xff,0xd5,0xb4,0xd5,0xa5,0x00,0x01,0xff,0xd5,0xb4,0xd5,
-       0xab,0x00,0x10,0x09,0x01,0xff,0xd5,0xbe,0xd5,0xb6,0x00,0x01,0xff,0xd5,0xb4,0xd5,
-       0xad,0x00,0xd3,0x09,0xe2,0x40,0x74,0xcf,0x06,0x01,0x00,0xd2,0x13,0xe1,0x30,0x75,
-       0xe0,0xc1,0x74,0xcf,0x86,0xe5,0x9e,0x74,0x64,0x8d,0x74,0x06,0xff,0x00,0xe1,0x96,
-       0x75,0xe0,0x63,0x75,0xcf,0x86,0xd5,0x18,0x94,0x14,0x93,0x10,0x92,0x0c,0x91,0x08,
-       0x10,0x04,0x00,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0xd4,0x7c,
-       0xd3,0x3c,0xd2,0x1c,0xd1,0x0c,0x10,0x04,0x01,0x00,0x01,0xff,0xef,0xbd,0x81,0x00,
-       0x10,0x08,0x01,0xff,0xef,0xbd,0x82,0x00,0x01,0xff,0xef,0xbd,0x83,0x00,0xd1,0x10,
-       0x10,0x08,0x01,0xff,0xef,0xbd,0x84,0x00,0x01,0xff,0xef,0xbd,0x85,0x00,0x10,0x08,
-       0x01,0xff,0xef,0xbd,0x86,0x00,0x01,0xff,0xef,0xbd,0x87,0x00,0xd2,0x20,0xd1,0x10,
-       0x10,0x08,0x01,0xff,0xef,0xbd,0x88,0x00,0x01,0xff,0xef,0xbd,0x89,0x00,0x10,0x08,
-       0x01,0xff,0xef,0xbd,0x8a,0x00,0x01,0xff,0xef,0xbd,0x8b,0x00,0xd1,0x10,0x10,0x08,
-       0x01,0xff,0xef,0xbd,0x8c,0x00,0x01,0xff,0xef,0xbd,0x8d,0x00,0x10,0x08,0x01,0xff,
-       0xef,0xbd,0x8e,0x00,0x01,0xff,0xef,0xbd,0x8f,0x00,0xd3,0x40,0xd2,0x20,0xd1,0x10,
-       0x10,0x08,0x01,0xff,0xef,0xbd,0x90,0x00,0x01,0xff,0xef,0xbd,0x91,0x00,0x10,0x08,
-       0x01,0xff,0xef,0xbd,0x92,0x00,0x01,0xff,0xef,0xbd,0x93,0x00,0xd1,0x10,0x10,0x08,
-       0x01,0xff,0xef,0xbd,0x94,0x00,0x01,0xff,0xef,0xbd,0x95,0x00,0x10,0x08,0x01,0xff,
-       0xef,0xbd,0x96,0x00,0x01,0xff,0xef,0xbd,0x97,0x00,0x92,0x1c,0xd1,0x10,0x10,0x08,
-       0x01,0xff,0xef,0xbd,0x98,0x00,0x01,0xff,0xef,0xbd,0x99,0x00,0x10,0x08,0x01,0xff,
-       0xef,0xbd,0x9a,0x00,0x01,0x00,0x01,0x00,0x83,0xe2,0x87,0xb3,0xe1,0x60,0xb0,0xe0,
-       0xdd,0xae,0xcf,0x86,0xe5,0x81,0x9b,0xc4,0xe3,0xc1,0x07,0xe2,0x62,0x06,0xe1,0x11,
-       0x86,0xe0,0x09,0x05,0xcf,0x86,0xe5,0xfb,0x02,0xd4,0x1c,0xe3,0x7f,0x76,0xe2,0xd6,
-       0x75,0xe1,0xb1,0x75,0xe0,0x8a,0x75,0xcf,0x86,0xe5,0x57,0x75,0x94,0x07,0x63,0x42,
-       0x75,0x07,0x00,0x07,0x00,0xe3,0x2b,0x78,0xe2,0xf0,0x77,0xe1,0x77,0x01,0xe0,0x88,
-       0x77,0xcf,0x86,0xe5,0x21,0x01,0xd4,0x90,0xd3,0x48,0xd2,0x24,0xd1,0x12,0x10,0x09,
-       0x05,0xff,0xf0,0x90,0x90,0xa8,0x00,0x05,0xff,0xf0,0x90,0x90,0xa9,0x00,0x10,0x09,
-       0x05,0xff,0xf0,0x90,0x90,0xaa,0x00,0x05,0xff,0xf0,0x90,0x90,0xab,0x00,0xd1,0x12,
-       0x10,0x09,0x05,0xff,0xf0,0x90,0x90,0xac,0x00,0x05,0xff,0xf0,0x90,0x90,0xad,0x00,
-       0x10,0x09,0x05,0xff,0xf0,0x90,0x90,0xae,0x00,0x05,0xff,0xf0,0x90,0x90,0xaf,0x00,
-       0xd2,0x24,0xd1,0x12,0x10,0x09,0x05,0xff,0xf0,0x90,0x90,0xb0,0x00,0x05,0xff,0xf0,
-       0x90,0x90,0xb1,0x00,0x10,0x09,0x05,0xff,0xf0,0x90,0x90,0xb2,0x00,0x05,0xff,0xf0,
-       0x90,0x90,0xb3,0x00,0xd1,0x12,0x10,0x09,0x05,0xff,0xf0,0x90,0x90,0xb4,0x00,0x05,
-       0xff,0xf0,0x90,0x90,0xb5,0x00,0x10,0x09,0x05,0xff,0xf0,0x90,0x90,0xb6,0x00,0x05,
-       0xff,0xf0,0x90,0x90,0xb7,0x00,0xd3,0x48,0xd2,0x24,0xd1,0x12,0x10,0x09,0x05,0xff,
-       0xf0,0x90,0x90,0xb8,0x00,0x05,0xff,0xf0,0x90,0x90,0xb9,0x00,0x10,0x09,0x05,0xff,
-       0xf0,0x90,0x90,0xba,0x00,0x05,0xff,0xf0,0x90,0x90,0xbb,0x00,0xd1,0x12,0x10,0x09,
-       0x05,0xff,0xf0,0x90,0x90,0xbc,0x00,0x05,0xff,0xf0,0x90,0x90,0xbd,0x00,0x10,0x09,
-       0x05,0xff,0xf0,0x90,0x90,0xbe,0x00,0x05,0xff,0xf0,0x90,0x90,0xbf,0x00,0xd2,0x24,
-       0xd1,0x12,0x10,0x09,0x05,0xff,0xf0,0x90,0x91,0x80,0x00,0x05,0xff,0xf0,0x90,0x91,
-       0x81,0x00,0x10,0x09,0x05,0xff,0xf0,0x90,0x91,0x82,0x00,0x05,0xff,0xf0,0x90,0x91,
-       0x83,0x00,0xd1,0x12,0x10,0x09,0x05,0xff,0xf0,0x90,0x91,0x84,0x00,0x05,0xff,0xf0,
-       0x90,0x91,0x85,0x00,0x10,0x09,0x05,0xff,0xf0,0x90,0x91,0x86,0x00,0x05,0xff,0xf0,
-       0x90,0x91,0x87,0x00,0x94,0x4c,0x93,0x48,0xd2,0x24,0xd1,0x12,0x10,0x09,0x05,0xff,
-       0xf0,0x90,0x91,0x88,0x00,0x05,0xff,0xf0,0x90,0x91,0x89,0x00,0x10,0x09,0x05,0xff,
-       0xf0,0x90,0x91,0x8a,0x00,0x05,0xff,0xf0,0x90,0x91,0x8b,0x00,0xd1,0x12,0x10,0x09,
-       0x05,0xff,0xf0,0x90,0x91,0x8c,0x00,0x05,0xff,0xf0,0x90,0x91,0x8d,0x00,0x10,0x09,
-       0x07,0xff,0xf0,0x90,0x91,0x8e,0x00,0x07,0xff,0xf0,0x90,0x91,0x8f,0x00,0x05,0x00,
-       0x05,0x00,0xd0,0xa0,0xcf,0x86,0xd5,0x07,0x64,0x30,0x76,0x07,0x00,0xd4,0x07,0x63,
-       0x3d,0x76,0x07,0x00,0xd3,0x48,0xd2,0x24,0xd1,0x12,0x10,0x09,0x12,0xff,0xf0,0x90,
-       0x93,0x98,0x00,0x12,0xff,0xf0,0x90,0x93,0x99,0x00,0x10,0x09,0x12,0xff,0xf0,0x90,
-       0x93,0x9a,0x00,0x12,0xff,0xf0,0x90,0x93,0x9b,0x00,0xd1,0x12,0x10,0x09,0x12,0xff,
-       0xf0,0x90,0x93,0x9c,0x00,0x12,0xff,0xf0,0x90,0x93,0x9d,0x00,0x10,0x09,0x12,0xff,
-       0xf0,0x90,0x93,0x9e,0x00,0x12,0xff,0xf0,0x90,0x93,0x9f,0x00,0xd2,0x24,0xd1,0x12,
-       0x10,0x09,0x12,0xff,0xf0,0x90,0x93,0xa0,0x00,0x12,0xff,0xf0,0x90,0x93,0xa1,0x00,
-       0x10,0x09,0x12,0xff,0xf0,0x90,0x93,0xa2,0x00,0x12,0xff,0xf0,0x90,0x93,0xa3,0x00,
-       0xd1,0x12,0x10,0x09,0x12,0xff,0xf0,0x90,0x93,0xa4,0x00,0x12,0xff,0xf0,0x90,0x93,
-       0xa5,0x00,0x10,0x09,0x12,0xff,0xf0,0x90,0x93,0xa6,0x00,0x12,0xff,0xf0,0x90,0x93,
-       0xa7,0x00,0xcf,0x86,0xe5,0xc6,0x75,0xd4,0x90,0xd3,0x48,0xd2,0x24,0xd1,0x12,0x10,
-       0x09,0x12,0xff,0xf0,0x90,0x93,0xa8,0x00,0x12,0xff,0xf0,0x90,0x93,0xa9,0x00,0x10,
-       0x09,0x12,0xff,0xf0,0x90,0x93,0xaa,0x00,0x12,0xff,0xf0,0x90,0x93,0xab,0x00,0xd1,
-       0x12,0x10,0x09,0x12,0xff,0xf0,0x90,0x93,0xac,0x00,0x12,0xff,0xf0,0x90,0x93,0xad,
-       0x00,0x10,0x09,0x12,0xff,0xf0,0x90,0x93,0xae,0x00,0x12,0xff,0xf0,0x90,0x93,0xaf,
-       0x00,0xd2,0x24,0xd1,0x12,0x10,0x09,0x12,0xff,0xf0,0x90,0x93,0xb0,0x00,0x12,0xff,
-       0xf0,0x90,0x93,0xb1,0x00,0x10,0x09,0x12,0xff,0xf0,0x90,0x93,0xb2,0x00,0x12,0xff,
-       0xf0,0x90,0x93,0xb3,0x00,0xd1,0x12,0x10,0x09,0x12,0xff,0xf0,0x90,0x93,0xb4,0x00,
-       0x12,0xff,0xf0,0x90,0x93,0xb5,0x00,0x10,0x09,0x12,0xff,0xf0,0x90,0x93,0xb6,0x00,
-       0x12,0xff,0xf0,0x90,0x93,0xb7,0x00,0x93,0x28,0x92,0x24,0xd1,0x12,0x10,0x09,0x12,
-       0xff,0xf0,0x90,0x93,0xb8,0x00,0x12,0xff,0xf0,0x90,0x93,0xb9,0x00,0x10,0x09,0x12,
-       0xff,0xf0,0x90,0x93,0xba,0x00,0x12,0xff,0xf0,0x90,0x93,0xbb,0x00,0x00,0x00,0x12,
-       0x00,0xd4,0x1f,0xe3,0xdf,0x76,0xe2,0x6a,0x76,0xe1,0x09,0x76,0xe0,0xea,0x75,0xcf,
-       0x86,0xe5,0xb7,0x75,0x94,0x0a,0xe3,0xa2,0x75,0x62,0x99,0x75,0x07,0x00,0x07,0x00,
-       0xe3,0xde,0x78,0xe2,0xaf,0x78,0xd1,0x09,0xe0,0x4c,0x78,0xcf,0x06,0x0b,0x00,0xe0,
-       0x7f,0x78,0xcf,0x86,0xe5,0x21,0x01,0xd4,0x90,0xd3,0x48,0xd2,0x24,0xd1,0x12,0x10,
-       0x09,0x11,0xff,0xf0,0x90,0xb3,0x80,0x00,0x11,0xff,0xf0,0x90,0xb3,0x81,0x00,0x10,
-       0x09,0x11,0xff,0xf0,0x90,0xb3,0x82,0x00,0x11,0xff,0xf0,0x90,0xb3,0x83,0x00,0xd1,
-       0x12,0x10,0x09,0x11,0xff,0xf0,0x90,0xb3,0x84,0x00,0x11,0xff,0xf0,0x90,0xb3,0x85,
-       0x00,0x10,0x09,0x11,0xff,0xf0,0x90,0xb3,0x86,0x00,0x11,0xff,0xf0,0x90,0xb3,0x87,
-       0x00,0xd2,0x24,0xd1,0x12,0x10,0x09,0x11,0xff,0xf0,0x90,0xb3,0x88,0x00,0x11,0xff,
-       0xf0,0x90,0xb3,0x89,0x00,0x10,0x09,0x11,0xff,0xf0,0x90,0xb3,0x8a,0x00,0x11,0xff,
-       0xf0,0x90,0xb3,0x8b,0x00,0xd1,0x12,0x10,0x09,0x11,0xff,0xf0,0x90,0xb3,0x8c,0x00,
-       0x11,0xff,0xf0,0x90,0xb3,0x8d,0x00,0x10,0x09,0x11,0xff,0xf0,0x90,0xb3,0x8e,0x00,
-       0x11,0xff,0xf0,0x90,0xb3,0x8f,0x00,0xd3,0x48,0xd2,0x24,0xd1,0x12,0x10,0x09,0x11,
-       0xff,0xf0,0x90,0xb3,0x90,0x00,0x11,0xff,0xf0,0x90,0xb3,0x91,0x00,0x10,0x09,0x11,
-       0xff,0xf0,0x90,0xb3,0x92,0x00,0x11,0xff,0xf0,0x90,0xb3,0x93,0x00,0xd1,0x12,0x10,
-       0x09,0x11,0xff,0xf0,0x90,0xb3,0x94,0x00,0x11,0xff,0xf0,0x90,0xb3,0x95,0x00,0x10,
-       0x09,0x11,0xff,0xf0,0x90,0xb3,0x96,0x00,0x11,0xff,0xf0,0x90,0xb3,0x97,0x00,0xd2,
-       0x24,0xd1,0x12,0x10,0x09,0x11,0xff,0xf0,0x90,0xb3,0x98,0x00,0x11,0xff,0xf0,0x90,
-       0xb3,0x99,0x00,0x10,0x09,0x11,0xff,0xf0,0x90,0xb3,0x9a,0x00,0x11,0xff,0xf0,0x90,
-       0xb3,0x9b,0x00,0xd1,0x12,0x10,0x09,0x11,0xff,0xf0,0x90,0xb3,0x9c,0x00,0x11,0xff,
-       0xf0,0x90,0xb3,0x9d,0x00,0x10,0x09,0x11,0xff,0xf0,0x90,0xb3,0x9e,0x00,0x11,0xff,
-       0xf0,0x90,0xb3,0x9f,0x00,0xd4,0x90,0xd3,0x48,0xd2,0x24,0xd1,0x12,0x10,0x09,0x11,
-       0xff,0xf0,0x90,0xb3,0xa0,0x00,0x11,0xff,0xf0,0x90,0xb3,0xa1,0x00,0x10,0x09,0x11,
-       0xff,0xf0,0x90,0xb3,0xa2,0x00,0x11,0xff,0xf0,0x90,0xb3,0xa3,0x00,0xd1,0x12,0x10,
-       0x09,0x11,0xff,0xf0,0x90,0xb3,0xa4,0x00,0x11,0xff,0xf0,0x90,0xb3,0xa5,0x00,0x10,
-       0x09,0x11,0xff,0xf0,0x90,0xb3,0xa6,0x00,0x11,0xff,0xf0,0x90,0xb3,0xa7,0x00,0xd2,
-       0x24,0xd1,0x12,0x10,0x09,0x11,0xff,0xf0,0x90,0xb3,0xa8,0x00,0x11,0xff,0xf0,0x90,
-       0xb3,0xa9,0x00,0x10,0x09,0x11,0xff,0xf0,0x90,0xb3,0xaa,0x00,0x11,0xff,0xf0,0x90,
-       0xb3,0xab,0x00,0xd1,0x12,0x10,0x09,0x11,0xff,0xf0,0x90,0xb3,0xac,0x00,0x11,0xff,
-       0xf0,0x90,0xb3,0xad,0x00,0x10,0x09,0x11,0xff,0xf0,0x90,0xb3,0xae,0x00,0x11,0xff,
-       0xf0,0x90,0xb3,0xaf,0x00,0x93,0x23,0x92,0x1f,0xd1,0x12,0x10,0x09,0x11,0xff,0xf0,
-       0x90,0xb3,0xb0,0x00,0x11,0xff,0xf0,0x90,0xb3,0xb1,0x00,0x10,0x09,0x11,0xff,0xf0,
-       0x90,0xb3,0xb2,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xcf,0x86,0xd5,0x15,0xe4,0x91,
-       0x7b,0xe3,0x9b,0x79,0xe2,0x94,0x78,0xe1,0xe4,0x77,0xe0,0x9d,0x77,0xcf,0x06,0x0c,
-       0x00,0xe4,0xeb,0x7e,0xe3,0x44,0x7e,0xe2,0xed,0x7d,0xd1,0x0c,0xe0,0xb2,0x7d,0xcf,
-       0x86,0x65,0x93,0x7d,0x14,0x00,0xe0,0xb6,0x7d,0xcf,0x86,0x55,0x04,0x00,0x00,0xd4,
-       0x90,0xd3,0x48,0xd2,0x24,0xd1,0x12,0x10,0x09,0x10,0xff,0xf0,0x91,0xa3,0x80,0x00,
-       0x10,0xff,0xf0,0x91,0xa3,0x81,0x00,0x10,0x09,0x10,0xff,0xf0,0x91,0xa3,0x82,0x00,
-       0x10,0xff,0xf0,0x91,0xa3,0x83,0x00,0xd1,0x12,0x10,0x09,0x10,0xff,0xf0,0x91,0xa3,
-       0x84,0x00,0x10,0xff,0xf0,0x91,0xa3,0x85,0x00,0x10,0x09,0x10,0xff,0xf0,0x91,0xa3,
-       0x86,0x00,0x10,0xff,0xf0,0x91,0xa3,0x87,0x00,0xd2,0x24,0xd1,0x12,0x10,0x09,0x10,
-       0xff,0xf0,0x91,0xa3,0x88,0x00,0x10,0xff,0xf0,0x91,0xa3,0x89,0x00,0x10,0x09,0x10,
-       0xff,0xf0,0x91,0xa3,0x8a,0x00,0x10,0xff,0xf0,0x91,0xa3,0x8b,0x00,0xd1,0x12,0x10,
-       0x09,0x10,0xff,0xf0,0x91,0xa3,0x8c,0x00,0x10,0xff,0xf0,0x91,0xa3,0x8d,0x00,0x10,
-       0x09,0x10,0xff,0xf0,0x91,0xa3,0x8e,0x00,0x10,0xff,0xf0,0x91,0xa3,0x8f,0x00,0xd3,
-       0x48,0xd2,0x24,0xd1,0x12,0x10,0x09,0x10,0xff,0xf0,0x91,0xa3,0x90,0x00,0x10,0xff,
-       0xf0,0x91,0xa3,0x91,0x00,0x10,0x09,0x10,0xff,0xf0,0x91,0xa3,0x92,0x00,0x10,0xff,
-       0xf0,0x91,0xa3,0x93,0x00,0xd1,0x12,0x10,0x09,0x10,0xff,0xf0,0x91,0xa3,0x94,0x00,
-       0x10,0xff,0xf0,0x91,0xa3,0x95,0x00,0x10,0x09,0x10,0xff,0xf0,0x91,0xa3,0x96,0x00,
-       0x10,0xff,0xf0,0x91,0xa3,0x97,0x00,0xd2,0x24,0xd1,0x12,0x10,0x09,0x10,0xff,0xf0,
-       0x91,0xa3,0x98,0x00,0x10,0xff,0xf0,0x91,0xa3,0x99,0x00,0x10,0x09,0x10,0xff,0xf0,
-       0x91,0xa3,0x9a,0x00,0x10,0xff,0xf0,0x91,0xa3,0x9b,0x00,0xd1,0x12,0x10,0x09,0x10,
-       0xff,0xf0,0x91,0xa3,0x9c,0x00,0x10,0xff,0xf0,0x91,0xa3,0x9d,0x00,0x10,0x09,0x10,
-       0xff,0xf0,0x91,0xa3,0x9e,0x00,0x10,0xff,0xf0,0x91,0xa3,0x9f,0x00,0xd1,0x11,0xe0,
-       0x12,0x81,0xcf,0x86,0xe5,0x09,0x81,0xe4,0xd2,0x80,0xcf,0x06,0x00,0x00,0xe0,0xdb,
-       0x82,0xcf,0x86,0xd5,0x06,0xcf,0x06,0x00,0x00,0xd4,0x09,0xe3,0x10,0x81,0xcf,0x06,
-       0x0c,0x00,0xd3,0x06,0xcf,0x06,0x00,0x00,0xe2,0x3b,0x82,0xe1,0x16,0x82,0xd0,0x06,
-       0xcf,0x06,0x00,0x00,0xcf,0x86,0xa5,0x21,0x01,0xd4,0x90,0xd3,0x48,0xd2,0x24,0xd1,
-       0x12,0x10,0x09,0x14,0xff,0xf0,0x96,0xb9,0xa0,0x00,0x14,0xff,0xf0,0x96,0xb9,0xa1,
-       0x00,0x10,0x09,0x14,0xff,0xf0,0x96,0xb9,0xa2,0x00,0x14,0xff,0xf0,0x96,0xb9,0xa3,
-       0x00,0xd1,0x12,0x10,0x09,0x14,0xff,0xf0,0x96,0xb9,0xa4,0x00,0x14,0xff,0xf0,0x96,
-       0xb9,0xa5,0x00,0x10,0x09,0x14,0xff,0xf0,0x96,0xb9,0xa6,0x00,0x14,0xff,0xf0,0x96,
-       0xb9,0xa7,0x00,0xd2,0x24,0xd1,0x12,0x10,0x09,0x14,0xff,0xf0,0x96,0xb9,0xa8,0x00,
-       0x14,0xff,0xf0,0x96,0xb9,0xa9,0x00,0x10,0x09,0x14,0xff,0xf0,0x96,0xb9,0xaa,0x00,
-       0x14,0xff,0xf0,0x96,0xb9,0xab,0x00,0xd1,0x12,0x10,0x09,0x14,0xff,0xf0,0x96,0xb9,
-       0xac,0x00,0x14,0xff,0xf0,0x96,0xb9,0xad,0x00,0x10,0x09,0x14,0xff,0xf0,0x96,0xb9,
-       0xae,0x00,0x14,0xff,0xf0,0x96,0xb9,0xaf,0x00,0xd3,0x48,0xd2,0x24,0xd1,0x12,0x10,
-       0x09,0x14,0xff,0xf0,0x96,0xb9,0xb0,0x00,0x14,0xff,0xf0,0x96,0xb9,0xb1,0x00,0x10,
-       0x09,0x14,0xff,0xf0,0x96,0xb9,0xb2,0x00,0x14,0xff,0xf0,0x96,0xb9,0xb3,0x00,0xd1,
-       0x12,0x10,0x09,0x14,0xff,0xf0,0x96,0xb9,0xb4,0x00,0x14,0xff,0xf0,0x96,0xb9,0xb5,
-       0x00,0x10,0x09,0x14,0xff,0xf0,0x96,0xb9,0xb6,0x00,0x14,0xff,0xf0,0x96,0xb9,0xb7,
-       0x00,0xd2,0x24,0xd1,0x12,0x10,0x09,0x14,0xff,0xf0,0x96,0xb9,0xb8,0x00,0x14,0xff,
-       0xf0,0x96,0xb9,0xb9,0x00,0x10,0x09,0x14,0xff,0xf0,0x96,0xb9,0xba,0x00,0x14,0xff,
-       0xf0,0x96,0xb9,0xbb,0x00,0xd1,0x12,0x10,0x09,0x14,0xff,0xf0,0x96,0xb9,0xbc,0x00,
-       0x14,0xff,0xf0,0x96,0xb9,0xbd,0x00,0x10,0x09,0x14,0xff,0xf0,0x96,0xb9,0xbe,0x00,
-       0x14,0xff,0xf0,0x96,0xb9,0xbf,0x00,0x14,0x00,0xd2,0x14,0xe1,0x25,0x82,0xe0,0x1c,
-       0x82,0xcf,0x86,0xe5,0xdd,0x81,0xe4,0x9a,0x81,0xcf,0x06,0x12,0x00,0xd1,0x0b,0xe0,
-       0x51,0x83,0xcf,0x86,0xcf,0x06,0x00,0x00,0xe0,0x95,0x8b,0xcf,0x86,0xd5,0x22,0xe4,
-       0xd0,0x88,0xe3,0x93,0x88,0xe2,0x38,0x88,0xe1,0x31,0x88,0xe0,0x2a,0x88,0xcf,0x86,
-       0xe5,0xfb,0x87,0xe4,0xe2,0x87,0x93,0x07,0x62,0xd1,0x87,0x12,0xe6,0x12,0xe6,0xe4,
-       0x36,0x89,0xe3,0x2f,0x89,0xd2,0x09,0xe1,0xb8,0x88,0xcf,0x06,0x10,0x00,0xe1,0x1f,
-       0x89,0xe0,0xec,0x88,0xcf,0x86,0xe5,0x21,0x01,0xd4,0x90,0xd3,0x48,0xd2,0x24,0xd1,
-       0x12,0x10,0x09,0x12,0xff,0xf0,0x9e,0xa4,0xa2,0x00,0x12,0xff,0xf0,0x9e,0xa4,0xa3,
-       0x00,0x10,0x09,0x12,0xff,0xf0,0x9e,0xa4,0xa4,0x00,0x12,0xff,0xf0,0x9e,0xa4,0xa5,
-       0x00,0xd1,0x12,0x10,0x09,0x12,0xff,0xf0,0x9e,0xa4,0xa6,0x00,0x12,0xff,0xf0,0x9e,
-       0xa4,0xa7,0x00,0x10,0x09,0x12,0xff,0xf0,0x9e,0xa4,0xa8,0x00,0x12,0xff,0xf0,0x9e,
-       0xa4,0xa9,0x00,0xd2,0x24,0xd1,0x12,0x10,0x09,0x12,0xff,0xf0,0x9e,0xa4,0xaa,0x00,
-       0x12,0xff,0xf0,0x9e,0xa4,0xab,0x00,0x10,0x09,0x12,0xff,0xf0,0x9e,0xa4,0xac,0x00,
-       0x12,0xff,0xf0,0x9e,0xa4,0xad,0x00,0xd1,0x12,0x10,0x09,0x12,0xff,0xf0,0x9e,0xa4,
-       0xae,0x00,0x12,0xff,0xf0,0x9e,0xa4,0xaf,0x00,0x10,0x09,0x12,0xff,0xf0,0x9e,0xa4,
-       0xb0,0x00,0x12,0xff,0xf0,0x9e,0xa4,0xb1,0x00,0xd3,0x48,0xd2,0x24,0xd1,0x12,0x10,
-       0x09,0x12,0xff,0xf0,0x9e,0xa4,0xb2,0x00,0x12,0xff,0xf0,0x9e,0xa4,0xb3,0x00,0x10,
-       0x09,0x12,0xff,0xf0,0x9e,0xa4,0xb4,0x00,0x12,0xff,0xf0,0x9e,0xa4,0xb5,0x00,0xd1,
-       0x12,0x10,0x09,0x12,0xff,0xf0,0x9e,0xa4,0xb6,0x00,0x12,0xff,0xf0,0x9e,0xa4,0xb7,
-       0x00,0x10,0x09,0x12,0xff,0xf0,0x9e,0xa4,0xb8,0x00,0x12,0xff,0xf0,0x9e,0xa4,0xb9,
-       0x00,0xd2,0x24,0xd1,0x12,0x10,0x09,0x12,0xff,0xf0,0x9e,0xa4,0xba,0x00,0x12,0xff,
-       0xf0,0x9e,0xa4,0xbb,0x00,0x10,0x09,0x12,0xff,0xf0,0x9e,0xa4,0xbc,0x00,0x12,0xff,
-       0xf0,0x9e,0xa4,0xbd,0x00,0xd1,0x12,0x10,0x09,0x12,0xff,0xf0,0x9e,0xa4,0xbe,0x00,
-       0x12,0xff,0xf0,0x9e,0xa4,0xbf,0x00,0x10,0x09,0x12,0xff,0xf0,0x9e,0xa5,0x80,0x00,
-       0x12,0xff,0xf0,0x9e,0xa5,0x81,0x00,0x94,0x1e,0x93,0x1a,0x92,0x16,0x91,0x12,0x10,
-       0x09,0x12,0xff,0xf0,0x9e,0xa5,0x82,0x00,0x12,0xff,0xf0,0x9e,0xa5,0x83,0x00,0x12,
-       0x00,0x12,0x00,0x12,0x00,0x12,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-       0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-       0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-       /* nfdi_c0100 */
-       0x57,0x04,0x01,0x00,0xc6,0xe5,0xac,0x13,0xe4,0x41,0x0c,0xe3,0x7a,0x07,0xe2,0xf3,
-       0x01,0xc1,0xd0,0x1f,0xcf,0x86,0x55,0x04,0x01,0x00,0x94,0x15,0x53,0x04,0x01,0x00,
-       0x52,0x04,0x01,0x00,0x91,0x09,0x10,0x04,0x01,0x00,0x01,0xff,0x00,0x01,0x00,0x01,
-       0x00,0xcf,0x86,0xd5,0xe4,0xd4,0x7c,0xd3,0x3c,0xd2,0x20,0xd1,0x10,0x10,0x08,0x01,
-       0xff,0x41,0xcc,0x80,0x00,0x01,0xff,0x41,0xcc,0x81,0x00,0x10,0x08,0x01,0xff,0x41,
-       0xcc,0x82,0x00,0x01,0xff,0x41,0xcc,0x83,0x00,0xd1,0x10,0x10,0x08,0x01,0xff,0x41,
-       0xcc,0x88,0x00,0x01,0xff,0x41,0xcc,0x8a,0x00,0x10,0x04,0x01,0x00,0x01,0xff,0x43,
-       0xcc,0xa7,0x00,0xd2,0x20,0xd1,0x10,0x10,0x08,0x01,0xff,0x45,0xcc,0x80,0x00,0x01,
-       0xff,0x45,0xcc,0x81,0x00,0x10,0x08,0x01,0xff,0x45,0xcc,0x82,0x00,0x01,0xff,0x45,
-       0xcc,0x88,0x00,0xd1,0x10,0x10,0x08,0x01,0xff,0x49,0xcc,0x80,0x00,0x01,0xff,0x49,
-       0xcc,0x81,0x00,0x10,0x08,0x01,0xff,0x49,0xcc,0x82,0x00,0x01,0xff,0x49,0xcc,0x88,
-       0x00,0xd3,0x38,0xd2,0x1c,0xd1,0x0c,0x10,0x04,0x01,0x00,0x01,0xff,0x4e,0xcc,0x83,
-       0x00,0x10,0x08,0x01,0xff,0x4f,0xcc,0x80,0x00,0x01,0xff,0x4f,0xcc,0x81,0x00,0xd1,
-       0x10,0x10,0x08,0x01,0xff,0x4f,0xcc,0x82,0x00,0x01,0xff,0x4f,0xcc,0x83,0x00,0x10,
-       0x08,0x01,0xff,0x4f,0xcc,0x88,0x00,0x01,0x00,0xd2,0x1c,0xd1,0x0c,0x10,0x04,0x01,
-       0x00,0x01,0xff,0x55,0xcc,0x80,0x00,0x10,0x08,0x01,0xff,0x55,0xcc,0x81,0x00,0x01,
-       0xff,0x55,0xcc,0x82,0x00,0x91,0x10,0x10,0x08,0x01,0xff,0x55,0xcc,0x88,0x00,0x01,
-       0xff,0x59,0xcc,0x81,0x00,0x01,0x00,0xd4,0x7c,0xd3,0x3c,0xd2,0x20,0xd1,0x10,0x10,
-       0x08,0x01,0xff,0x61,0xcc,0x80,0x00,0x01,0xff,0x61,0xcc,0x81,0x00,0x10,0x08,0x01,
-       0xff,0x61,0xcc,0x82,0x00,0x01,0xff,0x61,0xcc,0x83,0x00,0xd1,0x10,0x10,0x08,0x01,
-       0xff,0x61,0xcc,0x88,0x00,0x01,0xff,0x61,0xcc,0x8a,0x00,0x10,0x04,0x01,0x00,0x01,
+       0xc6,0xe5,0xf6,0x14,0xe4,0x6c,0x0d,0xe3,0x36,0x08,0xe2,0x1f,0x01,0xc1,0xd0,0x21,
+       0xcf,0x86,0x55,0x04,0x01,0x00,0x54,0x04,0x01,0x00,0x93,0x13,0x52,0x04,0x01,0x00,
+       0x91,0x0b,0x10,0x04,0x01,0x00,0x01,0xff,0xce,0xbc,0x00,0x01,0x00,0x01,0x00,0xcf,
+       0x86,0xe5,0x9d,0x44,0xd4,0x7f,0xd3,0x3f,0xd2,0x20,0xd1,0x10,0x10,0x08,0x01,0xff,
+       0x61,0xcc,0x80,0x00,0x01,0xff,0x61,0xcc,0x81,0x00,0x10,0x08,0x01,0xff,0x61,0xcc,
+       0x82,0x00,0x01,0xff,0x61,0xcc,0x83,0x00,0xd1,0x10,0x10,0x08,0x01,0xff,0x61,0xcc,
+       0x88,0x00,0x01,0xff,0x61,0xcc,0x8a,0x00,0x10,0x07,0x01,0xff,0xc3,0xa6,0x00,0x01,
        0xff,0x63,0xcc,0xa7,0x00,0xd2,0x20,0xd1,0x10,0x10,0x08,0x01,0xff,0x65,0xcc,0x80,
        0x00,0x01,0xff,0x65,0xcc,0x81,0x00,0x10,0x08,0x01,0xff,0x65,0xcc,0x82,0x00,0x01,
        0xff,0x65,0xcc,0x88,0x00,0xd1,0x10,0x10,0x08,0x01,0xff,0x69,0xcc,0x80,0x00,0x01,
        0xff,0x69,0xcc,0x81,0x00,0x10,0x08,0x01,0xff,0x69,0xcc,0x82,0x00,0x01,0xff,0x69,
-       0xcc,0x88,0x00,0xd3,0x38,0xd2,0x1c,0xd1,0x0c,0x10,0x04,0x01,0x00,0x01,0xff,0x6e,
-       0xcc,0x83,0x00,0x10,0x08,0x01,0xff,0x6f,0xcc,0x80,0x00,0x01,0xff,0x6f,0xcc,0x81,
-       0x00,0xd1,0x10,0x10,0x08,0x01,0xff,0x6f,0xcc,0x82,0x00,0x01,0xff,0x6f,0xcc,0x83,
-       0x00,0x10,0x08,0x01,0xff,0x6f,0xcc,0x88,0x00,0x01,0x00,0xd2,0x1c,0xd1,0x0c,0x10,
-       0x04,0x01,0x00,0x01,0xff,0x75,0xcc,0x80,0x00,0x10,0x08,0x01,0xff,0x75,0xcc,0x81,
-       0x00,0x01,0xff,0x75,0xcc,0x82,0x00,0xd1,0x10,0x10,0x08,0x01,0xff,0x75,0xcc,0x88,
-       0x00,0x01,0xff,0x79,0xcc,0x81,0x00,0x10,0x04,0x01,0x00,0x01,0xff,0x79,0xcc,0x88,
-       0x00,0xe1,0x9a,0x03,0xe0,0xd3,0x01,0xcf,0x86,0xd5,0xf4,0xd4,0x80,0xd3,0x40,0xd2,
-       0x20,0xd1,0x10,0x10,0x08,0x01,0xff,0x41,0xcc,0x84,0x00,0x01,0xff,0x61,0xcc,0x84,
-       0x00,0x10,0x08,0x01,0xff,0x41,0xcc,0x86,0x00,0x01,0xff,0x61,0xcc,0x86,0x00,0xd1,
-       0x10,0x10,0x08,0x01,0xff,0x41,0xcc,0xa8,0x00,0x01,0xff,0x61,0xcc,0xa8,0x00,0x10,
-       0x08,0x01,0xff,0x43,0xcc,0x81,0x00,0x01,0xff,0x63,0xcc,0x81,0x00,0xd2,0x20,0xd1,
-       0x10,0x10,0x08,0x01,0xff,0x43,0xcc,0x82,0x00,0x01,0xff,0x63,0xcc,0x82,0x00,0x10,
-       0x08,0x01,0xff,0x43,0xcc,0x87,0x00,0x01,0xff,0x63,0xcc,0x87,0x00,0xd1,0x10,0x10,
-       0x08,0x01,0xff,0x43,0xcc,0x8c,0x00,0x01,0xff,0x63,0xcc,0x8c,0x00,0x10,0x08,0x01,
-       0xff,0x44,0xcc,0x8c,0x00,0x01,0xff,0x64,0xcc,0x8c,0x00,0xd3,0x34,0xd2,0x14,0x51,
-       0x04,0x01,0x00,0x10,0x08,0x01,0xff,0x45,0xcc,0x84,0x00,0x01,0xff,0x65,0xcc,0x84,
-       0x00,0xd1,0x10,0x10,0x08,0x01,0xff,0x45,0xcc,0x86,0x00,0x01,0xff,0x65,0xcc,0x86,
-       0x00,0x10,0x08,0x01,0xff,0x45,0xcc,0x87,0x00,0x01,0xff,0x65,0xcc,0x87,0x00,0xd2,
-       0x20,0xd1,0x10,0x10,0x08,0x01,0xff,0x45,0xcc,0xa8,0x00,0x01,0xff,0x65,0xcc,0xa8,
-       0x00,0x10,0x08,0x01,0xff,0x45,0xcc,0x8c,0x00,0x01,0xff,0x65,0xcc,0x8c,0x00,0xd1,
-       0x10,0x10,0x08,0x01,0xff,0x47,0xcc,0x82,0x00,0x01,0xff,0x67,0xcc,0x82,0x00,0x10,
-       0x08,0x01,0xff,0x47,0xcc,0x86,0x00,0x01,0xff,0x67,0xcc,0x86,0x00,0xd4,0x74,0xd3,
-       0x34,0xd2,0x20,0xd1,0x10,0x10,0x08,0x01,0xff,0x47,0xcc,0x87,0x00,0x01,0xff,0x67,
-       0xcc,0x87,0x00,0x10,0x08,0x01,0xff,0x47,0xcc,0xa7,0x00,0x01,0xff,0x67,0xcc,0xa7,
-       0x00,0x91,0x10,0x10,0x08,0x01,0xff,0x48,0xcc,0x82,0x00,0x01,0xff,0x68,0xcc,0x82,
-       0x00,0x01,0x00,0xd2,0x20,0xd1,0x10,0x10,0x08,0x01,0xff,0x49,0xcc,0x83,0x00,0x01,
-       0xff,0x69,0xcc,0x83,0x00,0x10,0x08,0x01,0xff,0x49,0xcc,0x84,0x00,0x01,0xff,0x69,
-       0xcc,0x84,0x00,0xd1,0x10,0x10,0x08,0x01,0xff,0x49,0xcc,0x86,0x00,0x01,0xff,0x69,
-       0xcc,0x86,0x00,0x10,0x08,0x01,0xff,0x49,0xcc,0xa8,0x00,0x01,0xff,0x69,0xcc,0xa8,
-       0x00,0xd3,0x30,0xd2,0x10,0x91,0x0c,0x10,0x08,0x01,0xff,0x49,0xcc,0x87,0x00,0x01,
-       0x00,0x01,0x00,0xd1,0x10,0x10,0x08,0x01,0xff,0x4a,0xcc,0x82,0x00,0x01,0xff,0x6a,
-       0xcc,0x82,0x00,0x10,0x08,0x01,0xff,0x4b,0xcc,0xa7,0x00,0x01,0xff,0x6b,0xcc,0xa7,
-       0x00,0xd2,0x1c,0xd1,0x0c,0x10,0x04,0x01,0x00,0x01,0xff,0x4c,0xcc,0x81,0x00,0x10,
-       0x08,0x01,0xff,0x6c,0xcc,0x81,0x00,0x01,0xff,0x4c,0xcc,0xa7,0x00,0xd1,0x10,0x10,
-       0x08,0x01,0xff,0x6c,0xcc,0xa7,0x00,0x01,0xff,0x4c,0xcc,0x8c,0x00,0x10,0x08,0x01,
-       0xff,0x6c,0xcc,0x8c,0x00,0x01,0x00,0xcf,0x86,0xd5,0xd4,0xd4,0x60,0xd3,0x30,0xd2,
-       0x10,0x51,0x04,0x01,0x00,0x10,0x04,0x01,0x00,0x01,0xff,0x4e,0xcc,0x81,0x00,0xd1,
-       0x10,0x10,0x08,0x01,0xff,0x6e,0xcc,0x81,0x00,0x01,0xff,0x4e,0xcc,0xa7,0x00,0x10,
-       0x08,0x01,0xff,0x6e,0xcc,0xa7,0x00,0x01,0xff,0x4e,0xcc,0x8c,0x00,0xd2,0x10,0x91,
-       0x0c,0x10,0x08,0x01,0xff,0x6e,0xcc,0x8c,0x00,0x01,0x00,0x01,0x00,0xd1,0x10,0x10,
-       0x08,0x01,0xff,0x4f,0xcc,0x84,0x00,0x01,0xff,0x6f,0xcc,0x84,0x00,0x10,0x08,0x01,
-       0xff,0x4f,0xcc,0x86,0x00,0x01,0xff,0x6f,0xcc,0x86,0x00,0xd3,0x34,0xd2,0x14,0x91,
-       0x10,0x10,0x08,0x01,0xff,0x4f,0xcc,0x8b,0x00,0x01,0xff,0x6f,0xcc,0x8b,0x00,0x01,
-       0x00,0xd1,0x10,0x10,0x08,0x01,0xff,0x52,0xcc,0x81,0x00,0x01,0xff,0x72,0xcc,0x81,
-       0x00,0x10,0x08,0x01,0xff,0x52,0xcc,0xa7,0x00,0x01,0xff,0x72,0xcc,0xa7,0x00,0xd2,
-       0x20,0xd1,0x10,0x10,0x08,0x01,0xff,0x52,0xcc,0x8c,0x00,0x01,0xff,0x72,0xcc,0x8c,
-       0x00,0x10,0x08,0x01,0xff,0x53,0xcc,0x81,0x00,0x01,0xff,0x73,0xcc,0x81,0x00,0xd1,
-       0x10,0x10,0x08,0x01,0xff,0x53,0xcc,0x82,0x00,0x01,0xff,0x73,0xcc,0x82,0x00,0x10,
-       0x08,0x01,0xff,0x53,0xcc,0xa7,0x00,0x01,0xff,0x73,0xcc,0xa7,0x00,0xd4,0x74,0xd3,
-       0x34,0xd2,0x20,0xd1,0x10,0x10,0x08,0x01,0xff,0x53,0xcc,0x8c,0x00,0x01,0xff,0x73,
-       0xcc,0x8c,0x00,0x10,0x08,0x01,0xff,0x54,0xcc,0xa7,0x00,0x01,0xff,0x74,0xcc,0xa7,
-       0x00,0x91,0x10,0x10,0x08,0x01,0xff,0x54,0xcc,0x8c,0x00,0x01,0xff,0x74,0xcc,0x8c,
-       0x00,0x01,0x00,0xd2,0x20,0xd1,0x10,0x10,0x08,0x01,0xff,0x55,0xcc,0x83,0x00,0x01,
-       0xff,0x75,0xcc,0x83,0x00,0x10,0x08,0x01,0xff,0x55,0xcc,0x84,0x00,0x01,0xff,0x75,
-       0xcc,0x84,0x00,0xd1,0x10,0x10,0x08,0x01,0xff,0x55,0xcc,0x86,0x00,0x01,0xff,0x75,
-       0xcc,0x86,0x00,0x10,0x08,0x01,0xff,0x55,0xcc,0x8a,0x00,0x01,0xff,0x75,0xcc,0x8a,
-       0x00,0xd3,0x40,0xd2,0x20,0xd1,0x10,0x10,0x08,0x01,0xff,0x55,0xcc,0x8b,0x00,0x01,
-       0xff,0x75,0xcc,0x8b,0x00,0x10,0x08,0x01,0xff,0x55,0xcc,0xa8,0x00,0x01,0xff,0x75,
-       0xcc,0xa8,0x00,0xd1,0x10,0x10,0x08,0x01,0xff,0x57,0xcc,0x82,0x00,0x01,0xff,0x77,
-       0xcc,0x82,0x00,0x10,0x08,0x01,0xff,0x59,0xcc,0x82,0x00,0x01,0xff,0x79,0xcc,0x82,
-       0x00,0xd2,0x20,0xd1,0x10,0x10,0x08,0x01,0xff,0x59,0xcc,0x88,0x00,0x01,0xff,0x5a,
-       0xcc,0x81,0x00,0x10,0x08,0x01,0xff,0x7a,0xcc,0x81,0x00,0x01,0xff,0x5a,0xcc,0x87,
-       0x00,0xd1,0x10,0x10,0x08,0x01,0xff,0x7a,0xcc,0x87,0x00,0x01,0xff,0x5a,0xcc,0x8c,
-       0x00,0x10,0x08,0x01,0xff,0x7a,0xcc,0x8c,0x00,0x01,0x00,0xd0,0x4a,0xcf,0x86,0x55,
-       0x04,0x01,0x00,0xd4,0x2c,0xd3,0x18,0x92,0x14,0x91,0x10,0x10,0x08,0x01,0xff,0x4f,
-       0xcc,0x9b,0x00,0x01,0xff,0x6f,0xcc,0x9b,0x00,0x01,0x00,0x01,0x00,0x52,0x04,0x01,
-       0x00,0x51,0x04,0x01,0x00,0x10,0x04,0x01,0x00,0x01,0xff,0x55,0xcc,0x9b,0x00,0x93,
-       0x14,0x92,0x10,0x91,0x0c,0x10,0x08,0x01,0xff,0x75,0xcc,0x9b,0x00,0x01,0x00,0x01,
-       0x00,0x01,0x00,0x01,0x00,0xcf,0x86,0xd5,0xb4,0xd4,0x24,0x53,0x04,0x01,0x00,0x52,
-       0x04,0x01,0x00,0xd1,0x0c,0x10,0x04,0x01,0x00,0x01,0xff,0x41,0xcc,0x8c,0x00,0x10,
-       0x08,0x01,0xff,0x61,0xcc,0x8c,0x00,0x01,0xff,0x49,0xcc,0x8c,0x00,0xd3,0x46,0xd2,
-       0x20,0xd1,0x10,0x10,0x08,0x01,0xff,0x69,0xcc,0x8c,0x00,0x01,0xff,0x4f,0xcc,0x8c,
-       0x00,0x10,0x08,0x01,0xff,0x6f,0xcc,0x8c,0x00,0x01,0xff,0x55,0xcc,0x8c,0x00,0xd1,
-       0x12,0x10,0x08,0x01,0xff,0x75,0xcc,0x8c,0x00,0x01,0xff,0x55,0xcc,0x88,0xcc,0x84,
-       0x00,0x10,0x0a,0x01,0xff,0x75,0xcc,0x88,0xcc,0x84,0x00,0x01,0xff,0x55,0xcc,0x88,
-       0xcc,0x81,0x00,0xd2,0x28,0xd1,0x14,0x10,0x0a,0x01,0xff,0x75,0xcc,0x88,0xcc,0x81,
-       0x00,0x01,0xff,0x55,0xcc,0x88,0xcc,0x8c,0x00,0x10,0x0a,0x01,0xff,0x75,0xcc,0x88,
-       0xcc,0x8c,0x00,0x01,0xff,0x55,0xcc,0x88,0xcc,0x80,0x00,0xd1,0x0e,0x10,0x0a,0x01,
-       0xff,0x75,0xcc,0x88,0xcc,0x80,0x00,0x01,0x00,0x10,0x0a,0x01,0xff,0x41,0xcc,0x88,
-       0xcc,0x84,0x00,0x01,0xff,0x61,0xcc,0x88,0xcc,0x84,0x00,0xd4,0x80,0xd3,0x3a,0xd2,
-       0x26,0xd1,0x14,0x10,0x0a,0x01,0xff,0x41,0xcc,0x87,0xcc,0x84,0x00,0x01,0xff,0x61,
-       0xcc,0x87,0xcc,0x84,0x00,0x10,0x09,0x01,0xff,0xc3,0x86,0xcc,0x84,0x00,0x01,0xff,
-       0xc3,0xa6,0xcc,0x84,0x00,0x51,0x04,0x01,0x00,0x10,0x08,0x01,0xff,0x47,0xcc,0x8c,
-       0x00,0x01,0xff,0x67,0xcc,0x8c,0x00,0xd2,0x20,0xd1,0x10,0x10,0x08,0x01,0xff,0x4b,
-       0xcc,0x8c,0x00,0x01,0xff,0x6b,0xcc,0x8c,0x00,0x10,0x08,0x01,0xff,0x4f,0xcc,0xa8,
-       0x00,0x01,0xff,0x6f,0xcc,0xa8,0x00,0xd1,0x14,0x10,0x0a,0x01,0xff,0x4f,0xcc,0xa8,
-       0xcc,0x84,0x00,0x01,0xff,0x6f,0xcc,0xa8,0xcc,0x84,0x00,0x10,0x09,0x01,0xff,0xc6,
-       0xb7,0xcc,0x8c,0x00,0x01,0xff,0xca,0x92,0xcc,0x8c,0x00,0xd3,0x24,0xd2,0x10,0x91,
-       0x0c,0x10,0x08,0x01,0xff,0x6a,0xcc,0x8c,0x00,0x01,0x00,0x01,0x00,0x91,0x10,0x10,
-       0x08,0x01,0xff,0x47,0xcc,0x81,0x00,0x01,0xff,0x67,0xcc,0x81,0x00,0x04,0x00,0xd2,
-       0x24,0xd1,0x10,0x10,0x08,0x04,0xff,0x4e,0xcc,0x80,0x00,0x04,0xff,0x6e,0xcc,0x80,
-       0x00,0x10,0x0a,0x01,0xff,0x41,0xcc,0x8a,0xcc,0x81,0x00,0x01,0xff,0x61,0xcc,0x8a,
-       0xcc,0x81,0x00,0xd1,0x12,0x10,0x09,0x01,0xff,0xc3,0x86,0xcc,0x81,0x00,0x01,0xff,
-       0xc3,0xa6,0xcc,0x81,0x00,0x10,0x09,0x01,0xff,0xc3,0x98,0xcc,0x81,0x00,0x01,0xff,
-       0xc3,0xb8,0xcc,0x81,0x00,0xe2,0x07,0x02,0xe1,0xae,0x01,0xe0,0x93,0x01,0xcf,0x86,
-       0xd5,0xf4,0xd4,0x80,0xd3,0x40,0xd2,0x20,0xd1,0x10,0x10,0x08,0x01,0xff,0x41,0xcc,
-       0x8f,0x00,0x01,0xff,0x61,0xcc,0x8f,0x00,0x10,0x08,0x01,0xff,0x41,0xcc,0x91,0x00,
-       0x01,0xff,0x61,0xcc,0x91,0x00,0xd1,0x10,0x10,0x08,0x01,0xff,0x45,0xcc,0x8f,0x00,
-       0x01,0xff,0x65,0xcc,0x8f,0x00,0x10,0x08,0x01,0xff,0x45,0xcc,0x91,0x00,0x01,0xff,
-       0x65,0xcc,0x91,0x00,0xd2,0x20,0xd1,0x10,0x10,0x08,0x01,0xff,0x49,0xcc,0x8f,0x00,
-       0x01,0xff,0x69,0xcc,0x8f,0x00,0x10,0x08,0x01,0xff,0x49,0xcc,0x91,0x00,0x01,0xff,
-       0x69,0xcc,0x91,0x00,0xd1,0x10,0x10,0x08,0x01,0xff,0x4f,0xcc,0x8f,0x00,0x01,0xff,
-       0x6f,0xcc,0x8f,0x00,0x10,0x08,0x01,0xff,0x4f,0xcc,0x91,0x00,0x01,0xff,0x6f,0xcc,
-       0x91,0x00,0xd3,0x40,0xd2,0x20,0xd1,0x10,0x10,0x08,0x01,0xff,0x52,0xcc,0x8f,0x00,
-       0x01,0xff,0x72,0xcc,0x8f,0x00,0x10,0x08,0x01,0xff,0x52,0xcc,0x91,0x00,0x01,0xff,
-       0x72,0xcc,0x91,0x00,0xd1,0x10,0x10,0x08,0x01,0xff,0x55,0xcc,0x8f,0x00,0x01,0xff,
-       0x75,0xcc,0x8f,0x00,0x10,0x08,0x01,0xff,0x55,0xcc,0x91,0x00,0x01,0xff,0x75,0xcc,
-       0x91,0x00,0xd2,0x20,0xd1,0x10,0x10,0x08,0x04,0xff,0x53,0xcc,0xa6,0x00,0x04,0xff,
-       0x73,0xcc,0xa6,0x00,0x10,0x08,0x04,0xff,0x54,0xcc,0xa6,0x00,0x04,0xff,0x74,0xcc,
-       0xa6,0x00,0x51,0x04,0x04,0x00,0x10,0x08,0x04,0xff,0x48,0xcc,0x8c,0x00,0x04,0xff,
-       0x68,0xcc,0x8c,0x00,0xd4,0x68,0xd3,0x20,0xd2,0x0c,0x91,0x08,0x10,0x04,0x06,0x00,
-       0x07,0x00,0x04,0x00,0x51,0x04,0x04,0x00,0x10,0x08,0x04,0xff,0x41,0xcc,0x87,0x00,
-       0x04,0xff,0x61,0xcc,0x87,0x00,0xd2,0x24,0xd1,0x10,0x10,0x08,0x04,0xff,0x45,0xcc,
-       0xa7,0x00,0x04,0xff,0x65,0xcc,0xa7,0x00,0x10,0x0a,0x04,0xff,0x4f,0xcc,0x88,0xcc,
+       0xcc,0x88,0x00,0xd3,0x3b,0xd2,0x1f,0xd1,0x0f,0x10,0x07,0x01,0xff,0xc3,0xb0,0x00,
+       0x01,0xff,0x6e,0xcc,0x83,0x00,0x10,0x08,0x01,0xff,0x6f,0xcc,0x80,0x00,0x01,0xff,
+       0x6f,0xcc,0x81,0x00,0xd1,0x10,0x10,0x08,0x01,0xff,0x6f,0xcc,0x82,0x00,0x01,0xff,
+       0x6f,0xcc,0x83,0x00,0x10,0x08,0x01,0xff,0x6f,0xcc,0x88,0x00,0x01,0x00,0xd2,0x1f,
+       0xd1,0x0f,0x10,0x07,0x01,0xff,0xc3,0xb8,0x00,0x01,0xff,0x75,0xcc,0x80,0x00,0x10,
+       0x08,0x01,0xff,0x75,0xcc,0x81,0x00,0x01,0xff,0x75,0xcc,0x82,0x00,0xd1,0x10,0x10,
+       0x08,0x01,0xff,0x75,0xcc,0x88,0x00,0x01,0xff,0x79,0xcc,0x81,0x00,0x10,0x07,0x01,
+       0xff,0xc3,0xbe,0x00,0x01,0xff,0x73,0x73,0x00,0xe1,0xd4,0x03,0xe0,0xeb,0x01,0xcf,
+       0x86,0xd5,0xfb,0xd4,0x80,0xd3,0x40,0xd2,0x20,0xd1,0x10,0x10,0x08,0x01,0xff,0x61,
+       0xcc,0x84,0x00,0x01,0xff,0x61,0xcc,0x84,0x00,0x10,0x08,0x01,0xff,0x61,0xcc,0x86,
+       0x00,0x01,0xff,0x61,0xcc,0x86,0x00,0xd1,0x10,0x10,0x08,0x01,0xff,0x61,0xcc,0xa8,
+       0x00,0x01,0xff,0x61,0xcc,0xa8,0x00,0x10,0x08,0x01,0xff,0x63,0xcc,0x81,0x00,0x01,
+       0xff,0x63,0xcc,0x81,0x00,0xd2,0x20,0xd1,0x10,0x10,0x08,0x01,0xff,0x63,0xcc,0x82,
+       0x00,0x01,0xff,0x63,0xcc,0x82,0x00,0x10,0x08,0x01,0xff,0x63,0xcc,0x87,0x00,0x01,
+       0xff,0x63,0xcc,0x87,0x00,0xd1,0x10,0x10,0x08,0x01,0xff,0x63,0xcc,0x8c,0x00,0x01,
+       0xff,0x63,0xcc,0x8c,0x00,0x10,0x08,0x01,0xff,0x64,0xcc,0x8c,0x00,0x01,0xff,0x64,
+       0xcc,0x8c,0x00,0xd3,0x3b,0xd2,0x1b,0xd1,0x0b,0x10,0x07,0x01,0xff,0xc4,0x91,0x00,
+       0x01,0x00,0x10,0x08,0x01,0xff,0x65,0xcc,0x84,0x00,0x01,0xff,0x65,0xcc,0x84,0x00,
+       0xd1,0x10,0x10,0x08,0x01,0xff,0x65,0xcc,0x86,0x00,0x01,0xff,0x65,0xcc,0x86,0x00,
+       0x10,0x08,0x01,0xff,0x65,0xcc,0x87,0x00,0x01,0xff,0x65,0xcc,0x87,0x00,0xd2,0x20,
+       0xd1,0x10,0x10,0x08,0x01,0xff,0x65,0xcc,0xa8,0x00,0x01,0xff,0x65,0xcc,0xa8,0x00,
+       0x10,0x08,0x01,0xff,0x65,0xcc,0x8c,0x00,0x01,0xff,0x65,0xcc,0x8c,0x00,0xd1,0x10,
+       0x10,0x08,0x01,0xff,0x67,0xcc,0x82,0x00,0x01,0xff,0x67,0xcc,0x82,0x00,0x10,0x08,
+       0x01,0xff,0x67,0xcc,0x86,0x00,0x01,0xff,0x67,0xcc,0x86,0x00,0xd4,0x7b,0xd3,0x3b,
+       0xd2,0x20,0xd1,0x10,0x10,0x08,0x01,0xff,0x67,0xcc,0x87,0x00,0x01,0xff,0x67,0xcc,
+       0x87,0x00,0x10,0x08,0x01,0xff,0x67,0xcc,0xa7,0x00,0x01,0xff,0x67,0xcc,0xa7,0x00,
+       0xd1,0x10,0x10,0x08,0x01,0xff,0x68,0xcc,0x82,0x00,0x01,0xff,0x68,0xcc,0x82,0x00,
+       0x10,0x07,0x01,0xff,0xc4,0xa7,0x00,0x01,0x00,0xd2,0x20,0xd1,0x10,0x10,0x08,0x01,
+       0xff,0x69,0xcc,0x83,0x00,0x01,0xff,0x69,0xcc,0x83,0x00,0x10,0x08,0x01,0xff,0x69,
+       0xcc,0x84,0x00,0x01,0xff,0x69,0xcc,0x84,0x00,0xd1,0x10,0x10,0x08,0x01,0xff,0x69,
+       0xcc,0x86,0x00,0x01,0xff,0x69,0xcc,0x86,0x00,0x10,0x08,0x01,0xff,0x69,0xcc,0xa8,
+       0x00,0x01,0xff,0x69,0xcc,0xa8,0x00,0xd3,0x37,0xd2,0x17,0xd1,0x0c,0x10,0x08,0x01,
+       0xff,0x69,0xcc,0x87,0x00,0x01,0x00,0x10,0x07,0x01,0xff,0xc4,0xb3,0x00,0x01,0x00,
+       0xd1,0x10,0x10,0x08,0x01,0xff,0x6a,0xcc,0x82,0x00,0x01,0xff,0x6a,0xcc,0x82,0x00,
+       0x10,0x08,0x01,0xff,0x6b,0xcc,0xa7,0x00,0x01,0xff,0x6b,0xcc,0xa7,0x00,0xd2,0x1c,
+       0xd1,0x0c,0x10,0x04,0x01,0x00,0x01,0xff,0x6c,0xcc,0x81,0x00,0x10,0x08,0x01,0xff,
+       0x6c,0xcc,0x81,0x00,0x01,0xff,0x6c,0xcc,0xa7,0x00,0xd1,0x10,0x10,0x08,0x01,0xff,
+       0x6c,0xcc,0xa7,0x00,0x01,0xff,0x6c,0xcc,0x8c,0x00,0x10,0x08,0x01,0xff,0x6c,0xcc,
+       0x8c,0x00,0x01,0xff,0xc5,0x80,0x00,0xcf,0x86,0xd5,0xed,0xd4,0x72,0xd3,0x37,0xd2,
+       0x17,0xd1,0x0b,0x10,0x04,0x01,0x00,0x01,0xff,0xc5,0x82,0x00,0x10,0x04,0x01,0x00,
+       0x01,0xff,0x6e,0xcc,0x81,0x00,0xd1,0x10,0x10,0x08,0x01,0xff,0x6e,0xcc,0x81,0x00,
+       0x01,0xff,0x6e,0xcc,0xa7,0x00,0x10,0x08,0x01,0xff,0x6e,0xcc,0xa7,0x00,0x01,0xff,
+       0x6e,0xcc,0x8c,0x00,0xd2,0x1b,0xd1,0x10,0x10,0x08,0x01,0xff,0x6e,0xcc,0x8c,0x00,
+       0x01,0xff,0xca,0xbc,0x6e,0x00,0x10,0x07,0x01,0xff,0xc5,0x8b,0x00,0x01,0x00,0xd1,
+       0x10,0x10,0x08,0x01,0xff,0x6f,0xcc,0x84,0x00,0x01,0xff,0x6f,0xcc,0x84,0x00,0x10,
+       0x08,0x01,0xff,0x6f,0xcc,0x86,0x00,0x01,0xff,0x6f,0xcc,0x86,0x00,0xd3,0x3b,0xd2,
+       0x1b,0xd1,0x10,0x10,0x08,0x01,0xff,0x6f,0xcc,0x8b,0x00,0x01,0xff,0x6f,0xcc,0x8b,
+       0x00,0x10,0x07,0x01,0xff,0xc5,0x93,0x00,0x01,0x00,0xd1,0x10,0x10,0x08,0x01,0xff,
+       0x72,0xcc,0x81,0x00,0x01,0xff,0x72,0xcc,0x81,0x00,0x10,0x08,0x01,0xff,0x72,0xcc,
+       0xa7,0x00,0x01,0xff,0x72,0xcc,0xa7,0x00,0xd2,0x20,0xd1,0x10,0x10,0x08,0x01,0xff,
+       0x72,0xcc,0x8c,0x00,0x01,0xff,0x72,0xcc,0x8c,0x00,0x10,0x08,0x01,0xff,0x73,0xcc,
+       0x81,0x00,0x01,0xff,0x73,0xcc,0x81,0x00,0xd1,0x10,0x10,0x08,0x01,0xff,0x73,0xcc,
+       0x82,0x00,0x01,0xff,0x73,0xcc,0x82,0x00,0x10,0x08,0x01,0xff,0x73,0xcc,0xa7,0x00,
+       0x01,0xff,0x73,0xcc,0xa7,0x00,0xd4,0x7b,0xd3,0x3b,0xd2,0x20,0xd1,0x10,0x10,0x08,
+       0x01,0xff,0x73,0xcc,0x8c,0x00,0x01,0xff,0x73,0xcc,0x8c,0x00,0x10,0x08,0x01,0xff,
+       0x74,0xcc,0xa7,0x00,0x01,0xff,0x74,0xcc,0xa7,0x00,0xd1,0x10,0x10,0x08,0x01,0xff,
+       0x74,0xcc,0x8c,0x00,0x01,0xff,0x74,0xcc,0x8c,0x00,0x10,0x07,0x01,0xff,0xc5,0xa7,
+       0x00,0x01,0x00,0xd2,0x20,0xd1,0x10,0x10,0x08,0x01,0xff,0x75,0xcc,0x83,0x00,0x01,
+       0xff,0x75,0xcc,0x83,0x00,0x10,0x08,0x01,0xff,0x75,0xcc,0x84,0x00,0x01,0xff,0x75,
+       0xcc,0x84,0x00,0xd1,0x10,0x10,0x08,0x01,0xff,0x75,0xcc,0x86,0x00,0x01,0xff,0x75,
+       0xcc,0x86,0x00,0x10,0x08,0x01,0xff,0x75,0xcc,0x8a,0x00,0x01,0xff,0x75,0xcc,0x8a,
+       0x00,0xd3,0x40,0xd2,0x20,0xd1,0x10,0x10,0x08,0x01,0xff,0x75,0xcc,0x8b,0x00,0x01,
+       0xff,0x75,0xcc,0x8b,0x00,0x10,0x08,0x01,0xff,0x75,0xcc,0xa8,0x00,0x01,0xff,0x75,
+       0xcc,0xa8,0x00,0xd1,0x10,0x10,0x08,0x01,0xff,0x77,0xcc,0x82,0x00,0x01,0xff,0x77,
+       0xcc,0x82,0x00,0x10,0x08,0x01,0xff,0x79,0xcc,0x82,0x00,0x01,0xff,0x79,0xcc,0x82,
+       0x00,0xd2,0x20,0xd1,0x10,0x10,0x08,0x01,0xff,0x79,0xcc,0x88,0x00,0x01,0xff,0x7a,
+       0xcc,0x81,0x00,0x10,0x08,0x01,0xff,0x7a,0xcc,0x81,0x00,0x01,0xff,0x7a,0xcc,0x87,
+       0x00,0xd1,0x10,0x10,0x08,0x01,0xff,0x7a,0xcc,0x87,0x00,0x01,0xff,0x7a,0xcc,0x8c,
+       0x00,0x10,0x08,0x01,0xff,0x7a,0xcc,0x8c,0x00,0x01,0xff,0x73,0x00,0xe0,0x65,0x01,
+       0xcf,0x86,0xd5,0xb4,0xd4,0x5a,0xd3,0x2f,0xd2,0x16,0xd1,0x0b,0x10,0x04,0x01,0x00,
+       0x01,0xff,0xc9,0x93,0x00,0x10,0x07,0x01,0xff,0xc6,0x83,0x00,0x01,0x00,0xd1,0x0b,
+       0x10,0x07,0x01,0xff,0xc6,0x85,0x00,0x01,0x00,0x10,0x07,0x01,0xff,0xc9,0x94,0x00,
+       0x01,0xff,0xc6,0x88,0x00,0xd2,0x19,0xd1,0x0b,0x10,0x04,0x01,0x00,0x01,0xff,0xc9,
+       0x96,0x00,0x10,0x07,0x01,0xff,0xc9,0x97,0x00,0x01,0xff,0xc6,0x8c,0x00,0x51,0x04,
+       0x01,0x00,0x10,0x07,0x01,0xff,0xc7,0x9d,0x00,0x01,0xff,0xc9,0x99,0x00,0xd3,0x32,
+       0xd2,0x19,0xd1,0x0e,0x10,0x07,0x01,0xff,0xc9,0x9b,0x00,0x01,0xff,0xc6,0x92,0x00,
+       0x10,0x04,0x01,0x00,0x01,0xff,0xc9,0xa0,0x00,0xd1,0x0b,0x10,0x07,0x01,0xff,0xc9,
+       0xa3,0x00,0x01,0x00,0x10,0x07,0x01,0xff,0xc9,0xa9,0x00,0x01,0xff,0xc9,0xa8,0x00,
+       0xd2,0x0f,0x91,0x0b,0x10,0x07,0x01,0xff,0xc6,0x99,0x00,0x01,0x00,0x01,0x00,0xd1,
+       0x0e,0x10,0x07,0x01,0xff,0xc9,0xaf,0x00,0x01,0xff,0xc9,0xb2,0x00,0x10,0x04,0x01,
+       0x00,0x01,0xff,0xc9,0xb5,0x00,0xd4,0x5d,0xd3,0x34,0xd2,0x1b,0xd1,0x10,0x10,0x08,
+       0x01,0xff,0x6f,0xcc,0x9b,0x00,0x01,0xff,0x6f,0xcc,0x9b,0x00,0x10,0x07,0x01,0xff,
+       0xc6,0xa3,0x00,0x01,0x00,0xd1,0x0b,0x10,0x07,0x01,0xff,0xc6,0xa5,0x00,0x01,0x00,
+       0x10,0x07,0x01,0xff,0xca,0x80,0x00,0x01,0xff,0xc6,0xa8,0x00,0xd2,0x0f,0x91,0x0b,
+       0x10,0x04,0x01,0x00,0x01,0xff,0xca,0x83,0x00,0x01,0x00,0xd1,0x0b,0x10,0x07,0x01,
+       0xff,0xc6,0xad,0x00,0x01,0x00,0x10,0x07,0x01,0xff,0xca,0x88,0x00,0x01,0xff,0x75,
+       0xcc,0x9b,0x00,0xd3,0x33,0xd2,0x1d,0xd1,0x0f,0x10,0x08,0x01,0xff,0x75,0xcc,0x9b,
+       0x00,0x01,0xff,0xca,0x8a,0x00,0x10,0x07,0x01,0xff,0xca,0x8b,0x00,0x01,0xff,0xc6,
+       0xb4,0x00,0xd1,0x0b,0x10,0x04,0x01,0x00,0x01,0xff,0xc6,0xb6,0x00,0x10,0x04,0x01,
+       0x00,0x01,0xff,0xca,0x92,0x00,0xd2,0x0f,0x91,0x0b,0x10,0x07,0x01,0xff,0xc6,0xb9,
+       0x00,0x01,0x00,0x01,0x00,0x91,0x0b,0x10,0x07,0x01,0xff,0xc6,0xbd,0x00,0x01,0x00,
+       0x01,0x00,0xcf,0x86,0xd5,0xd4,0xd4,0x44,0xd3,0x16,0x52,0x04,0x01,0x00,0x51,0x07,
+       0x01,0xff,0xc7,0x86,0x00,0x10,0x04,0x01,0x00,0x01,0xff,0xc7,0x89,0x00,0xd2,0x12,
+       0x91,0x0b,0x10,0x07,0x01,0xff,0xc7,0x89,0x00,0x01,0x00,0x01,0xff,0xc7,0x8c,0x00,
+       0xd1,0x0c,0x10,0x04,0x01,0x00,0x01,0xff,0x61,0xcc,0x8c,0x00,0x10,0x08,0x01,0xff,
+       0x61,0xcc,0x8c,0x00,0x01,0xff,0x69,0xcc,0x8c,0x00,0xd3,0x46,0xd2,0x20,0xd1,0x10,
+       0x10,0x08,0x01,0xff,0x69,0xcc,0x8c,0x00,0x01,0xff,0x6f,0xcc,0x8c,0x00,0x10,0x08,
+       0x01,0xff,0x6f,0xcc,0x8c,0x00,0x01,0xff,0x75,0xcc,0x8c,0x00,0xd1,0x12,0x10,0x08,
+       0x01,0xff,0x75,0xcc,0x8c,0x00,0x01,0xff,0x75,0xcc,0x88,0xcc,0x84,0x00,0x10,0x0a,
+       0x01,0xff,0x75,0xcc,0x88,0xcc,0x84,0x00,0x01,0xff,0x75,0xcc,0x88,0xcc,0x81,0x00,
+       0xd2,0x28,0xd1,0x14,0x10,0x0a,0x01,0xff,0x75,0xcc,0x88,0xcc,0x81,0x00,0x01,0xff,
+       0x75,0xcc,0x88,0xcc,0x8c,0x00,0x10,0x0a,0x01,0xff,0x75,0xcc,0x88,0xcc,0x8c,0x00,
+       0x01,0xff,0x75,0xcc,0x88,0xcc,0x80,0x00,0xd1,0x0e,0x10,0x0a,0x01,0xff,0x75,0xcc,
+       0x88,0xcc,0x80,0x00,0x01,0x00,0x10,0x0a,0x01,0xff,0x61,0xcc,0x88,0xcc,0x84,0x00,
+       0x01,0xff,0x61,0xcc,0x88,0xcc,0x84,0x00,0xd4,0x87,0xd3,0x41,0xd2,0x26,0xd1,0x14,
+       0x10,0x0a,0x01,0xff,0x61,0xcc,0x87,0xcc,0x84,0x00,0x01,0xff,0x61,0xcc,0x87,0xcc,
+       0x84,0x00,0x10,0x09,0x01,0xff,0xc3,0xa6,0xcc,0x84,0x00,0x01,0xff,0xc3,0xa6,0xcc,
+       0x84,0x00,0xd1,0x0b,0x10,0x07,0x01,0xff,0xc7,0xa5,0x00,0x01,0x00,0x10,0x08,0x01,
+       0xff,0x67,0xcc,0x8c,0x00,0x01,0xff,0x67,0xcc,0x8c,0x00,0xd2,0x20,0xd1,0x10,0x10,
+       0x08,0x01,0xff,0x6b,0xcc,0x8c,0x00,0x01,0xff,0x6b,0xcc,0x8c,0x00,0x10,0x08,0x01,
+       0xff,0x6f,0xcc,0xa8,0x00,0x01,0xff,0x6f,0xcc,0xa8,0x00,0xd1,0x14,0x10,0x0a,0x01,
+       0xff,0x6f,0xcc,0xa8,0xcc,0x84,0x00,0x01,0xff,0x6f,0xcc,0xa8,0xcc,0x84,0x00,0x10,
+       0x09,0x01,0xff,0xca,0x92,0xcc,0x8c,0x00,0x01,0xff,0xca,0x92,0xcc,0x8c,0x00,0xd3,
+       0x38,0xd2,0x1a,0xd1,0x0f,0x10,0x08,0x01,0xff,0x6a,0xcc,0x8c,0x00,0x01,0xff,0xc7,
+       0xb3,0x00,0x10,0x07,0x01,0xff,0xc7,0xb3,0x00,0x01,0x00,0xd1,0x10,0x10,0x08,0x01,
+       0xff,0x67,0xcc,0x81,0x00,0x01,0xff,0x67,0xcc,0x81,0x00,0x10,0x07,0x04,0xff,0xc6,
+       0x95,0x00,0x04,0xff,0xc6,0xbf,0x00,0xd2,0x24,0xd1,0x10,0x10,0x08,0x04,0xff,0x6e,
+       0xcc,0x80,0x00,0x04,0xff,0x6e,0xcc,0x80,0x00,0x10,0x0a,0x01,0xff,0x61,0xcc,0x8a,
+       0xcc,0x81,0x00,0x01,0xff,0x61,0xcc,0x8a,0xcc,0x81,0x00,0xd1,0x12,0x10,0x09,0x01,
+       0xff,0xc3,0xa6,0xcc,0x81,0x00,0x01,0xff,0xc3,0xa6,0xcc,0x81,0x00,0x10,0x09,0x01,
+       0xff,0xc3,0xb8,0xcc,0x81,0x00,0x01,0xff,0xc3,0xb8,0xcc,0x81,0x00,0xe2,0x31,0x02,
+       0xe1,0xad,0x44,0xe0,0xc8,0x01,0xcf,0x86,0xd5,0xfb,0xd4,0x80,0xd3,0x40,0xd2,0x20,
+       0xd1,0x10,0x10,0x08,0x01,0xff,0x61,0xcc,0x8f,0x00,0x01,0xff,0x61,0xcc,0x8f,0x00,
+       0x10,0x08,0x01,0xff,0x61,0xcc,0x91,0x00,0x01,0xff,0x61,0xcc,0x91,0x00,0xd1,0x10,
+       0x10,0x08,0x01,0xff,0x65,0xcc,0x8f,0x00,0x01,0xff,0x65,0xcc,0x8f,0x00,0x10,0x08,
+       0x01,0xff,0x65,0xcc,0x91,0x00,0x01,0xff,0x65,0xcc,0x91,0x00,0xd2,0x20,0xd1,0x10,
+       0x10,0x08,0x01,0xff,0x69,0xcc,0x8f,0x00,0x01,0xff,0x69,0xcc,0x8f,0x00,0x10,0x08,
+       0x01,0xff,0x69,0xcc,0x91,0x00,0x01,0xff,0x69,0xcc,0x91,0x00,0xd1,0x10,0x10,0x08,
+       0x01,0xff,0x6f,0xcc,0x8f,0x00,0x01,0xff,0x6f,0xcc,0x8f,0x00,0x10,0x08,0x01,0xff,
+       0x6f,0xcc,0x91,0x00,0x01,0xff,0x6f,0xcc,0x91,0x00,0xd3,0x40,0xd2,0x20,0xd1,0x10,
+       0x10,0x08,0x01,0xff,0x72,0xcc,0x8f,0x00,0x01,0xff,0x72,0xcc,0x8f,0x00,0x10,0x08,
+       0x01,0xff,0x72,0xcc,0x91,0x00,0x01,0xff,0x72,0xcc,0x91,0x00,0xd1,0x10,0x10,0x08,
+       0x01,0xff,0x75,0xcc,0x8f,0x00,0x01,0xff,0x75,0xcc,0x8f,0x00,0x10,0x08,0x01,0xff,
+       0x75,0xcc,0x91,0x00,0x01,0xff,0x75,0xcc,0x91,0x00,0xd2,0x20,0xd1,0x10,0x10,0x08,
+       0x04,0xff,0x73,0xcc,0xa6,0x00,0x04,0xff,0x73,0xcc,0xa6,0x00,0x10,0x08,0x04,0xff,
+       0x74,0xcc,0xa6,0x00,0x04,0xff,0x74,0xcc,0xa6,0x00,0xd1,0x0b,0x10,0x07,0x04,0xff,
+       0xc8,0x9d,0x00,0x04,0x00,0x10,0x08,0x04,0xff,0x68,0xcc,0x8c,0x00,0x04,0xff,0x68,
+       0xcc,0x8c,0x00,0xd4,0x79,0xd3,0x31,0xd2,0x16,0xd1,0x0b,0x10,0x07,0x06,0xff,0xc6,
+       0x9e,0x00,0x07,0x00,0x10,0x07,0x04,0xff,0xc8,0xa3,0x00,0x04,0x00,0xd1,0x0b,0x10,
+       0x07,0x04,0xff,0xc8,0xa5,0x00,0x04,0x00,0x10,0x08,0x04,0xff,0x61,0xcc,0x87,0x00,
+       0x04,0xff,0x61,0xcc,0x87,0x00,0xd2,0x24,0xd1,0x10,0x10,0x08,0x04,0xff,0x65,0xcc,
+       0xa7,0x00,0x04,0xff,0x65,0xcc,0xa7,0x00,0x10,0x0a,0x04,0xff,0x6f,0xcc,0x88,0xcc,
        0x84,0x00,0x04,0xff,0x6f,0xcc,0x88,0xcc,0x84,0x00,0xd1,0x14,0x10,0x0a,0x04,0xff,
-       0x4f,0xcc,0x83,0xcc,0x84,0x00,0x04,0xff,0x6f,0xcc,0x83,0xcc,0x84,0x00,0x10,0x08,
-       0x04,0xff,0x4f,0xcc,0x87,0x00,0x04,0xff,0x6f,0xcc,0x87,0x00,0x93,0x30,0xd2,0x24,
-       0xd1,0x14,0x10,0x0a,0x04,0xff,0x4f,0xcc,0x87,0xcc,0x84,0x00,0x04,0xff,0x6f,0xcc,
-       0x87,0xcc,0x84,0x00,0x10,0x08,0x04,0xff,0x59,0xcc,0x84,0x00,0x04,0xff,0x79,0xcc,
-       0x84,0x00,0x51,0x04,0x07,0x00,0x10,0x04,0x07,0x00,0x08,0x00,0x08,0x00,0xcf,0x86,
-       0x95,0x14,0x94,0x10,0x93,0x0c,0x92,0x08,0x11,0x04,0x08,0x00,0x09,0x00,0x09,0x00,
-       0x09,0x00,0x01,0x00,0x01,0x00,0xd0,0x22,0xcf,0x86,0x55,0x04,0x01,0x00,0x94,0x18,
-       0x53,0x04,0x01,0x00,0xd2,0x0c,0x91,0x08,0x10,0x04,0x01,0x00,0x04,0x00,0x04,0x00,
-       0x11,0x04,0x04,0x00,0x07,0x00,0x01,0x00,0xcf,0x86,0xd5,0x18,0x54,0x04,0x01,0x00,
-       0x53,0x04,0x01,0x00,0x52,0x04,0x01,0x00,0x51,0x04,0x01,0x00,0x10,0x04,0x01,0x00,
-       0x04,0x00,0x94,0x18,0x53,0x04,0x01,0x00,0xd2,0x08,0x11,0x04,0x01,0x00,0x04,0x00,
-       0x51,0x04,0x04,0x00,0x10,0x04,0x04,0x00,0x07,0x00,0x07,0x00,0xe1,0x35,0x01,0xd0,
-       0x72,0xcf,0x86,0xd5,0x24,0x54,0x04,0x01,0xe6,0xd3,0x10,0x52,0x04,0x01,0xe6,0x91,
-       0x08,0x10,0x04,0x01,0xe6,0x01,0xe8,0x01,0xdc,0x92,0x0c,0x51,0x04,0x01,0xdc,0x10,
-       0x04,0x01,0xe8,0x01,0xd8,0x01,0xdc,0xd4,0x2c,0xd3,0x1c,0xd2,0x10,0xd1,0x08,0x10,
-       0x04,0x01,0xdc,0x01,0xca,0x10,0x04,0x01,0xca,0x01,0xdc,0x51,0x04,0x01,0xdc,0x10,
-       0x04,0x01,0xdc,0x01,0xca,0x92,0x0c,0x91,0x08,0x10,0x04,0x01,0xca,0x01,0xdc,0x01,
-       0xdc,0x01,0xdc,0xd3,0x08,0x12,0x04,0x01,0xdc,0x01,0x01,0xd2,0x0c,0x91,0x08,0x10,
-       0x04,0x01,0x01,0x01,0xdc,0x01,0xdc,0x91,0x08,0x10,0x04,0x01,0xdc,0x01,0xe6,0x01,
-       0xe6,0xcf,0x86,0xd5,0x7f,0xd4,0x47,0xd3,0x2e,0xd2,0x19,0xd1,0x0e,0x10,0x07,0x01,
-       0xff,0xcc,0x80,0x00,0x01,0xff,0xcc,0x81,0x00,0x10,0x04,0x01,0xe6,0x01,0xff,0xcc,
-       0x93,0x00,0xd1,0x0d,0x10,0x09,0x01,0xff,0xcc,0x88,0xcc,0x81,0x00,0x01,0xf0,0x10,
-       0x04,0x04,0xe6,0x04,0xdc,0xd2,0x08,0x11,0x04,0x04,0xdc,0x04,0xe6,0xd1,0x08,0x10,
-       0x04,0x04,0xe6,0x04,0xdc,0x10,0x04,0x04,0xdc,0x06,0xff,0x00,0xd3,0x18,0xd2,0x0c,
-       0x51,0x04,0x07,0xe6,0x10,0x04,0x07,0xe6,0x07,0xdc,0x51,0x04,0x07,0xdc,0x10,0x04,
-       0x07,0xdc,0x07,0xe6,0xd2,0x10,0xd1,0x08,0x10,0x04,0x08,0xe8,0x08,0xdc,0x10,0x04,
-       0x08,0xdc,0x08,0xe6,0xd1,0x08,0x10,0x04,0x08,0xe9,0x07,0xea,0x10,0x04,0x07,0xea,
-       0x07,0xe9,0xd4,0x14,0x93,0x10,0x92,0x0c,0x51,0x04,0x01,0xea,0x10,0x04,0x04,0xe9,
-       0x06,0xe6,0x06,0xe6,0x06,0xe6,0xd3,0x13,0x52,0x04,0x0a,0x00,0x91,0x0b,0x10,0x07,
-       0x01,0xff,0xca,0xb9,0x00,0x01,0x00,0x0a,0x00,0xd2,0x0c,0x51,0x04,0x00,0x00,0x10,
-       0x04,0x01,0x00,0x09,0x00,0x51,0x04,0x09,0x00,0x10,0x06,0x01,0xff,0x3b,0x00,0x10,
-       0x00,0xd0,0xe1,0xcf,0x86,0xd5,0x7a,0xd4,0x5f,0xd3,0x21,0x52,0x04,0x00,0x00,0xd1,
-       0x0d,0x10,0x04,0x01,0x00,0x01,0xff,0xc2,0xa8,0xcc,0x81,0x00,0x10,0x09,0x01,0xff,
-       0xce,0x91,0xcc,0x81,0x00,0x01,0xff,0xc2,0xb7,0x00,0xd2,0x1f,0xd1,0x12,0x10,0x09,
-       0x01,0xff,0xce,0x95,0xcc,0x81,0x00,0x01,0xff,0xce,0x97,0xcc,0x81,0x00,0x10,0x09,
-       0x01,0xff,0xce,0x99,0xcc,0x81,0x00,0x00,0x00,0xd1,0x0d,0x10,0x09,0x01,0xff,0xce,
-       0x9f,0xcc,0x81,0x00,0x00,0x00,0x10,0x09,0x01,0xff,0xce,0xa5,0xcc,0x81,0x00,0x01,
-       0xff,0xce,0xa9,0xcc,0x81,0x00,0x93,0x17,0x92,0x13,0x91,0x0f,0x10,0x0b,0x01,0xff,
-       0xce,0xb9,0xcc,0x88,0xcc,0x81,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0xd4,
-       0x4a,0xd3,0x10,0x92,0x0c,0x51,0x04,0x01,0x00,0x10,0x04,0x00,0x00,0x01,0x00,0x01,
-       0x00,0xd2,0x16,0x51,0x04,0x01,0x00,0x10,0x09,0x01,0xff,0xce,0x99,0xcc,0x88,0x00,
-       0x01,0xff,0xce,0xa5,0xcc,0x88,0x00,0xd1,0x12,0x10,0x09,0x01,0xff,0xce,0xb1,0xcc,
-       0x81,0x00,0x01,0xff,0xce,0xb5,0xcc,0x81,0x00,0x10,0x09,0x01,0xff,0xce,0xb7,0xcc,
-       0x81,0x00,0x01,0xff,0xce,0xb9,0xcc,0x81,0x00,0x93,0x17,0x92,0x13,0x91,0x0f,0x10,
-       0x0b,0x01,0xff,0xcf,0x85,0xcc,0x88,0xcc,0x81,0x00,0x01,0x00,0x01,0x00,0x01,0x00,
-       0x01,0x00,0xcf,0x86,0xd5,0x7b,0xd4,0x39,0x53,0x04,0x01,0x00,0xd2,0x16,0x51,0x04,
-       0x01,0x00,0x10,0x09,0x01,0xff,0xce,0xb9,0xcc,0x88,0x00,0x01,0xff,0xcf,0x85,0xcc,
-       0x88,0x00,0xd1,0x12,0x10,0x09,0x01,0xff,0xce,0xbf,0xcc,0x81,0x00,0x01,0xff,0xcf,
-       0x85,0xcc,0x81,0x00,0x10,0x09,0x01,0xff,0xcf,0x89,0xcc,0x81,0x00,0x0a,0x00,0xd3,
-       0x26,0xd2,0x11,0x51,0x04,0x01,0x00,0x10,0x04,0x01,0x00,0x01,0xff,0xcf,0x92,0xcc,
-       0x81,0x00,0xd1,0x0d,0x10,0x09,0x01,0xff,0xcf,0x92,0xcc,0x88,0x00,0x01,0x00,0x10,
-       0x04,0x01,0x00,0x04,0x00,0xd2,0x0c,0x51,0x04,0x06,0x00,0x10,0x04,0x01,0x00,0x04,
-       0x00,0xd1,0x08,0x10,0x04,0x01,0x00,0x04,0x00,0x10,0x04,0x01,0x00,0x04,0x00,0xd4,
-       0x14,0x93,0x10,0x92,0x0c,0x91,0x08,0x10,0x04,0x01,0x00,0x04,0x00,0x01,0x00,0x01,
-       0x00,0x01,0x00,0xd3,0x10,0x52,0x04,0x01,0x00,0x51,0x04,0x05,0x00,0x10,0x04,0x06,
-       0x00,0x07,0x00,0x12,0x04,0x07,0x00,0x08,0x00,0xe3,0x47,0x04,0xe2,0xbe,0x02,0xe1,
-       0x07,0x01,0xd0,0x8b,0xcf,0x86,0xd5,0x6c,0xd4,0x53,0xd3,0x30,0xd2,0x1f,0xd1,0x12,
-       0x10,0x09,0x04,0xff,0xd0,0x95,0xcc,0x80,0x00,0x01,0xff,0xd0,0x95,0xcc,0x88,0x00,
-       0x10,0x04,0x01,0x00,0x01,0xff,0xd0,0x93,0xcc,0x81,0x00,0x51,0x04,0x01,0x00,0x10,
-       0x04,0x01,0x00,0x01,0xff,0xd0,0x86,0xcc,0x88,0x00,0x52,0x04,0x01,0x00,0xd1,0x12,
-       0x10,0x09,0x01,0xff,0xd0,0x9a,0xcc,0x81,0x00,0x04,0xff,0xd0,0x98,0xcc,0x80,0x00,
-       0x10,0x09,0x01,0xff,0xd0,0xa3,0xcc,0x86,0x00,0x01,0x00,0x53,0x04,0x01,0x00,0x92,
-       0x11,0x91,0x0d,0x10,0x04,0x01,0x00,0x01,0xff,0xd0,0x98,0xcc,0x86,0x00,0x01,0x00,
-       0x01,0x00,0x54,0x04,0x01,0x00,0x53,0x04,0x01,0x00,0x92,0x11,0x91,0x0d,0x10,0x04,
-       0x01,0x00,0x01,0xff,0xd0,0xb8,0xcc,0x86,0x00,0x01,0x00,0x01,0x00,0xcf,0x86,0xd5,
-       0x57,0x54,0x04,0x01,0x00,0xd3,0x30,0xd2,0x1f,0xd1,0x12,0x10,0x09,0x04,0xff,0xd0,
-       0xb5,0xcc,0x80,0x00,0x01,0xff,0xd0,0xb5,0xcc,0x88,0x00,0x10,0x04,0x01,0x00,0x01,
-       0xff,0xd0,0xb3,0xcc,0x81,0x00,0x51,0x04,0x01,0x00,0x10,0x04,0x01,0x00,0x01,0xff,
-       0xd1,0x96,0xcc,0x88,0x00,0x52,0x04,0x01,0x00,0xd1,0x12,0x10,0x09,0x01,0xff,0xd0,
-       0xba,0xcc,0x81,0x00,0x04,0xff,0xd0,0xb8,0xcc,0x80,0x00,0x10,0x09,0x01,0xff,0xd1,
-       0x83,0xcc,0x86,0x00,0x01,0x00,0x54,0x04,0x01,0x00,0x93,0x1a,0x52,0x04,0x01,0x00,
-       0x51,0x04,0x01,0x00,0x10,0x09,0x01,0xff,0xd1,0xb4,0xcc,0x8f,0x00,0x01,0xff,0xd1,
-       0xb5,0xcc,0x8f,0x00,0x01,0x00,0xd0,0x2e,0xcf,0x86,0x95,0x28,0x94,0x24,0xd3,0x18,
-       0xd2,0x0c,0x51,0x04,0x01,0x00,0x10,0x04,0x01,0x00,0x01,0xe6,0x51,0x04,0x01,0xe6,
-       0x10,0x04,0x01,0xe6,0x0a,0xe6,0x92,0x08,0x11,0x04,0x04,0x00,0x06,0x00,0x04,0x00,
-       0x01,0x00,0x01,0x00,0xcf,0x86,0xd5,0xbe,0xd4,0x4a,0xd3,0x2a,0xd2,0x1a,0xd1,0x0d,
-       0x10,0x04,0x01,0x00,0x01,0xff,0xd0,0x96,0xcc,0x86,0x00,0x10,0x09,0x01,0xff,0xd0,
-       0xb6,0xcc,0x86,0x00,0x01,0x00,0xd1,0x08,0x10,0x04,0x01,0x00,0x06,0x00,0x10,0x04,
-       0x06,0x00,0x01,0x00,0xd2,0x10,0xd1,0x08,0x10,0x04,0x01,0x00,0x06,0x00,0x10,0x04,
-       0x06,0x00,0x01,0x00,0xd1,0x08,0x10,0x04,0x01,0x00,0x06,0x00,0x10,0x04,0x06,0x00,
-       0x09,0x00,0xd3,0x3a,0xd2,0x24,0xd1,0x12,0x10,0x09,0x01,0xff,0xd0,0x90,0xcc,0x86,
-       0x00,0x01,0xff,0xd0,0xb0,0xcc,0x86,0x00,0x10,0x09,0x01,0xff,0xd0,0x90,0xcc,0x88,
-       0x00,0x01,0xff,0xd0,0xb0,0xcc,0x88,0x00,0x51,0x04,0x01,0x00,0x10,0x09,0x01,0xff,
-       0xd0,0x95,0xcc,0x86,0x00,0x01,0xff,0xd0,0xb5,0xcc,0x86,0x00,0xd2,0x16,0x51,0x04,
-       0x01,0x00,0x10,0x09,0x01,0xff,0xd3,0x98,0xcc,0x88,0x00,0x01,0xff,0xd3,0x99,0xcc,
-       0x88,0x00,0xd1,0x12,0x10,0x09,0x01,0xff,0xd0,0x96,0xcc,0x88,0x00,0x01,0xff,0xd0,
-       0xb6,0xcc,0x88,0x00,0x10,0x09,0x01,0xff,0xd0,0x97,0xcc,0x88,0x00,0x01,0xff,0xd0,
-       0xb7,0xcc,0x88,0x00,0xd4,0x74,0xd3,0x3a,0xd2,0x16,0x51,0x04,0x01,0x00,0x10,0x09,
-       0x01,0xff,0xd0,0x98,0xcc,0x84,0x00,0x01,0xff,0xd0,0xb8,0xcc,0x84,0x00,0xd1,0x12,
-       0x10,0x09,0x01,0xff,0xd0,0x98,0xcc,0x88,0x00,0x01,0xff,0xd0,0xb8,0xcc,0x88,0x00,
-       0x10,0x09,0x01,0xff,0xd0,0x9e,0xcc,0x88,0x00,0x01,0xff,0xd0,0xbe,0xcc,0x88,0x00,
-       0xd2,0x16,0x51,0x04,0x01,0x00,0x10,0x09,0x01,0xff,0xd3,0xa8,0xcc,0x88,0x00,0x01,
-       0xff,0xd3,0xa9,0xcc,0x88,0x00,0xd1,0x12,0x10,0x09,0x04,0xff,0xd0,0xad,0xcc,0x88,
-       0x00,0x04,0xff,0xd1,0x8d,0xcc,0x88,0x00,0x10,0x09,0x01,0xff,0xd0,0xa3,0xcc,0x84,
-       0x00,0x01,0xff,0xd1,0x83,0xcc,0x84,0x00,0xd3,0x3a,0xd2,0x24,0xd1,0x12,0x10,0x09,
-       0x01,0xff,0xd0,0xa3,0xcc,0x88,0x00,0x01,0xff,0xd1,0x83,0xcc,0x88,0x00,0x10,0x09,
-       0x01,0xff,0xd0,0xa3,0xcc,0x8b,0x00,0x01,0xff,0xd1,0x83,0xcc,0x8b,0x00,0x91,0x12,
-       0x10,0x09,0x01,0xff,0xd0,0xa7,0xcc,0x88,0x00,0x01,0xff,0xd1,0x87,0xcc,0x88,0x00,
-       0x08,0x00,0x92,0x16,0x91,0x12,0x10,0x09,0x01,0xff,0xd0,0xab,0xcc,0x88,0x00,0x01,
-       0xff,0xd1,0x8b,0xcc,0x88,0x00,0x09,0x00,0x09,0x00,0xd1,0x74,0xd0,0x36,0xcf,0x86,
-       0xd5,0x10,0x54,0x04,0x06,0x00,0x93,0x08,0x12,0x04,0x09,0x00,0x0a,0x00,0x0a,0x00,
-       0xd4,0x10,0x93,0x0c,0x52,0x04,0x0a,0x00,0x11,0x04,0x0b,0x00,0x0c,0x00,0x10,0x00,
-       0x93,0x10,0x92,0x0c,0x91,0x08,0x10,0x04,0x00,0x00,0x01,0x00,0x01,0x00,0x01,0x00,
-       0x01,0x00,0xcf,0x86,0xd5,0x24,0x54,0x04,0x01,0x00,0xd3,0x10,0x52,0x04,0x01,0x00,
-       0x51,0x04,0x01,0x00,0x10,0x04,0x01,0x00,0x00,0x00,0x92,0x0c,0x91,0x08,0x10,0x04,
-       0x00,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x94,0x14,0x93,0x10,0x92,0x0c,0x91,0x08,
-       0x10,0x04,0x14,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0xd0,0xba,
-       0xcf,0x86,0xd5,0x4c,0xd4,0x24,0x53,0x04,0x01,0x00,0xd2,0x10,0xd1,0x08,0x10,0x04,
-       0x14,0x00,0x01,0x00,0x10,0x04,0x04,0x00,0x00,0x00,0xd1,0x08,0x10,0x04,0x00,0x00,
-       0x10,0x00,0x10,0x04,0x10,0x00,0x0d,0x00,0xd3,0x18,0xd2,0x0c,0x91,0x08,0x10,0x04,
-       0x00,0x00,0x02,0xdc,0x02,0xe6,0x51,0x04,0x02,0xe6,0x10,0x04,0x02,0xdc,0x02,0xe6,
-       0x92,0x0c,0x51,0x04,0x02,0xe6,0x10,0x04,0x02,0xde,0x02,0xdc,0x02,0xe6,0xd4,0x2c,
-       0xd3,0x10,0x92,0x0c,0x51,0x04,0x02,0xe6,0x10,0x04,0x08,0xdc,0x02,0xdc,0x02,0xdc,
-       0xd2,0x0c,0x51,0x04,0x02,0xe6,0x10,0x04,0x02,0xdc,0x02,0xe6,0xd1,0x08,0x10,0x04,
-       0x02,0xe6,0x02,0xde,0x10,0x04,0x02,0xe4,0x02,0xe6,0xd3,0x20,0xd2,0x10,0xd1,0x08,
-       0x10,0x04,0x01,0x0a,0x01,0x0b,0x10,0x04,0x01,0x0c,0x01,0x0d,0xd1,0x08,0x10,0x04,
-       0x01,0x0e,0x01,0x0f,0x10,0x04,0x01,0x10,0x01,0x11,0xd2,0x10,0xd1,0x08,0x10,0x04,
-       0x01,0x12,0x01,0x13,0x10,0x04,0x09,0x13,0x01,0x14,0xd1,0x08,0x10,0x04,0x01,0x15,
-       0x01,0x16,0x10,0x04,0x01,0x00,0x01,0x17,0xcf,0x86,0xd5,0x28,0x94,0x24,0x93,0x20,
-       0xd2,0x10,0xd1,0x08,0x10,0x04,0x01,0x00,0x01,0x18,0x10,0x04,0x01,0x19,0x01,0x00,
-       0xd1,0x08,0x10,0x04,0x02,0xe6,0x08,0xdc,0x10,0x04,0x08,0x00,0x08,0x12,0x00,0x00,
-       0x01,0x00,0xd4,0x1c,0x53,0x04,0x01,0x00,0xd2,0x0c,0x51,0x04,0x01,0x00,0x10,0x04,
-       0x01,0x00,0x00,0x00,0x51,0x04,0x00,0x00,0x10,0x04,0x00,0x00,0x14,0x00,0x93,0x10,
-       0x52,0x04,0x01,0x00,0x91,0x08,0x10,0x04,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-       0xe2,0xfb,0x01,0xe1,0x2b,0x01,0xd0,0xa8,0xcf,0x86,0xd5,0x55,0xd4,0x28,0xd3,0x10,
-       0x52,0x04,0x07,0x00,0x91,0x08,0x10,0x04,0x0d,0x00,0x10,0x00,0x0a,0x00,0xd2,0x0c,
-       0x51,0x04,0x0a,0x00,0x10,0x04,0x0a,0x00,0x08,0x00,0x91,0x08,0x10,0x04,0x01,0x00,
-       0x07,0x00,0x07,0x00,0xd3,0x0c,0x52,0x04,0x07,0xe6,0x11,0x04,0x07,0xe6,0x0a,0xe6,
-       0xd2,0x10,0xd1,0x08,0x10,0x04,0x0a,0x1e,0x0a,0x1f,0x10,0x04,0x0a,0x20,0x01,0x00,
-       0xd1,0x09,0x10,0x05,0x0f,0xff,0x00,0x00,0x00,0x10,0x04,0x08,0x00,0x01,0x00,0xd4,
-       0x3d,0x93,0x39,0xd2,0x1a,0xd1,0x08,0x10,0x04,0x0c,0x00,0x01,0x00,0x10,0x09,0x01,
-       0xff,0xd8,0xa7,0xd9,0x93,0x00,0x01,0xff,0xd8,0xa7,0xd9,0x94,0x00,0xd1,0x12,0x10,
-       0x09,0x01,0xff,0xd9,0x88,0xd9,0x94,0x00,0x01,0xff,0xd8,0xa7,0xd9,0x95,0x00,0x10,
-       0x09,0x01,0xff,0xd9,0x8a,0xd9,0x94,0x00,0x01,0x00,0x01,0x00,0x53,0x04,0x01,0x00,
-       0x92,0x0c,0x51,0x04,0x01,0x00,0x10,0x04,0x01,0x00,0x0a,0x00,0x0a,0x00,0xcf,0x86,
-       0xd5,0x5c,0xd4,0x20,0x53,0x04,0x01,0x00,0xd2,0x0c,0x51,0x04,0x01,0x00,0x10,0x04,
-       0x01,0x00,0x01,0x1b,0xd1,0x08,0x10,0x04,0x01,0x1c,0x01,0x1d,0x10,0x04,0x01,0x1e,
-       0x01,0x1f,0xd3,0x20,0xd2,0x10,0xd1,0x08,0x10,0x04,0x01,0x20,0x01,0x21,0x10,0x04,
-       0x01,0x22,0x04,0xe6,0xd1,0x08,0x10,0x04,0x04,0xe6,0x04,0xdc,0x10,0x04,0x07,0xdc,
-       0x07,0xe6,0xd2,0x0c,0x91,0x08,0x10,0x04,0x07,0xe6,0x08,0xe6,0x08,0xe6,0xd1,0x08,
-       0x10,0x04,0x08,0xdc,0x08,0xe6,0x10,0x04,0x08,0xe6,0x0c,0xdc,0xd4,0x10,0x53,0x04,
-       0x01,0x00,0x52,0x04,0x01,0x00,0x11,0x04,0x01,0x00,0x06,0x00,0x93,0x10,0x92,0x0c,
-       0x91,0x08,0x10,0x04,0x01,0x23,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0xd0,0x22,
-       0xcf,0x86,0x55,0x04,0x01,0x00,0x54,0x04,0x01,0x00,0x53,0x04,0x01,0x00,0xd2,0x08,
-       0x11,0x04,0x04,0x00,0x01,0x00,0x51,0x04,0x01,0x00,0x10,0x04,0x01,0x00,0x04,0x00,
-       0xcf,0x86,0xd5,0x5b,0xd4,0x2e,0xd3,0x1e,0x92,0x1a,0xd1,0x0d,0x10,0x09,0x01,0xff,
-       0xdb,0x95,0xd9,0x94,0x00,0x01,0x00,0x10,0x09,0x01,0xff,0xdb,0x81,0xd9,0x94,0x00,
+       0x6f,0xcc,0x83,0xcc,0x84,0x00,0x04,0xff,0x6f,0xcc,0x83,0xcc,0x84,0x00,0x10,0x08,
+       0x04,0xff,0x6f,0xcc,0x87,0x00,0x04,0xff,0x6f,0xcc,0x87,0x00,0xd3,0x27,0xe2,0x0b,
+       0x43,0xd1,0x14,0x10,0x0a,0x04,0xff,0x6f,0xcc,0x87,0xcc,0x84,0x00,0x04,0xff,0x6f,
+       0xcc,0x87,0xcc,0x84,0x00,0x10,0x08,0x04,0xff,0x79,0xcc,0x84,0x00,0x04,0xff,0x79,
+       0xcc,0x84,0x00,0xd2,0x13,0x51,0x04,0x08,0x00,0x10,0x08,0x08,0xff,0xe2,0xb1,0xa5,
+       0x00,0x08,0xff,0xc8,0xbc,0x00,0xd1,0x0b,0x10,0x04,0x08,0x00,0x08,0xff,0xc6,0x9a,
+       0x00,0x10,0x08,0x08,0xff,0xe2,0xb1,0xa6,0x00,0x08,0x00,0xcf,0x86,0x95,0x5f,0x94,
+       0x5b,0xd3,0x2f,0xd2,0x16,0xd1,0x0b,0x10,0x04,0x08,0x00,0x08,0xff,0xc9,0x82,0x00,
+       0x10,0x04,0x09,0x00,0x09,0xff,0xc6,0x80,0x00,0xd1,0x0e,0x10,0x07,0x09,0xff,0xca,
+       0x89,0x00,0x09,0xff,0xca,0x8c,0x00,0x10,0x07,0x09,0xff,0xc9,0x87,0x00,0x09,0x00,
+       0xd2,0x16,0xd1,0x0b,0x10,0x07,0x09,0xff,0xc9,0x89,0x00,0x09,0x00,0x10,0x07,0x09,
+       0xff,0xc9,0x8b,0x00,0x09,0x00,0xd1,0x0b,0x10,0x07,0x09,0xff,0xc9,0x8d,0x00,0x09,
+       0x00,0x10,0x07,0x09,0xff,0xc9,0x8f,0x00,0x09,0x00,0x01,0x00,0x01,0x00,0xd1,0x8b,
+       0xd0,0x0c,0xcf,0x86,0xe5,0xfa,0x42,0x64,0xd9,0x42,0x01,0xe6,0xcf,0x86,0xd5,0x2a,
+       0xe4,0x82,0x43,0xe3,0x69,0x43,0xd2,0x11,0xe1,0x48,0x43,0x10,0x07,0x01,0xff,0xcc,
+       0x80,0x00,0x01,0xff,0xcc,0x81,0x00,0xe1,0x4f,0x43,0x10,0x09,0x01,0xff,0xcc,0x88,
+       0xcc,0x81,0x00,0x01,0xff,0xce,0xb9,0x00,0xd4,0x0f,0x93,0x0b,0x92,0x07,0x61,0x94,
+       0x43,0x01,0xea,0x06,0xe6,0x06,0xe6,0xd3,0x2c,0xd2,0x16,0xd1,0x0b,0x10,0x07,0x0a,
+       0xff,0xcd,0xb1,0x00,0x0a,0x00,0x10,0x07,0x0a,0xff,0xcd,0xb3,0x00,0x0a,0x00,0xd1,
+       0x0b,0x10,0x07,0x01,0xff,0xca,0xb9,0x00,0x01,0x00,0x10,0x07,0x0a,0xff,0xcd,0xb7,
+       0x00,0x0a,0x00,0xd2,0x07,0x61,0x80,0x43,0x00,0x00,0x51,0x04,0x09,0x00,0x10,0x06,
+       0x01,0xff,0x3b,0x00,0x10,0xff,0xcf,0xb3,0x00,0xe0,0x31,0x01,0xcf,0x86,0xd5,0xd3,
+       0xd4,0x5f,0xd3,0x21,0x52,0x04,0x00,0x00,0xd1,0x0d,0x10,0x04,0x01,0x00,0x01,0xff,
+       0xc2,0xa8,0xcc,0x81,0x00,0x10,0x09,0x01,0xff,0xce,0xb1,0xcc,0x81,0x00,0x01,0xff,
+       0xc2,0xb7,0x00,0xd2,0x1f,0xd1,0x12,0x10,0x09,0x01,0xff,0xce,0xb5,0xcc,0x81,0x00,
+       0x01,0xff,0xce,0xb7,0xcc,0x81,0x00,0x10,0x09,0x01,0xff,0xce,0xb9,0xcc,0x81,0x00,
+       0x00,0x00,0xd1,0x0d,0x10,0x09,0x01,0xff,0xce,0xbf,0xcc,0x81,0x00,0x00,0x00,0x10,
+       0x09,0x01,0xff,0xcf,0x85,0xcc,0x81,0x00,0x01,0xff,0xcf,0x89,0xcc,0x81,0x00,0xd3,
+       0x3c,0xd2,0x20,0xd1,0x12,0x10,0x0b,0x01,0xff,0xce,0xb9,0xcc,0x88,0xcc,0x81,0x00,
+       0x01,0xff,0xce,0xb1,0x00,0x10,0x07,0x01,0xff,0xce,0xb2,0x00,0x01,0xff,0xce,0xb3,
+       0x00,0xd1,0x0e,0x10,0x07,0x01,0xff,0xce,0xb4,0x00,0x01,0xff,0xce,0xb5,0x00,0x10,
+       0x07,0x01,0xff,0xce,0xb6,0x00,0x01,0xff,0xce,0xb7,0x00,0xd2,0x1c,0xd1,0x0e,0x10,
+       0x07,0x01,0xff,0xce,0xb8,0x00,0x01,0xff,0xce,0xb9,0x00,0x10,0x07,0x01,0xff,0xce,
+       0xba,0x00,0x01,0xff,0xce,0xbb,0x00,0xd1,0x0e,0x10,0x07,0x01,0xff,0xce,0xbc,0x00,
+       0x01,0xff,0xce,0xbd,0x00,0x10,0x07,0x01,0xff,0xce,0xbe,0x00,0x01,0xff,0xce,0xbf,
+       0x00,0xe4,0x6e,0x43,0xd3,0x35,0xd2,0x19,0xd1,0x0e,0x10,0x07,0x01,0xff,0xcf,0x80,
+       0x00,0x01,0xff,0xcf,0x81,0x00,0x10,0x04,0x00,0x00,0x01,0xff,0xcf,0x83,0x00,0xd1,
+       0x0e,0x10,0x07,0x01,0xff,0xcf,0x84,0x00,0x01,0xff,0xcf,0x85,0x00,0x10,0x07,0x01,
+       0xff,0xcf,0x86,0x00,0x01,0xff,0xcf,0x87,0x00,0xe2,0x14,0x43,0xd1,0x0e,0x10,0x07,
+       0x01,0xff,0xcf,0x88,0x00,0x01,0xff,0xcf,0x89,0x00,0x10,0x09,0x01,0xff,0xce,0xb9,
+       0xcc,0x88,0x00,0x01,0xff,0xcf,0x85,0xcc,0x88,0x00,0xcf,0x86,0xd5,0x94,0xd4,0x3c,
+       0xd3,0x13,0x92,0x0f,0x51,0x04,0x01,0x00,0x10,0x07,0x01,0xff,0xcf,0x83,0x00,0x01,
+       0x00,0x01,0x00,0xd2,0x07,0x61,0x23,0x43,0x01,0x00,0xd1,0x12,0x10,0x09,0x01,0xff,
+       0xce,0xbf,0xcc,0x81,0x00,0x01,0xff,0xcf,0x85,0xcc,0x81,0x00,0x10,0x09,0x01,0xff,
+       0xcf,0x89,0xcc,0x81,0x00,0x0a,0xff,0xcf,0x97,0x00,0xd3,0x2c,0xd2,0x11,0xe1,0x2f,
+       0x43,0x10,0x07,0x01,0xff,0xce,0xb2,0x00,0x01,0xff,0xce,0xb8,0x00,0xd1,0x10,0x10,
+       0x09,0x01,0xff,0xcf,0x92,0xcc,0x88,0x00,0x01,0xff,0xcf,0x86,0x00,0x10,0x07,0x01,
+       0xff,0xcf,0x80,0x00,0x04,0x00,0xd2,0x16,0xd1,0x0b,0x10,0x07,0x06,0xff,0xcf,0x99,
+       0x00,0x06,0x00,0x10,0x07,0x01,0xff,0xcf,0x9b,0x00,0x04,0x00,0xd1,0x0b,0x10,0x07,
+       0x01,0xff,0xcf,0x9d,0x00,0x04,0x00,0x10,0x07,0x01,0xff,0xcf,0x9f,0x00,0x04,0x00,
+       0xd4,0x58,0xd3,0x2c,0xd2,0x16,0xd1,0x0b,0x10,0x07,0x01,0xff,0xcf,0xa1,0x00,0x04,
+       0x00,0x10,0x07,0x01,0xff,0xcf,0xa3,0x00,0x01,0x00,0xd1,0x0b,0x10,0x07,0x01,0xff,
+       0xcf,0xa5,0x00,0x01,0x00,0x10,0x07,0x01,0xff,0xcf,0xa7,0x00,0x01,0x00,0xd2,0x16,
+       0xd1,0x0b,0x10,0x07,0x01,0xff,0xcf,0xa9,0x00,0x01,0x00,0x10,0x07,0x01,0xff,0xcf,
+       0xab,0x00,0x01,0x00,0xd1,0x0b,0x10,0x07,0x01,0xff,0xcf,0xad,0x00,0x01,0x00,0x10,
+       0x07,0x01,0xff,0xcf,0xaf,0x00,0x01,0x00,0xd3,0x2b,0xd2,0x12,0x91,0x0e,0x10,0x07,
+       0x01,0xff,0xce,0xba,0x00,0x01,0xff,0xcf,0x81,0x00,0x01,0x00,0xd1,0x0e,0x10,0x07,
+       0x05,0xff,0xce,0xb8,0x00,0x05,0xff,0xce,0xb5,0x00,0x10,0x04,0x06,0x00,0x07,0xff,
+       0xcf,0xb8,0x00,0xd2,0x16,0xd1,0x0b,0x10,0x04,0x07,0x00,0x07,0xff,0xcf,0xb2,0x00,
+       0x10,0x07,0x07,0xff,0xcf,0xbb,0x00,0x07,0x00,0xd1,0x0b,0x10,0x04,0x08,0x00,0x08,
+       0xff,0xcd,0xbb,0x00,0x10,0x07,0x08,0xff,0xcd,0xbc,0x00,0x08,0xff,0xcd,0xbd,0x00,
+       0xe3,0xd6,0x46,0xe2,0x3d,0x05,0xe1,0x27,0x02,0xe0,0x66,0x01,0xcf,0x86,0xd5,0xf0,
+       0xd4,0x7e,0xd3,0x40,0xd2,0x22,0xd1,0x12,0x10,0x09,0x04,0xff,0xd0,0xb5,0xcc,0x80,
+       0x00,0x01,0xff,0xd0,0xb5,0xcc,0x88,0x00,0x10,0x07,0x01,0xff,0xd1,0x92,0x00,0x01,
+       0xff,0xd0,0xb3,0xcc,0x81,0x00,0xd1,0x0e,0x10,0x07,0x01,0xff,0xd1,0x94,0x00,0x01,
+       0xff,0xd1,0x95,0x00,0x10,0x07,0x01,0xff,0xd1,0x96,0x00,0x01,0xff,0xd1,0x96,0xcc,
+       0x88,0x00,0xd2,0x1c,0xd1,0x0e,0x10,0x07,0x01,0xff,0xd1,0x98,0x00,0x01,0xff,0xd1,
+       0x99,0x00,0x10,0x07,0x01,0xff,0xd1,0x9a,0x00,0x01,0xff,0xd1,0x9b,0x00,0xd1,0x12,
+       0x10,0x09,0x01,0xff,0xd0,0xba,0xcc,0x81,0x00,0x04,0xff,0xd0,0xb8,0xcc,0x80,0x00,
+       0x10,0x09,0x01,0xff,0xd1,0x83,0xcc,0x86,0x00,0x01,0xff,0xd1,0x9f,0x00,0xd3,0x38,
+       0xd2,0x1c,0xd1,0x0e,0x10,0x07,0x01,0xff,0xd0,0xb0,0x00,0x01,0xff,0xd0,0xb1,0x00,
+       0x10,0x07,0x01,0xff,0xd0,0xb2,0x00,0x01,0xff,0xd0,0xb3,0x00,0xd1,0x0e,0x10,0x07,
+       0x01,0xff,0xd0,0xb4,0x00,0x01,0xff,0xd0,0xb5,0x00,0x10,0x07,0x01,0xff,0xd0,0xb6,
+       0x00,0x01,0xff,0xd0,0xb7,0x00,0xd2,0x1e,0xd1,0x10,0x10,0x07,0x01,0xff,0xd0,0xb8,
+       0x00,0x01,0xff,0xd0,0xb8,0xcc,0x86,0x00,0x10,0x07,0x01,0xff,0xd0,0xba,0x00,0x01,
+       0xff,0xd0,0xbb,0x00,0xd1,0x0e,0x10,0x07,0x01,0xff,0xd0,0xbc,0x00,0x01,0xff,0xd0,
+       0xbd,0x00,0x10,0x07,0x01,0xff,0xd0,0xbe,0x00,0x01,0xff,0xd0,0xbf,0x00,0xe4,0x0e,
+       0x42,0xd3,0x38,0xd2,0x1c,0xd1,0x0e,0x10,0x07,0x01,0xff,0xd1,0x80,0x00,0x01,0xff,
+       0xd1,0x81,0x00,0x10,0x07,0x01,0xff,0xd1,0x82,0x00,0x01,0xff,0xd1,0x83,0x00,0xd1,
+       0x0e,0x10,0x07,0x01,0xff,0xd1,0x84,0x00,0x01,0xff,0xd1,0x85,0x00,0x10,0x07,0x01,
+       0xff,0xd1,0x86,0x00,0x01,0xff,0xd1,0x87,0x00,0xd2,0x1c,0xd1,0x0e,0x10,0x07,0x01,
+       0xff,0xd1,0x88,0x00,0x01,0xff,0xd1,0x89,0x00,0x10,0x07,0x01,0xff,0xd1,0x8a,0x00,
+       0x01,0xff,0xd1,0x8b,0x00,0xd1,0x0e,0x10,0x07,0x01,0xff,0xd1,0x8c,0x00,0x01,0xff,
+       0xd1,0x8d,0x00,0x10,0x07,0x01,0xff,0xd1,0x8e,0x00,0x01,0xff,0xd1,0x8f,0x00,0xcf,
+       0x86,0xd5,0x07,0x64,0xb8,0x41,0x01,0x00,0xd4,0x58,0xd3,0x2c,0xd2,0x16,0xd1,0x0b,
+       0x10,0x07,0x01,0xff,0xd1,0xa1,0x00,0x01,0x00,0x10,0x07,0x01,0xff,0xd1,0xa3,0x00,
+       0x01,0x00,0xd1,0x0b,0x10,0x07,0x01,0xff,0xd1,0xa5,0x00,0x01,0x00,0x10,0x07,0x01,
+       0xff,0xd1,0xa7,0x00,0x01,0x00,0xd2,0x16,0xd1,0x0b,0x10,0x07,0x01,0xff,0xd1,0xa9,
+       0x00,0x01,0x00,0x10,0x07,0x01,0xff,0xd1,0xab,0x00,0x01,0x00,0xd1,0x0b,0x10,0x07,
+       0x01,0xff,0xd1,0xad,0x00,0x01,0x00,0x10,0x07,0x01,0xff,0xd1,0xaf,0x00,0x01,0x00,
+       0xd3,0x33,0xd2,0x16,0xd1,0x0b,0x10,0x07,0x01,0xff,0xd1,0xb1,0x00,0x01,0x00,0x10,
+       0x07,0x01,0xff,0xd1,0xb3,0x00,0x01,0x00,0xd1,0x0b,0x10,0x07,0x01,0xff,0xd1,0xb5,
+       0x00,0x01,0x00,0x10,0x09,0x01,0xff,0xd1,0xb5,0xcc,0x8f,0x00,0x01,0xff,0xd1,0xb5,
+       0xcc,0x8f,0x00,0xd2,0x16,0xd1,0x0b,0x10,0x07,0x01,0xff,0xd1,0xb9,0x00,0x01,0x00,
+       0x10,0x07,0x01,0xff,0xd1,0xbb,0x00,0x01,0x00,0xd1,0x0b,0x10,0x07,0x01,0xff,0xd1,
+       0xbd,0x00,0x01,0x00,0x10,0x07,0x01,0xff,0xd1,0xbf,0x00,0x01,0x00,0xe0,0x41,0x01,
+       0xcf,0x86,0xd5,0x8e,0xd4,0x36,0xd3,0x11,0xe2,0x7a,0x41,0xe1,0x71,0x41,0x10,0x07,
+       0x01,0xff,0xd2,0x81,0x00,0x01,0x00,0xd2,0x0f,0x51,0x04,0x04,0x00,0x10,0x07,0x06,
+       0xff,0xd2,0x8b,0x00,0x06,0x00,0xd1,0x0b,0x10,0x07,0x04,0xff,0xd2,0x8d,0x00,0x04,
+       0x00,0x10,0x07,0x04,0xff,0xd2,0x8f,0x00,0x04,0x00,0xd3,0x2c,0xd2,0x16,0xd1,0x0b,
+       0x10,0x07,0x01,0xff,0xd2,0x91,0x00,0x01,0x00,0x10,0x07,0x01,0xff,0xd2,0x93,0x00,
+       0x01,0x00,0xd1,0x0b,0x10,0x07,0x01,0xff,0xd2,0x95,0x00,0x01,0x00,0x10,0x07,0x01,
+       0xff,0xd2,0x97,0x00,0x01,0x00,0xd2,0x16,0xd1,0x0b,0x10,0x07,0x01,0xff,0xd2,0x99,
+       0x00,0x01,0x00,0x10,0x07,0x01,0xff,0xd2,0x9b,0x00,0x01,0x00,0xd1,0x0b,0x10,0x07,
+       0x01,0xff,0xd2,0x9d,0x00,0x01,0x00,0x10,0x07,0x01,0xff,0xd2,0x9f,0x00,0x01,0x00,
+       0xd4,0x58,0xd3,0x2c,0xd2,0x16,0xd1,0x0b,0x10,0x07,0x01,0xff,0xd2,0xa1,0x00,0x01,
+       0x00,0x10,0x07,0x01,0xff,0xd2,0xa3,0x00,0x01,0x00,0xd1,0x0b,0x10,0x07,0x01,0xff,
+       0xd2,0xa5,0x00,0x01,0x00,0x10,0x07,0x01,0xff,0xd2,0xa7,0x00,0x01,0x00,0xd2,0x16,
+       0xd1,0x0b,0x10,0x07,0x01,0xff,0xd2,0xa9,0x00,0x01,0x00,0x10,0x07,0x01,0xff,0xd2,
+       0xab,0x00,0x01,0x00,0xd1,0x0b,0x10,0x07,0x01,0xff,0xd2,0xad,0x00,0x01,0x00,0x10,
+       0x07,0x01,0xff,0xd2,0xaf,0x00,0x01,0x00,0xd3,0x2c,0xd2,0x16,0xd1,0x0b,0x10,0x07,
+       0x01,0xff,0xd2,0xb1,0x00,0x01,0x00,0x10,0x07,0x01,0xff,0xd2,0xb3,0x00,0x01,0x00,
+       0xd1,0x0b,0x10,0x07,0x01,0xff,0xd2,0xb5,0x00,0x01,0x00,0x10,0x07,0x01,0xff,0xd2,
+       0xb7,0x00,0x01,0x00,0xd2,0x16,0xd1,0x0b,0x10,0x07,0x01,0xff,0xd2,0xb9,0x00,0x01,
+       0x00,0x10,0x07,0x01,0xff,0xd2,0xbb,0x00,0x01,0x00,0xd1,0x0b,0x10,0x07,0x01,0xff,
+       0xd2,0xbd,0x00,0x01,0x00,0x10,0x07,0x01,0xff,0xd2,0xbf,0x00,0x01,0x00,0xcf,0x86,
+       0xd5,0xdc,0xd4,0x5a,0xd3,0x36,0xd2,0x20,0xd1,0x10,0x10,0x07,0x01,0xff,0xd3,0x8f,
+       0x00,0x01,0xff,0xd0,0xb6,0xcc,0x86,0x00,0x10,0x09,0x01,0xff,0xd0,0xb6,0xcc,0x86,
+       0x00,0x01,0xff,0xd3,0x84,0x00,0xd1,0x0b,0x10,0x04,0x01,0x00,0x06,0xff,0xd3,0x86,
+       0x00,0x10,0x04,0x06,0x00,0x01,0xff,0xd3,0x88,0x00,0xd2,0x16,0xd1,0x0b,0x10,0x04,
+       0x01,0x00,0x06,0xff,0xd3,0x8a,0x00,0x10,0x04,0x06,0x00,0x01,0xff,0xd3,0x8c,0x00,
+       0xe1,0x52,0x40,0x10,0x04,0x01,0x00,0x06,0xff,0xd3,0x8e,0x00,0xd3,0x41,0xd2,0x24,
+       0xd1,0x12,0x10,0x09,0x01,0xff,0xd0,0xb0,0xcc,0x86,0x00,0x01,0xff,0xd0,0xb0,0xcc,
+       0x86,0x00,0x10,0x09,0x01,0xff,0xd0,0xb0,0xcc,0x88,0x00,0x01,0xff,0xd0,0xb0,0xcc,
+       0x88,0x00,0xd1,0x0b,0x10,0x07,0x01,0xff,0xd3,0x95,0x00,0x01,0x00,0x10,0x09,0x01,
+       0xff,0xd0,0xb5,0xcc,0x86,0x00,0x01,0xff,0xd0,0xb5,0xcc,0x86,0x00,0xd2,0x1d,0xd1,
+       0x0b,0x10,0x07,0x01,0xff,0xd3,0x99,0x00,0x01,0x00,0x10,0x09,0x01,0xff,0xd3,0x99,
+       0xcc,0x88,0x00,0x01,0xff,0xd3,0x99,0xcc,0x88,0x00,0xd1,0x12,0x10,0x09,0x01,0xff,
+       0xd0,0xb6,0xcc,0x88,0x00,0x01,0xff,0xd0,0xb6,0xcc,0x88,0x00,0x10,0x09,0x01,0xff,
+       0xd0,0xb7,0xcc,0x88,0x00,0x01,0xff,0xd0,0xb7,0xcc,0x88,0x00,0xd4,0x82,0xd3,0x41,
+       0xd2,0x1d,0xd1,0x0b,0x10,0x07,0x01,0xff,0xd3,0xa1,0x00,0x01,0x00,0x10,0x09,0x01,
+       0xff,0xd0,0xb8,0xcc,0x84,0x00,0x01,0xff,0xd0,0xb8,0xcc,0x84,0x00,0xd1,0x12,0x10,
+       0x09,0x01,0xff,0xd0,0xb8,0xcc,0x88,0x00,0x01,0xff,0xd0,0xb8,0xcc,0x88,0x00,0x10,
+       0x09,0x01,0xff,0xd0,0xbe,0xcc,0x88,0x00,0x01,0xff,0xd0,0xbe,0xcc,0x88,0x00,0xd2,
+       0x1d,0xd1,0x0b,0x10,0x07,0x01,0xff,0xd3,0xa9,0x00,0x01,0x00,0x10,0x09,0x01,0xff,
+       0xd3,0xa9,0xcc,0x88,0x00,0x01,0xff,0xd3,0xa9,0xcc,0x88,0x00,0xd1,0x12,0x10,0x09,
+       0x04,0xff,0xd1,0x8d,0xcc,0x88,0x00,0x04,0xff,0xd1,0x8d,0xcc,0x88,0x00,0x10,0x09,
+       0x01,0xff,0xd1,0x83,0xcc,0x84,0x00,0x01,0xff,0xd1,0x83,0xcc,0x84,0x00,0xd3,0x41,
+       0xd2,0x24,0xd1,0x12,0x10,0x09,0x01,0xff,0xd1,0x83,0xcc,0x88,0x00,0x01,0xff,0xd1,
+       0x83,0xcc,0x88,0x00,0x10,0x09,0x01,0xff,0xd1,0x83,0xcc,0x8b,0x00,0x01,0xff,0xd1,
+       0x83,0xcc,0x8b,0x00,0xd1,0x12,0x10,0x09,0x01,0xff,0xd1,0x87,0xcc,0x88,0x00,0x01,
+       0xff,0xd1,0x87,0xcc,0x88,0x00,0x10,0x07,0x08,0xff,0xd3,0xb7,0x00,0x08,0x00,0xd2,
+       0x1d,0xd1,0x12,0x10,0x09,0x01,0xff,0xd1,0x8b,0xcc,0x88,0x00,0x01,0xff,0xd1,0x8b,
+       0xcc,0x88,0x00,0x10,0x07,0x09,0xff,0xd3,0xbb,0x00,0x09,0x00,0xd1,0x0b,0x10,0x07,
+       0x09,0xff,0xd3,0xbd,0x00,0x09,0x00,0x10,0x07,0x09,0xff,0xd3,0xbf,0x00,0x09,0x00,
+       0xe1,0x26,0x02,0xe0,0x78,0x01,0xcf,0x86,0xd5,0xb0,0xd4,0x58,0xd3,0x2c,0xd2,0x16,
+       0xd1,0x0b,0x10,0x07,0x06,0xff,0xd4,0x81,0x00,0x06,0x00,0x10,0x07,0x06,0xff,0xd4,
+       0x83,0x00,0x06,0x00,0xd1,0x0b,0x10,0x07,0x06,0xff,0xd4,0x85,0x00,0x06,0x00,0x10,
+       0x07,0x06,0xff,0xd4,0x87,0x00,0x06,0x00,0xd2,0x16,0xd1,0x0b,0x10,0x07,0x06,0xff,
+       0xd4,0x89,0x00,0x06,0x00,0x10,0x07,0x06,0xff,0xd4,0x8b,0x00,0x06,0x00,0xd1,0x0b,
+       0x10,0x07,0x06,0xff,0xd4,0x8d,0x00,0x06,0x00,0x10,0x07,0x06,0xff,0xd4,0x8f,0x00,
+       0x06,0x00,0xd3,0x2c,0xd2,0x16,0xd1,0x0b,0x10,0x07,0x09,0xff,0xd4,0x91,0x00,0x09,
+       0x00,0x10,0x07,0x09,0xff,0xd4,0x93,0x00,0x09,0x00,0xd1,0x0b,0x10,0x07,0x0a,0xff,
+       0xd4,0x95,0x00,0x0a,0x00,0x10,0x07,0x0a,0xff,0xd4,0x97,0x00,0x0a,0x00,0xd2,0x16,
+       0xd1,0x0b,0x10,0x07,0x0a,0xff,0xd4,0x99,0x00,0x0a,0x00,0x10,0x07,0x0a,0xff,0xd4,
+       0x9b,0x00,0x0a,0x00,0xd1,0x0b,0x10,0x07,0x0a,0xff,0xd4,0x9d,0x00,0x0a,0x00,0x10,
+       0x07,0x0a,0xff,0xd4,0x9f,0x00,0x0a,0x00,0xd4,0x58,0xd3,0x2c,0xd2,0x16,0xd1,0x0b,
+       0x10,0x07,0x0a,0xff,0xd4,0xa1,0x00,0x0a,0x00,0x10,0x07,0x0a,0xff,0xd4,0xa3,0x00,
+       0x0a,0x00,0xd1,0x0b,0x10,0x07,0x0b,0xff,0xd4,0xa5,0x00,0x0b,0x00,0x10,0x07,0x0c,
+       0xff,0xd4,0xa7,0x00,0x0c,0x00,0xd2,0x16,0xd1,0x0b,0x10,0x07,0x10,0xff,0xd4,0xa9,
+       0x00,0x10,0x00,0x10,0x07,0x10,0xff,0xd4,0xab,0x00,0x10,0x00,0xd1,0x0b,0x10,0x07,
+       0x10,0xff,0xd4,0xad,0x00,0x10,0x00,0x10,0x07,0x10,0xff,0xd4,0xaf,0x00,0x10,0x00,
+       0xd3,0x35,0xd2,0x19,0xd1,0x0b,0x10,0x04,0x00,0x00,0x01,0xff,0xd5,0xa1,0x00,0x10,
+       0x07,0x01,0xff,0xd5,0xa2,0x00,0x01,0xff,0xd5,0xa3,0x00,0xd1,0x0e,0x10,0x07,0x01,
+       0xff,0xd5,0xa4,0x00,0x01,0xff,0xd5,0xa5,0x00,0x10,0x07,0x01,0xff,0xd5,0xa6,0x00,
+       0x01,0xff,0xd5,0xa7,0x00,0xd2,0x1c,0xd1,0x0e,0x10,0x07,0x01,0xff,0xd5,0xa8,0x00,
+       0x01,0xff,0xd5,0xa9,0x00,0x10,0x07,0x01,0xff,0xd5,0xaa,0x00,0x01,0xff,0xd5,0xab,
+       0x00,0xd1,0x0e,0x10,0x07,0x01,0xff,0xd5,0xac,0x00,0x01,0xff,0xd5,0xad,0x00,0x10,
+       0x07,0x01,0xff,0xd5,0xae,0x00,0x01,0xff,0xd5,0xaf,0x00,0xcf,0x86,0xe5,0xf1,0x3e,
+       0xd4,0x70,0xd3,0x38,0xd2,0x1c,0xd1,0x0e,0x10,0x07,0x01,0xff,0xd5,0xb0,0x00,0x01,
+       0xff,0xd5,0xb1,0x00,0x10,0x07,0x01,0xff,0xd5,0xb2,0x00,0x01,0xff,0xd5,0xb3,0x00,
+       0xd1,0x0e,0x10,0x07,0x01,0xff,0xd5,0xb4,0x00,0x01,0xff,0xd5,0xb5,0x00,0x10,0x07,
+       0x01,0xff,0xd5,0xb6,0x00,0x01,0xff,0xd5,0xb7,0x00,0xd2,0x1c,0xd1,0x0e,0x10,0x07,
+       0x01,0xff,0xd5,0xb8,0x00,0x01,0xff,0xd5,0xb9,0x00,0x10,0x07,0x01,0xff,0xd5,0xba,
+       0x00,0x01,0xff,0xd5,0xbb,0x00,0xd1,0x0e,0x10,0x07,0x01,0xff,0xd5,0xbc,0x00,0x01,
+       0xff,0xd5,0xbd,0x00,0x10,0x07,0x01,0xff,0xd5,0xbe,0x00,0x01,0xff,0xd5,0xbf,0x00,
+       0xe3,0x70,0x3e,0xd2,0x1c,0xd1,0x0e,0x10,0x07,0x01,0xff,0xd6,0x80,0x00,0x01,0xff,
+       0xd6,0x81,0x00,0x10,0x07,0x01,0xff,0xd6,0x82,0x00,0x01,0xff,0xd6,0x83,0x00,0xd1,
+       0x0e,0x10,0x07,0x01,0xff,0xd6,0x84,0x00,0x01,0xff,0xd6,0x85,0x00,0x10,0x07,0x01,
+       0xff,0xd6,0x86,0x00,0x00,0x00,0xe0,0x18,0x3f,0xcf,0x86,0xe5,0xa9,0x3e,0xe4,0x80,
+       0x3e,0xe3,0x5f,0x3e,0x52,0x04,0x01,0x00,0x51,0x04,0x01,0x00,0x10,0x04,0x01,0x00,
+       0x01,0xff,0xd5,0xa5,0xd6,0x82,0x00,0xe4,0x3e,0x25,0xe3,0xc4,0x1a,0xe2,0xf8,0x80,
+       0xe1,0xc0,0x13,0xd0,0x1e,0xcf,0x86,0xc5,0xe4,0xf0,0x4a,0xe3,0x3b,0x46,0xe2,0xd1,
+       0x43,0xe1,0x04,0x43,0xe0,0xc9,0x42,0xcf,0x86,0xe5,0x8e,0x42,0x64,0x71,0x42,0x0b,
+       0x00,0xcf,0x86,0xe5,0xfa,0x01,0xe4,0xd5,0x55,0xe3,0x76,0x01,0xe2,0x76,0x53,0xd1,
+       0x0c,0xe0,0xd7,0x52,0xcf,0x86,0x65,0x75,0x52,0x04,0x00,0xe0,0x0d,0x01,0xcf,0x86,
+       0xd5,0x0a,0xe4,0xf8,0x52,0x63,0xe7,0x52,0x0a,0x00,0xd4,0x80,0xd3,0x40,0xd2,0x20,
+       0xd1,0x10,0x10,0x08,0x01,0xff,0xe2,0xb4,0x80,0x00,0x01,0xff,0xe2,0xb4,0x81,0x00,
+       0x10,0x08,0x01,0xff,0xe2,0xb4,0x82,0x00,0x01,0xff,0xe2,0xb4,0x83,0x00,0xd1,0x10,
+       0x10,0x08,0x01,0xff,0xe2,0xb4,0x84,0x00,0x01,0xff,0xe2,0xb4,0x85,0x00,0x10,0x08,
+       0x01,0xff,0xe2,0xb4,0x86,0x00,0x01,0xff,0xe2,0xb4,0x87,0x00,0xd2,0x20,0xd1,0x10,
+       0x10,0x08,0x01,0xff,0xe2,0xb4,0x88,0x00,0x01,0xff,0xe2,0xb4,0x89,0x00,0x10,0x08,
+       0x01,0xff,0xe2,0xb4,0x8a,0x00,0x01,0xff,0xe2,0xb4,0x8b,0x00,0xd1,0x10,0x10,0x08,
+       0x01,0xff,0xe2,0xb4,0x8c,0x00,0x01,0xff,0xe2,0xb4,0x8d,0x00,0x10,0x08,0x01,0xff,
+       0xe2,0xb4,0x8e,0x00,0x01,0xff,0xe2,0xb4,0x8f,0x00,0xd3,0x40,0xd2,0x20,0xd1,0x10,
+       0x10,0x08,0x01,0xff,0xe2,0xb4,0x90,0x00,0x01,0xff,0xe2,0xb4,0x91,0x00,0x10,0x08,
+       0x01,0xff,0xe2,0xb4,0x92,0x00,0x01,0xff,0xe2,0xb4,0x93,0x00,0xd1,0x10,0x10,0x08,
+       0x01,0xff,0xe2,0xb4,0x94,0x00,0x01,0xff,0xe2,0xb4,0x95,0x00,0x10,0x08,0x01,0xff,
+       0xe2,0xb4,0x96,0x00,0x01,0xff,0xe2,0xb4,0x97,0x00,0xd2,0x20,0xd1,0x10,0x10,0x08,
+       0x01,0xff,0xe2,0xb4,0x98,0x00,0x01,0xff,0xe2,0xb4,0x99,0x00,0x10,0x08,0x01,0xff,
+       0xe2,0xb4,0x9a,0x00,0x01,0xff,0xe2,0xb4,0x9b,0x00,0xd1,0x10,0x10,0x08,0x01,0xff,
+       0xe2,0xb4,0x9c,0x00,0x01,0xff,0xe2,0xb4,0x9d,0x00,0x10,0x08,0x01,0xff,0xe2,0xb4,
+       0x9e,0x00,0x01,0xff,0xe2,0xb4,0x9f,0x00,0xcf,0x86,0xe5,0x2a,0x52,0x94,0x50,0xd3,
+       0x3c,0xd2,0x20,0xd1,0x10,0x10,0x08,0x01,0xff,0xe2,0xb4,0xa0,0x00,0x01,0xff,0xe2,
+       0xb4,0xa1,0x00,0x10,0x08,0x01,0xff,0xe2,0xb4,0xa2,0x00,0x01,0xff,0xe2,0xb4,0xa3,
+       0x00,0xd1,0x10,0x10,0x08,0x01,0xff,0xe2,0xb4,0xa4,0x00,0x01,0xff,0xe2,0xb4,0xa5,
+       0x00,0x10,0x04,0x00,0x00,0x0d,0xff,0xe2,0xb4,0xa7,0x00,0x52,0x04,0x00,0x00,0x91,
+       0x0c,0x10,0x04,0x00,0x00,0x0d,0xff,0xe2,0xb4,0xad,0x00,0x00,0x00,0x01,0x00,0xd2,
+       0x1b,0xe1,0xce,0x52,0xe0,0x7f,0x52,0xcf,0x86,0x95,0x0f,0x94,0x0b,0x93,0x07,0x62,
+       0x64,0x52,0x04,0x00,0x04,0x00,0x04,0x00,0x04,0x00,0xd1,0x13,0xe0,0xa5,0x53,0xcf,
+       0x86,0x95,0x0a,0xe4,0x7a,0x53,0x63,0x69,0x53,0x04,0x00,0x04,0x00,0xd0,0x0d,0xcf,
+       0x86,0x95,0x07,0x64,0xf4,0x53,0x08,0x00,0x04,0x00,0xcf,0x86,0x55,0x04,0x04,0x00,
+       0x54,0x04,0x04,0x00,0xd3,0x07,0x62,0x01,0x54,0x04,0x00,0xd2,0x20,0xd1,0x10,0x10,
+       0x08,0x11,0xff,0xe1,0x8f,0xb0,0x00,0x11,0xff,0xe1,0x8f,0xb1,0x00,0x10,0x08,0x11,
+       0xff,0xe1,0x8f,0xb2,0x00,0x11,0xff,0xe1,0x8f,0xb3,0x00,0x91,0x10,0x10,0x08,0x11,
+       0xff,0xe1,0x8f,0xb4,0x00,0x11,0xff,0xe1,0x8f,0xb5,0x00,0x00,0x00,0xd4,0x1c,0xe3,
+       0x92,0x56,0xe2,0xc9,0x55,0xe1,0x8c,0x55,0xe0,0x6d,0x55,0xcf,0x86,0x95,0x0a,0xe4,
+       0x56,0x55,0x63,0x45,0x55,0x04,0x00,0x04,0x00,0xe3,0xd2,0x01,0xe2,0xdd,0x59,0xd1,
+       0x0c,0xe0,0xfe,0x58,0xcf,0x86,0x65,0xd7,0x58,0x0a,0x00,0xe0,0x4e,0x59,0xcf,0x86,
+       0xd5,0xc5,0xd4,0x45,0xd3,0x31,0xd2,0x1c,0xd1,0x0e,0x10,0x07,0x12,0xff,0xd0,0xb2,
+       0x00,0x12,0xff,0xd0,0xb4,0x00,0x10,0x07,0x12,0xff,0xd0,0xbe,0x00,0x12,0xff,0xd1,
+       0x81,0x00,0x51,0x07,0x12,0xff,0xd1,0x82,0x00,0x10,0x07,0x12,0xff,0xd1,0x8a,0x00,
+       0x12,0xff,0xd1,0xa3,0x00,0x92,0x10,0x91,0x0c,0x10,0x08,0x12,0xff,0xea,0x99,0x8b,
+       0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xd3,0x40,0xd2,0x20,0xd1,0x10,0x10,0x08,0x14,
+       0xff,0xe1,0x83,0x90,0x00,0x14,0xff,0xe1,0x83,0x91,0x00,0x10,0x08,0x14,0xff,0xe1,
+       0x83,0x92,0x00,0x14,0xff,0xe1,0x83,0x93,0x00,0xd1,0x10,0x10,0x08,0x14,0xff,0xe1,
+       0x83,0x94,0x00,0x14,0xff,0xe1,0x83,0x95,0x00,0x10,0x08,0x14,0xff,0xe1,0x83,0x96,
+       0x00,0x14,0xff,0xe1,0x83,0x97,0x00,0xd2,0x20,0xd1,0x10,0x10,0x08,0x14,0xff,0xe1,
+       0x83,0x98,0x00,0x14,0xff,0xe1,0x83,0x99,0x00,0x10,0x08,0x14,0xff,0xe1,0x83,0x9a,
+       0x00,0x14,0xff,0xe1,0x83,0x9b,0x00,0xd1,0x10,0x10,0x08,0x14,0xff,0xe1,0x83,0x9c,
+       0x00,0x14,0xff,0xe1,0x83,0x9d,0x00,0x10,0x08,0x14,0xff,0xe1,0x83,0x9e,0x00,0x14,
+       0xff,0xe1,0x83,0x9f,0x00,0xd4,0x80,0xd3,0x40,0xd2,0x20,0xd1,0x10,0x10,0x08,0x14,
+       0xff,0xe1,0x83,0xa0,0x00,0x14,0xff,0xe1,0x83,0xa1,0x00,0x10,0x08,0x14,0xff,0xe1,
+       0x83,0xa2,0x00,0x14,0xff,0xe1,0x83,0xa3,0x00,0xd1,0x10,0x10,0x08,0x14,0xff,0xe1,
+       0x83,0xa4,0x00,0x14,0xff,0xe1,0x83,0xa5,0x00,0x10,0x08,0x14,0xff,0xe1,0x83,0xa6,
+       0x00,0x14,0xff,0xe1,0x83,0xa7,0x00,0xd2,0x20,0xd1,0x10,0x10,0x08,0x14,0xff,0xe1,
+       0x83,0xa8,0x00,0x14,0xff,0xe1,0x83,0xa9,0x00,0x10,0x08,0x14,0xff,0xe1,0x83,0xaa,
+       0x00,0x14,0xff,0xe1,0x83,0xab,0x00,0xd1,0x10,0x10,0x08,0x14,0xff,0xe1,0x83,0xac,
+       0x00,0x14,0xff,0xe1,0x83,0xad,0x00,0x10,0x08,0x14,0xff,0xe1,0x83,0xae,0x00,0x14,
+       0xff,0xe1,0x83,0xaf,0x00,0xd3,0x40,0xd2,0x20,0xd1,0x10,0x10,0x08,0x14,0xff,0xe1,
+       0x83,0xb0,0x00,0x14,0xff,0xe1,0x83,0xb1,0x00,0x10,0x08,0x14,0xff,0xe1,0x83,0xb2,
+       0x00,0x14,0xff,0xe1,0x83,0xb3,0x00,0xd1,0x10,0x10,0x08,0x14,0xff,0xe1,0x83,0xb4,
+       0x00,0x14,0xff,0xe1,0x83,0xb5,0x00,0x10,0x08,0x14,0xff,0xe1,0x83,0xb6,0x00,0x14,
+       0xff,0xe1,0x83,0xb7,0x00,0xd2,0x1c,0xd1,0x10,0x10,0x08,0x14,0xff,0xe1,0x83,0xb8,
+       0x00,0x14,0xff,0xe1,0x83,0xb9,0x00,0x10,0x08,0x14,0xff,0xe1,0x83,0xba,0x00,0x00,
+       0x00,0xd1,0x0c,0x10,0x04,0x00,0x00,0x14,0xff,0xe1,0x83,0xbd,0x00,0x10,0x08,0x14,
+       0xff,0xe1,0x83,0xbe,0x00,0x14,0xff,0xe1,0x83,0xbf,0x00,0xe2,0x9d,0x08,0xe1,0x48,
+       0x04,0xe0,0x1c,0x02,0xcf,0x86,0xe5,0x11,0x01,0xd4,0x84,0xd3,0x40,0xd2,0x20,0xd1,
+       0x10,0x10,0x08,0x01,0xff,0x61,0xcc,0xa5,0x00,0x01,0xff,0x61,0xcc,0xa5,0x00,0x10,
+       0x08,0x01,0xff,0x62,0xcc,0x87,0x00,0x01,0xff,0x62,0xcc,0x87,0x00,0xd1,0x10,0x10,
+       0x08,0x01,0xff,0x62,0xcc,0xa3,0x00,0x01,0xff,0x62,0xcc,0xa3,0x00,0x10,0x08,0x01,
+       0xff,0x62,0xcc,0xb1,0x00,0x01,0xff,0x62,0xcc,0xb1,0x00,0xd2,0x24,0xd1,0x14,0x10,
+       0x0a,0x01,0xff,0x63,0xcc,0xa7,0xcc,0x81,0x00,0x01,0xff,0x63,0xcc,0xa7,0xcc,0x81,
+       0x00,0x10,0x08,0x01,0xff,0x64,0xcc,0x87,0x00,0x01,0xff,0x64,0xcc,0x87,0x00,0xd1,
+       0x10,0x10,0x08,0x01,0xff,0x64,0xcc,0xa3,0x00,0x01,0xff,0x64,0xcc,0xa3,0x00,0x10,
+       0x08,0x01,0xff,0x64,0xcc,0xb1,0x00,0x01,0xff,0x64,0xcc,0xb1,0x00,0xd3,0x48,0xd2,
+       0x20,0xd1,0x10,0x10,0x08,0x01,0xff,0x64,0xcc,0xa7,0x00,0x01,0xff,0x64,0xcc,0xa7,
+       0x00,0x10,0x08,0x01,0xff,0x64,0xcc,0xad,0x00,0x01,0xff,0x64,0xcc,0xad,0x00,0xd1,
+       0x14,0x10,0x0a,0x01,0xff,0x65,0xcc,0x84,0xcc,0x80,0x00,0x01,0xff,0x65,0xcc,0x84,
+       0xcc,0x80,0x00,0x10,0x0a,0x01,0xff,0x65,0xcc,0x84,0xcc,0x81,0x00,0x01,0xff,0x65,
+       0xcc,0x84,0xcc,0x81,0x00,0xd2,0x20,0xd1,0x10,0x10,0x08,0x01,0xff,0x65,0xcc,0xad,
+       0x00,0x01,0xff,0x65,0xcc,0xad,0x00,0x10,0x08,0x01,0xff,0x65,0xcc,0xb0,0x00,0x01,
+       0xff,0x65,0xcc,0xb0,0x00,0xd1,0x14,0x10,0x0a,0x01,0xff,0x65,0xcc,0xa7,0xcc,0x86,
+       0x00,0x01,0xff,0x65,0xcc,0xa7,0xcc,0x86,0x00,0x10,0x08,0x01,0xff,0x66,0xcc,0x87,
+       0x00,0x01,0xff,0x66,0xcc,0x87,0x00,0xd4,0x84,0xd3,0x40,0xd2,0x20,0xd1,0x10,0x10,
+       0x08,0x01,0xff,0x67,0xcc,0x84,0x00,0x01,0xff,0x67,0xcc,0x84,0x00,0x10,0x08,0x01,
+       0xff,0x68,0xcc,0x87,0x00,0x01,0xff,0x68,0xcc,0x87,0x00,0xd1,0x10,0x10,0x08,0x01,
+       0xff,0x68,0xcc,0xa3,0x00,0x01,0xff,0x68,0xcc,0xa3,0x00,0x10,0x08,0x01,0xff,0x68,
+       0xcc,0x88,0x00,0x01,0xff,0x68,0xcc,0x88,0x00,0xd2,0x20,0xd1,0x10,0x10,0x08,0x01,
+       0xff,0x68,0xcc,0xa7,0x00,0x01,0xff,0x68,0xcc,0xa7,0x00,0x10,0x08,0x01,0xff,0x68,
+       0xcc,0xae,0x00,0x01,0xff,0x68,0xcc,0xae,0x00,0xd1,0x10,0x10,0x08,0x01,0xff,0x69,
+       0xcc,0xb0,0x00,0x01,0xff,0x69,0xcc,0xb0,0x00,0x10,0x0a,0x01,0xff,0x69,0xcc,0x88,
+       0xcc,0x81,0x00,0x01,0xff,0x69,0xcc,0x88,0xcc,0x81,0x00,0xd3,0x40,0xd2,0x20,0xd1,
+       0x10,0x10,0x08,0x01,0xff,0x6b,0xcc,0x81,0x00,0x01,0xff,0x6b,0xcc,0x81,0x00,0x10,
+       0x08,0x01,0xff,0x6b,0xcc,0xa3,0x00,0x01,0xff,0x6b,0xcc,0xa3,0x00,0xd1,0x10,0x10,
+       0x08,0x01,0xff,0x6b,0xcc,0xb1,0x00,0x01,0xff,0x6b,0xcc,0xb1,0x00,0x10,0x08,0x01,
+       0xff,0x6c,0xcc,0xa3,0x00,0x01,0xff,0x6c,0xcc,0xa3,0x00,0xd2,0x24,0xd1,0x14,0x10,
+       0x0a,0x01,0xff,0x6c,0xcc,0xa3,0xcc,0x84,0x00,0x01,0xff,0x6c,0xcc,0xa3,0xcc,0x84,
+       0x00,0x10,0x08,0x01,0xff,0x6c,0xcc,0xb1,0x00,0x01,0xff,0x6c,0xcc,0xb1,0x00,0xd1,
+       0x10,0x10,0x08,0x01,0xff,0x6c,0xcc,0xad,0x00,0x01,0xff,0x6c,0xcc,0xad,0x00,0x10,
+       0x08,0x01,0xff,0x6d,0xcc,0x81,0x00,0x01,0xff,0x6d,0xcc,0x81,0x00,0xcf,0x86,0xe5,
+       0x15,0x01,0xd4,0x88,0xd3,0x40,0xd2,0x20,0xd1,0x10,0x10,0x08,0x01,0xff,0x6d,0xcc,
+       0x87,0x00,0x01,0xff,0x6d,0xcc,0x87,0x00,0x10,0x08,0x01,0xff,0x6d,0xcc,0xa3,0x00,
+       0x01,0xff,0x6d,0xcc,0xa3,0x00,0xd1,0x10,0x10,0x08,0x01,0xff,0x6e,0xcc,0x87,0x00,
+       0x01,0xff,0x6e,0xcc,0x87,0x00,0x10,0x08,0x01,0xff,0x6e,0xcc,0xa3,0x00,0x01,0xff,
+       0x6e,0xcc,0xa3,0x00,0xd2,0x20,0xd1,0x10,0x10,0x08,0x01,0xff,0x6e,0xcc,0xb1,0x00,
+       0x01,0xff,0x6e,0xcc,0xb1,0x00,0x10,0x08,0x01,0xff,0x6e,0xcc,0xad,0x00,0x01,0xff,
+       0x6e,0xcc,0xad,0x00,0xd1,0x14,0x10,0x0a,0x01,0xff,0x6f,0xcc,0x83,0xcc,0x81,0x00,
+       0x01,0xff,0x6f,0xcc,0x83,0xcc,0x81,0x00,0x10,0x0a,0x01,0xff,0x6f,0xcc,0x83,0xcc,
+       0x88,0x00,0x01,0xff,0x6f,0xcc,0x83,0xcc,0x88,0x00,0xd3,0x48,0xd2,0x28,0xd1,0x14,
+       0x10,0x0a,0x01,0xff,0x6f,0xcc,0x84,0xcc,0x80,0x00,0x01,0xff,0x6f,0xcc,0x84,0xcc,
+       0x80,0x00,0x10,0x0a,0x01,0xff,0x6f,0xcc,0x84,0xcc,0x81,0x00,0x01,0xff,0x6f,0xcc,
+       0x84,0xcc,0x81,0x00,0xd1,0x10,0x10,0x08,0x01,0xff,0x70,0xcc,0x81,0x00,0x01,0xff,
+       0x70,0xcc,0x81,0x00,0x10,0x08,0x01,0xff,0x70,0xcc,0x87,0x00,0x01,0xff,0x70,0xcc,
+       0x87,0x00,0xd2,0x20,0xd1,0x10,0x10,0x08,0x01,0xff,0x72,0xcc,0x87,0x00,0x01,0xff,
+       0x72,0xcc,0x87,0x00,0x10,0x08,0x01,0xff,0x72,0xcc,0xa3,0x00,0x01,0xff,0x72,0xcc,
+       0xa3,0x00,0xd1,0x14,0x10,0x0a,0x01,0xff,0x72,0xcc,0xa3,0xcc,0x84,0x00,0x01,0xff,
+       0x72,0xcc,0xa3,0xcc,0x84,0x00,0x10,0x08,0x01,0xff,0x72,0xcc,0xb1,0x00,0x01,0xff,
+       0x72,0xcc,0xb1,0x00,0xd4,0x8c,0xd3,0x48,0xd2,0x20,0xd1,0x10,0x10,0x08,0x01,0xff,
+       0x73,0xcc,0x87,0x00,0x01,0xff,0x73,0xcc,0x87,0x00,0x10,0x08,0x01,0xff,0x73,0xcc,
+       0xa3,0x00,0x01,0xff,0x73,0xcc,0xa3,0x00,0xd1,0x14,0x10,0x0a,0x01,0xff,0x73,0xcc,
+       0x81,0xcc,0x87,0x00,0x01,0xff,0x73,0xcc,0x81,0xcc,0x87,0x00,0x10,0x0a,0x01,0xff,
+       0x73,0xcc,0x8c,0xcc,0x87,0x00,0x01,0xff,0x73,0xcc,0x8c,0xcc,0x87,0x00,0xd2,0x24,
+       0xd1,0x14,0x10,0x0a,0x01,0xff,0x73,0xcc,0xa3,0xcc,0x87,0x00,0x01,0xff,0x73,0xcc,
+       0xa3,0xcc,0x87,0x00,0x10,0x08,0x01,0xff,0x74,0xcc,0x87,0x00,0x01,0xff,0x74,0xcc,
+       0x87,0x00,0xd1,0x10,0x10,0x08,0x01,0xff,0x74,0xcc,0xa3,0x00,0x01,0xff,0x74,0xcc,
+       0xa3,0x00,0x10,0x08,0x01,0xff,0x74,0xcc,0xb1,0x00,0x01,0xff,0x74,0xcc,0xb1,0x00,
+       0xd3,0x40,0xd2,0x20,0xd1,0x10,0x10,0x08,0x01,0xff,0x74,0xcc,0xad,0x00,0x01,0xff,
+       0x74,0xcc,0xad,0x00,0x10,0x08,0x01,0xff,0x75,0xcc,0xa4,0x00,0x01,0xff,0x75,0xcc,
+       0xa4,0x00,0xd1,0x10,0x10,0x08,0x01,0xff,0x75,0xcc,0xb0,0x00,0x01,0xff,0x75,0xcc,
+       0xb0,0x00,0x10,0x08,0x01,0xff,0x75,0xcc,0xad,0x00,0x01,0xff,0x75,0xcc,0xad,0x00,
+       0xd2,0x28,0xd1,0x14,0x10,0x0a,0x01,0xff,0x75,0xcc,0x83,0xcc,0x81,0x00,0x01,0xff,
+       0x75,0xcc,0x83,0xcc,0x81,0x00,0x10,0x0a,0x01,0xff,0x75,0xcc,0x84,0xcc,0x88,0x00,
+       0x01,0xff,0x75,0xcc,0x84,0xcc,0x88,0x00,0xd1,0x10,0x10,0x08,0x01,0xff,0x76,0xcc,
+       0x83,0x00,0x01,0xff,0x76,0xcc,0x83,0x00,0x10,0x08,0x01,0xff,0x76,0xcc,0xa3,0x00,
+       0x01,0xff,0x76,0xcc,0xa3,0x00,0xe0,0x11,0x02,0xcf,0x86,0xd5,0xe2,0xd4,0x80,0xd3,
+       0x40,0xd2,0x20,0xd1,0x10,0x10,0x08,0x01,0xff,0x77,0xcc,0x80,0x00,0x01,0xff,0x77,
+       0xcc,0x80,0x00,0x10,0x08,0x01,0xff,0x77,0xcc,0x81,0x00,0x01,0xff,0x77,0xcc,0x81,
+       0x00,0xd1,0x10,0x10,0x08,0x01,0xff,0x77,0xcc,0x88,0x00,0x01,0xff,0x77,0xcc,0x88,
+       0x00,0x10,0x08,0x01,0xff,0x77,0xcc,0x87,0x00,0x01,0xff,0x77,0xcc,0x87,0x00,0xd2,
+       0x20,0xd1,0x10,0x10,0x08,0x01,0xff,0x77,0xcc,0xa3,0x00,0x01,0xff,0x77,0xcc,0xa3,
+       0x00,0x10,0x08,0x01,0xff,0x78,0xcc,0x87,0x00,0x01,0xff,0x78,0xcc,0x87,0x00,0xd1,
+       0x10,0x10,0x08,0x01,0xff,0x78,0xcc,0x88,0x00,0x01,0xff,0x78,0xcc,0x88,0x00,0x10,
+       0x08,0x01,0xff,0x79,0xcc,0x87,0x00,0x01,0xff,0x79,0xcc,0x87,0x00,0xd3,0x33,0xd2,
+       0x20,0xd1,0x10,0x10,0x08,0x01,0xff,0x7a,0xcc,0x82,0x00,0x01,0xff,0x7a,0xcc,0x82,
+       0x00,0x10,0x08,0x01,0xff,0x7a,0xcc,0xa3,0x00,0x01,0xff,0x7a,0xcc,0xa3,0x00,0xe1,
+       0xc4,0x58,0x10,0x08,0x01,0xff,0x7a,0xcc,0xb1,0x00,0x01,0xff,0x7a,0xcc,0xb1,0x00,
+       0xd2,0x20,0xd1,0x10,0x10,0x08,0x01,0xff,0x77,0xcc,0x8a,0x00,0x01,0xff,0x79,0xcc,
+       0x8a,0x00,0x10,0x08,0x01,0xff,0x61,0xca,0xbe,0x00,0x02,0xff,0x73,0xcc,0x87,0x00,
+       0x51,0x04,0x0a,0x00,0x10,0x07,0x0a,0xff,0x73,0x73,0x00,0x0a,0x00,0xd4,0x98,0xd3,
+       0x48,0xd2,0x20,0xd1,0x10,0x10,0x08,0x01,0xff,0x61,0xcc,0xa3,0x00,0x01,0xff,0x61,
+       0xcc,0xa3,0x00,0x10,0x08,0x01,0xff,0x61,0xcc,0x89,0x00,0x01,0xff,0x61,0xcc,0x89,
+       0x00,0xd1,0x14,0x10,0x0a,0x01,0xff,0x61,0xcc,0x82,0xcc,0x81,0x00,0x01,0xff,0x61,
+       0xcc,0x82,0xcc,0x81,0x00,0x10,0x0a,0x01,0xff,0x61,0xcc,0x82,0xcc,0x80,0x00,0x01,
+       0xff,0x61,0xcc,0x82,0xcc,0x80,0x00,0xd2,0x28,0xd1,0x14,0x10,0x0a,0x01,0xff,0x61,
+       0xcc,0x82,0xcc,0x89,0x00,0x01,0xff,0x61,0xcc,0x82,0xcc,0x89,0x00,0x10,0x0a,0x01,
+       0xff,0x61,0xcc,0x82,0xcc,0x83,0x00,0x01,0xff,0x61,0xcc,0x82,0xcc,0x83,0x00,0xd1,
+       0x14,0x10,0x0a,0x01,0xff,0x61,0xcc,0xa3,0xcc,0x82,0x00,0x01,0xff,0x61,0xcc,0xa3,
+       0xcc,0x82,0x00,0x10,0x0a,0x01,0xff,0x61,0xcc,0x86,0xcc,0x81,0x00,0x01,0xff,0x61,
+       0xcc,0x86,0xcc,0x81,0x00,0xd3,0x50,0xd2,0x28,0xd1,0x14,0x10,0x0a,0x01,0xff,0x61,
+       0xcc,0x86,0xcc,0x80,0x00,0x01,0xff,0x61,0xcc,0x86,0xcc,0x80,0x00,0x10,0x0a,0x01,
+       0xff,0x61,0xcc,0x86,0xcc,0x89,0x00,0x01,0xff,0x61,0xcc,0x86,0xcc,0x89,0x00,0xd1,
+       0x14,0x10,0x0a,0x01,0xff,0x61,0xcc,0x86,0xcc,0x83,0x00,0x01,0xff,0x61,0xcc,0x86,
+       0xcc,0x83,0x00,0x10,0x0a,0x01,0xff,0x61,0xcc,0xa3,0xcc,0x86,0x00,0x01,0xff,0x61,
+       0xcc,0xa3,0xcc,0x86,0x00,0xd2,0x20,0xd1,0x10,0x10,0x08,0x01,0xff,0x65,0xcc,0xa3,
+       0x00,0x01,0xff,0x65,0xcc,0xa3,0x00,0x10,0x08,0x01,0xff,0x65,0xcc,0x89,0x00,0x01,
+       0xff,0x65,0xcc,0x89,0x00,0xd1,0x10,0x10,0x08,0x01,0xff,0x65,0xcc,0x83,0x00,0x01,
+       0xff,0x65,0xcc,0x83,0x00,0x10,0x0a,0x01,0xff,0x65,0xcc,0x82,0xcc,0x81,0x00,0x01,
+       0xff,0x65,0xcc,0x82,0xcc,0x81,0x00,0xcf,0x86,0xe5,0x31,0x01,0xd4,0x90,0xd3,0x50,
+       0xd2,0x28,0xd1,0x14,0x10,0x0a,0x01,0xff,0x65,0xcc,0x82,0xcc,0x80,0x00,0x01,0xff,
+       0x65,0xcc,0x82,0xcc,0x80,0x00,0x10,0x0a,0x01,0xff,0x65,0xcc,0x82,0xcc,0x89,0x00,
+       0x01,0xff,0x65,0xcc,0x82,0xcc,0x89,0x00,0xd1,0x14,0x10,0x0a,0x01,0xff,0x65,0xcc,
+       0x82,0xcc,0x83,0x00,0x01,0xff,0x65,0xcc,0x82,0xcc,0x83,0x00,0x10,0x0a,0x01,0xff,
+       0x65,0xcc,0xa3,0xcc,0x82,0x00,0x01,0xff,0x65,0xcc,0xa3,0xcc,0x82,0x00,0xd2,0x20,
+       0xd1,0x10,0x10,0x08,0x01,0xff,0x69,0xcc,0x89,0x00,0x01,0xff,0x69,0xcc,0x89,0x00,
+       0x10,0x08,0x01,0xff,0x69,0xcc,0xa3,0x00,0x01,0xff,0x69,0xcc,0xa3,0x00,0xd1,0x10,
+       0x10,0x08,0x01,0xff,0x6f,0xcc,0xa3,0x00,0x01,0xff,0x6f,0xcc,0xa3,0x00,0x10,0x08,
+       0x01,0xff,0x6f,0xcc,0x89,0x00,0x01,0xff,0x6f,0xcc,0x89,0x00,0xd3,0x50,0xd2,0x28,
+       0xd1,0x14,0x10,0x0a,0x01,0xff,0x6f,0xcc,0x82,0xcc,0x81,0x00,0x01,0xff,0x6f,0xcc,
+       0x82,0xcc,0x81,0x00,0x10,0x0a,0x01,0xff,0x6f,0xcc,0x82,0xcc,0x80,0x00,0x01,0xff,
+       0x6f,0xcc,0x82,0xcc,0x80,0x00,0xd1,0x14,0x10,0x0a,0x01,0xff,0x6f,0xcc,0x82,0xcc,
+       0x89,0x00,0x01,0xff,0x6f,0xcc,0x82,0xcc,0x89,0x00,0x10,0x0a,0x01,0xff,0x6f,0xcc,
+       0x82,0xcc,0x83,0x00,0x01,0xff,0x6f,0xcc,0x82,0xcc,0x83,0x00,0xd2,0x28,0xd1,0x14,
+       0x10,0x0a,0x01,0xff,0x6f,0xcc,0xa3,0xcc,0x82,0x00,0x01,0xff,0x6f,0xcc,0xa3,0xcc,
+       0x82,0x00,0x10,0x0a,0x01,0xff,0x6f,0xcc,0x9b,0xcc,0x81,0x00,0x01,0xff,0x6f,0xcc,
+       0x9b,0xcc,0x81,0x00,0xd1,0x14,0x10,0x0a,0x01,0xff,0x6f,0xcc,0x9b,0xcc,0x80,0x00,
+       0x01,0xff,0x6f,0xcc,0x9b,0xcc,0x80,0x00,0x10,0x0a,0x01,0xff,0x6f,0xcc,0x9b,0xcc,
+       0x89,0x00,0x01,0xff,0x6f,0xcc,0x9b,0xcc,0x89,0x00,0xd4,0x98,0xd3,0x48,0xd2,0x28,
+       0xd1,0x14,0x10,0x0a,0x01,0xff,0x6f,0xcc,0x9b,0xcc,0x83,0x00,0x01,0xff,0x6f,0xcc,
+       0x9b,0xcc,0x83,0x00,0x10,0x0a,0x01,0xff,0x6f,0xcc,0x9b,0xcc,0xa3,0x00,0x01,0xff,
+       0x6f,0xcc,0x9b,0xcc,0xa3,0x00,0xd1,0x10,0x10,0x08,0x01,0xff,0x75,0xcc,0xa3,0x00,
+       0x01,0xff,0x75,0xcc,0xa3,0x00,0x10,0x08,0x01,0xff,0x75,0xcc,0x89,0x00,0x01,0xff,
+       0x75,0xcc,0x89,0x00,0xd2,0x28,0xd1,0x14,0x10,0x0a,0x01,0xff,0x75,0xcc,0x9b,0xcc,
+       0x81,0x00,0x01,0xff,0x75,0xcc,0x9b,0xcc,0x81,0x00,0x10,0x0a,0x01,0xff,0x75,0xcc,
+       0x9b,0xcc,0x80,0x00,0x01,0xff,0x75,0xcc,0x9b,0xcc,0x80,0x00,0xd1,0x14,0x10,0x0a,
+       0x01,0xff,0x75,0xcc,0x9b,0xcc,0x89,0x00,0x01,0xff,0x75,0xcc,0x9b,0xcc,0x89,0x00,
+       0x10,0x0a,0x01,0xff,0x75,0xcc,0x9b,0xcc,0x83,0x00,0x01,0xff,0x75,0xcc,0x9b,0xcc,
+       0x83,0x00,0xd3,0x44,0xd2,0x24,0xd1,0x14,0x10,0x0a,0x01,0xff,0x75,0xcc,0x9b,0xcc,
+       0xa3,0x00,0x01,0xff,0x75,0xcc,0x9b,0xcc,0xa3,0x00,0x10,0x08,0x01,0xff,0x79,0xcc,
+       0x80,0x00,0x01,0xff,0x79,0xcc,0x80,0x00,0xd1,0x10,0x10,0x08,0x01,0xff,0x79,0xcc,
+       0xa3,0x00,0x01,0xff,0x79,0xcc,0xa3,0x00,0x10,0x08,0x01,0xff,0x79,0xcc,0x89,0x00,
+       0x01,0xff,0x79,0xcc,0x89,0x00,0xd2,0x1c,0xd1,0x10,0x10,0x08,0x01,0xff,0x79,0xcc,
+       0x83,0x00,0x01,0xff,0x79,0xcc,0x83,0x00,0x10,0x08,0x0a,0xff,0xe1,0xbb,0xbb,0x00,
+       0x0a,0x00,0xd1,0x0c,0x10,0x08,0x0a,0xff,0xe1,0xbb,0xbd,0x00,0x0a,0x00,0x10,0x08,
+       0x0a,0xff,0xe1,0xbb,0xbf,0x00,0x0a,0x00,0xe1,0xbf,0x02,0xe0,0xa1,0x01,0xcf,0x86,
+       0xd5,0xc6,0xd4,0x6c,0xd3,0x18,0xe2,0xc0,0x58,0xe1,0xa9,0x58,0x10,0x09,0x01,0xff,
+       0xce,0xb1,0xcc,0x93,0x00,0x01,0xff,0xce,0xb1,0xcc,0x94,0x00,0xd2,0x28,0xd1,0x12,
+       0x10,0x09,0x01,0xff,0xce,0xb1,0xcc,0x93,0x00,0x01,0xff,0xce,0xb1,0xcc,0x94,0x00,
+       0x10,0x0b,0x01,0xff,0xce,0xb1,0xcc,0x93,0xcc,0x80,0x00,0x01,0xff,0xce,0xb1,0xcc,
+       0x94,0xcc,0x80,0x00,0xd1,0x16,0x10,0x0b,0x01,0xff,0xce,0xb1,0xcc,0x93,0xcc,0x81,
+       0x00,0x01,0xff,0xce,0xb1,0xcc,0x94,0xcc,0x81,0x00,0x10,0x0b,0x01,0xff,0xce,0xb1,
+       0xcc,0x93,0xcd,0x82,0x00,0x01,0xff,0xce,0xb1,0xcc,0x94,0xcd,0x82,0x00,0xd3,0x18,
+       0xe2,0xfc,0x58,0xe1,0xe5,0x58,0x10,0x09,0x01,0xff,0xce,0xb5,0xcc,0x93,0x00,0x01,
+       0xff,0xce,0xb5,0xcc,0x94,0x00,0xd2,0x28,0xd1,0x12,0x10,0x09,0x01,0xff,0xce,0xb5,
+       0xcc,0x93,0x00,0x01,0xff,0xce,0xb5,0xcc,0x94,0x00,0x10,0x0b,0x01,0xff,0xce,0xb5,
+       0xcc,0x93,0xcc,0x80,0x00,0x01,0xff,0xce,0xb5,0xcc,0x94,0xcc,0x80,0x00,0x91,0x16,
+       0x10,0x0b,0x01,0xff,0xce,0xb5,0xcc,0x93,0xcc,0x81,0x00,0x01,0xff,0xce,0xb5,0xcc,
+       0x94,0xcc,0x81,0x00,0x00,0x00,0xd4,0x6c,0xd3,0x18,0xe2,0x26,0x59,0xe1,0x0f,0x59,
+       0x10,0x09,0x01,0xff,0xce,0xb7,0xcc,0x93,0x00,0x01,0xff,0xce,0xb7,0xcc,0x94,0x00,
+       0xd2,0x28,0xd1,0x12,0x10,0x09,0x01,0xff,0xce,0xb7,0xcc,0x93,0x00,0x01,0xff,0xce,
+       0xb7,0xcc,0x94,0x00,0x10,0x0b,0x01,0xff,0xce,0xb7,0xcc,0x93,0xcc,0x80,0x00,0x01,
+       0xff,0xce,0xb7,0xcc,0x94,0xcc,0x80,0x00,0xd1,0x16,0x10,0x0b,0x01,0xff,0xce,0xb7,
+       0xcc,0x93,0xcc,0x81,0x00,0x01,0xff,0xce,0xb7,0xcc,0x94,0xcc,0x81,0x00,0x10,0x0b,
+       0x01,0xff,0xce,0xb7,0xcc,0x93,0xcd,0x82,0x00,0x01,0xff,0xce,0xb7,0xcc,0x94,0xcd,
+       0x82,0x00,0xd3,0x18,0xe2,0x62,0x59,0xe1,0x4b,0x59,0x10,0x09,0x01,0xff,0xce,0xb9,
+       0xcc,0x93,0x00,0x01,0xff,0xce,0xb9,0xcc,0x94,0x00,0xd2,0x28,0xd1,0x12,0x10,0x09,
+       0x01,0xff,0xce,0xb9,0xcc,0x93,0x00,0x01,0xff,0xce,0xb9,0xcc,0x94,0x00,0x10,0x0b,
+       0x01,0xff,0xce,0xb9,0xcc,0x93,0xcc,0x80,0x00,0x01,0xff,0xce,0xb9,0xcc,0x94,0xcc,
+       0x80,0x00,0xd1,0x16,0x10,0x0b,0x01,0xff,0xce,0xb9,0xcc,0x93,0xcc,0x81,0x00,0x01,
+       0xff,0xce,0xb9,0xcc,0x94,0xcc,0x81,0x00,0x10,0x0b,0x01,0xff,0xce,0xb9,0xcc,0x93,
+       0xcd,0x82,0x00,0x01,0xff,0xce,0xb9,0xcc,0x94,0xcd,0x82,0x00,0xcf,0x86,0xd5,0xac,
+       0xd4,0x5a,0xd3,0x18,0xe2,0x9f,0x59,0xe1,0x88,0x59,0x10,0x09,0x01,0xff,0xce,0xbf,
+       0xcc,0x93,0x00,0x01,0xff,0xce,0xbf,0xcc,0x94,0x00,0xd2,0x28,0xd1,0x12,0x10,0x09,
+       0x01,0xff,0xce,0xbf,0xcc,0x93,0x00,0x01,0xff,0xce,0xbf,0xcc,0x94,0x00,0x10,0x0b,
+       0x01,0xff,0xce,0xbf,0xcc,0x93,0xcc,0x80,0x00,0x01,0xff,0xce,0xbf,0xcc,0x94,0xcc,
+       0x80,0x00,0x91,0x16,0x10,0x0b,0x01,0xff,0xce,0xbf,0xcc,0x93,0xcc,0x81,0x00,0x01,
+       0xff,0xce,0xbf,0xcc,0x94,0xcc,0x81,0x00,0x00,0x00,0xd3,0x18,0xe2,0xc9,0x59,0xe1,
+       0xb2,0x59,0x10,0x09,0x01,0xff,0xcf,0x85,0xcc,0x93,0x00,0x01,0xff,0xcf,0x85,0xcc,
+       0x94,0x00,0xd2,0x1c,0xd1,0x0d,0x10,0x04,0x00,0x00,0x01,0xff,0xcf,0x85,0xcc,0x94,
+       0x00,0x10,0x04,0x00,0x00,0x01,0xff,0xcf,0x85,0xcc,0x94,0xcc,0x80,0x00,0xd1,0x0f,
+       0x10,0x04,0x00,0x00,0x01,0xff,0xcf,0x85,0xcc,0x94,0xcc,0x81,0x00,0x10,0x04,0x00,
+       0x00,0x01,0xff,0xcf,0x85,0xcc,0x94,0xcd,0x82,0x00,0xe4,0x85,0x5a,0xd3,0x18,0xe2,
+       0x04,0x5a,0xe1,0xed,0x59,0x10,0x09,0x01,0xff,0xcf,0x89,0xcc,0x93,0x00,0x01,0xff,
+       0xcf,0x89,0xcc,0x94,0x00,0xd2,0x28,0xd1,0x12,0x10,0x09,0x01,0xff,0xcf,0x89,0xcc,
+       0x93,0x00,0x01,0xff,0xcf,0x89,0xcc,0x94,0x00,0x10,0x0b,0x01,0xff,0xcf,0x89,0xcc,
+       0x93,0xcc,0x80,0x00,0x01,0xff,0xcf,0x89,0xcc,0x94,0xcc,0x80,0x00,0xd1,0x16,0x10,
+       0x0b,0x01,0xff,0xcf,0x89,0xcc,0x93,0xcc,0x81,0x00,0x01,0xff,0xcf,0x89,0xcc,0x94,
+       0xcc,0x81,0x00,0x10,0x0b,0x01,0xff,0xcf,0x89,0xcc,0x93,0xcd,0x82,0x00,0x01,0xff,
+       0xcf,0x89,0xcc,0x94,0xcd,0x82,0x00,0xe0,0xd9,0x02,0xcf,0x86,0xe5,0x91,0x01,0xd4,
+       0xc8,0xd3,0x64,0xd2,0x30,0xd1,0x16,0x10,0x0b,0x01,0xff,0xce,0xb1,0xcc,0x93,0xce,
+       0xb9,0x00,0x01,0xff,0xce,0xb1,0xcc,0x94,0xce,0xb9,0x00,0x10,0x0d,0x01,0xff,0xce,
+       0xb1,0xcc,0x93,0xcc,0x80,0xce,0xb9,0x00,0x01,0xff,0xce,0xb1,0xcc,0x94,0xcc,0x80,
+       0xce,0xb9,0x00,0xd1,0x1a,0x10,0x0d,0x01,0xff,0xce,0xb1,0xcc,0x93,0xcc,0x81,0xce,
+       0xb9,0x00,0x01,0xff,0xce,0xb1,0xcc,0x94,0xcc,0x81,0xce,0xb9,0x00,0x10,0x0d,0x01,
+       0xff,0xce,0xb1,0xcc,0x93,0xcd,0x82,0xce,0xb9,0x00,0x01,0xff,0xce,0xb1,0xcc,0x94,
+       0xcd,0x82,0xce,0xb9,0x00,0xd2,0x30,0xd1,0x16,0x10,0x0b,0x01,0xff,0xce,0xb1,0xcc,
+       0x93,0xce,0xb9,0x00,0x01,0xff,0xce,0xb1,0xcc,0x94,0xce,0xb9,0x00,0x10,0x0d,0x01,
+       0xff,0xce,0xb1,0xcc,0x93,0xcc,0x80,0xce,0xb9,0x00,0x01,0xff,0xce,0xb1,0xcc,0x94,
+       0xcc,0x80,0xce,0xb9,0x00,0xd1,0x1a,0x10,0x0d,0x01,0xff,0xce,0xb1,0xcc,0x93,0xcc,
+       0x81,0xce,0xb9,0x00,0x01,0xff,0xce,0xb1,0xcc,0x94,0xcc,0x81,0xce,0xb9,0x00,0x10,
+       0x0d,0x01,0xff,0xce,0xb1,0xcc,0x93,0xcd,0x82,0xce,0xb9,0x00,0x01,0xff,0xce,0xb1,
+       0xcc,0x94,0xcd,0x82,0xce,0xb9,0x00,0xd3,0x64,0xd2,0x30,0xd1,0x16,0x10,0x0b,0x01,
+       0xff,0xce,0xb7,0xcc,0x93,0xce,0xb9,0x00,0x01,0xff,0xce,0xb7,0xcc,0x94,0xce,0xb9,
+       0x00,0x10,0x0d,0x01,0xff,0xce,0xb7,0xcc,0x93,0xcc,0x80,0xce,0xb9,0x00,0x01,0xff,
+       0xce,0xb7,0xcc,0x94,0xcc,0x80,0xce,0xb9,0x00,0xd1,0x1a,0x10,0x0d,0x01,0xff,0xce,
+       0xb7,0xcc,0x93,0xcc,0x81,0xce,0xb9,0x00,0x01,0xff,0xce,0xb7,0xcc,0x94,0xcc,0x81,
+       0xce,0xb9,0x00,0x10,0x0d,0x01,0xff,0xce,0xb7,0xcc,0x93,0xcd,0x82,0xce,0xb9,0x00,
+       0x01,0xff,0xce,0xb7,0xcc,0x94,0xcd,0x82,0xce,0xb9,0x00,0xd2,0x30,0xd1,0x16,0x10,
+       0x0b,0x01,0xff,0xce,0xb7,0xcc,0x93,0xce,0xb9,0x00,0x01,0xff,0xce,0xb7,0xcc,0x94,
+       0xce,0xb9,0x00,0x10,0x0d,0x01,0xff,0xce,0xb7,0xcc,0x93,0xcc,0x80,0xce,0xb9,0x00,
+       0x01,0xff,0xce,0xb7,0xcc,0x94,0xcc,0x80,0xce,0xb9,0x00,0xd1,0x1a,0x10,0x0d,0x01,
+       0xff,0xce,0xb7,0xcc,0x93,0xcc,0x81,0xce,0xb9,0x00,0x01,0xff,0xce,0xb7,0xcc,0x94,
+       0xcc,0x81,0xce,0xb9,0x00,0x10,0x0d,0x01,0xff,0xce,0xb7,0xcc,0x93,0xcd,0x82,0xce,
+       0xb9,0x00,0x01,0xff,0xce,0xb7,0xcc,0x94,0xcd,0x82,0xce,0xb9,0x00,0xd4,0xc8,0xd3,
+       0x64,0xd2,0x30,0xd1,0x16,0x10,0x0b,0x01,0xff,0xcf,0x89,0xcc,0x93,0xce,0xb9,0x00,
+       0x01,0xff,0xcf,0x89,0xcc,0x94,0xce,0xb9,0x00,0x10,0x0d,0x01,0xff,0xcf,0x89,0xcc,
+       0x93,0xcc,0x80,0xce,0xb9,0x00,0x01,0xff,0xcf,0x89,0xcc,0x94,0xcc,0x80,0xce,0xb9,
+       0x00,0xd1,0x1a,0x10,0x0d,0x01,0xff,0xcf,0x89,0xcc,0x93,0xcc,0x81,0xce,0xb9,0x00,
+       0x01,0xff,0xcf,0x89,0xcc,0x94,0xcc,0x81,0xce,0xb9,0x00,0x10,0x0d,0x01,0xff,0xcf,
+       0x89,0xcc,0x93,0xcd,0x82,0xce,0xb9,0x00,0x01,0xff,0xcf,0x89,0xcc,0x94,0xcd,0x82,
+       0xce,0xb9,0x00,0xd2,0x30,0xd1,0x16,0x10,0x0b,0x01,0xff,0xcf,0x89,0xcc,0x93,0xce,
+       0xb9,0x00,0x01,0xff,0xcf,0x89,0xcc,0x94,0xce,0xb9,0x00,0x10,0x0d,0x01,0xff,0xcf,
+       0x89,0xcc,0x93,0xcc,0x80,0xce,0xb9,0x00,0x01,0xff,0xcf,0x89,0xcc,0x94,0xcc,0x80,
+       0xce,0xb9,0x00,0xd1,0x1a,0x10,0x0d,0x01,0xff,0xcf,0x89,0xcc,0x93,0xcc,0x81,0xce,
+       0xb9,0x00,0x01,0xff,0xcf,0x89,0xcc,0x94,0xcc,0x81,0xce,0xb9,0x00,0x10,0x0d,0x01,
+       0xff,0xcf,0x89,0xcc,0x93,0xcd,0x82,0xce,0xb9,0x00,0x01,0xff,0xcf,0x89,0xcc,0x94,
+       0xcd,0x82,0xce,0xb9,0x00,0xd3,0x49,0xd2,0x26,0xd1,0x12,0x10,0x09,0x01,0xff,0xce,
+       0xb1,0xcc,0x86,0x00,0x01,0xff,0xce,0xb1,0xcc,0x84,0x00,0x10,0x0b,0x01,0xff,0xce,
+       0xb1,0xcc,0x80,0xce,0xb9,0x00,0x01,0xff,0xce,0xb1,0xce,0xb9,0x00,0xd1,0x0f,0x10,
+       0x0b,0x01,0xff,0xce,0xb1,0xcc,0x81,0xce,0xb9,0x00,0x00,0x00,0x10,0x09,0x01,0xff,
+       0xce,0xb1,0xcd,0x82,0x00,0x01,0xff,0xce,0xb1,0xcd,0x82,0xce,0xb9,0x00,0xd2,0x24,
+       0xd1,0x12,0x10,0x09,0x01,0xff,0xce,0xb1,0xcc,0x86,0x00,0x01,0xff,0xce,0xb1,0xcc,
+       0x84,0x00,0x10,0x09,0x01,0xff,0xce,0xb1,0xcc,0x80,0x00,0x01,0xff,0xce,0xb1,0xcc,
+       0x81,0x00,0xe1,0xa5,0x5a,0x10,0x09,0x01,0xff,0xce,0xb1,0xce,0xb9,0x00,0x01,0x00,
+       0xcf,0x86,0xd5,0xbd,0xd4,0x7e,0xd3,0x44,0xd2,0x21,0xd1,0x0d,0x10,0x04,0x01,0x00,
+       0x01,0xff,0xc2,0xa8,0xcd,0x82,0x00,0x10,0x0b,0x01,0xff,0xce,0xb7,0xcc,0x80,0xce,
+       0xb9,0x00,0x01,0xff,0xce,0xb7,0xce,0xb9,0x00,0xd1,0x0f,0x10,0x0b,0x01,0xff,0xce,
+       0xb7,0xcc,0x81,0xce,0xb9,0x00,0x00,0x00,0x10,0x09,0x01,0xff,0xce,0xb7,0xcd,0x82,
+       0x00,0x01,0xff,0xce,0xb7,0xcd,0x82,0xce,0xb9,0x00,0xd2,0x24,0xd1,0x12,0x10,0x09,
+       0x01,0xff,0xce,0xb5,0xcc,0x80,0x00,0x01,0xff,0xce,0xb5,0xcc,0x81,0x00,0x10,0x09,
+       0x01,0xff,0xce,0xb7,0xcc,0x80,0x00,0x01,0xff,0xce,0xb7,0xcc,0x81,0x00,0xe1,0xb4,
+       0x5a,0x10,0x09,0x01,0xff,0xce,0xb7,0xce,0xb9,0x00,0x01,0xff,0xe1,0xbe,0xbf,0xcc,
+       0x80,0x00,0xd3,0x18,0xe2,0xda,0x5a,0xe1,0xc3,0x5a,0x10,0x09,0x01,0xff,0xce,0xb9,
+       0xcc,0x86,0x00,0x01,0xff,0xce,0xb9,0xcc,0x84,0x00,0xe2,0xfe,0x5a,0xd1,0x12,0x10,
+       0x09,0x01,0xff,0xce,0xb9,0xcc,0x86,0x00,0x01,0xff,0xce,0xb9,0xcc,0x84,0x00,0x10,
+       0x09,0x01,0xff,0xce,0xb9,0xcc,0x80,0x00,0x01,0xff,0xce,0xb9,0xcc,0x81,0x00,0xd4,
+       0x51,0xd3,0x18,0xe2,0x21,0x5b,0xe1,0x0a,0x5b,0x10,0x09,0x01,0xff,0xcf,0x85,0xcc,
+       0x86,0x00,0x01,0xff,0xcf,0x85,0xcc,0x84,0x00,0xd2,0x24,0xd1,0x12,0x10,0x09,0x01,
+       0xff,0xcf,0x85,0xcc,0x86,0x00,0x01,0xff,0xcf,0x85,0xcc,0x84,0x00,0x10,0x09,0x01,
+       0xff,0xcf,0x85,0xcc,0x80,0x00,0x01,0xff,0xcf,0x85,0xcc,0x81,0x00,0xe1,0x41,0x5b,
+       0x10,0x09,0x01,0xff,0xcf,0x81,0xcc,0x94,0x00,0x01,0xff,0xc2,0xa8,0xcc,0x80,0x00,
+       0xd3,0x3b,0xd2,0x18,0x51,0x04,0x00,0x00,0x10,0x0b,0x01,0xff,0xcf,0x89,0xcc,0x80,
+       0xce,0xb9,0x00,0x01,0xff,0xcf,0x89,0xce,0xb9,0x00,0xd1,0x0f,0x10,0x0b,0x01,0xff,
+       0xcf,0x89,0xcc,0x81,0xce,0xb9,0x00,0x00,0x00,0x10,0x09,0x01,0xff,0xcf,0x89,0xcd,
+       0x82,0x00,0x01,0xff,0xcf,0x89,0xcd,0x82,0xce,0xb9,0x00,0xd2,0x24,0xd1,0x12,0x10,
+       0x09,0x01,0xff,0xce,0xbf,0xcc,0x80,0x00,0x01,0xff,0xce,0xbf,0xcc,0x81,0x00,0x10,
+       0x09,0x01,0xff,0xcf,0x89,0xcc,0x80,0x00,0x01,0xff,0xcf,0x89,0xcc,0x81,0x00,0xe1,
+       0x4b,0x5b,0x10,0x09,0x01,0xff,0xcf,0x89,0xce,0xb9,0x00,0x01,0xff,0xc2,0xb4,0x00,
+       0xe0,0xa2,0x67,0xcf,0x86,0xe5,0x24,0x02,0xe4,0x26,0x01,0xe3,0x1b,0x5e,0xd2,0x2b,
+       0xe1,0xf5,0x5b,0xe0,0x7a,0x5b,0xcf,0x86,0xe5,0x5f,0x5b,0x94,0x1c,0x93,0x18,0x92,
+       0x14,0x91,0x10,0x10,0x08,0x01,0xff,0xe2,0x80,0x82,0x00,0x01,0xff,0xe2,0x80,0x83,
+       0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0xd1,0xd6,0xd0,0x46,0xcf,0x86,0x55,
+       0x04,0x01,0x00,0xd4,0x29,0xd3,0x13,0x52,0x04,0x01,0x00,0x51,0x04,0x01,0x00,0x10,
+       0x07,0x01,0xff,0xcf,0x89,0x00,0x01,0x00,0x92,0x12,0x51,0x04,0x01,0x00,0x10,0x06,
+       0x01,0xff,0x6b,0x00,0x01,0xff,0x61,0xcc,0x8a,0x00,0x01,0x00,0xe3,0xba,0x5c,0x92,
+       0x10,0x51,0x04,0x01,0x00,0x10,0x08,0x01,0xff,0xe2,0x85,0x8e,0x00,0x01,0x00,0x01,
+       0x00,0xcf,0x86,0xd5,0x0a,0xe4,0xd7,0x5c,0x63,0xc2,0x5c,0x06,0x00,0x94,0x80,0xd3,
+       0x40,0xd2,0x20,0xd1,0x10,0x10,0x08,0x01,0xff,0xe2,0x85,0xb0,0x00,0x01,0xff,0xe2,
+       0x85,0xb1,0x00,0x10,0x08,0x01,0xff,0xe2,0x85,0xb2,0x00,0x01,0xff,0xe2,0x85,0xb3,
+       0x00,0xd1,0x10,0x10,0x08,0x01,0xff,0xe2,0x85,0xb4,0x00,0x01,0xff,0xe2,0x85,0xb5,
+       0x00,0x10,0x08,0x01,0xff,0xe2,0x85,0xb6,0x00,0x01,0xff,0xe2,0x85,0xb7,0x00,0xd2,
+       0x20,0xd1,0x10,0x10,0x08,0x01,0xff,0xe2,0x85,0xb8,0x00,0x01,0xff,0xe2,0x85,0xb9,
+       0x00,0x10,0x08,0x01,0xff,0xe2,0x85,0xba,0x00,0x01,0xff,0xe2,0x85,0xbb,0x00,0xd1,
+       0x10,0x10,0x08,0x01,0xff,0xe2,0x85,0xbc,0x00,0x01,0xff,0xe2,0x85,0xbd,0x00,0x10,
+       0x08,0x01,0xff,0xe2,0x85,0xbe,0x00,0x01,0xff,0xe2,0x85,0xbf,0x00,0x01,0x00,0xe0,
+       0xc9,0x5c,0xcf,0x86,0xe5,0xa8,0x5c,0xe4,0x87,0x5c,0xe3,0x76,0x5c,0xe2,0x69,0x5c,
+       0x51,0x04,0x01,0x00,0x10,0x04,0x01,0x00,0x04,0xff,0xe2,0x86,0x84,0x00,0xe3,0xb8,
+       0x60,0xe2,0x85,0x60,0xd1,0x0c,0xe0,0x32,0x60,0xcf,0x86,0x65,0x13,0x60,0x01,0x00,
+       0xd0,0x62,0xcf,0x86,0x55,0x04,0x01,0x00,0x54,0x04,0x01,0x00,0xd3,0x18,0x52,0x04,
+       0x01,0x00,0x51,0x04,0x01,0x00,0x10,0x08,0x01,0xff,0xe2,0x93,0x90,0x00,0x01,0xff,
+       0xe2,0x93,0x91,0x00,0xd2,0x20,0xd1,0x10,0x10,0x08,0x01,0xff,0xe2,0x93,0x92,0x00,
+       0x01,0xff,0xe2,0x93,0x93,0x00,0x10,0x08,0x01,0xff,0xe2,0x93,0x94,0x00,0x01,0xff,
+       0xe2,0x93,0x95,0x00,0xd1,0x10,0x10,0x08,0x01,0xff,0xe2,0x93,0x96,0x00,0x01,0xff,
+       0xe2,0x93,0x97,0x00,0x10,0x08,0x01,0xff,0xe2,0x93,0x98,0x00,0x01,0xff,0xe2,0x93,
+       0x99,0x00,0xcf,0x86,0xe5,0xec,0x5f,0x94,0x80,0xd3,0x40,0xd2,0x20,0xd1,0x10,0x10,
+       0x08,0x01,0xff,0xe2,0x93,0x9a,0x00,0x01,0xff,0xe2,0x93,0x9b,0x00,0x10,0x08,0x01,
+       0xff,0xe2,0x93,0x9c,0x00,0x01,0xff,0xe2,0x93,0x9d,0x00,0xd1,0x10,0x10,0x08,0x01,
+       0xff,0xe2,0x93,0x9e,0x00,0x01,0xff,0xe2,0x93,0x9f,0x00,0x10,0x08,0x01,0xff,0xe2,
+       0x93,0xa0,0x00,0x01,0xff,0xe2,0x93,0xa1,0x00,0xd2,0x20,0xd1,0x10,0x10,0x08,0x01,
+       0xff,0xe2,0x93,0xa2,0x00,0x01,0xff,0xe2,0x93,0xa3,0x00,0x10,0x08,0x01,0xff,0xe2,
+       0x93,0xa4,0x00,0x01,0xff,0xe2,0x93,0xa5,0x00,0xd1,0x10,0x10,0x08,0x01,0xff,0xe2,
+       0x93,0xa6,0x00,0x01,0xff,0xe2,0x93,0xa7,0x00,0x10,0x08,0x01,0xff,0xe2,0x93,0xa8,
+       0x00,0x01,0xff,0xe2,0x93,0xa9,0x00,0x01,0x00,0xd4,0x0c,0xe3,0xc8,0x61,0xe2,0xc1,
+       0x61,0xcf,0x06,0x04,0x00,0xe3,0xa1,0x64,0xe2,0x94,0x63,0xe1,0x2e,0x02,0xe0,0x84,
+       0x01,0xcf,0x86,0xe5,0x01,0x01,0xd4,0x80,0xd3,0x40,0xd2,0x20,0xd1,0x10,0x10,0x08,
+       0x08,0xff,0xe2,0xb0,0xb0,0x00,0x08,0xff,0xe2,0xb0,0xb1,0x00,0x10,0x08,0x08,0xff,
+       0xe2,0xb0,0xb2,0x00,0x08,0xff,0xe2,0xb0,0xb3,0x00,0xd1,0x10,0x10,0x08,0x08,0xff,
+       0xe2,0xb0,0xb4,0x00,0x08,0xff,0xe2,0xb0,0xb5,0x00,0x10,0x08,0x08,0xff,0xe2,0xb0,
+       0xb6,0x00,0x08,0xff,0xe2,0xb0,0xb7,0x00,0xd2,0x20,0xd1,0x10,0x10,0x08,0x08,0xff,
+       0xe2,0xb0,0xb8,0x00,0x08,0xff,0xe2,0xb0,0xb9,0x00,0x10,0x08,0x08,0xff,0xe2,0xb0,
+       0xba,0x00,0x08,0xff,0xe2,0xb0,0xbb,0x00,0xd1,0x10,0x10,0x08,0x08,0xff,0xe2,0xb0,
+       0xbc,0x00,0x08,0xff,0xe2,0xb0,0xbd,0x00,0x10,0x08,0x08,0xff,0xe2,0xb0,0xbe,0x00,
+       0x08,0xff,0xe2,0xb0,0xbf,0x00,0xd3,0x40,0xd2,0x20,0xd1,0x10,0x10,0x08,0x08,0xff,
+       0xe2,0xb1,0x80,0x00,0x08,0xff,0xe2,0xb1,0x81,0x00,0x10,0x08,0x08,0xff,0xe2,0xb1,
+       0x82,0x00,0x08,0xff,0xe2,0xb1,0x83,0x00,0xd1,0x10,0x10,0x08,0x08,0xff,0xe2,0xb1,
+       0x84,0x00,0x08,0xff,0xe2,0xb1,0x85,0x00,0x10,0x08,0x08,0xff,0xe2,0xb1,0x86,0x00,
+       0x08,0xff,0xe2,0xb1,0x87,0x00,0xd2,0x20,0xd1,0x10,0x10,0x08,0x08,0xff,0xe2,0xb1,
+       0x88,0x00,0x08,0xff,0xe2,0xb1,0x89,0x00,0x10,0x08,0x08,0xff,0xe2,0xb1,0x8a,0x00,
+       0x08,0xff,0xe2,0xb1,0x8b,0x00,0xd1,0x10,0x10,0x08,0x08,0xff,0xe2,0xb1,0x8c,0x00,
+       0x08,0xff,0xe2,0xb1,0x8d,0x00,0x10,0x08,0x08,0xff,0xe2,0xb1,0x8e,0x00,0x08,0xff,
+       0xe2,0xb1,0x8f,0x00,0x94,0x7c,0xd3,0x40,0xd2,0x20,0xd1,0x10,0x10,0x08,0x08,0xff,
+       0xe2,0xb1,0x90,0x00,0x08,0xff,0xe2,0xb1,0x91,0x00,0x10,0x08,0x08,0xff,0xe2,0xb1,
+       0x92,0x00,0x08,0xff,0xe2,0xb1,0x93,0x00,0xd1,0x10,0x10,0x08,0x08,0xff,0xe2,0xb1,
+       0x94,0x00,0x08,0xff,0xe2,0xb1,0x95,0x00,0x10,0x08,0x08,0xff,0xe2,0xb1,0x96,0x00,
+       0x08,0xff,0xe2,0xb1,0x97,0x00,0xd2,0x20,0xd1,0x10,0x10,0x08,0x08,0xff,0xe2,0xb1,
+       0x98,0x00,0x08,0xff,0xe2,0xb1,0x99,0x00,0x10,0x08,0x08,0xff,0xe2,0xb1,0x9a,0x00,
+       0x08,0xff,0xe2,0xb1,0x9b,0x00,0xd1,0x10,0x10,0x08,0x08,0xff,0xe2,0xb1,0x9c,0x00,
+       0x08,0xff,0xe2,0xb1,0x9d,0x00,0x10,0x08,0x08,0xff,0xe2,0xb1,0x9e,0x00,0x00,0x00,
+       0x08,0x00,0xcf,0x86,0xd5,0x07,0x64,0x84,0x61,0x08,0x00,0xd4,0x63,0xd3,0x32,0xd2,
+       0x1b,0xd1,0x0c,0x10,0x08,0x09,0xff,0xe2,0xb1,0xa1,0x00,0x09,0x00,0x10,0x07,0x09,
+       0xff,0xc9,0xab,0x00,0x09,0xff,0xe1,0xb5,0xbd,0x00,0xd1,0x0b,0x10,0x07,0x09,0xff,
+       0xc9,0xbd,0x00,0x09,0x00,0x10,0x04,0x09,0x00,0x09,0xff,0xe2,0xb1,0xa8,0x00,0xd2,
+       0x18,0xd1,0x0c,0x10,0x04,0x09,0x00,0x09,0xff,0xe2,0xb1,0xaa,0x00,0x10,0x04,0x09,
+       0x00,0x09,0xff,0xe2,0xb1,0xac,0x00,0xd1,0x0b,0x10,0x04,0x09,0x00,0x0a,0xff,0xc9,
+       0x91,0x00,0x10,0x07,0x0a,0xff,0xc9,0xb1,0x00,0x0a,0xff,0xc9,0x90,0x00,0xd3,0x27,
+       0xd2,0x17,0xd1,0x0b,0x10,0x07,0x0b,0xff,0xc9,0x92,0x00,0x0a,0x00,0x10,0x08,0x0a,
+       0xff,0xe2,0xb1,0xb3,0x00,0x0a,0x00,0x91,0x0c,0x10,0x04,0x09,0x00,0x09,0xff,0xe2,
+       0xb1,0xb6,0x00,0x09,0x00,0x52,0x04,0x0a,0x00,0x51,0x04,0x0a,0x00,0x10,0x07,0x0b,
+       0xff,0xc8,0xbf,0x00,0x0b,0xff,0xc9,0x80,0x00,0xe0,0x83,0x01,0xcf,0x86,0xd5,0xc0,
+       0xd4,0x60,0xd3,0x30,0xd2,0x18,0xd1,0x0c,0x10,0x08,0x08,0xff,0xe2,0xb2,0x81,0x00,
+       0x08,0x00,0x10,0x08,0x08,0xff,0xe2,0xb2,0x83,0x00,0x08,0x00,0xd1,0x0c,0x10,0x08,
+       0x08,0xff,0xe2,0xb2,0x85,0x00,0x08,0x00,0x10,0x08,0x08,0xff,0xe2,0xb2,0x87,0x00,
+       0x08,0x00,0xd2,0x18,0xd1,0x0c,0x10,0x08,0x08,0xff,0xe2,0xb2,0x89,0x00,0x08,0x00,
+       0x10,0x08,0x08,0xff,0xe2,0xb2,0x8b,0x00,0x08,0x00,0xd1,0x0c,0x10,0x08,0x08,0xff,
+       0xe2,0xb2,0x8d,0x00,0x08,0x00,0x10,0x08,0x08,0xff,0xe2,0xb2,0x8f,0x00,0x08,0x00,
+       0xd3,0x30,0xd2,0x18,0xd1,0x0c,0x10,0x08,0x08,0xff,0xe2,0xb2,0x91,0x00,0x08,0x00,
+       0x10,0x08,0x08,0xff,0xe2,0xb2,0x93,0x00,0x08,0x00,0xd1,0x0c,0x10,0x08,0x08,0xff,
+       0xe2,0xb2,0x95,0x00,0x08,0x00,0x10,0x08,0x08,0xff,0xe2,0xb2,0x97,0x00,0x08,0x00,
+       0xd2,0x18,0xd1,0x0c,0x10,0x08,0x08,0xff,0xe2,0xb2,0x99,0x00,0x08,0x00,0x10,0x08,
+       0x08,0xff,0xe2,0xb2,0x9b,0x00,0x08,0x00,0xd1,0x0c,0x10,0x08,0x08,0xff,0xe2,0xb2,
+       0x9d,0x00,0x08,0x00,0x10,0x08,0x08,0xff,0xe2,0xb2,0x9f,0x00,0x08,0x00,0xd4,0x60,
+       0xd3,0x30,0xd2,0x18,0xd1,0x0c,0x10,0x08,0x08,0xff,0xe2,0xb2,0xa1,0x00,0x08,0x00,
+       0x10,0x08,0x08,0xff,0xe2,0xb2,0xa3,0x00,0x08,0x00,0xd1,0x0c,0x10,0x08,0x08,0xff,
+       0xe2,0xb2,0xa5,0x00,0x08,0x00,0x10,0x08,0x08,0xff,0xe2,0xb2,0xa7,0x00,0x08,0x00,
+       0xd2,0x18,0xd1,0x0c,0x10,0x08,0x08,0xff,0xe2,0xb2,0xa9,0x00,0x08,0x00,0x10,0x08,
+       0x08,0xff,0xe2,0xb2,0xab,0x00,0x08,0x00,0xd1,0x0c,0x10,0x08,0x08,0xff,0xe2,0xb2,
+       0xad,0x00,0x08,0x00,0x10,0x08,0x08,0xff,0xe2,0xb2,0xaf,0x00,0x08,0x00,0xd3,0x30,
+       0xd2,0x18,0xd1,0x0c,0x10,0x08,0x08,0xff,0xe2,0xb2,0xb1,0x00,0x08,0x00,0x10,0x08,
+       0x08,0xff,0xe2,0xb2,0xb3,0x00,0x08,0x00,0xd1,0x0c,0x10,0x08,0x08,0xff,0xe2,0xb2,
+       0xb5,0x00,0x08,0x00,0x10,0x08,0x08,0xff,0xe2,0xb2,0xb7,0x00,0x08,0x00,0xd2,0x18,
+       0xd1,0x0c,0x10,0x08,0x08,0xff,0xe2,0xb2,0xb9,0x00,0x08,0x00,0x10,0x08,0x08,0xff,
+       0xe2,0xb2,0xbb,0x00,0x08,0x00,0xd1,0x0c,0x10,0x08,0x08,0xff,0xe2,0xb2,0xbd,0x00,
+       0x08,0x00,0x10,0x08,0x08,0xff,0xe2,0xb2,0xbf,0x00,0x08,0x00,0xcf,0x86,0xd5,0xc0,
+       0xd4,0x60,0xd3,0x30,0xd2,0x18,0xd1,0x0c,0x10,0x08,0x08,0xff,0xe2,0xb3,0x81,0x00,
+       0x08,0x00,0x10,0x08,0x08,0xff,0xe2,0xb3,0x83,0x00,0x08,0x00,0xd1,0x0c,0x10,0x08,
+       0x08,0xff,0xe2,0xb3,0x85,0x00,0x08,0x00,0x10,0x08,0x08,0xff,0xe2,0xb3,0x87,0x00,
+       0x08,0x00,0xd2,0x18,0xd1,0x0c,0x10,0x08,0x08,0xff,0xe2,0xb3,0x89,0x00,0x08,0x00,
+       0x10,0x08,0x08,0xff,0xe2,0xb3,0x8b,0x00,0x08,0x00,0xd1,0x0c,0x10,0x08,0x08,0xff,
+       0xe2,0xb3,0x8d,0x00,0x08,0x00,0x10,0x08,0x08,0xff,0xe2,0xb3,0x8f,0x00,0x08,0x00,
+       0xd3,0x30,0xd2,0x18,0xd1,0x0c,0x10,0x08,0x08,0xff,0xe2,0xb3,0x91,0x00,0x08,0x00,
+       0x10,0x08,0x08,0xff,0xe2,0xb3,0x93,0x00,0x08,0x00,0xd1,0x0c,0x10,0x08,0x08,0xff,
+       0xe2,0xb3,0x95,0x00,0x08,0x00,0x10,0x08,0x08,0xff,0xe2,0xb3,0x97,0x00,0x08,0x00,
+       0xd2,0x18,0xd1,0x0c,0x10,0x08,0x08,0xff,0xe2,0xb3,0x99,0x00,0x08,0x00,0x10,0x08,
+       0x08,0xff,0xe2,0xb3,0x9b,0x00,0x08,0x00,0xd1,0x0c,0x10,0x08,0x08,0xff,0xe2,0xb3,
+       0x9d,0x00,0x08,0x00,0x10,0x08,0x08,0xff,0xe2,0xb3,0x9f,0x00,0x08,0x00,0xd4,0x3b,
+       0xd3,0x1c,0x92,0x18,0xd1,0x0c,0x10,0x08,0x08,0xff,0xe2,0xb3,0xa1,0x00,0x08,0x00,
+       0x10,0x08,0x08,0xff,0xe2,0xb3,0xa3,0x00,0x08,0x00,0x08,0x00,0xd2,0x10,0x51,0x04,
+       0x08,0x00,0x10,0x04,0x08,0x00,0x0b,0xff,0xe2,0xb3,0xac,0x00,0xe1,0xd0,0x5e,0x10,
+       0x04,0x0b,0x00,0x0b,0xff,0xe2,0xb3,0xae,0x00,0xe3,0xd5,0x5e,0x92,0x10,0x51,0x04,
+       0x0b,0xe6,0x10,0x08,0x0d,0xff,0xe2,0xb3,0xb3,0x00,0x0d,0x00,0x00,0x00,0xe2,0x98,
+       0x08,0xd1,0x0b,0xe0,0x8d,0x66,0xcf,0x86,0xcf,0x06,0x01,0x00,0xe0,0xe1,0x6b,0xcf,
+       0x86,0xe5,0xa7,0x05,0xd4,0x06,0xcf,0x06,0x04,0x00,0xd3,0x0c,0xe2,0x74,0x67,0xe1,
+       0x0b,0x67,0xcf,0x06,0x04,0x00,0xe2,0xdb,0x01,0xe1,0x26,0x01,0xd0,0x09,0xcf,0x86,
+       0x65,0x70,0x67,0x0a,0x00,0xcf,0x86,0xd5,0xc0,0xd4,0x60,0xd3,0x30,0xd2,0x18,0xd1,
+       0x0c,0x10,0x08,0x0a,0xff,0xea,0x99,0x81,0x00,0x0a,0x00,0x10,0x08,0x0a,0xff,0xea,
+       0x99,0x83,0x00,0x0a,0x00,0xd1,0x0c,0x10,0x08,0x0a,0xff,0xea,0x99,0x85,0x00,0x0a,
+       0x00,0x10,0x08,0x0a,0xff,0xea,0x99,0x87,0x00,0x0a,0x00,0xd2,0x18,0xd1,0x0c,0x10,
+       0x08,0x0a,0xff,0xea,0x99,0x89,0x00,0x0a,0x00,0x10,0x08,0x0a,0xff,0xea,0x99,0x8b,
+       0x00,0x0a,0x00,0xd1,0x0c,0x10,0x08,0x0a,0xff,0xea,0x99,0x8d,0x00,0x0a,0x00,0x10,
+       0x08,0x0a,0xff,0xea,0x99,0x8f,0x00,0x0a,0x00,0xd3,0x30,0xd2,0x18,0xd1,0x0c,0x10,
+       0x08,0x0a,0xff,0xea,0x99,0x91,0x00,0x0a,0x00,0x10,0x08,0x0a,0xff,0xea,0x99,0x93,
+       0x00,0x0a,0x00,0xd1,0x0c,0x10,0x08,0x0a,0xff,0xea,0x99,0x95,0x00,0x0a,0x00,0x10,
+       0x08,0x0a,0xff,0xea,0x99,0x97,0x00,0x0a,0x00,0xd2,0x18,0xd1,0x0c,0x10,0x08,0x0a,
+       0xff,0xea,0x99,0x99,0x00,0x0a,0x00,0x10,0x08,0x0a,0xff,0xea,0x99,0x9b,0x00,0x0a,
+       0x00,0xd1,0x0c,0x10,0x08,0x0a,0xff,0xea,0x99,0x9d,0x00,0x0a,0x00,0x10,0x08,0x0a,
+       0xff,0xea,0x99,0x9f,0x00,0x0a,0x00,0xe4,0xd9,0x66,0xd3,0x30,0xd2,0x18,0xd1,0x0c,
+       0x10,0x08,0x0c,0xff,0xea,0x99,0xa1,0x00,0x0c,0x00,0x10,0x08,0x0a,0xff,0xea,0x99,
+       0xa3,0x00,0x0a,0x00,0xd1,0x0c,0x10,0x08,0x0a,0xff,0xea,0x99,0xa5,0x00,0x0a,0x00,
+       0x10,0x08,0x0a,0xff,0xea,0x99,0xa7,0x00,0x0a,0x00,0xd2,0x18,0xd1,0x0c,0x10,0x08,
+       0x0a,0xff,0xea,0x99,0xa9,0x00,0x0a,0x00,0x10,0x08,0x0a,0xff,0xea,0x99,0xab,0x00,
+       0x0a,0x00,0xe1,0x88,0x66,0x10,0x08,0x0a,0xff,0xea,0x99,0xad,0x00,0x0a,0x00,0xe0,
+       0xb1,0x66,0xcf,0x86,0x95,0xab,0xd4,0x60,0xd3,0x30,0xd2,0x18,0xd1,0x0c,0x10,0x08,
+       0x0a,0xff,0xea,0x9a,0x81,0x00,0x0a,0x00,0x10,0x08,0x0a,0xff,0xea,0x9a,0x83,0x00,
+       0x0a,0x00,0xd1,0x0c,0x10,0x08,0x0a,0xff,0xea,0x9a,0x85,0x00,0x0a,0x00,0x10,0x08,
+       0x0a,0xff,0xea,0x9a,0x87,0x00,0x0a,0x00,0xd2,0x18,0xd1,0x0c,0x10,0x08,0x0a,0xff,
+       0xea,0x9a,0x89,0x00,0x0a,0x00,0x10,0x08,0x0a,0xff,0xea,0x9a,0x8b,0x00,0x0a,0x00,
+       0xd1,0x0c,0x10,0x08,0x0a,0xff,0xea,0x9a,0x8d,0x00,0x0a,0x00,0x10,0x08,0x0a,0xff,
+       0xea,0x9a,0x8f,0x00,0x0a,0x00,0xd3,0x30,0xd2,0x18,0xd1,0x0c,0x10,0x08,0x0a,0xff,
+       0xea,0x9a,0x91,0x00,0x0a,0x00,0x10,0x08,0x0a,0xff,0xea,0x9a,0x93,0x00,0x0a,0x00,
+       0xd1,0x0c,0x10,0x08,0x0a,0xff,0xea,0x9a,0x95,0x00,0x0a,0x00,0x10,0x08,0x0a,0xff,
+       0xea,0x9a,0x97,0x00,0x0a,0x00,0xe2,0x0e,0x66,0xd1,0x0c,0x10,0x08,0x10,0xff,0xea,
+       0x9a,0x99,0x00,0x10,0x00,0x10,0x08,0x10,0xff,0xea,0x9a,0x9b,0x00,0x10,0x00,0x0b,
+       0x00,0xe1,0x10,0x02,0xd0,0xb9,0xcf,0x86,0xd5,0x07,0x64,0x1a,0x66,0x08,0x00,0xd4,
+       0x58,0xd3,0x28,0xd2,0x10,0x51,0x04,0x09,0x00,0x10,0x08,0x0a,0xff,0xea,0x9c,0xa3,
+       0x00,0x0a,0x00,0xd1,0x0c,0x10,0x08,0x0a,0xff,0xea,0x9c,0xa5,0x00,0x0a,0x00,0x10,
+       0x08,0x0a,0xff,0xea,0x9c,0xa7,0x00,0x0a,0x00,0xd2,0x18,0xd1,0x0c,0x10,0x08,0x0a,
+       0xff,0xea,0x9c,0xa9,0x00,0x0a,0x00,0x10,0x08,0x0a,0xff,0xea,0x9c,0xab,0x00,0x0a,
+       0x00,0xd1,0x0c,0x10,0x08,0x0a,0xff,0xea,0x9c,0xad,0x00,0x0a,0x00,0x10,0x08,0x0a,
+       0xff,0xea,0x9c,0xaf,0x00,0x0a,0x00,0xd3,0x28,0xd2,0x10,0x51,0x04,0x0a,0x00,0x10,
+       0x08,0x0a,0xff,0xea,0x9c,0xb3,0x00,0x0a,0x00,0xd1,0x0c,0x10,0x08,0x0a,0xff,0xea,
+       0x9c,0xb5,0x00,0x0a,0x00,0x10,0x08,0x0a,0xff,0xea,0x9c,0xb7,0x00,0x0a,0x00,0xd2,
+       0x18,0xd1,0x0c,0x10,0x08,0x0a,0xff,0xea,0x9c,0xb9,0x00,0x0a,0x00,0x10,0x08,0x0a,
+       0xff,0xea,0x9c,0xbb,0x00,0x0a,0x00,0xd1,0x0c,0x10,0x08,0x0a,0xff,0xea,0x9c,0xbd,
+       0x00,0x0a,0x00,0x10,0x08,0x0a,0xff,0xea,0x9c,0xbf,0x00,0x0a,0x00,0xcf,0x86,0xd5,
+       0xc0,0xd4,0x60,0xd3,0x30,0xd2,0x18,0xd1,0x0c,0x10,0x08,0x0a,0xff,0xea,0x9d,0x81,
+       0x00,0x0a,0x00,0x10,0x08,0x0a,0xff,0xea,0x9d,0x83,0x00,0x0a,0x00,0xd1,0x0c,0x10,
+       0x08,0x0a,0xff,0xea,0x9d,0x85,0x00,0x0a,0x00,0x10,0x08,0x0a,0xff,0xea,0x9d,0x87,
+       0x00,0x0a,0x00,0xd2,0x18,0xd1,0x0c,0x10,0x08,0x0a,0xff,0xea,0x9d,0x89,0x00,0x0a,
+       0x00,0x10,0x08,0x0a,0xff,0xea,0x9d,0x8b,0x00,0x0a,0x00,0xd1,0x0c,0x10,0x08,0x0a,
+       0xff,0xea,0x9d,0x8d,0x00,0x0a,0x00,0x10,0x08,0x0a,0xff,0xea,0x9d,0x8f,0x00,0x0a,
+       0x00,0xd3,0x30,0xd2,0x18,0xd1,0x0c,0x10,0x08,0x0a,0xff,0xea,0x9d,0x91,0x00,0x0a,
+       0x00,0x10,0x08,0x0a,0xff,0xea,0x9d,0x93,0x00,0x0a,0x00,0xd1,0x0c,0x10,0x08,0x0a,
+       0xff,0xea,0x9d,0x95,0x00,0x0a,0x00,0x10,0x08,0x0a,0xff,0xea,0x9d,0x97,0x00,0x0a,
+       0x00,0xd2,0x18,0xd1,0x0c,0x10,0x08,0x0a,0xff,0xea,0x9d,0x99,0x00,0x0a,0x00,0x10,
+       0x08,0x0a,0xff,0xea,0x9d,0x9b,0x00,0x0a,0x00,0xd1,0x0c,0x10,0x08,0x0a,0xff,0xea,
+       0x9d,0x9d,0x00,0x0a,0x00,0x10,0x08,0x0a,0xff,0xea,0x9d,0x9f,0x00,0x0a,0x00,0xd4,
+       0x60,0xd3,0x30,0xd2,0x18,0xd1,0x0c,0x10,0x08,0x0a,0xff,0xea,0x9d,0xa1,0x00,0x0a,
+       0x00,0x10,0x08,0x0a,0xff,0xea,0x9d,0xa3,0x00,0x0a,0x00,0xd1,0x0c,0x10,0x08,0x0a,
+       0xff,0xea,0x9d,0xa5,0x00,0x0a,0x00,0x10,0x08,0x0a,0xff,0xea,0x9d,0xa7,0x00,0x0a,
+       0x00,0xd2,0x18,0xd1,0x0c,0x10,0x08,0x0a,0xff,0xea,0x9d,0xa9,0x00,0x0a,0x00,0x10,
+       0x08,0x0a,0xff,0xea,0x9d,0xab,0x00,0x0a,0x00,0xd1,0x0c,0x10,0x08,0x0a,0xff,0xea,
+       0x9d,0xad,0x00,0x0a,0x00,0x10,0x08,0x0a,0xff,0xea,0x9d,0xaf,0x00,0x0a,0x00,0x53,
+       0x04,0x0a,0x00,0xd2,0x18,0xd1,0x0c,0x10,0x04,0x0a,0x00,0x0a,0xff,0xea,0x9d,0xba,
+       0x00,0x10,0x04,0x0a,0x00,0x0a,0xff,0xea,0x9d,0xbc,0x00,0xd1,0x0c,0x10,0x04,0x0a,
+       0x00,0x0a,0xff,0xe1,0xb5,0xb9,0x00,0x10,0x08,0x0a,0xff,0xea,0x9d,0xbf,0x00,0x0a,
+       0x00,0xe0,0x71,0x01,0xcf,0x86,0xd5,0xa6,0xd4,0x4e,0xd3,0x30,0xd2,0x18,0xd1,0x0c,
+       0x10,0x08,0x0a,0xff,0xea,0x9e,0x81,0x00,0x0a,0x00,0x10,0x08,0x0a,0xff,0xea,0x9e,
+       0x83,0x00,0x0a,0x00,0xd1,0x0c,0x10,0x08,0x0a,0xff,0xea,0x9e,0x85,0x00,0x0a,0x00,
+       0x10,0x08,0x0a,0xff,0xea,0x9e,0x87,0x00,0x0a,0x00,0xd2,0x10,0x51,0x04,0x0a,0x00,
+       0x10,0x04,0x0a,0x00,0x0a,0xff,0xea,0x9e,0x8c,0x00,0xe1,0x16,0x64,0x10,0x04,0x0a,
+       0x00,0x0c,0xff,0xc9,0xa5,0x00,0xd3,0x28,0xd2,0x18,0xd1,0x0c,0x10,0x08,0x0c,0xff,
+       0xea,0x9e,0x91,0x00,0x0c,0x00,0x10,0x08,0x0d,0xff,0xea,0x9e,0x93,0x00,0x0d,0x00,
+       0x51,0x04,0x10,0x00,0x10,0x08,0x10,0xff,0xea,0x9e,0x97,0x00,0x10,0x00,0xd2,0x18,
+       0xd1,0x0c,0x10,0x08,0x10,0xff,0xea,0x9e,0x99,0x00,0x10,0x00,0x10,0x08,0x10,0xff,
+       0xea,0x9e,0x9b,0x00,0x10,0x00,0xd1,0x0c,0x10,0x08,0x10,0xff,0xea,0x9e,0x9d,0x00,
+       0x10,0x00,0x10,0x08,0x10,0xff,0xea,0x9e,0x9f,0x00,0x10,0x00,0xd4,0x63,0xd3,0x30,
+       0xd2,0x18,0xd1,0x0c,0x10,0x08,0x0c,0xff,0xea,0x9e,0xa1,0x00,0x0c,0x00,0x10,0x08,
+       0x0c,0xff,0xea,0x9e,0xa3,0x00,0x0c,0x00,0xd1,0x0c,0x10,0x08,0x0c,0xff,0xea,0x9e,
+       0xa5,0x00,0x0c,0x00,0x10,0x08,0x0c,0xff,0xea,0x9e,0xa7,0x00,0x0c,0x00,0xd2,0x1a,
+       0xd1,0x0c,0x10,0x08,0x0c,0xff,0xea,0x9e,0xa9,0x00,0x0c,0x00,0x10,0x07,0x0d,0xff,
+       0xc9,0xa6,0x00,0x10,0xff,0xc9,0x9c,0x00,0xd1,0x0e,0x10,0x07,0x10,0xff,0xc9,0xa1,
+       0x00,0x10,0xff,0xc9,0xac,0x00,0x10,0x07,0x12,0xff,0xc9,0xaa,0x00,0x14,0x00,0xd3,
+       0x35,0xd2,0x1d,0xd1,0x0e,0x10,0x07,0x10,0xff,0xca,0x9e,0x00,0x10,0xff,0xca,0x87,
+       0x00,0x10,0x07,0x11,0xff,0xca,0x9d,0x00,0x11,0xff,0xea,0xad,0x93,0x00,0xd1,0x0c,
+       0x10,0x08,0x11,0xff,0xea,0x9e,0xb5,0x00,0x11,0x00,0x10,0x08,0x11,0xff,0xea,0x9e,
+       0xb7,0x00,0x11,0x00,0xd2,0x18,0xd1,0x0c,0x10,0x08,0x14,0xff,0xea,0x9e,0xb9,0x00,
+       0x14,0x00,0x10,0x08,0x15,0xff,0xea,0x9e,0xbb,0x00,0x15,0x00,0xd1,0x0c,0x10,0x08,
+       0x15,0xff,0xea,0x9e,0xbd,0x00,0x15,0x00,0x10,0x08,0x15,0xff,0xea,0x9e,0xbf,0x00,
+       0x15,0x00,0xcf,0x86,0xe5,0x50,0x63,0x94,0x2f,0x93,0x2b,0xd2,0x10,0x51,0x04,0x00,
+       0x00,0x10,0x08,0x15,0xff,0xea,0x9f,0x83,0x00,0x15,0x00,0xd1,0x0f,0x10,0x08,0x15,
+       0xff,0xea,0x9e,0x94,0x00,0x15,0xff,0xca,0x82,0x00,0x10,0x08,0x15,0xff,0xe1,0xb6,
+       0x8e,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe4,0x30,0x66,0xd3,0x1d,0xe2,0xd7,0x63,
+       0xe1,0x86,0x63,0xe0,0x73,0x63,0xcf,0x86,0xe5,0x54,0x63,0x94,0x0b,0x93,0x07,0x62,
+       0x3f,0x63,0x08,0x00,0x08,0x00,0x08,0x00,0xd2,0x0f,0xe1,0xd6,0x64,0xe0,0xa3,0x64,
+       0xcf,0x86,0x65,0x88,0x64,0x0a,0x00,0xd1,0xab,0xd0,0x1a,0xcf,0x86,0xe5,0x93,0x65,
+       0xe4,0x76,0x65,0xe3,0x5d,0x65,0xe2,0x50,0x65,0x91,0x08,0x10,0x04,0x00,0x00,0x0c,
+       0x00,0x0c,0x00,0xcf,0x86,0x55,0x04,0x10,0x00,0xd4,0x0b,0x93,0x07,0x62,0xa3,0x65,
+       0x11,0x00,0x00,0x00,0xd3,0x40,0xd2,0x20,0xd1,0x10,0x10,0x08,0x11,0xff,0xe1,0x8e,
+       0xa0,0x00,0x11,0xff,0xe1,0x8e,0xa1,0x00,0x10,0x08,0x11,0xff,0xe1,0x8e,0xa2,0x00,
+       0x11,0xff,0xe1,0x8e,0xa3,0x00,0xd1,0x10,0x10,0x08,0x11,0xff,0xe1,0x8e,0xa4,0x00,
+       0x11,0xff,0xe1,0x8e,0xa5,0x00,0x10,0x08,0x11,0xff,0xe1,0x8e,0xa6,0x00,0x11,0xff,
+       0xe1,0x8e,0xa7,0x00,0xd2,0x20,0xd1,0x10,0x10,0x08,0x11,0xff,0xe1,0x8e,0xa8,0x00,
+       0x11,0xff,0xe1,0x8e,0xa9,0x00,0x10,0x08,0x11,0xff,0xe1,0x8e,0xaa,0x00,0x11,0xff,
+       0xe1,0x8e,0xab,0x00,0xd1,0x10,0x10,0x08,0x11,0xff,0xe1,0x8e,0xac,0x00,0x11,0xff,
+       0xe1,0x8e,0xad,0x00,0x10,0x08,0x11,0xff,0xe1,0x8e,0xae,0x00,0x11,0xff,0xe1,0x8e,
+       0xaf,0x00,0xe0,0x2e,0x65,0xcf,0x86,0xe5,0x01,0x01,0xd4,0x80,0xd3,0x40,0xd2,0x20,
+       0xd1,0x10,0x10,0x08,0x11,0xff,0xe1,0x8e,0xb0,0x00,0x11,0xff,0xe1,0x8e,0xb1,0x00,
+       0x10,0x08,0x11,0xff,0xe1,0x8e,0xb2,0x00,0x11,0xff,0xe1,0x8e,0xb3,0x00,0xd1,0x10,
+       0x10,0x08,0x11,0xff,0xe1,0x8e,0xb4,0x00,0x11,0xff,0xe1,0x8e,0xb5,0x00,0x10,0x08,
+       0x11,0xff,0xe1,0x8e,0xb6,0x00,0x11,0xff,0xe1,0x8e,0xb7,0x00,0xd2,0x20,0xd1,0x10,
+       0x10,0x08,0x11,0xff,0xe1,0x8e,0xb8,0x00,0x11,0xff,0xe1,0x8e,0xb9,0x00,0x10,0x08,
+       0x11,0xff,0xe1,0x8e,0xba,0x00,0x11,0xff,0xe1,0x8e,0xbb,0x00,0xd1,0x10,0x10,0x08,
+       0x11,0xff,0xe1,0x8e,0xbc,0x00,0x11,0xff,0xe1,0x8e,0xbd,0x00,0x10,0x08,0x11,0xff,
+       0xe1,0x8e,0xbe,0x00,0x11,0xff,0xe1,0x8e,0xbf,0x00,0xd3,0x40,0xd2,0x20,0xd1,0x10,
+       0x10,0x08,0x11,0xff,0xe1,0x8f,0x80,0x00,0x11,0xff,0xe1,0x8f,0x81,0x00,0x10,0x08,
+       0x11,0xff,0xe1,0x8f,0x82,0x00,0x11,0xff,0xe1,0x8f,0x83,0x00,0xd1,0x10,0x10,0x08,
+       0x11,0xff,0xe1,0x8f,0x84,0x00,0x11,0xff,0xe1,0x8f,0x85,0x00,0x10,0x08,0x11,0xff,
+       0xe1,0x8f,0x86,0x00,0x11,0xff,0xe1,0x8f,0x87,0x00,0xd2,0x20,0xd1,0x10,0x10,0x08,
+       0x11,0xff,0xe1,0x8f,0x88,0x00,0x11,0xff,0xe1,0x8f,0x89,0x00,0x10,0x08,0x11,0xff,
+       0xe1,0x8f,0x8a,0x00,0x11,0xff,0xe1,0x8f,0x8b,0x00,0xd1,0x10,0x10,0x08,0x11,0xff,
+       0xe1,0x8f,0x8c,0x00,0x11,0xff,0xe1,0x8f,0x8d,0x00,0x10,0x08,0x11,0xff,0xe1,0x8f,
+       0x8e,0x00,0x11,0xff,0xe1,0x8f,0x8f,0x00,0xd4,0x80,0xd3,0x40,0xd2,0x20,0xd1,0x10,
+       0x10,0x08,0x11,0xff,0xe1,0x8f,0x90,0x00,0x11,0xff,0xe1,0x8f,0x91,0x00,0x10,0x08,
+       0x11,0xff,0xe1,0x8f,0x92,0x00,0x11,0xff,0xe1,0x8f,0x93,0x00,0xd1,0x10,0x10,0x08,
+       0x11,0xff,0xe1,0x8f,0x94,0x00,0x11,0xff,0xe1,0x8f,0x95,0x00,0x10,0x08,0x11,0xff,
+       0xe1,0x8f,0x96,0x00,0x11,0xff,0xe1,0x8f,0x97,0x00,0xd2,0x20,0xd1,0x10,0x10,0x08,
+       0x11,0xff,0xe1,0x8f,0x98,0x00,0x11,0xff,0xe1,0x8f,0x99,0x00,0x10,0x08,0x11,0xff,
+       0xe1,0x8f,0x9a,0x00,0x11,0xff,0xe1,0x8f,0x9b,0x00,0xd1,0x10,0x10,0x08,0x11,0xff,
+       0xe1,0x8f,0x9c,0x00,0x11,0xff,0xe1,0x8f,0x9d,0x00,0x10,0x08,0x11,0xff,0xe1,0x8f,
+       0x9e,0x00,0x11,0xff,0xe1,0x8f,0x9f,0x00,0xd3,0x40,0xd2,0x20,0xd1,0x10,0x10,0x08,
+       0x11,0xff,0xe1,0x8f,0xa0,0x00,0x11,0xff,0xe1,0x8f,0xa1,0x00,0x10,0x08,0x11,0xff,
+       0xe1,0x8f,0xa2,0x00,0x11,0xff,0xe1,0x8f,0xa3,0x00,0xd1,0x10,0x10,0x08,0x11,0xff,
+       0xe1,0x8f,0xa4,0x00,0x11,0xff,0xe1,0x8f,0xa5,0x00,0x10,0x08,0x11,0xff,0xe1,0x8f,
+       0xa6,0x00,0x11,0xff,0xe1,0x8f,0xa7,0x00,0xd2,0x20,0xd1,0x10,0x10,0x08,0x11,0xff,
+       0xe1,0x8f,0xa8,0x00,0x11,0xff,0xe1,0x8f,0xa9,0x00,0x10,0x08,0x11,0xff,0xe1,0x8f,
+       0xaa,0x00,0x11,0xff,0xe1,0x8f,0xab,0x00,0xd1,0x10,0x10,0x08,0x11,0xff,0xe1,0x8f,
+       0xac,0x00,0x11,0xff,0xe1,0x8f,0xad,0x00,0x10,0x08,0x11,0xff,0xe1,0x8f,0xae,0x00,
+       0x11,0xff,0xe1,0x8f,0xaf,0x00,0xd1,0x0c,0xe0,0x67,0x63,0xcf,0x86,0xcf,0x06,0x02,
+       0xff,0xff,0xd0,0x08,0xcf,0x86,0xcf,0x06,0x01,0x00,0xcf,0x86,0xd5,0x06,0xcf,0x06,
+       0x01,0x00,0xd4,0xae,0xd3,0x09,0xe2,0xd0,0x63,0xcf,0x06,0x01,0x00,0xd2,0x27,0xe1,
+       0x9b,0x6f,0xe0,0xa2,0x6d,0xcf,0x86,0xe5,0xbb,0x6c,0xe4,0x4a,0x6c,0xe3,0x15,0x6c,
+       0xe2,0xf4,0x6b,0xe1,0xe3,0x6b,0x10,0x08,0x01,0xff,0xe5,0x88,0x87,0x00,0x01,0xff,
+       0xe5,0xba,0xa6,0x00,0xe1,0xf0,0x73,0xe0,0x64,0x73,0xcf,0x86,0xe5,0x9e,0x72,0xd4,
+       0x3b,0x93,0x37,0xd2,0x1d,0xd1,0x0e,0x10,0x07,0x01,0xff,0x66,0x66,0x00,0x01,0xff,
+       0x66,0x69,0x00,0x10,0x07,0x01,0xff,0x66,0x6c,0x00,0x01,0xff,0x66,0x66,0x69,0x00,
+       0xd1,0x0f,0x10,0x08,0x01,0xff,0x66,0x66,0x6c,0x00,0x01,0xff,0x73,0x74,0x00,0x10,
+       0x07,0x01,0xff,0x73,0x74,0x00,0x00,0x00,0x00,0x00,0xe3,0x44,0x72,0xd2,0x11,0x51,
+       0x04,0x00,0x00,0x10,0x04,0x00,0x00,0x01,0xff,0xd5,0xb4,0xd5,0xb6,0x00,0xd1,0x12,
+       0x10,0x09,0x01,0xff,0xd5,0xb4,0xd5,0xa5,0x00,0x01,0xff,0xd5,0xb4,0xd5,0xab,0x00,
+       0x10,0x09,0x01,0xff,0xd5,0xbe,0xd5,0xb6,0x00,0x01,0xff,0xd5,0xb4,0xd5,0xad,0x00,
+       0xd3,0x09,0xe2,0xbc,0x73,0xcf,0x06,0x01,0x00,0xd2,0x12,0xe1,0xab,0x74,0xe0,0x3c,
+       0x74,0xcf,0x86,0xe5,0x19,0x74,0x64,0x08,0x74,0x06,0x00,0xe1,0x11,0x75,0xe0,0xde,
+       0x74,0xcf,0x86,0xd5,0x18,0x94,0x14,0x93,0x10,0x92,0x0c,0x91,0x08,0x10,0x04,0x00,
+       0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0xd4,0x7c,0xd3,0x3c,0xd2,
+       0x1c,0xd1,0x0c,0x10,0x04,0x01,0x00,0x01,0xff,0xef,0xbd,0x81,0x00,0x10,0x08,0x01,
+       0xff,0xef,0xbd,0x82,0x00,0x01,0xff,0xef,0xbd,0x83,0x00,0xd1,0x10,0x10,0x08,0x01,
+       0xff,0xef,0xbd,0x84,0x00,0x01,0xff,0xef,0xbd,0x85,0x00,0x10,0x08,0x01,0xff,0xef,
+       0xbd,0x86,0x00,0x01,0xff,0xef,0xbd,0x87,0x00,0xd2,0x20,0xd1,0x10,0x10,0x08,0x01,
+       0xff,0xef,0xbd,0x88,0x00,0x01,0xff,0xef,0xbd,0x89,0x00,0x10,0x08,0x01,0xff,0xef,
+       0xbd,0x8a,0x00,0x01,0xff,0xef,0xbd,0x8b,0x00,0xd1,0x10,0x10,0x08,0x01,0xff,0xef,
+       0xbd,0x8c,0x00,0x01,0xff,0xef,0xbd,0x8d,0x00,0x10,0x08,0x01,0xff,0xef,0xbd,0x8e,
+       0x00,0x01,0xff,0xef,0xbd,0x8f,0x00,0xd3,0x40,0xd2,0x20,0xd1,0x10,0x10,0x08,0x01,
+       0xff,0xef,0xbd,0x90,0x00,0x01,0xff,0xef,0xbd,0x91,0x00,0x10,0x08,0x01,0xff,0xef,
+       0xbd,0x92,0x00,0x01,0xff,0xef,0xbd,0x93,0x00,0xd1,0x10,0x10,0x08,0x01,0xff,0xef,
+       0xbd,0x94,0x00,0x01,0xff,0xef,0xbd,0x95,0x00,0x10,0x08,0x01,0xff,0xef,0xbd,0x96,
+       0x00,0x01,0xff,0xef,0xbd,0x97,0x00,0x92,0x1c,0xd1,0x10,0x10,0x08,0x01,0xff,0xef,
+       0xbd,0x98,0x00,0x01,0xff,0xef,0xbd,0x99,0x00,0x10,0x08,0x01,0xff,0xef,0xbd,0x9a,
+       0x00,0x01,0x00,0x01,0x00,0x83,0xe2,0xd9,0xb2,0xe1,0xc3,0xaf,0xe0,0x40,0xae,0xcf,
+       0x86,0xe5,0xe4,0x9a,0xc4,0xe3,0xc1,0x07,0xe2,0x62,0x06,0xe1,0x79,0x85,0xe0,0x09,
+       0x05,0xcf,0x86,0xe5,0xfb,0x02,0xd4,0x1c,0xe3,0xe7,0x75,0xe2,0x3e,0x75,0xe1,0x19,
+       0x75,0xe0,0xf2,0x74,0xcf,0x86,0xe5,0xbf,0x74,0x94,0x07,0x63,0xaa,0x74,0x07,0x00,
+       0x07,0x00,0xe3,0x93,0x77,0xe2,0x58,0x77,0xe1,0x77,0x01,0xe0,0xf0,0x76,0xcf,0x86,
+       0xe5,0x21,0x01,0xd4,0x90,0xd3,0x48,0xd2,0x24,0xd1,0x12,0x10,0x09,0x05,0xff,0xf0,
+       0x90,0x90,0xa8,0x00,0x05,0xff,0xf0,0x90,0x90,0xa9,0x00,0x10,0x09,0x05,0xff,0xf0,
+       0x90,0x90,0xaa,0x00,0x05,0xff,0xf0,0x90,0x90,0xab,0x00,0xd1,0x12,0x10,0x09,0x05,
+       0xff,0xf0,0x90,0x90,0xac,0x00,0x05,0xff,0xf0,0x90,0x90,0xad,0x00,0x10,0x09,0x05,
+       0xff,0xf0,0x90,0x90,0xae,0x00,0x05,0xff,0xf0,0x90,0x90,0xaf,0x00,0xd2,0x24,0xd1,
+       0x12,0x10,0x09,0x05,0xff,0xf0,0x90,0x90,0xb0,0x00,0x05,0xff,0xf0,0x90,0x90,0xb1,
+       0x00,0x10,0x09,0x05,0xff,0xf0,0x90,0x90,0xb2,0x00,0x05,0xff,0xf0,0x90,0x90,0xb3,
+       0x00,0xd1,0x12,0x10,0x09,0x05,0xff,0xf0,0x90,0x90,0xb4,0x00,0x05,0xff,0xf0,0x90,
+       0x90,0xb5,0x00,0x10,0x09,0x05,0xff,0xf0,0x90,0x90,0xb6,0x00,0x05,0xff,0xf0,0x90,
+       0x90,0xb7,0x00,0xd3,0x48,0xd2,0x24,0xd1,0x12,0x10,0x09,0x05,0xff,0xf0,0x90,0x90,
+       0xb8,0x00,0x05,0xff,0xf0,0x90,0x90,0xb9,0x00,0x10,0x09,0x05,0xff,0xf0,0x90,0x90,
+       0xba,0x00,0x05,0xff,0xf0,0x90,0x90,0xbb,0x00,0xd1,0x12,0x10,0x09,0x05,0xff,0xf0,
+       0x90,0x90,0xbc,0x00,0x05,0xff,0xf0,0x90,0x90,0xbd,0x00,0x10,0x09,0x05,0xff,0xf0,
+       0x90,0x90,0xbe,0x00,0x05,0xff,0xf0,0x90,0x90,0xbf,0x00,0xd2,0x24,0xd1,0x12,0x10,
+       0x09,0x05,0xff,0xf0,0x90,0x91,0x80,0x00,0x05,0xff,0xf0,0x90,0x91,0x81,0x00,0x10,
+       0x09,0x05,0xff,0xf0,0x90,0x91,0x82,0x00,0x05,0xff,0xf0,0x90,0x91,0x83,0x00,0xd1,
+       0x12,0x10,0x09,0x05,0xff,0xf0,0x90,0x91,0x84,0x00,0x05,0xff,0xf0,0x90,0x91,0x85,
+       0x00,0x10,0x09,0x05,0xff,0xf0,0x90,0x91,0x86,0x00,0x05,0xff,0xf0,0x90,0x91,0x87,
+       0x00,0x94,0x4c,0x93,0x48,0xd2,0x24,0xd1,0x12,0x10,0x09,0x05,0xff,0xf0,0x90,0x91,
+       0x88,0x00,0x05,0xff,0xf0,0x90,0x91,0x89,0x00,0x10,0x09,0x05,0xff,0xf0,0x90,0x91,
+       0x8a,0x00,0x05,0xff,0xf0,0x90,0x91,0x8b,0x00,0xd1,0x12,0x10,0x09,0x05,0xff,0xf0,
+       0x90,0x91,0x8c,0x00,0x05,0xff,0xf0,0x90,0x91,0x8d,0x00,0x10,0x09,0x07,0xff,0xf0,
+       0x90,0x91,0x8e,0x00,0x07,0xff,0xf0,0x90,0x91,0x8f,0x00,0x05,0x00,0x05,0x00,0xd0,
+       0xa0,0xcf,0x86,0xd5,0x07,0x64,0x98,0x75,0x07,0x00,0xd4,0x07,0x63,0xa5,0x75,0x07,
+       0x00,0xd3,0x48,0xd2,0x24,0xd1,0x12,0x10,0x09,0x12,0xff,0xf0,0x90,0x93,0x98,0x00,
+       0x12,0xff,0xf0,0x90,0x93,0x99,0x00,0x10,0x09,0x12,0xff,0xf0,0x90,0x93,0x9a,0x00,
+       0x12,0xff,0xf0,0x90,0x93,0x9b,0x00,0xd1,0x12,0x10,0x09,0x12,0xff,0xf0,0x90,0x93,
+       0x9c,0x00,0x12,0xff,0xf0,0x90,0x93,0x9d,0x00,0x10,0x09,0x12,0xff,0xf0,0x90,0x93,
+       0x9e,0x00,0x12,0xff,0xf0,0x90,0x93,0x9f,0x00,0xd2,0x24,0xd1,0x12,0x10,0x09,0x12,
+       0xff,0xf0,0x90,0x93,0xa0,0x00,0x12,0xff,0xf0,0x90,0x93,0xa1,0x00,0x10,0x09,0x12,
+       0xff,0xf0,0x90,0x93,0xa2,0x00,0x12,0xff,0xf0,0x90,0x93,0xa3,0x00,0xd1,0x12,0x10,
+       0x09,0x12,0xff,0xf0,0x90,0x93,0xa4,0x00,0x12,0xff,0xf0,0x90,0x93,0xa5,0x00,0x10,
+       0x09,0x12,0xff,0xf0,0x90,0x93,0xa6,0x00,0x12,0xff,0xf0,0x90,0x93,0xa7,0x00,0xcf,
+       0x86,0xe5,0x2e,0x75,0xd4,0x90,0xd3,0x48,0xd2,0x24,0xd1,0x12,0x10,0x09,0x12,0xff,
+       0xf0,0x90,0x93,0xa8,0x00,0x12,0xff,0xf0,0x90,0x93,0xa9,0x00,0x10,0x09,0x12,0xff,
+       0xf0,0x90,0x93,0xaa,0x00,0x12,0xff,0xf0,0x90,0x93,0xab,0x00,0xd1,0x12,0x10,0x09,
+       0x12,0xff,0xf0,0x90,0x93,0xac,0x00,0x12,0xff,0xf0,0x90,0x93,0xad,0x00,0x10,0x09,
+       0x12,0xff,0xf0,0x90,0x93,0xae,0x00,0x12,0xff,0xf0,0x90,0x93,0xaf,0x00,0xd2,0x24,
+       0xd1,0x12,0x10,0x09,0x12,0xff,0xf0,0x90,0x93,0xb0,0x00,0x12,0xff,0xf0,0x90,0x93,
+       0xb1,0x00,0x10,0x09,0x12,0xff,0xf0,0x90,0x93,0xb2,0x00,0x12,0xff,0xf0,0x90,0x93,
+       0xb3,0x00,0xd1,0x12,0x10,0x09,0x12,0xff,0xf0,0x90,0x93,0xb4,0x00,0x12,0xff,0xf0,
+       0x90,0x93,0xb5,0x00,0x10,0x09,0x12,0xff,0xf0,0x90,0x93,0xb6,0x00,0x12,0xff,0xf0,
+       0x90,0x93,0xb7,0x00,0x93,0x28,0x92,0x24,0xd1,0x12,0x10,0x09,0x12,0xff,0xf0,0x90,
+       0x93,0xb8,0x00,0x12,0xff,0xf0,0x90,0x93,0xb9,0x00,0x10,0x09,0x12,0xff,0xf0,0x90,
+       0x93,0xba,0x00,0x12,0xff,0xf0,0x90,0x93,0xbb,0x00,0x00,0x00,0x12,0x00,0xd4,0x1f,
+       0xe3,0x47,0x76,0xe2,0xd2,0x75,0xe1,0x71,0x75,0xe0,0x52,0x75,0xcf,0x86,0xe5,0x1f,
+       0x75,0x94,0x0a,0xe3,0x0a,0x75,0x62,0x01,0x75,0x07,0x00,0x07,0x00,0xe3,0x46,0x78,
+       0xe2,0x17,0x78,0xd1,0x09,0xe0,0xb4,0x77,0xcf,0x06,0x0b,0x00,0xe0,0xe7,0x77,0xcf,
+       0x86,0xe5,0x21,0x01,0xd4,0x90,0xd3,0x48,0xd2,0x24,0xd1,0x12,0x10,0x09,0x11,0xff,
+       0xf0,0x90,0xb3,0x80,0x00,0x11,0xff,0xf0,0x90,0xb3,0x81,0x00,0x10,0x09,0x11,0xff,
+       0xf0,0x90,0xb3,0x82,0x00,0x11,0xff,0xf0,0x90,0xb3,0x83,0x00,0xd1,0x12,0x10,0x09,
+       0x11,0xff,0xf0,0x90,0xb3,0x84,0x00,0x11,0xff,0xf0,0x90,0xb3,0x85,0x00,0x10,0x09,
+       0x11,0xff,0xf0,0x90,0xb3,0x86,0x00,0x11,0xff,0xf0,0x90,0xb3,0x87,0x00,0xd2,0x24,
+       0xd1,0x12,0x10,0x09,0x11,0xff,0xf0,0x90,0xb3,0x88,0x00,0x11,0xff,0xf0,0x90,0xb3,
+       0x89,0x00,0x10,0x09,0x11,0xff,0xf0,0x90,0xb3,0x8a,0x00,0x11,0xff,0xf0,0x90,0xb3,
+       0x8b,0x00,0xd1,0x12,0x10,0x09,0x11,0xff,0xf0,0x90,0xb3,0x8c,0x00,0x11,0xff,0xf0,
+       0x90,0xb3,0x8d,0x00,0x10,0x09,0x11,0xff,0xf0,0x90,0xb3,0x8e,0x00,0x11,0xff,0xf0,
+       0x90,0xb3,0x8f,0x00,0xd3,0x48,0xd2,0x24,0xd1,0x12,0x10,0x09,0x11,0xff,0xf0,0x90,
+       0xb3,0x90,0x00,0x11,0xff,0xf0,0x90,0xb3,0x91,0x00,0x10,0x09,0x11,0xff,0xf0,0x90,
+       0xb3,0x92,0x00,0x11,0xff,0xf0,0x90,0xb3,0x93,0x00,0xd1,0x12,0x10,0x09,0x11,0xff,
+       0xf0,0x90,0xb3,0x94,0x00,0x11,0xff,0xf0,0x90,0xb3,0x95,0x00,0x10,0x09,0x11,0xff,
+       0xf0,0x90,0xb3,0x96,0x00,0x11,0xff,0xf0,0x90,0xb3,0x97,0x00,0xd2,0x24,0xd1,0x12,
+       0x10,0x09,0x11,0xff,0xf0,0x90,0xb3,0x98,0x00,0x11,0xff,0xf0,0x90,0xb3,0x99,0x00,
+       0x10,0x09,0x11,0xff,0xf0,0x90,0xb3,0x9a,0x00,0x11,0xff,0xf0,0x90,0xb3,0x9b,0x00,
+       0xd1,0x12,0x10,0x09,0x11,0xff,0xf0,0x90,0xb3,0x9c,0x00,0x11,0xff,0xf0,0x90,0xb3,
+       0x9d,0x00,0x10,0x09,0x11,0xff,0xf0,0x90,0xb3,0x9e,0x00,0x11,0xff,0xf0,0x90,0xb3,
+       0x9f,0x00,0xd4,0x90,0xd3,0x48,0xd2,0x24,0xd1,0x12,0x10,0x09,0x11,0xff,0xf0,0x90,
+       0xb3,0xa0,0x00,0x11,0xff,0xf0,0x90,0xb3,0xa1,0x00,0x10,0x09,0x11,0xff,0xf0,0x90,
+       0xb3,0xa2,0x00,0x11,0xff,0xf0,0x90,0xb3,0xa3,0x00,0xd1,0x12,0x10,0x09,0x11,0xff,
+       0xf0,0x90,0xb3,0xa4,0x00,0x11,0xff,0xf0,0x90,0xb3,0xa5,0x00,0x10,0x09,0x11,0xff,
+       0xf0,0x90,0xb3,0xa6,0x00,0x11,0xff,0xf0,0x90,0xb3,0xa7,0x00,0xd2,0x24,0xd1,0x12,
+       0x10,0x09,0x11,0xff,0xf0,0x90,0xb3,0xa8,0x00,0x11,0xff,0xf0,0x90,0xb3,0xa9,0x00,
+       0x10,0x09,0x11,0xff,0xf0,0x90,0xb3,0xaa,0x00,0x11,0xff,0xf0,0x90,0xb3,0xab,0x00,
+       0xd1,0x12,0x10,0x09,0x11,0xff,0xf0,0x90,0xb3,0xac,0x00,0x11,0xff,0xf0,0x90,0xb3,
+       0xad,0x00,0x10,0x09,0x11,0xff,0xf0,0x90,0xb3,0xae,0x00,0x11,0xff,0xf0,0x90,0xb3,
+       0xaf,0x00,0x93,0x23,0x92,0x1f,0xd1,0x12,0x10,0x09,0x11,0xff,0xf0,0x90,0xb3,0xb0,
+       0x00,0x11,0xff,0xf0,0x90,0xb3,0xb1,0x00,0x10,0x09,0x11,0xff,0xf0,0x90,0xb3,0xb2,
+       0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xcf,0x86,0xd5,0x15,0xe4,0xf9,0x7a,0xe3,0x03,
+       0x79,0xe2,0xfc,0x77,0xe1,0x4c,0x77,0xe0,0x05,0x77,0xcf,0x06,0x0c,0x00,0xe4,0x53,
+       0x7e,0xe3,0xac,0x7d,0xe2,0x55,0x7d,0xd1,0x0c,0xe0,0x1a,0x7d,0xcf,0x86,0x65,0xfb,
+       0x7c,0x14,0x00,0xe0,0x1e,0x7d,0xcf,0x86,0x55,0x04,0x00,0x00,0xd4,0x90,0xd3,0x48,
+       0xd2,0x24,0xd1,0x12,0x10,0x09,0x10,0xff,0xf0,0x91,0xa3,0x80,0x00,0x10,0xff,0xf0,
+       0x91,0xa3,0x81,0x00,0x10,0x09,0x10,0xff,0xf0,0x91,0xa3,0x82,0x00,0x10,0xff,0xf0,
+       0x91,0xa3,0x83,0x00,0xd1,0x12,0x10,0x09,0x10,0xff,0xf0,0x91,0xa3,0x84,0x00,0x10,
+       0xff,0xf0,0x91,0xa3,0x85,0x00,0x10,0x09,0x10,0xff,0xf0,0x91,0xa3,0x86,0x00,0x10,
+       0xff,0xf0,0x91,0xa3,0x87,0x00,0xd2,0x24,0xd1,0x12,0x10,0x09,0x10,0xff,0xf0,0x91,
+       0xa3,0x88,0x00,0x10,0xff,0xf0,0x91,0xa3,0x89,0x00,0x10,0x09,0x10,0xff,0xf0,0x91,
+       0xa3,0x8a,0x00,0x10,0xff,0xf0,0x91,0xa3,0x8b,0x00,0xd1,0x12,0x10,0x09,0x10,0xff,
+       0xf0,0x91,0xa3,0x8c,0x00,0x10,0xff,0xf0,0x91,0xa3,0x8d,0x00,0x10,0x09,0x10,0xff,
+       0xf0,0x91,0xa3,0x8e,0x00,0x10,0xff,0xf0,0x91,0xa3,0x8f,0x00,0xd3,0x48,0xd2,0x24,
+       0xd1,0x12,0x10,0x09,0x10,0xff,0xf0,0x91,0xa3,0x90,0x00,0x10,0xff,0xf0,0x91,0xa3,
+       0x91,0x00,0x10,0x09,0x10,0xff,0xf0,0x91,0xa3,0x92,0x00,0x10,0xff,0xf0,0x91,0xa3,
+       0x93,0x00,0xd1,0x12,0x10,0x09,0x10,0xff,0xf0,0x91,0xa3,0x94,0x00,0x10,0xff,0xf0,
+       0x91,0xa3,0x95,0x00,0x10,0x09,0x10,0xff,0xf0,0x91,0xa3,0x96,0x00,0x10,0xff,0xf0,
+       0x91,0xa3,0x97,0x00,0xd2,0x24,0xd1,0x12,0x10,0x09,0x10,0xff,0xf0,0x91,0xa3,0x98,
+       0x00,0x10,0xff,0xf0,0x91,0xa3,0x99,0x00,0x10,0x09,0x10,0xff,0xf0,0x91,0xa3,0x9a,
+       0x00,0x10,0xff,0xf0,0x91,0xa3,0x9b,0x00,0xd1,0x12,0x10,0x09,0x10,0xff,0xf0,0x91,
+       0xa3,0x9c,0x00,0x10,0xff,0xf0,0x91,0xa3,0x9d,0x00,0x10,0x09,0x10,0xff,0xf0,0x91,
+       0xa3,0x9e,0x00,0x10,0xff,0xf0,0x91,0xa3,0x9f,0x00,0xd1,0x11,0xe0,0x7a,0x80,0xcf,
+       0x86,0xe5,0x71,0x80,0xe4,0x3a,0x80,0xcf,0x06,0x00,0x00,0xe0,0x43,0x82,0xcf,0x86,
+       0xd5,0x06,0xcf,0x06,0x00,0x00,0xd4,0x09,0xe3,0x78,0x80,0xcf,0x06,0x0c,0x00,0xd3,
+       0x06,0xcf,0x06,0x00,0x00,0xe2,0xa3,0x81,0xe1,0x7e,0x81,0xd0,0x06,0xcf,0x06,0x00,
+       0x00,0xcf,0x86,0xa5,0x21,0x01,0xd4,0x90,0xd3,0x48,0xd2,0x24,0xd1,0x12,0x10,0x09,
+       0x14,0xff,0xf0,0x96,0xb9,0xa0,0x00,0x14,0xff,0xf0,0x96,0xb9,0xa1,0x00,0x10,0x09,
+       0x14,0xff,0xf0,0x96,0xb9,0xa2,0x00,0x14,0xff,0xf0,0x96,0xb9,0xa3,0x00,0xd1,0x12,
+       0x10,0x09,0x14,0xff,0xf0,0x96,0xb9,0xa4,0x00,0x14,0xff,0xf0,0x96,0xb9,0xa5,0x00,
+       0x10,0x09,0x14,0xff,0xf0,0x96,0xb9,0xa6,0x00,0x14,0xff,0xf0,0x96,0xb9,0xa7,0x00,
+       0xd2,0x24,0xd1,0x12,0x10,0x09,0x14,0xff,0xf0,0x96,0xb9,0xa8,0x00,0x14,0xff,0xf0,
+       0x96,0xb9,0xa9,0x00,0x10,0x09,0x14,0xff,0xf0,0x96,0xb9,0xaa,0x00,0x14,0xff,0xf0,
+       0x96,0xb9,0xab,0x00,0xd1,0x12,0x10,0x09,0x14,0xff,0xf0,0x96,0xb9,0xac,0x00,0x14,
+       0xff,0xf0,0x96,0xb9,0xad,0x00,0x10,0x09,0x14,0xff,0xf0,0x96,0xb9,0xae,0x00,0x14,
+       0xff,0xf0,0x96,0xb9,0xaf,0x00,0xd3,0x48,0xd2,0x24,0xd1,0x12,0x10,0x09,0x14,0xff,
+       0xf0,0x96,0xb9,0xb0,0x00,0x14,0xff,0xf0,0x96,0xb9,0xb1,0x00,0x10,0x09,0x14,0xff,
+       0xf0,0x96,0xb9,0xb2,0x00,0x14,0xff,0xf0,0x96,0xb9,0xb3,0x00,0xd1,0x12,0x10,0x09,
+       0x14,0xff,0xf0,0x96,0xb9,0xb4,0x00,0x14,0xff,0xf0,0x96,0xb9,0xb5,0x00,0x10,0x09,
+       0x14,0xff,0xf0,0x96,0xb9,0xb6,0x00,0x14,0xff,0xf0,0x96,0xb9,0xb7,0x00,0xd2,0x24,
+       0xd1,0x12,0x10,0x09,0x14,0xff,0xf0,0x96,0xb9,0xb8,0x00,0x14,0xff,0xf0,0x96,0xb9,
+       0xb9,0x00,0x10,0x09,0x14,0xff,0xf0,0x96,0xb9,0xba,0x00,0x14,0xff,0xf0,0x96,0xb9,
+       0xbb,0x00,0xd1,0x12,0x10,0x09,0x14,0xff,0xf0,0x96,0xb9,0xbc,0x00,0x14,0xff,0xf0,
+       0x96,0xb9,0xbd,0x00,0x10,0x09,0x14,0xff,0xf0,0x96,0xb9,0xbe,0x00,0x14,0xff,0xf0,
+       0x96,0xb9,0xbf,0x00,0x14,0x00,0xd2,0x14,0xe1,0x8d,0x81,0xe0,0x84,0x81,0xcf,0x86,
+       0xe5,0x45,0x81,0xe4,0x02,0x81,0xcf,0x06,0x12,0x00,0xd1,0x0b,0xe0,0xb8,0x82,0xcf,
+       0x86,0xcf,0x06,0x00,0x00,0xe0,0xf8,0x8a,0xcf,0x86,0xd5,0x22,0xe4,0x33,0x88,0xe3,
+       0xf6,0x87,0xe2,0x9b,0x87,0xe1,0x94,0x87,0xe0,0x8d,0x87,0xcf,0x86,0xe5,0x5e,0x87,
+       0xe4,0x45,0x87,0x93,0x07,0x62,0x34,0x87,0x12,0xe6,0x12,0xe6,0xe4,0x99,0x88,0xe3,
+       0x92,0x88,0xd2,0x09,0xe1,0x1b,0x88,0xcf,0x06,0x10,0x00,0xe1,0x82,0x88,0xe0,0x4f,
+       0x88,0xcf,0x86,0xe5,0x21,0x01,0xd4,0x90,0xd3,0x48,0xd2,0x24,0xd1,0x12,0x10,0x09,
+       0x12,0xff,0xf0,0x9e,0xa4,0xa2,0x00,0x12,0xff,0xf0,0x9e,0xa4,0xa3,0x00,0x10,0x09,
+       0x12,0xff,0xf0,0x9e,0xa4,0xa4,0x00,0x12,0xff,0xf0,0x9e,0xa4,0xa5,0x00,0xd1,0x12,
+       0x10,0x09,0x12,0xff,0xf0,0x9e,0xa4,0xa6,0x00,0x12,0xff,0xf0,0x9e,0xa4,0xa7,0x00,
+       0x10,0x09,0x12,0xff,0xf0,0x9e,0xa4,0xa8,0x00,0x12,0xff,0xf0,0x9e,0xa4,0xa9,0x00,
+       0xd2,0x24,0xd1,0x12,0x10,0x09,0x12,0xff,0xf0,0x9e,0xa4,0xaa,0x00,0x12,0xff,0xf0,
+       0x9e,0xa4,0xab,0x00,0x10,0x09,0x12,0xff,0xf0,0x9e,0xa4,0xac,0x00,0x12,0xff,0xf0,
+       0x9e,0xa4,0xad,0x00,0xd1,0x12,0x10,0x09,0x12,0xff,0xf0,0x9e,0xa4,0xae,0x00,0x12,
+       0xff,0xf0,0x9e,0xa4,0xaf,0x00,0x10,0x09,0x12,0xff,0xf0,0x9e,0xa4,0xb0,0x00,0x12,
+       0xff,0xf0,0x9e,0xa4,0xb1,0x00,0xd3,0x48,0xd2,0x24,0xd1,0x12,0x10,0x09,0x12,0xff,
+       0xf0,0x9e,0xa4,0xb2,0x00,0x12,0xff,0xf0,0x9e,0xa4,0xb3,0x00,0x10,0x09,0x12,0xff,
+       0xf0,0x9e,0xa4,0xb4,0x00,0x12,0xff,0xf0,0x9e,0xa4,0xb5,0x00,0xd1,0x12,0x10,0x09,
+       0x12,0xff,0xf0,0x9e,0xa4,0xb6,0x00,0x12,0xff,0xf0,0x9e,0xa4,0xb7,0x00,0x10,0x09,
+       0x12,0xff,0xf0,0x9e,0xa4,0xb8,0x00,0x12,0xff,0xf0,0x9e,0xa4,0xb9,0x00,0xd2,0x24,
+       0xd1,0x12,0x10,0x09,0x12,0xff,0xf0,0x9e,0xa4,0xba,0x00,0x12,0xff,0xf0,0x9e,0xa4,
+       0xbb,0x00,0x10,0x09,0x12,0xff,0xf0,0x9e,0xa4,0xbc,0x00,0x12,0xff,0xf0,0x9e,0xa4,
+       0xbd,0x00,0xd1,0x12,0x10,0x09,0x12,0xff,0xf0,0x9e,0xa4,0xbe,0x00,0x12,0xff,0xf0,
+       0x9e,0xa4,0xbf,0x00,0x10,0x09,0x12,0xff,0xf0,0x9e,0xa5,0x80,0x00,0x12,0xff,0xf0,
+       0x9e,0xa5,0x81,0x00,0x94,0x1e,0x93,0x1a,0x92,0x16,0x91,0x12,0x10,0x09,0x12,0xff,
+       0xf0,0x9e,0xa5,0x82,0x00,0x12,0xff,0xf0,0x9e,0xa5,0x83,0x00,0x12,0x00,0x12,0x00,
+       0x12,0x00,0x12,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+       0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+       0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+       /* nfdi_c0100 */
+       0x57,0x04,0x01,0x00,0xc6,0xe5,0x91,0x13,0xe4,0x27,0x0c,0xe3,0x61,0x07,0xe2,0xda,
+       0x01,0xc1,0xd0,0x06,0xcf,0x06,0x01,0x00,0xcf,0x86,0xd5,0xe4,0xd4,0x7c,0xd3,0x3c,
+       0xd2,0x20,0xd1,0x10,0x10,0x08,0x01,0xff,0x41,0xcc,0x80,0x00,0x01,0xff,0x41,0xcc,
+       0x81,0x00,0x10,0x08,0x01,0xff,0x41,0xcc,0x82,0x00,0x01,0xff,0x41,0xcc,0x83,0x00,
+       0xd1,0x10,0x10,0x08,0x01,0xff,0x41,0xcc,0x88,0x00,0x01,0xff,0x41,0xcc,0x8a,0x00,
+       0x10,0x04,0x01,0x00,0x01,0xff,0x43,0xcc,0xa7,0x00,0xd2,0x20,0xd1,0x10,0x10,0x08,
+       0x01,0xff,0x45,0xcc,0x80,0x00,0x01,0xff,0x45,0xcc,0x81,0x00,0x10,0x08,0x01,0xff,
+       0x45,0xcc,0x82,0x00,0x01,0xff,0x45,0xcc,0x88,0x00,0xd1,0x10,0x10,0x08,0x01,0xff,
+       0x49,0xcc,0x80,0x00,0x01,0xff,0x49,0xcc,0x81,0x00,0x10,0x08,0x01,0xff,0x49,0xcc,
+       0x82,0x00,0x01,0xff,0x49,0xcc,0x88,0x00,0xd3,0x38,0xd2,0x1c,0xd1,0x0c,0x10,0x04,
+       0x01,0x00,0x01,0xff,0x4e,0xcc,0x83,0x00,0x10,0x08,0x01,0xff,0x4f,0xcc,0x80,0x00,
+       0x01,0xff,0x4f,0xcc,0x81,0x00,0xd1,0x10,0x10,0x08,0x01,0xff,0x4f,0xcc,0x82,0x00,
+       0x01,0xff,0x4f,0xcc,0x83,0x00,0x10,0x08,0x01,0xff,0x4f,0xcc,0x88,0x00,0x01,0x00,
+       0xd2,0x1c,0xd1,0x0c,0x10,0x04,0x01,0x00,0x01,0xff,0x55,0xcc,0x80,0x00,0x10,0x08,
+       0x01,0xff,0x55,0xcc,0x81,0x00,0x01,0xff,0x55,0xcc,0x82,0x00,0x91,0x10,0x10,0x08,
+       0x01,0xff,0x55,0xcc,0x88,0x00,0x01,0xff,0x59,0xcc,0x81,0x00,0x01,0x00,0xd4,0x7c,
+       0xd3,0x3c,0xd2,0x20,0xd1,0x10,0x10,0x08,0x01,0xff,0x61,0xcc,0x80,0x00,0x01,0xff,
+       0x61,0xcc,0x81,0x00,0x10,0x08,0x01,0xff,0x61,0xcc,0x82,0x00,0x01,0xff,0x61,0xcc,
+       0x83,0x00,0xd1,0x10,0x10,0x08,0x01,0xff,0x61,0xcc,0x88,0x00,0x01,0xff,0x61,0xcc,
+       0x8a,0x00,0x10,0x04,0x01,0x00,0x01,0xff,0x63,0xcc,0xa7,0x00,0xd2,0x20,0xd1,0x10,
+       0x10,0x08,0x01,0xff,0x65,0xcc,0x80,0x00,0x01,0xff,0x65,0xcc,0x81,0x00,0x10,0x08,
+       0x01,0xff,0x65,0xcc,0x82,0x00,0x01,0xff,0x65,0xcc,0x88,0x00,0xd1,0x10,0x10,0x08,
+       0x01,0xff,0x69,0xcc,0x80,0x00,0x01,0xff,0x69,0xcc,0x81,0x00,0x10,0x08,0x01,0xff,
+       0x69,0xcc,0x82,0x00,0x01,0xff,0x69,0xcc,0x88,0x00,0xd3,0x38,0xd2,0x1c,0xd1,0x0c,
+       0x10,0x04,0x01,0x00,0x01,0xff,0x6e,0xcc,0x83,0x00,0x10,0x08,0x01,0xff,0x6f,0xcc,
+       0x80,0x00,0x01,0xff,0x6f,0xcc,0x81,0x00,0xd1,0x10,0x10,0x08,0x01,0xff,0x6f,0xcc,
+       0x82,0x00,0x01,0xff,0x6f,0xcc,0x83,0x00,0x10,0x08,0x01,0xff,0x6f,0xcc,0x88,0x00,
+       0x01,0x00,0xd2,0x1c,0xd1,0x0c,0x10,0x04,0x01,0x00,0x01,0xff,0x75,0xcc,0x80,0x00,
+       0x10,0x08,0x01,0xff,0x75,0xcc,0x81,0x00,0x01,0xff,0x75,0xcc,0x82,0x00,0xd1,0x10,
+       0x10,0x08,0x01,0xff,0x75,0xcc,0x88,0x00,0x01,0xff,0x79,0xcc,0x81,0x00,0x10,0x04,
+       0x01,0x00,0x01,0xff,0x79,0xcc,0x88,0x00,0xe1,0x9a,0x03,0xe0,0xd3,0x01,0xcf,0x86,
+       0xd5,0xf4,0xd4,0x80,0xd3,0x40,0xd2,0x20,0xd1,0x10,0x10,0x08,0x01,0xff,0x41,0xcc,
+       0x84,0x00,0x01,0xff,0x61,0xcc,0x84,0x00,0x10,0x08,0x01,0xff,0x41,0xcc,0x86,0x00,
+       0x01,0xff,0x61,0xcc,0x86,0x00,0xd1,0x10,0x10,0x08,0x01,0xff,0x41,0xcc,0xa8,0x00,
+       0x01,0xff,0x61,0xcc,0xa8,0x00,0x10,0x08,0x01,0xff,0x43,0xcc,0x81,0x00,0x01,0xff,
+       0x63,0xcc,0x81,0x00,0xd2,0x20,0xd1,0x10,0x10,0x08,0x01,0xff,0x43,0xcc,0x82,0x00,
+       0x01,0xff,0x63,0xcc,0x82,0x00,0x10,0x08,0x01,0xff,0x43,0xcc,0x87,0x00,0x01,0xff,
+       0x63,0xcc,0x87,0x00,0xd1,0x10,0x10,0x08,0x01,0xff,0x43,0xcc,0x8c,0x00,0x01,0xff,
+       0x63,0xcc,0x8c,0x00,0x10,0x08,0x01,0xff,0x44,0xcc,0x8c,0x00,0x01,0xff,0x64,0xcc,
+       0x8c,0x00,0xd3,0x34,0xd2,0x14,0x51,0x04,0x01,0x00,0x10,0x08,0x01,0xff,0x45,0xcc,
+       0x84,0x00,0x01,0xff,0x65,0xcc,0x84,0x00,0xd1,0x10,0x10,0x08,0x01,0xff,0x45,0xcc,
+       0x86,0x00,0x01,0xff,0x65,0xcc,0x86,0x00,0x10,0x08,0x01,0xff,0x45,0xcc,0x87,0x00,
+       0x01,0xff,0x65,0xcc,0x87,0x00,0xd2,0x20,0xd1,0x10,0x10,0x08,0x01,0xff,0x45,0xcc,
+       0xa8,0x00,0x01,0xff,0x65,0xcc,0xa8,0x00,0x10,0x08,0x01,0xff,0x45,0xcc,0x8c,0x00,
+       0x01,0xff,0x65,0xcc,0x8c,0x00,0xd1,0x10,0x10,0x08,0x01,0xff,0x47,0xcc,0x82,0x00,
+       0x01,0xff,0x67,0xcc,0x82,0x00,0x10,0x08,0x01,0xff,0x47,0xcc,0x86,0x00,0x01,0xff,
+       0x67,0xcc,0x86,0x00,0xd4,0x74,0xd3,0x34,0xd2,0x20,0xd1,0x10,0x10,0x08,0x01,0xff,
+       0x47,0xcc,0x87,0x00,0x01,0xff,0x67,0xcc,0x87,0x00,0x10,0x08,0x01,0xff,0x47,0xcc,
+       0xa7,0x00,0x01,0xff,0x67,0xcc,0xa7,0x00,0x91,0x10,0x10,0x08,0x01,0xff,0x48,0xcc,
+       0x82,0x00,0x01,0xff,0x68,0xcc,0x82,0x00,0x01,0x00,0xd2,0x20,0xd1,0x10,0x10,0x08,
+       0x01,0xff,0x49,0xcc,0x83,0x00,0x01,0xff,0x69,0xcc,0x83,0x00,0x10,0x08,0x01,0xff,
+       0x49,0xcc,0x84,0x00,0x01,0xff,0x69,0xcc,0x84,0x00,0xd1,0x10,0x10,0x08,0x01,0xff,
+       0x49,0xcc,0x86,0x00,0x01,0xff,0x69,0xcc,0x86,0x00,0x10,0x08,0x01,0xff,0x49,0xcc,
+       0xa8,0x00,0x01,0xff,0x69,0xcc,0xa8,0x00,0xd3,0x30,0xd2,0x10,0x91,0x0c,0x10,0x08,
+       0x01,0xff,0x49,0xcc,0x87,0x00,0x01,0x00,0x01,0x00,0xd1,0x10,0x10,0x08,0x01,0xff,
+       0x4a,0xcc,0x82,0x00,0x01,0xff,0x6a,0xcc,0x82,0x00,0x10,0x08,0x01,0xff,0x4b,0xcc,
+       0xa7,0x00,0x01,0xff,0x6b,0xcc,0xa7,0x00,0xd2,0x1c,0xd1,0x0c,0x10,0x04,0x01,0x00,
+       0x01,0xff,0x4c,0xcc,0x81,0x00,0x10,0x08,0x01,0xff,0x6c,0xcc,0x81,0x00,0x01,0xff,
+       0x4c,0xcc,0xa7,0x00,0xd1,0x10,0x10,0x08,0x01,0xff,0x6c,0xcc,0xa7,0x00,0x01,0xff,
+       0x4c,0xcc,0x8c,0x00,0x10,0x08,0x01,0xff,0x6c,0xcc,0x8c,0x00,0x01,0x00,0xcf,0x86,
+       0xd5,0xd4,0xd4,0x60,0xd3,0x30,0xd2,0x10,0x51,0x04,0x01,0x00,0x10,0x04,0x01,0x00,
+       0x01,0xff,0x4e,0xcc,0x81,0x00,0xd1,0x10,0x10,0x08,0x01,0xff,0x6e,0xcc,0x81,0x00,
+       0x01,0xff,0x4e,0xcc,0xa7,0x00,0x10,0x08,0x01,0xff,0x6e,0xcc,0xa7,0x00,0x01,0xff,
+       0x4e,0xcc,0x8c,0x00,0xd2,0x10,0x91,0x0c,0x10,0x08,0x01,0xff,0x6e,0xcc,0x8c,0x00,
+       0x01,0x00,0x01,0x00,0xd1,0x10,0x10,0x08,0x01,0xff,0x4f,0xcc,0x84,0x00,0x01,0xff,
+       0x6f,0xcc,0x84,0x00,0x10,0x08,0x01,0xff,0x4f,0xcc,0x86,0x00,0x01,0xff,0x6f,0xcc,
+       0x86,0x00,0xd3,0x34,0xd2,0x14,0x91,0x10,0x10,0x08,0x01,0xff,0x4f,0xcc,0x8b,0x00,
+       0x01,0xff,0x6f,0xcc,0x8b,0x00,0x01,0x00,0xd1,0x10,0x10,0x08,0x01,0xff,0x52,0xcc,
+       0x81,0x00,0x01,0xff,0x72,0xcc,0x81,0x00,0x10,0x08,0x01,0xff,0x52,0xcc,0xa7,0x00,
+       0x01,0xff,0x72,0xcc,0xa7,0x00,0xd2,0x20,0xd1,0x10,0x10,0x08,0x01,0xff,0x52,0xcc,
+       0x8c,0x00,0x01,0xff,0x72,0xcc,0x8c,0x00,0x10,0x08,0x01,0xff,0x53,0xcc,0x81,0x00,
+       0x01,0xff,0x73,0xcc,0x81,0x00,0xd1,0x10,0x10,0x08,0x01,0xff,0x53,0xcc,0x82,0x00,
+       0x01,0xff,0x73,0xcc,0x82,0x00,0x10,0x08,0x01,0xff,0x53,0xcc,0xa7,0x00,0x01,0xff,
+       0x73,0xcc,0xa7,0x00,0xd4,0x74,0xd3,0x34,0xd2,0x20,0xd1,0x10,0x10,0x08,0x01,0xff,
+       0x53,0xcc,0x8c,0x00,0x01,0xff,0x73,0xcc,0x8c,0x00,0x10,0x08,0x01,0xff,0x54,0xcc,
+       0xa7,0x00,0x01,0xff,0x74,0xcc,0xa7,0x00,0x91,0x10,0x10,0x08,0x01,0xff,0x54,0xcc,
+       0x8c,0x00,0x01,0xff,0x74,0xcc,0x8c,0x00,0x01,0x00,0xd2,0x20,0xd1,0x10,0x10,0x08,
+       0x01,0xff,0x55,0xcc,0x83,0x00,0x01,0xff,0x75,0xcc,0x83,0x00,0x10,0x08,0x01,0xff,
+       0x55,0xcc,0x84,0x00,0x01,0xff,0x75,0xcc,0x84,0x00,0xd1,0x10,0x10,0x08,0x01,0xff,
+       0x55,0xcc,0x86,0x00,0x01,0xff,0x75,0xcc,0x86,0x00,0x10,0x08,0x01,0xff,0x55,0xcc,
+       0x8a,0x00,0x01,0xff,0x75,0xcc,0x8a,0x00,0xd3,0x40,0xd2,0x20,0xd1,0x10,0x10,0x08,
+       0x01,0xff,0x55,0xcc,0x8b,0x00,0x01,0xff,0x75,0xcc,0x8b,0x00,0x10,0x08,0x01,0xff,
+       0x55,0xcc,0xa8,0x00,0x01,0xff,0x75,0xcc,0xa8,0x00,0xd1,0x10,0x10,0x08,0x01,0xff,
+       0x57,0xcc,0x82,0x00,0x01,0xff,0x77,0xcc,0x82,0x00,0x10,0x08,0x01,0xff,0x59,0xcc,
+       0x82,0x00,0x01,0xff,0x79,0xcc,0x82,0x00,0xd2,0x20,0xd1,0x10,0x10,0x08,0x01,0xff,
+       0x59,0xcc,0x88,0x00,0x01,0xff,0x5a,0xcc,0x81,0x00,0x10,0x08,0x01,0xff,0x7a,0xcc,
+       0x81,0x00,0x01,0xff,0x5a,0xcc,0x87,0x00,0xd1,0x10,0x10,0x08,0x01,0xff,0x7a,0xcc,
+       0x87,0x00,0x01,0xff,0x5a,0xcc,0x8c,0x00,0x10,0x08,0x01,0xff,0x7a,0xcc,0x8c,0x00,
+       0x01,0x00,0xd0,0x4a,0xcf,0x86,0x55,0x04,0x01,0x00,0xd4,0x2c,0xd3,0x18,0x92,0x14,
+       0x91,0x10,0x10,0x08,0x01,0xff,0x4f,0xcc,0x9b,0x00,0x01,0xff,0x6f,0xcc,0x9b,0x00,
        0x01,0x00,0x01,0x00,0x52,0x04,0x01,0x00,0x51,0x04,0x01,0x00,0x10,0x04,0x01,0x00,
-       0x04,0x00,0xd3,0x19,0xd2,0x11,0x51,0x04,0x01,0x00,0x10,0x04,0x01,0x00,0x01,0xff,
-       0xdb,0x92,0xd9,0x94,0x00,0x11,0x04,0x01,0x00,0x01,0xe6,0x52,0x04,0x01,0xe6,0xd1,
-       0x08,0x10,0x04,0x01,0xe6,0x01,0x00,0x10,0x04,0x01,0x00,0x01,0xe6,0xd4,0x38,0xd3,
-       0x1c,0xd2,0x0c,0x51,0x04,0x01,0xe6,0x10,0x04,0x01,0xe6,0x01,0xdc,0xd1,0x08,0x10,
-       0x04,0x01,0xe6,0x01,0x00,0x10,0x04,0x01,0x00,0x01,0xe6,0xd2,0x10,0xd1,0x08,0x10,
-       0x04,0x01,0xe6,0x01,0x00,0x10,0x04,0x01,0xdc,0x01,0xe6,0x91,0x08,0x10,0x04,0x01,
-       0xe6,0x01,0xdc,0x07,0x00,0x53,0x04,0x01,0x00,0xd2,0x08,0x11,0x04,0x01,0x00,0x04,
-       0x00,0x51,0x04,0x04,0x00,0x10,0x04,0x04,0x00,0x07,0x00,0xd1,0xc8,0xd0,0x76,0xcf,
-       0x86,0xd5,0x28,0xd4,0x14,0x53,0x04,0x04,0x00,0x52,0x04,0x04,0x00,0x51,0x04,0x04,
-       0x00,0x10,0x04,0x00,0x00,0x04,0x00,0x93,0x10,0x92,0x0c,0x91,0x08,0x10,0x04,0x04,
-       0x00,0x04,0x24,0x04,0x00,0x04,0x00,0x04,0x00,0xd4,0x14,0x53,0x04,0x04,0x00,0x52,
-       0x04,0x04,0x00,0x91,0x08,0x10,0x04,0x04,0x00,0x07,0x00,0x07,0x00,0xd3,0x1c,0xd2,
-       0x0c,0x91,0x08,0x10,0x04,0x04,0xe6,0x04,0xdc,0x04,0xe6,0xd1,0x08,0x10,0x04,0x04,
-       0xdc,0x04,0xe6,0x10,0x04,0x04,0xe6,0x04,0xdc,0xd2,0x0c,0x51,0x04,0x04,0xdc,0x10,
-       0x04,0x04,0xe6,0x04,0xdc,0xd1,0x08,0x10,0x04,0x04,0xdc,0x04,0xe6,0x10,0x04,0x04,
-       0xdc,0x04,0xe6,0xcf,0x86,0xd5,0x3c,0x94,0x38,0xd3,0x1c,0xd2,0x0c,0x51,0x04,0x04,
-       0xe6,0x10,0x04,0x04,0xdc,0x04,0xe6,0xd1,0x08,0x10,0x04,0x04,0xdc,0x04,0xe6,0x10,
-       0x04,0x04,0xdc,0x04,0xe6,0xd2,0x10,0xd1,0x08,0x10,0x04,0x04,0xdc,0x04,0xe6,0x10,
-       0x04,0x04,0xe6,0x00,0x00,0x91,0x08,0x10,0x04,0x00,0x00,0x07,0x00,0x07,0x00,0x08,
-       0x00,0x94,0x10,0x53,0x04,0x08,0x00,0x52,0x04,0x08,0x00,0x11,0x04,0x08,0x00,0x0a,
-       0x00,0x0a,0x00,0xd0,0x1e,0xcf,0x86,0x55,0x04,0x04,0x00,0x54,0x04,0x04,0x00,0x93,
-       0x10,0x92,0x0c,0x91,0x08,0x10,0x04,0x04,0x00,0x06,0x00,0x00,0x00,0x00,0x00,0x00,
-       0x00,0xcf,0x86,0x55,0x04,0x09,0x00,0xd4,0x14,0x53,0x04,0x09,0x00,0x92,0x0c,0x51,
-       0x04,0x09,0x00,0x10,0x04,0x09,0x00,0x09,0xe6,0x09,0xe6,0xd3,0x10,0x92,0x0c,0x51,
-       0x04,0x09,0xe6,0x10,0x04,0x09,0xdc,0x09,0xe6,0x09,0x00,0xd2,0x0c,0x51,0x04,0x09,
-       0x00,0x10,0x04,0x09,0x00,0x00,0x00,0x91,0x08,0x10,0x04,0x00,0x00,0x14,0xdc,0x14,
-       0x00,0xe4,0xf8,0x57,0xe3,0x45,0x3f,0xe2,0xf4,0x3e,0xe1,0xc7,0x2c,0xe0,0x21,0x10,
-       0xcf,0x86,0xc5,0xe4,0x80,0x08,0xe3,0xcb,0x03,0xe2,0x61,0x01,0xd1,0x94,0xd0,0x5a,
-       0xcf,0x86,0xd5,0x20,0x54,0x04,0x0b,0x00,0xd3,0x0c,0x52,0x04,0x0b,0x00,0x11,0x04,
-       0x0b,0x00,0x0b,0xe6,0x92,0x0c,0x51,0x04,0x0b,0xe6,0x10,0x04,0x0b,0x00,0x0b,0xe6,
-       0x0b,0xe6,0xd4,0x24,0xd3,0x10,0x52,0x04,0x0b,0xe6,0x91,0x08,0x10,0x04,0x0b,0x00,
-       0x0b,0xe6,0x0b,0xe6,0xd2,0x0c,0x91,0x08,0x10,0x04,0x0b,0x00,0x0b,0xe6,0x0b,0xe6,
-       0x11,0x04,0x0b,0xe6,0x00,0x00,0x53,0x04,0x0b,0x00,0x52,0x04,0x0b,0x00,0x51,0x04,
-       0x0b,0x00,0x10,0x04,0x0b,0x00,0x00,0x00,0xcf,0x86,0xd5,0x20,0x54,0x04,0x0c,0x00,
-       0x53,0x04,0x0c,0x00,0xd2,0x0c,0x91,0x08,0x10,0x04,0x0c,0x00,0x0c,0xdc,0x0c,0xdc,
-       0x51,0x04,0x00,0x00,0x10,0x04,0x0c,0x00,0x00,0x00,0x94,0x14,0x53,0x04,0x13,0x00,
-       0x92,0x0c,0x51,0x04,0x13,0x00,0x10,0x04,0x13,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-       0xd0,0x4a,0xcf,0x86,0x55,0x04,0x00,0x00,0xd4,0x20,0xd3,0x10,0x92,0x0c,0x91,0x08,
-       0x10,0x04,0x0d,0x00,0x10,0x00,0x0d,0x00,0x0d,0x00,0x52,0x04,0x0d,0x00,0x91,0x08,
-       0x10,0x04,0x0d,0x00,0x10,0x00,0x10,0x00,0xd3,0x18,0xd2,0x0c,0x51,0x04,0x10,0x00,
-       0x10,0x04,0x10,0x00,0x11,0x00,0x91,0x08,0x10,0x04,0x11,0x00,0x00,0x00,0x12,0x00,
-       0x52,0x04,0x12,0x00,0x11,0x04,0x12,0x00,0x00,0x00,0xcf,0x86,0xd5,0x18,0x54,0x04,
-       0x00,0x00,0x93,0x10,0x92,0x0c,0x51,0x04,0x00,0x00,0x10,0x04,0x00,0x00,0x14,0xdc,
-       0x12,0xe6,0x12,0xe6,0xd4,0x30,0xd3,0x18,0xd2,0x0c,0x51,0x04,0x12,0xe6,0x10,0x04,
-       0x12,0x00,0x11,0xdc,0x51,0x04,0x0d,0xe6,0x10,0x04,0x0d,0xdc,0x0d,0xe6,0xd2,0x0c,
-       0x91,0x08,0x10,0x04,0x0d,0xe6,0x0d,0xdc,0x0d,0xe6,0x91,0x08,0x10,0x04,0x0d,0xe6,
-       0x0d,0xdc,0x0d,0xdc,0xd3,0x1c,0xd2,0x10,0xd1,0x08,0x10,0x04,0x0d,0x1b,0x0d,0x1c,
-       0x10,0x04,0x0d,0x1d,0x0d,0xe6,0x51,0x04,0x0d,0xe6,0x10,0x04,0x0d,0xdc,0x0d,0xe6,
-       0xd2,0x10,0xd1,0x08,0x10,0x04,0x0d,0xe6,0x0d,0xdc,0x10,0x04,0x0d,0xdc,0x0d,0xe6,
-       0x51,0x04,0x0d,0xe6,0x10,0x04,0x0d,0xe6,0x10,0xe6,0xe1,0x3a,0x01,0xd0,0x77,0xcf,
-       0x86,0xd5,0x20,0x94,0x1c,0x93,0x18,0xd2,0x0c,0x91,0x08,0x10,0x04,0x0b,0x00,0x01,
-       0x00,0x01,0x00,0x91,0x08,0x10,0x04,0x07,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,
-       0x00,0xd4,0x1b,0x53,0x04,0x01,0x00,0x92,0x13,0x91,0x0f,0x10,0x04,0x01,0x00,0x01,
-       0xff,0xe0,0xa4,0xa8,0xe0,0xa4,0xbc,0x00,0x01,0x00,0x01,0x00,0xd3,0x26,0xd2,0x13,
-       0x91,0x0f,0x10,0x04,0x01,0x00,0x01,0xff,0xe0,0xa4,0xb0,0xe0,0xa4,0xbc,0x00,0x01,
-       0x00,0x91,0x0f,0x10,0x0b,0x01,0xff,0xe0,0xa4,0xb3,0xe0,0xa4,0xbc,0x00,0x01,0x00,
-       0x01,0x00,0xd2,0x08,0x11,0x04,0x01,0x00,0x0c,0x00,0x91,0x08,0x10,0x04,0x01,0x07,
-       0x01,0x00,0x01,0x00,0xcf,0x86,0xd5,0x8c,0xd4,0x18,0x53,0x04,0x01,0x00,0x52,0x04,
-       0x01,0x00,0xd1,0x08,0x10,0x04,0x01,0x00,0x01,0x09,0x10,0x04,0x0b,0x00,0x0c,0x00,
-       0xd3,0x1c,0xd2,0x10,0xd1,0x08,0x10,0x04,0x01,0x00,0x01,0xe6,0x10,0x04,0x01,0xdc,
-       0x01,0xe6,0x91,0x08,0x10,0x04,0x01,0xe6,0x0b,0x00,0x0c,0x00,0xd2,0x2c,0xd1,0x16,
-       0x10,0x0b,0x01,0xff,0xe0,0xa4,0x95,0xe0,0xa4,0xbc,0x00,0x01,0xff,0xe0,0xa4,0x96,
-       0xe0,0xa4,0xbc,0x00,0x10,0x0b,0x01,0xff,0xe0,0xa4,0x97,0xe0,0xa4,0xbc,0x00,0x01,
-       0xff,0xe0,0xa4,0x9c,0xe0,0xa4,0xbc,0x00,0xd1,0x16,0x10,0x0b,0x01,0xff,0xe0,0xa4,
-       0xa1,0xe0,0xa4,0xbc,0x00,0x01,0xff,0xe0,0xa4,0xa2,0xe0,0xa4,0xbc,0x00,0x10,0x0b,
-       0x01,0xff,0xe0,0xa4,0xab,0xe0,0xa4,0xbc,0x00,0x01,0xff,0xe0,0xa4,0xaf,0xe0,0xa4,
-       0xbc,0x00,0x54,0x04,0x01,0x00,0xd3,0x14,0x92,0x10,0xd1,0x08,0x10,0x04,0x01,0x00,
-       0x0a,0x00,0x10,0x04,0x0a,0x00,0x0c,0x00,0x0c,0x00,0xd2,0x10,0xd1,0x08,0x10,0x04,
-       0x10,0x00,0x0b,0x00,0x10,0x04,0x0b,0x00,0x09,0x00,0x91,0x08,0x10,0x04,0x09,0x00,
-       0x08,0x00,0x09,0x00,0xd0,0x86,0xcf,0x86,0xd5,0x44,0xd4,0x2c,0xd3,0x18,0xd2,0x0c,
-       0x91,0x08,0x10,0x04,0x10,0x00,0x01,0x00,0x01,0x00,0x91,0x08,0x10,0x04,0x00,0x00,
-       0x01,0x00,0x01,0x00,0x52,0x04,0x01,0x00,0xd1,0x08,0x10,0x04,0x01,0x00,0x00,0x00,
+       0x01,0xff,0x55,0xcc,0x9b,0x00,0x93,0x14,0x92,0x10,0x91,0x0c,0x10,0x08,0x01,0xff,
+       0x75,0xcc,0x9b,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0xcf,0x86,0xd5,0xb4,
+       0xd4,0x24,0x53,0x04,0x01,0x00,0x52,0x04,0x01,0x00,0xd1,0x0c,0x10,0x04,0x01,0x00,
+       0x01,0xff,0x41,0xcc,0x8c,0x00,0x10,0x08,0x01,0xff,0x61,0xcc,0x8c,0x00,0x01,0xff,
+       0x49,0xcc,0x8c,0x00,0xd3,0x46,0xd2,0x20,0xd1,0x10,0x10,0x08,0x01,0xff,0x69,0xcc,
+       0x8c,0x00,0x01,0xff,0x4f,0xcc,0x8c,0x00,0x10,0x08,0x01,0xff,0x6f,0xcc,0x8c,0x00,
+       0x01,0xff,0x55,0xcc,0x8c,0x00,0xd1,0x12,0x10,0x08,0x01,0xff,0x75,0xcc,0x8c,0x00,
+       0x01,0xff,0x55,0xcc,0x88,0xcc,0x84,0x00,0x10,0x0a,0x01,0xff,0x75,0xcc,0x88,0xcc,
+       0x84,0x00,0x01,0xff,0x55,0xcc,0x88,0xcc,0x81,0x00,0xd2,0x28,0xd1,0x14,0x10,0x0a,
+       0x01,0xff,0x75,0xcc,0x88,0xcc,0x81,0x00,0x01,0xff,0x55,0xcc,0x88,0xcc,0x8c,0x00,
+       0x10,0x0a,0x01,0xff,0x75,0xcc,0x88,0xcc,0x8c,0x00,0x01,0xff,0x55,0xcc,0x88,0xcc,
+       0x80,0x00,0xd1,0x0e,0x10,0x0a,0x01,0xff,0x75,0xcc,0x88,0xcc,0x80,0x00,0x01,0x00,
+       0x10,0x0a,0x01,0xff,0x41,0xcc,0x88,0xcc,0x84,0x00,0x01,0xff,0x61,0xcc,0x88,0xcc,
+       0x84,0x00,0xd4,0x80,0xd3,0x3a,0xd2,0x26,0xd1,0x14,0x10,0x0a,0x01,0xff,0x41,0xcc,
+       0x87,0xcc,0x84,0x00,0x01,0xff,0x61,0xcc,0x87,0xcc,0x84,0x00,0x10,0x09,0x01,0xff,
+       0xc3,0x86,0xcc,0x84,0x00,0x01,0xff,0xc3,0xa6,0xcc,0x84,0x00,0x51,0x04,0x01,0x00,
+       0x10,0x08,0x01,0xff,0x47,0xcc,0x8c,0x00,0x01,0xff,0x67,0xcc,0x8c,0x00,0xd2,0x20,
+       0xd1,0x10,0x10,0x08,0x01,0xff,0x4b,0xcc,0x8c,0x00,0x01,0xff,0x6b,0xcc,0x8c,0x00,
+       0x10,0x08,0x01,0xff,0x4f,0xcc,0xa8,0x00,0x01,0xff,0x6f,0xcc,0xa8,0x00,0xd1,0x14,
+       0x10,0x0a,0x01,0xff,0x4f,0xcc,0xa8,0xcc,0x84,0x00,0x01,0xff,0x6f,0xcc,0xa8,0xcc,
+       0x84,0x00,0x10,0x09,0x01,0xff,0xc6,0xb7,0xcc,0x8c,0x00,0x01,0xff,0xca,0x92,0xcc,
+       0x8c,0x00,0xd3,0x24,0xd2,0x10,0x91,0x0c,0x10,0x08,0x01,0xff,0x6a,0xcc,0x8c,0x00,
+       0x01,0x00,0x01,0x00,0x91,0x10,0x10,0x08,0x01,0xff,0x47,0xcc,0x81,0x00,0x01,0xff,
+       0x67,0xcc,0x81,0x00,0x04,0x00,0xd2,0x24,0xd1,0x10,0x10,0x08,0x04,0xff,0x4e,0xcc,
+       0x80,0x00,0x04,0xff,0x6e,0xcc,0x80,0x00,0x10,0x0a,0x01,0xff,0x41,0xcc,0x8a,0xcc,
+       0x81,0x00,0x01,0xff,0x61,0xcc,0x8a,0xcc,0x81,0x00,0xd1,0x12,0x10,0x09,0x01,0xff,
+       0xc3,0x86,0xcc,0x81,0x00,0x01,0xff,0xc3,0xa6,0xcc,0x81,0x00,0x10,0x09,0x01,0xff,
+       0xc3,0x98,0xcc,0x81,0x00,0x01,0xff,0xc3,0xb8,0xcc,0x81,0x00,0xe2,0x07,0x02,0xe1,
+       0xae,0x01,0xe0,0x93,0x01,0xcf,0x86,0xd5,0xf4,0xd4,0x80,0xd3,0x40,0xd2,0x20,0xd1,
+       0x10,0x10,0x08,0x01,0xff,0x41,0xcc,0x8f,0x00,0x01,0xff,0x61,0xcc,0x8f,0x00,0x10,
+       0x08,0x01,0xff,0x41,0xcc,0x91,0x00,0x01,0xff,0x61,0xcc,0x91,0x00,0xd1,0x10,0x10,
+       0x08,0x01,0xff,0x45,0xcc,0x8f,0x00,0x01,0xff,0x65,0xcc,0x8f,0x00,0x10,0x08,0x01,
+       0xff,0x45,0xcc,0x91,0x00,0x01,0xff,0x65,0xcc,0x91,0x00,0xd2,0x20,0xd1,0x10,0x10,
+       0x08,0x01,0xff,0x49,0xcc,0x8f,0x00,0x01,0xff,0x69,0xcc,0x8f,0x00,0x10,0x08,0x01,
+       0xff,0x49,0xcc,0x91,0x00,0x01,0xff,0x69,0xcc,0x91,0x00,0xd1,0x10,0x10,0x08,0x01,
+       0xff,0x4f,0xcc,0x8f,0x00,0x01,0xff,0x6f,0xcc,0x8f,0x00,0x10,0x08,0x01,0xff,0x4f,
+       0xcc,0x91,0x00,0x01,0xff,0x6f,0xcc,0x91,0x00,0xd3,0x40,0xd2,0x20,0xd1,0x10,0x10,
+       0x08,0x01,0xff,0x52,0xcc,0x8f,0x00,0x01,0xff,0x72,0xcc,0x8f,0x00,0x10,0x08,0x01,
+       0xff,0x52,0xcc,0x91,0x00,0x01,0xff,0x72,0xcc,0x91,0x00,0xd1,0x10,0x10,0x08,0x01,
+       0xff,0x55,0xcc,0x8f,0x00,0x01,0xff,0x75,0xcc,0x8f,0x00,0x10,0x08,0x01,0xff,0x55,
+       0xcc,0x91,0x00,0x01,0xff,0x75,0xcc,0x91,0x00,0xd2,0x20,0xd1,0x10,0x10,0x08,0x04,
+       0xff,0x53,0xcc,0xa6,0x00,0x04,0xff,0x73,0xcc,0xa6,0x00,0x10,0x08,0x04,0xff,0x54,
+       0xcc,0xa6,0x00,0x04,0xff,0x74,0xcc,0xa6,0x00,0x51,0x04,0x04,0x00,0x10,0x08,0x04,
+       0xff,0x48,0xcc,0x8c,0x00,0x04,0xff,0x68,0xcc,0x8c,0x00,0xd4,0x68,0xd3,0x20,0xd2,
+       0x0c,0x91,0x08,0x10,0x04,0x06,0x00,0x07,0x00,0x04,0x00,0x51,0x04,0x04,0x00,0x10,
+       0x08,0x04,0xff,0x41,0xcc,0x87,0x00,0x04,0xff,0x61,0xcc,0x87,0x00,0xd2,0x24,0xd1,
+       0x10,0x10,0x08,0x04,0xff,0x45,0xcc,0xa7,0x00,0x04,0xff,0x65,0xcc,0xa7,0x00,0x10,
+       0x0a,0x04,0xff,0x4f,0xcc,0x88,0xcc,0x84,0x00,0x04,0xff,0x6f,0xcc,0x88,0xcc,0x84,
+       0x00,0xd1,0x14,0x10,0x0a,0x04,0xff,0x4f,0xcc,0x83,0xcc,0x84,0x00,0x04,0xff,0x6f,
+       0xcc,0x83,0xcc,0x84,0x00,0x10,0x08,0x04,0xff,0x4f,0xcc,0x87,0x00,0x04,0xff,0x6f,
+       0xcc,0x87,0x00,0x93,0x30,0xd2,0x24,0xd1,0x14,0x10,0x0a,0x04,0xff,0x4f,0xcc,0x87,
+       0xcc,0x84,0x00,0x04,0xff,0x6f,0xcc,0x87,0xcc,0x84,0x00,0x10,0x08,0x04,0xff,0x59,
+       0xcc,0x84,0x00,0x04,0xff,0x79,0xcc,0x84,0x00,0x51,0x04,0x07,0x00,0x10,0x04,0x07,
+       0x00,0x08,0x00,0x08,0x00,0xcf,0x86,0x95,0x14,0x94,0x10,0x93,0x0c,0x92,0x08,0x11,
+       0x04,0x08,0x00,0x09,0x00,0x09,0x00,0x09,0x00,0x01,0x00,0x01,0x00,0xd0,0x22,0xcf,
+       0x86,0x55,0x04,0x01,0x00,0x94,0x18,0x53,0x04,0x01,0x00,0xd2,0x0c,0x91,0x08,0x10,
+       0x04,0x01,0x00,0x04,0x00,0x04,0x00,0x11,0x04,0x04,0x00,0x07,0x00,0x01,0x00,0xcf,
+       0x86,0xd5,0x18,0x54,0x04,0x01,0x00,0x53,0x04,0x01,0x00,0x52,0x04,0x01,0x00,0x51,
+       0x04,0x01,0x00,0x10,0x04,0x01,0x00,0x04,0x00,0x94,0x18,0x53,0x04,0x01,0x00,0xd2,
+       0x08,0x11,0x04,0x01,0x00,0x04,0x00,0x51,0x04,0x04,0x00,0x10,0x04,0x04,0x00,0x07,
+       0x00,0x07,0x00,0xe1,0x34,0x01,0xd0,0x72,0xcf,0x86,0xd5,0x24,0x54,0x04,0x01,0xe6,
+       0xd3,0x10,0x52,0x04,0x01,0xe6,0x91,0x08,0x10,0x04,0x01,0xe6,0x01,0xe8,0x01,0xdc,
+       0x92,0x0c,0x51,0x04,0x01,0xdc,0x10,0x04,0x01,0xe8,0x01,0xd8,0x01,0xdc,0xd4,0x2c,
+       0xd3,0x1c,0xd2,0x10,0xd1,0x08,0x10,0x04,0x01,0xdc,0x01,0xca,0x10,0x04,0x01,0xca,
+       0x01,0xdc,0x51,0x04,0x01,0xdc,0x10,0x04,0x01,0xdc,0x01,0xca,0x92,0x0c,0x91,0x08,
+       0x10,0x04,0x01,0xca,0x01,0xdc,0x01,0xdc,0x01,0xdc,0xd3,0x08,0x12,0x04,0x01,0xdc,
+       0x01,0x01,0xd2,0x0c,0x91,0x08,0x10,0x04,0x01,0x01,0x01,0xdc,0x01,0xdc,0x91,0x08,
+       0x10,0x04,0x01,0xdc,0x01,0xe6,0x01,0xe6,0xcf,0x86,0xd5,0x7e,0xd4,0x46,0xd3,0x2e,
+       0xd2,0x19,0xd1,0x0e,0x10,0x07,0x01,0xff,0xcc,0x80,0x00,0x01,0xff,0xcc,0x81,0x00,
+       0x10,0x04,0x01,0xe6,0x01,0xff,0xcc,0x93,0x00,0xd1,0x0d,0x10,0x09,0x01,0xff,0xcc,
+       0x88,0xcc,0x81,0x00,0x01,0xf0,0x10,0x04,0x04,0xe6,0x04,0xdc,0xd2,0x08,0x11,0x04,
+       0x04,0xdc,0x04,0xe6,0xd1,0x08,0x10,0x04,0x04,0xe6,0x04,0xdc,0x10,0x04,0x04,0xdc,
+       0x06,0x00,0xd3,0x18,0xd2,0x0c,0x51,0x04,0x07,0xe6,0x10,0x04,0x07,0xe6,0x07,0xdc,
+       0x51,0x04,0x07,0xdc,0x10,0x04,0x07,0xdc,0x07,0xe6,0xd2,0x10,0xd1,0x08,0x10,0x04,
+       0x08,0xe8,0x08,0xdc,0x10,0x04,0x08,0xdc,0x08,0xe6,0xd1,0x08,0x10,0x04,0x08,0xe9,
+       0x07,0xea,0x10,0x04,0x07,0xea,0x07,0xe9,0xd4,0x14,0x93,0x10,0x92,0x0c,0x51,0x04,
+       0x01,0xea,0x10,0x04,0x04,0xe9,0x06,0xe6,0x06,0xe6,0x06,0xe6,0xd3,0x13,0x52,0x04,
+       0x0a,0x00,0x91,0x0b,0x10,0x07,0x01,0xff,0xca,0xb9,0x00,0x01,0x00,0x0a,0x00,0xd2,
+       0x0c,0x51,0x04,0x00,0x00,0x10,0x04,0x01,0x00,0x09,0x00,0x51,0x04,0x09,0x00,0x10,
+       0x06,0x01,0xff,0x3b,0x00,0x10,0x00,0xd0,0xe1,0xcf,0x86,0xd5,0x7a,0xd4,0x5f,0xd3,
+       0x21,0x52,0x04,0x00,0x00,0xd1,0x0d,0x10,0x04,0x01,0x00,0x01,0xff,0xc2,0xa8,0xcc,
+       0x81,0x00,0x10,0x09,0x01,0xff,0xce,0x91,0xcc,0x81,0x00,0x01,0xff,0xc2,0xb7,0x00,
+       0xd2,0x1f,0xd1,0x12,0x10,0x09,0x01,0xff,0xce,0x95,0xcc,0x81,0x00,0x01,0xff,0xce,
+       0x97,0xcc,0x81,0x00,0x10,0x09,0x01,0xff,0xce,0x99,0xcc,0x81,0x00,0x00,0x00,0xd1,
+       0x0d,0x10,0x09,0x01,0xff,0xce,0x9f,0xcc,0x81,0x00,0x00,0x00,0x10,0x09,0x01,0xff,
+       0xce,0xa5,0xcc,0x81,0x00,0x01,0xff,0xce,0xa9,0xcc,0x81,0x00,0x93,0x17,0x92,0x13,
+       0x91,0x0f,0x10,0x0b,0x01,0xff,0xce,0xb9,0xcc,0x88,0xcc,0x81,0x00,0x01,0x00,0x01,
+       0x00,0x01,0x00,0x01,0x00,0xd4,0x4a,0xd3,0x10,0x92,0x0c,0x51,0x04,0x01,0x00,0x10,
+       0x04,0x00,0x00,0x01,0x00,0x01,0x00,0xd2,0x16,0x51,0x04,0x01,0x00,0x10,0x09,0x01,
+       0xff,0xce,0x99,0xcc,0x88,0x00,0x01,0xff,0xce,0xa5,0xcc,0x88,0x00,0xd1,0x12,0x10,
+       0x09,0x01,0xff,0xce,0xb1,0xcc,0x81,0x00,0x01,0xff,0xce,0xb5,0xcc,0x81,0x00,0x10,
+       0x09,0x01,0xff,0xce,0xb7,0xcc,0x81,0x00,0x01,0xff,0xce,0xb9,0xcc,0x81,0x00,0x93,
+       0x17,0x92,0x13,0x91,0x0f,0x10,0x0b,0x01,0xff,0xcf,0x85,0xcc,0x88,0xcc,0x81,0x00,
+       0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0xcf,0x86,0xd5,0x7b,0xd4,0x39,0x53,0x04,
+       0x01,0x00,0xd2,0x16,0x51,0x04,0x01,0x00,0x10,0x09,0x01,0xff,0xce,0xb9,0xcc,0x88,
+       0x00,0x01,0xff,0xcf,0x85,0xcc,0x88,0x00,0xd1,0x12,0x10,0x09,0x01,0xff,0xce,0xbf,
+       0xcc,0x81,0x00,0x01,0xff,0xcf,0x85,0xcc,0x81,0x00,0x10,0x09,0x01,0xff,0xcf,0x89,
+       0xcc,0x81,0x00,0x0a,0x00,0xd3,0x26,0xd2,0x11,0x51,0x04,0x01,0x00,0x10,0x04,0x01,
+       0x00,0x01,0xff,0xcf,0x92,0xcc,0x81,0x00,0xd1,0x0d,0x10,0x09,0x01,0xff,0xcf,0x92,
+       0xcc,0x88,0x00,0x01,0x00,0x10,0x04,0x01,0x00,0x04,0x00,0xd2,0x0c,0x51,0x04,0x06,
+       0x00,0x10,0x04,0x01,0x00,0x04,0x00,0xd1,0x08,0x10,0x04,0x01,0x00,0x04,0x00,0x10,
+       0x04,0x01,0x00,0x04,0x00,0xd4,0x14,0x93,0x10,0x92,0x0c,0x91,0x08,0x10,0x04,0x01,
+       0x00,0x04,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0xd3,0x10,0x52,0x04,0x01,0x00,0x51,
+       0x04,0x05,0x00,0x10,0x04,0x06,0x00,0x07,0x00,0x12,0x04,0x07,0x00,0x08,0x00,0xe3,
+       0x47,0x04,0xe2,0xbe,0x02,0xe1,0x07,0x01,0xd0,0x8b,0xcf,0x86,0xd5,0x6c,0xd4,0x53,
+       0xd3,0x30,0xd2,0x1f,0xd1,0x12,0x10,0x09,0x04,0xff,0xd0,0x95,0xcc,0x80,0x00,0x01,
+       0xff,0xd0,0x95,0xcc,0x88,0x00,0x10,0x04,0x01,0x00,0x01,0xff,0xd0,0x93,0xcc,0x81,
+       0x00,0x51,0x04,0x01,0x00,0x10,0x04,0x01,0x00,0x01,0xff,0xd0,0x86,0xcc,0x88,0x00,
+       0x52,0x04,0x01,0x00,0xd1,0x12,0x10,0x09,0x01,0xff,0xd0,0x9a,0xcc,0x81,0x00,0x04,
+       0xff,0xd0,0x98,0xcc,0x80,0x00,0x10,0x09,0x01,0xff,0xd0,0xa3,0xcc,0x86,0x00,0x01,
+       0x00,0x53,0x04,0x01,0x00,0x92,0x11,0x91,0x0d,0x10,0x04,0x01,0x00,0x01,0xff,0xd0,
+       0x98,0xcc,0x86,0x00,0x01,0x00,0x01,0x00,0x54,0x04,0x01,0x00,0x53,0x04,0x01,0x00,
+       0x92,0x11,0x91,0x0d,0x10,0x04,0x01,0x00,0x01,0xff,0xd0,0xb8,0xcc,0x86,0x00,0x01,
+       0x00,0x01,0x00,0xcf,0x86,0xd5,0x57,0x54,0x04,0x01,0x00,0xd3,0x30,0xd2,0x1f,0xd1,
+       0x12,0x10,0x09,0x04,0xff,0xd0,0xb5,0xcc,0x80,0x00,0x01,0xff,0xd0,0xb5,0xcc,0x88,
+       0x00,0x10,0x04,0x01,0x00,0x01,0xff,0xd0,0xb3,0xcc,0x81,0x00,0x51,0x04,0x01,0x00,
+       0x10,0x04,0x01,0x00,0x01,0xff,0xd1,0x96,0xcc,0x88,0x00,0x52,0x04,0x01,0x00,0xd1,
+       0x12,0x10,0x09,0x01,0xff,0xd0,0xba,0xcc,0x81,0x00,0x04,0xff,0xd0,0xb8,0xcc,0x80,
+       0x00,0x10,0x09,0x01,0xff,0xd1,0x83,0xcc,0x86,0x00,0x01,0x00,0x54,0x04,0x01,0x00,
+       0x93,0x1a,0x52,0x04,0x01,0x00,0x51,0x04,0x01,0x00,0x10,0x09,0x01,0xff,0xd1,0xb4,
+       0xcc,0x8f,0x00,0x01,0xff,0xd1,0xb5,0xcc,0x8f,0x00,0x01,0x00,0xd0,0x2e,0xcf,0x86,
+       0x95,0x28,0x94,0x24,0xd3,0x18,0xd2,0x0c,0x51,0x04,0x01,0x00,0x10,0x04,0x01,0x00,
+       0x01,0xe6,0x51,0x04,0x01,0xe6,0x10,0x04,0x01,0xe6,0x0a,0xe6,0x92,0x08,0x11,0x04,
+       0x04,0x00,0x06,0x00,0x04,0x00,0x01,0x00,0x01,0x00,0xcf,0x86,0xd5,0xbe,0xd4,0x4a,
+       0xd3,0x2a,0xd2,0x1a,0xd1,0x0d,0x10,0x04,0x01,0x00,0x01,0xff,0xd0,0x96,0xcc,0x86,
+       0x00,0x10,0x09,0x01,0xff,0xd0,0xb6,0xcc,0x86,0x00,0x01,0x00,0xd1,0x08,0x10,0x04,
+       0x01,0x00,0x06,0x00,0x10,0x04,0x06,0x00,0x01,0x00,0xd2,0x10,0xd1,0x08,0x10,0x04,
+       0x01,0x00,0x06,0x00,0x10,0x04,0x06,0x00,0x01,0x00,0xd1,0x08,0x10,0x04,0x01,0x00,
+       0x06,0x00,0x10,0x04,0x06,0x00,0x09,0x00,0xd3,0x3a,0xd2,0x24,0xd1,0x12,0x10,0x09,
+       0x01,0xff,0xd0,0x90,0xcc,0x86,0x00,0x01,0xff,0xd0,0xb0,0xcc,0x86,0x00,0x10,0x09,
+       0x01,0xff,0xd0,0x90,0xcc,0x88,0x00,0x01,0xff,0xd0,0xb0,0xcc,0x88,0x00,0x51,0x04,
+       0x01,0x00,0x10,0x09,0x01,0xff,0xd0,0x95,0xcc,0x86,0x00,0x01,0xff,0xd0,0xb5,0xcc,
+       0x86,0x00,0xd2,0x16,0x51,0x04,0x01,0x00,0x10,0x09,0x01,0xff,0xd3,0x98,0xcc,0x88,
+       0x00,0x01,0xff,0xd3,0x99,0xcc,0x88,0x00,0xd1,0x12,0x10,0x09,0x01,0xff,0xd0,0x96,
+       0xcc,0x88,0x00,0x01,0xff,0xd0,0xb6,0xcc,0x88,0x00,0x10,0x09,0x01,0xff,0xd0,0x97,
+       0xcc,0x88,0x00,0x01,0xff,0xd0,0xb7,0xcc,0x88,0x00,0xd4,0x74,0xd3,0x3a,0xd2,0x16,
+       0x51,0x04,0x01,0x00,0x10,0x09,0x01,0xff,0xd0,0x98,0xcc,0x84,0x00,0x01,0xff,0xd0,
+       0xb8,0xcc,0x84,0x00,0xd1,0x12,0x10,0x09,0x01,0xff,0xd0,0x98,0xcc,0x88,0x00,0x01,
+       0xff,0xd0,0xb8,0xcc,0x88,0x00,0x10,0x09,0x01,0xff,0xd0,0x9e,0xcc,0x88,0x00,0x01,
+       0xff,0xd0,0xbe,0xcc,0x88,0x00,0xd2,0x16,0x51,0x04,0x01,0x00,0x10,0x09,0x01,0xff,
+       0xd3,0xa8,0xcc,0x88,0x00,0x01,0xff,0xd3,0xa9,0xcc,0x88,0x00,0xd1,0x12,0x10,0x09,
+       0x04,0xff,0xd0,0xad,0xcc,0x88,0x00,0x04,0xff,0xd1,0x8d,0xcc,0x88,0x00,0x10,0x09,
+       0x01,0xff,0xd0,0xa3,0xcc,0x84,0x00,0x01,0xff,0xd1,0x83,0xcc,0x84,0x00,0xd3,0x3a,
+       0xd2,0x24,0xd1,0x12,0x10,0x09,0x01,0xff,0xd0,0xa3,0xcc,0x88,0x00,0x01,0xff,0xd1,
+       0x83,0xcc,0x88,0x00,0x10,0x09,0x01,0xff,0xd0,0xa3,0xcc,0x8b,0x00,0x01,0xff,0xd1,
+       0x83,0xcc,0x8b,0x00,0x91,0x12,0x10,0x09,0x01,0xff,0xd0,0xa7,0xcc,0x88,0x00,0x01,
+       0xff,0xd1,0x87,0xcc,0x88,0x00,0x08,0x00,0x92,0x16,0x91,0x12,0x10,0x09,0x01,0xff,
+       0xd0,0xab,0xcc,0x88,0x00,0x01,0xff,0xd1,0x8b,0xcc,0x88,0x00,0x09,0x00,0x09,0x00,
+       0xd1,0x74,0xd0,0x36,0xcf,0x86,0xd5,0x10,0x54,0x04,0x06,0x00,0x93,0x08,0x12,0x04,
+       0x09,0x00,0x0a,0x00,0x0a,0x00,0xd4,0x10,0x93,0x0c,0x52,0x04,0x0a,0x00,0x11,0x04,
+       0x0b,0x00,0x0c,0x00,0x10,0x00,0x93,0x10,0x92,0x0c,0x91,0x08,0x10,0x04,0x00,0x00,
+       0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0xcf,0x86,0xd5,0x24,0x54,0x04,0x01,0x00,
+       0xd3,0x10,0x52,0x04,0x01,0x00,0x51,0x04,0x01,0x00,0x10,0x04,0x01,0x00,0x00,0x00,
+       0x92,0x0c,0x91,0x08,0x10,0x04,0x00,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x94,0x14,
+       0x93,0x10,0x92,0x0c,0x91,0x08,0x10,0x04,0x14,0x00,0x01,0x00,0x01,0x00,0x01,0x00,
+       0x01,0x00,0x01,0x00,0xd0,0xba,0xcf,0x86,0xd5,0x4c,0xd4,0x24,0x53,0x04,0x01,0x00,
+       0xd2,0x10,0xd1,0x08,0x10,0x04,0x14,0x00,0x01,0x00,0x10,0x04,0x04,0x00,0x00,0x00,
+       0xd1,0x08,0x10,0x04,0x00,0x00,0x10,0x00,0x10,0x04,0x10,0x00,0x0d,0x00,0xd3,0x18,
+       0xd2,0x0c,0x91,0x08,0x10,0x04,0x00,0x00,0x02,0xdc,0x02,0xe6,0x51,0x04,0x02,0xe6,
+       0x10,0x04,0x02,0xdc,0x02,0xe6,0x92,0x0c,0x51,0x04,0x02,0xe6,0x10,0x04,0x02,0xde,
+       0x02,0xdc,0x02,0xe6,0xd4,0x2c,0xd3,0x10,0x92,0x0c,0x51,0x04,0x02,0xe6,0x10,0x04,
+       0x08,0xdc,0x02,0xdc,0x02,0xdc,0xd2,0x0c,0x51,0x04,0x02,0xe6,0x10,0x04,0x02,0xdc,
+       0x02,0xe6,0xd1,0x08,0x10,0x04,0x02,0xe6,0x02,0xde,0x10,0x04,0x02,0xe4,0x02,0xe6,
+       0xd3,0x20,0xd2,0x10,0xd1,0x08,0x10,0x04,0x01,0x0a,0x01,0x0b,0x10,0x04,0x01,0x0c,
+       0x01,0x0d,0xd1,0x08,0x10,0x04,0x01,0x0e,0x01,0x0f,0x10,0x04,0x01,0x10,0x01,0x11,
+       0xd2,0x10,0xd1,0x08,0x10,0x04,0x01,0x12,0x01,0x13,0x10,0x04,0x09,0x13,0x01,0x14,
+       0xd1,0x08,0x10,0x04,0x01,0x15,0x01,0x16,0x10,0x04,0x01,0x00,0x01,0x17,0xcf,0x86,
+       0xd5,0x28,0x94,0x24,0x93,0x20,0xd2,0x10,0xd1,0x08,0x10,0x04,0x01,0x00,0x01,0x18,
+       0x10,0x04,0x01,0x19,0x01,0x00,0xd1,0x08,0x10,0x04,0x02,0xe6,0x08,0xdc,0x10,0x04,
+       0x08,0x00,0x08,0x12,0x00,0x00,0x01,0x00,0xd4,0x1c,0x53,0x04,0x01,0x00,0xd2,0x0c,
+       0x51,0x04,0x01,0x00,0x10,0x04,0x01,0x00,0x00,0x00,0x51,0x04,0x00,0x00,0x10,0x04,
+       0x00,0x00,0x14,0x00,0x93,0x10,0x52,0x04,0x01,0x00,0x91,0x08,0x10,0x04,0x01,0x00,
+       0x00,0x00,0x00,0x00,0x00,0x00,0xe2,0xfa,0x01,0xe1,0x2a,0x01,0xd0,0xa7,0xcf,0x86,
+       0xd5,0x54,0xd4,0x28,0xd3,0x10,0x52,0x04,0x07,0x00,0x91,0x08,0x10,0x04,0x0d,0x00,
+       0x10,0x00,0x0a,0x00,0xd2,0x0c,0x51,0x04,0x0a,0x00,0x10,0x04,0x0a,0x00,0x08,0x00,
+       0x91,0x08,0x10,0x04,0x01,0x00,0x07,0x00,0x07,0x00,0xd3,0x0c,0x52,0x04,0x07,0xe6,
+       0x11,0x04,0x07,0xe6,0x0a,0xe6,0xd2,0x10,0xd1,0x08,0x10,0x04,0x0a,0x1e,0x0a,0x1f,
+       0x10,0x04,0x0a,0x20,0x01,0x00,0xd1,0x08,0x10,0x04,0x0f,0x00,0x00,0x00,0x10,0x04,
+       0x08,0x00,0x01,0x00,0xd4,0x3d,0x93,0x39,0xd2,0x1a,0xd1,0x08,0x10,0x04,0x0c,0x00,
+       0x01,0x00,0x10,0x09,0x01,0xff,0xd8,0xa7,0xd9,0x93,0x00,0x01,0xff,0xd8,0xa7,0xd9,
+       0x94,0x00,0xd1,0x12,0x10,0x09,0x01,0xff,0xd9,0x88,0xd9,0x94,0x00,0x01,0xff,0xd8,
+       0xa7,0xd9,0x95,0x00,0x10,0x09,0x01,0xff,0xd9,0x8a,0xd9,0x94,0x00,0x01,0x00,0x01,
+       0x00,0x53,0x04,0x01,0x00,0x92,0x0c,0x51,0x04,0x01,0x00,0x10,0x04,0x01,0x00,0x0a,
+       0x00,0x0a,0x00,0xcf,0x86,0xd5,0x5c,0xd4,0x20,0x53,0x04,0x01,0x00,0xd2,0x0c,0x51,
+       0x04,0x01,0x00,0x10,0x04,0x01,0x00,0x01,0x1b,0xd1,0x08,0x10,0x04,0x01,0x1c,0x01,
+       0x1d,0x10,0x04,0x01,0x1e,0x01,0x1f,0xd3,0x20,0xd2,0x10,0xd1,0x08,0x10,0x04,0x01,
+       0x20,0x01,0x21,0x10,0x04,0x01,0x22,0x04,0xe6,0xd1,0x08,0x10,0x04,0x04,0xe6,0x04,
+       0xdc,0x10,0x04,0x07,0xdc,0x07,0xe6,0xd2,0x0c,0x91,0x08,0x10,0x04,0x07,0xe6,0x08,
+       0xe6,0x08,0xe6,0xd1,0x08,0x10,0x04,0x08,0xdc,0x08,0xe6,0x10,0x04,0x08,0xe6,0x0c,
+       0xdc,0xd4,0x10,0x53,0x04,0x01,0x00,0x52,0x04,0x01,0x00,0x11,0x04,0x01,0x00,0x06,
+       0x00,0x93,0x10,0x92,0x0c,0x91,0x08,0x10,0x04,0x01,0x23,0x01,0x00,0x01,0x00,0x01,
+       0x00,0x01,0x00,0xd0,0x22,0xcf,0x86,0x55,0x04,0x01,0x00,0x54,0x04,0x01,0x00,0x53,
+       0x04,0x01,0x00,0xd2,0x08,0x11,0x04,0x04,0x00,0x01,0x00,0x51,0x04,0x01,0x00,0x10,
+       0x04,0x01,0x00,0x04,0x00,0xcf,0x86,0xd5,0x5b,0xd4,0x2e,0xd3,0x1e,0x92,0x1a,0xd1,
+       0x0d,0x10,0x09,0x01,0xff,0xdb,0x95,0xd9,0x94,0x00,0x01,0x00,0x10,0x09,0x01,0xff,
+       0xdb,0x81,0xd9,0x94,0x00,0x01,0x00,0x01,0x00,0x52,0x04,0x01,0x00,0x51,0x04,0x01,
+       0x00,0x10,0x04,0x01,0x00,0x04,0x00,0xd3,0x19,0xd2,0x11,0x51,0x04,0x01,0x00,0x10,
+       0x04,0x01,0x00,0x01,0xff,0xdb,0x92,0xd9,0x94,0x00,0x11,0x04,0x01,0x00,0x01,0xe6,
+       0x52,0x04,0x01,0xe6,0xd1,0x08,0x10,0x04,0x01,0xe6,0x01,0x00,0x10,0x04,0x01,0x00,
+       0x01,0xe6,0xd4,0x38,0xd3,0x1c,0xd2,0x0c,0x51,0x04,0x01,0xe6,0x10,0x04,0x01,0xe6,
+       0x01,0xdc,0xd1,0x08,0x10,0x04,0x01,0xe6,0x01,0x00,0x10,0x04,0x01,0x00,0x01,0xe6,
+       0xd2,0x10,0xd1,0x08,0x10,0x04,0x01,0xe6,0x01,0x00,0x10,0x04,0x01,0xdc,0x01,0xe6,
+       0x91,0x08,0x10,0x04,0x01,0xe6,0x01,0xdc,0x07,0x00,0x53,0x04,0x01,0x00,0xd2,0x08,
+       0x11,0x04,0x01,0x00,0x04,0x00,0x51,0x04,0x04,0x00,0x10,0x04,0x04,0x00,0x07,0x00,
+       0xd1,0xc8,0xd0,0x76,0xcf,0x86,0xd5,0x28,0xd4,0x14,0x53,0x04,0x04,0x00,0x52,0x04,
+       0x04,0x00,0x51,0x04,0x04,0x00,0x10,0x04,0x00,0x00,0x04,0x00,0x93,0x10,0x92,0x0c,
+       0x91,0x08,0x10,0x04,0x04,0x00,0x04,0x24,0x04,0x00,0x04,0x00,0x04,0x00,0xd4,0x14,
+       0x53,0x04,0x04,0x00,0x52,0x04,0x04,0x00,0x91,0x08,0x10,0x04,0x04,0x00,0x07,0x00,
+       0x07,0x00,0xd3,0x1c,0xd2,0x0c,0x91,0x08,0x10,0x04,0x04,0xe6,0x04,0xdc,0x04,0xe6,
+       0xd1,0x08,0x10,0x04,0x04,0xdc,0x04,0xe6,0x10,0x04,0x04,0xe6,0x04,0xdc,0xd2,0x0c,
+       0x51,0x04,0x04,0xdc,0x10,0x04,0x04,0xe6,0x04,0xdc,0xd1,0x08,0x10,0x04,0x04,0xdc,
+       0x04,0xe6,0x10,0x04,0x04,0xdc,0x04,0xe6,0xcf,0x86,0xd5,0x3c,0x94,0x38,0xd3,0x1c,
+       0xd2,0x0c,0x51,0x04,0x04,0xe6,0x10,0x04,0x04,0xdc,0x04,0xe6,0xd1,0x08,0x10,0x04,
+       0x04,0xdc,0x04,0xe6,0x10,0x04,0x04,0xdc,0x04,0xe6,0xd2,0x10,0xd1,0x08,0x10,0x04,
+       0x04,0xdc,0x04,0xe6,0x10,0x04,0x04,0xe6,0x00,0x00,0x91,0x08,0x10,0x04,0x00,0x00,
+       0x07,0x00,0x07,0x00,0x08,0x00,0x94,0x10,0x53,0x04,0x08,0x00,0x52,0x04,0x08,0x00,
+       0x11,0x04,0x08,0x00,0x0a,0x00,0x0a,0x00,0xd0,0x1e,0xcf,0x86,0x55,0x04,0x04,0x00,
+       0x54,0x04,0x04,0x00,0x93,0x10,0x92,0x0c,0x91,0x08,0x10,0x04,0x04,0x00,0x06,0x00,
+       0x00,0x00,0x00,0x00,0x00,0x00,0xcf,0x86,0x55,0x04,0x09,0x00,0xd4,0x14,0x53,0x04,
+       0x09,0x00,0x92,0x0c,0x51,0x04,0x09,0x00,0x10,0x04,0x09,0x00,0x09,0xe6,0x09,0xe6,
+       0xd3,0x10,0x92,0x0c,0x51,0x04,0x09,0xe6,0x10,0x04,0x09,0xdc,0x09,0xe6,0x09,0x00,
+       0xd2,0x0c,0x51,0x04,0x09,0x00,0x10,0x04,0x09,0x00,0x00,0x00,0x91,0x08,0x10,0x04,
+       0x00,0x00,0x14,0xdc,0x14,0x00,0xe4,0x78,0x57,0xe3,0xda,0x3e,0xe2,0x89,0x3e,0xe1,
+       0x91,0x2c,0xe0,0x21,0x10,0xcf,0x86,0xc5,0xe4,0x80,0x08,0xe3,0xcb,0x03,0xe2,0x61,
+       0x01,0xd1,0x94,0xd0,0x5a,0xcf,0x86,0xd5,0x20,0x54,0x04,0x0b,0x00,0xd3,0x0c,0x52,
+       0x04,0x0b,0x00,0x11,0x04,0x0b,0x00,0x0b,0xe6,0x92,0x0c,0x51,0x04,0x0b,0xe6,0x10,
+       0x04,0x0b,0x00,0x0b,0xe6,0x0b,0xe6,0xd4,0x24,0xd3,0x10,0x52,0x04,0x0b,0xe6,0x91,
+       0x08,0x10,0x04,0x0b,0x00,0x0b,0xe6,0x0b,0xe6,0xd2,0x0c,0x91,0x08,0x10,0x04,0x0b,
+       0x00,0x0b,0xe6,0x0b,0xe6,0x11,0x04,0x0b,0xe6,0x00,0x00,0x53,0x04,0x0b,0x00,0x52,
+       0x04,0x0b,0x00,0x51,0x04,0x0b,0x00,0x10,0x04,0x0b,0x00,0x00,0x00,0xcf,0x86,0xd5,
+       0x20,0x54,0x04,0x0c,0x00,0x53,0x04,0x0c,0x00,0xd2,0x0c,0x91,0x08,0x10,0x04,0x0c,
+       0x00,0x0c,0xdc,0x0c,0xdc,0x51,0x04,0x00,0x00,0x10,0x04,0x0c,0x00,0x00,0x00,0x94,
+       0x14,0x53,0x04,0x13,0x00,0x92,0x0c,0x51,0x04,0x13,0x00,0x10,0x04,0x13,0x00,0x00,
+       0x00,0x00,0x00,0x00,0x00,0xd0,0x4a,0xcf,0x86,0x55,0x04,0x00,0x00,0xd4,0x20,0xd3,
+       0x10,0x92,0x0c,0x91,0x08,0x10,0x04,0x0d,0x00,0x10,0x00,0x0d,0x00,0x0d,0x00,0x52,
+       0x04,0x0d,0x00,0x91,0x08,0x10,0x04,0x0d,0x00,0x10,0x00,0x10,0x00,0xd3,0x18,0xd2,
+       0x0c,0x51,0x04,0x10,0x00,0x10,0x04,0x10,0x00,0x11,0x00,0x91,0x08,0x10,0x04,0x11,
+       0x00,0x00,0x00,0x12,0x00,0x52,0x04,0x12,0x00,0x11,0x04,0x12,0x00,0x00,0x00,0xcf,
+       0x86,0xd5,0x18,0x54,0x04,0x00,0x00,0x93,0x10,0x92,0x0c,0x51,0x04,0x00,0x00,0x10,
+       0x04,0x00,0x00,0x14,0xdc,0x12,0xe6,0x12,0xe6,0xd4,0x30,0xd3,0x18,0xd2,0x0c,0x51,
+       0x04,0x12,0xe6,0x10,0x04,0x12,0x00,0x11,0xdc,0x51,0x04,0x0d,0xe6,0x10,0x04,0x0d,
+       0xdc,0x0d,0xe6,0xd2,0x0c,0x91,0x08,0x10,0x04,0x0d,0xe6,0x0d,0xdc,0x0d,0xe6,0x91,
+       0x08,0x10,0x04,0x0d,0xe6,0x0d,0xdc,0x0d,0xdc,0xd3,0x1c,0xd2,0x10,0xd1,0x08,0x10,
+       0x04,0x0d,0x1b,0x0d,0x1c,0x10,0x04,0x0d,0x1d,0x0d,0xe6,0x51,0x04,0x0d,0xe6,0x10,
+       0x04,0x0d,0xdc,0x0d,0xe6,0xd2,0x10,0xd1,0x08,0x10,0x04,0x0d,0xe6,0x0d,0xdc,0x10,
+       0x04,0x0d,0xdc,0x0d,0xe6,0x51,0x04,0x0d,0xe6,0x10,0x04,0x0d,0xe6,0x10,0xe6,0xe1,
+       0x3a,0x01,0xd0,0x77,0xcf,0x86,0xd5,0x20,0x94,0x1c,0x93,0x18,0xd2,0x0c,0x91,0x08,
+       0x10,0x04,0x0b,0x00,0x01,0x00,0x01,0x00,0x91,0x08,0x10,0x04,0x07,0x00,0x01,0x00,
+       0x01,0x00,0x01,0x00,0x01,0x00,0xd4,0x1b,0x53,0x04,0x01,0x00,0x92,0x13,0x91,0x0f,
+       0x10,0x04,0x01,0x00,0x01,0xff,0xe0,0xa4,0xa8,0xe0,0xa4,0xbc,0x00,0x01,0x00,0x01,
+       0x00,0xd3,0x26,0xd2,0x13,0x91,0x0f,0x10,0x04,0x01,0x00,0x01,0xff,0xe0,0xa4,0xb0,
+       0xe0,0xa4,0xbc,0x00,0x01,0x00,0x91,0x0f,0x10,0x0b,0x01,0xff,0xe0,0xa4,0xb3,0xe0,
+       0xa4,0xbc,0x00,0x01,0x00,0x01,0x00,0xd2,0x08,0x11,0x04,0x01,0x00,0x0c,0x00,0x91,
+       0x08,0x10,0x04,0x01,0x07,0x01,0x00,0x01,0x00,0xcf,0x86,0xd5,0x8c,0xd4,0x18,0x53,
+       0x04,0x01,0x00,0x52,0x04,0x01,0x00,0xd1,0x08,0x10,0x04,0x01,0x00,0x01,0x09,0x10,
+       0x04,0x0b,0x00,0x0c,0x00,0xd3,0x1c,0xd2,0x10,0xd1,0x08,0x10,0x04,0x01,0x00,0x01,
+       0xe6,0x10,0x04,0x01,0xdc,0x01,0xe6,0x91,0x08,0x10,0x04,0x01,0xe6,0x0b,0x00,0x0c,
+       0x00,0xd2,0x2c,0xd1,0x16,0x10,0x0b,0x01,0xff,0xe0,0xa4,0x95,0xe0,0xa4,0xbc,0x00,
+       0x01,0xff,0xe0,0xa4,0x96,0xe0,0xa4,0xbc,0x00,0x10,0x0b,0x01,0xff,0xe0,0xa4,0x97,
+       0xe0,0xa4,0xbc,0x00,0x01,0xff,0xe0,0xa4,0x9c,0xe0,0xa4,0xbc,0x00,0xd1,0x16,0x10,
+       0x0b,0x01,0xff,0xe0,0xa4,0xa1,0xe0,0xa4,0xbc,0x00,0x01,0xff,0xe0,0xa4,0xa2,0xe0,
+       0xa4,0xbc,0x00,0x10,0x0b,0x01,0xff,0xe0,0xa4,0xab,0xe0,0xa4,0xbc,0x00,0x01,0xff,
+       0xe0,0xa4,0xaf,0xe0,0xa4,0xbc,0x00,0x54,0x04,0x01,0x00,0xd3,0x14,0x92,0x10,0xd1,
+       0x08,0x10,0x04,0x01,0x00,0x0a,0x00,0x10,0x04,0x0a,0x00,0x0c,0x00,0x0c,0x00,0xd2,
+       0x10,0xd1,0x08,0x10,0x04,0x10,0x00,0x0b,0x00,0x10,0x04,0x0b,0x00,0x09,0x00,0x91,
+       0x08,0x10,0x04,0x09,0x00,0x08,0x00,0x09,0x00,0xd0,0x86,0xcf,0x86,0xd5,0x44,0xd4,
+       0x2c,0xd3,0x18,0xd2,0x0c,0x91,0x08,0x10,0x04,0x10,0x00,0x01,0x00,0x01,0x00,0x91,
+       0x08,0x10,0x04,0x00,0x00,0x01,0x00,0x01,0x00,0x52,0x04,0x01,0x00,0xd1,0x08,0x10,
+       0x04,0x01,0x00,0x00,0x00,0x10,0x04,0x00,0x00,0x01,0x00,0x93,0x14,0x92,0x10,0xd1,
+       0x08,0x10,0x04,0x01,0x00,0x00,0x00,0x10,0x04,0x00,0x00,0x01,0x00,0x01,0x00,0x01,
+       0x00,0xd4,0x14,0x53,0x04,0x01,0x00,0x92,0x0c,0x91,0x08,0x10,0x04,0x01,0x00,0x00,
+       0x00,0x01,0x00,0x01,0x00,0xd3,0x18,0xd2,0x10,0xd1,0x08,0x10,0x04,0x01,0x00,0x00,
+       0x00,0x10,0x04,0x01,0x00,0x00,0x00,0x11,0x04,0x00,0x00,0x01,0x00,0xd2,0x08,0x11,
+       0x04,0x01,0x00,0x00,0x00,0x91,0x08,0x10,0x04,0x01,0x07,0x07,0x00,0x01,0x00,0xcf,
+       0x86,0xd5,0x7b,0xd4,0x42,0xd3,0x14,0x52,0x04,0x01,0x00,0xd1,0x08,0x10,0x04,0x01,
+       0x00,0x00,0x00,0x10,0x04,0x00,0x00,0x01,0x00,0xd2,0x17,0xd1,0x08,0x10,0x04,0x01,
+       0x00,0x00,0x00,0x10,0x04,0x00,0x00,0x01,0xff,0xe0,0xa7,0x87,0xe0,0xa6,0xbe,0x00,
+       0xd1,0x0f,0x10,0x0b,0x01,0xff,0xe0,0xa7,0x87,0xe0,0xa7,0x97,0x00,0x01,0x09,0x10,
+       0x04,0x08,0x00,0x00,0x00,0xd3,0x10,0x52,0x04,0x00,0x00,0x51,0x04,0x00,0x00,0x10,
+       0x04,0x00,0x00,0x01,0x00,0x52,0x04,0x00,0x00,0xd1,0x16,0x10,0x0b,0x01,0xff,0xe0,
+       0xa6,0xa1,0xe0,0xa6,0xbc,0x00,0x01,0xff,0xe0,0xa6,0xa2,0xe0,0xa6,0xbc,0x00,0x10,
+       0x04,0x00,0x00,0x01,0xff,0xe0,0xa6,0xaf,0xe0,0xa6,0xbc,0x00,0xd4,0x10,0x93,0x0c,
+       0x52,0x04,0x01,0x00,0x11,0x04,0x00,0x00,0x01,0x00,0x01,0x00,0x53,0x04,0x01,0x00,
+       0xd2,0x0c,0x51,0x04,0x01,0x00,0x10,0x04,0x01,0x00,0x0b,0x00,0x51,0x04,0x13,0x00,
+       0x10,0x04,0x14,0xe6,0x00,0x00,0xe2,0x48,0x02,0xe1,0x4f,0x01,0xd0,0xa4,0xcf,0x86,
+       0xd5,0x4c,0xd4,0x34,0xd3,0x1c,0xd2,0x10,0xd1,0x08,0x10,0x04,0x00,0x00,0x07,0x00,
+       0x10,0x04,0x01,0x00,0x07,0x00,0x91,0x08,0x10,0x04,0x00,0x00,0x01,0x00,0x01,0x00,
+       0xd2,0x0c,0x51,0x04,0x01,0x00,0x10,0x04,0x01,0x00,0x00,0x00,0x51,0x04,0x00,0x00,
        0x10,0x04,0x00,0x00,0x01,0x00,0x93,0x14,0x92,0x10,0xd1,0x08,0x10,0x04,0x01,0x00,
        0x00,0x00,0x10,0x04,0x00,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0xd4,0x14,0x53,0x04,
        0x01,0x00,0x92,0x0c,0x91,0x08,0x10,0x04,0x01,0x00,0x00,0x00,0x01,0x00,0x01,0x00,
-       0xd3,0x18,0xd2,0x10,0xd1,0x08,0x10,0x04,0x01,0x00,0x00,0x00,0x10,0x04,0x01,0x00,
-       0x00,0x00,0x11,0x04,0x00,0x00,0x01,0x00,0xd2,0x08,0x11,0x04,0x01,0x00,0x00,0x00,
-       0x91,0x08,0x10,0x04,0x01,0x07,0x07,0x00,0x01,0x00,0xcf,0x86,0xd5,0x7b,0xd4,0x42,
-       0xd3,0x14,0x52,0x04,0x01,0x00,0xd1,0x08,0x10,0x04,0x01,0x00,0x00,0x00,0x10,0x04,
-       0x00,0x00,0x01,0x00,0xd2,0x17,0xd1,0x08,0x10,0x04,0x01,0x00,0x00,0x00,0x10,0x04,
-       0x00,0x00,0x01,0xff,0xe0,0xa7,0x87,0xe0,0xa6,0xbe,0x00,0xd1,0x0f,0x10,0x0b,0x01,
-       0xff,0xe0,0xa7,0x87,0xe0,0xa7,0x97,0x00,0x01,0x09,0x10,0x04,0x08,0x00,0x00,0x00,
-       0xd3,0x10,0x52,0x04,0x00,0x00,0x51,0x04,0x00,0x00,0x10,0x04,0x00,0x00,0x01,0x00,
-       0x52,0x04,0x00,0x00,0xd1,0x16,0x10,0x0b,0x01,0xff,0xe0,0xa6,0xa1,0xe0,0xa6,0xbc,
-       0x00,0x01,0xff,0xe0,0xa6,0xa2,0xe0,0xa6,0xbc,0x00,0x10,0x04,0x00,0x00,0x01,0xff,
-       0xe0,0xa6,0xaf,0xe0,0xa6,0xbc,0x00,0xd4,0x10,0x93,0x0c,0x52,0x04,0x01,0x00,0x11,
-       0x04,0x00,0x00,0x01,0x00,0x01,0x00,0x53,0x04,0x01,0x00,0xd2,0x0c,0x51,0x04,0x01,
-       0x00,0x10,0x04,0x01,0x00,0x0b,0x00,0x51,0x04,0x13,0x00,0x10,0x04,0x14,0xe6,0x00,
-       0x00,0xe2,0x48,0x02,0xe1,0x4f,0x01,0xd0,0xa4,0xcf,0x86,0xd5,0x4c,0xd4,0x34,0xd3,
-       0x1c,0xd2,0x10,0xd1,0x08,0x10,0x04,0x00,0x00,0x07,0x00,0x10,0x04,0x01,0x00,0x07,
-       0x00,0x91,0x08,0x10,0x04,0x00,0x00,0x01,0x00,0x01,0x00,0xd2,0x0c,0x51,0x04,0x01,
-       0x00,0x10,0x04,0x01,0x00,0x00,0x00,0x51,0x04,0x00,0x00,0x10,0x04,0x00,0x00,0x01,
-       0x00,0x93,0x14,0x92,0x10,0xd1,0x08,0x10,0x04,0x01,0x00,0x00,0x00,0x10,0x04,0x00,
-       0x00,0x01,0x00,0x01,0x00,0x01,0x00,0xd4,0x14,0x53,0x04,0x01,0x00,0x92,0x0c,0x91,
-       0x08,0x10,0x04,0x01,0x00,0x00,0x00,0x01,0x00,0x01,0x00,0xd3,0x2e,0xd2,0x17,0xd1,
-       0x08,0x10,0x04,0x01,0x00,0x00,0x00,0x10,0x04,0x01,0x00,0x01,0xff,0xe0,0xa8,0xb2,
-       0xe0,0xa8,0xbc,0x00,0xd1,0x08,0x10,0x04,0x00,0x00,0x01,0x00,0x10,0x0b,0x01,0xff,
-       0xe0,0xa8,0xb8,0xe0,0xa8,0xbc,0x00,0x00,0x00,0xd2,0x08,0x11,0x04,0x01,0x00,0x00,
-       0x00,0x91,0x08,0x10,0x04,0x01,0x07,0x00,0x00,0x01,0x00,0xcf,0x86,0xd5,0x80,0xd4,
-       0x34,0xd3,0x18,0xd2,0x0c,0x51,0x04,0x01,0x00,0x10,0x04,0x01,0x00,0x00,0x00,0x51,
-       0x04,0x00,0x00,0x10,0x04,0x00,0x00,0x01,0x00,0xd2,0x10,0xd1,0x08,0x10,0x04,0x01,
-       0x00,0x00,0x00,0x10,0x04,0x00,0x00,0x01,0x00,0x91,0x08,0x10,0x04,0x01,0x00,0x01,
-       0x09,0x00,0x00,0xd3,0x10,0x92,0x0c,0x91,0x08,0x10,0x04,0x00,0x00,0x0a,0x00,0x00,
-       0x00,0x00,0x00,0xd2,0x25,0xd1,0x0f,0x10,0x04,0x00,0x00,0x01,0xff,0xe0,0xa8,0x96,
-       0xe0,0xa8,0xbc,0x00,0x10,0x0b,0x01,0xff,0xe0,0xa8,0x97,0xe0,0xa8,0xbc,0x00,0x01,
-       0xff,0xe0,0xa8,0x9c,0xe0,0xa8,0xbc,0x00,0xd1,0x08,0x10,0x04,0x01,0x00,0x00,0x00,
-       0x10,0x0b,0x01,0xff,0xe0,0xa8,0xab,0xe0,0xa8,0xbc,0x00,0x00,0x00,0xd4,0x10,0x93,
-       0x0c,0x52,0x04,0x00,0x00,0x11,0x04,0x00,0x00,0x01,0x00,0x01,0x00,0x93,0x14,0x52,
-       0x04,0x01,0x00,0xd1,0x08,0x10,0x04,0x01,0x00,0x0a,0x00,0x10,0x04,0x14,0x00,0x00,
-       0x00,0x00,0x00,0xd0,0x82,0xcf,0x86,0xd5,0x40,0xd4,0x2c,0xd3,0x18,0xd2,0x0c,0x91,
-       0x08,0x10,0x04,0x00,0x00,0x01,0x00,0x01,0x00,0x91,0x08,0x10,0x04,0x00,0x00,0x01,
-       0x00,0x01,0x00,0x52,0x04,0x01,0x00,0xd1,0x08,0x10,0x04,0x07,0x00,0x01,0x00,0x10,
-       0x04,0x00,0x00,0x01,0x00,0x93,0x10,0x92,0x0c,0x51,0x04,0x01,0x00,0x10,0x04,0x00,
-       0x00,0x01,0x00,0x01,0x00,0x01,0x00,0xd4,0x14,0x53,0x04,0x01,0x00,0x92,0x0c,0x91,
-       0x08,0x10,0x04,0x01,0x00,0x00,0x00,0x01,0x00,0x01,0x00,0xd3,0x18,0xd2,0x0c,0x91,
-       0x08,0x10,0x04,0x01,0x00,0x00,0x00,0x01,0x00,0x91,0x08,0x10,0x04,0x00,0x00,0x01,
-       0x00,0x01,0x00,0xd2,0x08,0x11,0x04,0x01,0x00,0x00,0x00,0x91,0x08,0x10,0x04,0x01,
-       0x07,0x01,0x00,0x01,0x00,0xcf,0x86,0xd5,0x3c,0xd4,0x28,0xd3,0x10,0x52,0x04,0x01,
-       0x00,0x51,0x04,0x01,0x00,0x10,0x04,0x00,0x00,0x01,0x00,0xd2,0x0c,0x51,0x04,0x01,
-       0x00,0x10,0x04,0x00,0x00,0x01,0x00,0x91,0x08,0x10,0x04,0x01,0x00,0x01,0x09,0x00,
-       0x00,0x93,0x10,0x92,0x0c,0x91,0x08,0x10,0x04,0x01,0x00,0x00,0x00,0x00,0x00,0x00,
-       0x00,0x00,0x00,0xd4,0x18,0x93,0x14,0xd2,0x0c,0x91,0x08,0x10,0x04,0x01,0x00,0x07,
-       0x00,0x07,0x00,0x11,0x04,0x00,0x00,0x01,0x00,0x01,0x00,0xd3,0x10,0x92,0x0c,0x91,
-       0x08,0x10,0x04,0x0d,0x00,0x07,0x00,0x00,0x00,0x00,0x00,0x92,0x0c,0x91,0x08,0x10,
-       0x04,0x00,0x00,0x11,0x00,0x13,0x00,0x13,0x00,0xe1,0x24,0x01,0xd0,0x86,0xcf,0x86,
-       0xd5,0x44,0xd4,0x2c,0xd3,0x18,0xd2,0x0c,0x91,0x08,0x10,0x04,0x00,0x00,0x01,0x00,
-       0x01,0x00,0x91,0x08,0x10,0x04,0x00,0x00,0x01,0x00,0x01,0x00,0x52,0x04,0x01,0x00,
-       0xd1,0x08,0x10,0x04,0x01,0x00,0x00,0x00,0x10,0x04,0x00,0x00,0x01,0x00,0x93,0x14,
-       0x92,0x10,0xd1,0x08,0x10,0x04,0x01,0x00,0x00,0x00,0x10,0x04,0x00,0x00,0x01,0x00,
-       0x01,0x00,0x01,0x00,0xd4,0x14,0x53,0x04,0x01,0x00,0x92,0x0c,0x91,0x08,0x10,0x04,
-       0x01,0x00,0x00,0x00,0x01,0x00,0x01,0x00,0xd3,0x18,0xd2,0x0c,0x91,0x08,0x10,0x04,
-       0x01,0x00,0x00,0x00,0x01,0x00,0x91,0x08,0x10,0x04,0x00,0x00,0x07,0x00,0x01,0x00,
-       0xd2,0x08,0x11,0x04,0x01,0x00,0x00,0x00,0x91,0x08,0x10,0x04,0x01,0x07,0x01,0x00,
-       0x01,0x00,0xcf,0x86,0xd5,0x73,0xd4,0x45,0xd3,0x14,0x52,0x04,0x01,0x00,0xd1,0x08,
-       0x10,0x04,0x0a,0x00,0x00,0x00,0x10,0x04,0x00,0x00,0x01,0x00,0xd2,0x1e,0xd1,0x0f,
-       0x10,0x0b,0x01,0xff,0xe0,0xad,0x87,0xe0,0xad,0x96,0x00,0x00,0x00,0x10,0x04,0x00,
-       0x00,0x01,0xff,0xe0,0xad,0x87,0xe0,0xac,0xbe,0x00,0x91,0x0f,0x10,0x0b,0x01,0xff,
-       0xe0,0xad,0x87,0xe0,0xad,0x97,0x00,0x01,0x09,0x00,0x00,0xd3,0x0c,0x52,0x04,0x00,
-       0x00,0x11,0x04,0x00,0x00,0x01,0x00,0x52,0x04,0x00,0x00,0xd1,0x16,0x10,0x0b,0x01,
-       0xff,0xe0,0xac,0xa1,0xe0,0xac,0xbc,0x00,0x01,0xff,0xe0,0xac,0xa2,0xe0,0xac,0xbc,
-       0x00,0x10,0x04,0x00,0x00,0x01,0x00,0xd4,0x14,0x93,0x10,0xd2,0x08,0x11,0x04,0x01,
-       0x00,0x0a,0x00,0x11,0x04,0x00,0x00,0x01,0x00,0x01,0x00,0x93,0x10,0x92,0x0c,0x91,
-       0x08,0x10,0x04,0x01,0x00,0x07,0x00,0x0c,0x00,0x0c,0x00,0x00,0x00,0xd0,0xb1,0xcf,
-       0x86,0xd5,0x63,0xd4,0x28,0xd3,0x14,0xd2,0x08,0x11,0x04,0x00,0x00,0x01,0x00,0x91,
-       0x08,0x10,0x04,0x00,0x00,0x01,0x00,0x01,0x00,0xd2,0x0c,0x51,0x04,0x01,0x00,0x10,
-       0x04,0x01,0x00,0x00,0x00,0x11,0x04,0x00,0x00,0x01,0x00,0xd3,0x1f,0xd2,0x0c,0x91,
-       0x08,0x10,0x04,0x01,0x00,0x00,0x00,0x01,0x00,0x91,0x0f,0x10,0x0b,0x01,0xff,0xe0,
-       0xae,0x92,0xe0,0xaf,0x97,0x00,0x01,0x00,0x00,0x00,0xd2,0x10,0xd1,0x08,0x10,0x04,
-       0x00,0x00,0x01,0x00,0x10,0x04,0x01,0x00,0x00,0x00,0x91,0x08,0x10,0x04,0x01,0x00,
-       0x00,0x00,0x01,0x00,0xd4,0x2c,0xd3,0x18,0xd2,0x0c,0x51,0x04,0x00,0x00,0x10,0x04,
-       0x00,0x00,0x01,0x00,0x91,0x08,0x10,0x04,0x01,0x00,0x00,0x00,0x00,0x00,0xd2,0x0c,
-       0x51,0x04,0x01,0x00,0x10,0x04,0x01,0x00,0x00,0x00,0x11,0x04,0x00,0x00,0x01,0x00,
-       0xd3,0x10,0x52,0x04,0x01,0x00,0x51,0x04,0x01,0x00,0x10,0x04,0x08,0x00,0x01,0x00,
-       0xd2,0x08,0x11,0x04,0x01,0x00,0x00,0x00,0x11,0x04,0x00,0x00,0x01,0x00,0xcf,0x86,
-       0xd5,0x61,0xd4,0x45,0xd3,0x14,0xd2,0x0c,0x51,0x04,0x01,0x00,0x10,0x04,0x01,0x00,
-       0x00,0x00,0x11,0x04,0x00,0x00,0x01,0x00,0xd2,0x1e,0xd1,0x08,0x10,0x04,0x01,0x00,
-       0x00,0x00,0x10,0x0b,0x01,0xff,0xe0,0xaf,0x86,0xe0,0xae,0xbe,0x00,0x01,0xff,0xe0,
-       0xaf,0x87,0xe0,0xae,0xbe,0x00,0x91,0x0f,0x10,0x0b,0x01,0xff,0xe0,0xaf,0x86,0xe0,
-       0xaf,0x97,0x00,0x01,0x09,0x00,0x00,0x93,0x18,0xd2,0x0c,0x91,0x08,0x10,0x04,0x0a,
-       0x00,0x00,0x00,0x00,0x00,0x51,0x04,0x00,0x00,0x10,0x04,0x00,0x00,0x01,0x00,0x00,
-       0x00,0xd4,0x14,0x93,0x10,0x52,0x04,0x00,0x00,0x51,0x04,0x00,0x00,0x10,0x04,0x08,
-       0x00,0x01,0x00,0x01,0x00,0xd3,0x10,0x92,0x0c,0x51,0x04,0x01,0x00,0x10,0x04,0x01,
-       0x00,0x07,0x00,0x07,0x00,0x92,0x0c,0x51,0x04,0x07,0x00,0x10,0x04,0x07,0x00,0x00,
-       0x00,0x00,0x00,0xe3,0x1c,0x04,0xe2,0x1a,0x02,0xd1,0xf3,0xd0,0x76,0xcf,0x86,0xd5,
-       0x3c,0xd4,0x28,0xd3,0x18,0xd2,0x0c,0x91,0x08,0x10,0x04,0x10,0x00,0x01,0x00,0x01,
-       0x00,0x91,0x08,0x10,0x04,0x14,0x00,0x01,0x00,0x01,0x00,0x52,0x04,0x01,0x00,0x91,
-       0x08,0x10,0x04,0x01,0x00,0x00,0x00,0x01,0x00,0x93,0x10,0x92,0x0c,0x91,0x08,0x10,
-       0x04,0x01,0x00,0x00,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0xd4,0x14,0x53,0x04,0x01,
-       0x00,0x92,0x0c,0x91,0x08,0x10,0x04,0x01,0x00,0x00,0x00,0x01,0x00,0x01,0x00,0xd3,
-       0x10,0x52,0x04,0x01,0x00,0x91,0x08,0x10,0x04,0x10,0x00,0x01,0x00,0x01,0x00,0xd2,
-       0x08,0x11,0x04,0x01,0x00,0x00,0x00,0x91,0x08,0x10,0x04,0x00,0x00,0x0a,0x00,0x01,
-       0x00,0xcf,0x86,0xd5,0x53,0xd4,0x2f,0xd3,0x10,0x52,0x04,0x01,0x00,0x91,0x08,0x10,
-       0x04,0x01,0x00,0x00,0x00,0x01,0x00,0xd2,0x13,0x91,0x0f,0x10,0x0b,0x01,0xff,0xe0,
-       0xb1,0x86,0xe0,0xb1,0x96,0x00,0x00,0x00,0x01,0x00,0x91,0x08,0x10,0x04,0x01,0x00,
-       0x01,0x09,0x00,0x00,0xd3,0x14,0x52,0x04,0x00,0x00,0xd1,0x08,0x10,0x04,0x00,0x00,
-       0x01,0x54,0x10,0x04,0x01,0x5b,0x00,0x00,0x92,0x0c,0x51,0x04,0x0a,0x00,0x10,0x04,
-       0x11,0x00,0x00,0x00,0x00,0x00,0xd4,0x14,0x93,0x10,0xd2,0x08,0x11,0x04,0x01,0x00,
-       0x0a,0x00,0x11,0x04,0x00,0x00,0x01,0x00,0x01,0x00,0x93,0x10,0x52,0x04,0x00,0x00,
-       0x51,0x04,0x00,0x00,0x10,0x04,0x00,0x00,0x15,0x00,0x0a,0x00,0xd0,0x76,0xcf,0x86,
-       0xd5,0x3c,0xd4,0x28,0xd3,0x18,0xd2,0x0c,0x91,0x08,0x10,0x04,0x12,0x00,0x10,0x00,
-       0x01,0x00,0x91,0x08,0x10,0x04,0x14,0x00,0x01,0x00,0x01,0x00,0x52,0x04,0x01,0x00,
-       0x91,0x08,0x10,0x04,0x01,0x00,0x00,0x00,0x01,0x00,0x93,0x10,0x92,0x0c,0x91,0x08,
-       0x10,0x04,0x01,0x00,0x00,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0xd4,0x14,0x53,0x04,
+       0xd3,0x2e,0xd2,0x17,0xd1,0x08,0x10,0x04,0x01,0x00,0x00,0x00,0x10,0x04,0x01,0x00,
+       0x01,0xff,0xe0,0xa8,0xb2,0xe0,0xa8,0xbc,0x00,0xd1,0x08,0x10,0x04,0x00,0x00,0x01,
+       0x00,0x10,0x0b,0x01,0xff,0xe0,0xa8,0xb8,0xe0,0xa8,0xbc,0x00,0x00,0x00,0xd2,0x08,
+       0x11,0x04,0x01,0x00,0x00,0x00,0x91,0x08,0x10,0x04,0x01,0x07,0x00,0x00,0x01,0x00,
+       0xcf,0x86,0xd5,0x80,0xd4,0x34,0xd3,0x18,0xd2,0x0c,0x51,0x04,0x01,0x00,0x10,0x04,
+       0x01,0x00,0x00,0x00,0x51,0x04,0x00,0x00,0x10,0x04,0x00,0x00,0x01,0x00,0xd2,0x10,
+       0xd1,0x08,0x10,0x04,0x01,0x00,0x00,0x00,0x10,0x04,0x00,0x00,0x01,0x00,0x91,0x08,
+       0x10,0x04,0x01,0x00,0x01,0x09,0x00,0x00,0xd3,0x10,0x92,0x0c,0x91,0x08,0x10,0x04,
+       0x00,0x00,0x0a,0x00,0x00,0x00,0x00,0x00,0xd2,0x25,0xd1,0x0f,0x10,0x04,0x00,0x00,
+       0x01,0xff,0xe0,0xa8,0x96,0xe0,0xa8,0xbc,0x00,0x10,0x0b,0x01,0xff,0xe0,0xa8,0x97,
+       0xe0,0xa8,0xbc,0x00,0x01,0xff,0xe0,0xa8,0x9c,0xe0,0xa8,0xbc,0x00,0xd1,0x08,0x10,
+       0x04,0x01,0x00,0x00,0x00,0x10,0x0b,0x01,0xff,0xe0,0xa8,0xab,0xe0,0xa8,0xbc,0x00,
+       0x00,0x00,0xd4,0x10,0x93,0x0c,0x52,0x04,0x00,0x00,0x11,0x04,0x00,0x00,0x01,0x00,
+       0x01,0x00,0x93,0x14,0x52,0x04,0x01,0x00,0xd1,0x08,0x10,0x04,0x01,0x00,0x0a,0x00,
+       0x10,0x04,0x14,0x00,0x00,0x00,0x00,0x00,0xd0,0x82,0xcf,0x86,0xd5,0x40,0xd4,0x2c,
+       0xd3,0x18,0xd2,0x0c,0x91,0x08,0x10,0x04,0x00,0x00,0x01,0x00,0x01,0x00,0x91,0x08,
+       0x10,0x04,0x00,0x00,0x01,0x00,0x01,0x00,0x52,0x04,0x01,0x00,0xd1,0x08,0x10,0x04,
+       0x07,0x00,0x01,0x00,0x10,0x04,0x00,0x00,0x01,0x00,0x93,0x10,0x92,0x0c,0x51,0x04,
+       0x01,0x00,0x10,0x04,0x00,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0xd4,0x14,0x53,0x04,
        0x01,0x00,0x92,0x0c,0x91,0x08,0x10,0x04,0x01,0x00,0x00,0x00,0x01,0x00,0x01,0x00,
-       0xd3,0x10,0x52,0x04,0x01,0x00,0x91,0x08,0x10,0x04,0x00,0x00,0x01,0x00,0x01,0x00,
-       0xd2,0x08,0x11,0x04,0x01,0x00,0x00,0x00,0x91,0x08,0x10,0x04,0x07,0x07,0x07,0x00,
-       0x01,0x00,0xcf,0x86,0xd5,0x82,0xd4,0x5e,0xd3,0x2a,0xd2,0x13,0x91,0x0f,0x10,0x0b,
-       0x01,0xff,0xe0,0xb2,0xbf,0xe0,0xb3,0x95,0x00,0x01,0x00,0x01,0x00,0xd1,0x08,0x10,
-       0x04,0x01,0x00,0x00,0x00,0x10,0x04,0x01,0x00,0x01,0xff,0xe0,0xb3,0x86,0xe0,0xb3,
-       0x95,0x00,0xd2,0x28,0xd1,0x0f,0x10,0x0b,0x01,0xff,0xe0,0xb3,0x86,0xe0,0xb3,0x96,
-       0x00,0x00,0x00,0x10,0x0b,0x01,0xff,0xe0,0xb3,0x86,0xe0,0xb3,0x82,0x00,0x01,0xff,
-       0xe0,0xb3,0x86,0xe0,0xb3,0x82,0xe0,0xb3,0x95,0x00,0x91,0x08,0x10,0x04,0x01,0x00,
-       0x01,0x09,0x00,0x00,0xd3,0x14,0x52,0x04,0x00,0x00,0xd1,0x08,0x10,0x04,0x00,0x00,
-       0x01,0x00,0x10,0x04,0x01,0x00,0x00,0x00,0x52,0x04,0x00,0x00,0x51,0x04,0x00,0x00,
-       0x10,0x04,0x01,0x00,0x00,0x00,0xd4,0x14,0x93,0x10,0xd2,0x08,0x11,0x04,0x01,0x00,
-       0x09,0x00,0x11,0x04,0x00,0x00,0x01,0x00,0x01,0x00,0x93,0x14,0x92,0x10,0xd1,0x08,
-       0x10,0x04,0x00,0x00,0x09,0x00,0x10,0x04,0x09,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-       0xe1,0x06,0x01,0xd0,0x6e,0xcf,0x86,0xd5,0x3c,0xd4,0x28,0xd3,0x18,0xd2,0x0c,0x91,
-       0x08,0x10,0x04,0x13,0x00,0x10,0x00,0x01,0x00,0x91,0x08,0x10,0x04,0x00,0x00,0x01,
-       0x00,0x01,0x00,0x52,0x04,0x01,0x00,0x91,0x08,0x10,0x04,0x01,0x00,0x00,0x00,0x01,
-       0x00,0x93,0x10,0x92,0x0c,0x91,0x08,0x10,0x04,0x01,0x00,0x00,0x00,0x01,0x00,0x01,
-       0x00,0x01,0x00,0xd4,0x14,0x53,0x04,0x01,0x00,0x92,0x0c,0x91,0x08,0x10,0x04,0x01,
-       0x00,0x0c,0x00,0x01,0x00,0x01,0x00,0x53,0x04,0x01,0x00,0xd2,0x0c,0x51,0x04,0x01,
-       0x00,0x10,0x04,0x0c,0x00,0x13,0x09,0x91,0x08,0x10,0x04,0x13,0x09,0x0a,0x00,0x01,
-       0x00,0xcf,0x86,0xd5,0x65,0xd4,0x45,0xd3,0x10,0x52,0x04,0x01,0x00,0x91,0x08,0x10,
-       0x04,0x0a,0x00,0x00,0x00,0x01,0x00,0xd2,0x1e,0xd1,0x08,0x10,0x04,0x01,0x00,0x00,
-       0x00,0x10,0x0b,0x01,0xff,0xe0,0xb5,0x86,0xe0,0xb4,0xbe,0x00,0x01,0xff,0xe0,0xb5,
-       0x87,0xe0,0xb4,0xbe,0x00,0xd1,0x0f,0x10,0x0b,0x01,0xff,0xe0,0xb5,0x86,0xe0,0xb5,
-       0x97,0x00,0x01,0x09,0x10,0x04,0x0c,0x00,0x12,0x00,0xd3,0x10,0x52,0x04,0x00,0x00,
-       0x51,0x04,0x12,0x00,0x10,0x04,0x12,0x00,0x01,0x00,0x52,0x04,0x12,0x00,0x51,0x04,
-       0x12,0x00,0x10,0x04,0x12,0x00,0x11,0x00,0xd4,0x14,0x93,0x10,0xd2,0x08,0x11,0x04,
-       0x01,0x00,0x0a,0x00,0x11,0x04,0x00,0x00,0x01,0x00,0x01,0x00,0xd3,0x0c,0x52,0x04,
-       0x0a,0x00,0x11,0x04,0x0a,0x00,0x12,0x00,0x92,0x0c,0x91,0x08,0x10,0x04,0x12,0x00,
-       0x0a,0x00,0x0a,0x00,0x0a,0x00,0xd0,0x5a,0xcf,0x86,0xd5,0x34,0xd4,0x18,0x93,0x14,
-       0xd2,0x08,0x11,0x04,0x00,0x00,0x04,0x00,0x91,0x08,0x10,0x04,0x00,0x00,0x04,0x00,
-       0x04,0x00,0x04,0x00,0xd3,0x10,0x52,0x04,0x04,0x00,0x51,0x04,0x04,0x00,0x10,0x04,
-       0x04,0x00,0x00,0x00,0x92,0x08,0x11,0x04,0x00,0x00,0x04,0x00,0x04,0x00,0x54,0x04,
-       0x04,0x00,0xd3,0x10,0x92,0x0c,0x51,0x04,0x04,0x00,0x10,0x04,0x00,0x00,0x04,0x00,
-       0x04,0x00,0x52,0x04,0x04,0x00,0x91,0x08,0x10,0x04,0x00,0x00,0x04,0x00,0x00,0x00,
-       0xcf,0x86,0xd5,0x77,0xd4,0x28,0xd3,0x10,0x52,0x04,0x04,0x00,0x51,0x04,0x04,0x00,
-       0x10,0x04,0x04,0x00,0x00,0x00,0xd2,0x0c,0x51,0x04,0x00,0x00,0x10,0x04,0x04,0x09,
-       0x00,0x00,0x51,0x04,0x00,0x00,0x10,0x04,0x00,0x00,0x04,0x00,0xd3,0x14,0x52,0x04,
-       0x04,0x00,0xd1,0x08,0x10,0x04,0x04,0x00,0x00,0x00,0x10,0x04,0x04,0x00,0x00,0x00,
-       0xd2,0x13,0x51,0x04,0x04,0x00,0x10,0x0b,0x04,0xff,0xe0,0xb7,0x99,0xe0,0xb7,0x8a,
-       0x00,0x04,0x00,0xd1,0x19,0x10,0x0b,0x04,0xff,0xe0,0xb7,0x99,0xe0,0xb7,0x8f,0x00,
-       0x04,0xff,0xe0,0xb7,0x99,0xe0,0xb7,0x8f,0xe0,0xb7,0x8a,0x00,0x10,0x0b,0x04,0xff,
-       0xe0,0xb7,0x99,0xe0,0xb7,0x9f,0x00,0x04,0x00,0xd4,0x10,0x93,0x0c,0x52,0x04,0x00,
-       0x00,0x11,0x04,0x00,0x00,0x10,0x00,0x10,0x00,0x93,0x14,0xd2,0x08,0x11,0x04,0x00,
-       0x00,0x04,0x00,0x91,0x08,0x10,0x04,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe2,
-       0x31,0x01,0xd1,0x58,0xd0,0x3a,0xcf,0x86,0xd5,0x18,0x94,0x14,0x93,0x10,0x92,0x0c,
-       0x91,0x08,0x10,0x04,0x00,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,
-       0x54,0x04,0x01,0x00,0x53,0x04,0x01,0x00,0xd2,0x0c,0x51,0x04,0x01,0x67,0x10,0x04,
-       0x01,0x09,0x00,0x00,0x51,0x04,0x00,0x00,0x10,0x04,0x00,0x00,0x01,0x00,0xcf,0x86,
-       0x95,0x18,0xd4,0x0c,0x53,0x04,0x01,0x00,0x12,0x04,0x01,0x6b,0x01,0x00,0x53,0x04,
-       0x01,0x00,0x12,0x04,0x01,0x00,0x00,0x00,0x00,0x00,0xd0,0x9e,0xcf,0x86,0xd5,0x54,
-       0xd4,0x3c,0xd3,0x20,0xd2,0x10,0xd1,0x08,0x10,0x04,0x00,0x00,0x01,0x00,0x10,0x04,
-       0x01,0x00,0x00,0x00,0xd1,0x08,0x10,0x04,0x01,0x00,0x00,0x00,0x10,0x04,0x15,0x00,
-       0x01,0x00,0xd2,0x10,0xd1,0x08,0x10,0x04,0x01,0x00,0x15,0x00,0x10,0x04,0x01,0x00,
-       0x00,0x00,0x91,0x08,0x10,0x04,0x15,0x00,0x01,0x00,0x15,0x00,0xd3,0x08,0x12,0x04,
-       0x15,0x00,0x01,0x00,0x92,0x0c,0x91,0x08,0x10,0x04,0x15,0x00,0x01,0x00,0x01,0x00,
-       0x01,0x00,0xd4,0x30,0xd3,0x1c,0xd2,0x0c,0x91,0x08,0x10,0x04,0x15,0x00,0x01,0x00,
-       0x01,0x00,0xd1,0x08,0x10,0x04,0x00,0x00,0x01,0x00,0x10,0x04,0x00,0x00,0x01,0x00,
-       0xd2,0x08,0x11,0x04,0x15,0x00,0x01,0x00,0x91,0x08,0x10,0x04,0x15,0x00,0x01,0x00,
-       0x01,0x00,0x53,0x04,0x01,0x00,0xd2,0x0c,0x51,0x04,0x01,0x76,0x10,0x04,0x15,0x09,
-       0x01,0x00,0x11,0x04,0x01,0x00,0x00,0x00,0xcf,0x86,0x95,0x34,0xd4,0x20,0xd3,0x14,
-       0x52,0x04,0x01,0x00,0xd1,0x08,0x10,0x04,0x01,0x00,0x00,0x00,0x10,0x04,0x01,0x00,
-       0x00,0x00,0x52,0x04,0x01,0x7a,0x11,0x04,0x01,0x00,0x00,0x00,0x53,0x04,0x01,0x00,
-       0xd2,0x08,0x11,0x04,0x01,0x00,0x00,0x00,0x11,0x04,0x01,0x00,0x0d,0x00,0x00,0x00,
-       0xe1,0x2b,0x01,0xd0,0x3e,0xcf,0x86,0xd5,0x14,0x54,0x04,0x02,0x00,0x53,0x04,0x02,
-       0x00,0x92,0x08,0x11,0x04,0x02,0xdc,0x02,0x00,0x02,0x00,0x54,0x04,0x02,0x00,0xd3,
-       0x14,0x52,0x04,0x02,0x00,0xd1,0x08,0x10,0x04,0x02,0x00,0x02,0xdc,0x10,0x04,0x02,
-       0x00,0x02,0xdc,0x92,0x0c,0x91,0x08,0x10,0x04,0x02,0x00,0x02,0xd8,0x02,0x00,0x02,
-       0x00,0xcf,0x86,0xd5,0x73,0xd4,0x36,0xd3,0x17,0x92,0x13,0x51,0x04,0x02,0x00,0x10,
-       0x04,0x02,0x00,0x02,0xff,0xe0,0xbd,0x82,0xe0,0xbe,0xb7,0x00,0x02,0x00,0xd2,0x0c,
-       0x91,0x08,0x10,0x04,0x00,0x00,0x02,0x00,0x02,0x00,0x91,0x0f,0x10,0x04,0x02,0x00,
-       0x02,0xff,0xe0,0xbd,0x8c,0xe0,0xbe,0xb7,0x00,0x02,0x00,0xd3,0x26,0xd2,0x13,0x51,
-       0x04,0x02,0x00,0x10,0x0b,0x02,0xff,0xe0,0xbd,0x91,0xe0,0xbe,0xb7,0x00,0x02,0x00,
-       0x51,0x04,0x02,0x00,0x10,0x04,0x02,0x00,0x02,0xff,0xe0,0xbd,0x96,0xe0,0xbe,0xb7,
-       0x00,0x52,0x04,0x02,0x00,0x91,0x0f,0x10,0x0b,0x02,0xff,0xe0,0xbd,0x9b,0xe0,0xbe,
-       0xb7,0x00,0x02,0x00,0x02,0x00,0xd4,0x27,0x53,0x04,0x02,0x00,0xd2,0x17,0xd1,0x0f,
-       0x10,0x04,0x02,0x00,0x02,0xff,0xe0,0xbd,0x80,0xe0,0xbe,0xb5,0x00,0x10,0x04,0x04,
-       0x00,0x0a,0x00,0x91,0x08,0x10,0x04,0x0a,0x00,0x00,0x00,0x00,0x00,0xd3,0x35,0xd2,
-       0x17,0xd1,0x08,0x10,0x04,0x00,0x00,0x02,0x81,0x10,0x04,0x02,0x82,0x02,0xff,0xe0,
-       0xbd,0xb1,0xe0,0xbd,0xb2,0x00,0xd1,0x0f,0x10,0x04,0x02,0x84,0x02,0xff,0xe0,0xbd,
-       0xb1,0xe0,0xbd,0xb4,0x00,0x10,0x0b,0x02,0xff,0xe0,0xbe,0xb2,0xe0,0xbe,0x80,0x00,
-       0x02,0x00,0xd2,0x13,0x91,0x0f,0x10,0x0b,0x02,0xff,0xe0,0xbe,0xb3,0xe0,0xbe,0x80,
-       0x00,0x02,0x00,0x02,0x82,0x11,0x04,0x02,0x82,0x02,0x00,0xd0,0xd3,0xcf,0x86,0xd5,
-       0x65,0xd4,0x27,0xd3,0x1f,0xd2,0x13,0x91,0x0f,0x10,0x04,0x02,0x82,0x02,0xff,0xe0,
-       0xbd,0xb1,0xe0,0xbe,0x80,0x00,0x02,0xe6,0x91,0x08,0x10,0x04,0x02,0x09,0x02,0x00,
-       0x02,0xe6,0x12,0x04,0x02,0x00,0x0c,0x00,0xd3,0x1f,0xd2,0x13,0x51,0x04,0x02,0x00,
-       0x10,0x04,0x02,0x00,0x02,0xff,0xe0,0xbe,0x92,0xe0,0xbe,0xb7,0x00,0x51,0x04,0x02,
-       0x00,0x10,0x04,0x04,0x00,0x02,0x00,0xd2,0x0c,0x91,0x08,0x10,0x04,0x00,0x00,0x02,
-       0x00,0x02,0x00,0x91,0x0f,0x10,0x04,0x02,0x00,0x02,0xff,0xe0,0xbe,0x9c,0xe0,0xbe,
-       0xb7,0x00,0x02,0x00,0xd4,0x3d,0xd3,0x26,0xd2,0x13,0x51,0x04,0x02,0x00,0x10,0x0b,
-       0x02,0xff,0xe0,0xbe,0xa1,0xe0,0xbe,0xb7,0x00,0x02,0x00,0x51,0x04,0x02,0x00,0x10,
-       0x04,0x02,0x00,0x02,0xff,0xe0,0xbe,0xa6,0xe0,0xbe,0xb7,0x00,0x52,0x04,0x02,0x00,
-       0x91,0x0f,0x10,0x0b,0x02,0xff,0xe0,0xbe,0xab,0xe0,0xbe,0xb7,0x00,0x02,0x00,0x04,
-       0x00,0xd3,0x10,0x92,0x0c,0x91,0x08,0x10,0x04,0x04,0x00,0x02,0x00,0x02,0x00,0x02,
-       0x00,0xd2,0x13,0x91,0x0f,0x10,0x04,0x04,0x00,0x02,0xff,0xe0,0xbe,0x90,0xe0,0xbe,
-       0xb5,0x00,0x04,0x00,0x91,0x08,0x10,0x04,0x04,0x00,0x00,0x00,0x04,0x00,0xcf,0x86,
-       0x95,0x4c,0xd4,0x24,0xd3,0x10,0x52,0x04,0x04,0x00,0x51,0x04,0x04,0x00,0x10,0x04,
-       0x04,0xdc,0x04,0x00,0x52,0x04,0x04,0x00,0xd1,0x08,0x10,0x04,0x04,0x00,0x00,0x00,
-       0x10,0x04,0x0a,0x00,0x04,0x00,0xd3,0x14,0xd2,0x08,0x11,0x04,0x08,0x00,0x0a,0x00,
-       0x91,0x08,0x10,0x04,0x0a,0x00,0x0b,0x00,0x0b,0x00,0x92,0x10,0xd1,0x08,0x10,0x04,
-       0x0b,0x00,0x0c,0x00,0x10,0x04,0x0c,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xcf,0x86,
-       0xe5,0xf7,0x04,0xe4,0x79,0x03,0xe3,0x7b,0x01,0xe2,0x04,0x01,0xd1,0x7f,0xd0,0x65,
-       0xcf,0x86,0x55,0x04,0x04,0x00,0xd4,0x33,0xd3,0x1f,0xd2,0x0c,0x51,0x04,0x04,0x00,
-       0x10,0x04,0x0a,0x00,0x04,0x00,0x51,0x04,0x04,0x00,0x10,0x0b,0x04,0xff,0xe1,0x80,
-       0xa5,0xe1,0x80,0xae,0x00,0x04,0x00,0x92,0x10,0xd1,0x08,0x10,0x04,0x0a,0x00,0x04,
-       0x00,0x10,0x04,0x04,0x00,0x0a,0x00,0x04,0x00,0xd3,0x18,0xd2,0x0c,0x51,0x04,0x04,
-       0x00,0x10,0x04,0x04,0x00,0x0a,0x00,0x51,0x04,0x0a,0x00,0x10,0x04,0x04,0x00,0x04,
-       0x07,0x92,0x10,0xd1,0x08,0x10,0x04,0x04,0x00,0x04,0x09,0x10,0x04,0x0a,0x09,0x0a,
-       0x00,0x0a,0x00,0xcf,0x86,0x95,0x14,0x54,0x04,0x04,0x00,0x53,0x04,0x04,0x00,0x92,
-       0x08,0x11,0x04,0x04,0x00,0x0a,0x00,0x0a,0x00,0x0a,0x00,0xd0,0x2e,0xcf,0x86,0x95,
-       0x28,0xd4,0x14,0x53,0x04,0x0a,0x00,0x52,0x04,0x0a,0x00,0x91,0x08,0x10,0x04,0x0a,
-       0x00,0x0a,0xdc,0x0a,0x00,0x53,0x04,0x0a,0x00,0xd2,0x08,0x11,0x04,0x0a,0x00,0x0b,
-       0x00,0x11,0x04,0x0b,0x00,0x0a,0x00,0x01,0x00,0xcf,0x86,0xd5,0x24,0x94,0x20,0xd3,
-       0x10,0x52,0x04,0x01,0x00,0x51,0x04,0x01,0x00,0x10,0x04,0x00,0x00,0x0d,0x00,0x52,
-       0x04,0x00,0x00,0x91,0x08,0x10,0x04,0x00,0x00,0x0d,0x00,0x00,0x00,0x01,0x00,0x54,
-       0x04,0x01,0x00,0xd3,0x10,0x52,0x04,0x01,0x00,0x51,0x04,0x01,0x00,0x10,0x04,0x01,
-       0x00,0x06,0x00,0xd2,0x10,0xd1,0x08,0x10,0x04,0x06,0x00,0x08,0x00,0x10,0x04,0x08,
-       0x00,0x01,0x00,0x91,0x08,0x10,0x04,0x08,0x00,0x0d,0x00,0x0d,0x00,0xd1,0x3e,0xd0,
-       0x06,0xcf,0x06,0x01,0x00,0xcf,0x86,0xd5,0x1d,0x54,0x04,0x01,0x00,0x53,0x04,0x01,
-       0x00,0xd2,0x08,0x11,0x04,0x01,0x00,0x0b,0x00,0x51,0x04,0x0b,0x00,0x10,0x04,0x0b,
-       0x00,0x01,0xff,0x00,0x94,0x15,0x93,0x11,0x92,0x0d,0x91,0x09,0x10,0x05,0x01,0xff,
-       0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0xd0,0x1e,0xcf,0x86,0x55,
-       0x04,0x01,0x00,0x94,0x14,0x93,0x10,0x92,0x0c,0x51,0x04,0x01,0x00,0x10,0x04,0x01,
-       0x00,0x0b,0x00,0x0b,0x00,0x01,0x00,0x01,0x00,0xcf,0x86,0x55,0x04,0x01,0x00,0x54,
-       0x04,0x01,0x00,0x53,0x04,0x01,0x00,0x92,0x08,0x11,0x04,0x01,0x00,0x0b,0x00,0x0b,
-       0x00,0xe2,0x21,0x01,0xd1,0x6c,0xd0,0x1e,0xcf,0x86,0x95,0x18,0x94,0x14,0x93,0x10,
-       0x52,0x04,0x04,0x00,0x51,0x04,0x04,0x00,0x10,0x04,0x04,0x00,0x08,0x00,0x04,0x00,
-       0x04,0x00,0x04,0x00,0xcf,0x86,0x95,0x48,0xd4,0x24,0xd3,0x10,0x52,0x04,0x04,0x00,
-       0x51,0x04,0x04,0x00,0x10,0x04,0x04,0x00,0x08,0x00,0xd2,0x0c,0x91,0x08,0x10,0x04,
-       0x04,0x00,0x00,0x00,0x04,0x00,0x11,0x04,0x04,0x00,0x00,0x00,0xd3,0x10,0x52,0x04,
-       0x04,0x00,0x51,0x04,0x04,0x00,0x10,0x04,0x04,0x00,0x00,0x00,0xd2,0x0c,0x91,0x08,
-       0x10,0x04,0x04,0x00,0x00,0x00,0x04,0x00,0x11,0x04,0x04,0x00,0x00,0x00,0x04,0x00,
-       0xd0,0x62,0xcf,0x86,0xd5,0x28,0x94,0x24,0xd3,0x10,0x52,0x04,0x04,0x00,0x51,0x04,
-       0x04,0x00,0x10,0x04,0x04,0x00,0x08,0x00,0xd2,0x0c,0x91,0x08,0x10,0x04,0x04,0x00,
-       0x00,0x00,0x04,0x00,0x11,0x04,0x04,0x00,0x00,0x00,0x04,0x00,0xd4,0x14,0x53,0x04,
-       0x04,0x00,0x52,0x04,0x04,0x00,0x51,0x04,0x04,0x00,0x10,0x04,0x04,0x00,0x08,0x00,
-       0xd3,0x14,0xd2,0x0c,0x91,0x08,0x10,0x04,0x04,0x00,0x00,0x00,0x04,0x00,0x11,0x04,
-       0x04,0x00,0x00,0x00,0x52,0x04,0x04,0x00,0x51,0x04,0x04,0x00,0x10,0x04,0x04,0x00,
-       0x00,0x00,0xcf,0x86,0xd5,0x38,0xd4,0x24,0xd3,0x14,0xd2,0x0c,0x91,0x08,0x10,0x04,
-       0x04,0x00,0x00,0x00,0x04,0x00,0x11,0x04,0x04,0x00,0x00,0x00,0x52,0x04,0x04,0x00,
-       0x51,0x04,0x04,0x00,0x10,0x04,0x04,0x00,0x08,0x00,0x93,0x10,0x52,0x04,0x04,0x00,
-       0x51,0x04,0x04,0x00,0x10,0x04,0x04,0x00,0x00,0x00,0x04,0x00,0x94,0x14,0x53,0x04,
-       0x04,0x00,0x52,0x04,0x04,0x00,0x51,0x04,0x04,0x00,0x10,0x04,0x04,0x00,0x08,0x00,
-       0x04,0x00,0xd1,0x9c,0xd0,0x3e,0xcf,0x86,0x95,0x38,0xd4,0x14,0x53,0x04,0x04,0x00,
-       0x52,0x04,0x04,0x00,0x51,0x04,0x04,0x00,0x10,0x04,0x04,0x00,0x08,0x00,0xd3,0x14,
-       0xd2,0x0c,0x91,0x08,0x10,0x04,0x04,0x00,0x00,0x00,0x04,0x00,0x11,0x04,0x04,0x00,
-       0x00,0x00,0x52,0x04,0x04,0x00,0x51,0x04,0x04,0x00,0x10,0x04,0x04,0x00,0x08,0x00,
-       0x04,0x00,0xcf,0x86,0xd5,0x34,0xd4,0x14,0x93,0x10,0x52,0x04,0x04,0x00,0x51,0x04,
-       0x04,0x00,0x10,0x04,0x04,0x00,0x08,0x00,0x04,0x00,0x53,0x04,0x04,0x00,0xd2,0x0c,
-       0x51,0x04,0x04,0x00,0x10,0x04,0x04,0x00,0x00,0x00,0xd1,0x08,0x10,0x04,0x00,0x00,
-       0x0c,0xe6,0x10,0x04,0x0c,0xe6,0x08,0xe6,0xd4,0x14,0x93,0x10,0x92,0x0c,0x91,0x08,
-       0x10,0x04,0x08,0x00,0x04,0x00,0x04,0x00,0x04,0x00,0x04,0x00,0x53,0x04,0x04,0x00,
-       0x52,0x04,0x04,0x00,0x91,0x08,0x10,0x04,0x04,0x00,0x00,0x00,0x00,0x00,0xd0,0x1a,
-       0xcf,0x86,0x95,0x14,0x54,0x04,0x08,0x00,0x53,0x04,0x08,0x00,0x92,0x08,0x11,0x04,
-       0x08,0x00,0x00,0x00,0x00,0x00,0x04,0x00,0xcf,0x86,0x55,0x04,0x04,0x00,0x54,0x04,
-       0x04,0x00,0xd3,0x10,0x52,0x04,0x04,0x00,0x91,0x08,0x10,0x04,0x04,0x00,0x11,0x00,
-       0x00,0x00,0x52,0x04,0x11,0x00,0x11,0x04,0x11,0x00,0x00,0x00,0xd3,0x30,0xd2,0x2a,
-       0xd1,0x24,0xd0,0x1e,0xcf,0x86,0x95,0x18,0x94,0x14,0x93,0x10,0x92,0x0c,0x91,0x08,
-       0x10,0x04,0x0b,0x00,0x04,0x00,0x04,0x00,0x04,0x00,0x04,0x00,0x04,0x00,0x04,0x00,
-       0xcf,0x06,0x04,0x00,0xcf,0x06,0x04,0x00,0xcf,0x06,0x04,0x00,0xd2,0x6c,0xd1,0x24,
-       0xd0,0x06,0xcf,0x06,0x04,0x00,0xcf,0x86,0x55,0x04,0x04,0x00,0x54,0x04,0x04,0x00,
-       0x93,0x10,0x52,0x04,0x04,0x00,0x51,0x04,0x04,0x00,0x10,0x04,0x04,0x00,0x0b,0x00,
-       0x0b,0x00,0xd0,0x1e,0xcf,0x86,0x95,0x18,0x54,0x04,0x04,0x00,0x53,0x04,0x04,0x00,
-       0x52,0x04,0x04,0x00,0x91,0x08,0x10,0x04,0x04,0x00,0x00,0x00,0x00,0x00,0x04,0x00,
-       0xcf,0x86,0x55,0x04,0x04,0x00,0x54,0x04,0x04,0x00,0xd3,0x10,0x92,0x0c,0x91,0x08,
-       0x10,0x04,0x04,0x00,0x10,0x00,0x10,0x00,0x10,0x00,0x92,0x0c,0x91,0x08,0x10,0x04,
-       0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xd1,0x80,0xd0,0x46,0xcf,0x86,0xd5,0x28,
-       0xd4,0x14,0x53,0x04,0x06,0x00,0x52,0x04,0x06,0x00,0x91,0x08,0x10,0x04,0x06,0x00,
-       0x00,0x00,0x06,0x00,0x93,0x10,0x52,0x04,0x06,0x00,0x91,0x08,0x10,0x04,0x06,0x09,
-       0x00,0x00,0x00,0x00,0x00,0x00,0x54,0x04,0x06,0x00,0x93,0x14,0x52,0x04,0x06,0x00,
-       0xd1,0x08,0x10,0x04,0x06,0x09,0x06,0x00,0x10,0x04,0x06,0x00,0x00,0x00,0x00,0x00,
-       0xcf,0x86,0xd5,0x10,0x54,0x04,0x06,0x00,0x93,0x08,0x12,0x04,0x06,0x00,0x00,0x00,
-       0x00,0x00,0xd4,0x14,0x53,0x04,0x06,0x00,0x52,0x04,0x06,0x00,0x91,0x08,0x10,0x04,
-       0x06,0x00,0x00,0x00,0x06,0x00,0x93,0x10,0x92,0x0c,0x91,0x08,0x10,0x04,0x06,0x00,
-       0x00,0x00,0x06,0x00,0x00,0x00,0x00,0x00,0xd0,0x1b,0xcf,0x86,0x55,0x04,0x04,0x00,
-       0x54,0x04,0x04,0x00,0x93,0x0d,0x52,0x04,0x04,0x00,0x11,0x05,0x04,0xff,0x00,0x04,
-       0x00,0x04,0x00,0xcf,0x86,0xd5,0x24,0x54,0x04,0x04,0x00,0xd3,0x10,0x92,0x0c,0x51,
-       0x04,0x04,0x00,0x10,0x04,0x04,0x09,0x04,0x00,0x04,0x00,0x52,0x04,0x04,0x00,0x91,
-       0x08,0x10,0x04,0x04,0x00,0x07,0xe6,0x00,0x00,0xd4,0x10,0x53,0x04,0x04,0x00,0x92,
-       0x08,0x11,0x04,0x04,0x00,0x00,0x00,0x00,0x00,0x53,0x04,0x07,0x00,0x92,0x08,0x11,
-       0x04,0x07,0x00,0x00,0x00,0x00,0x00,0xe4,0xb7,0x03,0xe3,0x58,0x01,0xd2,0x8f,0xd1,
-       0x53,0xd0,0x35,0xcf,0x86,0x95,0x2f,0xd4,0x1f,0x53,0x04,0x04,0x00,0xd2,0x0d,0x51,
-       0x04,0x04,0x00,0x10,0x04,0x04,0x00,0x04,0xff,0x00,0x51,0x05,0x04,0xff,0x00,0x10,
-       0x05,0x04,0xff,0x00,0x00,0x00,0x53,0x04,0x04,0x00,0x92,0x08,0x11,0x04,0x04,0x00,
-       0x00,0x00,0x00,0x00,0x04,0x00,0xcf,0x86,0x55,0x04,0x04,0x00,0x54,0x04,0x04,0x00,
-       0x53,0x04,0x04,0x00,0x92,0x0c,0x91,0x08,0x10,0x04,0x14,0x00,0x00,0x00,0x00,0x00,
-       0x00,0x00,0xd0,0x22,0xcf,0x86,0x55,0x04,0x04,0x00,0x94,0x18,0x53,0x04,0x04,0x00,
-       0x92,0x10,0xd1,0x08,0x10,0x04,0x04,0x00,0x04,0xe4,0x10,0x04,0x0a,0x00,0x00,0x00,
-       0x00,0x00,0x0b,0x00,0xcf,0x86,0x55,0x04,0x0b,0x00,0x54,0x04,0x0b,0x00,0x93,0x0c,
-       0x52,0x04,0x0b,0x00,0x11,0x04,0x0b,0x00,0x00,0x00,0x00,0x00,0xd1,0x80,0xd0,0x42,
-       0xcf,0x86,0xd5,0x1c,0x54,0x04,0x07,0x00,0x53,0x04,0x07,0x00,0x52,0x04,0x07,0x00,
-       0xd1,0x08,0x10,0x04,0x07,0x00,0x10,0x00,0x10,0x04,0x10,0x00,0x00,0x00,0xd4,0x0c,
-       0x53,0x04,0x07,0x00,0x12,0x04,0x07,0x00,0x00,0x00,0x53,0x04,0x07,0x00,0x92,0x10,
-       0xd1,0x08,0x10,0x04,0x07,0x00,0x07,0xde,0x10,0x04,0x07,0xe6,0x07,0xdc,0x00,0x00,
-       0xcf,0x86,0xd5,0x18,0x94,0x14,0x93,0x10,0x92,0x0c,0x91,0x08,0x10,0x04,0x07,0x00,
-       0x00,0x00,0x00,0x00,0x07,0x00,0x07,0x00,0x07,0x00,0xd4,0x10,0x53,0x04,0x07,0x00,
-       0x52,0x04,0x07,0x00,0x11,0x04,0x07,0x00,0x00,0x00,0x93,0x10,0x52,0x04,0x07,0x00,
-       0x91,0x08,0x10,0x04,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xd0,0x1a,0xcf,0x86,
-       0x55,0x04,0x08,0x00,0x94,0x10,0x53,0x04,0x08,0x00,0x92,0x08,0x11,0x04,0x08,0x00,
-       0x0b,0x00,0x00,0x00,0x08,0x00,0xcf,0x86,0x95,0x28,0xd4,0x10,0x53,0x04,0x08,0x00,
-       0x92,0x08,0x11,0x04,0x08,0x00,0x00,0x00,0x00,0x00,0x53,0x04,0x08,0x00,0xd2,0x0c,
-       0x51,0x04,0x08,0x00,0x10,0x04,0x0b,0x00,0x00,0x00,0x11,0x04,0x00,0x00,0x08,0x00,
-       0x07,0x00,0xd2,0xe4,0xd1,0x80,0xd0,0x2e,0xcf,0x86,0x95,0x28,0x54,0x04,0x08,0x00,
-       0xd3,0x10,0x52,0x04,0x08,0x00,0x51,0x04,0x08,0x00,0x10,0x04,0x08,0x00,0x08,0xe6,
-       0xd2,0x0c,0x91,0x08,0x10,0x04,0x08,0xdc,0x08,0x00,0x08,0x00,0x11,0x04,0x00,0x00,
-       0x08,0x00,0x0b,0x00,0xcf,0x86,0xd5,0x18,0x54,0x04,0x0b,0x00,0x53,0x04,0x0b,0x00,
-       0x52,0x04,0x0b,0x00,0x51,0x04,0x0b,0x00,0x10,0x04,0x0b,0x00,0x00,0x00,0xd4,0x14,
-       0x93,0x10,0x92,0x0c,0x91,0x08,0x10,0x04,0x0b,0x09,0x0b,0x00,0x0b,0x00,0x0b,0x00,
-       0x0b,0x00,0xd3,0x10,0x52,0x04,0x0b,0x00,0x91,0x08,0x10,0x04,0x0b,0x00,0x0b,0xe6,
-       0x0b,0xe6,0x52,0x04,0x0b,0xe6,0xd1,0x08,0x10,0x04,0x0b,0xe6,0x00,0x00,0x10,0x04,
-       0x00,0x00,0x0b,0xdc,0xd0,0x5e,0xcf,0x86,0xd5,0x20,0xd4,0x10,0x53,0x04,0x0b,0x00,
-       0x92,0x08,0x11,0x04,0x0b,0x00,0x00,0x00,0x00,0x00,0x53,0x04,0x0b,0x00,0x92,0x08,
-       0x11,0x04,0x0b,0x00,0x00,0x00,0x00,0x00,0xd4,0x10,0x53,0x04,0x0b,0x00,0x52,0x04,
-       0x0b,0x00,0x11,0x04,0x0b,0x00,0x00,0x00,0xd3,0x10,0x52,0x04,0x10,0xe6,0x91,0x08,
-       0x10,0x04,0x10,0xe6,0x10,0xdc,0x10,0xdc,0xd2,0x0c,0x51,0x04,0x10,0xdc,0x10,0x04,
-       0x10,0xdc,0x10,0xe6,0xd1,0x08,0x10,0x04,0x10,0xe6,0x10,0xdc,0x10,0x04,0x10,0x00,
-       0x00,0x00,0xcf,0x06,0x00,0x00,0xe1,0x1e,0x01,0xd0,0xaa,0xcf,0x86,0xd5,0x6e,0xd4,
-       0x53,0xd3,0x17,0x52,0x04,0x09,0x00,0x51,0x04,0x09,0x00,0x10,0x0b,0x09,0xff,0xe1,
-       0xac,0x85,0xe1,0xac,0xb5,0x00,0x09,0x00,0xd2,0x1e,0xd1,0x0f,0x10,0x0b,0x09,0xff,
-       0xe1,0xac,0x87,0xe1,0xac,0xb5,0x00,0x09,0x00,0x10,0x0b,0x09,0xff,0xe1,0xac,0x89,
-       0xe1,0xac,0xb5,0x00,0x09,0x00,0xd1,0x0f,0x10,0x0b,0x09,0xff,0xe1,0xac,0x8b,0xe1,
-       0xac,0xb5,0x00,0x09,0x00,0x10,0x0b,0x09,0xff,0xe1,0xac,0x8d,0xe1,0xac,0xb5,0x00,
-       0x09,0x00,0x93,0x17,0x92,0x13,0x51,0x04,0x09,0x00,0x10,0x0b,0x09,0xff,0xe1,0xac,
-       0x91,0xe1,0xac,0xb5,0x00,0x09,0x00,0x09,0x00,0x09,0x00,0x54,0x04,0x09,0x00,0xd3,
-       0x10,0x52,0x04,0x09,0x00,0x91,0x08,0x10,0x04,0x09,0x07,0x09,0x00,0x09,0x00,0xd2,
-       0x13,0x51,0x04,0x09,0x00,0x10,0x04,0x09,0x00,0x09,0xff,0xe1,0xac,0xba,0xe1,0xac,
-       0xb5,0x00,0x91,0x0f,0x10,0x04,0x09,0x00,0x09,0xff,0xe1,0xac,0xbc,0xe1,0xac,0xb5,
-       0x00,0x09,0x00,0xcf,0x86,0xd5,0x3d,0x94,0x39,0xd3,0x31,0xd2,0x25,0xd1,0x16,0x10,
-       0x0b,0x09,0xff,0xe1,0xac,0xbe,0xe1,0xac,0xb5,0x00,0x09,0xff,0xe1,0xac,0xbf,0xe1,
-       0xac,0xb5,0x00,0x10,0x04,0x09,0x00,0x09,0xff,0xe1,0xad,0x82,0xe1,0xac,0xb5,0x00,
-       0x91,0x08,0x10,0x04,0x09,0x09,0x09,0x00,0x09,0x00,0x12,0x04,0x09,0x00,0x00,0x00,
-       0x09,0x00,0xd4,0x1c,0x53,0x04,0x09,0x00,0xd2,0x0c,0x51,0x04,0x09,0x00,0x10,0x04,
-       0x09,0x00,0x09,0xe6,0x91,0x08,0x10,0x04,0x09,0xdc,0x09,0xe6,0x09,0xe6,0xd3,0x08,
-       0x12,0x04,0x09,0xe6,0x09,0x00,0x52,0x04,0x09,0x00,0x91,0x08,0x10,0x04,0x09,0x00,
-       0x00,0x00,0x00,0x00,0xd0,0x2e,0xcf,0x86,0x55,0x04,0x0a,0x00,0xd4,0x18,0x53,0x04,
-       0x0a,0x00,0xd2,0x0c,0x51,0x04,0x0a,0x00,0x10,0x04,0x0a,0x09,0x0d,0x09,0x11,0x04,
-       0x0d,0x00,0x0a,0x00,0x53,0x04,0x0a,0x00,0x92,0x08,0x11,0x04,0x0a,0x00,0x0d,0x00,
-       0x0d,0x00,0xcf,0x86,0x55,0x04,0x0c,0x00,0xd4,0x14,0x93,0x10,0x52,0x04,0x0c,0x00,
-       0x51,0x04,0x0c,0x00,0x10,0x04,0x0c,0x07,0x0c,0x00,0x0c,0x00,0xd3,0x0c,0x92,0x08,
-       0x11,0x04,0x0c,0x00,0x0c,0x09,0x00,0x00,0x12,0x04,0x00,0x00,0x0c,0x00,0xe3,0xb2,
-       0x01,0xe2,0x09,0x01,0xd1,0x4c,0xd0,0x2a,0xcf,0x86,0x55,0x04,0x0a,0x00,0x54,0x04,
-       0x0a,0x00,0xd3,0x10,0x52,0x04,0x0a,0x00,0x51,0x04,0x0a,0x00,0x10,0x04,0x0a,0x00,
-       0x0a,0x07,0x92,0x0c,0x51,0x04,0x00,0x00,0x10,0x04,0x00,0x00,0x0a,0x00,0x0a,0x00,
-       0xcf,0x86,0x95,0x1c,0x94,0x18,0x53,0x04,0x0a,0x00,0xd2,0x08,0x11,0x04,0x0a,0x00,
-       0x00,0x00,0x91,0x08,0x10,0x04,0x00,0x00,0x0a,0x00,0x0a,0x00,0x0a,0x00,0x0a,0x00,
-       0xd0,0x3a,0xcf,0x86,0xd5,0x18,0x94,0x14,0x53,0x04,0x12,0x00,0x92,0x0c,0x91,0x08,
-       0x10,0x04,0x12,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x14,0x00,0x54,0x04,0x14,0x00,
-       0x53,0x04,0x14,0x00,0xd2,0x0c,0x51,0x04,0x14,0x00,0x10,0x04,0x14,0x00,0x00,0x00,
-       0x91,0x08,0x10,0x04,0x00,0x00,0x14,0x00,0x14,0x00,0xcf,0x86,0xd5,0x2c,0xd4,0x08,
-       0x13,0x04,0x0d,0x00,0x00,0x00,0xd3,0x18,0xd2,0x0c,0x51,0x04,0x0b,0xe6,0x10,0x04,
-       0x0b,0xe6,0x0b,0x00,0x91,0x08,0x10,0x04,0x0b,0x01,0x0b,0xdc,0x0b,0xdc,0x92,0x08,
-       0x11,0x04,0x0b,0xdc,0x0b,0xe6,0x0b,0xdc,0xd4,0x28,0xd3,0x10,0x92,0x0c,0x91,0x08,
-       0x10,0x04,0x0b,0xe6,0x0b,0x00,0x0b,0x01,0x0b,0x01,0xd2,0x0c,0x91,0x08,0x10,0x04,
-       0x0b,0x01,0x0b,0x00,0x0b,0x00,0x91,0x08,0x10,0x04,0x0b,0x00,0x0b,0xdc,0x0b,0x00,
-       0xd3,0x1c,0xd2,0x0c,0x51,0x04,0x0b,0x00,0x10,0x04,0x0b,0x00,0x0d,0x00,0xd1,0x08,
-       0x10,0x04,0x0d,0xe6,0x0d,0x00,0x10,0x04,0x0d,0x00,0x13,0x00,0x92,0x0c,0x51,0x04,
-       0x10,0xe6,0x10,0x04,0x15,0x00,0x00,0x00,0x00,0x00,0xd1,0x1c,0xd0,0x06,0xcf,0x06,
-       0x07,0x00,0xcf,0x86,0x55,0x04,0x07,0x00,0x94,0x0c,0x53,0x04,0x07,0x00,0x12,0x04,
-       0x07,0x00,0x08,0x00,0x08,0x00,0xd0,0x06,0xcf,0x06,0x08,0x00,0xcf,0x86,0xd5,0x40,
-       0xd4,0x2c,0xd3,0x10,0x92,0x0c,0x51,0x04,0x08,0xe6,0x10,0x04,0x08,0xdc,0x08,0xe6,
-       0x09,0xe6,0xd2,0x0c,0x51,0x04,0x09,0xe6,0x10,0x04,0x09,0xdc,0x0a,0xe6,0xd1,0x08,
-       0x10,0x04,0x0a,0xe6,0x0a,0xea,0x10,0x04,0x0a,0xd6,0x0a,0xdc,0x93,0x10,0x92,0x0c,
-       0x91,0x08,0x10,0x04,0x0a,0xca,0x0a,0xe6,0x0a,0xe6,0x0a,0xe6,0x0a,0xe6,0xd4,0x14,
-       0x93,0x10,0x52,0x04,0x0a,0xe6,0x51,0x04,0x0a,0xe6,0x10,0x04,0x0a,0xe6,0x10,0xe6,
-       0x10,0xe6,0xd3,0x10,0x52,0x04,0x10,0xe6,0x51,0x04,0x10,0xe6,0x10,0x04,0x13,0xe8,
-       0x13,0xe4,0xd2,0x10,0xd1,0x08,0x10,0x04,0x13,0xe4,0x13,0xdc,0x10,0x04,0x00,0x00,
-       0x12,0xe6,0xd1,0x08,0x10,0x04,0x0c,0xe9,0x0b,0xdc,0x10,0x04,0x09,0xe6,0x09,0xdc,
-       0xe2,0x80,0x08,0xe1,0x48,0x04,0xe0,0x1c,0x02,0xcf,0x86,0xe5,0x11,0x01,0xd4,0x84,
-       0xd3,0x40,0xd2,0x20,0xd1,0x10,0x10,0x08,0x01,0xff,0x41,0xcc,0xa5,0x00,0x01,0xff,
-       0x61,0xcc,0xa5,0x00,0x10,0x08,0x01,0xff,0x42,0xcc,0x87,0x00,0x01,0xff,0x62,0xcc,
-       0x87,0x00,0xd1,0x10,0x10,0x08,0x01,0xff,0x42,0xcc,0xa3,0x00,0x01,0xff,0x62,0xcc,
-       0xa3,0x00,0x10,0x08,0x01,0xff,0x42,0xcc,0xb1,0x00,0x01,0xff,0x62,0xcc,0xb1,0x00,
-       0xd2,0x24,0xd1,0x14,0x10,0x0a,0x01,0xff,0x43,0xcc,0xa7,0xcc,0x81,0x00,0x01,0xff,
-       0x63,0xcc,0xa7,0xcc,0x81,0x00,0x10,0x08,0x01,0xff,0x44,0xcc,0x87,0x00,0x01,0xff,
-       0x64,0xcc,0x87,0x00,0xd1,0x10,0x10,0x08,0x01,0xff,0x44,0xcc,0xa3,0x00,0x01,0xff,
-       0x64,0xcc,0xa3,0x00,0x10,0x08,0x01,0xff,0x44,0xcc,0xb1,0x00,0x01,0xff,0x64,0xcc,
-       0xb1,0x00,0xd3,0x48,0xd2,0x20,0xd1,0x10,0x10,0x08,0x01,0xff,0x44,0xcc,0xa7,0x00,
-       0x01,0xff,0x64,0xcc,0xa7,0x00,0x10,0x08,0x01,0xff,0x44,0xcc,0xad,0x00,0x01,0xff,
-       0x64,0xcc,0xad,0x00,0xd1,0x14,0x10,0x0a,0x01,0xff,0x45,0xcc,0x84,0xcc,0x80,0x00,
-       0x01,0xff,0x65,0xcc,0x84,0xcc,0x80,0x00,0x10,0x0a,0x01,0xff,0x45,0xcc,0x84,0xcc,
-       0x81,0x00,0x01,0xff,0x65,0xcc,0x84,0xcc,0x81,0x00,0xd2,0x20,0xd1,0x10,0x10,0x08,
-       0x01,0xff,0x45,0xcc,0xad,0x00,0x01,0xff,0x65,0xcc,0xad,0x00,0x10,0x08,0x01,0xff,
-       0x45,0xcc,0xb0,0x00,0x01,0xff,0x65,0xcc,0xb0,0x00,0xd1,0x14,0x10,0x0a,0x01,0xff,
-       0x45,0xcc,0xa7,0xcc,0x86,0x00,0x01,0xff,0x65,0xcc,0xa7,0xcc,0x86,0x00,0x10,0x08,
-       0x01,0xff,0x46,0xcc,0x87,0x00,0x01,0xff,0x66,0xcc,0x87,0x00,0xd4,0x84,0xd3,0x40,
-       0xd2,0x20,0xd1,0x10,0x10,0x08,0x01,0xff,0x47,0xcc,0x84,0x00,0x01,0xff,0x67,0xcc,
-       0x84,0x00,0x10,0x08,0x01,0xff,0x48,0xcc,0x87,0x00,0x01,0xff,0x68,0xcc,0x87,0x00,
-       0xd1,0x10,0x10,0x08,0x01,0xff,0x48,0xcc,0xa3,0x00,0x01,0xff,0x68,0xcc,0xa3,0x00,
-       0x10,0x08,0x01,0xff,0x48,0xcc,0x88,0x00,0x01,0xff,0x68,0xcc,0x88,0x00,0xd2,0x20,
-       0xd1,0x10,0x10,0x08,0x01,0xff,0x48,0xcc,0xa7,0x00,0x01,0xff,0x68,0xcc,0xa7,0x00,
-       0x10,0x08,0x01,0xff,0x48,0xcc,0xae,0x00,0x01,0xff,0x68,0xcc,0xae,0x00,0xd1,0x10,
-       0x10,0x08,0x01,0xff,0x49,0xcc,0xb0,0x00,0x01,0xff,0x69,0xcc,0xb0,0x00,0x10,0x0a,
-       0x01,0xff,0x49,0xcc,0x88,0xcc,0x81,0x00,0x01,0xff,0x69,0xcc,0x88,0xcc,0x81,0x00,
-       0xd3,0x40,0xd2,0x20,0xd1,0x10,0x10,0x08,0x01,0xff,0x4b,0xcc,0x81,0x00,0x01,0xff,
-       0x6b,0xcc,0x81,0x00,0x10,0x08,0x01,0xff,0x4b,0xcc,0xa3,0x00,0x01,0xff,0x6b,0xcc,
-       0xa3,0x00,0xd1,0x10,0x10,0x08,0x01,0xff,0x4b,0xcc,0xb1,0x00,0x01,0xff,0x6b,0xcc,
-       0xb1,0x00,0x10,0x08,0x01,0xff,0x4c,0xcc,0xa3,0x00,0x01,0xff,0x6c,0xcc,0xa3,0x00,
-       0xd2,0x24,0xd1,0x14,0x10,0x0a,0x01,0xff,0x4c,0xcc,0xa3,0xcc,0x84,0x00,0x01,0xff,
-       0x6c,0xcc,0xa3,0xcc,0x84,0x00,0x10,0x08,0x01,0xff,0x4c,0xcc,0xb1,0x00,0x01,0xff,
-       0x6c,0xcc,0xb1,0x00,0xd1,0x10,0x10,0x08,0x01,0xff,0x4c,0xcc,0xad,0x00,0x01,0xff,
-       0x6c,0xcc,0xad,0x00,0x10,0x08,0x01,0xff,0x4d,0xcc,0x81,0x00,0x01,0xff,0x6d,0xcc,
-       0x81,0x00,0xcf,0x86,0xe5,0x15,0x01,0xd4,0x88,0xd3,0x40,0xd2,0x20,0xd1,0x10,0x10,
-       0x08,0x01,0xff,0x4d,0xcc,0x87,0x00,0x01,0xff,0x6d,0xcc,0x87,0x00,0x10,0x08,0x01,
-       0xff,0x4d,0xcc,0xa3,0x00,0x01,0xff,0x6d,0xcc,0xa3,0x00,0xd1,0x10,0x10,0x08,0x01,
-       0xff,0x4e,0xcc,0x87,0x00,0x01,0xff,0x6e,0xcc,0x87,0x00,0x10,0x08,0x01,0xff,0x4e,
-       0xcc,0xa3,0x00,0x01,0xff,0x6e,0xcc,0xa3,0x00,0xd2,0x20,0xd1,0x10,0x10,0x08,0x01,
-       0xff,0x4e,0xcc,0xb1,0x00,0x01,0xff,0x6e,0xcc,0xb1,0x00,0x10,0x08,0x01,0xff,0x4e,
-       0xcc,0xad,0x00,0x01,0xff,0x6e,0xcc,0xad,0x00,0xd1,0x14,0x10,0x0a,0x01,0xff,0x4f,
-       0xcc,0x83,0xcc,0x81,0x00,0x01,0xff,0x6f,0xcc,0x83,0xcc,0x81,0x00,0x10,0x0a,0x01,
-       0xff,0x4f,0xcc,0x83,0xcc,0x88,0x00,0x01,0xff,0x6f,0xcc,0x83,0xcc,0x88,0x00,0xd3,
-       0x48,0xd2,0x28,0xd1,0x14,0x10,0x0a,0x01,0xff,0x4f,0xcc,0x84,0xcc,0x80,0x00,0x01,
-       0xff,0x6f,0xcc,0x84,0xcc,0x80,0x00,0x10,0x0a,0x01,0xff,0x4f,0xcc,0x84,0xcc,0x81,
-       0x00,0x01,0xff,0x6f,0xcc,0x84,0xcc,0x81,0x00,0xd1,0x10,0x10,0x08,0x01,0xff,0x50,
-       0xcc,0x81,0x00,0x01,0xff,0x70,0xcc,0x81,0x00,0x10,0x08,0x01,0xff,0x50,0xcc,0x87,
-       0x00,0x01,0xff,0x70,0xcc,0x87,0x00,0xd2,0x20,0xd1,0x10,0x10,0x08,0x01,0xff,0x52,
-       0xcc,0x87,0x00,0x01,0xff,0x72,0xcc,0x87,0x00,0x10,0x08,0x01,0xff,0x52,0xcc,0xa3,
-       0x00,0x01,0xff,0x72,0xcc,0xa3,0x00,0xd1,0x14,0x10,0x0a,0x01,0xff,0x52,0xcc,0xa3,
-       0xcc,0x84,0x00,0x01,0xff,0x72,0xcc,0xa3,0xcc,0x84,0x00,0x10,0x08,0x01,0xff,0x52,
-       0xcc,0xb1,0x00,0x01,0xff,0x72,0xcc,0xb1,0x00,0xd4,0x8c,0xd3,0x48,0xd2,0x20,0xd1,
-       0x10,0x10,0x08,0x01,0xff,0x53,0xcc,0x87,0x00,0x01,0xff,0x73,0xcc,0x87,0x00,0x10,
-       0x08,0x01,0xff,0x53,0xcc,0xa3,0x00,0x01,0xff,0x73,0xcc,0xa3,0x00,0xd1,0x14,0x10,
-       0x0a,0x01,0xff,0x53,0xcc,0x81,0xcc,0x87,0x00,0x01,0xff,0x73,0xcc,0x81,0xcc,0x87,
-       0x00,0x10,0x0a,0x01,0xff,0x53,0xcc,0x8c,0xcc,0x87,0x00,0x01,0xff,0x73,0xcc,0x8c,
-       0xcc,0x87,0x00,0xd2,0x24,0xd1,0x14,0x10,0x0a,0x01,0xff,0x53,0xcc,0xa3,0xcc,0x87,
-       0x00,0x01,0xff,0x73,0xcc,0xa3,0xcc,0x87,0x00,0x10,0x08,0x01,0xff,0x54,0xcc,0x87,
-       0x00,0x01,0xff,0x74,0xcc,0x87,0x00,0xd1,0x10,0x10,0x08,0x01,0xff,0x54,0xcc,0xa3,
-       0x00,0x01,0xff,0x74,0xcc,0xa3,0x00,0x10,0x08,0x01,0xff,0x54,0xcc,0xb1,0x00,0x01,
-       0xff,0x74,0xcc,0xb1,0x00,0xd3,0x40,0xd2,0x20,0xd1,0x10,0x10,0x08,0x01,0xff,0x54,
-       0xcc,0xad,0x00,0x01,0xff,0x74,0xcc,0xad,0x00,0x10,0x08,0x01,0xff,0x55,0xcc,0xa4,
-       0x00,0x01,0xff,0x75,0xcc,0xa4,0x00,0xd1,0x10,0x10,0x08,0x01,0xff,0x55,0xcc,0xb0,
-       0x00,0x01,0xff,0x75,0xcc,0xb0,0x00,0x10,0x08,0x01,0xff,0x55,0xcc,0xad,0x00,0x01,
-       0xff,0x75,0xcc,0xad,0x00,0xd2,0x28,0xd1,0x14,0x10,0x0a,0x01,0xff,0x55,0xcc,0x83,
-       0xcc,0x81,0x00,0x01,0xff,0x75,0xcc,0x83,0xcc,0x81,0x00,0x10,0x0a,0x01,0xff,0x55,
-       0xcc,0x84,0xcc,0x88,0x00,0x01,0xff,0x75,0xcc,0x84,0xcc,0x88,0x00,0xd1,0x10,0x10,
-       0x08,0x01,0xff,0x56,0xcc,0x83,0x00,0x01,0xff,0x76,0xcc,0x83,0x00,0x10,0x08,0x01,
-       0xff,0x56,0xcc,0xa3,0x00,0x01,0xff,0x76,0xcc,0xa3,0x00,0xe0,0x10,0x02,0xcf,0x86,
-       0xd5,0xe1,0xd4,0x80,0xd3,0x40,0xd2,0x20,0xd1,0x10,0x10,0x08,0x01,0xff,0x57,0xcc,
-       0x80,0x00,0x01,0xff,0x77,0xcc,0x80,0x00,0x10,0x08,0x01,0xff,0x57,0xcc,0x81,0x00,
-       0x01,0xff,0x77,0xcc,0x81,0x00,0xd1,0x10,0x10,0x08,0x01,0xff,0x57,0xcc,0x88,0x00,
-       0x01,0xff,0x77,0xcc,0x88,0x00,0x10,0x08,0x01,0xff,0x57,0xcc,0x87,0x00,0x01,0xff,
-       0x77,0xcc,0x87,0x00,0xd2,0x20,0xd1,0x10,0x10,0x08,0x01,0xff,0x57,0xcc,0xa3,0x00,
-       0x01,0xff,0x77,0xcc,0xa3,0x00,0x10,0x08,0x01,0xff,0x58,0xcc,0x87,0x00,0x01,0xff,
-       0x78,0xcc,0x87,0x00,0xd1,0x10,0x10,0x08,0x01,0xff,0x58,0xcc,0x88,0x00,0x01,0xff,
-       0x78,0xcc,0x88,0x00,0x10,0x08,0x01,0xff,0x59,0xcc,0x87,0x00,0x01,0xff,0x79,0xcc,
-       0x87,0x00,0xd3,0x40,0xd2,0x20,0xd1,0x10,0x10,0x08,0x01,0xff,0x5a,0xcc,0x82,0x00,
-       0x01,0xff,0x7a,0xcc,0x82,0x00,0x10,0x08,0x01,0xff,0x5a,0xcc,0xa3,0x00,0x01,0xff,
-       0x7a,0xcc,0xa3,0x00,0xd1,0x10,0x10,0x08,0x01,0xff,0x5a,0xcc,0xb1,0x00,0x01,0xff,
-       0x7a,0xcc,0xb1,0x00,0x10,0x08,0x01,0xff,0x68,0xcc,0xb1,0x00,0x01,0xff,0x74,0xcc,
-       0x88,0x00,0x92,0x1d,0xd1,0x10,0x10,0x08,0x01,0xff,0x77,0xcc,0x8a,0x00,0x01,0xff,
-       0x79,0xcc,0x8a,0x00,0x10,0x04,0x01,0x00,0x02,0xff,0xc5,0xbf,0xcc,0x87,0x00,0x0a,
-       0x00,0xd4,0x98,0xd3,0x48,0xd2,0x20,0xd1,0x10,0x10,0x08,0x01,0xff,0x41,0xcc,0xa3,
-       0x00,0x01,0xff,0x61,0xcc,0xa3,0x00,0x10,0x08,0x01,0xff,0x41,0xcc,0x89,0x00,0x01,
-       0xff,0x61,0xcc,0x89,0x00,0xd1,0x14,0x10,0x0a,0x01,0xff,0x41,0xcc,0x82,0xcc,0x81,
-       0x00,0x01,0xff,0x61,0xcc,0x82,0xcc,0x81,0x00,0x10,0x0a,0x01,0xff,0x41,0xcc,0x82,
-       0xcc,0x80,0x00,0x01,0xff,0x61,0xcc,0x82,0xcc,0x80,0x00,0xd2,0x28,0xd1,0x14,0x10,
-       0x0a,0x01,0xff,0x41,0xcc,0x82,0xcc,0x89,0x00,0x01,0xff,0x61,0xcc,0x82,0xcc,0x89,
-       0x00,0x10,0x0a,0x01,0xff,0x41,0xcc,0x82,0xcc,0x83,0x00,0x01,0xff,0x61,0xcc,0x82,
-       0xcc,0x83,0x00,0xd1,0x14,0x10,0x0a,0x01,0xff,0x41,0xcc,0xa3,0xcc,0x82,0x00,0x01,
-       0xff,0x61,0xcc,0xa3,0xcc,0x82,0x00,0x10,0x0a,0x01,0xff,0x41,0xcc,0x86,0xcc,0x81,
-       0x00,0x01,0xff,0x61,0xcc,0x86,0xcc,0x81,0x00,0xd3,0x50,0xd2,0x28,0xd1,0x14,0x10,
-       0x0a,0x01,0xff,0x41,0xcc,0x86,0xcc,0x80,0x00,0x01,0xff,0x61,0xcc,0x86,0xcc,0x80,
-       0x00,0x10,0x0a,0x01,0xff,0x41,0xcc,0x86,0xcc,0x89,0x00,0x01,0xff,0x61,0xcc,0x86,
-       0xcc,0x89,0x00,0xd1,0x14,0x10,0x0a,0x01,0xff,0x41,0xcc,0x86,0xcc,0x83,0x00,0x01,
-       0xff,0x61,0xcc,0x86,0xcc,0x83,0x00,0x10,0x0a,0x01,0xff,0x41,0xcc,0xa3,0xcc,0x86,
-       0x00,0x01,0xff,0x61,0xcc,0xa3,0xcc,0x86,0x00,0xd2,0x20,0xd1,0x10,0x10,0x08,0x01,
-       0xff,0x45,0xcc,0xa3,0x00,0x01,0xff,0x65,0xcc,0xa3,0x00,0x10,0x08,0x01,0xff,0x45,
-       0xcc,0x89,0x00,0x01,0xff,0x65,0xcc,0x89,0x00,0xd1,0x10,0x10,0x08,0x01,0xff,0x45,
-       0xcc,0x83,0x00,0x01,0xff,0x65,0xcc,0x83,0x00,0x10,0x0a,0x01,0xff,0x45,0xcc,0x82,
-       0xcc,0x81,0x00,0x01,0xff,0x65,0xcc,0x82,0xcc,0x81,0x00,0xcf,0x86,0xe5,0x31,0x01,
-       0xd4,0x90,0xd3,0x50,0xd2,0x28,0xd1,0x14,0x10,0x0a,0x01,0xff,0x45,0xcc,0x82,0xcc,
-       0x80,0x00,0x01,0xff,0x65,0xcc,0x82,0xcc,0x80,0x00,0x10,0x0a,0x01,0xff,0x45,0xcc,
-       0x82,0xcc,0x89,0x00,0x01,0xff,0x65,0xcc,0x82,0xcc,0x89,0x00,0xd1,0x14,0x10,0x0a,
-       0x01,0xff,0x45,0xcc,0x82,0xcc,0x83,0x00,0x01,0xff,0x65,0xcc,0x82,0xcc,0x83,0x00,
-       0x10,0x0a,0x01,0xff,0x45,0xcc,0xa3,0xcc,0x82,0x00,0x01,0xff,0x65,0xcc,0xa3,0xcc,
-       0x82,0x00,0xd2,0x20,0xd1,0x10,0x10,0x08,0x01,0xff,0x49,0xcc,0x89,0x00,0x01,0xff,
-       0x69,0xcc,0x89,0x00,0x10,0x08,0x01,0xff,0x49,0xcc,0xa3,0x00,0x01,0xff,0x69,0xcc,
-       0xa3,0x00,0xd1,0x10,0x10,0x08,0x01,0xff,0x4f,0xcc,0xa3,0x00,0x01,0xff,0x6f,0xcc,
-       0xa3,0x00,0x10,0x08,0x01,0xff,0x4f,0xcc,0x89,0x00,0x01,0xff,0x6f,0xcc,0x89,0x00,
-       0xd3,0x50,0xd2,0x28,0xd1,0x14,0x10,0x0a,0x01,0xff,0x4f,0xcc,0x82,0xcc,0x81,0x00,
-       0x01,0xff,0x6f,0xcc,0x82,0xcc,0x81,0x00,0x10,0x0a,0x01,0xff,0x4f,0xcc,0x82,0xcc,
-       0x80,0x00,0x01,0xff,0x6f,0xcc,0x82,0xcc,0x80,0x00,0xd1,0x14,0x10,0x0a,0x01,0xff,
-       0x4f,0xcc,0x82,0xcc,0x89,0x00,0x01,0xff,0x6f,0xcc,0x82,0xcc,0x89,0x00,0x10,0x0a,
-       0x01,0xff,0x4f,0xcc,0x82,0xcc,0x83,0x00,0x01,0xff,0x6f,0xcc,0x82,0xcc,0x83,0x00,
-       0xd2,0x28,0xd1,0x14,0x10,0x0a,0x01,0xff,0x4f,0xcc,0xa3,0xcc,0x82,0x00,0x01,0xff,
-       0x6f,0xcc,0xa3,0xcc,0x82,0x00,0x10,0x0a,0x01,0xff,0x4f,0xcc,0x9b,0xcc,0x81,0x00,
-       0x01,0xff,0x6f,0xcc,0x9b,0xcc,0x81,0x00,0xd1,0x14,0x10,0x0a,0x01,0xff,0x4f,0xcc,
-       0x9b,0xcc,0x80,0x00,0x01,0xff,0x6f,0xcc,0x9b,0xcc,0x80,0x00,0x10,0x0a,0x01,0xff,
-       0x4f,0xcc,0x9b,0xcc,0x89,0x00,0x01,0xff,0x6f,0xcc,0x9b,0xcc,0x89,0x00,0xd4,0x98,
-       0xd3,0x48,0xd2,0x28,0xd1,0x14,0x10,0x0a,0x01,0xff,0x4f,0xcc,0x9b,0xcc,0x83,0x00,
-       0x01,0xff,0x6f,0xcc,0x9b,0xcc,0x83,0x00,0x10,0x0a,0x01,0xff,0x4f,0xcc,0x9b,0xcc,
-       0xa3,0x00,0x01,0xff,0x6f,0xcc,0x9b,0xcc,0xa3,0x00,0xd1,0x10,0x10,0x08,0x01,0xff,
-       0x55,0xcc,0xa3,0x00,0x01,0xff,0x75,0xcc,0xa3,0x00,0x10,0x08,0x01,0xff,0x55,0xcc,
-       0x89,0x00,0x01,0xff,0x75,0xcc,0x89,0x00,0xd2,0x28,0xd1,0x14,0x10,0x0a,0x01,0xff,
-       0x55,0xcc,0x9b,0xcc,0x81,0x00,0x01,0xff,0x75,0xcc,0x9b,0xcc,0x81,0x00,0x10,0x0a,
-       0x01,0xff,0x55,0xcc,0x9b,0xcc,0x80,0x00,0x01,0xff,0x75,0xcc,0x9b,0xcc,0x80,0x00,
-       0xd1,0x14,0x10,0x0a,0x01,0xff,0x55,0xcc,0x9b,0xcc,0x89,0x00,0x01,0xff,0x75,0xcc,
-       0x9b,0xcc,0x89,0x00,0x10,0x0a,0x01,0xff,0x55,0xcc,0x9b,0xcc,0x83,0x00,0x01,0xff,
-       0x75,0xcc,0x9b,0xcc,0x83,0x00,0xd3,0x44,0xd2,0x24,0xd1,0x14,0x10,0x0a,0x01,0xff,
-       0x55,0xcc,0x9b,0xcc,0xa3,0x00,0x01,0xff,0x75,0xcc,0x9b,0xcc,0xa3,0x00,0x10,0x08,
-       0x01,0xff,0x59,0xcc,0x80,0x00,0x01,0xff,0x79,0xcc,0x80,0x00,0xd1,0x10,0x10,0x08,
-       0x01,0xff,0x59,0xcc,0xa3,0x00,0x01,0xff,0x79,0xcc,0xa3,0x00,0x10,0x08,0x01,0xff,
-       0x59,0xcc,0x89,0x00,0x01,0xff,0x79,0xcc,0x89,0x00,0x92,0x14,0x91,0x10,0x10,0x08,
-       0x01,0xff,0x59,0xcc,0x83,0x00,0x01,0xff,0x79,0xcc,0x83,0x00,0x0a,0x00,0x0a,0x00,
-       0xe1,0xc0,0x04,0xe0,0x80,0x02,0xcf,0x86,0xe5,0x2d,0x01,0xd4,0xa8,0xd3,0x54,0xd2,
-       0x28,0xd1,0x12,0x10,0x09,0x01,0xff,0xce,0xb1,0xcc,0x93,0x00,0x01,0xff,0xce,0xb1,
-       0xcc,0x94,0x00,0x10,0x0b,0x01,0xff,0xce,0xb1,0xcc,0x93,0xcc,0x80,0x00,0x01,0xff,
-       0xce,0xb1,0xcc,0x94,0xcc,0x80,0x00,0xd1,0x16,0x10,0x0b,0x01,0xff,0xce,0xb1,0xcc,
-       0x93,0xcc,0x81,0x00,0x01,0xff,0xce,0xb1,0xcc,0x94,0xcc,0x81,0x00,0x10,0x0b,0x01,
-       0xff,0xce,0xb1,0xcc,0x93,0xcd,0x82,0x00,0x01,0xff,0xce,0xb1,0xcc,0x94,0xcd,0x82,
-       0x00,0xd2,0x28,0xd1,0x12,0x10,0x09,0x01,0xff,0xce,0x91,0xcc,0x93,0x00,0x01,0xff,
-       0xce,0x91,0xcc,0x94,0x00,0x10,0x0b,0x01,0xff,0xce,0x91,0xcc,0x93,0xcc,0x80,0x00,
-       0x01,0xff,0xce,0x91,0xcc,0x94,0xcc,0x80,0x00,0xd1,0x16,0x10,0x0b,0x01,0xff,0xce,
-       0x91,0xcc,0x93,0xcc,0x81,0x00,0x01,0xff,0xce,0x91,0xcc,0x94,0xcc,0x81,0x00,0x10,
-       0x0b,0x01,0xff,0xce,0x91,0xcc,0x93,0xcd,0x82,0x00,0x01,0xff,0xce,0x91,0xcc,0x94,
-       0xcd,0x82,0x00,0xd3,0x42,0xd2,0x28,0xd1,0x12,0x10,0x09,0x01,0xff,0xce,0xb5,0xcc,
-       0x93,0x00,0x01,0xff,0xce,0xb5,0xcc,0x94,0x00,0x10,0x0b,0x01,0xff,0xce,0xb5,0xcc,
-       0x93,0xcc,0x80,0x00,0x01,0xff,0xce,0xb5,0xcc,0x94,0xcc,0x80,0x00,0x91,0x16,0x10,
-       0x0b,0x01,0xff,0xce,0xb5,0xcc,0x93,0xcc,0x81,0x00,0x01,0xff,0xce,0xb5,0xcc,0x94,
-       0xcc,0x81,0x00,0x00,0x00,0xd2,0x28,0xd1,0x12,0x10,0x09,0x01,0xff,0xce,0x95,0xcc,
-       0x93,0x00,0x01,0xff,0xce,0x95,0xcc,0x94,0x00,0x10,0x0b,0x01,0xff,0xce,0x95,0xcc,
-       0x93,0xcc,0x80,0x00,0x01,0xff,0xce,0x95,0xcc,0x94,0xcc,0x80,0x00,0x91,0x16,0x10,
-       0x0b,0x01,0xff,0xce,0x95,0xcc,0x93,0xcc,0x81,0x00,0x01,0xff,0xce,0x95,0xcc,0x94,
-       0xcc,0x81,0x00,0x00,0x00,0xd4,0xa8,0xd3,0x54,0xd2,0x28,0xd1,0x12,0x10,0x09,0x01,
-       0xff,0xce,0xb7,0xcc,0x93,0x00,0x01,0xff,0xce,0xb7,0xcc,0x94,0x00,0x10,0x0b,0x01,
-       0xff,0xce,0xb7,0xcc,0x93,0xcc,0x80,0x00,0x01,0xff,0xce,0xb7,0xcc,0x94,0xcc,0x80,
-       0x00,0xd1,0x16,0x10,0x0b,0x01,0xff,0xce,0xb7,0xcc,0x93,0xcc,0x81,0x00,0x01,0xff,
-       0xce,0xb7,0xcc,0x94,0xcc,0x81,0x00,0x10,0x0b,0x01,0xff,0xce,0xb7,0xcc,0x93,0xcd,
-       0x82,0x00,0x01,0xff,0xce,0xb7,0xcc,0x94,0xcd,0x82,0x00,0xd2,0x28,0xd1,0x12,0x10,
-       0x09,0x01,0xff,0xce,0x97,0xcc,0x93,0x00,0x01,0xff,0xce,0x97,0xcc,0x94,0x00,0x10,
-       0x0b,0x01,0xff,0xce,0x97,0xcc,0x93,0xcc,0x80,0x00,0x01,0xff,0xce,0x97,0xcc,0x94,
-       0xcc,0x80,0x00,0xd1,0x16,0x10,0x0b,0x01,0xff,0xce,0x97,0xcc,0x93,0xcc,0x81,0x00,
-       0x01,0xff,0xce,0x97,0xcc,0x94,0xcc,0x81,0x00,0x10,0x0b,0x01,0xff,0xce,0x97,0xcc,
-       0x93,0xcd,0x82,0x00,0x01,0xff,0xce,0x97,0xcc,0x94,0xcd,0x82,0x00,0xd3,0x54,0xd2,
-       0x28,0xd1,0x12,0x10,0x09,0x01,0xff,0xce,0xb9,0xcc,0x93,0x00,0x01,0xff,0xce,0xb9,
-       0xcc,0x94,0x00,0x10,0x0b,0x01,0xff,0xce,0xb9,0xcc,0x93,0xcc,0x80,0x00,0x01,0xff,
-       0xce,0xb9,0xcc,0x94,0xcc,0x80,0x00,0xd1,0x16,0x10,0x0b,0x01,0xff,0xce,0xb9,0xcc,
-       0x93,0xcc,0x81,0x00,0x01,0xff,0xce,0xb9,0xcc,0x94,0xcc,0x81,0x00,0x10,0x0b,0x01,
-       0xff,0xce,0xb9,0xcc,0x93,0xcd,0x82,0x00,0x01,0xff,0xce,0xb9,0xcc,0x94,0xcd,0x82,
-       0x00,0xd2,0x28,0xd1,0x12,0x10,0x09,0x01,0xff,0xce,0x99,0xcc,0x93,0x00,0x01,0xff,
-       0xce,0x99,0xcc,0x94,0x00,0x10,0x0b,0x01,0xff,0xce,0x99,0xcc,0x93,0xcc,0x80,0x00,
-       0x01,0xff,0xce,0x99,0xcc,0x94,0xcc,0x80,0x00,0xd1,0x16,0x10,0x0b,0x01,0xff,0xce,
-       0x99,0xcc,0x93,0xcc,0x81,0x00,0x01,0xff,0xce,0x99,0xcc,0x94,0xcc,0x81,0x00,0x10,
-       0x0b,0x01,0xff,0xce,0x99,0xcc,0x93,0xcd,0x82,0x00,0x01,0xff,0xce,0x99,0xcc,0x94,
-       0xcd,0x82,0x00,0xcf,0x86,0xe5,0x13,0x01,0xd4,0x84,0xd3,0x42,0xd2,0x28,0xd1,0x12,
-       0x10,0x09,0x01,0xff,0xce,0xbf,0xcc,0x93,0x00,0x01,0xff,0xce,0xbf,0xcc,0x94,0x00,
-       0x10,0x0b,0x01,0xff,0xce,0xbf,0xcc,0x93,0xcc,0x80,0x00,0x01,0xff,0xce,0xbf,0xcc,
-       0x94,0xcc,0x80,0x00,0x91,0x16,0x10,0x0b,0x01,0xff,0xce,0xbf,0xcc,0x93,0xcc,0x81,
-       0x00,0x01,0xff,0xce,0xbf,0xcc,0x94,0xcc,0x81,0x00,0x00,0x00,0xd2,0x28,0xd1,0x12,
-       0x10,0x09,0x01,0xff,0xce,0x9f,0xcc,0x93,0x00,0x01,0xff,0xce,0x9f,0xcc,0x94,0x00,
-       0x10,0x0b,0x01,0xff,0xce,0x9f,0xcc,0x93,0xcc,0x80,0x00,0x01,0xff,0xce,0x9f,0xcc,
-       0x94,0xcc,0x80,0x00,0x91,0x16,0x10,0x0b,0x01,0xff,0xce,0x9f,0xcc,0x93,0xcc,0x81,
-       0x00,0x01,0xff,0xce,0x9f,0xcc,0x94,0xcc,0x81,0x00,0x00,0x00,0xd3,0x54,0xd2,0x28,
-       0xd1,0x12,0x10,0x09,0x01,0xff,0xcf,0x85,0xcc,0x93,0x00,0x01,0xff,0xcf,0x85,0xcc,
-       0x94,0x00,0x10,0x0b,0x01,0xff,0xcf,0x85,0xcc,0x93,0xcc,0x80,0x00,0x01,0xff,0xcf,
-       0x85,0xcc,0x94,0xcc,0x80,0x00,0xd1,0x16,0x10,0x0b,0x01,0xff,0xcf,0x85,0xcc,0x93,
-       0xcc,0x81,0x00,0x01,0xff,0xcf,0x85,0xcc,0x94,0xcc,0x81,0x00,0x10,0x0b,0x01,0xff,
-       0xcf,0x85,0xcc,0x93,0xcd,0x82,0x00,0x01,0xff,0xcf,0x85,0xcc,0x94,0xcd,0x82,0x00,
-       0xd2,0x1c,0xd1,0x0d,0x10,0x04,0x00,0x00,0x01,0xff,0xce,0xa5,0xcc,0x94,0x00,0x10,
-       0x04,0x00,0x00,0x01,0xff,0xce,0xa5,0xcc,0x94,0xcc,0x80,0x00,0xd1,0x0f,0x10,0x04,
-       0x00,0x00,0x01,0xff,0xce,0xa5,0xcc,0x94,0xcc,0x81,0x00,0x10,0x04,0x00,0x00,0x01,
-       0xff,0xce,0xa5,0xcc,0x94,0xcd,0x82,0x00,0xd4,0xa8,0xd3,0x54,0xd2,0x28,0xd1,0x12,
-       0x10,0x09,0x01,0xff,0xcf,0x89,0xcc,0x93,0x00,0x01,0xff,0xcf,0x89,0xcc,0x94,0x00,
-       0x10,0x0b,0x01,0xff,0xcf,0x89,0xcc,0x93,0xcc,0x80,0x00,0x01,0xff,0xcf,0x89,0xcc,
-       0x94,0xcc,0x80,0x00,0xd1,0x16,0x10,0x0b,0x01,0xff,0xcf,0x89,0xcc,0x93,0xcc,0x81,
-       0x00,0x01,0xff,0xcf,0x89,0xcc,0x94,0xcc,0x81,0x00,0x10,0x0b,0x01,0xff,0xcf,0x89,
-       0xcc,0x93,0xcd,0x82,0x00,0x01,0xff,0xcf,0x89,0xcc,0x94,0xcd,0x82,0x00,0xd2,0x28,
-       0xd1,0x12,0x10,0x09,0x01,0xff,0xce,0xa9,0xcc,0x93,0x00,0x01,0xff,0xce,0xa9,0xcc,
-       0x94,0x00,0x10,0x0b,0x01,0xff,0xce,0xa9,0xcc,0x93,0xcc,0x80,0x00,0x01,0xff,0xce,
-       0xa9,0xcc,0x94,0xcc,0x80,0x00,0xd1,0x16,0x10,0x0b,0x01,0xff,0xce,0xa9,0xcc,0x93,
-       0xcc,0x81,0x00,0x01,0xff,0xce,0xa9,0xcc,0x94,0xcc,0x81,0x00,0x10,0x0b,0x01,0xff,
-       0xce,0xa9,0xcc,0x93,0xcd,0x82,0x00,0x01,0xff,0xce,0xa9,0xcc,0x94,0xcd,0x82,0x00,
-       0xd3,0x48,0xd2,0x24,0xd1,0x12,0x10,0x09,0x01,0xff,0xce,0xb1,0xcc,0x80,0x00,0x01,
-       0xff,0xce,0xb1,0xcc,0x81,0x00,0x10,0x09,0x01,0xff,0xce,0xb5,0xcc,0x80,0x00,0x01,
-       0xff,0xce,0xb5,0xcc,0x81,0x00,0xd1,0x12,0x10,0x09,0x01,0xff,0xce,0xb7,0xcc,0x80,
-       0x00,0x01,0xff,0xce,0xb7,0xcc,0x81,0x00,0x10,0x09,0x01,0xff,0xce,0xb9,0xcc,0x80,
-       0x00,0x01,0xff,0xce,0xb9,0xcc,0x81,0x00,0xd2,0x24,0xd1,0x12,0x10,0x09,0x01,0xff,
-       0xce,0xbf,0xcc,0x80,0x00,0x01,0xff,0xce,0xbf,0xcc,0x81,0x00,0x10,0x09,0x01,0xff,
-       0xcf,0x85,0xcc,0x80,0x00,0x01,0xff,0xcf,0x85,0xcc,0x81,0x00,0x91,0x12,0x10,0x09,
-       0x01,0xff,0xcf,0x89,0xcc,0x80,0x00,0x01,0xff,0xcf,0x89,0xcc,0x81,0x00,0x00,0x00,
-       0xe0,0xe1,0x02,0xcf,0x86,0xe5,0x91,0x01,0xd4,0xc8,0xd3,0x64,0xd2,0x30,0xd1,0x16,
-       0x10,0x0b,0x01,0xff,0xce,0xb1,0xcc,0x93,0xcd,0x85,0x00,0x01,0xff,0xce,0xb1,0xcc,
-       0x94,0xcd,0x85,0x00,0x10,0x0d,0x01,0xff,0xce,0xb1,0xcc,0x93,0xcc,0x80,0xcd,0x85,
-       0x00,0x01,0xff,0xce,0xb1,0xcc,0x94,0xcc,0x80,0xcd,0x85,0x00,0xd1,0x1a,0x10,0x0d,
-       0x01,0xff,0xce,0xb1,0xcc,0x93,0xcc,0x81,0xcd,0x85,0x00,0x01,0xff,0xce,0xb1,0xcc,
-       0x94,0xcc,0x81,0xcd,0x85,0x00,0x10,0x0d,0x01,0xff,0xce,0xb1,0xcc,0x93,0xcd,0x82,
-       0xcd,0x85,0x00,0x01,0xff,0xce,0xb1,0xcc,0x94,0xcd,0x82,0xcd,0x85,0x00,0xd2,0x30,
-       0xd1,0x16,0x10,0x0b,0x01,0xff,0xce,0x91,0xcc,0x93,0xcd,0x85,0x00,0x01,0xff,0xce,
-       0x91,0xcc,0x94,0xcd,0x85,0x00,0x10,0x0d,0x01,0xff,0xce,0x91,0xcc,0x93,0xcc,0x80,
-       0xcd,0x85,0x00,0x01,0xff,0xce,0x91,0xcc,0x94,0xcc,0x80,0xcd,0x85,0x00,0xd1,0x1a,
-       0x10,0x0d,0x01,0xff,0xce,0x91,0xcc,0x93,0xcc,0x81,0xcd,0x85,0x00,0x01,0xff,0xce,
-       0x91,0xcc,0x94,0xcc,0x81,0xcd,0x85,0x00,0x10,0x0d,0x01,0xff,0xce,0x91,0xcc,0x93,
-       0xcd,0x82,0xcd,0x85,0x00,0x01,0xff,0xce,0x91,0xcc,0x94,0xcd,0x82,0xcd,0x85,0x00,
-       0xd3,0x64,0xd2,0x30,0xd1,0x16,0x10,0x0b,0x01,0xff,0xce,0xb7,0xcc,0x93,0xcd,0x85,
-       0x00,0x01,0xff,0xce,0xb7,0xcc,0x94,0xcd,0x85,0x00,0x10,0x0d,0x01,0xff,0xce,0xb7,
-       0xcc,0x93,0xcc,0x80,0xcd,0x85,0x00,0x01,0xff,0xce,0xb7,0xcc,0x94,0xcc,0x80,0xcd,
-       0x85,0x00,0xd1,0x1a,0x10,0x0d,0x01,0xff,0xce,0xb7,0xcc,0x93,0xcc,0x81,0xcd,0x85,
-       0x00,0x01,0xff,0xce,0xb7,0xcc,0x94,0xcc,0x81,0xcd,0x85,0x00,0x10,0x0d,0x01,0xff,
-       0xce,0xb7,0xcc,0x93,0xcd,0x82,0xcd,0x85,0x00,0x01,0xff,0xce,0xb7,0xcc,0x94,0xcd,
-       0x82,0xcd,0x85,0x00,0xd2,0x30,0xd1,0x16,0x10,0x0b,0x01,0xff,0xce,0x97,0xcc,0x93,
-       0xcd,0x85,0x00,0x01,0xff,0xce,0x97,0xcc,0x94,0xcd,0x85,0x00,0x10,0x0d,0x01,0xff,
-       0xce,0x97,0xcc,0x93,0xcc,0x80,0xcd,0x85,0x00,0x01,0xff,0xce,0x97,0xcc,0x94,0xcc,
-       0x80,0xcd,0x85,0x00,0xd1,0x1a,0x10,0x0d,0x01,0xff,0xce,0x97,0xcc,0x93,0xcc,0x81,
-       0xcd,0x85,0x00,0x01,0xff,0xce,0x97,0xcc,0x94,0xcc,0x81,0xcd,0x85,0x00,0x10,0x0d,
-       0x01,0xff,0xce,0x97,0xcc,0x93,0xcd,0x82,0xcd,0x85,0x00,0x01,0xff,0xce,0x97,0xcc,
-       0x94,0xcd,0x82,0xcd,0x85,0x00,0xd4,0xc8,0xd3,0x64,0xd2,0x30,0xd1,0x16,0x10,0x0b,
-       0x01,0xff,0xcf,0x89,0xcc,0x93,0xcd,0x85,0x00,0x01,0xff,0xcf,0x89,0xcc,0x94,0xcd,
-       0x85,0x00,0x10,0x0d,0x01,0xff,0xcf,0x89,0xcc,0x93,0xcc,0x80,0xcd,0x85,0x00,0x01,
-       0xff,0xcf,0x89,0xcc,0x94,0xcc,0x80,0xcd,0x85,0x00,0xd1,0x1a,0x10,0x0d,0x01,0xff,
-       0xcf,0x89,0xcc,0x93,0xcc,0x81,0xcd,0x85,0x00,0x01,0xff,0xcf,0x89,0xcc,0x94,0xcc,
-       0x81,0xcd,0x85,0x00,0x10,0x0d,0x01,0xff,0xcf,0x89,0xcc,0x93,0xcd,0x82,0xcd,0x85,
-       0x00,0x01,0xff,0xcf,0x89,0xcc,0x94,0xcd,0x82,0xcd,0x85,0x00,0xd2,0x30,0xd1,0x16,
-       0x10,0x0b,0x01,0xff,0xce,0xa9,0xcc,0x93,0xcd,0x85,0x00,0x01,0xff,0xce,0xa9,0xcc,
-       0x94,0xcd,0x85,0x00,0x10,0x0d,0x01,0xff,0xce,0xa9,0xcc,0x93,0xcc,0x80,0xcd,0x85,
-       0x00,0x01,0xff,0xce,0xa9,0xcc,0x94,0xcc,0x80,0xcd,0x85,0x00,0xd1,0x1a,0x10,0x0d,
-       0x01,0xff,0xce,0xa9,0xcc,0x93,0xcc,0x81,0xcd,0x85,0x00,0x01,0xff,0xce,0xa9,0xcc,
-       0x94,0xcc,0x81,0xcd,0x85,0x00,0x10,0x0d,0x01,0xff,0xce,0xa9,0xcc,0x93,0xcd,0x82,
-       0xcd,0x85,0x00,0x01,0xff,0xce,0xa9,0xcc,0x94,0xcd,0x82,0xcd,0x85,0x00,0xd3,0x49,
-       0xd2,0x26,0xd1,0x12,0x10,0x09,0x01,0xff,0xce,0xb1,0xcc,0x86,0x00,0x01,0xff,0xce,
-       0xb1,0xcc,0x84,0x00,0x10,0x0b,0x01,0xff,0xce,0xb1,0xcc,0x80,0xcd,0x85,0x00,0x01,
-       0xff,0xce,0xb1,0xcd,0x85,0x00,0xd1,0x0f,0x10,0x0b,0x01,0xff,0xce,0xb1,0xcc,0x81,
-       0xcd,0x85,0x00,0x00,0x00,0x10,0x09,0x01,0xff,0xce,0xb1,0xcd,0x82,0x00,0x01,0xff,
-       0xce,0xb1,0xcd,0x82,0xcd,0x85,0x00,0xd2,0x24,0xd1,0x12,0x10,0x09,0x01,0xff,0xce,
-       0x91,0xcc,0x86,0x00,0x01,0xff,0xce,0x91,0xcc,0x84,0x00,0x10,0x09,0x01,0xff,0xce,
-       0x91,0xcc,0x80,0x00,0x01,0xff,0xce,0x91,0xcc,0x81,0x00,0xd1,0x0d,0x10,0x09,0x01,
-       0xff,0xce,0x91,0xcd,0x85,0x00,0x01,0x00,0x10,0x07,0x01,0xff,0xce,0xb9,0x00,0x01,
-       0x00,0xcf,0x86,0xe5,0x16,0x01,0xd4,0x8f,0xd3,0x44,0xd2,0x21,0xd1,0x0d,0x10,0x04,
-       0x01,0x00,0x01,0xff,0xc2,0xa8,0xcd,0x82,0x00,0x10,0x0b,0x01,0xff,0xce,0xb7,0xcc,
-       0x80,0xcd,0x85,0x00,0x01,0xff,0xce,0xb7,0xcd,0x85,0x00,0xd1,0x0f,0x10,0x0b,0x01,
-       0xff,0xce,0xb7,0xcc,0x81,0xcd,0x85,0x00,0x00,0x00,0x10,0x09,0x01,0xff,0xce,0xb7,
-       0xcd,0x82,0x00,0x01,0xff,0xce,0xb7,0xcd,0x82,0xcd,0x85,0x00,0xd2,0x24,0xd1,0x12,
-       0x10,0x09,0x01,0xff,0xce,0x95,0xcc,0x80,0x00,0x01,0xff,0xce,0x95,0xcc,0x81,0x00,
-       0x10,0x09,0x01,0xff,0xce,0x97,0xcc,0x80,0x00,0x01,0xff,0xce,0x97,0xcc,0x81,0x00,
-       0xd1,0x13,0x10,0x09,0x01,0xff,0xce,0x97,0xcd,0x85,0x00,0x01,0xff,0xe1,0xbe,0xbf,
-       0xcc,0x80,0x00,0x10,0x0a,0x01,0xff,0xe1,0xbe,0xbf,0xcc,0x81,0x00,0x01,0xff,0xe1,
-       0xbe,0xbf,0xcd,0x82,0x00,0xd3,0x40,0xd2,0x28,0xd1,0x12,0x10,0x09,0x01,0xff,0xce,
-       0xb9,0xcc,0x86,0x00,0x01,0xff,0xce,0xb9,0xcc,0x84,0x00,0x10,0x0b,0x01,0xff,0xce,
-       0xb9,0xcc,0x88,0xcc,0x80,0x00,0x01,0xff,0xce,0xb9,0xcc,0x88,0xcc,0x81,0x00,0x51,
-       0x04,0x00,0x00,0x10,0x09,0x01,0xff,0xce,0xb9,0xcd,0x82,0x00,0x01,0xff,0xce,0xb9,
-       0xcc,0x88,0xcd,0x82,0x00,0xd2,0x24,0xd1,0x12,0x10,0x09,0x01,0xff,0xce,0x99,0xcc,
-       0x86,0x00,0x01,0xff,0xce,0x99,0xcc,0x84,0x00,0x10,0x09,0x01,0xff,0xce,0x99,0xcc,
-       0x80,0x00,0x01,0xff,0xce,0x99,0xcc,0x81,0x00,0xd1,0x0e,0x10,0x04,0x00,0x00,0x01,
-       0xff,0xe1,0xbf,0xbe,0xcc,0x80,0x00,0x10,0x0a,0x01,0xff,0xe1,0xbf,0xbe,0xcc,0x81,
-       0x00,0x01,0xff,0xe1,0xbf,0xbe,0xcd,0x82,0x00,0xd4,0x93,0xd3,0x4e,0xd2,0x28,0xd1,
-       0x12,0x10,0x09,0x01,0xff,0xcf,0x85,0xcc,0x86,0x00,0x01,0xff,0xcf,0x85,0xcc,0x84,
-       0x00,0x10,0x0b,0x01,0xff,0xcf,0x85,0xcc,0x88,0xcc,0x80,0x00,0x01,0xff,0xcf,0x85,
-       0xcc,0x88,0xcc,0x81,0x00,0xd1,0x12,0x10,0x09,0x01,0xff,0xcf,0x81,0xcc,0x93,0x00,
-       0x01,0xff,0xcf,0x81,0xcc,0x94,0x00,0x10,0x09,0x01,0xff,0xcf,0x85,0xcd,0x82,0x00,
-       0x01,0xff,0xcf,0x85,0xcc,0x88,0xcd,0x82,0x00,0xd2,0x24,0xd1,0x12,0x10,0x09,0x01,
-       0xff,0xce,0xa5,0xcc,0x86,0x00,0x01,0xff,0xce,0xa5,0xcc,0x84,0x00,0x10,0x09,0x01,
-       0xff,0xce,0xa5,0xcc,0x80,0x00,0x01,0xff,0xce,0xa5,0xcc,0x81,0x00,0xd1,0x12,0x10,
-       0x09,0x01,0xff,0xce,0xa1,0xcc,0x94,0x00,0x01,0xff,0xc2,0xa8,0xcc,0x80,0x00,0x10,
-       0x09,0x01,0xff,0xc2,0xa8,0xcc,0x81,0x00,0x01,0xff,0x60,0x00,0xd3,0x3b,0xd2,0x18,
-       0x51,0x04,0x00,0x00,0x10,0x0b,0x01,0xff,0xcf,0x89,0xcc,0x80,0xcd,0x85,0x00,0x01,
-       0xff,0xcf,0x89,0xcd,0x85,0x00,0xd1,0x0f,0x10,0x0b,0x01,0xff,0xcf,0x89,0xcc,0x81,
-       0xcd,0x85,0x00,0x00,0x00,0x10,0x09,0x01,0xff,0xcf,0x89,0xcd,0x82,0x00,0x01,0xff,
-       0xcf,0x89,0xcd,0x82,0xcd,0x85,0x00,0xd2,0x24,0xd1,0x12,0x10,0x09,0x01,0xff,0xce,
-       0x9f,0xcc,0x80,0x00,0x01,0xff,0xce,0x9f,0xcc,0x81,0x00,0x10,0x09,0x01,0xff,0xce,
-       0xa9,0xcc,0x80,0x00,0x01,0xff,0xce,0xa9,0xcc,0x81,0x00,0xd1,0x10,0x10,0x09,0x01,
-       0xff,0xce,0xa9,0xcd,0x85,0x00,0x01,0xff,0xc2,0xb4,0x00,0x10,0x04,0x01,0x00,0x00,
-       0x00,0xe0,0x7e,0x0c,0xcf,0x86,0xe5,0xbb,0x08,0xe4,0x14,0x06,0xe3,0xf7,0x02,0xe2,
-       0xbd,0x01,0xd1,0xd0,0xd0,0x4f,0xcf,0x86,0xd5,0x2e,0x94,0x2a,0xd3,0x18,0x92,0x14,
-       0x91,0x10,0x10,0x08,0x01,0xff,0xe2,0x80,0x82,0x00,0x01,0xff,0xe2,0x80,0x83,0x00,
-       0x01,0x00,0x01,0x00,0x92,0x0d,0x51,0x04,0x01,0x00,0x10,0x04,0x01,0x00,0x01,0xff,
-       0x00,0x01,0xff,0x00,0x01,0x00,0x94,0x1b,0x53,0x04,0x01,0x00,0xd2,0x09,0x11,0x04,
-       0x01,0x00,0x01,0xff,0x00,0x51,0x05,0x01,0xff,0x00,0x10,0x05,0x01,0xff,0x00,0x04,
-       0x00,0x01,0x00,0xcf,0x86,0xd5,0x48,0xd4,0x1c,0xd3,0x10,0x52,0x04,0x01,0x00,0x51,
-       0x04,0x01,0x00,0x10,0x04,0x01,0x00,0x06,0x00,0x52,0x04,0x04,0x00,0x11,0x04,0x04,
-       0x00,0x06,0x00,0xd3,0x1c,0xd2,0x0c,0x51,0x04,0x06,0x00,0x10,0x04,0x06,0x00,0x07,
-       0x00,0xd1,0x08,0x10,0x04,0x07,0x00,0x08,0x00,0x10,0x04,0x08,0x00,0x06,0x00,0x52,
-       0x04,0x08,0x00,0x51,0x04,0x08,0x00,0x10,0x04,0x08,0x00,0x06,0x00,0xd4,0x23,0xd3,
-       0x14,0x52,0x05,0x06,0xff,0x00,0x91,0x0a,0x10,0x05,0x0a,0xff,0x00,0x00,0xff,0x00,
-       0x0f,0xff,0x00,0x92,0x0a,0x11,0x05,0x0f,0xff,0x00,0x01,0xff,0x00,0x01,0xff,0x00,
-       0x93,0x10,0x92,0x0c,0x91,0x08,0x10,0x04,0x01,0x00,0x06,0x00,0x00,0x00,0x01,0x00,
-       0x01,0x00,0xd0,0x7e,0xcf,0x86,0xd5,0x34,0xd4,0x14,0x53,0x04,0x01,0x00,0x52,0x04,
-       0x01,0x00,0x51,0x04,0x01,0x00,0x10,0x04,0x01,0x00,0x00,0x00,0xd3,0x10,0x52,0x04,
-       0x08,0x00,0x91,0x08,0x10,0x04,0x08,0x00,0x0c,0x00,0x0c,0x00,0x52,0x04,0x0c,0x00,
-       0x91,0x08,0x10,0x04,0x0c,0x00,0x00,0x00,0x00,0x00,0xd4,0x1c,0x53,0x04,0x01,0x00,
-       0xd2,0x0c,0x51,0x04,0x01,0x00,0x10,0x04,0x01,0x00,0x02,0x00,0x91,0x08,0x10,0x04,
-       0x03,0x00,0x04,0x00,0x04,0x00,0xd3,0x10,0xd2,0x08,0x11,0x04,0x06,0x00,0x08,0x00,
-       0x11,0x04,0x08,0x00,0x0b,0x00,0xd2,0x10,0xd1,0x08,0x10,0x04,0x0b,0x00,0x0c,0x00,
-       0x10,0x04,0x0e,0x00,0x10,0x00,0x51,0x04,0x10,0x00,0x10,0x04,0x11,0x00,0x13,0x00,
-       0xcf,0x86,0xd5,0x28,0x54,0x04,0x00,0x00,0xd3,0x0c,0x92,0x08,0x11,0x04,0x01,0xe6,
-       0x01,0x01,0x01,0xe6,0xd2,0x0c,0x51,0x04,0x01,0x01,0x10,0x04,0x01,0x01,0x01,0xe6,
-       0x91,0x08,0x10,0x04,0x01,0xe6,0x01,0x00,0x01,0x00,0xd4,0x30,0xd3,0x1c,0xd2,0x0c,
-       0x91,0x08,0x10,0x04,0x01,0x00,0x01,0xe6,0x04,0x00,0xd1,0x08,0x10,0x04,0x06,0x00,
-       0x06,0x01,0x10,0x04,0x06,0x01,0x06,0xe6,0x92,0x10,0xd1,0x08,0x10,0x04,0x06,0xdc,
-       0x06,0xe6,0x10,0x04,0x06,0x01,0x08,0x01,0x09,0xdc,0x93,0x10,0x92,0x0c,0x91,0x08,
-       0x10,0x04,0x0a,0xe6,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xd1,0x81,0xd0,0x4f,
-       0xcf,0x86,0x55,0x04,0x01,0x00,0xd4,0x29,0xd3,0x13,0x52,0x04,0x01,0x00,0x51,0x04,
-       0x01,0x00,0x10,0x07,0x01,0xff,0xce,0xa9,0x00,0x01,0x00,0x92,0x12,0x51,0x04,0x01,
-       0x00,0x10,0x06,0x01,0xff,0x4b,0x00,0x01,0xff,0x41,0xcc,0x8a,0x00,0x01,0x00,0x53,
-       0x04,0x01,0x00,0xd2,0x10,0xd1,0x08,0x10,0x04,0x01,0x00,0x04,0x00,0x10,0x04,0x04,
-       0x00,0x07,0x00,0x91,0x08,0x10,0x04,0x08,0x00,0x06,0x00,0x06,0x00,0xcf,0x86,0x95,
-       0x2c,0xd4,0x18,0x53,0x04,0x06,0x00,0x52,0x04,0x06,0x00,0xd1,0x08,0x10,0x04,0x08,
-       0x00,0x09,0x00,0x10,0x04,0x09,0x00,0x0a,0x00,0x93,0x10,0x92,0x0c,0x51,0x04,0x0b,
-       0x00,0x10,0x04,0x0b,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0xd0,0x68,0xcf,
-       0x86,0xd5,0x48,0xd4,0x28,0xd3,0x18,0xd2,0x0c,0x51,0x04,0x01,0x00,0x10,0x04,0x01,
-       0x00,0x04,0x00,0x91,0x08,0x10,0x04,0x09,0x00,0x0a,0x00,0x0a,0x00,0x92,0x0c,0x91,
-       0x08,0x10,0x04,0x0a,0x00,0x0b,0x00,0x11,0x00,0x00,0x00,0x53,0x04,0x01,0x00,0x92,
-       0x18,0x51,0x04,0x01,0x00,0x10,0x0a,0x01,0xff,0xe2,0x86,0x90,0xcc,0xb8,0x00,0x01,
-       0xff,0xe2,0x86,0x92,0xcc,0xb8,0x00,0x01,0x00,0x94,0x1a,0x53,0x04,0x01,0x00,0x52,
-       0x04,0x01,0x00,0x51,0x04,0x01,0x00,0x10,0x0a,0x01,0xff,0xe2,0x86,0x94,0xcc,0xb8,
-       0x00,0x01,0x00,0x01,0x00,0xcf,0x86,0xd5,0x2e,0x94,0x2a,0x53,0x04,0x01,0x00,0x52,
-       0x04,0x01,0x00,0xd1,0x0e,0x10,0x04,0x01,0x00,0x01,0xff,0xe2,0x87,0x90,0xcc,0xb8,
-       0x00,0x10,0x0a,0x01,0xff,0xe2,0x87,0x94,0xcc,0xb8,0x00,0x01,0xff,0xe2,0x87,0x92,
-       0xcc,0xb8,0x00,0x01,0x00,0xd4,0x14,0x53,0x04,0x01,0x00,0x92,0x0c,0x51,0x04,0x01,
-       0x00,0x10,0x04,0x01,0x00,0x04,0x00,0x04,0x00,0x93,0x08,0x12,0x04,0x04,0x00,0x06,
-       0x00,0x06,0x00,0xe2,0x38,0x02,0xe1,0x3f,0x01,0xd0,0x68,0xcf,0x86,0xd5,0x3e,0x94,
-       0x3a,0xd3,0x16,0x52,0x04,0x01,0x00,0x91,0x0e,0x10,0x0a,0x01,0xff,0xe2,0x88,0x83,
-       0xcc,0xb8,0x00,0x01,0x00,0x01,0x00,0xd2,0x12,0x91,0x0e,0x10,0x04,0x01,0x00,0x01,
-       0xff,0xe2,0x88,0x88,0xcc,0xb8,0x00,0x01,0x00,0x91,0x0e,0x10,0x0a,0x01,0xff,0xe2,
-       0x88,0x8b,0xcc,0xb8,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x94,0x24,0x93,0x20,0x52,
-       0x04,0x01,0x00,0xd1,0x0e,0x10,0x0a,0x01,0xff,0xe2,0x88,0xa3,0xcc,0xb8,0x00,0x01,
-       0x00,0x10,0x0a,0x01,0xff,0xe2,0x88,0xa5,0xcc,0xb8,0x00,0x01,0x00,0x01,0x00,0x01,
-       0x00,0xcf,0x86,0xd5,0x48,0x94,0x44,0xd3,0x2e,0xd2,0x12,0x91,0x0e,0x10,0x04,0x01,
-       0x00,0x01,0xff,0xe2,0x88,0xbc,0xcc,0xb8,0x00,0x01,0x00,0xd1,0x0e,0x10,0x0a,0x01,
-       0xff,0xe2,0x89,0x83,0xcc,0xb8,0x00,0x01,0x00,0x10,0x04,0x01,0x00,0x01,0xff,0xe2,
-       0x89,0x85,0xcc,0xb8,0x00,0x92,0x12,0x91,0x0e,0x10,0x04,0x01,0x00,0x01,0xff,0xe2,
-       0x89,0x88,0xcc,0xb8,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0xd4,0x40,0xd3,0x1e,0x92,
-       0x1a,0xd1,0x0c,0x10,0x08,0x01,0xff,0x3d,0xcc,0xb8,0x00,0x01,0x00,0x10,0x0a,0x01,
-       0xff,0xe2,0x89,0xa1,0xcc,0xb8,0x00,0x01,0x00,0x01,0x00,0x52,0x04,0x01,0x00,0xd1,
-       0x0e,0x10,0x04,0x01,0x00,0x01,0xff,0xe2,0x89,0x8d,0xcc,0xb8,0x00,0x10,0x08,0x01,
-       0xff,0x3c,0xcc,0xb8,0x00,0x01,0xff,0x3e,0xcc,0xb8,0x00,0xd3,0x30,0xd2,0x18,0x91,
-       0x14,0x10,0x0a,0x01,0xff,0xe2,0x89,0xa4,0xcc,0xb8,0x00,0x01,0xff,0xe2,0x89,0xa5,
-       0xcc,0xb8,0x00,0x01,0x00,0x91,0x14,0x10,0x0a,0x01,0xff,0xe2,0x89,0xb2,0xcc,0xb8,
-       0x00,0x01,0xff,0xe2,0x89,0xb3,0xcc,0xb8,0x00,0x01,0x00,0x92,0x18,0x91,0x14,0x10,
-       0x0a,0x01,0xff,0xe2,0x89,0xb6,0xcc,0xb8,0x00,0x01,0xff,0xe2,0x89,0xb7,0xcc,0xb8,
-       0x00,0x01,0x00,0x01,0x00,0xd0,0x86,0xcf,0x86,0xd5,0x50,0x94,0x4c,0xd3,0x30,0xd2,
-       0x18,0x91,0x14,0x10,0x0a,0x01,0xff,0xe2,0x89,0xba,0xcc,0xb8,0x00,0x01,0xff,0xe2,
-       0x89,0xbb,0xcc,0xb8,0x00,0x01,0x00,0x91,0x14,0x10,0x0a,0x01,0xff,0xe2,0x8a,0x82,
-       0xcc,0xb8,0x00,0x01,0xff,0xe2,0x8a,0x83,0xcc,0xb8,0x00,0x01,0x00,0x92,0x18,0x91,
-       0x14,0x10,0x0a,0x01,0xff,0xe2,0x8a,0x86,0xcc,0xb8,0x00,0x01,0xff,0xe2,0x8a,0x87,
-       0xcc,0xb8,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x94,0x30,0x53,0x04,0x01,0x00,0x52,
-       0x04,0x01,0x00,0xd1,0x14,0x10,0x0a,0x01,0xff,0xe2,0x8a,0xa2,0xcc,0xb8,0x00,0x01,
-       0xff,0xe2,0x8a,0xa8,0xcc,0xb8,0x00,0x10,0x0a,0x01,0xff,0xe2,0x8a,0xa9,0xcc,0xb8,
-       0x00,0x01,0xff,0xe2,0x8a,0xab,0xcc,0xb8,0x00,0x01,0x00,0xcf,0x86,0x55,0x04,0x01,
-       0x00,0xd4,0x5c,0xd3,0x2c,0x92,0x28,0xd1,0x14,0x10,0x0a,0x01,0xff,0xe2,0x89,0xbc,
-       0xcc,0xb8,0x00,0x01,0xff,0xe2,0x89,0xbd,0xcc,0xb8,0x00,0x10,0x0a,0x01,0xff,0xe2,
-       0x8a,0x91,0xcc,0xb8,0x00,0x01,0xff,0xe2,0x8a,0x92,0xcc,0xb8,0x00,0x01,0x00,0xd2,
-       0x18,0x51,0x04,0x01,0x00,0x10,0x0a,0x01,0xff,0xe2,0x8a,0xb2,0xcc,0xb8,0x00,0x01,
-       0xff,0xe2,0x8a,0xb3,0xcc,0xb8,0x00,0x91,0x14,0x10,0x0a,0x01,0xff,0xe2,0x8a,0xb4,
-       0xcc,0xb8,0x00,0x01,0xff,0xe2,0x8a,0xb5,0xcc,0xb8,0x00,0x01,0x00,0x93,0x0c,0x92,
-       0x08,0x11,0x04,0x01,0x00,0x06,0x00,0x06,0x00,0x06,0x00,0xd1,0x64,0xd0,0x3e,0xcf,
-       0x86,0xd5,0x18,0x94,0x14,0x93,0x10,0x92,0x0c,0x91,0x08,0x10,0x04,0x01,0x00,0x04,
-       0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x94,0x20,0x53,0x04,0x01,0x00,0x92,
-       0x18,0xd1,0x0c,0x10,0x04,0x01,0x00,0x01,0xff,0xe3,0x80,0x88,0x00,0x10,0x08,0x01,
-       0xff,0xe3,0x80,0x89,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0xcf,0x86,0x55,0x04,0x01,
-       0x00,0x54,0x04,0x01,0x00,0x53,0x04,0x01,0x00,0xd2,0x0c,0x51,0x04,0x01,0x00,0x10,
-       0x04,0x01,0x00,0x04,0x00,0x91,0x08,0x10,0x04,0x06,0x00,0x04,0x00,0x04,0x00,0xd0,
-       0x1e,0xcf,0x86,0x95,0x18,0x54,0x04,0x04,0x00,0x53,0x04,0x04,0x00,0x92,0x0c,0x51,
-       0x04,0x04,0x00,0x10,0x04,0x04,0x00,0x06,0x00,0x06,0x00,0x06,0x00,0xcf,0x86,0xd5,
-       0x2c,0xd4,0x14,0x53,0x04,0x06,0x00,0x52,0x04,0x06,0x00,0x51,0x04,0x06,0x00,0x10,
-       0x04,0x06,0x00,0x07,0x00,0xd3,0x10,0x92,0x0c,0x91,0x08,0x10,0x04,0x07,0x00,0x08,
-       0x00,0x08,0x00,0x08,0x00,0x12,0x04,0x08,0x00,0x09,0x00,0xd4,0x14,0x53,0x04,0x09,
-       0x00,0x92,0x0c,0x91,0x08,0x10,0x04,0x0b,0x00,0x0c,0x00,0x0c,0x00,0x0c,0x00,0xd3,
-       0x08,0x12,0x04,0x0c,0x00,0x10,0x00,0xd2,0x0c,0x51,0x04,0x10,0x00,0x10,0x04,0x10,
-       0x00,0x12,0x00,0x51,0x04,0x12,0x00,0x10,0x04,0x12,0x00,0x13,0x00,0xd3,0xa6,0xd2,
-       0x74,0xd1,0x40,0xd0,0x22,0xcf,0x86,0x55,0x04,0x01,0x00,0x94,0x18,0x93,0x14,0x52,
-       0x04,0x01,0x00,0xd1,0x08,0x10,0x04,0x01,0x00,0x04,0x00,0x10,0x04,0x04,0x00,0x00,
-       0x00,0x00,0x00,0x00,0x00,0xcf,0x86,0x95,0x18,0x94,0x14,0x53,0x04,0x01,0x00,0x92,
-       0x0c,0x51,0x04,0x01,0x00,0x10,0x04,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,
-       0x00,0xd0,0x06,0xcf,0x06,0x01,0x00,0xcf,0x86,0x55,0x04,0x01,0x00,0xd4,0x14,0x53,
-       0x04,0x01,0x00,0x92,0x0c,0x51,0x04,0x01,0x00,0x10,0x04,0x01,0x00,0x06,0x00,0x06,
-       0x00,0x53,0x04,0x06,0x00,0x52,0x04,0x06,0x00,0x51,0x04,0x06,0x00,0x10,0x04,0x06,
-       0x00,0x07,0x00,0xd1,0x06,0xcf,0x06,0x01,0x00,0xd0,0x1a,0xcf,0x86,0x95,0x14,0x54,
-       0x04,0x01,0x00,0x93,0x0c,0x52,0x04,0x01,0x00,0x11,0x04,0x01,0x00,0x06,0x00,0x06,
-       0x00,0x01,0x00,0xcf,0x86,0x55,0x04,0x01,0x00,0x54,0x04,0x01,0x00,0x13,0x04,0x04,
-       0x00,0x06,0x00,0xd2,0xdc,0xd1,0x48,0xd0,0x26,0xcf,0x86,0x95,0x20,0x54,0x04,0x01,
-       0x00,0xd3,0x0c,0x52,0x04,0x01,0x00,0x11,0x04,0x07,0x00,0x06,0x00,0x92,0x0c,0x91,
-       0x08,0x10,0x04,0x08,0x00,0x04,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0xcf,0x86,0x55,
-       0x04,0x01,0x00,0x54,0x04,0x01,0x00,0xd3,0x0c,0x92,0x08,0x11,0x04,0x04,0x00,0x06,
-       0x00,0x06,0x00,0x52,0x04,0x06,0x00,0x11,0x04,0x06,0x00,0x08,0x00,0xd0,0x5e,0xcf,
-       0x86,0xd5,0x2c,0xd4,0x10,0x53,0x04,0x06,0x00,0x92,0x08,0x11,0x04,0x06,0x00,0x07,
-       0x00,0x07,0x00,0xd3,0x0c,0x92,0x08,0x11,0x04,0x07,0x00,0x08,0x00,0x08,0x00,0x52,
-       0x04,0x08,0x00,0x91,0x08,0x10,0x04,0x08,0x00,0x0a,0x00,0x0b,0x00,0xd4,0x10,0x93,
-       0x0c,0x92,0x08,0x11,0x04,0x07,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0xd3,0x10,0x92,
-       0x0c,0x51,0x04,0x08,0x00,0x10,0x04,0x09,0x00,0x0a,0x00,0x0a,0x00,0x52,0x04,0x0a,
-       0x00,0x91,0x08,0x10,0x04,0x0a,0x00,0x0b,0x00,0x0b,0x00,0xcf,0x86,0xd5,0x1c,0x94,
-       0x18,0xd3,0x08,0x12,0x04,0x0a,0x00,0x0b,0x00,0x52,0x04,0x0b,0x00,0x51,0x04,0x0b,
-       0x00,0x10,0x04,0x0c,0x00,0x0b,0x00,0x0b,0x00,0x94,0x14,0x93,0x10,0x92,0x0c,0x51,
-       0x04,0x0b,0x00,0x10,0x04,0x0c,0x00,0x0b,0x00,0x0c,0x00,0x0b,0x00,0x0b,0x00,0xd1,
-       0xa8,0xd0,0x42,0xcf,0x86,0xd5,0x28,0x94,0x24,0xd3,0x18,0xd2,0x0c,0x91,0x08,0x10,
-       0x04,0x10,0x00,0x01,0x00,0x01,0x00,0x91,0x08,0x10,0x04,0x01,0x00,0x0c,0x00,0x01,
-       0x00,0x92,0x08,0x11,0x04,0x01,0x00,0x0c,0x00,0x01,0x00,0x01,0x00,0x94,0x14,0x53,
-       0x04,0x01,0x00,0x92,0x0c,0x91,0x08,0x10,0x04,0x0c,0x00,0x01,0x00,0x01,0x00,0x01,
-       0x00,0x01,0x00,0xcf,0x86,0xd5,0x40,0xd4,0x18,0x53,0x04,0x01,0x00,0x52,0x04,0x01,
-       0x00,0xd1,0x08,0x10,0x04,0x0c,0x00,0x01,0x00,0x10,0x04,0x0c,0x00,0x01,0x00,0xd3,
-       0x18,0xd2,0x0c,0x51,0x04,0x01,0x00,0x10,0x04,0x01,0x00,0x0c,0x00,0x51,0x04,0x0c,
-       0x00,0x10,0x04,0x01,0x00,0x0b,0x00,0x52,0x04,0x01,0x00,0x51,0x04,0x01,0x00,0x10,
-       0x04,0x01,0x00,0x0c,0x00,0xd4,0x14,0x93,0x10,0x92,0x0c,0x91,0x08,0x10,0x04,0x0c,
-       0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x06,0x00,0x93,0x0c,0x52,0x04,0x06,0x00,0x11,
-       0x04,0x06,0x00,0x01,0x00,0x01,0x00,0xd0,0x3e,0xcf,0x86,0xd5,0x18,0x54,0x04,0x01,
-       0x00,0x93,0x10,0x52,0x04,0x01,0x00,0x91,0x08,0x10,0x04,0x01,0x00,0x0c,0x00,0x0c,
-       0x00,0x01,0x00,0x54,0x04,0x01,0x00,0xd3,0x10,0x92,0x0c,0x91,0x08,0x10,0x04,0x0c,
-       0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x52,0x04,0x01,0x00,0x51,0x04,0x01,0x00,0x10,
-       0x04,0x01,0x00,0x0c,0x00,0xcf,0x86,0xd5,0x2c,0x94,0x28,0xd3,0x10,0x52,0x04,0x08,
-       0x00,0x51,0x04,0x08,0x00,0x10,0x04,0x08,0x00,0x09,0x00,0xd2,0x0c,0x51,0x04,0x09,
-       0x00,0x10,0x04,0x09,0x00,0x0d,0x00,0x91,0x08,0x10,0x04,0x0a,0x00,0x0d,0x00,0x0c,
-       0x00,0x06,0x00,0x94,0x0c,0x53,0x04,0x06,0x00,0x12,0x04,0x06,0x00,0x0a,0x00,0x06,
-       0x00,0xe4,0x39,0x01,0xd3,0x0c,0xd2,0x06,0xcf,0x06,0x04,0x00,0xcf,0x06,0x06,0x00,
-       0xd2,0x30,0xd1,0x06,0xcf,0x06,0x06,0x00,0xd0,0x06,0xcf,0x06,0x06,0x00,0xcf,0x86,
-       0x95,0x1e,0x54,0x04,0x06,0x00,0x53,0x04,0x06,0x00,0x52,0x04,0x06,0x00,0x91,0x0e,
-       0x10,0x0a,0x06,0xff,0xe2,0xab,0x9d,0xcc,0xb8,0x00,0x06,0x00,0x06,0x00,0x06,0x00,
-       0xd1,0x80,0xd0,0x3a,0xcf,0x86,0xd5,0x28,0xd4,0x10,0x53,0x04,0x07,0x00,0x52,0x04,
-       0x07,0x00,0x11,0x04,0x07,0x00,0x08,0x00,0xd3,0x08,0x12,0x04,0x08,0x00,0x09,0x00,
-       0x92,0x0c,0x51,0x04,0x09,0x00,0x10,0x04,0x09,0x00,0x0a,0x00,0x0a,0x00,0x94,0x0c,
-       0x93,0x08,0x12,0x04,0x09,0x00,0x0a,0x00,0x0a,0x00,0x0a,0x00,0xcf,0x86,0xd5,0x30,
-       0xd4,0x14,0x53,0x04,0x0a,0x00,0x52,0x04,0x0a,0x00,0x91,0x08,0x10,0x04,0x0a,0x00,
-       0x10,0x00,0x10,0x00,0xd3,0x10,0x52,0x04,0x0a,0x00,0x91,0x08,0x10,0x04,0x0a,0x00,
-       0x0b,0x00,0x0b,0x00,0x92,0x08,0x11,0x04,0x0b,0x00,0x10,0x00,0x10,0x00,0x54,0x04,
-       0x10,0x00,0x93,0x0c,0x52,0x04,0x10,0x00,0x11,0x04,0x00,0x00,0x10,0x00,0x10,0x00,
-       0xd0,0x32,0xcf,0x86,0xd5,0x14,0x54,0x04,0x10,0x00,0x93,0x0c,0x52,0x04,0x10,0x00,
-       0x11,0x04,0x10,0x00,0x00,0x00,0x10,0x00,0x54,0x04,0x10,0x00,0x53,0x04,0x10,0x00,
-       0xd2,0x08,0x11,0x04,0x10,0x00,0x14,0x00,0x91,0x08,0x10,0x04,0x14,0x00,0x10,0x00,
-       0x10,0x00,0xcf,0x86,0xd5,0x28,0xd4,0x14,0x53,0x04,0x10,0x00,0x92,0x0c,0x91,0x08,
-       0x10,0x04,0x10,0x00,0x15,0x00,0x10,0x00,0x10,0x00,0x93,0x10,0x92,0x0c,0x51,0x04,
-       0x10,0x00,0x10,0x04,0x13,0x00,0x14,0x00,0x14,0x00,0x14,0x00,0xd4,0x0c,0x53,0x04,
-       0x14,0x00,0x12,0x04,0x14,0x00,0x11,0x00,0x53,0x04,0x14,0x00,0x52,0x04,0x14,0x00,
-       0x51,0x04,0x14,0x00,0x10,0x04,0x14,0x00,0x15,0x00,0xe3,0xb9,0x01,0xd2,0xac,0xd1,
-       0x68,0xd0,0x1e,0xcf,0x86,0x55,0x04,0x08,0x00,0x94,0x14,0x53,0x04,0x08,0x00,0x52,
-       0x04,0x08,0x00,0x51,0x04,0x08,0x00,0x10,0x04,0x08,0x00,0x00,0x00,0x08,0x00,0xcf,
-       0x86,0xd5,0x18,0x54,0x04,0x08,0x00,0x53,0x04,0x08,0x00,0x52,0x04,0x08,0x00,0x51,
-       0x04,0x08,0x00,0x10,0x04,0x08,0x00,0x00,0x00,0xd4,0x14,0x53,0x04,0x09,0x00,0x52,
-       0x04,0x09,0x00,0x91,0x08,0x10,0x04,0x09,0x00,0x0a,0x00,0x0a,0x00,0xd3,0x10,0x92,
-       0x0c,0x91,0x08,0x10,0x04,0x0b,0x00,0x0a,0x00,0x0a,0x00,0x09,0x00,0x52,0x04,0x0a,
-       0x00,0x11,0x04,0x0a,0x00,0x0b,0x00,0xd0,0x06,0xcf,0x06,0x08,0x00,0xcf,0x86,0x55,
-       0x04,0x08,0x00,0xd4,0x1c,0x53,0x04,0x08,0x00,0xd2,0x0c,0x51,0x04,0x08,0x00,0x10,
-       0x04,0x08,0x00,0x0b,0x00,0x51,0x04,0x0b,0x00,0x10,0x04,0x0b,0x00,0x0b,0xe6,0xd3,
-       0x0c,0x92,0x08,0x11,0x04,0x0b,0xe6,0x0d,0x00,0x00,0x00,0x92,0x0c,0x91,0x08,0x10,
-       0x04,0x00,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0xd1,0x6c,0xd0,0x2a,0xcf,0x86,0x55,
-       0x04,0x08,0x00,0x94,0x20,0xd3,0x10,0x52,0x04,0x08,0x00,0x51,0x04,0x08,0x00,0x10,
-       0x04,0x00,0x00,0x0d,0x00,0x52,0x04,0x00,0x00,0x91,0x08,0x10,0x04,0x00,0x00,0x0d,
-       0x00,0x00,0x00,0x08,0x00,0xcf,0x86,0x55,0x04,0x08,0x00,0xd4,0x1c,0xd3,0x0c,0x52,
-       0x04,0x08,0x00,0x11,0x04,0x08,0x00,0x0d,0x00,0x52,0x04,0x00,0x00,0x51,0x04,0x00,
-       0x00,0x10,0x04,0x00,0x00,0x08,0x00,0xd3,0x10,0x92,0x0c,0x91,0x08,0x10,0x04,0x0c,
-       0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x52,0x04,0x00,0x00,0x51,0x04,0x00,0x00,0x10,
-       0x04,0x00,0x00,0x0c,0x09,0xd0,0x5a,0xcf,0x86,0xd5,0x18,0x54,0x04,0x08,0x00,0x93,
-       0x10,0x52,0x04,0x08,0x00,0x51,0x04,0x08,0x00,0x10,0x04,0x08,0x00,0x00,0x00,0x00,
-       0x00,0xd4,0x20,0xd3,0x10,0x52,0x04,0x08,0x00,0x51,0x04,0x08,0x00,0x10,0x04,0x08,
-       0x00,0x00,0x00,0x52,0x04,0x08,0x00,0x51,0x04,0x08,0x00,0x10,0x04,0x08,0x00,0x00,
-       0x00,0xd3,0x10,0x52,0x04,0x08,0x00,0x51,0x04,0x08,0x00,0x10,0x04,0x08,0x00,0x00,
-       0x00,0x52,0x04,0x08,0x00,0x51,0x04,0x08,0x00,0x10,0x04,0x08,0x00,0x00,0x00,0xcf,
-       0x86,0x95,0x40,0xd4,0x20,0xd3,0x10,0x52,0x04,0x08,0x00,0x51,0x04,0x08,0x00,0x10,
-       0x04,0x08,0x00,0x00,0x00,0x52,0x04,0x08,0x00,0x51,0x04,0x08,0x00,0x10,0x04,0x08,
-       0x00,0x00,0x00,0xd3,0x10,0x52,0x04,0x08,0x00,0x51,0x04,0x08,0x00,0x10,0x04,0x08,
-       0x00,0x00,0x00,0x52,0x04,0x08,0x00,0x51,0x04,0x08,0x00,0x10,0x04,0x08,0x00,0x00,
-       0x00,0x0a,0xe6,0xd2,0x9c,0xd1,0x68,0xd0,0x32,0xcf,0x86,0xd5,0x14,0x54,0x04,0x08,
-       0x00,0x53,0x04,0x08,0x00,0x52,0x04,0x0a,0x00,0x11,0x04,0x08,0x00,0x0a,0x00,0x54,
-       0x04,0x0a,0x00,0xd3,0x10,0x92,0x0c,0x91,0x08,0x10,0x04,0x0a,0x00,0x0b,0x00,0x0d,
-       0x00,0x0d,0x00,0x12,0x04,0x0d,0x00,0x10,0x00,0xcf,0x86,0x95,0x30,0x94,0x2c,0xd3,
-       0x18,0xd2,0x0c,0x51,0x04,0x10,0x00,0x10,0x04,0x10,0x00,0x12,0x00,0x91,0x08,0x10,
-       0x04,0x12,0x00,0x13,0x00,0x13,0x00,0xd2,0x08,0x11,0x04,0x13,0x00,0x14,0x00,0x51,
-       0x04,0x14,0x00,0x10,0x04,0x14,0x00,0x15,0x00,0x00,0x00,0x00,0x00,0xd0,0x1e,0xcf,
-       0x86,0x95,0x18,0x54,0x04,0x04,0x00,0x53,0x04,0x04,0x00,0x92,0x0c,0x51,0x04,0x04,
-       0x00,0x10,0x04,0x00,0x00,0x04,0x00,0x04,0x00,0x04,0x00,0xcf,0x86,0x55,0x04,0x04,
-       0x00,0x54,0x04,0x04,0x00,0x93,0x08,0x12,0x04,0x04,0x00,0x00,0x00,0x00,0x00,0xd1,
-       0x06,0xcf,0x06,0x04,0x00,0xd0,0x06,0xcf,0x06,0x04,0x00,0xcf,0x86,0xd5,0x14,0x54,
-       0x04,0x04,0x00,0x93,0x0c,0x52,0x04,0x04,0x00,0x11,0x04,0x04,0x00,0x00,0x00,0x00,
-       0x00,0x54,0x04,0x00,0x00,0x53,0x04,0x04,0x00,0x12,0x04,0x04,0x00,0x00,0x00,0xcf,
-       0x86,0xe5,0xa6,0x05,0xe4,0x9f,0x05,0xe3,0x96,0x04,0xe2,0xe4,0x03,0xe1,0xc0,0x01,
-       0xd0,0x3e,0xcf,0x86,0x55,0x04,0x01,0x00,0xd4,0x1c,0x53,0x04,0x01,0x00,0xd2,0x0c,
-       0x51,0x04,0x01,0x00,0x10,0x04,0x01,0xda,0x01,0xe4,0x91,0x08,0x10,0x04,0x01,0xe8,
-       0x01,0xde,0x01,0xe0,0x53,0x04,0x01,0x00,0xd2,0x0c,0x51,0x04,0x04,0x00,0x10,0x04,
-       0x04,0x00,0x06,0x00,0x51,0x04,0x06,0x00,0x10,0x04,0x04,0x00,0x01,0x00,0xcf,0x86,
-       0xd5,0xaa,0xd4,0x32,0xd3,0x10,0x92,0x0c,0x91,0x08,0x10,0x04,0x00,0x00,0x01,0x00,
-       0x01,0x00,0x01,0x00,0x52,0x04,0x01,0x00,0xd1,0x0f,0x10,0x0b,0x01,0xff,0xe3,0x81,
-       0x8b,0xe3,0x82,0x99,0x00,0x01,0x00,0x10,0x0b,0x01,0xff,0xe3,0x81,0x8d,0xe3,0x82,
-       0x99,0x00,0x01,0x00,0xd3,0x3c,0xd2,0x1e,0xd1,0x0f,0x10,0x0b,0x01,0xff,0xe3,0x81,
-       0x8f,0xe3,0x82,0x99,0x00,0x01,0x00,0x10,0x0b,0x01,0xff,0xe3,0x81,0x91,0xe3,0x82,
-       0x99,0x00,0x01,0x00,0xd1,0x0f,0x10,0x0b,0x01,0xff,0xe3,0x81,0x93,0xe3,0x82,0x99,
-       0x00,0x01,0x00,0x10,0x0b,0x01,0xff,0xe3,0x81,0x95,0xe3,0x82,0x99,0x00,0x01,0x00,
-       0xd2,0x1e,0xd1,0x0f,0x10,0x0b,0x01,0xff,0xe3,0x81,0x97,0xe3,0x82,0x99,0x00,0x01,
-       0x00,0x10,0x0b,0x01,0xff,0xe3,0x81,0x99,0xe3,0x82,0x99,0x00,0x01,0x00,0xd1,0x0f,
-       0x10,0x0b,0x01,0xff,0xe3,0x81,0x9b,0xe3,0x82,0x99,0x00,0x01,0x00,0x10,0x0b,0x01,
-       0xff,0xe3,0x81,0x9d,0xe3,0x82,0x99,0x00,0x01,0x00,0xd4,0x53,0xd3,0x3c,0xd2,0x1e,
-       0xd1,0x0f,0x10,0x0b,0x01,0xff,0xe3,0x81,0x9f,0xe3,0x82,0x99,0x00,0x01,0x00,0x10,
-       0x0b,0x01,0xff,0xe3,0x81,0xa1,0xe3,0x82,0x99,0x00,0x01,0x00,0xd1,0x0f,0x10,0x04,
-       0x01,0x00,0x01,0xff,0xe3,0x81,0xa4,0xe3,0x82,0x99,0x00,0x10,0x04,0x01,0x00,0x01,
-       0xff,0xe3,0x81,0xa6,0xe3,0x82,0x99,0x00,0x92,0x13,0x91,0x0f,0x10,0x04,0x01,0x00,
-       0x01,0xff,0xe3,0x81,0xa8,0xe3,0x82,0x99,0x00,0x01,0x00,0x01,0x00,0xd3,0x4a,0xd2,
-       0x25,0xd1,0x16,0x10,0x0b,0x01,0xff,0xe3,0x81,0xaf,0xe3,0x82,0x99,0x00,0x01,0xff,
-       0xe3,0x81,0xaf,0xe3,0x82,0x9a,0x00,0x10,0x04,0x01,0x00,0x01,0xff,0xe3,0x81,0xb2,
-       0xe3,0x82,0x99,0x00,0xd1,0x0f,0x10,0x0b,0x01,0xff,0xe3,0x81,0xb2,0xe3,0x82,0x9a,
-       0x00,0x01,0x00,0x10,0x0b,0x01,0xff,0xe3,0x81,0xb5,0xe3,0x82,0x99,0x00,0x01,0xff,
-       0xe3,0x81,0xb5,0xe3,0x82,0x9a,0x00,0xd2,0x1e,0xd1,0x0f,0x10,0x04,0x01,0x00,0x01,
-       0xff,0xe3,0x81,0xb8,0xe3,0x82,0x99,0x00,0x10,0x0b,0x01,0xff,0xe3,0x81,0xb8,0xe3,
-       0x82,0x9a,0x00,0x01,0x00,0x91,0x16,0x10,0x0b,0x01,0xff,0xe3,0x81,0xbb,0xe3,0x82,
-       0x99,0x00,0x01,0xff,0xe3,0x81,0xbb,0xe3,0x82,0x9a,0x00,0x01,0x00,0xd0,0xee,0xcf,
-       0x86,0xd5,0x42,0x54,0x04,0x01,0x00,0xd3,0x1b,0x52,0x04,0x01,0x00,0xd1,0x0f,0x10,
-       0x0b,0x01,0xff,0xe3,0x81,0x86,0xe3,0x82,0x99,0x00,0x06,0x00,0x10,0x04,0x06,0x00,
-       0x00,0x00,0xd2,0x10,0xd1,0x08,0x10,0x04,0x00,0x00,0x01,0x08,0x10,0x04,0x01,0x08,
-       0x01,0x00,0x51,0x04,0x01,0x00,0x10,0x0b,0x01,0xff,0xe3,0x82,0x9d,0xe3,0x82,0x99,
-       0x00,0x06,0x00,0xd4,0x32,0xd3,0x10,0x92,0x0c,0x91,0x08,0x10,0x04,0x06,0x00,0x01,
-       0x00,0x01,0x00,0x01,0x00,0x52,0x04,0x01,0x00,0xd1,0x0f,0x10,0x0b,0x01,0xff,0xe3,
-       0x82,0xab,0xe3,0x82,0x99,0x00,0x01,0x00,0x10,0x0b,0x01,0xff,0xe3,0x82,0xad,0xe3,
-       0x82,0x99,0x00,0x01,0x00,0xd3,0x3c,0xd2,0x1e,0xd1,0x0f,0x10,0x0b,0x01,0xff,0xe3,
-       0x82,0xaf,0xe3,0x82,0x99,0x00,0x01,0x00,0x10,0x0b,0x01,0xff,0xe3,0x82,0xb1,0xe3,
-       0x82,0x99,0x00,0x01,0x00,0xd1,0x0f,0x10,0x0b,0x01,0xff,0xe3,0x82,0xb3,0xe3,0x82,
-       0x99,0x00,0x01,0x00,0x10,0x0b,0x01,0xff,0xe3,0x82,0xb5,0xe3,0x82,0x99,0x00,0x01,
-       0x00,0xd2,0x1e,0xd1,0x0f,0x10,0x0b,0x01,0xff,0xe3,0x82,0xb7,0xe3,0x82,0x99,0x00,
-       0x01,0x00,0x10,0x0b,0x01,0xff,0xe3,0x82,0xb9,0xe3,0x82,0x99,0x00,0x01,0x00,0xd1,
-       0x0f,0x10,0x0b,0x01,0xff,0xe3,0x82,0xbb,0xe3,0x82,0x99,0x00,0x01,0x00,0x10,0x0b,
-       0x01,0xff,0xe3,0x82,0xbd,0xe3,0x82,0x99,0x00,0x01,0x00,0xcf,0x86,0xd5,0xd5,0xd4,
-       0x53,0xd3,0x3c,0xd2,0x1e,0xd1,0x0f,0x10,0x0b,0x01,0xff,0xe3,0x82,0xbf,0xe3,0x82,
-       0x99,0x00,0x01,0x00,0x10,0x0b,0x01,0xff,0xe3,0x83,0x81,0xe3,0x82,0x99,0x00,0x01,
-       0x00,0xd1,0x0f,0x10,0x04,0x01,0x00,0x01,0xff,0xe3,0x83,0x84,0xe3,0x82,0x99,0x00,
-       0x10,0x04,0x01,0x00,0x01,0xff,0xe3,0x83,0x86,0xe3,0x82,0x99,0x00,0x92,0x13,0x91,
-       0x0f,0x10,0x04,0x01,0x00,0x01,0xff,0xe3,0x83,0x88,0xe3,0x82,0x99,0x00,0x01,0x00,
-       0x01,0x00,0xd3,0x4a,0xd2,0x25,0xd1,0x16,0x10,0x0b,0x01,0xff,0xe3,0x83,0x8f,0xe3,
-       0x82,0x99,0x00,0x01,0xff,0xe3,0x83,0x8f,0xe3,0x82,0x9a,0x00,0x10,0x04,0x01,0x00,
-       0x01,0xff,0xe3,0x83,0x92,0xe3,0x82,0x99,0x00,0xd1,0x0f,0x10,0x0b,0x01,0xff,0xe3,
-       0x83,0x92,0xe3,0x82,0x9a,0x00,0x01,0x00,0x10,0x0b,0x01,0xff,0xe3,0x83,0x95,0xe3,
-       0x82,0x99,0x00,0x01,0xff,0xe3,0x83,0x95,0xe3,0x82,0x9a,0x00,0xd2,0x1e,0xd1,0x0f,
-       0x10,0x04,0x01,0x00,0x01,0xff,0xe3,0x83,0x98,0xe3,0x82,0x99,0x00,0x10,0x0b,0x01,
-       0xff,0xe3,0x83,0x98,0xe3,0x82,0x9a,0x00,0x01,0x00,0x91,0x16,0x10,0x0b,0x01,0xff,
-       0xe3,0x83,0x9b,0xe3,0x82,0x99,0x00,0x01,0xff,0xe3,0x83,0x9b,0xe3,0x82,0x9a,0x00,
-       0x01,0x00,0x54,0x04,0x01,0x00,0xd3,0x22,0x52,0x04,0x01,0x00,0xd1,0x0f,0x10,0x0b,
-       0x01,0xff,0xe3,0x82,0xa6,0xe3,0x82,0x99,0x00,0x01,0x00,0x10,0x04,0x01,0x00,0x01,
-       0xff,0xe3,0x83,0xaf,0xe3,0x82,0x99,0x00,0xd2,0x25,0xd1,0x16,0x10,0x0b,0x01,0xff,
-       0xe3,0x83,0xb0,0xe3,0x82,0x99,0x00,0x01,0xff,0xe3,0x83,0xb1,0xe3,0x82,0x99,0x00,
-       0x10,0x0b,0x01,0xff,0xe3,0x83,0xb2,0xe3,0x82,0x99,0x00,0x01,0x00,0x51,0x04,0x01,
-       0x00,0x10,0x0b,0x01,0xff,0xe3,0x83,0xbd,0xe3,0x82,0x99,0x00,0x06,0x00,0xd1,0x65,
-       0xd0,0x46,0xcf,0x86,0xd5,0x18,0x94,0x14,0x93,0x10,0x52,0x04,0x00,0x00,0x91,0x08,
-       0x10,0x04,0x00,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0xd4,0x18,0x53,0x04,
-       0x01,0x00,0x52,0x04,0x01,0x00,0xd1,0x08,0x10,0x04,0x01,0x00,0x0a,0x00,0x10,0x04,
-       0x13,0x00,0x14,0x00,0x93,0x10,0x92,0x0c,0x91,0x08,0x10,0x04,0x00,0x00,0x01,0x00,
-       0x01,0x00,0x01,0x00,0x01,0x00,0xcf,0x86,0x55,0x04,0x01,0x00,0x94,0x15,0x93,0x11,
-       0x52,0x04,0x01,0x00,0x91,0x09,0x10,0x05,0x01,0xff,0x00,0x01,0x00,0x01,0x00,0x01,
-       0x00,0x01,0x00,0xd0,0x32,0xcf,0x86,0xd5,0x18,0x94,0x14,0x53,0x04,0x01,0x00,0x52,
-       0x04,0x01,0x00,0x51,0x04,0x01,0x00,0x10,0x04,0x01,0x00,0x00,0x00,0x01,0x00,0x54,
-       0x04,0x04,0x00,0x53,0x04,0x04,0x00,0x92,0x0c,0x51,0x04,0x0c,0x00,0x10,0x04,0x0c,
-       0x00,0x00,0x00,0x00,0x00,0xcf,0x86,0xd5,0x08,0x14,0x04,0x08,0x00,0x0a,0x00,0x94,
-       0x0c,0x93,0x08,0x12,0x04,0x0a,0x00,0x00,0x00,0x00,0x00,0x06,0x00,0xd2,0xa4,0xd1,
-       0x5c,0xd0,0x22,0xcf,0x86,0x95,0x1c,0x54,0x04,0x01,0x00,0x53,0x04,0x01,0x00,0x52,
-       0x04,0x01,0x00,0xd1,0x08,0x10,0x04,0x01,0x00,0x07,0x00,0x10,0x04,0x07,0x00,0x00,
-       0x00,0x01,0x00,0xcf,0x86,0xd5,0x20,0xd4,0x0c,0x93,0x08,0x12,0x04,0x01,0x00,0x0b,
-       0x00,0x0b,0x00,0x93,0x10,0x92,0x0c,0x91,0x08,0x10,0x04,0x07,0x00,0x06,0x00,0x06,
-       0x00,0x06,0x00,0x06,0x00,0x54,0x04,0x01,0x00,0x53,0x04,0x01,0x00,0x52,0x04,0x01,
-       0x00,0x51,0x04,0x07,0x00,0x10,0x04,0x08,0x00,0x01,0x00,0xd0,0x1e,0xcf,0x86,0x55,
-       0x04,0x01,0x00,0x54,0x04,0x01,0x00,0x93,0x10,0x92,0x0c,0x91,0x08,0x10,0x04,0x01,
-       0x00,0x06,0x00,0x06,0x00,0x06,0x00,0x06,0x00,0xcf,0x86,0xd5,0x10,0x94,0x0c,0x53,
-       0x04,0x01,0x00,0x12,0x04,0x01,0x00,0x07,0x00,0x01,0x00,0x54,0x04,0x01,0x00,0x53,
-       0x04,0x01,0x00,0x52,0x04,0x01,0x00,0x51,0x04,0x01,0x00,0x10,0x04,0x01,0x00,0x16,
-       0x00,0xd1,0x30,0xd0,0x06,0xcf,0x06,0x01,0x00,0xcf,0x86,0x55,0x04,0x01,0x00,0x54,
-       0x04,0x01,0x00,0xd3,0x10,0x52,0x04,0x01,0x00,0x51,0x04,0x01,0x00,0x10,0x04,0x01,
-       0x00,0x07,0x00,0x92,0x0c,0x51,0x04,0x07,0x00,0x10,0x04,0x07,0x00,0x01,0x00,0x01,
-       0x00,0xd0,0x06,0xcf,0x06,0x01,0x00,0xcf,0x86,0xd5,0x14,0x54,0x04,0x01,0x00,0x53,
-       0x04,0x01,0x00,0x52,0x04,0x01,0x00,0x11,0x04,0x01,0x00,0x07,0x00,0x54,0x04,0x01,
-       0x00,0x53,0x04,0x01,0x00,0x52,0x04,0x01,0x00,0x51,0x04,0x01,0x00,0x10,0x04,0x01,
-       0x00,0x07,0x00,0xcf,0x06,0x04,0x00,0xcf,0x06,0x04,0x00,0xd1,0x48,0xd0,0x40,0xcf,
-       0x86,0xd5,0x06,0xcf,0x06,0x04,0x00,0xd4,0x06,0xcf,0x06,0x04,0x00,0xd3,0x2c,0xd2,
-       0x06,0xcf,0x06,0x04,0x00,0xd1,0x06,0xcf,0x06,0x04,0x00,0xd0,0x1a,0xcf,0x86,0x55,
-       0x04,0x04,0x00,0x54,0x04,0x04,0x00,0x93,0x0c,0x52,0x04,0x04,0x00,0x11,0x04,0x04,
-       0x00,0x00,0x00,0x00,0x00,0xcf,0x06,0x07,0x00,0xcf,0x06,0x01,0x00,0xcf,0x86,0xcf,
-       0x06,0x01,0x00,0xcf,0x86,0xcf,0x06,0x01,0x00,0xe2,0x71,0x05,0xd1,0x8c,0xd0,0x08,
-       0xcf,0x86,0xcf,0x06,0x01,0x00,0xcf,0x86,0xd5,0x06,0xcf,0x06,0x01,0x00,0xd4,0x06,
-       0xcf,0x06,0x01,0x00,0xd3,0x06,0xcf,0x06,0x01,0x00,0xd2,0x06,0xcf,0x06,0x01,0x00,
-       0xd1,0x06,0xcf,0x06,0x01,0x00,0xd0,0x22,0xcf,0x86,0x55,0x04,0x01,0x00,0xd4,0x10,
-       0x93,0x0c,0x52,0x04,0x01,0x00,0x11,0x04,0x01,0x00,0x08,0x00,0x08,0x00,0x53,0x04,
-       0x08,0x00,0x12,0x04,0x08,0x00,0x0a,0x00,0xcf,0x86,0xd5,0x28,0xd4,0x18,0xd3,0x08,
-       0x12,0x04,0x0a,0x00,0x0b,0x00,0x52,0x04,0x0b,0x00,0x91,0x08,0x10,0x04,0x0d,0x00,
-       0x11,0x00,0x11,0x00,0x93,0x0c,0x52,0x04,0x11,0x00,0x11,0x04,0x11,0x00,0x13,0x00,
-       0x13,0x00,0x94,0x14,0x53,0x04,0x13,0x00,0x92,0x0c,0x51,0x04,0x13,0x00,0x10,0x04,
-       0x13,0x00,0x14,0x00,0x14,0x00,0x00,0x00,0xe0,0xdb,0x04,0xcf,0x86,0xe5,0xdf,0x01,
-       0xd4,0x06,0xcf,0x06,0x04,0x00,0xd3,0x74,0xd2,0x6e,0xd1,0x06,0xcf,0x06,0x04,0x00,
-       0xd0,0x3e,0xcf,0x86,0xd5,0x18,0x94,0x14,0x53,0x04,0x04,0x00,0x52,0x04,0x04,0x00,
-       0x91,0x08,0x10,0x04,0x04,0x00,0x00,0x00,0x00,0x00,0x04,0x00,0xd4,0x10,0x93,0x0c,
-       0x92,0x08,0x11,0x04,0x04,0x00,0x06,0x00,0x04,0x00,0x04,0x00,0x93,0x10,0x52,0x04,
-       0x04,0x00,0x91,0x08,0x10,0x04,0x06,0x00,0x04,0x00,0x04,0x00,0x04,0x00,0xcf,0x86,
-       0x95,0x24,0x94,0x20,0x93,0x1c,0xd2,0x0c,0x91,0x08,0x10,0x04,0x04,0x00,0x06,0x00,
-       0x04,0x00,0xd1,0x08,0x10,0x04,0x04,0x00,0x06,0x00,0x10,0x04,0x04,0x00,0x00,0x00,
-       0x00,0x00,0x0b,0x00,0x0b,0x00,0xcf,0x06,0x0a,0x00,0xd2,0x84,0xd1,0x4c,0xd0,0x16,
-       0xcf,0x86,0x55,0x04,0x0a,0x00,0x94,0x0c,0x53,0x04,0x0a,0x00,0x12,0x04,0x0a,0x00,
-       0x00,0x00,0x00,0x00,0xcf,0x86,0x55,0x04,0x0a,0x00,0xd4,0x1c,0xd3,0x0c,0x92,0x08,
-       0x11,0x04,0x0c,0x00,0x0a,0x00,0x0a,0x00,0x52,0x04,0x0a,0x00,0x51,0x04,0x0a,0x00,
-       0x10,0x04,0x0a,0x00,0x0a,0xe6,0xd3,0x08,0x12,0x04,0x0a,0x00,0x0d,0xe6,0x52,0x04,
-       0x0d,0xe6,0x11,0x04,0x0a,0xe6,0x0a,0x00,0xd0,0x1e,0xcf,0x86,0x95,0x18,0x54,0x04,
-       0x0a,0x00,0x53,0x04,0x0a,0x00,0x52,0x04,0x10,0x00,0x51,0x04,0x10,0x00,0x10,0x04,
-       0x11,0xe6,0x0d,0xe6,0x0b,0x00,0xcf,0x86,0x55,0x04,0x0b,0x00,0x54,0x04,0x0b,0x00,
-       0x93,0x0c,0x92,0x08,0x11,0x04,0x0b,0xe6,0x0b,0x00,0x0b,0x00,0x00,0x00,0xd1,0x40,
-       0xd0,0x3a,0xcf,0x86,0xd5,0x24,0x54,0x04,0x08,0x00,0xd3,0x10,0x52,0x04,0x08,0x00,
-       0x51,0x04,0x08,0x00,0x10,0x04,0x08,0x00,0x09,0x00,0x92,0x0c,0x51,0x04,0x09,0x00,
-       0x10,0x04,0x09,0x00,0x0a,0x00,0x0a,0x00,0x94,0x10,0x93,0x0c,0x92,0x08,0x11,0x04,
-       0x09,0x00,0x0a,0x00,0x0a,0x00,0x0a,0x00,0x0a,0x00,0xcf,0x06,0x0a,0x00,0xd0,0x5e,
-       0xcf,0x86,0xd5,0x28,0xd4,0x18,0x53,0x04,0x0a,0x00,0x52,0x04,0x0a,0x00,0xd1,0x08,
-       0x10,0x04,0x0a,0x00,0x0c,0x00,0x10,0x04,0x0c,0x00,0x11,0x00,0x93,0x0c,0x92,0x08,
-       0x11,0x04,0x0c,0x00,0x0d,0x00,0x10,0x00,0x10,0x00,0xd4,0x1c,0x53,0x04,0x0c,0x00,
-       0xd2,0x0c,0x51,0x04,0x0c,0x00,0x10,0x04,0x0d,0x00,0x10,0x00,0x51,0x04,0x10,0x00,
-       0x10,0x04,0x12,0x00,0x14,0x00,0xd3,0x0c,0x92,0x08,0x11,0x04,0x10,0x00,0x11,0x00,
-       0x11,0x00,0x92,0x08,0x11,0x04,0x14,0x00,0x15,0x00,0x15,0x00,0xcf,0x86,0xd5,0x1c,
-       0x94,0x18,0x93,0x14,0xd2,0x08,0x11,0x04,0x00,0x00,0x15,0x00,0x51,0x04,0x15,0x00,
-       0x10,0x04,0x15,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x54,0x04,0x00,0x00,0xd3,0x10,
-       0x52,0x04,0x00,0x00,0x51,0x04,0x00,0x00,0x10,0x04,0x00,0x00,0x10,0x00,0x92,0x0c,
-       0x51,0x04,0x0d,0x00,0x10,0x04,0x0c,0x00,0x0a,0x00,0x0a,0x00,0xe4,0xf2,0x02,0xe3,
-       0x65,0x01,0xd2,0x98,0xd1,0x48,0xd0,0x36,0xcf,0x86,0xd5,0x18,0x94,0x14,0x93,0x10,
-       0x52,0x04,0x08,0x00,0x51,0x04,0x08,0x00,0x10,0x04,0x08,0x09,0x08,0x00,0x08,0x00,
-       0x08,0x00,0xd4,0x0c,0x53,0x04,0x08,0x00,0x12,0x04,0x08,0x00,0x00,0x00,0x53,0x04,
-       0x0b,0x00,0x92,0x08,0x11,0x04,0x0b,0x00,0x00,0x00,0x00,0x00,0xcf,0x86,0x55,0x04,
-       0x09,0x00,0x54,0x04,0x09,0x00,0x13,0x04,0x09,0x00,0x00,0x00,0xd0,0x06,0xcf,0x06,
-       0x0a,0x00,0xcf,0x86,0xd5,0x2c,0xd4,0x1c,0xd3,0x10,0x52,0x04,0x0a,0x00,0x91,0x08,
-       0x10,0x04,0x0a,0x09,0x12,0x00,0x00,0x00,0x52,0x04,0x00,0x00,0x11,0x04,0x00,0x00,
-       0x0a,0x00,0x53,0x04,0x0a,0x00,0x92,0x08,0x11,0x04,0x0a,0x00,0x00,0x00,0x00,0x00,
-       0x54,0x04,0x0b,0xe6,0xd3,0x0c,0x92,0x08,0x11,0x04,0x0b,0xe6,0x0b,0x00,0x0b,0x00,
-       0x52,0x04,0x0b,0x00,0x11,0x04,0x11,0x00,0x14,0x00,0xd1,0x60,0xd0,0x22,0xcf,0x86,
-       0x55,0x04,0x0a,0x00,0x94,0x18,0x53,0x04,0x0a,0x00,0xd2,0x0c,0x51,0x04,0x0a,0x00,
-       0x10,0x04,0x0a,0x00,0x0a,0xdc,0x11,0x04,0x0a,0xdc,0x0a,0x00,0x0a,0x00,0xcf,0x86,
-       0xd5,0x24,0x54,0x04,0x0a,0x00,0xd3,0x10,0x92,0x0c,0x51,0x04,0x0a,0x00,0x10,0x04,
-       0x0a,0x00,0x0a,0x09,0x00,0x00,0x52,0x04,0x00,0x00,0x51,0x04,0x00,0x00,0x10,0x04,
-       0x00,0x00,0x0a,0x00,0x54,0x04,0x0b,0x00,0x53,0x04,0x0b,0x00,0x52,0x04,0x0b,0x00,
-       0x91,0x08,0x10,0x04,0x0b,0x00,0x00,0x00,0x00,0x00,0xd0,0x1e,0xcf,0x86,0x55,0x04,
-       0x0b,0x00,0x54,0x04,0x0b,0x00,0x93,0x10,0x92,0x0c,0x51,0x04,0x0b,0x00,0x10,0x04,
-       0x0b,0x00,0x0b,0x07,0x0b,0x00,0x0b,0x00,0xcf,0x86,0xd5,0x34,0xd4,0x20,0xd3,0x10,
-       0x92,0x0c,0x91,0x08,0x10,0x04,0x0b,0x09,0x0b,0x00,0x0b,0x00,0x0b,0x00,0x52,0x04,
-       0x0b,0x00,0x51,0x04,0x0b,0x00,0x10,0x04,0x00,0x00,0x0b,0x00,0x53,0x04,0x0b,0x00,
-       0xd2,0x08,0x11,0x04,0x0b,0x00,0x00,0x00,0x11,0x04,0x00,0x00,0x0b,0x00,0x54,0x04,
-       0x10,0x00,0x53,0x04,0x10,0x00,0x52,0x04,0x10,0x00,0x51,0x04,0x10,0x00,0x10,0x04,
-       0x10,0x00,0x00,0x00,0xd2,0xd0,0xd1,0x50,0xd0,0x1e,0xcf,0x86,0x55,0x04,0x0a,0x00,
-       0x54,0x04,0x0a,0x00,0x93,0x10,0x52,0x04,0x0a,0x00,0x51,0x04,0x0a,0x00,0x10,0x04,
-       0x0a,0x00,0x00,0x00,0x00,0x00,0xcf,0x86,0xd5,0x20,0xd4,0x10,0x53,0x04,0x0a,0x00,
-       0x52,0x04,0x0a,0x00,0x11,0x04,0x0a,0x00,0x00,0x00,0x53,0x04,0x0a,0x00,0x92,0x08,
-       0x11,0x04,0x0a,0x00,0x00,0x00,0x0a,0x00,0x54,0x04,0x0b,0x00,0x53,0x04,0x0b,0x00,
-       0x12,0x04,0x0b,0x00,0x10,0x00,0xd0,0x3a,0xcf,0x86,0x55,0x04,0x0b,0x00,0x54,0x04,
-       0x0b,0x00,0xd3,0x1c,0xd2,0x0c,0x91,0x08,0x10,0x04,0x0b,0xe6,0x0b,0x00,0x0b,0xe6,
-       0xd1,0x08,0x10,0x04,0x0b,0xdc,0x0b,0x00,0x10,0x04,0x0b,0x00,0x0b,0xe6,0xd2,0x0c,
-       0x91,0x08,0x10,0x04,0x0b,0xe6,0x0b,0x00,0x0b,0x00,0x11,0x04,0x0b,0x00,0x0b,0xe6,
-       0xcf,0x86,0xd5,0x2c,0xd4,0x18,0x93,0x14,0x92,0x10,0xd1,0x08,0x10,0x04,0x0b,0x00,
-       0x0b,0xe6,0x10,0x04,0x0b,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x53,0x04,0x00,0x00,
-       0x92,0x0c,0x51,0x04,0x00,0x00,0x10,0x04,0x00,0x00,0x0b,0x00,0x0b,0x00,0x54,0x04,
-       0x0d,0x00,0x93,0x10,0x52,0x04,0x0d,0x00,0x51,0x04,0x0d,0x00,0x10,0x04,0x0d,0x09,
-       0x00,0x00,0x00,0x00,0xd1,0x8c,0xd0,0x72,0xcf,0x86,0xd5,0x4c,0xd4,0x30,0xd3,0x18,
-       0xd2,0x0c,0x91,0x08,0x10,0x04,0x00,0x00,0x0c,0x00,0x0c,0x00,0x51,0x04,0x0c,0x00,
-       0x10,0x04,0x0c,0x00,0x00,0x00,0xd2,0x0c,0x91,0x08,0x10,0x04,0x00,0x00,0x0c,0x00,
-       0x0c,0x00,0x51,0x04,0x0c,0x00,0x10,0x04,0x0c,0x00,0x00,0x00,0x93,0x18,0xd2,0x0c,
-       0x91,0x08,0x10,0x04,0x00,0x00,0x0c,0x00,0x0c,0x00,0x51,0x04,0x0c,0x00,0x10,0x04,
-       0x0c,0x00,0x00,0x00,0x00,0x00,0x94,0x20,0xd3,0x10,0x52,0x04,0x0c,0x00,0x51,0x04,
-       0x0c,0x00,0x10,0x04,0x0c,0x00,0x00,0x00,0x52,0x04,0x0c,0x00,0x51,0x04,0x0c,0x00,
-       0x10,0x04,0x0c,0x00,0x00,0x00,0x10,0x00,0xcf,0x86,0x55,0x04,0x10,0x00,0x94,0x10,
-       0x93,0x0c,0x52,0x04,0x11,0x00,0x11,0x04,0x10,0x00,0x15,0x00,0x00,0x00,0x11,0x00,
-       0xd0,0x06,0xcf,0x06,0x11,0x00,0xcf,0x86,0x55,0x04,0x0b,0x00,0xd4,0x14,0x53,0x04,
-       0x0b,0x00,0x52,0x04,0x0b,0x00,0x91,0x08,0x10,0x04,0x0b,0x00,0x0b,0x09,0x00,0x00,
-       0x53,0x04,0x0b,0x00,0x92,0x08,0x11,0x04,0x0b,0x00,0x00,0x00,0x00,0x00,0xcf,0x06,
-       0x02,0xff,0xff,0xcf,0x86,0xcf,0x06,0x02,0xff,0xff,0xd1,0x76,0xd0,0x09,0xcf,0x86,
-       0xcf,0x06,0x02,0xff,0xff,0xcf,0x86,0x85,0xd4,0x07,0xcf,0x06,0x02,0xff,0xff,0xd3,
-       0x07,0xcf,0x06,0x02,0xff,0xff,0xd2,0x07,0xcf,0x06,0x02,0xff,0xff,0xd1,0x07,0xcf,
-       0x06,0x02,0xff,0xff,0xd0,0x18,0xcf,0x86,0x55,0x05,0x02,0xff,0xff,0x94,0x0d,0x93,
-       0x09,0x12,0x05,0x02,0xff,0xff,0x00,0x00,0x00,0x00,0x0b,0x00,0xcf,0x86,0xd5,0x24,
-       0x94,0x20,0xd3,0x10,0x52,0x04,0x0b,0x00,0x51,0x04,0x0b,0x00,0x10,0x04,0x0b,0x00,
-       0x00,0x00,0x92,0x0c,0x51,0x04,0x00,0x00,0x10,0x04,0x00,0x00,0x0b,0x00,0x0b,0x00,
-       0x0b,0x00,0x54,0x04,0x0b,0x00,0x53,0x04,0x0b,0x00,0x12,0x04,0x0b,0x00,0x00,0x00,
-       0xd0,0x08,0xcf,0x86,0xcf,0x06,0x01,0x00,0xcf,0x86,0xd5,0x06,0xcf,0x06,0x01,0x00,
-       0xe4,0x9c,0x10,0xe3,0x16,0x08,0xd2,0x06,0xcf,0x06,0x01,0x00,0xe1,0x08,0x04,0xe0,
-       0x04,0x02,0xcf,0x86,0xe5,0x01,0x01,0xd4,0x80,0xd3,0x40,0xd2,0x20,0xd1,0x10,0x10,
-       0x08,0x01,0xff,0xe8,0xb1,0x88,0x00,0x01,0xff,0xe6,0x9b,0xb4,0x00,0x10,0x08,0x01,
-       0xff,0xe8,0xbb,0x8a,0x00,0x01,0xff,0xe8,0xb3,0x88,0x00,0xd1,0x10,0x10,0x08,0x01,
-       0xff,0xe6,0xbb,0x91,0x00,0x01,0xff,0xe4,0xb8,0xb2,0x00,0x10,0x08,0x01,0xff,0xe5,
-       0x8f,0xa5,0x00,0x01,0xff,0xe9,0xbe,0x9c,0x00,0xd2,0x20,0xd1,0x10,0x10,0x08,0x01,
-       0xff,0xe9,0xbe,0x9c,0x00,0x01,0xff,0xe5,0xa5,0x91,0x00,0x10,0x08,0x01,0xff,0xe9,
-       0x87,0x91,0x00,0x01,0xff,0xe5,0x96,0x87,0x00,0xd1,0x10,0x10,0x08,0x01,0xff,0xe5,
-       0xa5,0x88,0x00,0x01,0xff,0xe6,0x87,0xb6,0x00,0x10,0x08,0x01,0xff,0xe7,0x99,0xa9,
-       0x00,0x01,0xff,0xe7,0xbe,0x85,0x00,0xd3,0x40,0xd2,0x20,0xd1,0x10,0x10,0x08,0x01,
-       0xff,0xe8,0x98,0xbf,0x00,0x01,0xff,0xe8,0x9e,0xba,0x00,0x10,0x08,0x01,0xff,0xe8,
-       0xa3,0xb8,0x00,0x01,0xff,0xe9,0x82,0x8f,0x00,0xd1,0x10,0x10,0x08,0x01,0xff,0xe6,
-       0xa8,0x82,0x00,0x01,0xff,0xe6,0xb4,0x9b,0x00,0x10,0x08,0x01,0xff,0xe7,0x83,0x99,
-       0x00,0x01,0xff,0xe7,0x8f,0x9e,0x00,0xd2,0x20,0xd1,0x10,0x10,0x08,0x01,0xff,0xe8,
-       0x90,0xbd,0x00,0x01,0xff,0xe9,0x85,0xaa,0x00,0x10,0x08,0x01,0xff,0xe9,0xa7,0xb1,
-       0x00,0x01,0xff,0xe4,0xba,0x82,0x00,0xd1,0x10,0x10,0x08,0x01,0xff,0xe5,0x8d,0xb5,
-       0x00,0x01,0xff,0xe6,0xac,0x84,0x00,0x10,0x08,0x01,0xff,0xe7,0x88,0x9b,0x00,0x01,
-       0xff,0xe8,0x98,0xad,0x00,0xd4,0x80,0xd3,0x40,0xd2,0x20,0xd1,0x10,0x10,0x08,0x01,
-       0xff,0xe9,0xb8,0x9e,0x00,0x01,0xff,0xe5,0xb5,0x90,0x00,0x10,0x08,0x01,0xff,0xe6,
-       0xbf,0xab,0x00,0x01,0xff,0xe8,0x97,0x8d,0x00,0xd1,0x10,0x10,0x08,0x01,0xff,0xe8,
-       0xa5,0xa4,0x00,0x01,0xff,0xe6,0x8b,0x89,0x00,0x10,0x08,0x01,0xff,0xe8,0x87,0x98,
-       0x00,0x01,0xff,0xe8,0xa0,0x9f,0x00,0xd2,0x20,0xd1,0x10,0x10,0x08,0x01,0xff,0xe5,
-       0xbb,0x8a,0x00,0x01,0xff,0xe6,0x9c,0x97,0x00,0x10,0x08,0x01,0xff,0xe6,0xb5,0xaa,
-       0x00,0x01,0xff,0xe7,0x8b,0xbc,0x00,0xd1,0x10,0x10,0x08,0x01,0xff,0xe9,0x83,0x8e,
-       0x00,0x01,0xff,0xe4,0xbe,0x86,0x00,0x10,0x08,0x01,0xff,0xe5,0x86,0xb7,0x00,0x01,
-       0xff,0xe5,0x8b,0x9e,0x00,0xd3,0x40,0xd2,0x20,0xd1,0x10,0x10,0x08,0x01,0xff,0xe6,
-       0x93,0x84,0x00,0x01,0xff,0xe6,0xab,0x93,0x00,0x10,0x08,0x01,0xff,0xe7,0x88,0x90,
-       0x00,0x01,0xff,0xe7,0x9b,0xa7,0x00,0xd1,0x10,0x10,0x08,0x01,0xff,0xe8,0x80,0x81,
-       0x00,0x01,0xff,0xe8,0x98,0x86,0x00,0x10,0x08,0x01,0xff,0xe8,0x99,0x9c,0x00,0x01,
-       0xff,0xe8,0xb7,0xaf,0x00,0xd2,0x20,0xd1,0x10,0x10,0x08,0x01,0xff,0xe9,0x9c,0xb2,
-       0x00,0x01,0xff,0xe9,0xad,0xaf,0x00,0x10,0x08,0x01,0xff,0xe9,0xb7,0xba,0x00,0x01,
-       0xff,0xe7,0xa2,0x8c,0x00,0xd1,0x10,0x10,0x08,0x01,0xff,0xe7,0xa5,0xbf,0x00,0x01,
-       0xff,0xe7,0xb6,0xa0,0x00,0x10,0x08,0x01,0xff,0xe8,0x8f,0x89,0x00,0x01,0xff,0xe9,
-       0x8c,0x84,0x00,0xcf,0x86,0xe5,0x01,0x01,0xd4,0x80,0xd3,0x40,0xd2,0x20,0xd1,0x10,
-       0x10,0x08,0x01,0xff,0xe9,0xb9,0xbf,0x00,0x01,0xff,0xe8,0xab,0x96,0x00,0x10,0x08,
-       0x01,0xff,0xe5,0xa3,0x9f,0x00,0x01,0xff,0xe5,0xbc,0x84,0x00,0xd1,0x10,0x10,0x08,
-       0x01,0xff,0xe7,0xb1,0xa0,0x00,0x01,0xff,0xe8,0x81,0xbe,0x00,0x10,0x08,0x01,0xff,
-       0xe7,0x89,0xa2,0x00,0x01,0xff,0xe7,0xa3,0x8a,0x00,0xd2,0x20,0xd1,0x10,0x10,0x08,
-       0x01,0xff,0xe8,0xb3,0x82,0x00,0x01,0xff,0xe9,0x9b,0xb7,0x00,0x10,0x08,0x01,0xff,
-       0xe5,0xa3,0x98,0x00,0x01,0xff,0xe5,0xb1,0xa2,0x00,0xd1,0x10,0x10,0x08,0x01,0xff,
-       0xe6,0xa8,0x93,0x00,0x01,0xff,0xe6,0xb7,0x9a,0x00,0x10,0x08,0x01,0xff,0xe6,0xbc,
-       0x8f,0x00,0x01,0xff,0xe7,0xb4,0xaf,0x00,0xd3,0x40,0xd2,0x20,0xd1,0x10,0x10,0x08,
-       0x01,0xff,0xe7,0xb8,0xb7,0x00,0x01,0xff,0xe9,0x99,0x8b,0x00,0x10,0x08,0x01,0xff,
-       0xe5,0x8b,0x92,0x00,0x01,0xff,0xe8,0x82,0x8b,0x00,0xd1,0x10,0x10,0x08,0x01,0xff,
-       0xe5,0x87,0x9c,0x00,0x01,0xff,0xe5,0x87,0x8c,0x00,0x10,0x08,0x01,0xff,0xe7,0xa8,
-       0x9c,0x00,0x01,0xff,0xe7,0xb6,0xbe,0x00,0xd2,0x20,0xd1,0x10,0x10,0x08,0x01,0xff,
-       0xe8,0x8f,0xb1,0x00,0x01,0xff,0xe9,0x99,0xb5,0x00,0x10,0x08,0x01,0xff,0xe8,0xae,
-       0x80,0x00,0x01,0xff,0xe6,0x8b,0x8f,0x00,0xd1,0x10,0x10,0x08,0x01,0xff,0xe6,0xa8,
-       0x82,0x00,0x01,0xff,0xe8,0xab,0xbe,0x00,0x10,0x08,0x01,0xff,0xe4,0xb8,0xb9,0x00,
-       0x01,0xff,0xe5,0xaf,0xa7,0x00,0xd4,0x80,0xd3,0x40,0xd2,0x20,0xd1,0x10,0x10,0x08,
-       0x01,0xff,0xe6,0x80,0x92,0x00,0x01,0xff,0xe7,0x8e,0x87,0x00,0x10,0x08,0x01,0xff,
-       0xe7,0x95,0xb0,0x00,0x01,0xff,0xe5,0x8c,0x97,0x00,0xd1,0x10,0x10,0x08,0x01,0xff,
-       0xe7,0xa3,0xbb,0x00,0x01,0xff,0xe4,0xbe,0xbf,0x00,0x10,0x08,0x01,0xff,0xe5,0xbe,
-       0xa9,0x00,0x01,0xff,0xe4,0xb8,0x8d,0x00,0xd2,0x20,0xd1,0x10,0x10,0x08,0x01,0xff,
-       0xe6,0xb3,0x8c,0x00,0x01,0xff,0xe6,0x95,0xb8,0x00,0x10,0x08,0x01,0xff,0xe7,0xb4,
-       0xa2,0x00,0x01,0xff,0xe5,0x8f,0x83,0x00,0xd1,0x10,0x10,0x08,0x01,0xff,0xe5,0xa1,
-       0x9e,0x00,0x01,0xff,0xe7,0x9c,0x81,0x00,0x10,0x08,0x01,0xff,0xe8,0x91,0x89,0x00,
-       0x01,0xff,0xe8,0xaa,0xaa,0x00,0xd3,0x40,0xd2,0x20,0xd1,0x10,0x10,0x08,0x01,0xff,
-       0xe6,0xae,0xba,0x00,0x01,0xff,0xe8,0xbe,0xb0,0x00,0x10,0x08,0x01,0xff,0xe6,0xb2,
-       0x88,0x00,0x01,0xff,0xe6,0x8b,0xbe,0x00,0xd1,0x10,0x10,0x08,0x01,0xff,0xe8,0x8b,
-       0xa5,0x00,0x01,0xff,0xe6,0x8e,0xa0,0x00,0x10,0x08,0x01,0xff,0xe7,0x95,0xa5,0x00,
-       0x01,0xff,0xe4,0xba,0xae,0x00,0xd2,0x20,0xd1,0x10,0x10,0x08,0x01,0xff,0xe5,0x85,
-       0xa9,0x00,0x01,0xff,0xe5,0x87,0x89,0x00,0x10,0x08,0x01,0xff,0xe6,0xa2,0x81,0x00,
-       0x01,0xff,0xe7,0xb3,0xa7,0x00,0xd1,0x10,0x10,0x08,0x01,0xff,0xe8,0x89,0xaf,0x00,
-       0x01,0xff,0xe8,0xab,0x92,0x00,0x10,0x08,0x01,0xff,0xe9,0x87,0x8f,0x00,0x01,0xff,
-       0xe5,0x8b,0xb5,0x00,0xe0,0x04,0x02,0xcf,0x86,0xe5,0x01,0x01,0xd4,0x80,0xd3,0x40,
-       0xd2,0x20,0xd1,0x10,0x10,0x08,0x01,0xff,0xe5,0x91,0x82,0x00,0x01,0xff,0xe5,0xa5,
-       0xb3,0x00,0x10,0x08,0x01,0xff,0xe5,0xbb,0xac,0x00,0x01,0xff,0xe6,0x97,0x85,0x00,
-       0xd1,0x10,0x10,0x08,0x01,0xff,0xe6,0xbf,0xbe,0x00,0x01,0xff,0xe7,0xa4,0xaa,0x00,
-       0x10,0x08,0x01,0xff,0xe9,0x96,0xad,0x00,0x01,0xff,0xe9,0xa9,0xaa,0x00,0xd2,0x20,
-       0xd1,0x10,0x10,0x08,0x01,0xff,0xe9,0xba,0x97,0x00,0x01,0xff,0xe9,0xbb,0x8e,0x00,
-       0x10,0x08,0x01,0xff,0xe5,0x8a,0x9b,0x00,0x01,0xff,0xe6,0x9b,0x86,0x00,0xd1,0x10,
-       0x10,0x08,0x01,0xff,0xe6,0xad,0xb7,0x00,0x01,0xff,0xe8,0xbd,0xa2,0x00,0x10,0x08,
-       0x01,0xff,0xe5,0xb9,0xb4,0x00,0x01,0xff,0xe6,0x86,0x90,0x00,0xd3,0x40,0xd2,0x20,
-       0xd1,0x10,0x10,0x08,0x01,0xff,0xe6,0x88,0x80,0x00,0x01,0xff,0xe6,0x92,0x9a,0x00,
-       0x10,0x08,0x01,0xff,0xe6,0xbc,0xa3,0x00,0x01,0xff,0xe7,0x85,0x89,0x00,0xd1,0x10,
-       0x10,0x08,0x01,0xff,0xe7,0x92,0x89,0x00,0x01,0xff,0xe7,0xa7,0x8a,0x00,0x10,0x08,
-       0x01,0xff,0xe7,0xb7,0xb4,0x00,0x01,0xff,0xe8,0x81,0xaf,0x00,0xd2,0x20,0xd1,0x10,
-       0x10,0x08,0x01,0xff,0xe8,0xbc,0xa6,0x00,0x01,0xff,0xe8,0x93,0xae,0x00,0x10,0x08,
-       0x01,0xff,0xe9,0x80,0xa3,0x00,0x01,0xff,0xe9,0x8d,0x8a,0x00,0xd1,0x10,0x10,0x08,
-       0x01,0xff,0xe5,0x88,0x97,0x00,0x01,0xff,0xe5,0x8a,0xa3,0x00,0x10,0x08,0x01,0xff,
-       0xe5,0x92,0xbd,0x00,0x01,0xff,0xe7,0x83,0x88,0x00,0xd4,0x80,0xd3,0x40,0xd2,0x20,
-       0xd1,0x10,0x10,0x08,0x01,0xff,0xe8,0xa3,0x82,0x00,0x01,0xff,0xe8,0xaa,0xaa,0x00,
-       0x10,0x08,0x01,0xff,0xe5,0xbb,0x89,0x00,0x01,0xff,0xe5,0xbf,0xb5,0x00,0xd1,0x10,
-       0x10,0x08,0x01,0xff,0xe6,0x8d,0xbb,0x00,0x01,0xff,0xe6,0xae,0xae,0x00,0x10,0x08,
-       0x01,0xff,0xe7,0xb0,0xbe,0x00,0x01,0xff,0xe7,0x8d,0xb5,0x00,0xd2,0x20,0xd1,0x10,
-       0x10,0x08,0x01,0xff,0xe4,0xbb,0xa4,0x00,0x01,0xff,0xe5,0x9b,0xb9,0x00,0x10,0x08,
-       0x01,0xff,0xe5,0xaf,0xa7,0x00,0x01,0xff,0xe5,0xb6,0xba,0x00,0xd1,0x10,0x10,0x08,
-       0x01,0xff,0xe6,0x80,0x9c,0x00,0x01,0xff,0xe7,0x8e,0xb2,0x00,0x10,0x08,0x01,0xff,
-       0xe7,0x91,0xa9,0x00,0x01,0xff,0xe7,0xbe,0x9a,0x00,0xd3,0x40,0xd2,0x20,0xd1,0x10,
-       0x10,0x08,0x01,0xff,0xe8,0x81,0x86,0x00,0x01,0xff,0xe9,0x88,0xb4,0x00,0x10,0x08,
-       0x01,0xff,0xe9,0x9b,0xb6,0x00,0x01,0xff,0xe9,0x9d,0x88,0x00,0xd1,0x10,0x10,0x08,
-       0x01,0xff,0xe9,0xa0,0x98,0x00,0x01,0xff,0xe4,0xbe,0x8b,0x00,0x10,0x08,0x01,0xff,
-       0xe7,0xa6,0xae,0x00,0x01,0xff,0xe9,0x86,0xb4,0x00,0xd2,0x20,0xd1,0x10,0x10,0x08,
-       0x01,0xff,0xe9,0x9a,0xb8,0x00,0x01,0xff,0xe6,0x83,0xa1,0x00,0x10,0x08,0x01,0xff,
-       0xe4,0xba,0x86,0x00,0x01,0xff,0xe5,0x83,0x9a,0x00,0xd1,0x10,0x10,0x08,0x01,0xff,
-       0xe5,0xaf,0xae,0x00,0x01,0xff,0xe5,0xb0,0xbf,0x00,0x10,0x08,0x01,0xff,0xe6,0x96,
-       0x99,0x00,0x01,0xff,0xe6,0xa8,0x82,0x00,0xcf,0x86,0xe5,0x01,0x01,0xd4,0x80,0xd3,
-       0x40,0xd2,0x20,0xd1,0x10,0x10,0x08,0x01,0xff,0xe7,0x87,0x8e,0x00,0x01,0xff,0xe7,
-       0x99,0x82,0x00,0x10,0x08,0x01,0xff,0xe8,0x93,0xbc,0x00,0x01,0xff,0xe9,0x81,0xbc,
-       0x00,0xd1,0x10,0x10,0x08,0x01,0xff,0xe9,0xbe,0x8d,0x00,0x01,0xff,0xe6,0x9a,0x88,
-       0x00,0x10,0x08,0x01,0xff,0xe9,0x98,0xae,0x00,0x01,0xff,0xe5,0x8a,0x89,0x00,0xd2,
-       0x20,0xd1,0x10,0x10,0x08,0x01,0xff,0xe6,0x9d,0xbb,0x00,0x01,0xff,0xe6,0x9f,0xb3,
-       0x00,0x10,0x08,0x01,0xff,0xe6,0xb5,0x81,0x00,0x01,0xff,0xe6,0xba,0x9c,0x00,0xd1,
-       0x10,0x10,0x08,0x01,0xff,0xe7,0x90,0x89,0x00,0x01,0xff,0xe7,0x95,0x99,0x00,0x10,
-       0x08,0x01,0xff,0xe7,0xa1,0xab,0x00,0x01,0xff,0xe7,0xb4,0x90,0x00,0xd3,0x40,0xd2,
-       0x20,0xd1,0x10,0x10,0x08,0x01,0xff,0xe9,0xa1,0x9e,0x00,0x01,0xff,0xe5,0x85,0xad,
-       0x00,0x10,0x08,0x01,0xff,0xe6,0x88,0xae,0x00,0x01,0xff,0xe9,0x99,0xb8,0x00,0xd1,
-       0x10,0x10,0x08,0x01,0xff,0xe5,0x80,0xab,0x00,0x01,0xff,0xe5,0xb4,0x99,0x00,0x10,
-       0x08,0x01,0xff,0xe6,0xb7,0xaa,0x00,0x01,0xff,0xe8,0xbc,0xaa,0x00,0xd2,0x20,0xd1,
-       0x10,0x10,0x08,0x01,0xff,0xe5,0xbe,0x8b,0x00,0x01,0xff,0xe6,0x85,0x84,0x00,0x10,
-       0x08,0x01,0xff,0xe6,0xa0,0x97,0x00,0x01,0xff,0xe7,0x8e,0x87,0x00,0xd1,0x10,0x10,
-       0x08,0x01,0xff,0xe9,0x9a,0x86,0x00,0x01,0xff,0xe5,0x88,0xa9,0x00,0x10,0x08,0x01,
-       0xff,0xe5,0x90,0x8f,0x00,0x01,0xff,0xe5,0xb1,0xa5,0x00,0xd4,0x80,0xd3,0x40,0xd2,
-       0x20,0xd1,0x10,0x10,0x08,0x01,0xff,0xe6,0x98,0x93,0x00,0x01,0xff,0xe6,0x9d,0x8e,
-       0x00,0x10,0x08,0x01,0xff,0xe6,0xa2,0xa8,0x00,0x01,0xff,0xe6,0xb3,0xa5,0x00,0xd1,
-       0x10,0x10,0x08,0x01,0xff,0xe7,0x90,0x86,0x00,0x01,0xff,0xe7,0x97,0xa2,0x00,0x10,
-       0x08,0x01,0xff,0xe7,0xbd,0xb9,0x00,0x01,0xff,0xe8,0xa3,0x8f,0x00,0xd2,0x20,0xd1,
-       0x10,0x10,0x08,0x01,0xff,0xe8,0xa3,0xa1,0x00,0x01,0xff,0xe9,0x87,0x8c,0x00,0x10,
-       0x08,0x01,0xff,0xe9,0x9b,0xa2,0x00,0x01,0xff,0xe5,0x8c,0xbf,0x00,0xd1,0x10,0x10,
-       0x08,0x01,0xff,0xe6,0xba,0xba,0x00,0x01,0xff,0xe5,0x90,0x9d,0x00,0x10,0x08,0x01,
-       0xff,0xe7,0x87,0x90,0x00,0x01,0xff,0xe7,0x92,0x98,0x00,0xd3,0x40,0xd2,0x20,0xd1,
-       0x10,0x10,0x08,0x01,0xff,0xe8,0x97,0xba,0x00,0x01,0xff,0xe9,0x9a,0xa3,0x00,0x10,
-       0x08,0x01,0xff,0xe9,0xb1,0x97,0x00,0x01,0xff,0xe9,0xba,0x9f,0x00,0xd1,0x10,0x10,
-       0x08,0x01,0xff,0xe6,0x9e,0x97,0x00,0x01,0xff,0xe6,0xb7,0x8b,0x00,0x10,0x08,0x01,
-       0xff,0xe8,0x87,0xa8,0x00,0x01,0xff,0xe7,0xab,0x8b,0x00,0xd2,0x20,0xd1,0x10,0x10,
-       0x08,0x01,0xff,0xe7,0xac,0xa0,0x00,0x01,0xff,0xe7,0xb2,0x92,0x00,0x10,0x08,0x01,
-       0xff,0xe7,0x8b,0x80,0x00,0x01,0xff,0xe7,0x82,0x99,0x00,0xd1,0x10,0x10,0x08,0x01,
-       0xff,0xe8,0xad,0x98,0x00,0x01,0xff,0xe4,0xbb,0x80,0x00,0x10,0x08,0x01,0xff,0xe8,
-       0x8c,0xb6,0x00,0x01,0xff,0xe5,0x88,0xba,0x00,0xe2,0xad,0x06,0xe1,0xc4,0x03,0xe0,
-       0xcb,0x01,0xcf,0x86,0xd5,0xe4,0xd4,0x74,0xd3,0x40,0xd2,0x20,0xd1,0x10,0x10,0x08,
-       0x01,0xff,0xe5,0x88,0x87,0x00,0x01,0xff,0xe5,0xba,0xa6,0x00,0x10,0x08,0x01,0xff,
-       0xe6,0x8b,0x93,0x00,0x01,0xff,0xe7,0xb3,0x96,0x00,0xd1,0x10,0x10,0x08,0x01,0xff,
-       0xe5,0xae,0x85,0x00,0x01,0xff,0xe6,0xb4,0x9e,0x00,0x10,0x08,0x01,0xff,0xe6,0x9a,
-       0xb4,0x00,0x01,0xff,0xe8,0xbc,0xbb,0x00,0xd2,0x20,0xd1,0x10,0x10,0x08,0x01,0xff,
-       0xe8,0xa1,0x8c,0x00,0x01,0xff,0xe9,0x99,0x8d,0x00,0x10,0x08,0x01,0xff,0xe8,0xa6,
-       0x8b,0x00,0x01,0xff,0xe5,0xbb,0x93,0x00,0x91,0x10,0x10,0x08,0x01,0xff,0xe5,0x85,
-       0x80,0x00,0x01,0xff,0xe5,0x97,0x80,0x00,0x01,0x00,0xd3,0x34,0xd2,0x18,0xd1,0x0c,
-       0x10,0x08,0x01,0xff,0xe5,0xa1,0x9a,0x00,0x01,0x00,0x10,0x08,0x01,0xff,0xe6,0x99,
-       0xb4,0x00,0x01,0x00,0xd1,0x0c,0x10,0x04,0x01,0x00,0x01,0xff,0xe5,0x87,0x9e,0x00,
-       0x10,0x08,0x01,0xff,0xe7,0x8c,0xaa,0x00,0x01,0xff,0xe7,0x9b,0x8a,0x00,0xd2,0x20,
-       0xd1,0x10,0x10,0x08,0x01,0xff,0xe7,0xa4,0xbc,0x00,0x01,0xff,0xe7,0xa5,0x9e,0x00,
-       0x10,0x08,0x01,0xff,0xe7,0xa5,0xa5,0x00,0x01,0xff,0xe7,0xa6,0x8f,0x00,0xd1,0x10,
-       0x10,0x08,0x01,0xff,0xe9,0x9d,0x96,0x00,0x01,0xff,0xe7,0xb2,0xbe,0x00,0x10,0x08,
-       0x01,0xff,0xe7,0xbe,0xbd,0x00,0x01,0x00,0xd4,0x64,0xd3,0x30,0xd2,0x18,0xd1,0x0c,
-       0x10,0x08,0x01,0xff,0xe8,0x98,0x92,0x00,0x01,0x00,0x10,0x08,0x01,0xff,0xe8,0xab,
-       0xb8,0x00,0x01,0x00,0xd1,0x0c,0x10,0x04,0x01,0x00,0x01,0xff,0xe9,0x80,0xb8,0x00,
-       0x10,0x08,0x01,0xff,0xe9,0x83,0xbd,0x00,0x01,0x00,0xd2,0x14,0x51,0x04,0x01,0x00,
-       0x10,0x08,0x01,0xff,0xe9,0xa3,0xaf,0x00,0x01,0xff,0xe9,0xa3,0xbc,0x00,0xd1,0x10,
-       0x10,0x08,0x01,0xff,0xe9,0xa4,0xa8,0x00,0x01,0xff,0xe9,0xb6,0xb4,0x00,0x10,0x08,
-       0x0d,0xff,0xe9,0x83,0x9e,0x00,0x0d,0xff,0xe9,0x9a,0xb7,0x00,0xd3,0x40,0xd2,0x20,
-       0xd1,0x10,0x10,0x08,0x06,0xff,0xe4,0xbe,0xae,0x00,0x06,0xff,0xe5,0x83,0xa7,0x00,
-       0x10,0x08,0x06,0xff,0xe5,0x85,0x8d,0x00,0x06,0xff,0xe5,0x8b,0x89,0x00,0xd1,0x10,
-       0x10,0x08,0x06,0xff,0xe5,0x8b,0xa4,0x00,0x06,0xff,0xe5,0x8d,0x91,0x00,0x10,0x08,
-       0x06,0xff,0xe5,0x96,0x9d,0x00,0x06,0xff,0xe5,0x98,0x86,0x00,0xd2,0x20,0xd1,0x10,
-       0x10,0x08,0x06,0xff,0xe5,0x99,0xa8,0x00,0x06,0xff,0xe5,0xa1,0x80,0x00,0x10,0x08,
-       0x06,0xff,0xe5,0xa2,0xa8,0x00,0x06,0xff,0xe5,0xb1,0xa4,0x00,0xd1,0x10,0x10,0x08,
-       0x06,0xff,0xe5,0xb1,0xae,0x00,0x06,0xff,0xe6,0x82,0x94,0x00,0x10,0x08,0x06,0xff,
-       0xe6,0x85,0xa8,0x00,0x06,0xff,0xe6,0x86,0x8e,0x00,0xcf,0x86,0xe5,0x01,0x01,0xd4,
-       0x80,0xd3,0x40,0xd2,0x20,0xd1,0x10,0x10,0x08,0x06,0xff,0xe6,0x87,0xb2,0x00,0x06,
-       0xff,0xe6,0x95,0x8f,0x00,0x10,0x08,0x06,0xff,0xe6,0x97,0xa2,0x00,0x06,0xff,0xe6,
-       0x9a,0x91,0x00,0xd1,0x10,0x10,0x08,0x06,0xff,0xe6,0xa2,0x85,0x00,0x06,0xff,0xe6,
-       0xb5,0xb7,0x00,0x10,0x08,0x06,0xff,0xe6,0xb8,0x9a,0x00,0x06,0xff,0xe6,0xbc,0xa2,
-       0x00,0xd2,0x20,0xd1,0x10,0x10,0x08,0x06,0xff,0xe7,0x85,0xae,0x00,0x06,0xff,0xe7,
-       0x88,0xab,0x00,0x10,0x08,0x06,0xff,0xe7,0x90,0xa2,0x00,0x06,0xff,0xe7,0xa2,0x91,
-       0x00,0xd1,0x10,0x10,0x08,0x06,0xff,0xe7,0xa4,0xbe,0x00,0x06,0xff,0xe7,0xa5,0x89,
-       0x00,0x10,0x08,0x06,0xff,0xe7,0xa5,0x88,0x00,0x06,0xff,0xe7,0xa5,0x90,0x00,0xd3,
-       0x40,0xd2,0x20,0xd1,0x10,0x10,0x08,0x06,0xff,0xe7,0xa5,0x96,0x00,0x06,0xff,0xe7,
-       0xa5,0x9d,0x00,0x10,0x08,0x06,0xff,0xe7,0xa6,0x8d,0x00,0x06,0xff,0xe7,0xa6,0x8e,
-       0x00,0xd1,0x10,0x10,0x08,0x06,0xff,0xe7,0xa9,0x80,0x00,0x06,0xff,0xe7,0xaa,0x81,
-       0x00,0x10,0x08,0x06,0xff,0xe7,0xaf,0x80,0x00,0x06,0xff,0xe7,0xb7,0xb4,0x00,0xd2,
-       0x20,0xd1,0x10,0x10,0x08,0x06,0xff,0xe7,0xb8,0x89,0x00,0x06,0xff,0xe7,0xb9,0x81,
-       0x00,0x10,0x08,0x06,0xff,0xe7,0xbd,0xb2,0x00,0x06,0xff,0xe8,0x80,0x85,0x00,0xd1,
-       0x10,0x10,0x08,0x06,0xff,0xe8,0x87,0xad,0x00,0x06,0xff,0xe8,0x89,0xb9,0x00,0x10,
-       0x08,0x06,0xff,0xe8,0x89,0xb9,0x00,0x06,0xff,0xe8,0x91,0x97,0x00,0xd4,0x75,0xd3,
-       0x40,0xd2,0x20,0xd1,0x10,0x10,0x08,0x06,0xff,0xe8,0xa4,0x90,0x00,0x06,0xff,0xe8,
-       0xa6,0x96,0x00,0x10,0x08,0x06,0xff,0xe8,0xac,0x81,0x00,0x06,0xff,0xe8,0xac,0xb9,
-       0x00,0xd1,0x10,0x10,0x08,0x06,0xff,0xe8,0xb3,0x93,0x00,0x06,0xff,0xe8,0xb4,0x88,
-       0x00,0x10,0x08,0x06,0xff,0xe8,0xbe,0xb6,0x00,0x06,0xff,0xe9,0x80,0xb8,0x00,0xd2,
-       0x20,0xd1,0x10,0x10,0x08,0x06,0xff,0xe9,0x9b,0xa3,0x00,0x06,0xff,0xe9,0x9f,0xbf,
-       0x00,0x10,0x08,0x06,0xff,0xe9,0xa0,0xbb,0x00,0x0b,0xff,0xe6,0x81,0xb5,0x00,0x91,
-       0x11,0x10,0x09,0x0b,0xff,0xf0,0xa4,0x8b,0xae,0x00,0x0b,0xff,0xe8,0x88,0x98,0x00,
-       0x00,0x00,0xd3,0x40,0xd2,0x20,0xd1,0x10,0x10,0x08,0x08,0xff,0xe4,0xb8,0xa6,0x00,
-       0x08,0xff,0xe5,0x86,0xb5,0x00,0x10,0x08,0x08,0xff,0xe5,0x85,0xa8,0x00,0x08,0xff,
-       0xe4,0xbe,0x80,0x00,0xd1,0x10,0x10,0x08,0x08,0xff,0xe5,0x85,0x85,0x00,0x08,0xff,
-       0xe5,0x86,0x80,0x00,0x10,0x08,0x08,0xff,0xe5,0x8b,0x87,0x00,0x08,0xff,0xe5,0x8b,
-       0xba,0x00,0xd2,0x20,0xd1,0x10,0x10,0x08,0x08,0xff,0xe5,0x96,0x9d,0x00,0x08,0xff,
-       0xe5,0x95,0x95,0x00,0x10,0x08,0x08,0xff,0xe5,0x96,0x99,0x00,0x08,0xff,0xe5,0x97,
-       0xa2,0x00,0xd1,0x10,0x10,0x08,0x08,0xff,0xe5,0xa1,0x9a,0x00,0x08,0xff,0xe5,0xa2,
-       0xb3,0x00,0x10,0x08,0x08,0xff,0xe5,0xa5,0x84,0x00,0x08,0xff,0xe5,0xa5,0x94,0x00,
-       0xe0,0x04,0x02,0xcf,0x86,0xe5,0x01,0x01,0xd4,0x80,0xd3,0x40,0xd2,0x20,0xd1,0x10,
-       0x10,0x08,0x08,0xff,0xe5,0xa9,0xa2,0x00,0x08,0xff,0xe5,0xac,0xa8,0x00,0x10,0x08,
-       0x08,0xff,0xe5,0xbb,0x92,0x00,0x08,0xff,0xe5,0xbb,0x99,0x00,0xd1,0x10,0x10,0x08,
-       0x08,0xff,0xe5,0xbd,0xa9,0x00,0x08,0xff,0xe5,0xbe,0xad,0x00,0x10,0x08,0x08,0xff,
-       0xe6,0x83,0x98,0x00,0x08,0xff,0xe6,0x85,0x8e,0x00,0xd2,0x20,0xd1,0x10,0x10,0x08,
-       0x08,0xff,0xe6,0x84,0x88,0x00,0x08,0xff,0xe6,0x86,0x8e,0x00,0x10,0x08,0x08,0xff,
-       0xe6,0x85,0xa0,0x00,0x08,0xff,0xe6,0x87,0xb2,0x00,0xd1,0x10,0x10,0x08,0x08,0xff,
-       0xe6,0x88,0xb4,0x00,0x08,0xff,0xe6,0x8f,0x84,0x00,0x10,0x08,0x08,0xff,0xe6,0x90,
-       0x9c,0x00,0x08,0xff,0xe6,0x91,0x92,0x00,0xd3,0x40,0xd2,0x20,0xd1,0x10,0x10,0x08,
-       0x08,0xff,0xe6,0x95,0x96,0x00,0x08,0xff,0xe6,0x99,0xb4,0x00,0x10,0x08,0x08,0xff,
-       0xe6,0x9c,0x97,0x00,0x08,0xff,0xe6,0x9c,0x9b,0x00,0xd1,0x10,0x10,0x08,0x08,0xff,
-       0xe6,0x9d,0x96,0x00,0x08,0xff,0xe6,0xad,0xb9,0x00,0x10,0x08,0x08,0xff,0xe6,0xae,
-       0xba,0x00,0x08,0xff,0xe6,0xb5,0x81,0x00,0xd2,0x20,0xd1,0x10,0x10,0x08,0x08,0xff,
-       0xe6,0xbb,0x9b,0x00,0x08,0xff,0xe6,0xbb,0x8b,0x00,0x10,0x08,0x08,0xff,0xe6,0xbc,
-       0xa2,0x00,0x08,0xff,0xe7,0x80,0x9e,0x00,0xd1,0x10,0x10,0x08,0x08,0xff,0xe7,0x85,
-       0xae,0x00,0x08,0xff,0xe7,0x9e,0xa7,0x00,0x10,0x08,0x08,0xff,0xe7,0x88,0xb5,0x00,
-       0x08,0xff,0xe7,0x8a,0xaf,0x00,0xd4,0x80,0xd3,0x40,0xd2,0x20,0xd1,0x10,0x10,0x08,
-       0x08,0xff,0xe7,0x8c,0xaa,0x00,0x08,0xff,0xe7,0x91,0xb1,0x00,0x10,0x08,0x08,0xff,
-       0xe7,0x94,0x86,0x00,0x08,0xff,0xe7,0x94,0xbb,0x00,0xd1,0x10,0x10,0x08,0x08,0xff,
-       0xe7,0x98,0x9d,0x00,0x08,0xff,0xe7,0x98,0x9f,0x00,0x10,0x08,0x08,0xff,0xe7,0x9b,
-       0x8a,0x00,0x08,0xff,0xe7,0x9b,0x9b,0x00,0xd2,0x20,0xd1,0x10,0x10,0x08,0x08,0xff,
-       0xe7,0x9b,0xb4,0x00,0x08,0xff,0xe7,0x9d,0x8a,0x00,0x10,0x08,0x08,0xff,0xe7,0x9d,
-       0x80,0x00,0x08,0xff,0xe7,0xa3,0x8c,0x00,0xd1,0x10,0x10,0x08,0x08,0xff,0xe7,0xaa,
-       0xb1,0x00,0x08,0xff,0xe7,0xaf,0x80,0x00,0x10,0x08,0x08,0xff,0xe7,0xb1,0xbb,0x00,
-       0x08,0xff,0xe7,0xb5,0x9b,0x00,0xd3,0x40,0xd2,0x20,0xd1,0x10,0x10,0x08,0x08,0xff,
-       0xe7,0xb7,0xb4,0x00,0x08,0xff,0xe7,0xbc,0xbe,0x00,0x10,0x08,0x08,0xff,0xe8,0x80,
-       0x85,0x00,0x08,0xff,0xe8,0x8d,0x92,0x00,0xd1,0x10,0x10,0x08,0x08,0xff,0xe8,0x8f,
-       0xaf,0x00,0x08,0xff,0xe8,0x9d,0xb9,0x00,0x10,0x08,0x08,0xff,0xe8,0xa5,0x81,0x00,
-       0x08,0xff,0xe8,0xa6,0x86,0x00,0xd2,0x20,0xd1,0x10,0x10,0x08,0x08,0xff,0xe8,0xa6,
-       0x96,0x00,0x08,0xff,0xe8,0xaa,0xbf,0x00,0x10,0x08,0x08,0xff,0xe8,0xab,0xb8,0x00,
-       0x08,0xff,0xe8,0xab,0x8b,0x00,0xd1,0x10,0x10,0x08,0x08,0xff,0xe8,0xac,0x81,0x00,
-       0x08,0xff,0xe8,0xab,0xbe,0x00,0x10,0x08,0x08,0xff,0xe8,0xab,0xad,0x00,0x08,0xff,
-       0xe8,0xac,0xb9,0x00,0xcf,0x86,0x95,0xde,0xd4,0x81,0xd3,0x40,0xd2,0x20,0xd1,0x10,
-       0x10,0x08,0x08,0xff,0xe8,0xae,0x8a,0x00,0x08,0xff,0xe8,0xb4,0x88,0x00,0x10,0x08,
-       0x08,0xff,0xe8,0xbc,0xb8,0x00,0x08,0xff,0xe9,0x81,0xb2,0x00,0xd1,0x10,0x10,0x08,
-       0x08,0xff,0xe9,0x86,0x99,0x00,0x08,0xff,0xe9,0x89,0xb6,0x00,0x10,0x08,0x08,0xff,
-       0xe9,0x99,0xbc,0x00,0x08,0xff,0xe9,0x9b,0xa3,0x00,0xd2,0x20,0xd1,0x10,0x10,0x08,
-       0x08,0xff,0xe9,0x9d,0x96,0x00,0x08,0xff,0xe9,0x9f,0x9b,0x00,0x10,0x08,0x08,0xff,
-       0xe9,0x9f,0xbf,0x00,0x08,0xff,0xe9,0xa0,0x8b,0x00,0xd1,0x10,0x10,0x08,0x08,0xff,
-       0xe9,0xa0,0xbb,0x00,0x08,0xff,0xe9,0xac,0x92,0x00,0x10,0x08,0x08,0xff,0xe9,0xbe,
-       0x9c,0x00,0x08,0xff,0xf0,0xa2,0xa1,0x8a,0x00,0xd3,0x45,0xd2,0x22,0xd1,0x12,0x10,
-       0x09,0x08,0xff,0xf0,0xa2,0xa1,0x84,0x00,0x08,0xff,0xf0,0xa3,0x8f,0x95,0x00,0x10,
-       0x08,0x08,0xff,0xe3,0xae,0x9d,0x00,0x08,0xff,0xe4,0x80,0x98,0x00,0xd1,0x11,0x10,
-       0x08,0x08,0xff,0xe4,0x80,0xb9,0x00,0x08,0xff,0xf0,0xa5,0x89,0x89,0x00,0x10,0x09,
-       0x08,0xff,0xf0,0xa5,0xb3,0x90,0x00,0x08,0xff,0xf0,0xa7,0xbb,0x93,0x00,0x92,0x14,
-       0x91,0x10,0x10,0x08,0x08,0xff,0xe9,0xbd,0x83,0x00,0x08,0xff,0xe9,0xbe,0x8e,0x00,
-       0x00,0x00,0x00,0x00,0x00,0x00,0xe1,0x94,0x01,0xe0,0x08,0x01,0xcf,0x86,0xd5,0x42,
-       0xd4,0x14,0x93,0x10,0x52,0x04,0x01,0x00,0x51,0x04,0x01,0x00,0x10,0x04,0x01,0x00,
-       0x00,0x00,0x00,0x00,0xd3,0x10,0x92,0x0c,0x51,0x04,0x00,0x00,0x10,0x04,0x00,0x00,
-       0x01,0x00,0x01,0x00,0x52,0x04,0x00,0x00,0xd1,0x0d,0x10,0x04,0x00,0x00,0x04,0xff,
-       0xd7,0x99,0xd6,0xb4,0x00,0x10,0x04,0x01,0x1a,0x01,0xff,0xd7,0xb2,0xd6,0xb7,0x00,
-       0xd4,0x42,0x53,0x04,0x01,0x00,0xd2,0x16,0x51,0x04,0x01,0x00,0x10,0x09,0x01,0xff,
-       0xd7,0xa9,0xd7,0x81,0x00,0x01,0xff,0xd7,0xa9,0xd7,0x82,0x00,0xd1,0x16,0x10,0x0b,
-       0x01,0xff,0xd7,0xa9,0xd6,0xbc,0xd7,0x81,0x00,0x01,0xff,0xd7,0xa9,0xd6,0xbc,0xd7,
-       0x82,0x00,0x10,0x09,0x01,0xff,0xd7,0x90,0xd6,0xb7,0x00,0x01,0xff,0xd7,0x90,0xd6,
-       0xb8,0x00,0xd3,0x43,0xd2,0x24,0xd1,0x12,0x10,0x09,0x01,0xff,0xd7,0x90,0xd6,0xbc,
-       0x00,0x01,0xff,0xd7,0x91,0xd6,0xbc,0x00,0x10,0x09,0x01,0xff,0xd7,0x92,0xd6,0xbc,
-       0x00,0x01,0xff,0xd7,0x93,0xd6,0xbc,0x00,0xd1,0x12,0x10,0x09,0x01,0xff,0xd7,0x94,
-       0xd6,0xbc,0x00,0x01,0xff,0xd7,0x95,0xd6,0xbc,0x00,0x10,0x09,0x01,0xff,0xd7,0x96,
-       0xd6,0xbc,0x00,0x00,0x00,0xd2,0x24,0xd1,0x12,0x10,0x09,0x01,0xff,0xd7,0x98,0xd6,
-       0xbc,0x00,0x01,0xff,0xd7,0x99,0xd6,0xbc,0x00,0x10,0x09,0x01,0xff,0xd7,0x9a,0xd6,
-       0xbc,0x00,0x01,0xff,0xd7,0x9b,0xd6,0xbc,0x00,0xd1,0x0d,0x10,0x09,0x01,0xff,0xd7,
-       0x9c,0xd6,0xbc,0x00,0x00,0x00,0x10,0x09,0x01,0xff,0xd7,0x9e,0xd6,0xbc,0x00,0x00,
-       0x00,0xcf,0x86,0x95,0x85,0x94,0x81,0xd3,0x3e,0xd2,0x1f,0xd1,0x12,0x10,0x09,0x01,
-       0xff,0xd7,0xa0,0xd6,0xbc,0x00,0x01,0xff,0xd7,0xa1,0xd6,0xbc,0x00,0x10,0x04,0x00,
-       0x00,0x01,0xff,0xd7,0xa3,0xd6,0xbc,0x00,0xd1,0x0d,0x10,0x09,0x01,0xff,0xd7,0xa4,
-       0xd6,0xbc,0x00,0x00,0x00,0x10,0x09,0x01,0xff,0xd7,0xa6,0xd6,0xbc,0x00,0x01,0xff,
-       0xd7,0xa7,0xd6,0xbc,0x00,0xd2,0x24,0xd1,0x12,0x10,0x09,0x01,0xff,0xd7,0xa8,0xd6,
-       0xbc,0x00,0x01,0xff,0xd7,0xa9,0xd6,0xbc,0x00,0x10,0x09,0x01,0xff,0xd7,0xaa,0xd6,
-       0xbc,0x00,0x01,0xff,0xd7,0x95,0xd6,0xb9,0x00,0xd1,0x12,0x10,0x09,0x01,0xff,0xd7,
-       0x91,0xd6,0xbf,0x00,0x01,0xff,0xd7,0x9b,0xd6,0xbf,0x00,0x10,0x09,0x01,0xff,0xd7,
-       0xa4,0xd6,0xbf,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0xd0,0x1a,0xcf,0x86,0x55,0x04,
-       0x01,0x00,0x54,0x04,0x01,0x00,0x93,0x0c,0x92,0x08,0x11,0x04,0x01,0x00,0x0c,0x00,
-       0x0c,0x00,0x0c,0x00,0xcf,0x86,0x95,0x24,0xd4,0x10,0x93,0x0c,0x92,0x08,0x11,0x04,
-       0x0c,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x93,0x10,0x92,0x0c,0x51,0x04,0x00,0x00,
-       0x10,0x04,0x00,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0xd3,0x5a,0xd2,0x06,
-       0xcf,0x06,0x01,0x00,0xd1,0x14,0xd0,0x06,0xcf,0x06,0x01,0x00,0xcf,0x86,0x95,0x08,
-       0x14,0x04,0x00,0x00,0x01,0x00,0x01,0x00,0xd0,0x1a,0xcf,0x86,0x95,0x14,0x54,0x04,
-       0x01,0x00,0x93,0x0c,0x92,0x08,0x11,0x04,0x00,0x00,0x01,0x00,0x01,0x00,0x01,0x00,
-       0x01,0x00,0xcf,0x86,0xd5,0x0c,0x94,0x08,0x13,0x04,0x01,0x00,0x00,0x00,0x05,0x00,
-       0x54,0x04,0x05,0x00,0x53,0x04,0x01,0x00,0x52,0x04,0x01,0x00,0x91,0x08,0x10,0x04,
-       0x06,0x00,0x07,0x00,0x00,0x00,0xd2,0xce,0xd1,0xa5,0xd0,0x37,0xcf,0x86,0xd5,0x15,
-       0x54,0x05,0x06,0xff,0x00,0x53,0x04,0x08,0x00,0x92,0x08,0x11,0x04,0x08,0x00,0x00,
-       0x00,0x00,0x00,0x94,0x1c,0xd3,0x10,0x52,0x04,0x01,0xe6,0x51,0x04,0x0a,0xe6,0x10,
-       0x04,0x0a,0xe6,0x10,0xdc,0x52,0x04,0x10,0xdc,0x11,0x04,0x10,0xdc,0x11,0xe6,0x01,
-       0x00,0xcf,0x86,0xd5,0x38,0xd4,0x24,0xd3,0x14,0x52,0x04,0x01,0x00,0xd1,0x08,0x10,
-       0x04,0x01,0x00,0x06,0x00,0x10,0x04,0x06,0x00,0x07,0x00,0x92,0x0c,0x91,0x08,0x10,
-       0x04,0x07,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x93,0x10,0x92,0x0c,0x51,0x04,0x01,
-       0x00,0x10,0x04,0x01,0x00,0x00,0x00,0x01,0x00,0x01,0x00,0xd4,0x18,0xd3,0x10,0x52,
-       0x04,0x01,0x00,0x51,0x04,0x01,0x00,0x10,0x04,0x01,0x00,0x00,0x00,0x12,0x04,0x01,
-       0x00,0x00,0x00,0x93,0x18,0xd2,0x0c,0x51,0x04,0x01,0x00,0x10,0x04,0x01,0x00,0x06,
-       0x00,0x91,0x08,0x10,0x04,0x01,0x00,0x00,0x00,0x01,0x00,0x01,0x00,0xd0,0x06,0xcf,
-       0x06,0x01,0x00,0xcf,0x86,0x55,0x04,0x01,0x00,0x54,0x04,0x01,0x00,0x53,0x04,0x01,
+       0xd3,0x18,0xd2,0x0c,0x91,0x08,0x10,0x04,0x01,0x00,0x00,0x00,0x01,0x00,0x91,0x08,
+       0x10,0x04,0x00,0x00,0x01,0x00,0x01,0x00,0xd2,0x08,0x11,0x04,0x01,0x00,0x00,0x00,
+       0x91,0x08,0x10,0x04,0x01,0x07,0x01,0x00,0x01,0x00,0xcf,0x86,0xd5,0x3c,0xd4,0x28,
+       0xd3,0x10,0x52,0x04,0x01,0x00,0x51,0x04,0x01,0x00,0x10,0x04,0x00,0x00,0x01,0x00,
+       0xd2,0x0c,0x51,0x04,0x01,0x00,0x10,0x04,0x00,0x00,0x01,0x00,0x91,0x08,0x10,0x04,
+       0x01,0x00,0x01,0x09,0x00,0x00,0x93,0x10,0x92,0x0c,0x91,0x08,0x10,0x04,0x01,0x00,
+       0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xd4,0x18,0x93,0x14,0xd2,0x0c,0x91,0x08,
+       0x10,0x04,0x01,0x00,0x07,0x00,0x07,0x00,0x11,0x04,0x00,0x00,0x01,0x00,0x01,0x00,
+       0xd3,0x10,0x92,0x0c,0x91,0x08,0x10,0x04,0x0d,0x00,0x07,0x00,0x00,0x00,0x00,0x00,
+       0x92,0x0c,0x91,0x08,0x10,0x04,0x00,0x00,0x11,0x00,0x13,0x00,0x13,0x00,0xe1,0x24,
+       0x01,0xd0,0x86,0xcf,0x86,0xd5,0x44,0xd4,0x2c,0xd3,0x18,0xd2,0x0c,0x91,0x08,0x10,
+       0x04,0x00,0x00,0x01,0x00,0x01,0x00,0x91,0x08,0x10,0x04,0x00,0x00,0x01,0x00,0x01,
        0x00,0x52,0x04,0x01,0x00,0xd1,0x08,0x10,0x04,0x01,0x00,0x00,0x00,0x10,0x04,0x00,
-       0x00,0x01,0xff,0x00,0xd1,0x50,0xd0,0x1e,0xcf,0x86,0x95,0x18,0x94,0x14,0x93,0x10,
-       0x92,0x0c,0x91,0x08,0x10,0x04,0x00,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,
-       0x01,0x00,0x01,0x00,0xcf,0x86,0xd5,0x18,0x54,0x04,0x01,0x00,0x53,0x04,0x01,0x00,
-       0x52,0x04,0x01,0x00,0x51,0x04,0x01,0x00,0x10,0x04,0x01,0x00,0x06,0x00,0x94,0x14,
-       0x93,0x10,0x92,0x0c,0x91,0x08,0x10,0x04,0x06,0x00,0x01,0x00,0x01,0x00,0x01,0x00,
-       0x01,0x00,0x01,0x00,0xd0,0x2f,0xcf,0x86,0x55,0x04,0x01,0x00,0xd4,0x15,0x93,0x11,
-       0x92,0x0d,0x91,0x09,0x10,0x05,0x01,0xff,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,
-       0x00,0x53,0x04,0x01,0x00,0x52,0x04,0x01,0x00,0x51,0x04,0x01,0x00,0x10,0x04,0x01,
-       0x00,0x00,0x00,0xcf,0x86,0xd5,0x38,0xd4,0x18,0xd3,0x0c,0x92,0x08,0x11,0x04,0x00,
-       0x00,0x01,0x00,0x01,0x00,0x92,0x08,0x11,0x04,0x00,0x00,0x01,0x00,0x01,0x00,0xd3,
-       0x0c,0x92,0x08,0x11,0x04,0x00,0x00,0x01,0x00,0x01,0x00,0xd2,0x08,0x11,0x04,0x00,
-       0x00,0x01,0x00,0x91,0x08,0x10,0x04,0x01,0x00,0x00,0x00,0x00,0x00,0xd4,0x20,0xd3,
-       0x10,0x52,0x04,0x01,0x00,0x51,0x04,0x01,0x00,0x10,0x04,0x01,0x00,0x00,0x00,0x52,
-       0x04,0x01,0x00,0x51,0x04,0x01,0x00,0x10,0x04,0x01,0x00,0x00,0x00,0x53,0x05,0x00,
-       0xff,0x00,0xd2,0x0d,0x91,0x09,0x10,0x05,0x00,0xff,0x00,0x04,0x00,0x04,0x00,0x91,
-       0x08,0x10,0x04,0x03,0x00,0x01,0x00,0x01,0x00,0x83,0xe2,0x46,0x3e,0xe1,0x1f,0x3b,
-       0xe0,0x9c,0x39,0xcf,0x86,0xe5,0x40,0x26,0xc4,0xe3,0x16,0x14,0xe2,0xef,0x11,0xe1,
-       0xd0,0x10,0xe0,0x60,0x07,0xcf,0x86,0xe5,0x53,0x03,0xe4,0x4c,0x02,0xe3,0x3d,0x01,
-       0xd2,0x94,0xd1,0x70,0xd0,0x4a,0xcf,0x86,0xd5,0x18,0x94,0x14,0x53,0x04,0x07,0x00,
-       0x52,0x04,0x07,0x00,0x91,0x08,0x10,0x04,0x00,0x00,0x07,0x00,0x07,0x00,0x07,0x00,
-       0xd4,0x14,0x93,0x10,0x52,0x04,0x07,0x00,0x51,0x04,0x07,0x00,0x10,0x04,0x07,0x00,
-       0x00,0x00,0x07,0x00,0x53,0x04,0x07,0x00,0xd2,0x0c,0x51,0x04,0x07,0x00,0x10,0x04,
-       0x07,0x00,0x00,0x00,0x51,0x04,0x07,0x00,0x10,0x04,0x00,0x00,0x07,0x00,0xcf,0x86,
-       0x95,0x20,0xd4,0x10,0x53,0x04,0x07,0x00,0x52,0x04,0x07,0x00,0x11,0x04,0x07,0x00,
-       0x00,0x00,0x53,0x04,0x07,0x00,0x52,0x04,0x07,0x00,0x11,0x04,0x07,0x00,0x00,0x00,
-       0x00,0x00,0xd0,0x06,0xcf,0x06,0x07,0x00,0xcf,0x86,0x55,0x04,0x07,0x00,0x54,0x04,
-       0x07,0x00,0x53,0x04,0x07,0x00,0x92,0x0c,0x51,0x04,0x07,0x00,0x10,0x04,0x07,0x00,
-       0x00,0x00,0x00,0x00,0xd1,0x40,0xd0,0x3a,0xcf,0x86,0xd5,0x20,0x94,0x1c,0x93,0x18,
-       0xd2,0x0c,0x51,0x04,0x07,0x00,0x10,0x04,0x07,0x00,0x00,0x00,0x51,0x04,0x00,0x00,
-       0x10,0x04,0x00,0x00,0x07,0x00,0x07,0x00,0x07,0x00,0x54,0x04,0x07,0x00,0x93,0x10,
-       0x52,0x04,0x07,0x00,0x51,0x04,0x00,0x00,0x10,0x04,0x00,0x00,0x07,0x00,0x07,0x00,
-       0xcf,0x06,0x08,0x00,0xd0,0x46,0xcf,0x86,0xd5,0x2c,0xd4,0x20,0x53,0x04,0x08,0x00,
-       0xd2,0x0c,0x51,0x04,0x08,0x00,0x10,0x04,0x08,0x00,0x10,0x00,0xd1,0x08,0x10,0x04,
-       0x10,0x00,0x12,0x00,0x10,0x04,0x12,0x00,0x00,0x00,0x53,0x04,0x0a,0x00,0x12,0x04,
-       0x0a,0x00,0x00,0x00,0x94,0x14,0x93,0x10,0x92,0x0c,0x91,0x08,0x10,0x04,0x10,0x00,
-       0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xcf,0x86,0xd5,0x08,0x14,0x04,
-       0x00,0x00,0x0a,0x00,0x54,0x04,0x0a,0x00,0x53,0x04,0x0a,0x00,0x52,0x04,0x0a,0x00,
-       0x91,0x08,0x10,0x04,0x0a,0x00,0x0a,0xdc,0x00,0x00,0xd2,0x5e,0xd1,0x06,0xcf,0x06,
-       0x00,0x00,0xd0,0x1e,0xcf,0x86,0x95,0x18,0x54,0x04,0x0a,0x00,0x53,0x04,0x0a,0x00,
-       0x52,0x04,0x0a,0x00,0x91,0x08,0x10,0x04,0x0a,0x00,0x00,0x00,0x00,0x00,0x0a,0x00,
-       0xcf,0x86,0xd5,0x18,0x54,0x04,0x0a,0x00,0x93,0x10,0x92,0x0c,0x91,0x08,0x10,0x04,
-       0x0a,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xd4,0x14,0x93,0x10,0x92,0x0c,
-       0x91,0x08,0x10,0x04,0x10,0xdc,0x10,0x00,0x10,0x00,0x10,0x00,0x10,0x00,0x53,0x04,
-       0x10,0x00,0x12,0x04,0x10,0x00,0x00,0x00,0xd1,0x70,0xd0,0x36,0xcf,0x86,0xd5,0x18,
-       0x54,0x04,0x05,0x00,0x53,0x04,0x05,0x00,0x52,0x04,0x05,0x00,0x51,0x04,0x05,0x00,
-       0x10,0x04,0x05,0x00,0x10,0x00,0x94,0x18,0xd3,0x08,0x12,0x04,0x05,0x00,0x00,0x00,
-       0x52,0x04,0x00,0x00,0x91,0x08,0x10,0x04,0x00,0x00,0x13,0x00,0x13,0x00,0x05,0x00,
-       0xcf,0x86,0xd5,0x18,0x94,0x14,0x53,0x04,0x05,0x00,0x92,0x0c,0x51,0x04,0x05,0x00,
-       0x10,0x04,0x05,0x00,0x00,0x00,0x00,0x00,0x10,0x00,0x54,0x04,0x10,0x00,0xd3,0x0c,
-       0x52,0x04,0x10,0x00,0x11,0x04,0x10,0x00,0x10,0xe6,0x92,0x0c,0x51,0x04,0x10,0xe6,
-       0x10,0x04,0x10,0xe6,0x00,0x00,0x00,0x00,0xd0,0x1e,0xcf,0x86,0x95,0x18,0x54,0x04,
-       0x07,0x00,0x53,0x04,0x07,0x00,0x52,0x04,0x07,0x00,0x51,0x04,0x07,0x00,0x10,0x04,
-       0x00,0x00,0x07,0x00,0x08,0x00,0xcf,0x86,0x95,0x1c,0xd4,0x0c,0x93,0x08,0x12,0x04,
-       0x08,0x00,0x00,0x00,0x08,0x00,0x93,0x0c,0x52,0x04,0x08,0x00,0x11,0x04,0x08,0x00,
-       0x00,0x00,0x00,0x00,0x00,0x00,0xd3,0xba,0xd2,0x80,0xd1,0x34,0xd0,0x1a,0xcf,0x86,
-       0x55,0x04,0x05,0x00,0x94,0x10,0x93,0x0c,0x52,0x04,0x05,0x00,0x11,0x04,0x05,0x00,
-       0x07,0x00,0x05,0x00,0x05,0x00,0xcf,0x86,0x95,0x14,0x94,0x10,0x53,0x04,0x05,0x00,
-       0x52,0x04,0x05,0x00,0x11,0x04,0x05,0x00,0x07,0x00,0x07,0x00,0x07,0x00,0xd0,0x2a,
-       0xcf,0x86,0xd5,0x14,0x54,0x04,0x07,0x00,0x53,0x04,0x07,0x00,0x52,0x04,0x07,0x00,
-       0x11,0x04,0x07,0x00,0x00,0x00,0x94,0x10,0x53,0x04,0x07,0x00,0x92,0x08,0x11,0x04,
-       0x07,0x00,0x00,0x00,0x00,0x00,0x12,0x00,0xcf,0x86,0xd5,0x10,0x54,0x04,0x12,0x00,
-       0x93,0x08,0x12,0x04,0x12,0x00,0x00,0x00,0x12,0x00,0x54,0x04,0x12,0x00,0x53,0x04,
-       0x12,0x00,0x12,0x04,0x12,0x00,0x00,0x00,0xd1,0x34,0xd0,0x12,0xcf,0x86,0x55,0x04,
-       0x10,0x00,0x94,0x08,0x13,0x04,0x10,0x00,0x00,0x00,0x10,0x00,0xcf,0x86,0x55,0x04,
-       0x10,0x00,0x94,0x18,0xd3,0x08,0x12,0x04,0x10,0x00,0x00,0x00,0x52,0x04,0x00,0x00,
-       0x51,0x04,0x00,0x00,0x10,0x04,0x00,0x00,0x10,0x00,0x00,0x00,0xcf,0x06,0x00,0x00,
-       0xd2,0x06,0xcf,0x06,0x10,0x00,0xd1,0x40,0xd0,0x1e,0xcf,0x86,0x55,0x04,0x10,0x00,
-       0x54,0x04,0x10,0x00,0x93,0x10,0x52,0x04,0x10,0x00,0x51,0x04,0x10,0x00,0x10,0x04,
-       0x10,0x00,0x00,0x00,0x00,0x00,0xcf,0x86,0xd5,0x14,0x54,0x04,0x10,0x00,0x93,0x0c,
-       0x52,0x04,0x10,0x00,0x11,0x04,0x10,0x00,0x00,0x00,0x00,0x00,0x94,0x08,0x13,0x04,
-       0x10,0x00,0x00,0x00,0x00,0x00,0xcf,0x06,0x00,0x00,0xe4,0xce,0x02,0xe3,0x45,0x01,
-       0xd2,0xd0,0xd1,0x70,0xd0,0x52,0xcf,0x86,0xd5,0x20,0x94,0x1c,0xd3,0x0c,0x52,0x04,
-       0x07,0x00,0x11,0x04,0x07,0x00,0x00,0x00,0x92,0x0c,0x91,0x08,0x10,0x04,0x07,0x00,
-       0x00,0x00,0x07,0x00,0x07,0x00,0x07,0x00,0x54,0x04,0x07,0x00,0xd3,0x10,0x52,0x04,
-       0x07,0x00,0x51,0x04,0x07,0x00,0x10,0x04,0x00,0x00,0x07,0x00,0xd2,0x0c,0x91,0x08,
-       0x10,0x04,0x07,0x00,0x00,0x00,0x00,0x00,0xd1,0x08,0x10,0x04,0x07,0x00,0x00,0x00,
-       0x10,0x04,0x00,0x00,0x07,0x00,0xcf,0x86,0x95,0x18,0x54,0x04,0x0b,0x00,0x93,0x10,
-       0x52,0x04,0x0b,0x00,0x51,0x04,0x0b,0x00,0x10,0x04,0x00,0x00,0x0b,0x00,0x0b,0x00,
-       0x10,0x00,0xd0,0x32,0xcf,0x86,0xd5,0x18,0x54,0x04,0x10,0x00,0x53,0x04,0x10,0x00,
-       0x52,0x04,0x10,0x00,0x51,0x04,0x10,0x00,0x10,0x04,0x10,0x00,0x00,0x00,0x94,0x14,
-       0x93,0x10,0x52,0x04,0x00,0x00,0x51,0x04,0x00,0x00,0x10,0x04,0x00,0x00,0x10,0x00,
-       0x10,0x00,0x00,0x00,0xcf,0x86,0x55,0x04,0x00,0x00,0x54,0x04,0x11,0x00,0xd3,0x14,
-       0xd2,0x0c,0x51,0x04,0x11,0x00,0x10,0x04,0x11,0x00,0x00,0x00,0x11,0x04,0x11,0x00,
-       0x00,0x00,0x92,0x0c,0x51,0x04,0x00,0x00,0x10,0x04,0x00,0x00,0x11,0x00,0x11,0x00,
-       0xd1,0x40,0xd0,0x3a,0xcf,0x86,0xd5,0x1c,0x54,0x04,0x09,0x00,0x53,0x04,0x09,0x00,
-       0xd2,0x08,0x11,0x04,0x09,0x00,0x0b,0x00,0x51,0x04,0x00,0x00,0x10,0x04,0x00,0x00,
-       0x09,0x00,0x54,0x04,0x0a,0x00,0x53,0x04,0x0a,0x00,0xd2,0x08,0x11,0x04,0x0a,0x00,
-       0x00,0x00,0x51,0x04,0x00,0x00,0x10,0x04,0x00,0x00,0x0a,0x00,0xcf,0x06,0x00,0x00,
-       0xd0,0x1a,0xcf,0x86,0x55,0x04,0x0d,0x00,0x54,0x04,0x0d,0x00,0x53,0x04,0x0d,0x00,
-       0x52,0x04,0x00,0x00,0x11,0x04,0x11,0x00,0x0d,0x00,0xcf,0x86,0x95,0x14,0x54,0x04,
-       0x11,0x00,0x93,0x0c,0x92,0x08,0x11,0x04,0x00,0x00,0x11,0x00,0x11,0x00,0x11,0x00,
-       0x11,0x00,0xd2,0xec,0xd1,0xa4,0xd0,0x76,0xcf,0x86,0xd5,0x48,0xd4,0x28,0xd3,0x14,
-       0x52,0x04,0x08,0x00,0xd1,0x08,0x10,0x04,0x00,0x00,0x08,0x00,0x10,0x04,0x08,0x00,
-       0x00,0x00,0x52,0x04,0x00,0x00,0xd1,0x08,0x10,0x04,0x08,0x00,0x08,0xdc,0x10,0x04,
-       0x08,0x00,0x08,0xe6,0xd3,0x10,0x52,0x04,0x08,0x00,0x91,0x08,0x10,0x04,0x00,0x00,
-       0x08,0x00,0x08,0x00,0x92,0x0c,0x91,0x08,0x10,0x04,0x00,0x00,0x08,0x00,0x08,0x00,
-       0x08,0x00,0x54,0x04,0x08,0x00,0xd3,0x0c,0x52,0x04,0x08,0x00,0x11,0x04,0x14,0x00,
-       0x00,0x00,0xd2,0x10,0xd1,0x08,0x10,0x04,0x08,0xe6,0x08,0x01,0x10,0x04,0x08,0xdc,
-       0x00,0x00,0x51,0x04,0x00,0x00,0x10,0x04,0x00,0x00,0x08,0x09,0xcf,0x86,0x95,0x28,
-       0xd4,0x14,0x53,0x04,0x08,0x00,0x92,0x0c,0x91,0x08,0x10,0x04,0x14,0x00,0x00,0x00,
-       0x00,0x00,0x00,0x00,0x53,0x04,0x08,0x00,0x92,0x0c,0x91,0x08,0x10,0x04,0x08,0x00,
-       0x00,0x00,0x00,0x00,0x00,0x00,0x0b,0x00,0xd0,0x0a,0xcf,0x86,0x15,0x04,0x10,0x00,
-       0x00,0x00,0xcf,0x86,0x55,0x04,0x10,0x00,0xd4,0x24,0xd3,0x14,0x52,0x04,0x10,0x00,
-       0xd1,0x08,0x10,0x04,0x10,0x00,0x10,0xe6,0x10,0x04,0x10,0xdc,0x00,0x00,0x92,0x0c,
-       0x51,0x04,0x00,0x00,0x10,0x04,0x00,0x00,0x10,0x00,0x10,0x00,0x93,0x10,0x52,0x04,
-       0x10,0x00,0x51,0x04,0x10,0x00,0x10,0x04,0x10,0x00,0x00,0x00,0x00,0x00,0xd1,0x54,
-       0xd0,0x26,0xcf,0x86,0x55,0x04,0x0b,0x00,0x54,0x04,0x0b,0x00,0xd3,0x0c,0x52,0x04,
-       0x0b,0x00,0x11,0x04,0x0b,0x00,0x00,0x00,0x92,0x0c,0x91,0x08,0x10,0x04,0x00,0x00,
-       0x0b,0x00,0x0b,0x00,0x0b,0x00,0xcf,0x86,0xd5,0x14,0x54,0x04,0x0b,0x00,0x93,0x0c,
-       0x52,0x04,0x0b,0x00,0x11,0x04,0x0b,0x00,0x00,0x00,0x0b,0x00,0x54,0x04,0x0b,0x00,
-       0x93,0x10,0x92,0x0c,0x51,0x04,0x0b,0x00,0x10,0x04,0x0b,0x00,0x00,0x00,0x00,0x00,
-       0x0b,0x00,0xd0,0x42,0xcf,0x86,0xd5,0x28,0x54,0x04,0x10,0x00,0xd3,0x0c,0x92,0x08,
-       0x11,0x04,0x10,0x00,0x00,0x00,0x00,0x00,0xd2,0x0c,0x91,0x08,0x10,0x04,0x00,0x00,
-       0x10,0x00,0x10,0x00,0x91,0x08,0x10,0x04,0x10,0x00,0x00,0x00,0x00,0x00,0x94,0x14,
-       0x53,0x04,0x00,0x00,0x92,0x0c,0x91,0x08,0x10,0x04,0x00,0x00,0x10,0x00,0x10,0x00,
-       0x10,0x00,0x00,0x00,0xcf,0x06,0x00,0x00,0xd3,0x96,0xd2,0x68,0xd1,0x24,0xd0,0x06,
-       0xcf,0x06,0x0b,0x00,0xcf,0x86,0x95,0x18,0x94,0x14,0x53,0x04,0x0b,0x00,0x92,0x0c,
-       0x91,0x08,0x10,0x04,0x0b,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-       0xd0,0x1e,0xcf,0x86,0x55,0x04,0x11,0x00,0x54,0x04,0x11,0x00,0x93,0x10,0x92,0x0c,
-       0x51,0x04,0x11,0x00,0x10,0x04,0x11,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xcf,0x86,
-       0x55,0x04,0x11,0x00,0x54,0x04,0x11,0x00,0xd3,0x10,0x92,0x0c,0x51,0x04,0x11,0x00,
-       0x10,0x04,0x11,0x00,0x00,0x00,0x00,0x00,0x92,0x08,0x11,0x04,0x00,0x00,0x11,0x00,
-       0x11,0x00,0xd1,0x28,0xd0,0x22,0xcf,0x86,0x55,0x04,0x14,0x00,0xd4,0x0c,0x93,0x08,
-       0x12,0x04,0x14,0x00,0x14,0xe6,0x00,0x00,0x53,0x04,0x14,0x00,0x92,0x08,0x11,0x04,
-       0x14,0x00,0x00,0x00,0x00,0x00,0xcf,0x06,0x00,0x00,0xcf,0x06,0x00,0x00,0xd2,0x2a,
-       0xd1,0x24,0xd0,0x06,0xcf,0x06,0x00,0x00,0xcf,0x86,0x55,0x04,0x00,0x00,0x54,0x04,
-       0x0b,0x00,0x53,0x04,0x0b,0x00,0x52,0x04,0x0b,0x00,0x51,0x04,0x0b,0x00,0x10,0x04,
-       0x0b,0x00,0x00,0x00,0xcf,0x06,0x00,0x00,0xd1,0x58,0xd0,0x12,0xcf,0x86,0x55,0x04,
-       0x14,0x00,0x94,0x08,0x13,0x04,0x14,0x00,0x00,0x00,0x14,0x00,0xcf,0x86,0x95,0x40,
-       0xd4,0x24,0xd3,0x0c,0x52,0x04,0x14,0x00,0x11,0x04,0x14,0x00,0x14,0xdc,0xd2,0x0c,
-       0x51,0x04,0x14,0xe6,0x10,0x04,0x14,0xe6,0x14,0xdc,0x91,0x08,0x10,0x04,0x14,0xe6,
-       0x14,0xdc,0x14,0xdc,0xd3,0x10,0x92,0x0c,0x91,0x08,0x10,0x04,0x14,0xdc,0x14,0x00,
-       0x14,0x00,0x14,0x00,0x92,0x08,0x11,0x04,0x14,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-       0xd0,0x06,0xcf,0x06,0x00,0x00,0xcf,0x86,0x55,0x04,0x00,0x00,0x54,0x04,0x15,0x00,
-       0x93,0x10,0x52,0x04,0x15,0x00,0x51,0x04,0x15,0x00,0x10,0x04,0x15,0x00,0x00,0x00,
-       0x00,0x00,0xcf,0x86,0xe5,0x0f,0x06,0xe4,0xf8,0x03,0xe3,0x02,0x02,0xd2,0xfb,0xd1,
-       0x4c,0xd0,0x06,0xcf,0x06,0x0c,0x00,0xcf,0x86,0xd5,0x2c,0xd4,0x1c,0xd3,0x10,0x52,
-       0x04,0x0c,0x00,0x51,0x04,0x0c,0x00,0x10,0x04,0x0c,0x09,0x0c,0x00,0x52,0x04,0x0c,
-       0x00,0x11,0x04,0x0c,0x00,0x00,0x00,0x93,0x0c,0x92,0x08,0x11,0x04,0x00,0x00,0x0c,
-       0x00,0x0c,0x00,0x0c,0x00,0x54,0x04,0x0c,0x00,0x53,0x04,0x00,0x00,0x52,0x04,0x00,
-       0x00,0x51,0x04,0x00,0x00,0x10,0x04,0x00,0x00,0x10,0x09,0xd0,0x69,0xcf,0x86,0xd5,
-       0x32,0x54,0x04,0x0b,0x00,0x53,0x04,0x0b,0x00,0xd2,0x15,0x51,0x04,0x0b,0x00,0x10,
-       0x0d,0x0b,0xff,0xf0,0x91,0x82,0x99,0xf0,0x91,0x82,0xba,0x00,0x0b,0x00,0x91,0x11,
-       0x10,0x0d,0x0b,0xff,0xf0,0x91,0x82,0x9b,0xf0,0x91,0x82,0xba,0x00,0x0b,0x00,0x0b,
-       0x00,0xd4,0x1d,0x53,0x04,0x0b,0x00,0x92,0x15,0x51,0x04,0x0b,0x00,0x10,0x04,0x0b,
-       0x00,0x0b,0xff,0xf0,0x91,0x82,0xa5,0xf0,0x91,0x82,0xba,0x00,0x0b,0x00,0x53,0x04,
-       0x0b,0x00,0x92,0x10,0xd1,0x08,0x10,0x04,0x0b,0x00,0x0b,0x09,0x10,0x04,0x0b,0x07,
-       0x0b,0x00,0x0b,0x00,0xcf,0x86,0xd5,0x20,0x94,0x1c,0xd3,0x0c,0x92,0x08,0x11,0x04,
-       0x0b,0x00,0x00,0x00,0x00,0x00,0x52,0x04,0x00,0x00,0x91,0x08,0x10,0x04,0x00,0x00,
-       0x14,0x00,0x00,0x00,0x0d,0x00,0xd4,0x14,0x53,0x04,0x0d,0x00,0x92,0x0c,0x91,0x08,
-       0x10,0x04,0x0d,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x53,0x04,0x0d,0x00,0x92,0x08,
-       0x11,0x04,0x0d,0x00,0x00,0x00,0x00,0x00,0xd1,0x96,0xd0,0x5c,0xcf,0x86,0xd5,0x18,
-       0x94,0x14,0x93,0x10,0x92,0x0c,0x51,0x04,0x0d,0xe6,0x10,0x04,0x0d,0xe6,0x0d,0x00,
-       0x0d,0x00,0x0d,0x00,0x0d,0x00,0xd4,0x26,0x53,0x04,0x0d,0x00,0x52,0x04,0x0d,0x00,
-       0x51,0x04,0x0d,0x00,0x10,0x0d,0x0d,0xff,0xf0,0x91,0x84,0xb1,0xf0,0x91,0x84,0xa7,
-       0x00,0x0d,0xff,0xf0,0x91,0x84,0xb2,0xf0,0x91,0x84,0xa7,0x00,0x93,0x18,0xd2,0x0c,
-       0x51,0x04,0x0d,0x00,0x10,0x04,0x0d,0x00,0x0d,0x09,0x91,0x08,0x10,0x04,0x0d,0x09,
-       0x00,0x00,0x0d,0x00,0x0d,0x00,0xcf,0x86,0xd5,0x18,0x94,0x14,0x93,0x10,0x52,0x04,
-       0x0d,0x00,0x51,0x04,0x14,0x00,0x10,0x04,0x14,0x00,0x00,0x00,0x00,0x00,0x10,0x00,
-       0x54,0x04,0x10,0x00,0x93,0x18,0xd2,0x0c,0x51,0x04,0x10,0x00,0x10,0x04,0x10,0x00,
-       0x10,0x07,0x51,0x04,0x10,0x00,0x10,0x04,0x10,0x00,0x00,0x00,0x00,0x00,0xd0,0x06,
-       0xcf,0x06,0x0d,0x00,0xcf,0x86,0xd5,0x40,0xd4,0x2c,0xd3,0x10,0x92,0x0c,0x91,0x08,
-       0x10,0x04,0x0d,0x09,0x0d,0x00,0x0d,0x00,0x0d,0x00,0xd2,0x10,0xd1,0x08,0x10,0x04,
-       0x0d,0x00,0x11,0x00,0x10,0x04,0x11,0x07,0x11,0x00,0x91,0x08,0x10,0x04,0x11,0x00,
-       0x10,0x00,0x00,0x00,0x53,0x04,0x0d,0x00,0x92,0x0c,0x51,0x04,0x0d,0x00,0x10,0x04,
-       0x10,0x00,0x11,0x00,0x11,0x00,0xd4,0x14,0x93,0x10,0x92,0x0c,0x91,0x08,0x10,0x04,
-       0x00,0x00,0x10,0x00,0x10,0x00,0x10,0x00,0x10,0x00,0x93,0x10,0x52,0x04,0x10,0x00,
-       0x91,0x08,0x10,0x04,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xd2,0xc8,0xd1,0x48,
-       0xd0,0x42,0xcf,0x86,0xd5,0x18,0x54,0x04,0x10,0x00,0x93,0x10,0x92,0x0c,0x51,0x04,
-       0x10,0x00,0x10,0x04,0x00,0x00,0x10,0x00,0x10,0x00,0x10,0x00,0x54,0x04,0x10,0x00,
-       0xd3,0x14,0x52,0x04,0x10,0x00,0xd1,0x08,0x10,0x04,0x10,0x00,0x10,0x09,0x10,0x04,
-       0x10,0x07,0x10,0x00,0x52,0x04,0x10,0x00,0x51,0x04,0x10,0x00,0x10,0x04,0x12,0x00,
-       0x00,0x00,0xcf,0x06,0x00,0x00,0xd0,0x52,0xcf,0x86,0xd5,0x3c,0xd4,0x28,0xd3,0x10,
-       0x52,0x04,0x11,0x00,0x51,0x04,0x11,0x00,0x10,0x04,0x11,0x00,0x00,0x00,0xd2,0x0c,
-       0x91,0x08,0x10,0x04,0x11,0x00,0x00,0x00,0x11,0x00,0x51,0x04,0x11,0x00,0x10,0x04,
-       0x00,0x00,0x11,0x00,0x53,0x04,0x11,0x00,0x52,0x04,0x11,0x00,0x51,0x04,0x11,0x00,
-       0x10,0x04,0x00,0x00,0x11,0x00,0x94,0x10,0x53,0x04,0x11,0x00,0x92,0x08,0x11,0x04,
-       0x11,0x00,0x00,0x00,0x00,0x00,0x10,0x00,0xcf,0x86,0x55,0x04,0x10,0x00,0xd4,0x18,
-       0x53,0x04,0x10,0x00,0x92,0x10,0xd1,0x08,0x10,0x04,0x10,0x00,0x10,0x07,0x10,0x04,
-       0x10,0x09,0x00,0x00,0x00,0x00,0x53,0x04,0x10,0x00,0x92,0x08,0x11,0x04,0x10,0x00,
-       0x00,0x00,0x00,0x00,0xe1,0x27,0x01,0xd0,0x8a,0xcf,0x86,0xd5,0x44,0xd4,0x2c,0xd3,
-       0x18,0xd2,0x0c,0x91,0x08,0x10,0x04,0x11,0x00,0x10,0x00,0x10,0x00,0x91,0x08,0x10,
-       0x04,0x00,0x00,0x10,0x00,0x10,0x00,0x52,0x04,0x10,0x00,0xd1,0x08,0x10,0x04,0x10,
-       0x00,0x00,0x00,0x10,0x04,0x00,0x00,0x10,0x00,0x93,0x14,0x92,0x10,0xd1,0x08,0x10,
-       0x04,0x10,0x00,0x00,0x00,0x10,0x04,0x00,0x00,0x10,0x00,0x10,0x00,0x10,0x00,0xd4,
-       0x14,0x53,0x04,0x10,0x00,0x92,0x0c,0x91,0x08,0x10,0x04,0x10,0x00,0x00,0x00,0x10,
-       0x00,0x10,0x00,0xd3,0x18,0xd2,0x0c,0x91,0x08,0x10,0x04,0x10,0x00,0x00,0x00,0x10,
-       0x00,0x91,0x08,0x10,0x04,0x00,0x00,0x10,0x00,0x10,0x00,0xd2,0x0c,0x51,0x04,0x10,
-       0x00,0x10,0x04,0x00,0x00,0x14,0x07,0x91,0x08,0x10,0x04,0x10,0x07,0x10,0x00,0x10,
-       0x00,0xcf,0x86,0xd5,0x6a,0xd4,0x42,0xd3,0x14,0x52,0x04,0x10,0x00,0xd1,0x08,0x10,
-       0x04,0x10,0x00,0x00,0x00,0x10,0x04,0x00,0x00,0x10,0x00,0xd2,0x19,0xd1,0x08,0x10,
-       0x04,0x10,0x00,0x00,0x00,0x10,0x04,0x00,0x00,0x10,0xff,0xf0,0x91,0x8d,0x87,0xf0,
-       0x91,0x8c,0xbe,0x00,0x91,0x11,0x10,0x0d,0x10,0xff,0xf0,0x91,0x8d,0x87,0xf0,0x91,
-       0x8d,0x97,0x00,0x10,0x09,0x00,0x00,0xd3,0x18,0xd2,0x0c,0x91,0x08,0x10,0x04,0x11,
-       0x00,0x00,0x00,0x00,0x00,0x51,0x04,0x00,0x00,0x10,0x04,0x00,0x00,0x10,0x00,0x52,
-       0x04,0x00,0x00,0x91,0x08,0x10,0x04,0x00,0x00,0x10,0x00,0x10,0x00,0xd4,0x1c,0xd3,
-       0x0c,0x52,0x04,0x10,0x00,0x11,0x04,0x00,0x00,0x10,0xe6,0x52,0x04,0x10,0xe6,0x91,
-       0x08,0x10,0x04,0x10,0xe6,0x00,0x00,0x00,0x00,0x93,0x10,0x52,0x04,0x10,0xe6,0x91,
-       0x08,0x10,0x04,0x10,0xe6,0x00,0x00,0x00,0x00,0x00,0x00,0xcf,0x06,0x00,0x00,0xe3,
-       0x30,0x01,0xd2,0xb7,0xd1,0x48,0xd0,0x06,0xcf,0x06,0x12,0x00,0xcf,0x86,0x95,0x3c,
-       0xd4,0x1c,0x93,0x18,0xd2,0x0c,0x51,0x04,0x12,0x00,0x10,0x04,0x12,0x09,0x12,0x00,
-       0x51,0x04,0x12,0x00,0x10,0x04,0x12,0x07,0x12,0x00,0x12,0x00,0x53,0x04,0x12,0x00,
-       0xd2,0x0c,0x51,0x04,0x12,0x00,0x10,0x04,0x00,0x00,0x12,0x00,0xd1,0x08,0x10,0x04,
-       0x00,0x00,0x12,0x00,0x10,0x04,0x14,0xe6,0x15,0x00,0x00,0x00,0xd0,0x45,0xcf,0x86,
-       0x55,0x04,0x10,0x00,0x54,0x04,0x10,0x00,0x53,0x04,0x10,0x00,0xd2,0x15,0x51,0x04,
-       0x10,0x00,0x10,0x04,0x10,0x00,0x10,0xff,0xf0,0x91,0x92,0xb9,0xf0,0x91,0x92,0xba,
-       0x00,0xd1,0x11,0x10,0x0d,0x10,0xff,0xf0,0x91,0x92,0xb9,0xf0,0x91,0x92,0xb0,0x00,
-       0x10,0x00,0x10,0x0d,0x10,0xff,0xf0,0x91,0x92,0xb9,0xf0,0x91,0x92,0xbd,0x00,0x10,
-       0x00,0xcf,0x86,0x95,0x24,0xd4,0x14,0x93,0x10,0x92,0x0c,0x51,0x04,0x10,0x00,0x10,
-       0x04,0x10,0x09,0x10,0x07,0x10,0x00,0x00,0x00,0x53,0x04,0x10,0x00,0x92,0x08,0x11,
-       0x04,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xd1,0x06,0xcf,0x06,0x00,0x00,0xd0,
-       0x40,0xcf,0x86,0x55,0x04,0x10,0x00,0x54,0x04,0x10,0x00,0xd3,0x0c,0x52,0x04,0x10,
-       0x00,0x11,0x04,0x10,0x00,0x00,0x00,0xd2,0x1e,0x51,0x04,0x10,0x00,0x10,0x0d,0x10,
-       0xff,0xf0,0x91,0x96,0xb8,0xf0,0x91,0x96,0xaf,0x00,0x10,0xff,0xf0,0x91,0x96,0xb9,
-       0xf0,0x91,0x96,0xaf,0x00,0x51,0x04,0x10,0x00,0x10,0x04,0x10,0x00,0x10,0x09,0xcf,
-       0x86,0x95,0x2c,0xd4,0x1c,0xd3,0x10,0x92,0x0c,0x91,0x08,0x10,0x04,0x10,0x07,0x10,
-       0x00,0x10,0x00,0x10,0x00,0x92,0x08,0x11,0x04,0x10,0x00,0x11,0x00,0x11,0x00,0x53,
-       0x04,0x11,0x00,0x52,0x04,0x11,0x00,0x11,0x04,0x11,0x00,0x00,0x00,0x00,0x00,0xd2,
-       0xa0,0xd1,0x5c,0xd0,0x1e,0xcf,0x86,0x55,0x04,0x10,0x00,0x54,0x04,0x10,0x00,0x53,
-       0x04,0x10,0x00,0x52,0x04,0x10,0x00,0x51,0x04,0x10,0x00,0x10,0x04,0x10,0x00,0x10,
-       0x09,0xcf,0x86,0xd5,0x24,0xd4,0x14,0x93,0x10,0x52,0x04,0x10,0x00,0x91,0x08,0x10,
-       0x04,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x53,0x04,0x10,0x00,0x92,0x08,0x11,
-       0x04,0x10,0x00,0x00,0x00,0x00,0x00,0x94,0x14,0x53,0x04,0x12,0x00,0x52,0x04,0x12,
-       0x00,0x91,0x08,0x10,0x04,0x12,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xd0,0x2a,0xcf,
-       0x86,0x55,0x04,0x0d,0x00,0x54,0x04,0x0d,0x00,0xd3,0x10,0x52,0x04,0x0d,0x00,0x51,
-       0x04,0x0d,0x00,0x10,0x04,0x0d,0x09,0x0d,0x07,0x92,0x0c,0x91,0x08,0x10,0x04,0x15,
-       0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xcf,0x86,0x95,0x14,0x94,0x10,0x53,0x04,0x0d,
-       0x00,0x92,0x08,0x11,0x04,0x0d,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xd1,
-       0x40,0xd0,0x3a,0xcf,0x86,0xd5,0x20,0x54,0x04,0x11,0x00,0x53,0x04,0x11,0x00,0xd2,
-       0x0c,0x51,0x04,0x11,0x00,0x10,0x04,0x14,0x00,0x00,0x00,0x91,0x08,0x10,0x04,0x00,
-       0x00,0x11,0x00,0x11,0x00,0x94,0x14,0x53,0x04,0x11,0x00,0x92,0x0c,0x51,0x04,0x11,
-       0x00,0x10,0x04,0x11,0x00,0x11,0x09,0x00,0x00,0x11,0x00,0xcf,0x06,0x00,0x00,0xcf,
-       0x06,0x00,0x00,0xe4,0x59,0x01,0xd3,0xb2,0xd2,0x5c,0xd1,0x28,0xd0,0x22,0xcf,0x86,
-       0x55,0x04,0x14,0x00,0x54,0x04,0x14,0x00,0x53,0x04,0x14,0x00,0x92,0x10,0xd1,0x08,
-       0x10,0x04,0x14,0x00,0x14,0x09,0x10,0x04,0x14,0x07,0x14,0x00,0x00,0x00,0xcf,0x06,
-       0x00,0x00,0xd0,0x0a,0xcf,0x86,0x15,0x04,0x00,0x00,0x10,0x00,0xcf,0x86,0x55,0x04,
-       0x10,0x00,0x54,0x04,0x10,0x00,0xd3,0x10,0x92,0x0c,0x51,0x04,0x10,0x00,0x10,0x04,
-       0x10,0x00,0x00,0x00,0x00,0x00,0x52,0x04,0x00,0x00,0x51,0x04,0x00,0x00,0x10,0x04,
-       0x00,0x00,0x10,0x00,0xd1,0x06,0xcf,0x06,0x00,0x00,0xd0,0x1a,0xcf,0x86,0x55,0x04,
-       0x00,0x00,0x94,0x10,0x53,0x04,0x15,0x00,0x92,0x08,0x11,0x04,0x00,0x00,0x15,0x00,
-       0x15,0x00,0x15,0x00,0xcf,0x86,0xd5,0x14,0x54,0x04,0x15,0x00,0x53,0x04,0x15,0x00,
-       0x92,0x08,0x11,0x04,0x00,0x00,0x15,0x00,0x15,0x00,0x94,0x1c,0x93,0x18,0xd2,0x0c,
-       0x91,0x08,0x10,0x04,0x15,0x09,0x15,0x00,0x15,0x00,0x91,0x08,0x10,0x04,0x15,0x00,
-       0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xd2,0xa0,0xd1,0x3c,0xd0,0x1e,0xcf,0x86,
-       0x55,0x04,0x13,0x00,0x54,0x04,0x13,0x00,0x93,0x10,0x52,0x04,0x13,0x00,0x91,0x08,
-       0x10,0x04,0x13,0x09,0x13,0x00,0x13,0x00,0x13,0x00,0xcf,0x86,0x95,0x18,0x94,0x14,
-       0x93,0x10,0x52,0x04,0x13,0x00,0x51,0x04,0x13,0x00,0x10,0x04,0x13,0x00,0x13,0x09,
-       0x00,0x00,0x13,0x00,0x13,0x00,0xd0,0x46,0xcf,0x86,0xd5,0x2c,0xd4,0x10,0x93,0x0c,
-       0x52,0x04,0x13,0x00,0x11,0x04,0x15,0x00,0x13,0x00,0x13,0x00,0x53,0x04,0x13,0x00,
-       0xd2,0x0c,0x91,0x08,0x10,0x04,0x13,0x00,0x13,0x09,0x13,0x00,0x91,0x08,0x10,0x04,
-       0x13,0x00,0x14,0x00,0x13,0x00,0x94,0x14,0x93,0x10,0x92,0x0c,0x51,0x04,0x13,0x00,
-       0x10,0x04,0x13,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xcf,0x86,0x55,0x04,
-       0x10,0x00,0x54,0x04,0x10,0x00,0x53,0x04,0x10,0x00,0x92,0x0c,0x91,0x08,0x10,0x04,
-       0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xcf,0x06,0x00,0x00,0xe3,0xa9,0x01,0xd2,
-       0xb0,0xd1,0x6c,0xd0,0x3e,0xcf,0x86,0xd5,0x18,0x94,0x14,0x53,0x04,0x12,0x00,0x92,
-       0x0c,0x91,0x08,0x10,0x04,0x12,0x00,0x00,0x00,0x12,0x00,0x12,0x00,0x12,0x00,0x54,
-       0x04,0x12,0x00,0xd3,0x10,0x52,0x04,0x12,0x00,0x51,0x04,0x12,0x00,0x10,0x04,0x12,
-       0x00,0x00,0x00,0x52,0x04,0x12,0x00,0x51,0x04,0x12,0x00,0x10,0x04,0x12,0x00,0x12,
-       0x09,0xcf,0x86,0xd5,0x14,0x94,0x10,0x93,0x0c,0x52,0x04,0x12,0x00,0x11,0x04,0x12,
-       0x00,0x00,0x00,0x00,0x00,0x12,0x00,0x94,0x14,0x53,0x04,0x12,0x00,0x52,0x04,0x12,
-       0x00,0x91,0x08,0x10,0x04,0x12,0x00,0x00,0x00,0x00,0x00,0x12,0x00,0xd0,0x3e,0xcf,
-       0x86,0xd5,0x14,0x54,0x04,0x12,0x00,0x93,0x0c,0x92,0x08,0x11,0x04,0x00,0x00,0x12,
-       0x00,0x12,0x00,0x12,0x00,0xd4,0x14,0x53,0x04,0x12,0x00,0x92,0x0c,0x91,0x08,0x10,
-       0x04,0x00,0x00,0x12,0x00,0x12,0x00,0x12,0x00,0x93,0x10,0x52,0x04,0x12,0x00,0x51,
-       0x04,0x12,0x00,0x10,0x04,0x12,0x00,0x00,0x00,0x00,0x00,0xcf,0x06,0x00,0x00,0xd1,
-       0xa0,0xd0,0x52,0xcf,0x86,0xd5,0x24,0x94,0x20,0xd3,0x10,0x52,0x04,0x13,0x00,0x51,
-       0x04,0x13,0x00,0x10,0x04,0x13,0x00,0x00,0x00,0x92,0x0c,0x51,0x04,0x13,0x00,0x10,
-       0x04,0x00,0x00,0x13,0x00,0x13,0x00,0x13,0x00,0x54,0x04,0x13,0x00,0xd3,0x10,0x52,
-       0x04,0x13,0x00,0x51,0x04,0x13,0x00,0x10,0x04,0x13,0x00,0x00,0x00,0xd2,0x0c,0x51,
-       0x04,0x00,0x00,0x10,0x04,0x13,0x00,0x00,0x00,0x51,0x04,0x13,0x00,0x10,0x04,0x00,
-       0x00,0x13,0x00,0xcf,0x86,0xd5,0x28,0xd4,0x18,0x93,0x14,0xd2,0x0c,0x51,0x04,0x13,
-       0x00,0x10,0x04,0x13,0x07,0x13,0x00,0x11,0x04,0x13,0x09,0x13,0x00,0x00,0x00,0x53,
-       0x04,0x13,0x00,0x92,0x08,0x11,0x04,0x13,0x00,0x00,0x00,0x00,0x00,0x94,0x20,0xd3,
-       0x10,0x52,0x04,0x14,0x00,0x51,0x04,0x14,0x00,0x10,0x04,0x00,0x00,0x14,0x00,0x92,
-       0x0c,0x91,0x08,0x10,0x04,0x14,0x00,0x00,0x00,0x14,0x00,0x14,0x00,0x14,0x00,0xd0,
-       0x52,0xcf,0x86,0xd5,0x3c,0xd4,0x14,0x53,0x04,0x14,0x00,0x52,0x04,0x14,0x00,0x51,
-       0x04,0x14,0x00,0x10,0x04,0x14,0x00,0x00,0x00,0xd3,0x18,0xd2,0x0c,0x51,0x04,0x14,
-       0x00,0x10,0x04,0x00,0x00,0x14,0x00,0x51,0x04,0x14,0x00,0x10,0x04,0x14,0x00,0x14,
-       0x09,0x92,0x0c,0x91,0x08,0x10,0x04,0x14,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x94,
-       0x10,0x53,0x04,0x14,0x00,0x92,0x08,0x11,0x04,0x14,0x00,0x00,0x00,0x00,0x00,0x00,
-       0x00,0xcf,0x06,0x00,0x00,0xd2,0x2a,0xd1,0x06,0xcf,0x06,0x00,0x00,0xd0,0x06,0xcf,
-       0x06,0x00,0x00,0xcf,0x86,0x55,0x04,0x00,0x00,0x54,0x04,0x14,0x00,0x53,0x04,0x14,
-       0x00,0x92,0x0c,0x91,0x08,0x10,0x04,0x14,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xd1,
-       0x06,0xcf,0x06,0x00,0x00,0xd0,0x06,0xcf,0x06,0x00,0x00,0xcf,0x86,0x55,0x04,0x15,
-       0x00,0x54,0x04,0x15,0x00,0xd3,0x0c,0x92,0x08,0x11,0x04,0x15,0x00,0x00,0x00,0x00,
-       0x00,0x52,0x04,0x00,0x00,0x51,0x04,0x00,0x00,0x10,0x04,0x00,0x00,0x15,0x00,0xd0,
-       0xca,0xcf,0x86,0xd5,0xc2,0xd4,0x54,0xd3,0x06,0xcf,0x06,0x09,0x00,0xd2,0x06,0xcf,
-       0x06,0x09,0x00,0xd1,0x24,0xd0,0x06,0xcf,0x06,0x09,0x00,0xcf,0x86,0x55,0x04,0x09,
-       0x00,0x94,0x14,0x53,0x04,0x09,0x00,0x52,0x04,0x09,0x00,0x51,0x04,0x09,0x00,0x10,
-       0x04,0x09,0x00,0x10,0x00,0x10,0x00,0xd0,0x1e,0xcf,0x86,0x95,0x18,0x54,0x04,0x10,
-       0x00,0x53,0x04,0x10,0x00,0x92,0x0c,0x91,0x08,0x10,0x04,0x10,0x00,0x11,0x00,0x00,
-       0x00,0x00,0x00,0x00,0x00,0xcf,0x06,0x00,0x00,0xd3,0x68,0xd2,0x46,0xd1,0x40,0xd0,
-       0x06,0xcf,0x06,0x09,0x00,0xcf,0x86,0x55,0x04,0x09,0x00,0xd4,0x20,0xd3,0x10,0x92,
-       0x0c,0x51,0x04,0x09,0x00,0x10,0x04,0x09,0x00,0x10,0x00,0x10,0x00,0x52,0x04,0x10,
-       0x00,0x51,0x04,0x10,0x00,0x10,0x04,0x10,0x00,0x00,0x00,0x93,0x10,0x52,0x04,0x09,
-       0x00,0x91,0x08,0x10,0x04,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xcf,0x06,0x11,
-       0x00,0xd1,0x1c,0xd0,0x06,0xcf,0x06,0x11,0x00,0xcf,0x86,0x95,0x10,0x94,0x0c,0x93,
-       0x08,0x12,0x04,0x11,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xcf,0x06,0x00,
-       0x00,0xcf,0x06,0x00,0x00,0xcf,0x06,0x00,0x00,0xcf,0x86,0xd5,0x4c,0xd4,0x06,0xcf,
-       0x06,0x0b,0x00,0xd3,0x40,0xd2,0x3a,0xd1,0x34,0xd0,0x2e,0xcf,0x86,0x55,0x04,0x0b,
-       0x00,0xd4,0x14,0x53,0x04,0x0b,0x00,0x52,0x04,0x0b,0x00,0x51,0x04,0x0b,0x00,0x10,
-       0x04,0x0b,0x00,0x00,0x00,0x53,0x04,0x15,0x00,0x92,0x0c,0x91,0x08,0x10,0x04,0x15,
+       0x00,0x01,0x00,0x93,0x14,0x92,0x10,0xd1,0x08,0x10,0x04,0x01,0x00,0x00,0x00,0x10,
+       0x04,0x00,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0xd4,0x14,0x53,0x04,0x01,0x00,0x92,
+       0x0c,0x91,0x08,0x10,0x04,0x01,0x00,0x00,0x00,0x01,0x00,0x01,0x00,0xd3,0x18,0xd2,
+       0x0c,0x91,0x08,0x10,0x04,0x01,0x00,0x00,0x00,0x01,0x00,0x91,0x08,0x10,0x04,0x00,
+       0x00,0x07,0x00,0x01,0x00,0xd2,0x08,0x11,0x04,0x01,0x00,0x00,0x00,0x91,0x08,0x10,
+       0x04,0x01,0x07,0x01,0x00,0x01,0x00,0xcf,0x86,0xd5,0x73,0xd4,0x45,0xd3,0x14,0x52,
+       0x04,0x01,0x00,0xd1,0x08,0x10,0x04,0x0a,0x00,0x00,0x00,0x10,0x04,0x00,0x00,0x01,
+       0x00,0xd2,0x1e,0xd1,0x0f,0x10,0x0b,0x01,0xff,0xe0,0xad,0x87,0xe0,0xad,0x96,0x00,
+       0x00,0x00,0x10,0x04,0x00,0x00,0x01,0xff,0xe0,0xad,0x87,0xe0,0xac,0xbe,0x00,0x91,
+       0x0f,0x10,0x0b,0x01,0xff,0xe0,0xad,0x87,0xe0,0xad,0x97,0x00,0x01,0x09,0x00,0x00,
+       0xd3,0x0c,0x52,0x04,0x00,0x00,0x11,0x04,0x00,0x00,0x01,0x00,0x52,0x04,0x00,0x00,
+       0xd1,0x16,0x10,0x0b,0x01,0xff,0xe0,0xac,0xa1,0xe0,0xac,0xbc,0x00,0x01,0xff,0xe0,
+       0xac,0xa2,0xe0,0xac,0xbc,0x00,0x10,0x04,0x00,0x00,0x01,0x00,0xd4,0x14,0x93,0x10,
+       0xd2,0x08,0x11,0x04,0x01,0x00,0x0a,0x00,0x11,0x04,0x00,0x00,0x01,0x00,0x01,0x00,
+       0x93,0x10,0x92,0x0c,0x91,0x08,0x10,0x04,0x01,0x00,0x07,0x00,0x0c,0x00,0x0c,0x00,
+       0x00,0x00,0xd0,0xb1,0xcf,0x86,0xd5,0x63,0xd4,0x28,0xd3,0x14,0xd2,0x08,0x11,0x04,
+       0x00,0x00,0x01,0x00,0x91,0x08,0x10,0x04,0x00,0x00,0x01,0x00,0x01,0x00,0xd2,0x0c,
+       0x51,0x04,0x01,0x00,0x10,0x04,0x01,0x00,0x00,0x00,0x11,0x04,0x00,0x00,0x01,0x00,
+       0xd3,0x1f,0xd2,0x0c,0x91,0x08,0x10,0x04,0x01,0x00,0x00,0x00,0x01,0x00,0x91,0x0f,
+       0x10,0x0b,0x01,0xff,0xe0,0xae,0x92,0xe0,0xaf,0x97,0x00,0x01,0x00,0x00,0x00,0xd2,
+       0x10,0xd1,0x08,0x10,0x04,0x00,0x00,0x01,0x00,0x10,0x04,0x01,0x00,0x00,0x00,0x91,
+       0x08,0x10,0x04,0x01,0x00,0x00,0x00,0x01,0x00,0xd4,0x2c,0xd3,0x18,0xd2,0x0c,0x51,
+       0x04,0x00,0x00,0x10,0x04,0x00,0x00,0x01,0x00,0x91,0x08,0x10,0x04,0x01,0x00,0x00,
+       0x00,0x00,0x00,0xd2,0x0c,0x51,0x04,0x01,0x00,0x10,0x04,0x01,0x00,0x00,0x00,0x11,
+       0x04,0x00,0x00,0x01,0x00,0xd3,0x10,0x52,0x04,0x01,0x00,0x51,0x04,0x01,0x00,0x10,
+       0x04,0x08,0x00,0x01,0x00,0xd2,0x08,0x11,0x04,0x01,0x00,0x00,0x00,0x11,0x04,0x00,
+       0x00,0x01,0x00,0xcf,0x86,0xd5,0x61,0xd4,0x45,0xd3,0x14,0xd2,0x0c,0x51,0x04,0x01,
+       0x00,0x10,0x04,0x01,0x00,0x00,0x00,0x11,0x04,0x00,0x00,0x01,0x00,0xd2,0x1e,0xd1,
+       0x08,0x10,0x04,0x01,0x00,0x00,0x00,0x10,0x0b,0x01,0xff,0xe0,0xaf,0x86,0xe0,0xae,
+       0xbe,0x00,0x01,0xff,0xe0,0xaf,0x87,0xe0,0xae,0xbe,0x00,0x91,0x0f,0x10,0x0b,0x01,
+       0xff,0xe0,0xaf,0x86,0xe0,0xaf,0x97,0x00,0x01,0x09,0x00,0x00,0x93,0x18,0xd2,0x0c,
+       0x91,0x08,0x10,0x04,0x0a,0x00,0x00,0x00,0x00,0x00,0x51,0x04,0x00,0x00,0x10,0x04,
+       0x00,0x00,0x01,0x00,0x00,0x00,0xd4,0x14,0x93,0x10,0x52,0x04,0x00,0x00,0x51,0x04,
+       0x00,0x00,0x10,0x04,0x08,0x00,0x01,0x00,0x01,0x00,0xd3,0x10,0x92,0x0c,0x51,0x04,
+       0x01,0x00,0x10,0x04,0x01,0x00,0x07,0x00,0x07,0x00,0x92,0x0c,0x51,0x04,0x07,0x00,
+       0x10,0x04,0x07,0x00,0x00,0x00,0x00,0x00,0xe3,0x1c,0x04,0xe2,0x1a,0x02,0xd1,0xf3,
+       0xd0,0x76,0xcf,0x86,0xd5,0x3c,0xd4,0x28,0xd3,0x18,0xd2,0x0c,0x91,0x08,0x10,0x04,
+       0x10,0x00,0x01,0x00,0x01,0x00,0x91,0x08,0x10,0x04,0x14,0x00,0x01,0x00,0x01,0x00,
+       0x52,0x04,0x01,0x00,0x91,0x08,0x10,0x04,0x01,0x00,0x00,0x00,0x01,0x00,0x93,0x10,
+       0x92,0x0c,0x91,0x08,0x10,0x04,0x01,0x00,0x00,0x00,0x01,0x00,0x01,0x00,0x01,0x00,
+       0xd4,0x14,0x53,0x04,0x01,0x00,0x92,0x0c,0x91,0x08,0x10,0x04,0x01,0x00,0x00,0x00,
+       0x01,0x00,0x01,0x00,0xd3,0x10,0x52,0x04,0x01,0x00,0x91,0x08,0x10,0x04,0x10,0x00,
+       0x01,0x00,0x01,0x00,0xd2,0x08,0x11,0x04,0x01,0x00,0x00,0x00,0x91,0x08,0x10,0x04,
+       0x00,0x00,0x0a,0x00,0x01,0x00,0xcf,0x86,0xd5,0x53,0xd4,0x2f,0xd3,0x10,0x52,0x04,
+       0x01,0x00,0x91,0x08,0x10,0x04,0x01,0x00,0x00,0x00,0x01,0x00,0xd2,0x13,0x91,0x0f,
+       0x10,0x0b,0x01,0xff,0xe0,0xb1,0x86,0xe0,0xb1,0x96,0x00,0x00,0x00,0x01,0x00,0x91,
+       0x08,0x10,0x04,0x01,0x00,0x01,0x09,0x00,0x00,0xd3,0x14,0x52,0x04,0x00,0x00,0xd1,
+       0x08,0x10,0x04,0x00,0x00,0x01,0x54,0x10,0x04,0x01,0x5b,0x00,0x00,0x92,0x0c,0x51,
+       0x04,0x0a,0x00,0x10,0x04,0x11,0x00,0x00,0x00,0x00,0x00,0xd4,0x14,0x93,0x10,0xd2,
+       0x08,0x11,0x04,0x01,0x00,0x0a,0x00,0x11,0x04,0x00,0x00,0x01,0x00,0x01,0x00,0x93,
+       0x10,0x52,0x04,0x00,0x00,0x51,0x04,0x00,0x00,0x10,0x04,0x00,0x00,0x15,0x00,0x0a,
+       0x00,0xd0,0x76,0xcf,0x86,0xd5,0x3c,0xd4,0x28,0xd3,0x18,0xd2,0x0c,0x91,0x08,0x10,
+       0x04,0x12,0x00,0x10,0x00,0x01,0x00,0x91,0x08,0x10,0x04,0x14,0x00,0x01,0x00,0x01,
+       0x00,0x52,0x04,0x01,0x00,0x91,0x08,0x10,0x04,0x01,0x00,0x00,0x00,0x01,0x00,0x93,
+       0x10,0x92,0x0c,0x91,0x08,0x10,0x04,0x01,0x00,0x00,0x00,0x01,0x00,0x01,0x00,0x01,
+       0x00,0xd4,0x14,0x53,0x04,0x01,0x00,0x92,0x0c,0x91,0x08,0x10,0x04,0x01,0x00,0x00,
+       0x00,0x01,0x00,0x01,0x00,0xd3,0x10,0x52,0x04,0x01,0x00,0x91,0x08,0x10,0x04,0x00,
+       0x00,0x01,0x00,0x01,0x00,0xd2,0x08,0x11,0x04,0x01,0x00,0x00,0x00,0x91,0x08,0x10,
+       0x04,0x07,0x07,0x07,0x00,0x01,0x00,0xcf,0x86,0xd5,0x82,0xd4,0x5e,0xd3,0x2a,0xd2,
+       0x13,0x91,0x0f,0x10,0x0b,0x01,0xff,0xe0,0xb2,0xbf,0xe0,0xb3,0x95,0x00,0x01,0x00,
+       0x01,0x00,0xd1,0x08,0x10,0x04,0x01,0x00,0x00,0x00,0x10,0x04,0x01,0x00,0x01,0xff,
+       0xe0,0xb3,0x86,0xe0,0xb3,0x95,0x00,0xd2,0x28,0xd1,0x0f,0x10,0x0b,0x01,0xff,0xe0,
+       0xb3,0x86,0xe0,0xb3,0x96,0x00,0x00,0x00,0x10,0x0b,0x01,0xff,0xe0,0xb3,0x86,0xe0,
+       0xb3,0x82,0x00,0x01,0xff,0xe0,0xb3,0x86,0xe0,0xb3,0x82,0xe0,0xb3,0x95,0x00,0x91,
+       0x08,0x10,0x04,0x01,0x00,0x01,0x09,0x00,0x00,0xd3,0x14,0x52,0x04,0x00,0x00,0xd1,
+       0x08,0x10,0x04,0x00,0x00,0x01,0x00,0x10,0x04,0x01,0x00,0x00,0x00,0x52,0x04,0x00,
+       0x00,0x51,0x04,0x00,0x00,0x10,0x04,0x01,0x00,0x00,0x00,0xd4,0x14,0x93,0x10,0xd2,
+       0x08,0x11,0x04,0x01,0x00,0x09,0x00,0x11,0x04,0x00,0x00,0x01,0x00,0x01,0x00,0x93,
+       0x14,0x92,0x10,0xd1,0x08,0x10,0x04,0x00,0x00,0x09,0x00,0x10,0x04,0x09,0x00,0x00,
+       0x00,0x00,0x00,0x00,0x00,0xe1,0x06,0x01,0xd0,0x6e,0xcf,0x86,0xd5,0x3c,0xd4,0x28,
+       0xd3,0x18,0xd2,0x0c,0x91,0x08,0x10,0x04,0x13,0x00,0x10,0x00,0x01,0x00,0x91,0x08,
+       0x10,0x04,0x00,0x00,0x01,0x00,0x01,0x00,0x52,0x04,0x01,0x00,0x91,0x08,0x10,0x04,
+       0x01,0x00,0x00,0x00,0x01,0x00,0x93,0x10,0x92,0x0c,0x91,0x08,0x10,0x04,0x01,0x00,
+       0x00,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0xd4,0x14,0x53,0x04,0x01,0x00,0x92,0x0c,
+       0x91,0x08,0x10,0x04,0x01,0x00,0x0c,0x00,0x01,0x00,0x01,0x00,0x53,0x04,0x01,0x00,
+       0xd2,0x0c,0x51,0x04,0x01,0x00,0x10,0x04,0x0c,0x00,0x13,0x09,0x91,0x08,0x10,0x04,
+       0x13,0x09,0x0a,0x00,0x01,0x00,0xcf,0x86,0xd5,0x65,0xd4,0x45,0xd3,0x10,0x52,0x04,
+       0x01,0x00,0x91,0x08,0x10,0x04,0x0a,0x00,0x00,0x00,0x01,0x00,0xd2,0x1e,0xd1,0x08,
+       0x10,0x04,0x01,0x00,0x00,0x00,0x10,0x0b,0x01,0xff,0xe0,0xb5,0x86,0xe0,0xb4,0xbe,
+       0x00,0x01,0xff,0xe0,0xb5,0x87,0xe0,0xb4,0xbe,0x00,0xd1,0x0f,0x10,0x0b,0x01,0xff,
+       0xe0,0xb5,0x86,0xe0,0xb5,0x97,0x00,0x01,0x09,0x10,0x04,0x0c,0x00,0x12,0x00,0xd3,
+       0x10,0x52,0x04,0x00,0x00,0x51,0x04,0x12,0x00,0x10,0x04,0x12,0x00,0x01,0x00,0x52,
+       0x04,0x12,0x00,0x51,0x04,0x12,0x00,0x10,0x04,0x12,0x00,0x11,0x00,0xd4,0x14,0x93,
+       0x10,0xd2,0x08,0x11,0x04,0x01,0x00,0x0a,0x00,0x11,0x04,0x00,0x00,0x01,0x00,0x01,
+       0x00,0xd3,0x0c,0x52,0x04,0x0a,0x00,0x11,0x04,0x0a,0x00,0x12,0x00,0x92,0x0c,0x91,
+       0x08,0x10,0x04,0x12,0x00,0x0a,0x00,0x0a,0x00,0x0a,0x00,0xd0,0x5a,0xcf,0x86,0xd5,
+       0x34,0xd4,0x18,0x93,0x14,0xd2,0x08,0x11,0x04,0x00,0x00,0x04,0x00,0x91,0x08,0x10,
+       0x04,0x00,0x00,0x04,0x00,0x04,0x00,0x04,0x00,0xd3,0x10,0x52,0x04,0x04,0x00,0x51,
+       0x04,0x04,0x00,0x10,0x04,0x04,0x00,0x00,0x00,0x92,0x08,0x11,0x04,0x00,0x00,0x04,
+       0x00,0x04,0x00,0x54,0x04,0x04,0x00,0xd3,0x10,0x92,0x0c,0x51,0x04,0x04,0x00,0x10,
+       0x04,0x00,0x00,0x04,0x00,0x04,0x00,0x52,0x04,0x04,0x00,0x91,0x08,0x10,0x04,0x00,
+       0x00,0x04,0x00,0x00,0x00,0xcf,0x86,0xd5,0x77,0xd4,0x28,0xd3,0x10,0x52,0x04,0x04,
+       0x00,0x51,0x04,0x04,0x00,0x10,0x04,0x04,0x00,0x00,0x00,0xd2,0x0c,0x51,0x04,0x00,
+       0x00,0x10,0x04,0x04,0x09,0x00,0x00,0x51,0x04,0x00,0x00,0x10,0x04,0x00,0x00,0x04,
+       0x00,0xd3,0x14,0x52,0x04,0x04,0x00,0xd1,0x08,0x10,0x04,0x04,0x00,0x00,0x00,0x10,
+       0x04,0x04,0x00,0x00,0x00,0xd2,0x13,0x51,0x04,0x04,0x00,0x10,0x0b,0x04,0xff,0xe0,
+       0xb7,0x99,0xe0,0xb7,0x8a,0x00,0x04,0x00,0xd1,0x19,0x10,0x0b,0x04,0xff,0xe0,0xb7,
+       0x99,0xe0,0xb7,0x8f,0x00,0x04,0xff,0xe0,0xb7,0x99,0xe0,0xb7,0x8f,0xe0,0xb7,0x8a,
+       0x00,0x10,0x0b,0x04,0xff,0xe0,0xb7,0x99,0xe0,0xb7,0x9f,0x00,0x04,0x00,0xd4,0x10,
+       0x93,0x0c,0x52,0x04,0x00,0x00,0x11,0x04,0x00,0x00,0x10,0x00,0x10,0x00,0x93,0x14,
+       0xd2,0x08,0x11,0x04,0x00,0x00,0x04,0x00,0x91,0x08,0x10,0x04,0x04,0x00,0x00,0x00,
+       0x00,0x00,0x00,0x00,0xe2,0x31,0x01,0xd1,0x58,0xd0,0x3a,0xcf,0x86,0xd5,0x18,0x94,
+       0x14,0x93,0x10,0x92,0x0c,0x91,0x08,0x10,0x04,0x00,0x00,0x01,0x00,0x01,0x00,0x01,
+       0x00,0x01,0x00,0x01,0x00,0x54,0x04,0x01,0x00,0x53,0x04,0x01,0x00,0xd2,0x0c,0x51,
+       0x04,0x01,0x67,0x10,0x04,0x01,0x09,0x00,0x00,0x51,0x04,0x00,0x00,0x10,0x04,0x00,
+       0x00,0x01,0x00,0xcf,0x86,0x95,0x18,0xd4,0x0c,0x53,0x04,0x01,0x00,0x12,0x04,0x01,
+       0x6b,0x01,0x00,0x53,0x04,0x01,0x00,0x12,0x04,0x01,0x00,0x00,0x00,0x00,0x00,0xd0,
+       0x9e,0xcf,0x86,0xd5,0x54,0xd4,0x3c,0xd3,0x20,0xd2,0x10,0xd1,0x08,0x10,0x04,0x00,
+       0x00,0x01,0x00,0x10,0x04,0x01,0x00,0x00,0x00,0xd1,0x08,0x10,0x04,0x01,0x00,0x00,
+       0x00,0x10,0x04,0x15,0x00,0x01,0x00,0xd2,0x10,0xd1,0x08,0x10,0x04,0x01,0x00,0x15,
+       0x00,0x10,0x04,0x01,0x00,0x00,0x00,0x91,0x08,0x10,0x04,0x15,0x00,0x01,0x00,0x15,
+       0x00,0xd3,0x08,0x12,0x04,0x15,0x00,0x01,0x00,0x92,0x0c,0x91,0x08,0x10,0x04,0x15,
+       0x00,0x01,0x00,0x01,0x00,0x01,0x00,0xd4,0x30,0xd3,0x1c,0xd2,0x0c,0x91,0x08,0x10,
+       0x04,0x15,0x00,0x01,0x00,0x01,0x00,0xd1,0x08,0x10,0x04,0x00,0x00,0x01,0x00,0x10,
+       0x04,0x00,0x00,0x01,0x00,0xd2,0x08,0x11,0x04,0x15,0x00,0x01,0x00,0x91,0x08,0x10,
+       0x04,0x15,0x00,0x01,0x00,0x01,0x00,0x53,0x04,0x01,0x00,0xd2,0x0c,0x51,0x04,0x01,
+       0x76,0x10,0x04,0x15,0x09,0x01,0x00,0x11,0x04,0x01,0x00,0x00,0x00,0xcf,0x86,0x95,
+       0x34,0xd4,0x20,0xd3,0x14,0x52,0x04,0x01,0x00,0xd1,0x08,0x10,0x04,0x01,0x00,0x00,
+       0x00,0x10,0x04,0x01,0x00,0x00,0x00,0x52,0x04,0x01,0x7a,0x11,0x04,0x01,0x00,0x00,
+       0x00,0x53,0x04,0x01,0x00,0xd2,0x08,0x11,0x04,0x01,0x00,0x00,0x00,0x11,0x04,0x01,
+       0x00,0x0d,0x00,0x00,0x00,0xe1,0x2b,0x01,0xd0,0x3e,0xcf,0x86,0xd5,0x14,0x54,0x04,
+       0x02,0x00,0x53,0x04,0x02,0x00,0x92,0x08,0x11,0x04,0x02,0xdc,0x02,0x00,0x02,0x00,
+       0x54,0x04,0x02,0x00,0xd3,0x14,0x52,0x04,0x02,0x00,0xd1,0x08,0x10,0x04,0x02,0x00,
+       0x02,0xdc,0x10,0x04,0x02,0x00,0x02,0xdc,0x92,0x0c,0x91,0x08,0x10,0x04,0x02,0x00,
+       0x02,0xd8,0x02,0x00,0x02,0x00,0xcf,0x86,0xd5,0x73,0xd4,0x36,0xd3,0x17,0x92,0x13,
+       0x51,0x04,0x02,0x00,0x10,0x04,0x02,0x00,0x02,0xff,0xe0,0xbd,0x82,0xe0,0xbe,0xb7,
+       0x00,0x02,0x00,0xd2,0x0c,0x91,0x08,0x10,0x04,0x00,0x00,0x02,0x00,0x02,0x00,0x91,
+       0x0f,0x10,0x04,0x02,0x00,0x02,0xff,0xe0,0xbd,0x8c,0xe0,0xbe,0xb7,0x00,0x02,0x00,
+       0xd3,0x26,0xd2,0x13,0x51,0x04,0x02,0x00,0x10,0x0b,0x02,0xff,0xe0,0xbd,0x91,0xe0,
+       0xbe,0xb7,0x00,0x02,0x00,0x51,0x04,0x02,0x00,0x10,0x04,0x02,0x00,0x02,0xff,0xe0,
+       0xbd,0x96,0xe0,0xbe,0xb7,0x00,0x52,0x04,0x02,0x00,0x91,0x0f,0x10,0x0b,0x02,0xff,
+       0xe0,0xbd,0x9b,0xe0,0xbe,0xb7,0x00,0x02,0x00,0x02,0x00,0xd4,0x27,0x53,0x04,0x02,
+       0x00,0xd2,0x17,0xd1,0x0f,0x10,0x04,0x02,0x00,0x02,0xff,0xe0,0xbd,0x80,0xe0,0xbe,
+       0xb5,0x00,0x10,0x04,0x04,0x00,0x0a,0x00,0x91,0x08,0x10,0x04,0x0a,0x00,0x00,0x00,
+       0x00,0x00,0xd3,0x35,0xd2,0x17,0xd1,0x08,0x10,0x04,0x00,0x00,0x02,0x81,0x10,0x04,
+       0x02,0x82,0x02,0xff,0xe0,0xbd,0xb1,0xe0,0xbd,0xb2,0x00,0xd1,0x0f,0x10,0x04,0x02,
+       0x84,0x02,0xff,0xe0,0xbd,0xb1,0xe0,0xbd,0xb4,0x00,0x10,0x0b,0x02,0xff,0xe0,0xbe,
+       0xb2,0xe0,0xbe,0x80,0x00,0x02,0x00,0xd2,0x13,0x91,0x0f,0x10,0x0b,0x02,0xff,0xe0,
+       0xbe,0xb3,0xe0,0xbe,0x80,0x00,0x02,0x00,0x02,0x82,0x11,0x04,0x02,0x82,0x02,0x00,
+       0xd0,0xd3,0xcf,0x86,0xd5,0x65,0xd4,0x27,0xd3,0x1f,0xd2,0x13,0x91,0x0f,0x10,0x04,
+       0x02,0x82,0x02,0xff,0xe0,0xbd,0xb1,0xe0,0xbe,0x80,0x00,0x02,0xe6,0x91,0x08,0x10,
+       0x04,0x02,0x09,0x02,0x00,0x02,0xe6,0x12,0x04,0x02,0x00,0x0c,0x00,0xd3,0x1f,0xd2,
+       0x13,0x51,0x04,0x02,0x00,0x10,0x04,0x02,0x00,0x02,0xff,0xe0,0xbe,0x92,0xe0,0xbe,
+       0xb7,0x00,0x51,0x04,0x02,0x00,0x10,0x04,0x04,0x00,0x02,0x00,0xd2,0x0c,0x91,0x08,
+       0x10,0x04,0x00,0x00,0x02,0x00,0x02,0x00,0x91,0x0f,0x10,0x04,0x02,0x00,0x02,0xff,
+       0xe0,0xbe,0x9c,0xe0,0xbe,0xb7,0x00,0x02,0x00,0xd4,0x3d,0xd3,0x26,0xd2,0x13,0x51,
+       0x04,0x02,0x00,0x10,0x0b,0x02,0xff,0xe0,0xbe,0xa1,0xe0,0xbe,0xb7,0x00,0x02,0x00,
+       0x51,0x04,0x02,0x00,0x10,0x04,0x02,0x00,0x02,0xff,0xe0,0xbe,0xa6,0xe0,0xbe,0xb7,
+       0x00,0x52,0x04,0x02,0x00,0x91,0x0f,0x10,0x0b,0x02,0xff,0xe0,0xbe,0xab,0xe0,0xbe,
+       0xb7,0x00,0x02,0x00,0x04,0x00,0xd3,0x10,0x92,0x0c,0x91,0x08,0x10,0x04,0x04,0x00,
+       0x02,0x00,0x02,0x00,0x02,0x00,0xd2,0x13,0x91,0x0f,0x10,0x04,0x04,0x00,0x02,0xff,
+       0xe0,0xbe,0x90,0xe0,0xbe,0xb5,0x00,0x04,0x00,0x91,0x08,0x10,0x04,0x04,0x00,0x00,
+       0x00,0x04,0x00,0xcf,0x86,0x95,0x4c,0xd4,0x24,0xd3,0x10,0x52,0x04,0x04,0x00,0x51,
+       0x04,0x04,0x00,0x10,0x04,0x04,0xdc,0x04,0x00,0x52,0x04,0x04,0x00,0xd1,0x08,0x10,
+       0x04,0x04,0x00,0x00,0x00,0x10,0x04,0x0a,0x00,0x04,0x00,0xd3,0x14,0xd2,0x08,0x11,
+       0x04,0x08,0x00,0x0a,0x00,0x91,0x08,0x10,0x04,0x0a,0x00,0x0b,0x00,0x0b,0x00,0x92,
+       0x10,0xd1,0x08,0x10,0x04,0x0b,0x00,0x0c,0x00,0x10,0x04,0x0c,0x00,0x00,0x00,0x00,
+       0x00,0x00,0x00,0xcf,0x86,0xe5,0xcc,0x04,0xe4,0x63,0x03,0xe3,0x65,0x01,0xe2,0x04,
+       0x01,0xd1,0x7f,0xd0,0x65,0xcf,0x86,0x55,0x04,0x04,0x00,0xd4,0x33,0xd3,0x1f,0xd2,
+       0x0c,0x51,0x04,0x04,0x00,0x10,0x04,0x0a,0x00,0x04,0x00,0x51,0x04,0x04,0x00,0x10,
+       0x0b,0x04,0xff,0xe1,0x80,0xa5,0xe1,0x80,0xae,0x00,0x04,0x00,0x92,0x10,0xd1,0x08,
+       0x10,0x04,0x0a,0x00,0x04,0x00,0x10,0x04,0x04,0x00,0x0a,0x00,0x04,0x00,0xd3,0x18,
+       0xd2,0x0c,0x51,0x04,0x04,0x00,0x10,0x04,0x04,0x00,0x0a,0x00,0x51,0x04,0x0a,0x00,
+       0x10,0x04,0x04,0x00,0x04,0x07,0x92,0x10,0xd1,0x08,0x10,0x04,0x04,0x00,0x04,0x09,
+       0x10,0x04,0x0a,0x09,0x0a,0x00,0x0a,0x00,0xcf,0x86,0x95,0x14,0x54,0x04,0x04,0x00,
+       0x53,0x04,0x04,0x00,0x92,0x08,0x11,0x04,0x04,0x00,0x0a,0x00,0x0a,0x00,0x0a,0x00,
+       0xd0,0x2e,0xcf,0x86,0x95,0x28,0xd4,0x14,0x53,0x04,0x0a,0x00,0x52,0x04,0x0a,0x00,
+       0x91,0x08,0x10,0x04,0x0a,0x00,0x0a,0xdc,0x0a,0x00,0x53,0x04,0x0a,0x00,0xd2,0x08,
+       0x11,0x04,0x0a,0x00,0x0b,0x00,0x11,0x04,0x0b,0x00,0x0a,0x00,0x01,0x00,0xcf,0x86,
+       0xd5,0x24,0x94,0x20,0xd3,0x10,0x52,0x04,0x01,0x00,0x51,0x04,0x01,0x00,0x10,0x04,
+       0x00,0x00,0x0d,0x00,0x52,0x04,0x00,0x00,0x91,0x08,0x10,0x04,0x00,0x00,0x0d,0x00,
+       0x00,0x00,0x01,0x00,0x54,0x04,0x01,0x00,0xd3,0x10,0x52,0x04,0x01,0x00,0x51,0x04,
+       0x01,0x00,0x10,0x04,0x01,0x00,0x06,0x00,0xd2,0x10,0xd1,0x08,0x10,0x04,0x06,0x00,
+       0x08,0x00,0x10,0x04,0x08,0x00,0x01,0x00,0x91,0x08,0x10,0x04,0x08,0x00,0x0d,0x00,
+       0x0d,0x00,0xd1,0x28,0xd0,0x06,0xcf,0x06,0x01,0x00,0xcf,0x86,0x95,0x1c,0x54,0x04,
+       0x01,0x00,0x53,0x04,0x01,0x00,0xd2,0x08,0x11,0x04,0x01,0x00,0x0b,0x00,0x51,0x04,
+       0x0b,0x00,0x10,0x04,0x0b,0x00,0x01,0x00,0x01,0x00,0xd0,0x1e,0xcf,0x86,0x55,0x04,
+       0x01,0x00,0x94,0x14,0x93,0x10,0x92,0x0c,0x51,0x04,0x01,0x00,0x10,0x04,0x01,0x00,
+       0x0b,0x00,0x0b,0x00,0x01,0x00,0x01,0x00,0xcf,0x86,0x55,0x04,0x01,0x00,0x54,0x04,
+       0x01,0x00,0x53,0x04,0x01,0x00,0x92,0x08,0x11,0x04,0x01,0x00,0x0b,0x00,0x0b,0x00,
+       0xe2,0x21,0x01,0xd1,0x6c,0xd0,0x1e,0xcf,0x86,0x95,0x18,0x94,0x14,0x93,0x10,0x52,
+       0x04,0x04,0x00,0x51,0x04,0x04,0x00,0x10,0x04,0x04,0x00,0x08,0x00,0x04,0x00,0x04,
+       0x00,0x04,0x00,0xcf,0x86,0x95,0x48,0xd4,0x24,0xd3,0x10,0x52,0x04,0x04,0x00,0x51,
+       0x04,0x04,0x00,0x10,0x04,0x04,0x00,0x08,0x00,0xd2,0x0c,0x91,0x08,0x10,0x04,0x04,
+       0x00,0x00,0x00,0x04,0x00,0x11,0x04,0x04,0x00,0x00,0x00,0xd3,0x10,0x52,0x04,0x04,
+       0x00,0x51,0x04,0x04,0x00,0x10,0x04,0x04,0x00,0x00,0x00,0xd2,0x0c,0x91,0x08,0x10,
+       0x04,0x04,0x00,0x00,0x00,0x04,0x00,0x11,0x04,0x04,0x00,0x00,0x00,0x04,0x00,0xd0,
+       0x62,0xcf,0x86,0xd5,0x28,0x94,0x24,0xd3,0x10,0x52,0x04,0x04,0x00,0x51,0x04,0x04,
+       0x00,0x10,0x04,0x04,0x00,0x08,0x00,0xd2,0x0c,0x91,0x08,0x10,0x04,0x04,0x00,0x00,
+       0x00,0x04,0x00,0x11,0x04,0x04,0x00,0x00,0x00,0x04,0x00,0xd4,0x14,0x53,0x04,0x04,
+       0x00,0x52,0x04,0x04,0x00,0x51,0x04,0x04,0x00,0x10,0x04,0x04,0x00,0x08,0x00,0xd3,
+       0x14,0xd2,0x0c,0x91,0x08,0x10,0x04,0x04,0x00,0x00,0x00,0x04,0x00,0x11,0x04,0x04,
+       0x00,0x00,0x00,0x52,0x04,0x04,0x00,0x51,0x04,0x04,0x00,0x10,0x04,0x04,0x00,0x00,
+       0x00,0xcf,0x86,0xd5,0x38,0xd4,0x24,0xd3,0x14,0xd2,0x0c,0x91,0x08,0x10,0x04,0x04,
+       0x00,0x00,0x00,0x04,0x00,0x11,0x04,0x04,0x00,0x00,0x00,0x52,0x04,0x04,0x00,0x51,
+       0x04,0x04,0x00,0x10,0x04,0x04,0x00,0x08,0x00,0x93,0x10,0x52,0x04,0x04,0x00,0x51,
+       0x04,0x04,0x00,0x10,0x04,0x04,0x00,0x00,0x00,0x04,0x00,0x94,0x14,0x53,0x04,0x04,
+       0x00,0x52,0x04,0x04,0x00,0x51,0x04,0x04,0x00,0x10,0x04,0x04,0x00,0x08,0x00,0x04,
+       0x00,0xd1,0x9c,0xd0,0x3e,0xcf,0x86,0x95,0x38,0xd4,0x14,0x53,0x04,0x04,0x00,0x52,
+       0x04,0x04,0x00,0x51,0x04,0x04,0x00,0x10,0x04,0x04,0x00,0x08,0x00,0xd3,0x14,0xd2,
+       0x0c,0x91,0x08,0x10,0x04,0x04,0x00,0x00,0x00,0x04,0x00,0x11,0x04,0x04,0x00,0x00,
+       0x00,0x52,0x04,0x04,0x00,0x51,0x04,0x04,0x00,0x10,0x04,0x04,0x00,0x08,0x00,0x04,
+       0x00,0xcf,0x86,0xd5,0x34,0xd4,0x14,0x93,0x10,0x52,0x04,0x04,0x00,0x51,0x04,0x04,
+       0x00,0x10,0x04,0x04,0x00,0x08,0x00,0x04,0x00,0x53,0x04,0x04,0x00,0xd2,0x0c,0x51,
+       0x04,0x04,0x00,0x10,0x04,0x04,0x00,0x00,0x00,0xd1,0x08,0x10,0x04,0x00,0x00,0x0c,
+       0xe6,0x10,0x04,0x0c,0xe6,0x08,0xe6,0xd4,0x14,0x93,0x10,0x92,0x0c,0x91,0x08,0x10,
+       0x04,0x08,0x00,0x04,0x00,0x04,0x00,0x04,0x00,0x04,0x00,0x53,0x04,0x04,0x00,0x52,
+       0x04,0x04,0x00,0x91,0x08,0x10,0x04,0x04,0x00,0x00,0x00,0x00,0x00,0xd0,0x1a,0xcf,
+       0x86,0x95,0x14,0x54,0x04,0x08,0x00,0x53,0x04,0x08,0x00,0x92,0x08,0x11,0x04,0x08,
+       0x00,0x00,0x00,0x00,0x00,0x04,0x00,0xcf,0x86,0x55,0x04,0x04,0x00,0x54,0x04,0x04,
+       0x00,0xd3,0x10,0x52,0x04,0x04,0x00,0x91,0x08,0x10,0x04,0x04,0x00,0x11,0x00,0x00,
+       0x00,0x52,0x04,0x11,0x00,0x11,0x04,0x11,0x00,0x00,0x00,0xd3,0x30,0xd2,0x2a,0xd1,
+       0x24,0xd0,0x1e,0xcf,0x86,0x95,0x18,0x94,0x14,0x93,0x10,0x92,0x0c,0x91,0x08,0x10,
+       0x04,0x0b,0x00,0x04,0x00,0x04,0x00,0x04,0x00,0x04,0x00,0x04,0x00,0x04,0x00,0xcf,
+       0x06,0x04,0x00,0xcf,0x06,0x04,0x00,0xcf,0x06,0x04,0x00,0xd2,0x6c,0xd1,0x24,0xd0,
+       0x06,0xcf,0x06,0x04,0x00,0xcf,0x86,0x55,0x04,0x04,0x00,0x54,0x04,0x04,0x00,0x93,
+       0x10,0x52,0x04,0x04,0x00,0x51,0x04,0x04,0x00,0x10,0x04,0x04,0x00,0x0b,0x00,0x0b,
+       0x00,0xd0,0x1e,0xcf,0x86,0x95,0x18,0x54,0x04,0x04,0x00,0x53,0x04,0x04,0x00,0x52,
+       0x04,0x04,0x00,0x91,0x08,0x10,0x04,0x04,0x00,0x00,0x00,0x00,0x00,0x04,0x00,0xcf,
+       0x86,0x55,0x04,0x04,0x00,0x54,0x04,0x04,0x00,0xd3,0x10,0x92,0x0c,0x91,0x08,0x10,
+       0x04,0x04,0x00,0x10,0x00,0x10,0x00,0x10,0x00,0x92,0x0c,0x91,0x08,0x10,0x04,0x10,
+       0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xd1,0x80,0xd0,0x46,0xcf,0x86,0xd5,0x28,0xd4,
+       0x14,0x53,0x04,0x06,0x00,0x52,0x04,0x06,0x00,0x91,0x08,0x10,0x04,0x06,0x00,0x00,
+       0x00,0x06,0x00,0x93,0x10,0x52,0x04,0x06,0x00,0x91,0x08,0x10,0x04,0x06,0x09,0x00,
+       0x00,0x00,0x00,0x00,0x00,0x54,0x04,0x06,0x00,0x93,0x14,0x52,0x04,0x06,0x00,0xd1,
+       0x08,0x10,0x04,0x06,0x09,0x06,0x00,0x10,0x04,0x06,0x00,0x00,0x00,0x00,0x00,0xcf,
+       0x86,0xd5,0x10,0x54,0x04,0x06,0x00,0x93,0x08,0x12,0x04,0x06,0x00,0x00,0x00,0x00,
+       0x00,0xd4,0x14,0x53,0x04,0x06,0x00,0x52,0x04,0x06,0x00,0x91,0x08,0x10,0x04,0x06,
+       0x00,0x00,0x00,0x06,0x00,0x93,0x10,0x92,0x0c,0x91,0x08,0x10,0x04,0x06,0x00,0x00,
+       0x00,0x06,0x00,0x00,0x00,0x00,0x00,0xd0,0x06,0xcf,0x06,0x04,0x00,0xcf,0x86,0xd5,
+       0x24,0x54,0x04,0x04,0x00,0xd3,0x10,0x92,0x0c,0x51,0x04,0x04,0x00,0x10,0x04,0x04,
+       0x09,0x04,0x00,0x04,0x00,0x52,0x04,0x04,0x00,0x91,0x08,0x10,0x04,0x04,0x00,0x07,
+       0xe6,0x00,0x00,0xd4,0x10,0x53,0x04,0x04,0x00,0x92,0x08,0x11,0x04,0x04,0x00,0x00,
+       0x00,0x00,0x00,0x53,0x04,0x07,0x00,0x92,0x08,0x11,0x04,0x07,0x00,0x00,0x00,0x00,
+       0x00,0xe4,0xac,0x03,0xe3,0x4d,0x01,0xd2,0x84,0xd1,0x48,0xd0,0x2a,0xcf,0x86,0x95,
+       0x24,0xd4,0x14,0x53,0x04,0x04,0x00,0x52,0x04,0x04,0x00,0x51,0x04,0x04,0x00,0x10,
+       0x04,0x04,0x00,0x00,0x00,0x53,0x04,0x04,0x00,0x92,0x08,0x11,0x04,0x04,0x00,0x00,
+       0x00,0x00,0x00,0x04,0x00,0xcf,0x86,0x55,0x04,0x04,0x00,0x54,0x04,0x04,0x00,0x53,
+       0x04,0x04,0x00,0x92,0x0c,0x91,0x08,0x10,0x04,0x14,0x00,0x00,0x00,0x00,0x00,0x00,
+       0x00,0xd0,0x22,0xcf,0x86,0x55,0x04,0x04,0x00,0x94,0x18,0x53,0x04,0x04,0x00,0x92,
+       0x10,0xd1,0x08,0x10,0x04,0x04,0x00,0x04,0xe4,0x10,0x04,0x0a,0x00,0x00,0x00,0x00,
+       0x00,0x0b,0x00,0xcf,0x86,0x55,0x04,0x0b,0x00,0x54,0x04,0x0b,0x00,0x93,0x0c,0x52,
+       0x04,0x0b,0x00,0x11,0x04,0x0b,0x00,0x00,0x00,0x00,0x00,0xd1,0x80,0xd0,0x42,0xcf,
+       0x86,0xd5,0x1c,0x54,0x04,0x07,0x00,0x53,0x04,0x07,0x00,0x52,0x04,0x07,0x00,0xd1,
+       0x08,0x10,0x04,0x07,0x00,0x10,0x00,0x10,0x04,0x10,0x00,0x00,0x00,0xd4,0x0c,0x53,
+       0x04,0x07,0x00,0x12,0x04,0x07,0x00,0x00,0x00,0x53,0x04,0x07,0x00,0x92,0x10,0xd1,
+       0x08,0x10,0x04,0x07,0x00,0x07,0xde,0x10,0x04,0x07,0xe6,0x07,0xdc,0x00,0x00,0xcf,
+       0x86,0xd5,0x18,0x94,0x14,0x93,0x10,0x92,0x0c,0x91,0x08,0x10,0x04,0x07,0x00,0x00,
+       0x00,0x00,0x00,0x07,0x00,0x07,0x00,0x07,0x00,0xd4,0x10,0x53,0x04,0x07,0x00,0x52,
+       0x04,0x07,0x00,0x11,0x04,0x07,0x00,0x00,0x00,0x93,0x10,0x52,0x04,0x07,0x00,0x91,
+       0x08,0x10,0x04,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xd0,0x1a,0xcf,0x86,0x55,
+       0x04,0x08,0x00,0x94,0x10,0x53,0x04,0x08,0x00,0x92,0x08,0x11,0x04,0x08,0x00,0x0b,
+       0x00,0x00,0x00,0x08,0x00,0xcf,0x86,0x95,0x28,0xd4,0x10,0x53,0x04,0x08,0x00,0x92,
+       0x08,0x11,0x04,0x08,0x00,0x00,0x00,0x00,0x00,0x53,0x04,0x08,0x00,0xd2,0x0c,0x51,
+       0x04,0x08,0x00,0x10,0x04,0x0b,0x00,0x00,0x00,0x11,0x04,0x00,0x00,0x08,0x00,0x07,
+       0x00,0xd2,0xe4,0xd1,0x80,0xd0,0x2e,0xcf,0x86,0x95,0x28,0x54,0x04,0x08,0x00,0xd3,
+       0x10,0x52,0x04,0x08,0x00,0x51,0x04,0x08,0x00,0x10,0x04,0x08,0x00,0x08,0xe6,0xd2,
+       0x0c,0x91,0x08,0x10,0x04,0x08,0xdc,0x08,0x00,0x08,0x00,0x11,0x04,0x00,0x00,0x08,
+       0x00,0x0b,0x00,0xcf,0x86,0xd5,0x18,0x54,0x04,0x0b,0x00,0x53,0x04,0x0b,0x00,0x52,
+       0x04,0x0b,0x00,0x51,0x04,0x0b,0x00,0x10,0x04,0x0b,0x00,0x00,0x00,0xd4,0x14,0x93,
+       0x10,0x92,0x0c,0x91,0x08,0x10,0x04,0x0b,0x09,0x0b,0x00,0x0b,0x00,0x0b,0x00,0x0b,
+       0x00,0xd3,0x10,0x52,0x04,0x0b,0x00,0x91,0x08,0x10,0x04,0x0b,0x00,0x0b,0xe6,0x0b,
+       0xe6,0x52,0x04,0x0b,0xe6,0xd1,0x08,0x10,0x04,0x0b,0xe6,0x00,0x00,0x10,0x04,0x00,
+       0x00,0x0b,0xdc,0xd0,0x5e,0xcf,0x86,0xd5,0x20,0xd4,0x10,0x53,0x04,0x0b,0x00,0x92,
+       0x08,0x11,0x04,0x0b,0x00,0x00,0x00,0x00,0x00,0x53,0x04,0x0b,0x00,0x92,0x08,0x11,
+       0x04,0x0b,0x00,0x00,0x00,0x00,0x00,0xd4,0x10,0x53,0x04,0x0b,0x00,0x52,0x04,0x0b,
+       0x00,0x11,0x04,0x0b,0x00,0x00,0x00,0xd3,0x10,0x52,0x04,0x10,0xe6,0x91,0x08,0x10,
+       0x04,0x10,0xe6,0x10,0xdc,0x10,0xdc,0xd2,0x0c,0x51,0x04,0x10,0xdc,0x10,0x04,0x10,
+       0xdc,0x10,0xe6,0xd1,0x08,0x10,0x04,0x10,0xe6,0x10,0xdc,0x10,0x04,0x10,0x00,0x00,
+       0x00,0xcf,0x06,0x00,0x00,0xe1,0x1e,0x01,0xd0,0xaa,0xcf,0x86,0xd5,0x6e,0xd4,0x53,
+       0xd3,0x17,0x52,0x04,0x09,0x00,0x51,0x04,0x09,0x00,0x10,0x0b,0x09,0xff,0xe1,0xac,
+       0x85,0xe1,0xac,0xb5,0x00,0x09,0x00,0xd2,0x1e,0xd1,0x0f,0x10,0x0b,0x09,0xff,0xe1,
+       0xac,0x87,0xe1,0xac,0xb5,0x00,0x09,0x00,0x10,0x0b,0x09,0xff,0xe1,0xac,0x89,0xe1,
+       0xac,0xb5,0x00,0x09,0x00,0xd1,0x0f,0x10,0x0b,0x09,0xff,0xe1,0xac,0x8b,0xe1,0xac,
+       0xb5,0x00,0x09,0x00,0x10,0x0b,0x09,0xff,0xe1,0xac,0x8d,0xe1,0xac,0xb5,0x00,0x09,
+       0x00,0x93,0x17,0x92,0x13,0x51,0x04,0x09,0x00,0x10,0x0b,0x09,0xff,0xe1,0xac,0x91,
+       0xe1,0xac,0xb5,0x00,0x09,0x00,0x09,0x00,0x09,0x00,0x54,0x04,0x09,0x00,0xd3,0x10,
+       0x52,0x04,0x09,0x00,0x91,0x08,0x10,0x04,0x09,0x07,0x09,0x00,0x09,0x00,0xd2,0x13,
+       0x51,0x04,0x09,0x00,0x10,0x04,0x09,0x00,0x09,0xff,0xe1,0xac,0xba,0xe1,0xac,0xb5,
+       0x00,0x91,0x0f,0x10,0x04,0x09,0x00,0x09,0xff,0xe1,0xac,0xbc,0xe1,0xac,0xb5,0x00,
+       0x09,0x00,0xcf,0x86,0xd5,0x3d,0x94,0x39,0xd3,0x31,0xd2,0x25,0xd1,0x16,0x10,0x0b,
+       0x09,0xff,0xe1,0xac,0xbe,0xe1,0xac,0xb5,0x00,0x09,0xff,0xe1,0xac,0xbf,0xe1,0xac,
+       0xb5,0x00,0x10,0x04,0x09,0x00,0x09,0xff,0xe1,0xad,0x82,0xe1,0xac,0xb5,0x00,0x91,
+       0x08,0x10,0x04,0x09,0x09,0x09,0x00,0x09,0x00,0x12,0x04,0x09,0x00,0x00,0x00,0x09,
+       0x00,0xd4,0x1c,0x53,0x04,0x09,0x00,0xd2,0x0c,0x51,0x04,0x09,0x00,0x10,0x04,0x09,
+       0x00,0x09,0xe6,0x91,0x08,0x10,0x04,0x09,0xdc,0x09,0xe6,0x09,0xe6,0xd3,0x08,0x12,
+       0x04,0x09,0xe6,0x09,0x00,0x52,0x04,0x09,0x00,0x91,0x08,0x10,0x04,0x09,0x00,0x00,
+       0x00,0x00,0x00,0xd0,0x2e,0xcf,0x86,0x55,0x04,0x0a,0x00,0xd4,0x18,0x53,0x04,0x0a,
+       0x00,0xd2,0x0c,0x51,0x04,0x0a,0x00,0x10,0x04,0x0a,0x09,0x0d,0x09,0x11,0x04,0x0d,
+       0x00,0x0a,0x00,0x53,0x04,0x0a,0x00,0x92,0x08,0x11,0x04,0x0a,0x00,0x0d,0x00,0x0d,
+       0x00,0xcf,0x86,0x55,0x04,0x0c,0x00,0xd4,0x14,0x93,0x10,0x52,0x04,0x0c,0x00,0x51,
+       0x04,0x0c,0x00,0x10,0x04,0x0c,0x07,0x0c,0x00,0x0c,0x00,0xd3,0x0c,0x92,0x08,0x11,
+       0x04,0x0c,0x00,0x0c,0x09,0x00,0x00,0x12,0x04,0x00,0x00,0x0c,0x00,0xe3,0xb2,0x01,
+       0xe2,0x09,0x01,0xd1,0x4c,0xd0,0x2a,0xcf,0x86,0x55,0x04,0x0a,0x00,0x54,0x04,0x0a,
+       0x00,0xd3,0x10,0x52,0x04,0x0a,0x00,0x51,0x04,0x0a,0x00,0x10,0x04,0x0a,0x00,0x0a,
+       0x07,0x92,0x0c,0x51,0x04,0x00,0x00,0x10,0x04,0x00,0x00,0x0a,0x00,0x0a,0x00,0xcf,
+       0x86,0x95,0x1c,0x94,0x18,0x53,0x04,0x0a,0x00,0xd2,0x08,0x11,0x04,0x0a,0x00,0x00,
+       0x00,0x91,0x08,0x10,0x04,0x00,0x00,0x0a,0x00,0x0a,0x00,0x0a,0x00,0x0a,0x00,0xd0,
+       0x3a,0xcf,0x86,0xd5,0x18,0x94,0x14,0x53,0x04,0x12,0x00,0x92,0x0c,0x91,0x08,0x10,
+       0x04,0x12,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x14,0x00,0x54,0x04,0x14,0x00,0x53,
+       0x04,0x14,0x00,0xd2,0x0c,0x51,0x04,0x14,0x00,0x10,0x04,0x14,0x00,0x00,0x00,0x91,
+       0x08,0x10,0x04,0x00,0x00,0x14,0x00,0x14,0x00,0xcf,0x86,0xd5,0x2c,0xd4,0x08,0x13,
+       0x04,0x0d,0x00,0x00,0x00,0xd3,0x18,0xd2,0x0c,0x51,0x04,0x0b,0xe6,0x10,0x04,0x0b,
+       0xe6,0x0b,0x00,0x91,0x08,0x10,0x04,0x0b,0x01,0x0b,0xdc,0x0b,0xdc,0x92,0x08,0x11,
+       0x04,0x0b,0xdc,0x0b,0xe6,0x0b,0xdc,0xd4,0x28,0xd3,0x10,0x92,0x0c,0x91,0x08,0x10,
+       0x04,0x0b,0xe6,0x0b,0x00,0x0b,0x01,0x0b,0x01,0xd2,0x0c,0x91,0x08,0x10,0x04,0x0b,
+       0x01,0x0b,0x00,0x0b,0x00,0x91,0x08,0x10,0x04,0x0b,0x00,0x0b,0xdc,0x0b,0x00,0xd3,
+       0x1c,0xd2,0x0c,0x51,0x04,0x0b,0x00,0x10,0x04,0x0b,0x00,0x0d,0x00,0xd1,0x08,0x10,
+       0x04,0x0d,0xe6,0x0d,0x00,0x10,0x04,0x0d,0x00,0x13,0x00,0x92,0x0c,0x51,0x04,0x10,
+       0xe6,0x10,0x04,0x15,0x00,0x00,0x00,0x00,0x00,0xd1,0x1c,0xd0,0x06,0xcf,0x06,0x07,
+       0x00,0xcf,0x86,0x55,0x04,0x07,0x00,0x94,0x0c,0x53,0x04,0x07,0x00,0x12,0x04,0x07,
+       0x00,0x08,0x00,0x08,0x00,0xd0,0x06,0xcf,0x06,0x08,0x00,0xcf,0x86,0xd5,0x40,0xd4,
+       0x2c,0xd3,0x10,0x92,0x0c,0x51,0x04,0x08,0xe6,0x10,0x04,0x08,0xdc,0x08,0xe6,0x09,
+       0xe6,0xd2,0x0c,0x51,0x04,0x09,0xe6,0x10,0x04,0x09,0xdc,0x0a,0xe6,0xd1,0x08,0x10,
+       0x04,0x0a,0xe6,0x0a,0xea,0x10,0x04,0x0a,0xd6,0x0a,0xdc,0x93,0x10,0x92,0x0c,0x91,
+       0x08,0x10,0x04,0x0a,0xca,0x0a,0xe6,0x0a,0xe6,0x0a,0xe6,0x0a,0xe6,0xd4,0x14,0x93,
+       0x10,0x52,0x04,0x0a,0xe6,0x51,0x04,0x0a,0xe6,0x10,0x04,0x0a,0xe6,0x10,0xe6,0x10,
+       0xe6,0xd3,0x10,0x52,0x04,0x10,0xe6,0x51,0x04,0x10,0xe6,0x10,0x04,0x13,0xe8,0x13,
+       0xe4,0xd2,0x10,0xd1,0x08,0x10,0x04,0x13,0xe4,0x13,0xdc,0x10,0x04,0x00,0x00,0x12,
+       0xe6,0xd1,0x08,0x10,0x04,0x0c,0xe9,0x0b,0xdc,0x10,0x04,0x09,0xe6,0x09,0xdc,0xe2,
+       0x80,0x08,0xe1,0x48,0x04,0xe0,0x1c,0x02,0xcf,0x86,0xe5,0x11,0x01,0xd4,0x84,0xd3,
+       0x40,0xd2,0x20,0xd1,0x10,0x10,0x08,0x01,0xff,0x41,0xcc,0xa5,0x00,0x01,0xff,0x61,
+       0xcc,0xa5,0x00,0x10,0x08,0x01,0xff,0x42,0xcc,0x87,0x00,0x01,0xff,0x62,0xcc,0x87,
+       0x00,0xd1,0x10,0x10,0x08,0x01,0xff,0x42,0xcc,0xa3,0x00,0x01,0xff,0x62,0xcc,0xa3,
+       0x00,0x10,0x08,0x01,0xff,0x42,0xcc,0xb1,0x00,0x01,0xff,0x62,0xcc,0xb1,0x00,0xd2,
+       0x24,0xd1,0x14,0x10,0x0a,0x01,0xff,0x43,0xcc,0xa7,0xcc,0x81,0x00,0x01,0xff,0x63,
+       0xcc,0xa7,0xcc,0x81,0x00,0x10,0x08,0x01,0xff,0x44,0xcc,0x87,0x00,0x01,0xff,0x64,
+       0xcc,0x87,0x00,0xd1,0x10,0x10,0x08,0x01,0xff,0x44,0xcc,0xa3,0x00,0x01,0xff,0x64,
+       0xcc,0xa3,0x00,0x10,0x08,0x01,0xff,0x44,0xcc,0xb1,0x00,0x01,0xff,0x64,0xcc,0xb1,
+       0x00,0xd3,0x48,0xd2,0x20,0xd1,0x10,0x10,0x08,0x01,0xff,0x44,0xcc,0xa7,0x00,0x01,
+       0xff,0x64,0xcc,0xa7,0x00,0x10,0x08,0x01,0xff,0x44,0xcc,0xad,0x00,0x01,0xff,0x64,
+       0xcc,0xad,0x00,0xd1,0x14,0x10,0x0a,0x01,0xff,0x45,0xcc,0x84,0xcc,0x80,0x00,0x01,
+       0xff,0x65,0xcc,0x84,0xcc,0x80,0x00,0x10,0x0a,0x01,0xff,0x45,0xcc,0x84,0xcc,0x81,
+       0x00,0x01,0xff,0x65,0xcc,0x84,0xcc,0x81,0x00,0xd2,0x20,0xd1,0x10,0x10,0x08,0x01,
+       0xff,0x45,0xcc,0xad,0x00,0x01,0xff,0x65,0xcc,0xad,0x00,0x10,0x08,0x01,0xff,0x45,
+       0xcc,0xb0,0x00,0x01,0xff,0x65,0xcc,0xb0,0x00,0xd1,0x14,0x10,0x0a,0x01,0xff,0x45,
+       0xcc,0xa7,0xcc,0x86,0x00,0x01,0xff,0x65,0xcc,0xa7,0xcc,0x86,0x00,0x10,0x08,0x01,
+       0xff,0x46,0xcc,0x87,0x00,0x01,0xff,0x66,0xcc,0x87,0x00,0xd4,0x84,0xd3,0x40,0xd2,
+       0x20,0xd1,0x10,0x10,0x08,0x01,0xff,0x47,0xcc,0x84,0x00,0x01,0xff,0x67,0xcc,0x84,
+       0x00,0x10,0x08,0x01,0xff,0x48,0xcc,0x87,0x00,0x01,0xff,0x68,0xcc,0x87,0x00,0xd1,
+       0x10,0x10,0x08,0x01,0xff,0x48,0xcc,0xa3,0x00,0x01,0xff,0x68,0xcc,0xa3,0x00,0x10,
+       0x08,0x01,0xff,0x48,0xcc,0x88,0x00,0x01,0xff,0x68,0xcc,0x88,0x00,0xd2,0x20,0xd1,
+       0x10,0x10,0x08,0x01,0xff,0x48,0xcc,0xa7,0x00,0x01,0xff,0x68,0xcc,0xa7,0x00,0x10,
+       0x08,0x01,0xff,0x48,0xcc,0xae,0x00,0x01,0xff,0x68,0xcc,0xae,0x00,0xd1,0x10,0x10,
+       0x08,0x01,0xff,0x49,0xcc,0xb0,0x00,0x01,0xff,0x69,0xcc,0xb0,0x00,0x10,0x0a,0x01,
+       0xff,0x49,0xcc,0x88,0xcc,0x81,0x00,0x01,0xff,0x69,0xcc,0x88,0xcc,0x81,0x00,0xd3,
+       0x40,0xd2,0x20,0xd1,0x10,0x10,0x08,0x01,0xff,0x4b,0xcc,0x81,0x00,0x01,0xff,0x6b,
+       0xcc,0x81,0x00,0x10,0x08,0x01,0xff,0x4b,0xcc,0xa3,0x00,0x01,0xff,0x6b,0xcc,0xa3,
+       0x00,0xd1,0x10,0x10,0x08,0x01,0xff,0x4b,0xcc,0xb1,0x00,0x01,0xff,0x6b,0xcc,0xb1,
+       0x00,0x10,0x08,0x01,0xff,0x4c,0xcc,0xa3,0x00,0x01,0xff,0x6c,0xcc,0xa3,0x00,0xd2,
+       0x24,0xd1,0x14,0x10,0x0a,0x01,0xff,0x4c,0xcc,0xa3,0xcc,0x84,0x00,0x01,0xff,0x6c,
+       0xcc,0xa3,0xcc,0x84,0x00,0x10,0x08,0x01,0xff,0x4c,0xcc,0xb1,0x00,0x01,0xff,0x6c,
+       0xcc,0xb1,0x00,0xd1,0x10,0x10,0x08,0x01,0xff,0x4c,0xcc,0xad,0x00,0x01,0xff,0x6c,
+       0xcc,0xad,0x00,0x10,0x08,0x01,0xff,0x4d,0xcc,0x81,0x00,0x01,0xff,0x6d,0xcc,0x81,
+       0x00,0xcf,0x86,0xe5,0x15,0x01,0xd4,0x88,0xd3,0x40,0xd2,0x20,0xd1,0x10,0x10,0x08,
+       0x01,0xff,0x4d,0xcc,0x87,0x00,0x01,0xff,0x6d,0xcc,0x87,0x00,0x10,0x08,0x01,0xff,
+       0x4d,0xcc,0xa3,0x00,0x01,0xff,0x6d,0xcc,0xa3,0x00,0xd1,0x10,0x10,0x08,0x01,0xff,
+       0x4e,0xcc,0x87,0x00,0x01,0xff,0x6e,0xcc,0x87,0x00,0x10,0x08,0x01,0xff,0x4e,0xcc,
+       0xa3,0x00,0x01,0xff,0x6e,0xcc,0xa3,0x00,0xd2,0x20,0xd1,0x10,0x10,0x08,0x01,0xff,
+       0x4e,0xcc,0xb1,0x00,0x01,0xff,0x6e,0xcc,0xb1,0x00,0x10,0x08,0x01,0xff,0x4e,0xcc,
+       0xad,0x00,0x01,0xff,0x6e,0xcc,0xad,0x00,0xd1,0x14,0x10,0x0a,0x01,0xff,0x4f,0xcc,
+       0x83,0xcc,0x81,0x00,0x01,0xff,0x6f,0xcc,0x83,0xcc,0x81,0x00,0x10,0x0a,0x01,0xff,
+       0x4f,0xcc,0x83,0xcc,0x88,0x00,0x01,0xff,0x6f,0xcc,0x83,0xcc,0x88,0x00,0xd3,0x48,
+       0xd2,0x28,0xd1,0x14,0x10,0x0a,0x01,0xff,0x4f,0xcc,0x84,0xcc,0x80,0x00,0x01,0xff,
+       0x6f,0xcc,0x84,0xcc,0x80,0x00,0x10,0x0a,0x01,0xff,0x4f,0xcc,0x84,0xcc,0x81,0x00,
+       0x01,0xff,0x6f,0xcc,0x84,0xcc,0x81,0x00,0xd1,0x10,0x10,0x08,0x01,0xff,0x50,0xcc,
+       0x81,0x00,0x01,0xff,0x70,0xcc,0x81,0x00,0x10,0x08,0x01,0xff,0x50,0xcc,0x87,0x00,
+       0x01,0xff,0x70,0xcc,0x87,0x00,0xd2,0x20,0xd1,0x10,0x10,0x08,0x01,0xff,0x52,0xcc,
+       0x87,0x00,0x01,0xff,0x72,0xcc,0x87,0x00,0x10,0x08,0x01,0xff,0x52,0xcc,0xa3,0x00,
+       0x01,0xff,0x72,0xcc,0xa3,0x00,0xd1,0x14,0x10,0x0a,0x01,0xff,0x52,0xcc,0xa3,0xcc,
+       0x84,0x00,0x01,0xff,0x72,0xcc,0xa3,0xcc,0x84,0x00,0x10,0x08,0x01,0xff,0x52,0xcc,
+       0xb1,0x00,0x01,0xff,0x72,0xcc,0xb1,0x00,0xd4,0x8c,0xd3,0x48,0xd2,0x20,0xd1,0x10,
+       0x10,0x08,0x01,0xff,0x53,0xcc,0x87,0x00,0x01,0xff,0x73,0xcc,0x87,0x00,0x10,0x08,
+       0x01,0xff,0x53,0xcc,0xa3,0x00,0x01,0xff,0x73,0xcc,0xa3,0x00,0xd1,0x14,0x10,0x0a,
+       0x01,0xff,0x53,0xcc,0x81,0xcc,0x87,0x00,0x01,0xff,0x73,0xcc,0x81,0xcc,0x87,0x00,
+       0x10,0x0a,0x01,0xff,0x53,0xcc,0x8c,0xcc,0x87,0x00,0x01,0xff,0x73,0xcc,0x8c,0xcc,
+       0x87,0x00,0xd2,0x24,0xd1,0x14,0x10,0x0a,0x01,0xff,0x53,0xcc,0xa3,0xcc,0x87,0x00,
+       0x01,0xff,0x73,0xcc,0xa3,0xcc,0x87,0x00,0x10,0x08,0x01,0xff,0x54,0xcc,0x87,0x00,
+       0x01,0xff,0x74,0xcc,0x87,0x00,0xd1,0x10,0x10,0x08,0x01,0xff,0x54,0xcc,0xa3,0x00,
+       0x01,0xff,0x74,0xcc,0xa3,0x00,0x10,0x08,0x01,0xff,0x54,0xcc,0xb1,0x00,0x01,0xff,
+       0x74,0xcc,0xb1,0x00,0xd3,0x40,0xd2,0x20,0xd1,0x10,0x10,0x08,0x01,0xff,0x54,0xcc,
+       0xad,0x00,0x01,0xff,0x74,0xcc,0xad,0x00,0x10,0x08,0x01,0xff,0x55,0xcc,0xa4,0x00,
+       0x01,0xff,0x75,0xcc,0xa4,0x00,0xd1,0x10,0x10,0x08,0x01,0xff,0x55,0xcc,0xb0,0x00,
+       0x01,0xff,0x75,0xcc,0xb0,0x00,0x10,0x08,0x01,0xff,0x55,0xcc,0xad,0x00,0x01,0xff,
+       0x75,0xcc,0xad,0x00,0xd2,0x28,0xd1,0x14,0x10,0x0a,0x01,0xff,0x55,0xcc,0x83,0xcc,
+       0x81,0x00,0x01,0xff,0x75,0xcc,0x83,0xcc,0x81,0x00,0x10,0x0a,0x01,0xff,0x55,0xcc,
+       0x84,0xcc,0x88,0x00,0x01,0xff,0x75,0xcc,0x84,0xcc,0x88,0x00,0xd1,0x10,0x10,0x08,
+       0x01,0xff,0x56,0xcc,0x83,0x00,0x01,0xff,0x76,0xcc,0x83,0x00,0x10,0x08,0x01,0xff,
+       0x56,0xcc,0xa3,0x00,0x01,0xff,0x76,0xcc,0xa3,0x00,0xe0,0x10,0x02,0xcf,0x86,0xd5,
+       0xe1,0xd4,0x80,0xd3,0x40,0xd2,0x20,0xd1,0x10,0x10,0x08,0x01,0xff,0x57,0xcc,0x80,
+       0x00,0x01,0xff,0x77,0xcc,0x80,0x00,0x10,0x08,0x01,0xff,0x57,0xcc,0x81,0x00,0x01,
+       0xff,0x77,0xcc,0x81,0x00,0xd1,0x10,0x10,0x08,0x01,0xff,0x57,0xcc,0x88,0x00,0x01,
+       0xff,0x77,0xcc,0x88,0x00,0x10,0x08,0x01,0xff,0x57,0xcc,0x87,0x00,0x01,0xff,0x77,
+       0xcc,0x87,0x00,0xd2,0x20,0xd1,0x10,0x10,0x08,0x01,0xff,0x57,0xcc,0xa3,0x00,0x01,
+       0xff,0x77,0xcc,0xa3,0x00,0x10,0x08,0x01,0xff,0x58,0xcc,0x87,0x00,0x01,0xff,0x78,
+       0xcc,0x87,0x00,0xd1,0x10,0x10,0x08,0x01,0xff,0x58,0xcc,0x88,0x00,0x01,0xff,0x78,
+       0xcc,0x88,0x00,0x10,0x08,0x01,0xff,0x59,0xcc,0x87,0x00,0x01,0xff,0x79,0xcc,0x87,
+       0x00,0xd3,0x40,0xd2,0x20,0xd1,0x10,0x10,0x08,0x01,0xff,0x5a,0xcc,0x82,0x00,0x01,
+       0xff,0x7a,0xcc,0x82,0x00,0x10,0x08,0x01,0xff,0x5a,0xcc,0xa3,0x00,0x01,0xff,0x7a,
+       0xcc,0xa3,0x00,0xd1,0x10,0x10,0x08,0x01,0xff,0x5a,0xcc,0xb1,0x00,0x01,0xff,0x7a,
+       0xcc,0xb1,0x00,0x10,0x08,0x01,0xff,0x68,0xcc,0xb1,0x00,0x01,0xff,0x74,0xcc,0x88,
+       0x00,0x92,0x1d,0xd1,0x10,0x10,0x08,0x01,0xff,0x77,0xcc,0x8a,0x00,0x01,0xff,0x79,
+       0xcc,0x8a,0x00,0x10,0x04,0x01,0x00,0x02,0xff,0xc5,0xbf,0xcc,0x87,0x00,0x0a,0x00,
+       0xd4,0x98,0xd3,0x48,0xd2,0x20,0xd1,0x10,0x10,0x08,0x01,0xff,0x41,0xcc,0xa3,0x00,
+       0x01,0xff,0x61,0xcc,0xa3,0x00,0x10,0x08,0x01,0xff,0x41,0xcc,0x89,0x00,0x01,0xff,
+       0x61,0xcc,0x89,0x00,0xd1,0x14,0x10,0x0a,0x01,0xff,0x41,0xcc,0x82,0xcc,0x81,0x00,
+       0x01,0xff,0x61,0xcc,0x82,0xcc,0x81,0x00,0x10,0x0a,0x01,0xff,0x41,0xcc,0x82,0xcc,
+       0x80,0x00,0x01,0xff,0x61,0xcc,0x82,0xcc,0x80,0x00,0xd2,0x28,0xd1,0x14,0x10,0x0a,
+       0x01,0xff,0x41,0xcc,0x82,0xcc,0x89,0x00,0x01,0xff,0x61,0xcc,0x82,0xcc,0x89,0x00,
+       0x10,0x0a,0x01,0xff,0x41,0xcc,0x82,0xcc,0x83,0x00,0x01,0xff,0x61,0xcc,0x82,0xcc,
+       0x83,0x00,0xd1,0x14,0x10,0x0a,0x01,0xff,0x41,0xcc,0xa3,0xcc,0x82,0x00,0x01,0xff,
+       0x61,0xcc,0xa3,0xcc,0x82,0x00,0x10,0x0a,0x01,0xff,0x41,0xcc,0x86,0xcc,0x81,0x00,
+       0x01,0xff,0x61,0xcc,0x86,0xcc,0x81,0x00,0xd3,0x50,0xd2,0x28,0xd1,0x14,0x10,0x0a,
+       0x01,0xff,0x41,0xcc,0x86,0xcc,0x80,0x00,0x01,0xff,0x61,0xcc,0x86,0xcc,0x80,0x00,
+       0x10,0x0a,0x01,0xff,0x41,0xcc,0x86,0xcc,0x89,0x00,0x01,0xff,0x61,0xcc,0x86,0xcc,
+       0x89,0x00,0xd1,0x14,0x10,0x0a,0x01,0xff,0x41,0xcc,0x86,0xcc,0x83,0x00,0x01,0xff,
+       0x61,0xcc,0x86,0xcc,0x83,0x00,0x10,0x0a,0x01,0xff,0x41,0xcc,0xa3,0xcc,0x86,0x00,
+       0x01,0xff,0x61,0xcc,0xa3,0xcc,0x86,0x00,0xd2,0x20,0xd1,0x10,0x10,0x08,0x01,0xff,
+       0x45,0xcc,0xa3,0x00,0x01,0xff,0x65,0xcc,0xa3,0x00,0x10,0x08,0x01,0xff,0x45,0xcc,
+       0x89,0x00,0x01,0xff,0x65,0xcc,0x89,0x00,0xd1,0x10,0x10,0x08,0x01,0xff,0x45,0xcc,
+       0x83,0x00,0x01,0xff,0x65,0xcc,0x83,0x00,0x10,0x0a,0x01,0xff,0x45,0xcc,0x82,0xcc,
+       0x81,0x00,0x01,0xff,0x65,0xcc,0x82,0xcc,0x81,0x00,0xcf,0x86,0xe5,0x31,0x01,0xd4,
+       0x90,0xd3,0x50,0xd2,0x28,0xd1,0x14,0x10,0x0a,0x01,0xff,0x45,0xcc,0x82,0xcc,0x80,
+       0x00,0x01,0xff,0x65,0xcc,0x82,0xcc,0x80,0x00,0x10,0x0a,0x01,0xff,0x45,0xcc,0x82,
+       0xcc,0x89,0x00,0x01,0xff,0x65,0xcc,0x82,0xcc,0x89,0x00,0xd1,0x14,0x10,0x0a,0x01,
+       0xff,0x45,0xcc,0x82,0xcc,0x83,0x00,0x01,0xff,0x65,0xcc,0x82,0xcc,0x83,0x00,0x10,
+       0x0a,0x01,0xff,0x45,0xcc,0xa3,0xcc,0x82,0x00,0x01,0xff,0x65,0xcc,0xa3,0xcc,0x82,
+       0x00,0xd2,0x20,0xd1,0x10,0x10,0x08,0x01,0xff,0x49,0xcc,0x89,0x00,0x01,0xff,0x69,
+       0xcc,0x89,0x00,0x10,0x08,0x01,0xff,0x49,0xcc,0xa3,0x00,0x01,0xff,0x69,0xcc,0xa3,
+       0x00,0xd1,0x10,0x10,0x08,0x01,0xff,0x4f,0xcc,0xa3,0x00,0x01,0xff,0x6f,0xcc,0xa3,
+       0x00,0x10,0x08,0x01,0xff,0x4f,0xcc,0x89,0x00,0x01,0xff,0x6f,0xcc,0x89,0x00,0xd3,
+       0x50,0xd2,0x28,0xd1,0x14,0x10,0x0a,0x01,0xff,0x4f,0xcc,0x82,0xcc,0x81,0x00,0x01,
+       0xff,0x6f,0xcc,0x82,0xcc,0x81,0x00,0x10,0x0a,0x01,0xff,0x4f,0xcc,0x82,0xcc,0x80,
+       0x00,0x01,0xff,0x6f,0xcc,0x82,0xcc,0x80,0x00,0xd1,0x14,0x10,0x0a,0x01,0xff,0x4f,
+       0xcc,0x82,0xcc,0x89,0x00,0x01,0xff,0x6f,0xcc,0x82,0xcc,0x89,0x00,0x10,0x0a,0x01,
+       0xff,0x4f,0xcc,0x82,0xcc,0x83,0x00,0x01,0xff,0x6f,0xcc,0x82,0xcc,0x83,0x00,0xd2,
+       0x28,0xd1,0x14,0x10,0x0a,0x01,0xff,0x4f,0xcc,0xa3,0xcc,0x82,0x00,0x01,0xff,0x6f,
+       0xcc,0xa3,0xcc,0x82,0x00,0x10,0x0a,0x01,0xff,0x4f,0xcc,0x9b,0xcc,0x81,0x00,0x01,
+       0xff,0x6f,0xcc,0x9b,0xcc,0x81,0x00,0xd1,0x14,0x10,0x0a,0x01,0xff,0x4f,0xcc,0x9b,
+       0xcc,0x80,0x00,0x01,0xff,0x6f,0xcc,0x9b,0xcc,0x80,0x00,0x10,0x0a,0x01,0xff,0x4f,
+       0xcc,0x9b,0xcc,0x89,0x00,0x01,0xff,0x6f,0xcc,0x9b,0xcc,0x89,0x00,0xd4,0x98,0xd3,
+       0x48,0xd2,0x28,0xd1,0x14,0x10,0x0a,0x01,0xff,0x4f,0xcc,0x9b,0xcc,0x83,0x00,0x01,
+       0xff,0x6f,0xcc,0x9b,0xcc,0x83,0x00,0x10,0x0a,0x01,0xff,0x4f,0xcc,0x9b,0xcc,0xa3,
+       0x00,0x01,0xff,0x6f,0xcc,0x9b,0xcc,0xa3,0x00,0xd1,0x10,0x10,0x08,0x01,0xff,0x55,
+       0xcc,0xa3,0x00,0x01,0xff,0x75,0xcc,0xa3,0x00,0x10,0x08,0x01,0xff,0x55,0xcc,0x89,
+       0x00,0x01,0xff,0x75,0xcc,0x89,0x00,0xd2,0x28,0xd1,0x14,0x10,0x0a,0x01,0xff,0x55,
+       0xcc,0x9b,0xcc,0x81,0x00,0x01,0xff,0x75,0xcc,0x9b,0xcc,0x81,0x00,0x10,0x0a,0x01,
+       0xff,0x55,0xcc,0x9b,0xcc,0x80,0x00,0x01,0xff,0x75,0xcc,0x9b,0xcc,0x80,0x00,0xd1,
+       0x14,0x10,0x0a,0x01,0xff,0x55,0xcc,0x9b,0xcc,0x89,0x00,0x01,0xff,0x75,0xcc,0x9b,
+       0xcc,0x89,0x00,0x10,0x0a,0x01,0xff,0x55,0xcc,0x9b,0xcc,0x83,0x00,0x01,0xff,0x75,
+       0xcc,0x9b,0xcc,0x83,0x00,0xd3,0x44,0xd2,0x24,0xd1,0x14,0x10,0x0a,0x01,0xff,0x55,
+       0xcc,0x9b,0xcc,0xa3,0x00,0x01,0xff,0x75,0xcc,0x9b,0xcc,0xa3,0x00,0x10,0x08,0x01,
+       0xff,0x59,0xcc,0x80,0x00,0x01,0xff,0x79,0xcc,0x80,0x00,0xd1,0x10,0x10,0x08,0x01,
+       0xff,0x59,0xcc,0xa3,0x00,0x01,0xff,0x79,0xcc,0xa3,0x00,0x10,0x08,0x01,0xff,0x59,
+       0xcc,0x89,0x00,0x01,0xff,0x79,0xcc,0x89,0x00,0x92,0x14,0x91,0x10,0x10,0x08,0x01,
+       0xff,0x59,0xcc,0x83,0x00,0x01,0xff,0x79,0xcc,0x83,0x00,0x0a,0x00,0x0a,0x00,0xe1,
+       0xc0,0x04,0xe0,0x80,0x02,0xcf,0x86,0xe5,0x2d,0x01,0xd4,0xa8,0xd3,0x54,0xd2,0x28,
+       0xd1,0x12,0x10,0x09,0x01,0xff,0xce,0xb1,0xcc,0x93,0x00,0x01,0xff,0xce,0xb1,0xcc,
+       0x94,0x00,0x10,0x0b,0x01,0xff,0xce,0xb1,0xcc,0x93,0xcc,0x80,0x00,0x01,0xff,0xce,
+       0xb1,0xcc,0x94,0xcc,0x80,0x00,0xd1,0x16,0x10,0x0b,0x01,0xff,0xce,0xb1,0xcc,0x93,
+       0xcc,0x81,0x00,0x01,0xff,0xce,0xb1,0xcc,0x94,0xcc,0x81,0x00,0x10,0x0b,0x01,0xff,
+       0xce,0xb1,0xcc,0x93,0xcd,0x82,0x00,0x01,0xff,0xce,0xb1,0xcc,0x94,0xcd,0x82,0x00,
+       0xd2,0x28,0xd1,0x12,0x10,0x09,0x01,0xff,0xce,0x91,0xcc,0x93,0x00,0x01,0xff,0xce,
+       0x91,0xcc,0x94,0x00,0x10,0x0b,0x01,0xff,0xce,0x91,0xcc,0x93,0xcc,0x80,0x00,0x01,
+       0xff,0xce,0x91,0xcc,0x94,0xcc,0x80,0x00,0xd1,0x16,0x10,0x0b,0x01,0xff,0xce,0x91,
+       0xcc,0x93,0xcc,0x81,0x00,0x01,0xff,0xce,0x91,0xcc,0x94,0xcc,0x81,0x00,0x10,0x0b,
+       0x01,0xff,0xce,0x91,0xcc,0x93,0xcd,0x82,0x00,0x01,0xff,0xce,0x91,0xcc,0x94,0xcd,
+       0x82,0x00,0xd3,0x42,0xd2,0x28,0xd1,0x12,0x10,0x09,0x01,0xff,0xce,0xb5,0xcc,0x93,
+       0x00,0x01,0xff,0xce,0xb5,0xcc,0x94,0x00,0x10,0x0b,0x01,0xff,0xce,0xb5,0xcc,0x93,
+       0xcc,0x80,0x00,0x01,0xff,0xce,0xb5,0xcc,0x94,0xcc,0x80,0x00,0x91,0x16,0x10,0x0b,
+       0x01,0xff,0xce,0xb5,0xcc,0x93,0xcc,0x81,0x00,0x01,0xff,0xce,0xb5,0xcc,0x94,0xcc,
+       0x81,0x00,0x00,0x00,0xd2,0x28,0xd1,0x12,0x10,0x09,0x01,0xff,0xce,0x95,0xcc,0x93,
+       0x00,0x01,0xff,0xce,0x95,0xcc,0x94,0x00,0x10,0x0b,0x01,0xff,0xce,0x95,0xcc,0x93,
+       0xcc,0x80,0x00,0x01,0xff,0xce,0x95,0xcc,0x94,0xcc,0x80,0x00,0x91,0x16,0x10,0x0b,
+       0x01,0xff,0xce,0x95,0xcc,0x93,0xcc,0x81,0x00,0x01,0xff,0xce,0x95,0xcc,0x94,0xcc,
+       0x81,0x00,0x00,0x00,0xd4,0xa8,0xd3,0x54,0xd2,0x28,0xd1,0x12,0x10,0x09,0x01,0xff,
+       0xce,0xb7,0xcc,0x93,0x00,0x01,0xff,0xce,0xb7,0xcc,0x94,0x00,0x10,0x0b,0x01,0xff,
+       0xce,0xb7,0xcc,0x93,0xcc,0x80,0x00,0x01,0xff,0xce,0xb7,0xcc,0x94,0xcc,0x80,0x00,
+       0xd1,0x16,0x10,0x0b,0x01,0xff,0xce,0xb7,0xcc,0x93,0xcc,0x81,0x00,0x01,0xff,0xce,
+       0xb7,0xcc,0x94,0xcc,0x81,0x00,0x10,0x0b,0x01,0xff,0xce,0xb7,0xcc,0x93,0xcd,0x82,
+       0x00,0x01,0xff,0xce,0xb7,0xcc,0x94,0xcd,0x82,0x00,0xd2,0x28,0xd1,0x12,0x10,0x09,
+       0x01,0xff,0xce,0x97,0xcc,0x93,0x00,0x01,0xff,0xce,0x97,0xcc,0x94,0x00,0x10,0x0b,
+       0x01,0xff,0xce,0x97,0xcc,0x93,0xcc,0x80,0x00,0x01,0xff,0xce,0x97,0xcc,0x94,0xcc,
+       0x80,0x00,0xd1,0x16,0x10,0x0b,0x01,0xff,0xce,0x97,0xcc,0x93,0xcc,0x81,0x00,0x01,
+       0xff,0xce,0x97,0xcc,0x94,0xcc,0x81,0x00,0x10,0x0b,0x01,0xff,0xce,0x97,0xcc,0x93,
+       0xcd,0x82,0x00,0x01,0xff,0xce,0x97,0xcc,0x94,0xcd,0x82,0x00,0xd3,0x54,0xd2,0x28,
+       0xd1,0x12,0x10,0x09,0x01,0xff,0xce,0xb9,0xcc,0x93,0x00,0x01,0xff,0xce,0xb9,0xcc,
+       0x94,0x00,0x10,0x0b,0x01,0xff,0xce,0xb9,0xcc,0x93,0xcc,0x80,0x00,0x01,0xff,0xce,
+       0xb9,0xcc,0x94,0xcc,0x80,0x00,0xd1,0x16,0x10,0x0b,0x01,0xff,0xce,0xb9,0xcc,0x93,
+       0xcc,0x81,0x00,0x01,0xff,0xce,0xb9,0xcc,0x94,0xcc,0x81,0x00,0x10,0x0b,0x01,0xff,
+       0xce,0xb9,0xcc,0x93,0xcd,0x82,0x00,0x01,0xff,0xce,0xb9,0xcc,0x94,0xcd,0x82,0x00,
+       0xd2,0x28,0xd1,0x12,0x10,0x09,0x01,0xff,0xce,0x99,0xcc,0x93,0x00,0x01,0xff,0xce,
+       0x99,0xcc,0x94,0x00,0x10,0x0b,0x01,0xff,0xce,0x99,0xcc,0x93,0xcc,0x80,0x00,0x01,
+       0xff,0xce,0x99,0xcc,0x94,0xcc,0x80,0x00,0xd1,0x16,0x10,0x0b,0x01,0xff,0xce,0x99,
+       0xcc,0x93,0xcc,0x81,0x00,0x01,0xff,0xce,0x99,0xcc,0x94,0xcc,0x81,0x00,0x10,0x0b,
+       0x01,0xff,0xce,0x99,0xcc,0x93,0xcd,0x82,0x00,0x01,0xff,0xce,0x99,0xcc,0x94,0xcd,
+       0x82,0x00,0xcf,0x86,0xe5,0x13,0x01,0xd4,0x84,0xd3,0x42,0xd2,0x28,0xd1,0x12,0x10,
+       0x09,0x01,0xff,0xce,0xbf,0xcc,0x93,0x00,0x01,0xff,0xce,0xbf,0xcc,0x94,0x00,0x10,
+       0x0b,0x01,0xff,0xce,0xbf,0xcc,0x93,0xcc,0x80,0x00,0x01,0xff,0xce,0xbf,0xcc,0x94,
+       0xcc,0x80,0x00,0x91,0x16,0x10,0x0b,0x01,0xff,0xce,0xbf,0xcc,0x93,0xcc,0x81,0x00,
+       0x01,0xff,0xce,0xbf,0xcc,0x94,0xcc,0x81,0x00,0x00,0x00,0xd2,0x28,0xd1,0x12,0x10,
+       0x09,0x01,0xff,0xce,0x9f,0xcc,0x93,0x00,0x01,0xff,0xce,0x9f,0xcc,0x94,0x00,0x10,
+       0x0b,0x01,0xff,0xce,0x9f,0xcc,0x93,0xcc,0x80,0x00,0x01,0xff,0xce,0x9f,0xcc,0x94,
+       0xcc,0x80,0x00,0x91,0x16,0x10,0x0b,0x01,0xff,0xce,0x9f,0xcc,0x93,0xcc,0x81,0x00,
+       0x01,0xff,0xce,0x9f,0xcc,0x94,0xcc,0x81,0x00,0x00,0x00,0xd3,0x54,0xd2,0x28,0xd1,
+       0x12,0x10,0x09,0x01,0xff,0xcf,0x85,0xcc,0x93,0x00,0x01,0xff,0xcf,0x85,0xcc,0x94,
+       0x00,0x10,0x0b,0x01,0xff,0xcf,0x85,0xcc,0x93,0xcc,0x80,0x00,0x01,0xff,0xcf,0x85,
+       0xcc,0x94,0xcc,0x80,0x00,0xd1,0x16,0x10,0x0b,0x01,0xff,0xcf,0x85,0xcc,0x93,0xcc,
+       0x81,0x00,0x01,0xff,0xcf,0x85,0xcc,0x94,0xcc,0x81,0x00,0x10,0x0b,0x01,0xff,0xcf,
+       0x85,0xcc,0x93,0xcd,0x82,0x00,0x01,0xff,0xcf,0x85,0xcc,0x94,0xcd,0x82,0x00,0xd2,
+       0x1c,0xd1,0x0d,0x10,0x04,0x00,0x00,0x01,0xff,0xce,0xa5,0xcc,0x94,0x00,0x10,0x04,
+       0x00,0x00,0x01,0xff,0xce,0xa5,0xcc,0x94,0xcc,0x80,0x00,0xd1,0x0f,0x10,0x04,0x00,
+       0x00,0x01,0xff,0xce,0xa5,0xcc,0x94,0xcc,0x81,0x00,0x10,0x04,0x00,0x00,0x01,0xff,
+       0xce,0xa5,0xcc,0x94,0xcd,0x82,0x00,0xd4,0xa8,0xd3,0x54,0xd2,0x28,0xd1,0x12,0x10,
+       0x09,0x01,0xff,0xcf,0x89,0xcc,0x93,0x00,0x01,0xff,0xcf,0x89,0xcc,0x94,0x00,0x10,
+       0x0b,0x01,0xff,0xcf,0x89,0xcc,0x93,0xcc,0x80,0x00,0x01,0xff,0xcf,0x89,0xcc,0x94,
+       0xcc,0x80,0x00,0xd1,0x16,0x10,0x0b,0x01,0xff,0xcf,0x89,0xcc,0x93,0xcc,0x81,0x00,
+       0x01,0xff,0xcf,0x89,0xcc,0x94,0xcc,0x81,0x00,0x10,0x0b,0x01,0xff,0xcf,0x89,0xcc,
+       0x93,0xcd,0x82,0x00,0x01,0xff,0xcf,0x89,0xcc,0x94,0xcd,0x82,0x00,0xd2,0x28,0xd1,
+       0x12,0x10,0x09,0x01,0xff,0xce,0xa9,0xcc,0x93,0x00,0x01,0xff,0xce,0xa9,0xcc,0x94,
+       0x00,0x10,0x0b,0x01,0xff,0xce,0xa9,0xcc,0x93,0xcc,0x80,0x00,0x01,0xff,0xce,0xa9,
+       0xcc,0x94,0xcc,0x80,0x00,0xd1,0x16,0x10,0x0b,0x01,0xff,0xce,0xa9,0xcc,0x93,0xcc,
+       0x81,0x00,0x01,0xff,0xce,0xa9,0xcc,0x94,0xcc,0x81,0x00,0x10,0x0b,0x01,0xff,0xce,
+       0xa9,0xcc,0x93,0xcd,0x82,0x00,0x01,0xff,0xce,0xa9,0xcc,0x94,0xcd,0x82,0x00,0xd3,
+       0x48,0xd2,0x24,0xd1,0x12,0x10,0x09,0x01,0xff,0xce,0xb1,0xcc,0x80,0x00,0x01,0xff,
+       0xce,0xb1,0xcc,0x81,0x00,0x10,0x09,0x01,0xff,0xce,0xb5,0xcc,0x80,0x00,0x01,0xff,
+       0xce,0xb5,0xcc,0x81,0x00,0xd1,0x12,0x10,0x09,0x01,0xff,0xce,0xb7,0xcc,0x80,0x00,
+       0x01,0xff,0xce,0xb7,0xcc,0x81,0x00,0x10,0x09,0x01,0xff,0xce,0xb9,0xcc,0x80,0x00,
+       0x01,0xff,0xce,0xb9,0xcc,0x81,0x00,0xd2,0x24,0xd1,0x12,0x10,0x09,0x01,0xff,0xce,
+       0xbf,0xcc,0x80,0x00,0x01,0xff,0xce,0xbf,0xcc,0x81,0x00,0x10,0x09,0x01,0xff,0xcf,
+       0x85,0xcc,0x80,0x00,0x01,0xff,0xcf,0x85,0xcc,0x81,0x00,0x91,0x12,0x10,0x09,0x01,
+       0xff,0xcf,0x89,0xcc,0x80,0x00,0x01,0xff,0xcf,0x89,0xcc,0x81,0x00,0x00,0x00,0xe0,
+       0xe1,0x02,0xcf,0x86,0xe5,0x91,0x01,0xd4,0xc8,0xd3,0x64,0xd2,0x30,0xd1,0x16,0x10,
+       0x0b,0x01,0xff,0xce,0xb1,0xcc,0x93,0xcd,0x85,0x00,0x01,0xff,0xce,0xb1,0xcc,0x94,
+       0xcd,0x85,0x00,0x10,0x0d,0x01,0xff,0xce,0xb1,0xcc,0x93,0xcc,0x80,0xcd,0x85,0x00,
+       0x01,0xff,0xce,0xb1,0xcc,0x94,0xcc,0x80,0xcd,0x85,0x00,0xd1,0x1a,0x10,0x0d,0x01,
+       0xff,0xce,0xb1,0xcc,0x93,0xcc,0x81,0xcd,0x85,0x00,0x01,0xff,0xce,0xb1,0xcc,0x94,
+       0xcc,0x81,0xcd,0x85,0x00,0x10,0x0d,0x01,0xff,0xce,0xb1,0xcc,0x93,0xcd,0x82,0xcd,
+       0x85,0x00,0x01,0xff,0xce,0xb1,0xcc,0x94,0xcd,0x82,0xcd,0x85,0x00,0xd2,0x30,0xd1,
+       0x16,0x10,0x0b,0x01,0xff,0xce,0x91,0xcc,0x93,0xcd,0x85,0x00,0x01,0xff,0xce,0x91,
+       0xcc,0x94,0xcd,0x85,0x00,0x10,0x0d,0x01,0xff,0xce,0x91,0xcc,0x93,0xcc,0x80,0xcd,
+       0x85,0x00,0x01,0xff,0xce,0x91,0xcc,0x94,0xcc,0x80,0xcd,0x85,0x00,0xd1,0x1a,0x10,
+       0x0d,0x01,0xff,0xce,0x91,0xcc,0x93,0xcc,0x81,0xcd,0x85,0x00,0x01,0xff,0xce,0x91,
+       0xcc,0x94,0xcc,0x81,0xcd,0x85,0x00,0x10,0x0d,0x01,0xff,0xce,0x91,0xcc,0x93,0xcd,
+       0x82,0xcd,0x85,0x00,0x01,0xff,0xce,0x91,0xcc,0x94,0xcd,0x82,0xcd,0x85,0x00,0xd3,
+       0x64,0xd2,0x30,0xd1,0x16,0x10,0x0b,0x01,0xff,0xce,0xb7,0xcc,0x93,0xcd,0x85,0x00,
+       0x01,0xff,0xce,0xb7,0xcc,0x94,0xcd,0x85,0x00,0x10,0x0d,0x01,0xff,0xce,0xb7,0xcc,
+       0x93,0xcc,0x80,0xcd,0x85,0x00,0x01,0xff,0xce,0xb7,0xcc,0x94,0xcc,0x80,0xcd,0x85,
+       0x00,0xd1,0x1a,0x10,0x0d,0x01,0xff,0xce,0xb7,0xcc,0x93,0xcc,0x81,0xcd,0x85,0x00,
+       0x01,0xff,0xce,0xb7,0xcc,0x94,0xcc,0x81,0xcd,0x85,0x00,0x10,0x0d,0x01,0xff,0xce,
+       0xb7,0xcc,0x93,0xcd,0x82,0xcd,0x85,0x00,0x01,0xff,0xce,0xb7,0xcc,0x94,0xcd,0x82,
+       0xcd,0x85,0x00,0xd2,0x30,0xd1,0x16,0x10,0x0b,0x01,0xff,0xce,0x97,0xcc,0x93,0xcd,
+       0x85,0x00,0x01,0xff,0xce,0x97,0xcc,0x94,0xcd,0x85,0x00,0x10,0x0d,0x01,0xff,0xce,
+       0x97,0xcc,0x93,0xcc,0x80,0xcd,0x85,0x00,0x01,0xff,0xce,0x97,0xcc,0x94,0xcc,0x80,
+       0xcd,0x85,0x00,0xd1,0x1a,0x10,0x0d,0x01,0xff,0xce,0x97,0xcc,0x93,0xcc,0x81,0xcd,
+       0x85,0x00,0x01,0xff,0xce,0x97,0xcc,0x94,0xcc,0x81,0xcd,0x85,0x00,0x10,0x0d,0x01,
+       0xff,0xce,0x97,0xcc,0x93,0xcd,0x82,0xcd,0x85,0x00,0x01,0xff,0xce,0x97,0xcc,0x94,
+       0xcd,0x82,0xcd,0x85,0x00,0xd4,0xc8,0xd3,0x64,0xd2,0x30,0xd1,0x16,0x10,0x0b,0x01,
+       0xff,0xcf,0x89,0xcc,0x93,0xcd,0x85,0x00,0x01,0xff,0xcf,0x89,0xcc,0x94,0xcd,0x85,
+       0x00,0x10,0x0d,0x01,0xff,0xcf,0x89,0xcc,0x93,0xcc,0x80,0xcd,0x85,0x00,0x01,0xff,
+       0xcf,0x89,0xcc,0x94,0xcc,0x80,0xcd,0x85,0x00,0xd1,0x1a,0x10,0x0d,0x01,0xff,0xcf,
+       0x89,0xcc,0x93,0xcc,0x81,0xcd,0x85,0x00,0x01,0xff,0xcf,0x89,0xcc,0x94,0xcc,0x81,
+       0xcd,0x85,0x00,0x10,0x0d,0x01,0xff,0xcf,0x89,0xcc,0x93,0xcd,0x82,0xcd,0x85,0x00,
+       0x01,0xff,0xcf,0x89,0xcc,0x94,0xcd,0x82,0xcd,0x85,0x00,0xd2,0x30,0xd1,0x16,0x10,
+       0x0b,0x01,0xff,0xce,0xa9,0xcc,0x93,0xcd,0x85,0x00,0x01,0xff,0xce,0xa9,0xcc,0x94,
+       0xcd,0x85,0x00,0x10,0x0d,0x01,0xff,0xce,0xa9,0xcc,0x93,0xcc,0x80,0xcd,0x85,0x00,
+       0x01,0xff,0xce,0xa9,0xcc,0x94,0xcc,0x80,0xcd,0x85,0x00,0xd1,0x1a,0x10,0x0d,0x01,
+       0xff,0xce,0xa9,0xcc,0x93,0xcc,0x81,0xcd,0x85,0x00,0x01,0xff,0xce,0xa9,0xcc,0x94,
+       0xcc,0x81,0xcd,0x85,0x00,0x10,0x0d,0x01,0xff,0xce,0xa9,0xcc,0x93,0xcd,0x82,0xcd,
+       0x85,0x00,0x01,0xff,0xce,0xa9,0xcc,0x94,0xcd,0x82,0xcd,0x85,0x00,0xd3,0x49,0xd2,
+       0x26,0xd1,0x12,0x10,0x09,0x01,0xff,0xce,0xb1,0xcc,0x86,0x00,0x01,0xff,0xce,0xb1,
+       0xcc,0x84,0x00,0x10,0x0b,0x01,0xff,0xce,0xb1,0xcc,0x80,0xcd,0x85,0x00,0x01,0xff,
+       0xce,0xb1,0xcd,0x85,0x00,0xd1,0x0f,0x10,0x0b,0x01,0xff,0xce,0xb1,0xcc,0x81,0xcd,
+       0x85,0x00,0x00,0x00,0x10,0x09,0x01,0xff,0xce,0xb1,0xcd,0x82,0x00,0x01,0xff,0xce,
+       0xb1,0xcd,0x82,0xcd,0x85,0x00,0xd2,0x24,0xd1,0x12,0x10,0x09,0x01,0xff,0xce,0x91,
+       0xcc,0x86,0x00,0x01,0xff,0xce,0x91,0xcc,0x84,0x00,0x10,0x09,0x01,0xff,0xce,0x91,
+       0xcc,0x80,0x00,0x01,0xff,0xce,0x91,0xcc,0x81,0x00,0xd1,0x0d,0x10,0x09,0x01,0xff,
+       0xce,0x91,0xcd,0x85,0x00,0x01,0x00,0x10,0x07,0x01,0xff,0xce,0xb9,0x00,0x01,0x00,
+       0xcf,0x86,0xe5,0x16,0x01,0xd4,0x8f,0xd3,0x44,0xd2,0x21,0xd1,0x0d,0x10,0x04,0x01,
+       0x00,0x01,0xff,0xc2,0xa8,0xcd,0x82,0x00,0x10,0x0b,0x01,0xff,0xce,0xb7,0xcc,0x80,
+       0xcd,0x85,0x00,0x01,0xff,0xce,0xb7,0xcd,0x85,0x00,0xd1,0x0f,0x10,0x0b,0x01,0xff,
+       0xce,0xb7,0xcc,0x81,0xcd,0x85,0x00,0x00,0x00,0x10,0x09,0x01,0xff,0xce,0xb7,0xcd,
+       0x82,0x00,0x01,0xff,0xce,0xb7,0xcd,0x82,0xcd,0x85,0x00,0xd2,0x24,0xd1,0x12,0x10,
+       0x09,0x01,0xff,0xce,0x95,0xcc,0x80,0x00,0x01,0xff,0xce,0x95,0xcc,0x81,0x00,0x10,
+       0x09,0x01,0xff,0xce,0x97,0xcc,0x80,0x00,0x01,0xff,0xce,0x97,0xcc,0x81,0x00,0xd1,
+       0x13,0x10,0x09,0x01,0xff,0xce,0x97,0xcd,0x85,0x00,0x01,0xff,0xe1,0xbe,0xbf,0xcc,
+       0x80,0x00,0x10,0x0a,0x01,0xff,0xe1,0xbe,0xbf,0xcc,0x81,0x00,0x01,0xff,0xe1,0xbe,
+       0xbf,0xcd,0x82,0x00,0xd3,0x40,0xd2,0x28,0xd1,0x12,0x10,0x09,0x01,0xff,0xce,0xb9,
+       0xcc,0x86,0x00,0x01,0xff,0xce,0xb9,0xcc,0x84,0x00,0x10,0x0b,0x01,0xff,0xce,0xb9,
+       0xcc,0x88,0xcc,0x80,0x00,0x01,0xff,0xce,0xb9,0xcc,0x88,0xcc,0x81,0x00,0x51,0x04,
+       0x00,0x00,0x10,0x09,0x01,0xff,0xce,0xb9,0xcd,0x82,0x00,0x01,0xff,0xce,0xb9,0xcc,
+       0x88,0xcd,0x82,0x00,0xd2,0x24,0xd1,0x12,0x10,0x09,0x01,0xff,0xce,0x99,0xcc,0x86,
+       0x00,0x01,0xff,0xce,0x99,0xcc,0x84,0x00,0x10,0x09,0x01,0xff,0xce,0x99,0xcc,0x80,
+       0x00,0x01,0xff,0xce,0x99,0xcc,0x81,0x00,0xd1,0x0e,0x10,0x04,0x00,0x00,0x01,0xff,
+       0xe1,0xbf,0xbe,0xcc,0x80,0x00,0x10,0x0a,0x01,0xff,0xe1,0xbf,0xbe,0xcc,0x81,0x00,
+       0x01,0xff,0xe1,0xbf,0xbe,0xcd,0x82,0x00,0xd4,0x93,0xd3,0x4e,0xd2,0x28,0xd1,0x12,
+       0x10,0x09,0x01,0xff,0xcf,0x85,0xcc,0x86,0x00,0x01,0xff,0xcf,0x85,0xcc,0x84,0x00,
+       0x10,0x0b,0x01,0xff,0xcf,0x85,0xcc,0x88,0xcc,0x80,0x00,0x01,0xff,0xcf,0x85,0xcc,
+       0x88,0xcc,0x81,0x00,0xd1,0x12,0x10,0x09,0x01,0xff,0xcf,0x81,0xcc,0x93,0x00,0x01,
+       0xff,0xcf,0x81,0xcc,0x94,0x00,0x10,0x09,0x01,0xff,0xcf,0x85,0xcd,0x82,0x00,0x01,
+       0xff,0xcf,0x85,0xcc,0x88,0xcd,0x82,0x00,0xd2,0x24,0xd1,0x12,0x10,0x09,0x01,0xff,
+       0xce,0xa5,0xcc,0x86,0x00,0x01,0xff,0xce,0xa5,0xcc,0x84,0x00,0x10,0x09,0x01,0xff,
+       0xce,0xa5,0xcc,0x80,0x00,0x01,0xff,0xce,0xa5,0xcc,0x81,0x00,0xd1,0x12,0x10,0x09,
+       0x01,0xff,0xce,0xa1,0xcc,0x94,0x00,0x01,0xff,0xc2,0xa8,0xcc,0x80,0x00,0x10,0x09,
+       0x01,0xff,0xc2,0xa8,0xcc,0x81,0x00,0x01,0xff,0x60,0x00,0xd3,0x3b,0xd2,0x18,0x51,
+       0x04,0x00,0x00,0x10,0x0b,0x01,0xff,0xcf,0x89,0xcc,0x80,0xcd,0x85,0x00,0x01,0xff,
+       0xcf,0x89,0xcd,0x85,0x00,0xd1,0x0f,0x10,0x0b,0x01,0xff,0xcf,0x89,0xcc,0x81,0xcd,
+       0x85,0x00,0x00,0x00,0x10,0x09,0x01,0xff,0xcf,0x89,0xcd,0x82,0x00,0x01,0xff,0xcf,
+       0x89,0xcd,0x82,0xcd,0x85,0x00,0xd2,0x24,0xd1,0x12,0x10,0x09,0x01,0xff,0xce,0x9f,
+       0xcc,0x80,0x00,0x01,0xff,0xce,0x9f,0xcc,0x81,0x00,0x10,0x09,0x01,0xff,0xce,0xa9,
+       0xcc,0x80,0x00,0x01,0xff,0xce,0xa9,0xcc,0x81,0x00,0xd1,0x10,0x10,0x09,0x01,0xff,
+       0xce,0xa9,0xcd,0x85,0x00,0x01,0xff,0xc2,0xb4,0x00,0x10,0x04,0x01,0x00,0x00,0x00,
+       0xe0,0x62,0x0c,0xcf,0x86,0xe5,0x9f,0x08,0xe4,0xf8,0x05,0xe3,0xdb,0x02,0xe2,0xa1,
+       0x01,0xd1,0xb4,0xd0,0x3a,0xcf,0x86,0xd5,0x20,0x94,0x1c,0x93,0x18,0x92,0x14,0x91,
+       0x10,0x10,0x08,0x01,0xff,0xe2,0x80,0x82,0x00,0x01,0xff,0xe2,0x80,0x83,0x00,0x01,
+       0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x94,0x14,0x53,0x04,0x01,0x00,0x52,0x04,0x01,
+       0x00,0x51,0x04,0x01,0x00,0x10,0x04,0x01,0x00,0x04,0x00,0x01,0x00,0xcf,0x86,0xd5,
+       0x48,0xd4,0x1c,0xd3,0x10,0x52,0x04,0x01,0x00,0x51,0x04,0x01,0x00,0x10,0x04,0x01,
+       0x00,0x06,0x00,0x52,0x04,0x04,0x00,0x11,0x04,0x04,0x00,0x06,0x00,0xd3,0x1c,0xd2,
+       0x0c,0x51,0x04,0x06,0x00,0x10,0x04,0x06,0x00,0x07,0x00,0xd1,0x08,0x10,0x04,0x07,
+       0x00,0x08,0x00,0x10,0x04,0x08,0x00,0x06,0x00,0x52,0x04,0x08,0x00,0x51,0x04,0x08,
+       0x00,0x10,0x04,0x08,0x00,0x06,0x00,0xd4,0x1c,0xd3,0x10,0x52,0x04,0x06,0x00,0x91,
+       0x08,0x10,0x04,0x0a,0x00,0x00,0x00,0x0f,0x00,0x92,0x08,0x11,0x04,0x0f,0x00,0x01,
+       0x00,0x01,0x00,0x93,0x10,0x92,0x0c,0x91,0x08,0x10,0x04,0x01,0x00,0x06,0x00,0x00,
+       0x00,0x01,0x00,0x01,0x00,0xd0,0x7e,0xcf,0x86,0xd5,0x34,0xd4,0x14,0x53,0x04,0x01,
+       0x00,0x52,0x04,0x01,0x00,0x51,0x04,0x01,0x00,0x10,0x04,0x01,0x00,0x00,0x00,0xd3,
+       0x10,0x52,0x04,0x08,0x00,0x91,0x08,0x10,0x04,0x08,0x00,0x0c,0x00,0x0c,0x00,0x52,
+       0x04,0x0c,0x00,0x91,0x08,0x10,0x04,0x0c,0x00,0x00,0x00,0x00,0x00,0xd4,0x1c,0x53,
+       0x04,0x01,0x00,0xd2,0x0c,0x51,0x04,0x01,0x00,0x10,0x04,0x01,0x00,0x02,0x00,0x91,
+       0x08,0x10,0x04,0x03,0x00,0x04,0x00,0x04,0x00,0xd3,0x10,0xd2,0x08,0x11,0x04,0x06,
+       0x00,0x08,0x00,0x11,0x04,0x08,0x00,0x0b,0x00,0xd2,0x10,0xd1,0x08,0x10,0x04,0x0b,
+       0x00,0x0c,0x00,0x10,0x04,0x0e,0x00,0x10,0x00,0x51,0x04,0x10,0x00,0x10,0x04,0x11,
+       0x00,0x13,0x00,0xcf,0x86,0xd5,0x28,0x54,0x04,0x00,0x00,0xd3,0x0c,0x92,0x08,0x11,
+       0x04,0x01,0xe6,0x01,0x01,0x01,0xe6,0xd2,0x0c,0x51,0x04,0x01,0x01,0x10,0x04,0x01,
+       0x01,0x01,0xe6,0x91,0x08,0x10,0x04,0x01,0xe6,0x01,0x00,0x01,0x00,0xd4,0x30,0xd3,
+       0x1c,0xd2,0x0c,0x91,0x08,0x10,0x04,0x01,0x00,0x01,0xe6,0x04,0x00,0xd1,0x08,0x10,
+       0x04,0x06,0x00,0x06,0x01,0x10,0x04,0x06,0x01,0x06,0xe6,0x92,0x10,0xd1,0x08,0x10,
+       0x04,0x06,0xdc,0x06,0xe6,0x10,0x04,0x06,0x01,0x08,0x01,0x09,0xdc,0x93,0x10,0x92,
+       0x0c,0x91,0x08,0x10,0x04,0x0a,0xe6,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xd1,
+       0x81,0xd0,0x4f,0xcf,0x86,0x55,0x04,0x01,0x00,0xd4,0x29,0xd3,0x13,0x52,0x04,0x01,
+       0x00,0x51,0x04,0x01,0x00,0x10,0x07,0x01,0xff,0xce,0xa9,0x00,0x01,0x00,0x92,0x12,
+       0x51,0x04,0x01,0x00,0x10,0x06,0x01,0xff,0x4b,0x00,0x01,0xff,0x41,0xcc,0x8a,0x00,
+       0x01,0x00,0x53,0x04,0x01,0x00,0xd2,0x10,0xd1,0x08,0x10,0x04,0x01,0x00,0x04,0x00,
+       0x10,0x04,0x04,0x00,0x07,0x00,0x91,0x08,0x10,0x04,0x08,0x00,0x06,0x00,0x06,0x00,
+       0xcf,0x86,0x95,0x2c,0xd4,0x18,0x53,0x04,0x06,0x00,0x52,0x04,0x06,0x00,0xd1,0x08,
+       0x10,0x04,0x08,0x00,0x09,0x00,0x10,0x04,0x09,0x00,0x0a,0x00,0x93,0x10,0x92,0x0c,
+       0x51,0x04,0x0b,0x00,0x10,0x04,0x0b,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,
+       0xd0,0x68,0xcf,0x86,0xd5,0x48,0xd4,0x28,0xd3,0x18,0xd2,0x0c,0x51,0x04,0x01,0x00,
+       0x10,0x04,0x01,0x00,0x04,0x00,0x91,0x08,0x10,0x04,0x09,0x00,0x0a,0x00,0x0a,0x00,
+       0x92,0x0c,0x91,0x08,0x10,0x04,0x0a,0x00,0x0b,0x00,0x11,0x00,0x00,0x00,0x53,0x04,
+       0x01,0x00,0x92,0x18,0x51,0x04,0x01,0x00,0x10,0x0a,0x01,0xff,0xe2,0x86,0x90,0xcc,
+       0xb8,0x00,0x01,0xff,0xe2,0x86,0x92,0xcc,0xb8,0x00,0x01,0x00,0x94,0x1a,0x53,0x04,
+       0x01,0x00,0x52,0x04,0x01,0x00,0x51,0x04,0x01,0x00,0x10,0x0a,0x01,0xff,0xe2,0x86,
+       0x94,0xcc,0xb8,0x00,0x01,0x00,0x01,0x00,0xcf,0x86,0xd5,0x2e,0x94,0x2a,0x53,0x04,
+       0x01,0x00,0x52,0x04,0x01,0x00,0xd1,0x0e,0x10,0x04,0x01,0x00,0x01,0xff,0xe2,0x87,
+       0x90,0xcc,0xb8,0x00,0x10,0x0a,0x01,0xff,0xe2,0x87,0x94,0xcc,0xb8,0x00,0x01,0xff,
+       0xe2,0x87,0x92,0xcc,0xb8,0x00,0x01,0x00,0xd4,0x14,0x53,0x04,0x01,0x00,0x92,0x0c,
+       0x51,0x04,0x01,0x00,0x10,0x04,0x01,0x00,0x04,0x00,0x04,0x00,0x93,0x08,0x12,0x04,
+       0x04,0x00,0x06,0x00,0x06,0x00,0xe2,0x38,0x02,0xe1,0x3f,0x01,0xd0,0x68,0xcf,0x86,
+       0xd5,0x3e,0x94,0x3a,0xd3,0x16,0x52,0x04,0x01,0x00,0x91,0x0e,0x10,0x0a,0x01,0xff,
+       0xe2,0x88,0x83,0xcc,0xb8,0x00,0x01,0x00,0x01,0x00,0xd2,0x12,0x91,0x0e,0x10,0x04,
+       0x01,0x00,0x01,0xff,0xe2,0x88,0x88,0xcc,0xb8,0x00,0x01,0x00,0x91,0x0e,0x10,0x0a,
+       0x01,0xff,0xe2,0x88,0x8b,0xcc,0xb8,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x94,0x24,
+       0x93,0x20,0x52,0x04,0x01,0x00,0xd1,0x0e,0x10,0x0a,0x01,0xff,0xe2,0x88,0xa3,0xcc,
+       0xb8,0x00,0x01,0x00,0x10,0x0a,0x01,0xff,0xe2,0x88,0xa5,0xcc,0xb8,0x00,0x01,0x00,
+       0x01,0x00,0x01,0x00,0xcf,0x86,0xd5,0x48,0x94,0x44,0xd3,0x2e,0xd2,0x12,0x91,0x0e,
+       0x10,0x04,0x01,0x00,0x01,0xff,0xe2,0x88,0xbc,0xcc,0xb8,0x00,0x01,0x00,0xd1,0x0e,
+       0x10,0x0a,0x01,0xff,0xe2,0x89,0x83,0xcc,0xb8,0x00,0x01,0x00,0x10,0x04,0x01,0x00,
+       0x01,0xff,0xe2,0x89,0x85,0xcc,0xb8,0x00,0x92,0x12,0x91,0x0e,0x10,0x04,0x01,0x00,
+       0x01,0xff,0xe2,0x89,0x88,0xcc,0xb8,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0xd4,0x40,
+       0xd3,0x1e,0x92,0x1a,0xd1,0x0c,0x10,0x08,0x01,0xff,0x3d,0xcc,0xb8,0x00,0x01,0x00,
+       0x10,0x0a,0x01,0xff,0xe2,0x89,0xa1,0xcc,0xb8,0x00,0x01,0x00,0x01,0x00,0x52,0x04,
+       0x01,0x00,0xd1,0x0e,0x10,0x04,0x01,0x00,0x01,0xff,0xe2,0x89,0x8d,0xcc,0xb8,0x00,
+       0x10,0x08,0x01,0xff,0x3c,0xcc,0xb8,0x00,0x01,0xff,0x3e,0xcc,0xb8,0x00,0xd3,0x30,
+       0xd2,0x18,0x91,0x14,0x10,0x0a,0x01,0xff,0xe2,0x89,0xa4,0xcc,0xb8,0x00,0x01,0xff,
+       0xe2,0x89,0xa5,0xcc,0xb8,0x00,0x01,0x00,0x91,0x14,0x10,0x0a,0x01,0xff,0xe2,0x89,
+       0xb2,0xcc,0xb8,0x00,0x01,0xff,0xe2,0x89,0xb3,0xcc,0xb8,0x00,0x01,0x00,0x92,0x18,
+       0x91,0x14,0x10,0x0a,0x01,0xff,0xe2,0x89,0xb6,0xcc,0xb8,0x00,0x01,0xff,0xe2,0x89,
+       0xb7,0xcc,0xb8,0x00,0x01,0x00,0x01,0x00,0xd0,0x86,0xcf,0x86,0xd5,0x50,0x94,0x4c,
+       0xd3,0x30,0xd2,0x18,0x91,0x14,0x10,0x0a,0x01,0xff,0xe2,0x89,0xba,0xcc,0xb8,0x00,
+       0x01,0xff,0xe2,0x89,0xbb,0xcc,0xb8,0x00,0x01,0x00,0x91,0x14,0x10,0x0a,0x01,0xff,
+       0xe2,0x8a,0x82,0xcc,0xb8,0x00,0x01,0xff,0xe2,0x8a,0x83,0xcc,0xb8,0x00,0x01,0x00,
+       0x92,0x18,0x91,0x14,0x10,0x0a,0x01,0xff,0xe2,0x8a,0x86,0xcc,0xb8,0x00,0x01,0xff,
+       0xe2,0x8a,0x87,0xcc,0xb8,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x94,0x30,0x53,0x04,
+       0x01,0x00,0x52,0x04,0x01,0x00,0xd1,0x14,0x10,0x0a,0x01,0xff,0xe2,0x8a,0xa2,0xcc,
+       0xb8,0x00,0x01,0xff,0xe2,0x8a,0xa8,0xcc,0xb8,0x00,0x10,0x0a,0x01,0xff,0xe2,0x8a,
+       0xa9,0xcc,0xb8,0x00,0x01,0xff,0xe2,0x8a,0xab,0xcc,0xb8,0x00,0x01,0x00,0xcf,0x86,
+       0x55,0x04,0x01,0x00,0xd4,0x5c,0xd3,0x2c,0x92,0x28,0xd1,0x14,0x10,0x0a,0x01,0xff,
+       0xe2,0x89,0xbc,0xcc,0xb8,0x00,0x01,0xff,0xe2,0x89,0xbd,0xcc,0xb8,0x00,0x10,0x0a,
+       0x01,0xff,0xe2,0x8a,0x91,0xcc,0xb8,0x00,0x01,0xff,0xe2,0x8a,0x92,0xcc,0xb8,0x00,
+       0x01,0x00,0xd2,0x18,0x51,0x04,0x01,0x00,0x10,0x0a,0x01,0xff,0xe2,0x8a,0xb2,0xcc,
+       0xb8,0x00,0x01,0xff,0xe2,0x8a,0xb3,0xcc,0xb8,0x00,0x91,0x14,0x10,0x0a,0x01,0xff,
+       0xe2,0x8a,0xb4,0xcc,0xb8,0x00,0x01,0xff,0xe2,0x8a,0xb5,0xcc,0xb8,0x00,0x01,0x00,
+       0x93,0x0c,0x92,0x08,0x11,0x04,0x01,0x00,0x06,0x00,0x06,0x00,0x06,0x00,0xd1,0x64,
+       0xd0,0x3e,0xcf,0x86,0xd5,0x18,0x94,0x14,0x93,0x10,0x92,0x0c,0x91,0x08,0x10,0x04,
+       0x01,0x00,0x04,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x94,0x20,0x53,0x04,
+       0x01,0x00,0x92,0x18,0xd1,0x0c,0x10,0x04,0x01,0x00,0x01,0xff,0xe3,0x80,0x88,0x00,
+       0x10,0x08,0x01,0xff,0xe3,0x80,0x89,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0xcf,0x86,
+       0x55,0x04,0x01,0x00,0x54,0x04,0x01,0x00,0x53,0x04,0x01,0x00,0xd2,0x0c,0x51,0x04,
+       0x01,0x00,0x10,0x04,0x01,0x00,0x04,0x00,0x91,0x08,0x10,0x04,0x06,0x00,0x04,0x00,
+       0x04,0x00,0xd0,0x1e,0xcf,0x86,0x95,0x18,0x54,0x04,0x04,0x00,0x53,0x04,0x04,0x00,
+       0x92,0x0c,0x51,0x04,0x04,0x00,0x10,0x04,0x04,0x00,0x06,0x00,0x06,0x00,0x06,0x00,
+       0xcf,0x86,0xd5,0x2c,0xd4,0x14,0x53,0x04,0x06,0x00,0x52,0x04,0x06,0x00,0x51,0x04,
+       0x06,0x00,0x10,0x04,0x06,0x00,0x07,0x00,0xd3,0x10,0x92,0x0c,0x91,0x08,0x10,0x04,
+       0x07,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x12,0x04,0x08,0x00,0x09,0x00,0xd4,0x14,
+       0x53,0x04,0x09,0x00,0x92,0x0c,0x91,0x08,0x10,0x04,0x0b,0x00,0x0c,0x00,0x0c,0x00,
+       0x0c,0x00,0xd3,0x08,0x12,0x04,0x0c,0x00,0x10,0x00,0xd2,0x0c,0x51,0x04,0x10,0x00,
+       0x10,0x04,0x10,0x00,0x12,0x00,0x51,0x04,0x12,0x00,0x10,0x04,0x12,0x00,0x13,0x00,
+       0xd3,0xa6,0xd2,0x74,0xd1,0x40,0xd0,0x22,0xcf,0x86,0x55,0x04,0x01,0x00,0x94,0x18,
+       0x93,0x14,0x52,0x04,0x01,0x00,0xd1,0x08,0x10,0x04,0x01,0x00,0x04,0x00,0x10,0x04,
+       0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xcf,0x86,0x95,0x18,0x94,0x14,0x53,0x04,
+       0x01,0x00,0x92,0x0c,0x51,0x04,0x01,0x00,0x10,0x04,0x01,0x00,0x00,0x00,0x00,0x00,
+       0x00,0x00,0x01,0x00,0xd0,0x06,0xcf,0x06,0x01,0x00,0xcf,0x86,0x55,0x04,0x01,0x00,
+       0xd4,0x14,0x53,0x04,0x01,0x00,0x92,0x0c,0x51,0x04,0x01,0x00,0x10,0x04,0x01,0x00,
+       0x06,0x00,0x06,0x00,0x53,0x04,0x06,0x00,0x52,0x04,0x06,0x00,0x51,0x04,0x06,0x00,
+       0x10,0x04,0x06,0x00,0x07,0x00,0xd1,0x06,0xcf,0x06,0x01,0x00,0xd0,0x1a,0xcf,0x86,
+       0x95,0x14,0x54,0x04,0x01,0x00,0x93,0x0c,0x52,0x04,0x01,0x00,0x11,0x04,0x01,0x00,
+       0x06,0x00,0x06,0x00,0x01,0x00,0xcf,0x86,0x55,0x04,0x01,0x00,0x54,0x04,0x01,0x00,
+       0x13,0x04,0x04,0x00,0x06,0x00,0xd2,0xdc,0xd1,0x48,0xd0,0x26,0xcf,0x86,0x95,0x20,
+       0x54,0x04,0x01,0x00,0xd3,0x0c,0x52,0x04,0x01,0x00,0x11,0x04,0x07,0x00,0x06,0x00,
+       0x92,0x0c,0x91,0x08,0x10,0x04,0x08,0x00,0x04,0x00,0x01,0x00,0x01,0x00,0x01,0x00,
+       0xcf,0x86,0x55,0x04,0x01,0x00,0x54,0x04,0x01,0x00,0xd3,0x0c,0x92,0x08,0x11,0x04,
+       0x04,0x00,0x06,0x00,0x06,0x00,0x52,0x04,0x06,0x00,0x11,0x04,0x06,0x00,0x08,0x00,
+       0xd0,0x5e,0xcf,0x86,0xd5,0x2c,0xd4,0x10,0x53,0x04,0x06,0x00,0x92,0x08,0x11,0x04,
+       0x06,0x00,0x07,0x00,0x07,0x00,0xd3,0x0c,0x92,0x08,0x11,0x04,0x07,0x00,0x08,0x00,
+       0x08,0x00,0x52,0x04,0x08,0x00,0x91,0x08,0x10,0x04,0x08,0x00,0x0a,0x00,0x0b,0x00,
+       0xd4,0x10,0x93,0x0c,0x92,0x08,0x11,0x04,0x07,0x00,0x08,0x00,0x08,0x00,0x08,0x00,
+       0xd3,0x10,0x92,0x0c,0x51,0x04,0x08,0x00,0x10,0x04,0x09,0x00,0x0a,0x00,0x0a,0x00,
+       0x52,0x04,0x0a,0x00,0x91,0x08,0x10,0x04,0x0a,0x00,0x0b,0x00,0x0b,0x00,0xcf,0x86,
+       0xd5,0x1c,0x94,0x18,0xd3,0x08,0x12,0x04,0x0a,0x00,0x0b,0x00,0x52,0x04,0x0b,0x00,
+       0x51,0x04,0x0b,0x00,0x10,0x04,0x0c,0x00,0x0b,0x00,0x0b,0x00,0x94,0x14,0x93,0x10,
+       0x92,0x0c,0x51,0x04,0x0b,0x00,0x10,0x04,0x0c,0x00,0x0b,0x00,0x0c,0x00,0x0b,0x00,
+       0x0b,0x00,0xd1,0xa8,0xd0,0x42,0xcf,0x86,0xd5,0x28,0x94,0x24,0xd3,0x18,0xd2,0x0c,
+       0x91,0x08,0x10,0x04,0x10,0x00,0x01,0x00,0x01,0x00,0x91,0x08,0x10,0x04,0x01,0x00,
+       0x0c,0x00,0x01,0x00,0x92,0x08,0x11,0x04,0x01,0x00,0x0c,0x00,0x01,0x00,0x01,0x00,
+       0x94,0x14,0x53,0x04,0x01,0x00,0x92,0x0c,0x91,0x08,0x10,0x04,0x0c,0x00,0x01,0x00,
+       0x01,0x00,0x01,0x00,0x01,0x00,0xcf,0x86,0xd5,0x40,0xd4,0x18,0x53,0x04,0x01,0x00,
+       0x52,0x04,0x01,0x00,0xd1,0x08,0x10,0x04,0x0c,0x00,0x01,0x00,0x10,0x04,0x0c,0x00,
+       0x01,0x00,0xd3,0x18,0xd2,0x0c,0x51,0x04,0x01,0x00,0x10,0x04,0x01,0x00,0x0c,0x00,
+       0x51,0x04,0x0c,0x00,0x10,0x04,0x01,0x00,0x0b,0x00,0x52,0x04,0x01,0x00,0x51,0x04,
+       0x01,0x00,0x10,0x04,0x01,0x00,0x0c,0x00,0xd4,0x14,0x93,0x10,0x92,0x0c,0x91,0x08,
+       0x10,0x04,0x0c,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x06,0x00,0x93,0x0c,0x52,0x04,
+       0x06,0x00,0x11,0x04,0x06,0x00,0x01,0x00,0x01,0x00,0xd0,0x3e,0xcf,0x86,0xd5,0x18,
+       0x54,0x04,0x01,0x00,0x93,0x10,0x52,0x04,0x01,0x00,0x91,0x08,0x10,0x04,0x01,0x00,
+       0x0c,0x00,0x0c,0x00,0x01,0x00,0x54,0x04,0x01,0x00,0xd3,0x10,0x92,0x0c,0x91,0x08,
+       0x10,0x04,0x0c,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x52,0x04,0x01,0x00,0x51,0x04,
+       0x01,0x00,0x10,0x04,0x01,0x00,0x0c,0x00,0xcf,0x86,0xd5,0x2c,0x94,0x28,0xd3,0x10,
+       0x52,0x04,0x08,0x00,0x51,0x04,0x08,0x00,0x10,0x04,0x08,0x00,0x09,0x00,0xd2,0x0c,
+       0x51,0x04,0x09,0x00,0x10,0x04,0x09,0x00,0x0d,0x00,0x91,0x08,0x10,0x04,0x0a,0x00,
+       0x0d,0x00,0x0c,0x00,0x06,0x00,0x94,0x0c,0x53,0x04,0x06,0x00,0x12,0x04,0x06,0x00,
+       0x0a,0x00,0x06,0x00,0xe4,0x39,0x01,0xd3,0x0c,0xd2,0x06,0xcf,0x06,0x04,0x00,0xcf,
+       0x06,0x06,0x00,0xd2,0x30,0xd1,0x06,0xcf,0x06,0x06,0x00,0xd0,0x06,0xcf,0x06,0x06,
+       0x00,0xcf,0x86,0x95,0x1e,0x54,0x04,0x06,0x00,0x53,0x04,0x06,0x00,0x52,0x04,0x06,
+       0x00,0x91,0x0e,0x10,0x0a,0x06,0xff,0xe2,0xab,0x9d,0xcc,0xb8,0x00,0x06,0x00,0x06,
+       0x00,0x06,0x00,0xd1,0x80,0xd0,0x3a,0xcf,0x86,0xd5,0x28,0xd4,0x10,0x53,0x04,0x07,
+       0x00,0x52,0x04,0x07,0x00,0x11,0x04,0x07,0x00,0x08,0x00,0xd3,0x08,0x12,0x04,0x08,
+       0x00,0x09,0x00,0x92,0x0c,0x51,0x04,0x09,0x00,0x10,0x04,0x09,0x00,0x0a,0x00,0x0a,
+       0x00,0x94,0x0c,0x93,0x08,0x12,0x04,0x09,0x00,0x0a,0x00,0x0a,0x00,0x0a,0x00,0xcf,
+       0x86,0xd5,0x30,0xd4,0x14,0x53,0x04,0x0a,0x00,0x52,0x04,0x0a,0x00,0x91,0x08,0x10,
+       0x04,0x0a,0x00,0x10,0x00,0x10,0x00,0xd3,0x10,0x52,0x04,0x0a,0x00,0x91,0x08,0x10,
+       0x04,0x0a,0x00,0x0b,0x00,0x0b,0x00,0x92,0x08,0x11,0x04,0x0b,0x00,0x10,0x00,0x10,
+       0x00,0x54,0x04,0x10,0x00,0x93,0x0c,0x52,0x04,0x10,0x00,0x11,0x04,0x00,0x00,0x10,
+       0x00,0x10,0x00,0xd0,0x32,0xcf,0x86,0xd5,0x14,0x54,0x04,0x10,0x00,0x93,0x0c,0x52,
+       0x04,0x10,0x00,0x11,0x04,0x10,0x00,0x00,0x00,0x10,0x00,0x54,0x04,0x10,0x00,0x53,
+       0x04,0x10,0x00,0xd2,0x08,0x11,0x04,0x10,0x00,0x14,0x00,0x91,0x08,0x10,0x04,0x14,
+       0x00,0x10,0x00,0x10,0x00,0xcf,0x86,0xd5,0x28,0xd4,0x14,0x53,0x04,0x10,0x00,0x92,
+       0x0c,0x91,0x08,0x10,0x04,0x10,0x00,0x15,0x00,0x10,0x00,0x10,0x00,0x93,0x10,0x92,
+       0x0c,0x51,0x04,0x10,0x00,0x10,0x04,0x13,0x00,0x14,0x00,0x14,0x00,0x14,0x00,0xd4,
+       0x0c,0x53,0x04,0x14,0x00,0x12,0x04,0x14,0x00,0x11,0x00,0x53,0x04,0x14,0x00,0x52,
+       0x04,0x14,0x00,0x51,0x04,0x14,0x00,0x10,0x04,0x14,0x00,0x15,0x00,0xe3,0xb9,0x01,
+       0xd2,0xac,0xd1,0x68,0xd0,0x1e,0xcf,0x86,0x55,0x04,0x08,0x00,0x94,0x14,0x53,0x04,
+       0x08,0x00,0x52,0x04,0x08,0x00,0x51,0x04,0x08,0x00,0x10,0x04,0x08,0x00,0x00,0x00,
+       0x08,0x00,0xcf,0x86,0xd5,0x18,0x54,0x04,0x08,0x00,0x53,0x04,0x08,0x00,0x52,0x04,
+       0x08,0x00,0x51,0x04,0x08,0x00,0x10,0x04,0x08,0x00,0x00,0x00,0xd4,0x14,0x53,0x04,
+       0x09,0x00,0x52,0x04,0x09,0x00,0x91,0x08,0x10,0x04,0x09,0x00,0x0a,0x00,0x0a,0x00,
+       0xd3,0x10,0x92,0x0c,0x91,0x08,0x10,0x04,0x0b,0x00,0x0a,0x00,0x0a,0x00,0x09,0x00,
+       0x52,0x04,0x0a,0x00,0x11,0x04,0x0a,0x00,0x0b,0x00,0xd0,0x06,0xcf,0x06,0x08,0x00,
+       0xcf,0x86,0x55,0x04,0x08,0x00,0xd4,0x1c,0x53,0x04,0x08,0x00,0xd2,0x0c,0x51,0x04,
+       0x08,0x00,0x10,0x04,0x08,0x00,0x0b,0x00,0x51,0x04,0x0b,0x00,0x10,0x04,0x0b,0x00,
+       0x0b,0xe6,0xd3,0x0c,0x92,0x08,0x11,0x04,0x0b,0xe6,0x0d,0x00,0x00,0x00,0x92,0x0c,
+       0x91,0x08,0x10,0x04,0x00,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0xd1,0x6c,0xd0,0x2a,
+       0xcf,0x86,0x55,0x04,0x08,0x00,0x94,0x20,0xd3,0x10,0x52,0x04,0x08,0x00,0x51,0x04,
+       0x08,0x00,0x10,0x04,0x00,0x00,0x0d,0x00,0x52,0x04,0x00,0x00,0x91,0x08,0x10,0x04,
+       0x00,0x00,0x0d,0x00,0x00,0x00,0x08,0x00,0xcf,0x86,0x55,0x04,0x08,0x00,0xd4,0x1c,
+       0xd3,0x0c,0x52,0x04,0x08,0x00,0x11,0x04,0x08,0x00,0x0d,0x00,0x52,0x04,0x00,0x00,
+       0x51,0x04,0x00,0x00,0x10,0x04,0x00,0x00,0x08,0x00,0xd3,0x10,0x92,0x0c,0x91,0x08,
+       0x10,0x04,0x0c,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x52,0x04,0x00,0x00,0x51,0x04,
+       0x00,0x00,0x10,0x04,0x00,0x00,0x0c,0x09,0xd0,0x5a,0xcf,0x86,0xd5,0x18,0x54,0x04,
+       0x08,0x00,0x93,0x10,0x52,0x04,0x08,0x00,0x51,0x04,0x08,0x00,0x10,0x04,0x08,0x00,
+       0x00,0x00,0x00,0x00,0xd4,0x20,0xd3,0x10,0x52,0x04,0x08,0x00,0x51,0x04,0x08,0x00,
+       0x10,0x04,0x08,0x00,0x00,0x00,0x52,0x04,0x08,0x00,0x51,0x04,0x08,0x00,0x10,0x04,
+       0x08,0x00,0x00,0x00,0xd3,0x10,0x52,0x04,0x08,0x00,0x51,0x04,0x08,0x00,0x10,0x04,
+       0x08,0x00,0x00,0x00,0x52,0x04,0x08,0x00,0x51,0x04,0x08,0x00,0x10,0x04,0x08,0x00,
+       0x00,0x00,0xcf,0x86,0x95,0x40,0xd4,0x20,0xd3,0x10,0x52,0x04,0x08,0x00,0x51,0x04,
+       0x08,0x00,0x10,0x04,0x08,0x00,0x00,0x00,0x52,0x04,0x08,0x00,0x51,0x04,0x08,0x00,
+       0x10,0x04,0x08,0x00,0x00,0x00,0xd3,0x10,0x52,0x04,0x08,0x00,0x51,0x04,0x08,0x00,
+       0x10,0x04,0x08,0x00,0x00,0x00,0x52,0x04,0x08,0x00,0x51,0x04,0x08,0x00,0x10,0x04,
+       0x08,0x00,0x00,0x00,0x0a,0xe6,0xd2,0x9c,0xd1,0x68,0xd0,0x32,0xcf,0x86,0xd5,0x14,
+       0x54,0x04,0x08,0x00,0x53,0x04,0x08,0x00,0x52,0x04,0x0a,0x00,0x11,0x04,0x08,0x00,
+       0x0a,0x00,0x54,0x04,0x0a,0x00,0xd3,0x10,0x92,0x0c,0x91,0x08,0x10,0x04,0x0a,0x00,
+       0x0b,0x00,0x0d,0x00,0x0d,0x00,0x12,0x04,0x0d,0x00,0x10,0x00,0xcf,0x86,0x95,0x30,
+       0x94,0x2c,0xd3,0x18,0xd2,0x0c,0x51,0x04,0x10,0x00,0x10,0x04,0x10,0x00,0x12,0x00,
+       0x91,0x08,0x10,0x04,0x12,0x00,0x13,0x00,0x13,0x00,0xd2,0x08,0x11,0x04,0x13,0x00,
+       0x14,0x00,0x51,0x04,0x14,0x00,0x10,0x04,0x14,0x00,0x15,0x00,0x00,0x00,0x00,0x00,
+       0xd0,0x1e,0xcf,0x86,0x95,0x18,0x54,0x04,0x04,0x00,0x53,0x04,0x04,0x00,0x92,0x0c,
+       0x51,0x04,0x04,0x00,0x10,0x04,0x00,0x00,0x04,0x00,0x04,0x00,0x04,0x00,0xcf,0x86,
+       0x55,0x04,0x04,0x00,0x54,0x04,0x04,0x00,0x93,0x08,0x12,0x04,0x04,0x00,0x00,0x00,
+       0x00,0x00,0xd1,0x06,0xcf,0x06,0x04,0x00,0xd0,0x06,0xcf,0x06,0x04,0x00,0xcf,0x86,
+       0xd5,0x14,0x54,0x04,0x04,0x00,0x93,0x0c,0x52,0x04,0x04,0x00,0x11,0x04,0x04,0x00,
+       0x00,0x00,0x00,0x00,0x54,0x04,0x00,0x00,0x53,0x04,0x04,0x00,0x12,0x04,0x04,0x00,
+       0x00,0x00,0xcf,0x86,0xe5,0x8d,0x05,0xe4,0x86,0x05,0xe3,0x7d,0x04,0xe2,0xe4,0x03,
+       0xe1,0xc0,0x01,0xd0,0x3e,0xcf,0x86,0x55,0x04,0x01,0x00,0xd4,0x1c,0x53,0x04,0x01,
+       0x00,0xd2,0x0c,0x51,0x04,0x01,0x00,0x10,0x04,0x01,0xda,0x01,0xe4,0x91,0x08,0x10,
+       0x04,0x01,0xe8,0x01,0xde,0x01,0xe0,0x53,0x04,0x01,0x00,0xd2,0x0c,0x51,0x04,0x04,
+       0x00,0x10,0x04,0x04,0x00,0x06,0x00,0x51,0x04,0x06,0x00,0x10,0x04,0x04,0x00,0x01,
+       0x00,0xcf,0x86,0xd5,0xaa,0xd4,0x32,0xd3,0x10,0x92,0x0c,0x91,0x08,0x10,0x04,0x00,
+       0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x52,0x04,0x01,0x00,0xd1,0x0f,0x10,0x0b,0x01,
+       0xff,0xe3,0x81,0x8b,0xe3,0x82,0x99,0x00,0x01,0x00,0x10,0x0b,0x01,0xff,0xe3,0x81,
+       0x8d,0xe3,0x82,0x99,0x00,0x01,0x00,0xd3,0x3c,0xd2,0x1e,0xd1,0x0f,0x10,0x0b,0x01,
+       0xff,0xe3,0x81,0x8f,0xe3,0x82,0x99,0x00,0x01,0x00,0x10,0x0b,0x01,0xff,0xe3,0x81,
+       0x91,0xe3,0x82,0x99,0x00,0x01,0x00,0xd1,0x0f,0x10,0x0b,0x01,0xff,0xe3,0x81,0x93,
+       0xe3,0x82,0x99,0x00,0x01,0x00,0x10,0x0b,0x01,0xff,0xe3,0x81,0x95,0xe3,0x82,0x99,
+       0x00,0x01,0x00,0xd2,0x1e,0xd1,0x0f,0x10,0x0b,0x01,0xff,0xe3,0x81,0x97,0xe3,0x82,
+       0x99,0x00,0x01,0x00,0x10,0x0b,0x01,0xff,0xe3,0x81,0x99,0xe3,0x82,0x99,0x00,0x01,
+       0x00,0xd1,0x0f,0x10,0x0b,0x01,0xff,0xe3,0x81,0x9b,0xe3,0x82,0x99,0x00,0x01,0x00,
+       0x10,0x0b,0x01,0xff,0xe3,0x81,0x9d,0xe3,0x82,0x99,0x00,0x01,0x00,0xd4,0x53,0xd3,
+       0x3c,0xd2,0x1e,0xd1,0x0f,0x10,0x0b,0x01,0xff,0xe3,0x81,0x9f,0xe3,0x82,0x99,0x00,
+       0x01,0x00,0x10,0x0b,0x01,0xff,0xe3,0x81,0xa1,0xe3,0x82,0x99,0x00,0x01,0x00,0xd1,
+       0x0f,0x10,0x04,0x01,0x00,0x01,0xff,0xe3,0x81,0xa4,0xe3,0x82,0x99,0x00,0x10,0x04,
+       0x01,0x00,0x01,0xff,0xe3,0x81,0xa6,0xe3,0x82,0x99,0x00,0x92,0x13,0x91,0x0f,0x10,
+       0x04,0x01,0x00,0x01,0xff,0xe3,0x81,0xa8,0xe3,0x82,0x99,0x00,0x01,0x00,0x01,0x00,
+       0xd3,0x4a,0xd2,0x25,0xd1,0x16,0x10,0x0b,0x01,0xff,0xe3,0x81,0xaf,0xe3,0x82,0x99,
+       0x00,0x01,0xff,0xe3,0x81,0xaf,0xe3,0x82,0x9a,0x00,0x10,0x04,0x01,0x00,0x01,0xff,
+       0xe3,0x81,0xb2,0xe3,0x82,0x99,0x00,0xd1,0x0f,0x10,0x0b,0x01,0xff,0xe3,0x81,0xb2,
+       0xe3,0x82,0x9a,0x00,0x01,0x00,0x10,0x0b,0x01,0xff,0xe3,0x81,0xb5,0xe3,0x82,0x99,
+       0x00,0x01,0xff,0xe3,0x81,0xb5,0xe3,0x82,0x9a,0x00,0xd2,0x1e,0xd1,0x0f,0x10,0x04,
+       0x01,0x00,0x01,0xff,0xe3,0x81,0xb8,0xe3,0x82,0x99,0x00,0x10,0x0b,0x01,0xff,0xe3,
+       0x81,0xb8,0xe3,0x82,0x9a,0x00,0x01,0x00,0x91,0x16,0x10,0x0b,0x01,0xff,0xe3,0x81,
+       0xbb,0xe3,0x82,0x99,0x00,0x01,0xff,0xe3,0x81,0xbb,0xe3,0x82,0x9a,0x00,0x01,0x00,
+       0xd0,0xee,0xcf,0x86,0xd5,0x42,0x54,0x04,0x01,0x00,0xd3,0x1b,0x52,0x04,0x01,0x00,
+       0xd1,0x0f,0x10,0x0b,0x01,0xff,0xe3,0x81,0x86,0xe3,0x82,0x99,0x00,0x06,0x00,0x10,
+       0x04,0x06,0x00,0x00,0x00,0xd2,0x10,0xd1,0x08,0x10,0x04,0x00,0x00,0x01,0x08,0x10,
+       0x04,0x01,0x08,0x01,0x00,0x51,0x04,0x01,0x00,0x10,0x0b,0x01,0xff,0xe3,0x82,0x9d,
+       0xe3,0x82,0x99,0x00,0x06,0x00,0xd4,0x32,0xd3,0x10,0x92,0x0c,0x91,0x08,0x10,0x04,
+       0x06,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x52,0x04,0x01,0x00,0xd1,0x0f,0x10,0x0b,
+       0x01,0xff,0xe3,0x82,0xab,0xe3,0x82,0x99,0x00,0x01,0x00,0x10,0x0b,0x01,0xff,0xe3,
+       0x82,0xad,0xe3,0x82,0x99,0x00,0x01,0x00,0xd3,0x3c,0xd2,0x1e,0xd1,0x0f,0x10,0x0b,
+       0x01,0xff,0xe3,0x82,0xaf,0xe3,0x82,0x99,0x00,0x01,0x00,0x10,0x0b,0x01,0xff,0xe3,
+       0x82,0xb1,0xe3,0x82,0x99,0x00,0x01,0x00,0xd1,0x0f,0x10,0x0b,0x01,0xff,0xe3,0x82,
+       0xb3,0xe3,0x82,0x99,0x00,0x01,0x00,0x10,0x0b,0x01,0xff,0xe3,0x82,0xb5,0xe3,0x82,
+       0x99,0x00,0x01,0x00,0xd2,0x1e,0xd1,0x0f,0x10,0x0b,0x01,0xff,0xe3,0x82,0xb7,0xe3,
+       0x82,0x99,0x00,0x01,0x00,0x10,0x0b,0x01,0xff,0xe3,0x82,0xb9,0xe3,0x82,0x99,0x00,
+       0x01,0x00,0xd1,0x0f,0x10,0x0b,0x01,0xff,0xe3,0x82,0xbb,0xe3,0x82,0x99,0x00,0x01,
+       0x00,0x10,0x0b,0x01,0xff,0xe3,0x82,0xbd,0xe3,0x82,0x99,0x00,0x01,0x00,0xcf,0x86,
+       0xd5,0xd5,0xd4,0x53,0xd3,0x3c,0xd2,0x1e,0xd1,0x0f,0x10,0x0b,0x01,0xff,0xe3,0x82,
+       0xbf,0xe3,0x82,0x99,0x00,0x01,0x00,0x10,0x0b,0x01,0xff,0xe3,0x83,0x81,0xe3,0x82,
+       0x99,0x00,0x01,0x00,0xd1,0x0f,0x10,0x04,0x01,0x00,0x01,0xff,0xe3,0x83,0x84,0xe3,
+       0x82,0x99,0x00,0x10,0x04,0x01,0x00,0x01,0xff,0xe3,0x83,0x86,0xe3,0x82,0x99,0x00,
+       0x92,0x13,0x91,0x0f,0x10,0x04,0x01,0x00,0x01,0xff,0xe3,0x83,0x88,0xe3,0x82,0x99,
+       0x00,0x01,0x00,0x01,0x00,0xd3,0x4a,0xd2,0x25,0xd1,0x16,0x10,0x0b,0x01,0xff,0xe3,
+       0x83,0x8f,0xe3,0x82,0x99,0x00,0x01,0xff,0xe3,0x83,0x8f,0xe3,0x82,0x9a,0x00,0x10,
+       0x04,0x01,0x00,0x01,0xff,0xe3,0x83,0x92,0xe3,0x82,0x99,0x00,0xd1,0x0f,0x10,0x0b,
+       0x01,0xff,0xe3,0x83,0x92,0xe3,0x82,0x9a,0x00,0x01,0x00,0x10,0x0b,0x01,0xff,0xe3,
+       0x83,0x95,0xe3,0x82,0x99,0x00,0x01,0xff,0xe3,0x83,0x95,0xe3,0x82,0x9a,0x00,0xd2,
+       0x1e,0xd1,0x0f,0x10,0x04,0x01,0x00,0x01,0xff,0xe3,0x83,0x98,0xe3,0x82,0x99,0x00,
+       0x10,0x0b,0x01,0xff,0xe3,0x83,0x98,0xe3,0x82,0x9a,0x00,0x01,0x00,0x91,0x16,0x10,
+       0x0b,0x01,0xff,0xe3,0x83,0x9b,0xe3,0x82,0x99,0x00,0x01,0xff,0xe3,0x83,0x9b,0xe3,
+       0x82,0x9a,0x00,0x01,0x00,0x54,0x04,0x01,0x00,0xd3,0x22,0x52,0x04,0x01,0x00,0xd1,
+       0x0f,0x10,0x0b,0x01,0xff,0xe3,0x82,0xa6,0xe3,0x82,0x99,0x00,0x01,0x00,0x10,0x04,
+       0x01,0x00,0x01,0xff,0xe3,0x83,0xaf,0xe3,0x82,0x99,0x00,0xd2,0x25,0xd1,0x16,0x10,
+       0x0b,0x01,0xff,0xe3,0x83,0xb0,0xe3,0x82,0x99,0x00,0x01,0xff,0xe3,0x83,0xb1,0xe3,
+       0x82,0x99,0x00,0x10,0x0b,0x01,0xff,0xe3,0x83,0xb2,0xe3,0x82,0x99,0x00,0x01,0x00,
+       0x51,0x04,0x01,0x00,0x10,0x0b,0x01,0xff,0xe3,0x83,0xbd,0xe3,0x82,0x99,0x00,0x06,
+       0x00,0xd1,0x4c,0xd0,0x46,0xcf,0x86,0xd5,0x18,0x94,0x14,0x93,0x10,0x52,0x04,0x00,
+       0x00,0x91,0x08,0x10,0x04,0x00,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0xd4,
+       0x18,0x53,0x04,0x01,0x00,0x52,0x04,0x01,0x00,0xd1,0x08,0x10,0x04,0x01,0x00,0x0a,
+       0x00,0x10,0x04,0x13,0x00,0x14,0x00,0x93,0x10,0x92,0x0c,0x91,0x08,0x10,0x04,0x00,
+       0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0xcf,0x06,0x01,0x00,0xd0,0x32,0xcf,
+       0x86,0xd5,0x18,0x94,0x14,0x53,0x04,0x01,0x00,0x52,0x04,0x01,0x00,0x51,0x04,0x01,
+       0x00,0x10,0x04,0x01,0x00,0x00,0x00,0x01,0x00,0x54,0x04,0x04,0x00,0x53,0x04,0x04,
+       0x00,0x92,0x0c,0x51,0x04,0x0c,0x00,0x10,0x04,0x0c,0x00,0x00,0x00,0x00,0x00,0xcf,
+       0x86,0xd5,0x08,0x14,0x04,0x08,0x00,0x0a,0x00,0x94,0x0c,0x93,0x08,0x12,0x04,0x0a,
+       0x00,0x00,0x00,0x00,0x00,0x06,0x00,0xd2,0xa4,0xd1,0x5c,0xd0,0x22,0xcf,0x86,0x95,
+       0x1c,0x54,0x04,0x01,0x00,0x53,0x04,0x01,0x00,0x52,0x04,0x01,0x00,0xd1,0x08,0x10,
+       0x04,0x01,0x00,0x07,0x00,0x10,0x04,0x07,0x00,0x00,0x00,0x01,0x00,0xcf,0x86,0xd5,
+       0x20,0xd4,0x0c,0x93,0x08,0x12,0x04,0x01,0x00,0x0b,0x00,0x0b,0x00,0x93,0x10,0x92,
+       0x0c,0x91,0x08,0x10,0x04,0x07,0x00,0x06,0x00,0x06,0x00,0x06,0x00,0x06,0x00,0x54,
+       0x04,0x01,0x00,0x53,0x04,0x01,0x00,0x52,0x04,0x01,0x00,0x51,0x04,0x07,0x00,0x10,
+       0x04,0x08,0x00,0x01,0x00,0xd0,0x1e,0xcf,0x86,0x55,0x04,0x01,0x00,0x54,0x04,0x01,
+       0x00,0x93,0x10,0x92,0x0c,0x91,0x08,0x10,0x04,0x01,0x00,0x06,0x00,0x06,0x00,0x06,
+       0x00,0x06,0x00,0xcf,0x86,0xd5,0x10,0x94,0x0c,0x53,0x04,0x01,0x00,0x12,0x04,0x01,
+       0x00,0x07,0x00,0x01,0x00,0x54,0x04,0x01,0x00,0x53,0x04,0x01,0x00,0x52,0x04,0x01,
+       0x00,0x51,0x04,0x01,0x00,0x10,0x04,0x01,0x00,0x16,0x00,0xd1,0x30,0xd0,0x06,0xcf,
+       0x06,0x01,0x00,0xcf,0x86,0x55,0x04,0x01,0x00,0x54,0x04,0x01,0x00,0xd3,0x10,0x52,
+       0x04,0x01,0x00,0x51,0x04,0x01,0x00,0x10,0x04,0x01,0x00,0x07,0x00,0x92,0x0c,0x51,
+       0x04,0x07,0x00,0x10,0x04,0x07,0x00,0x01,0x00,0x01,0x00,0xd0,0x06,0xcf,0x06,0x01,
+       0x00,0xcf,0x86,0xd5,0x14,0x54,0x04,0x01,0x00,0x53,0x04,0x01,0x00,0x52,0x04,0x01,
+       0x00,0x11,0x04,0x01,0x00,0x07,0x00,0x54,0x04,0x01,0x00,0x53,0x04,0x01,0x00,0x52,
+       0x04,0x01,0x00,0x51,0x04,0x01,0x00,0x10,0x04,0x01,0x00,0x07,0x00,0xcf,0x06,0x04,
+       0x00,0xcf,0x06,0x04,0x00,0xd1,0x48,0xd0,0x40,0xcf,0x86,0xd5,0x06,0xcf,0x06,0x04,
+       0x00,0xd4,0x06,0xcf,0x06,0x04,0x00,0xd3,0x2c,0xd2,0x06,0xcf,0x06,0x04,0x00,0xd1,
+       0x06,0xcf,0x06,0x04,0x00,0xd0,0x1a,0xcf,0x86,0x55,0x04,0x04,0x00,0x54,0x04,0x04,
+       0x00,0x93,0x0c,0x52,0x04,0x04,0x00,0x11,0x04,0x04,0x00,0x00,0x00,0x00,0x00,0xcf,
+       0x06,0x07,0x00,0xcf,0x06,0x01,0x00,0xcf,0x86,0xcf,0x06,0x01,0x00,0xcf,0x86,0xcf,
+       0x06,0x01,0x00,0xe2,0x71,0x05,0xd1,0x8c,0xd0,0x08,0xcf,0x86,0xcf,0x06,0x01,0x00,
+       0xcf,0x86,0xd5,0x06,0xcf,0x06,0x01,0x00,0xd4,0x06,0xcf,0x06,0x01,0x00,0xd3,0x06,
+       0xcf,0x06,0x01,0x00,0xd2,0x06,0xcf,0x06,0x01,0x00,0xd1,0x06,0xcf,0x06,0x01,0x00,
+       0xd0,0x22,0xcf,0x86,0x55,0x04,0x01,0x00,0xd4,0x10,0x93,0x0c,0x52,0x04,0x01,0x00,
+       0x11,0x04,0x01,0x00,0x08,0x00,0x08,0x00,0x53,0x04,0x08,0x00,0x12,0x04,0x08,0x00,
+       0x0a,0x00,0xcf,0x86,0xd5,0x28,0xd4,0x18,0xd3,0x08,0x12,0x04,0x0a,0x00,0x0b,0x00,
+       0x52,0x04,0x0b,0x00,0x91,0x08,0x10,0x04,0x0d,0x00,0x11,0x00,0x11,0x00,0x93,0x0c,
+       0x52,0x04,0x11,0x00,0x11,0x04,0x11,0x00,0x13,0x00,0x13,0x00,0x94,0x14,0x53,0x04,
+       0x13,0x00,0x92,0x0c,0x51,0x04,0x13,0x00,0x10,0x04,0x13,0x00,0x14,0x00,0x14,0x00,
+       0x00,0x00,0xe0,0xdb,0x04,0xcf,0x86,0xe5,0xdf,0x01,0xd4,0x06,0xcf,0x06,0x04,0x00,
+       0xd3,0x74,0xd2,0x6e,0xd1,0x06,0xcf,0x06,0x04,0x00,0xd0,0x3e,0xcf,0x86,0xd5,0x18,
+       0x94,0x14,0x53,0x04,0x04,0x00,0x52,0x04,0x04,0x00,0x91,0x08,0x10,0x04,0x04,0x00,
+       0x00,0x00,0x00,0x00,0x04,0x00,0xd4,0x10,0x93,0x0c,0x92,0x08,0x11,0x04,0x04,0x00,
+       0x06,0x00,0x04,0x00,0x04,0x00,0x93,0x10,0x52,0x04,0x04,0x00,0x91,0x08,0x10,0x04,
+       0x06,0x00,0x04,0x00,0x04,0x00,0x04,0x00,0xcf,0x86,0x95,0x24,0x94,0x20,0x93,0x1c,
+       0xd2,0x0c,0x91,0x08,0x10,0x04,0x04,0x00,0x06,0x00,0x04,0x00,0xd1,0x08,0x10,0x04,
+       0x04,0x00,0x06,0x00,0x10,0x04,0x04,0x00,0x00,0x00,0x00,0x00,0x0b,0x00,0x0b,0x00,
+       0xcf,0x06,0x0a,0x00,0xd2,0x84,0xd1,0x4c,0xd0,0x16,0xcf,0x86,0x55,0x04,0x0a,0x00,
+       0x94,0x0c,0x53,0x04,0x0a,0x00,0x12,0x04,0x0a,0x00,0x00,0x00,0x00,0x00,0xcf,0x86,
+       0x55,0x04,0x0a,0x00,0xd4,0x1c,0xd3,0x0c,0x92,0x08,0x11,0x04,0x0c,0x00,0x0a,0x00,
+       0x0a,0x00,0x52,0x04,0x0a,0x00,0x51,0x04,0x0a,0x00,0x10,0x04,0x0a,0x00,0x0a,0xe6,
+       0xd3,0x08,0x12,0x04,0x0a,0x00,0x0d,0xe6,0x52,0x04,0x0d,0xe6,0x11,0x04,0x0a,0xe6,
+       0x0a,0x00,0xd0,0x1e,0xcf,0x86,0x95,0x18,0x54,0x04,0x0a,0x00,0x53,0x04,0x0a,0x00,
+       0x52,0x04,0x10,0x00,0x51,0x04,0x10,0x00,0x10,0x04,0x11,0xe6,0x0d,0xe6,0x0b,0x00,
+       0xcf,0x86,0x55,0x04,0x0b,0x00,0x54,0x04,0x0b,0x00,0x93,0x0c,0x92,0x08,0x11,0x04,
+       0x0b,0xe6,0x0b,0x00,0x0b,0x00,0x00,0x00,0xd1,0x40,0xd0,0x3a,0xcf,0x86,0xd5,0x24,
+       0x54,0x04,0x08,0x00,0xd3,0x10,0x52,0x04,0x08,0x00,0x51,0x04,0x08,0x00,0x10,0x04,
+       0x08,0x00,0x09,0x00,0x92,0x0c,0x51,0x04,0x09,0x00,0x10,0x04,0x09,0x00,0x0a,0x00,
+       0x0a,0x00,0x94,0x10,0x93,0x0c,0x92,0x08,0x11,0x04,0x09,0x00,0x0a,0x00,0x0a,0x00,
+       0x0a,0x00,0x0a,0x00,0xcf,0x06,0x0a,0x00,0xd0,0x5e,0xcf,0x86,0xd5,0x28,0xd4,0x18,
+       0x53,0x04,0x0a,0x00,0x52,0x04,0x0a,0x00,0xd1,0x08,0x10,0x04,0x0a,0x00,0x0c,0x00,
+       0x10,0x04,0x0c,0x00,0x11,0x00,0x93,0x0c,0x92,0x08,0x11,0x04,0x0c,0x00,0x0d,0x00,
+       0x10,0x00,0x10,0x00,0xd4,0x1c,0x53,0x04,0x0c,0x00,0xd2,0x0c,0x51,0x04,0x0c,0x00,
+       0x10,0x04,0x0d,0x00,0x10,0x00,0x51,0x04,0x10,0x00,0x10,0x04,0x12,0x00,0x14,0x00,
+       0xd3,0x0c,0x92,0x08,0x11,0x04,0x10,0x00,0x11,0x00,0x11,0x00,0x92,0x08,0x11,0x04,
+       0x14,0x00,0x15,0x00,0x15,0x00,0xcf,0x86,0xd5,0x1c,0x94,0x18,0x93,0x14,0xd2,0x08,
+       0x11,0x04,0x00,0x00,0x15,0x00,0x51,0x04,0x15,0x00,0x10,0x04,0x15,0x00,0x00,0x00,
+       0x00,0x00,0x00,0x00,0x54,0x04,0x00,0x00,0xd3,0x10,0x52,0x04,0x00,0x00,0x51,0x04,
+       0x00,0x00,0x10,0x04,0x00,0x00,0x10,0x00,0x92,0x0c,0x51,0x04,0x0d,0x00,0x10,0x04,
+       0x0c,0x00,0x0a,0x00,0x0a,0x00,0xe4,0xf2,0x02,0xe3,0x65,0x01,0xd2,0x98,0xd1,0x48,
+       0xd0,0x36,0xcf,0x86,0xd5,0x18,0x94,0x14,0x93,0x10,0x52,0x04,0x08,0x00,0x51,0x04,
+       0x08,0x00,0x10,0x04,0x08,0x09,0x08,0x00,0x08,0x00,0x08,0x00,0xd4,0x0c,0x53,0x04,
+       0x08,0x00,0x12,0x04,0x08,0x00,0x00,0x00,0x53,0x04,0x0b,0x00,0x92,0x08,0x11,0x04,
+       0x0b,0x00,0x00,0x00,0x00,0x00,0xcf,0x86,0x55,0x04,0x09,0x00,0x54,0x04,0x09,0x00,
+       0x13,0x04,0x09,0x00,0x00,0x00,0xd0,0x06,0xcf,0x06,0x0a,0x00,0xcf,0x86,0xd5,0x2c,
+       0xd4,0x1c,0xd3,0x10,0x52,0x04,0x0a,0x00,0x91,0x08,0x10,0x04,0x0a,0x09,0x12,0x00,
+       0x00,0x00,0x52,0x04,0x00,0x00,0x11,0x04,0x00,0x00,0x0a,0x00,0x53,0x04,0x0a,0x00,
+       0x92,0x08,0x11,0x04,0x0a,0x00,0x00,0x00,0x00,0x00,0x54,0x04,0x0b,0xe6,0xd3,0x0c,
+       0x92,0x08,0x11,0x04,0x0b,0xe6,0x0b,0x00,0x0b,0x00,0x52,0x04,0x0b,0x00,0x11,0x04,
+       0x11,0x00,0x14,0x00,0xd1,0x60,0xd0,0x22,0xcf,0x86,0x55,0x04,0x0a,0x00,0x94,0x18,
+       0x53,0x04,0x0a,0x00,0xd2,0x0c,0x51,0x04,0x0a,0x00,0x10,0x04,0x0a,0x00,0x0a,0xdc,
+       0x11,0x04,0x0a,0xdc,0x0a,0x00,0x0a,0x00,0xcf,0x86,0xd5,0x24,0x54,0x04,0x0a,0x00,
+       0xd3,0x10,0x92,0x0c,0x51,0x04,0x0a,0x00,0x10,0x04,0x0a,0x00,0x0a,0x09,0x00,0x00,
+       0x52,0x04,0x00,0x00,0x51,0x04,0x00,0x00,0x10,0x04,0x00,0x00,0x0a,0x00,0x54,0x04,
+       0x0b,0x00,0x53,0x04,0x0b,0x00,0x52,0x04,0x0b,0x00,0x91,0x08,0x10,0x04,0x0b,0x00,
+       0x00,0x00,0x00,0x00,0xd0,0x1e,0xcf,0x86,0x55,0x04,0x0b,0x00,0x54,0x04,0x0b,0x00,
+       0x93,0x10,0x92,0x0c,0x51,0x04,0x0b,0x00,0x10,0x04,0x0b,0x00,0x0b,0x07,0x0b,0x00,
+       0x0b,0x00,0xcf,0x86,0xd5,0x34,0xd4,0x20,0xd3,0x10,0x92,0x0c,0x91,0x08,0x10,0x04,
+       0x0b,0x09,0x0b,0x00,0x0b,0x00,0x0b,0x00,0x52,0x04,0x0b,0x00,0x51,0x04,0x0b,0x00,
+       0x10,0x04,0x00,0x00,0x0b,0x00,0x53,0x04,0x0b,0x00,0xd2,0x08,0x11,0x04,0x0b,0x00,
+       0x00,0x00,0x11,0x04,0x00,0x00,0x0b,0x00,0x54,0x04,0x10,0x00,0x53,0x04,0x10,0x00,
+       0x52,0x04,0x10,0x00,0x51,0x04,0x10,0x00,0x10,0x04,0x10,0x00,0x00,0x00,0xd2,0xd0,
+       0xd1,0x50,0xd0,0x1e,0xcf,0x86,0x55,0x04,0x0a,0x00,0x54,0x04,0x0a,0x00,0x93,0x10,
+       0x52,0x04,0x0a,0x00,0x51,0x04,0x0a,0x00,0x10,0x04,0x0a,0x00,0x00,0x00,0x00,0x00,
+       0xcf,0x86,0xd5,0x20,0xd4,0x10,0x53,0x04,0x0a,0x00,0x52,0x04,0x0a,0x00,0x11,0x04,
+       0x0a,0x00,0x00,0x00,0x53,0x04,0x0a,0x00,0x92,0x08,0x11,0x04,0x0a,0x00,0x00,0x00,
+       0x0a,0x00,0x54,0x04,0x0b,0x00,0x53,0x04,0x0b,0x00,0x12,0x04,0x0b,0x00,0x10,0x00,
+       0xd0,0x3a,0xcf,0x86,0x55,0x04,0x0b,0x00,0x54,0x04,0x0b,0x00,0xd3,0x1c,0xd2,0x0c,
+       0x91,0x08,0x10,0x04,0x0b,0xe6,0x0b,0x00,0x0b,0xe6,0xd1,0x08,0x10,0x04,0x0b,0xdc,
+       0x0b,0x00,0x10,0x04,0x0b,0x00,0x0b,0xe6,0xd2,0x0c,0x91,0x08,0x10,0x04,0x0b,0xe6,
+       0x0b,0x00,0x0b,0x00,0x11,0x04,0x0b,0x00,0x0b,0xe6,0xcf,0x86,0xd5,0x2c,0xd4,0x18,
+       0x93,0x14,0x92,0x10,0xd1,0x08,0x10,0x04,0x0b,0x00,0x0b,0xe6,0x10,0x04,0x0b,0x00,
+       0x00,0x00,0x00,0x00,0x00,0x00,0x53,0x04,0x00,0x00,0x92,0x0c,0x51,0x04,0x00,0x00,
+       0x10,0x04,0x00,0x00,0x0b,0x00,0x0b,0x00,0x54,0x04,0x0d,0x00,0x93,0x10,0x52,0x04,
+       0x0d,0x00,0x51,0x04,0x0d,0x00,0x10,0x04,0x0d,0x09,0x00,0x00,0x00,0x00,0xd1,0x8c,
+       0xd0,0x72,0xcf,0x86,0xd5,0x4c,0xd4,0x30,0xd3,0x18,0xd2,0x0c,0x91,0x08,0x10,0x04,
+       0x00,0x00,0x0c,0x00,0x0c,0x00,0x51,0x04,0x0c,0x00,0x10,0x04,0x0c,0x00,0x00,0x00,
+       0xd2,0x0c,0x91,0x08,0x10,0x04,0x00,0x00,0x0c,0x00,0x0c,0x00,0x51,0x04,0x0c,0x00,
+       0x10,0x04,0x0c,0x00,0x00,0x00,0x93,0x18,0xd2,0x0c,0x91,0x08,0x10,0x04,0x00,0x00,
+       0x0c,0x00,0x0c,0x00,0x51,0x04,0x0c,0x00,0x10,0x04,0x0c,0x00,0x00,0x00,0x00,0x00,
+       0x94,0x20,0xd3,0x10,0x52,0x04,0x0c,0x00,0x51,0x04,0x0c,0x00,0x10,0x04,0x0c,0x00,
+       0x00,0x00,0x52,0x04,0x0c,0x00,0x51,0x04,0x0c,0x00,0x10,0x04,0x0c,0x00,0x00,0x00,
+       0x10,0x00,0xcf,0x86,0x55,0x04,0x10,0x00,0x94,0x10,0x93,0x0c,0x52,0x04,0x11,0x00,
+       0x11,0x04,0x10,0x00,0x15,0x00,0x00,0x00,0x11,0x00,0xd0,0x06,0xcf,0x06,0x11,0x00,
+       0xcf,0x86,0x55,0x04,0x0b,0x00,0xd4,0x14,0x53,0x04,0x0b,0x00,0x52,0x04,0x0b,0x00,
+       0x91,0x08,0x10,0x04,0x0b,0x00,0x0b,0x09,0x00,0x00,0x53,0x04,0x0b,0x00,0x92,0x08,
+       0x11,0x04,0x0b,0x00,0x00,0x00,0x00,0x00,0xcf,0x06,0x02,0xff,0xff,0xcf,0x86,0xcf,
+       0x06,0x02,0xff,0xff,0xd1,0x76,0xd0,0x09,0xcf,0x86,0xcf,0x06,0x02,0xff,0xff,0xcf,
+       0x86,0x85,0xd4,0x07,0xcf,0x06,0x02,0xff,0xff,0xd3,0x07,0xcf,0x06,0x02,0xff,0xff,
+       0xd2,0x07,0xcf,0x06,0x02,0xff,0xff,0xd1,0x07,0xcf,0x06,0x02,0xff,0xff,0xd0,0x18,
+       0xcf,0x86,0x55,0x05,0x02,0xff,0xff,0x94,0x0d,0x93,0x09,0x12,0x05,0x02,0xff,0xff,
+       0x00,0x00,0x00,0x00,0x0b,0x00,0xcf,0x86,0xd5,0x24,0x94,0x20,0xd3,0x10,0x52,0x04,
+       0x0b,0x00,0x51,0x04,0x0b,0x00,0x10,0x04,0x0b,0x00,0x00,0x00,0x92,0x0c,0x51,0x04,
+       0x00,0x00,0x10,0x04,0x00,0x00,0x0b,0x00,0x0b,0x00,0x0b,0x00,0x54,0x04,0x0b,0x00,
+       0x53,0x04,0x0b,0x00,0x12,0x04,0x0b,0x00,0x00,0x00,0xd0,0x08,0xcf,0x86,0xcf,0x06,
+       0x01,0x00,0xcf,0x86,0xd5,0x06,0xcf,0x06,0x01,0x00,0xe4,0x9c,0x10,0xe3,0x16,0x08,
+       0xd2,0x06,0xcf,0x06,0x01,0x00,0xe1,0x08,0x04,0xe0,0x04,0x02,0xcf,0x86,0xe5,0x01,
+       0x01,0xd4,0x80,0xd3,0x40,0xd2,0x20,0xd1,0x10,0x10,0x08,0x01,0xff,0xe8,0xb1,0x88,
+       0x00,0x01,0xff,0xe6,0x9b,0xb4,0x00,0x10,0x08,0x01,0xff,0xe8,0xbb,0x8a,0x00,0x01,
+       0xff,0xe8,0xb3,0x88,0x00,0xd1,0x10,0x10,0x08,0x01,0xff,0xe6,0xbb,0x91,0x00,0x01,
+       0xff,0xe4,0xb8,0xb2,0x00,0x10,0x08,0x01,0xff,0xe5,0x8f,0xa5,0x00,0x01,0xff,0xe9,
+       0xbe,0x9c,0x00,0xd2,0x20,0xd1,0x10,0x10,0x08,0x01,0xff,0xe9,0xbe,0x9c,0x00,0x01,
+       0xff,0xe5,0xa5,0x91,0x00,0x10,0x08,0x01,0xff,0xe9,0x87,0x91,0x00,0x01,0xff,0xe5,
+       0x96,0x87,0x00,0xd1,0x10,0x10,0x08,0x01,0xff,0xe5,0xa5,0x88,0x00,0x01,0xff,0xe6,
+       0x87,0xb6,0x00,0x10,0x08,0x01,0xff,0xe7,0x99,0xa9,0x00,0x01,0xff,0xe7,0xbe,0x85,
+       0x00,0xd3,0x40,0xd2,0x20,0xd1,0x10,0x10,0x08,0x01,0xff,0xe8,0x98,0xbf,0x00,0x01,
+       0xff,0xe8,0x9e,0xba,0x00,0x10,0x08,0x01,0xff,0xe8,0xa3,0xb8,0x00,0x01,0xff,0xe9,
+       0x82,0x8f,0x00,0xd1,0x10,0x10,0x08,0x01,0xff,0xe6,0xa8,0x82,0x00,0x01,0xff,0xe6,
+       0xb4,0x9b,0x00,0x10,0x08,0x01,0xff,0xe7,0x83,0x99,0x00,0x01,0xff,0xe7,0x8f,0x9e,
+       0x00,0xd2,0x20,0xd1,0x10,0x10,0x08,0x01,0xff,0xe8,0x90,0xbd,0x00,0x01,0xff,0xe9,
+       0x85,0xaa,0x00,0x10,0x08,0x01,0xff,0xe9,0xa7,0xb1,0x00,0x01,0xff,0xe4,0xba,0x82,
+       0x00,0xd1,0x10,0x10,0x08,0x01,0xff,0xe5,0x8d,0xb5,0x00,0x01,0xff,0xe6,0xac,0x84,
+       0x00,0x10,0x08,0x01,0xff,0xe7,0x88,0x9b,0x00,0x01,0xff,0xe8,0x98,0xad,0x00,0xd4,
+       0x80,0xd3,0x40,0xd2,0x20,0xd1,0x10,0x10,0x08,0x01,0xff,0xe9,0xb8,0x9e,0x00,0x01,
+       0xff,0xe5,0xb5,0x90,0x00,0x10,0x08,0x01,0xff,0xe6,0xbf,0xab,0x00,0x01,0xff,0xe8,
+       0x97,0x8d,0x00,0xd1,0x10,0x10,0x08,0x01,0xff,0xe8,0xa5,0xa4,0x00,0x01,0xff,0xe6,
+       0x8b,0x89,0x00,0x10,0x08,0x01,0xff,0xe8,0x87,0x98,0x00,0x01,0xff,0xe8,0xa0,0x9f,
+       0x00,0xd2,0x20,0xd1,0x10,0x10,0x08,0x01,0xff,0xe5,0xbb,0x8a,0x00,0x01,0xff,0xe6,
+       0x9c,0x97,0x00,0x10,0x08,0x01,0xff,0xe6,0xb5,0xaa,0x00,0x01,0xff,0xe7,0x8b,0xbc,
+       0x00,0xd1,0x10,0x10,0x08,0x01,0xff,0xe9,0x83,0x8e,0x00,0x01,0xff,0xe4,0xbe,0x86,
+       0x00,0x10,0x08,0x01,0xff,0xe5,0x86,0xb7,0x00,0x01,0xff,0xe5,0x8b,0x9e,0x00,0xd3,
+       0x40,0xd2,0x20,0xd1,0x10,0x10,0x08,0x01,0xff,0xe6,0x93,0x84,0x00,0x01,0xff,0xe6,
+       0xab,0x93,0x00,0x10,0x08,0x01,0xff,0xe7,0x88,0x90,0x00,0x01,0xff,0xe7,0x9b,0xa7,
+       0x00,0xd1,0x10,0x10,0x08,0x01,0xff,0xe8,0x80,0x81,0x00,0x01,0xff,0xe8,0x98,0x86,
+       0x00,0x10,0x08,0x01,0xff,0xe8,0x99,0x9c,0x00,0x01,0xff,0xe8,0xb7,0xaf,0x00,0xd2,
+       0x20,0xd1,0x10,0x10,0x08,0x01,0xff,0xe9,0x9c,0xb2,0x00,0x01,0xff,0xe9,0xad,0xaf,
+       0x00,0x10,0x08,0x01,0xff,0xe9,0xb7,0xba,0x00,0x01,0xff,0xe7,0xa2,0x8c,0x00,0xd1,
+       0x10,0x10,0x08,0x01,0xff,0xe7,0xa5,0xbf,0x00,0x01,0xff,0xe7,0xb6,0xa0,0x00,0x10,
+       0x08,0x01,0xff,0xe8,0x8f,0x89,0x00,0x01,0xff,0xe9,0x8c,0x84,0x00,0xcf,0x86,0xe5,
+       0x01,0x01,0xd4,0x80,0xd3,0x40,0xd2,0x20,0xd1,0x10,0x10,0x08,0x01,0xff,0xe9,0xb9,
+       0xbf,0x00,0x01,0xff,0xe8,0xab,0x96,0x00,0x10,0x08,0x01,0xff,0xe5,0xa3,0x9f,0x00,
+       0x01,0xff,0xe5,0xbc,0x84,0x00,0xd1,0x10,0x10,0x08,0x01,0xff,0xe7,0xb1,0xa0,0x00,
+       0x01,0xff,0xe8,0x81,0xbe,0x00,0x10,0x08,0x01,0xff,0xe7,0x89,0xa2,0x00,0x01,0xff,
+       0xe7,0xa3,0x8a,0x00,0xd2,0x20,0xd1,0x10,0x10,0x08,0x01,0xff,0xe8,0xb3,0x82,0x00,
+       0x01,0xff,0xe9,0x9b,0xb7,0x00,0x10,0x08,0x01,0xff,0xe5,0xa3,0x98,0x00,0x01,0xff,
+       0xe5,0xb1,0xa2,0x00,0xd1,0x10,0x10,0x08,0x01,0xff,0xe6,0xa8,0x93,0x00,0x01,0xff,
+       0xe6,0xb7,0x9a,0x00,0x10,0x08,0x01,0xff,0xe6,0xbc,0x8f,0x00,0x01,0xff,0xe7,0xb4,
+       0xaf,0x00,0xd3,0x40,0xd2,0x20,0xd1,0x10,0x10,0x08,0x01,0xff,0xe7,0xb8,0xb7,0x00,
+       0x01,0xff,0xe9,0x99,0x8b,0x00,0x10,0x08,0x01,0xff,0xe5,0x8b,0x92,0x00,0x01,0xff,
+       0xe8,0x82,0x8b,0x00,0xd1,0x10,0x10,0x08,0x01,0xff,0xe5,0x87,0x9c,0x00,0x01,0xff,
+       0xe5,0x87,0x8c,0x00,0x10,0x08,0x01,0xff,0xe7,0xa8,0x9c,0x00,0x01,0xff,0xe7,0xb6,
+       0xbe,0x00,0xd2,0x20,0xd1,0x10,0x10,0x08,0x01,0xff,0xe8,0x8f,0xb1,0x00,0x01,0xff,
+       0xe9,0x99,0xb5,0x00,0x10,0x08,0x01,0xff,0xe8,0xae,0x80,0x00,0x01,0xff,0xe6,0x8b,
+       0x8f,0x00,0xd1,0x10,0x10,0x08,0x01,0xff,0xe6,0xa8,0x82,0x00,0x01,0xff,0xe8,0xab,
+       0xbe,0x00,0x10,0x08,0x01,0xff,0xe4,0xb8,0xb9,0x00,0x01,0xff,0xe5,0xaf,0xa7,0x00,
+       0xd4,0x80,0xd3,0x40,0xd2,0x20,0xd1,0x10,0x10,0x08,0x01,0xff,0xe6,0x80,0x92,0x00,
+       0x01,0xff,0xe7,0x8e,0x87,0x00,0x10,0x08,0x01,0xff,0xe7,0x95,0xb0,0x00,0x01,0xff,
+       0xe5,0x8c,0x97,0x00,0xd1,0x10,0x10,0x08,0x01,0xff,0xe7,0xa3,0xbb,0x00,0x01,0xff,
+       0xe4,0xbe,0xbf,0x00,0x10,0x08,0x01,0xff,0xe5,0xbe,0xa9,0x00,0x01,0xff,0xe4,0xb8,
+       0x8d,0x00,0xd2,0x20,0xd1,0x10,0x10,0x08,0x01,0xff,0xe6,0xb3,0x8c,0x00,0x01,0xff,
+       0xe6,0x95,0xb8,0x00,0x10,0x08,0x01,0xff,0xe7,0xb4,0xa2,0x00,0x01,0xff,0xe5,0x8f,
+       0x83,0x00,0xd1,0x10,0x10,0x08,0x01,0xff,0xe5,0xa1,0x9e,0x00,0x01,0xff,0xe7,0x9c,
+       0x81,0x00,0x10,0x08,0x01,0xff,0xe8,0x91,0x89,0x00,0x01,0xff,0xe8,0xaa,0xaa,0x00,
+       0xd3,0x40,0xd2,0x20,0xd1,0x10,0x10,0x08,0x01,0xff,0xe6,0xae,0xba,0x00,0x01,0xff,
+       0xe8,0xbe,0xb0,0x00,0x10,0x08,0x01,0xff,0xe6,0xb2,0x88,0x00,0x01,0xff,0xe6,0x8b,
+       0xbe,0x00,0xd1,0x10,0x10,0x08,0x01,0xff,0xe8,0x8b,0xa5,0x00,0x01,0xff,0xe6,0x8e,
+       0xa0,0x00,0x10,0x08,0x01,0xff,0xe7,0x95,0xa5,0x00,0x01,0xff,0xe4,0xba,0xae,0x00,
+       0xd2,0x20,0xd1,0x10,0x10,0x08,0x01,0xff,0xe5,0x85,0xa9,0x00,0x01,0xff,0xe5,0x87,
+       0x89,0x00,0x10,0x08,0x01,0xff,0xe6,0xa2,0x81,0x00,0x01,0xff,0xe7,0xb3,0xa7,0x00,
+       0xd1,0x10,0x10,0x08,0x01,0xff,0xe8,0x89,0xaf,0x00,0x01,0xff,0xe8,0xab,0x92,0x00,
+       0x10,0x08,0x01,0xff,0xe9,0x87,0x8f,0x00,0x01,0xff,0xe5,0x8b,0xb5,0x00,0xe0,0x04,
+       0x02,0xcf,0x86,0xe5,0x01,0x01,0xd4,0x80,0xd3,0x40,0xd2,0x20,0xd1,0x10,0x10,0x08,
+       0x01,0xff,0xe5,0x91,0x82,0x00,0x01,0xff,0xe5,0xa5,0xb3,0x00,0x10,0x08,0x01,0xff,
+       0xe5,0xbb,0xac,0x00,0x01,0xff,0xe6,0x97,0x85,0x00,0xd1,0x10,0x10,0x08,0x01,0xff,
+       0xe6,0xbf,0xbe,0x00,0x01,0xff,0xe7,0xa4,0xaa,0x00,0x10,0x08,0x01,0xff,0xe9,0x96,
+       0xad,0x00,0x01,0xff,0xe9,0xa9,0xaa,0x00,0xd2,0x20,0xd1,0x10,0x10,0x08,0x01,0xff,
+       0xe9,0xba,0x97,0x00,0x01,0xff,0xe9,0xbb,0x8e,0x00,0x10,0x08,0x01,0xff,0xe5,0x8a,
+       0x9b,0x00,0x01,0xff,0xe6,0x9b,0x86,0x00,0xd1,0x10,0x10,0x08,0x01,0xff,0xe6,0xad,
+       0xb7,0x00,0x01,0xff,0xe8,0xbd,0xa2,0x00,0x10,0x08,0x01,0xff,0xe5,0xb9,0xb4,0x00,
+       0x01,0xff,0xe6,0x86,0x90,0x00,0xd3,0x40,0xd2,0x20,0xd1,0x10,0x10,0x08,0x01,0xff,
+       0xe6,0x88,0x80,0x00,0x01,0xff,0xe6,0x92,0x9a,0x00,0x10,0x08,0x01,0xff,0xe6,0xbc,
+       0xa3,0x00,0x01,0xff,0xe7,0x85,0x89,0x00,0xd1,0x10,0x10,0x08,0x01,0xff,0xe7,0x92,
+       0x89,0x00,0x01,0xff,0xe7,0xa7,0x8a,0x00,0x10,0x08,0x01,0xff,0xe7,0xb7,0xb4,0x00,
+       0x01,0xff,0xe8,0x81,0xaf,0x00,0xd2,0x20,0xd1,0x10,0x10,0x08,0x01,0xff,0xe8,0xbc,
+       0xa6,0x00,0x01,0xff,0xe8,0x93,0xae,0x00,0x10,0x08,0x01,0xff,0xe9,0x80,0xa3,0x00,
+       0x01,0xff,0xe9,0x8d,0x8a,0x00,0xd1,0x10,0x10,0x08,0x01,0xff,0xe5,0x88,0x97,0x00,
+       0x01,0xff,0xe5,0x8a,0xa3,0x00,0x10,0x08,0x01,0xff,0xe5,0x92,0xbd,0x00,0x01,0xff,
+       0xe7,0x83,0x88,0x00,0xd4,0x80,0xd3,0x40,0xd2,0x20,0xd1,0x10,0x10,0x08,0x01,0xff,
+       0xe8,0xa3,0x82,0x00,0x01,0xff,0xe8,0xaa,0xaa,0x00,0x10,0x08,0x01,0xff,0xe5,0xbb,
+       0x89,0x00,0x01,0xff,0xe5,0xbf,0xb5,0x00,0xd1,0x10,0x10,0x08,0x01,0xff,0xe6,0x8d,
+       0xbb,0x00,0x01,0xff,0xe6,0xae,0xae,0x00,0x10,0x08,0x01,0xff,0xe7,0xb0,0xbe,0x00,
+       0x01,0xff,0xe7,0x8d,0xb5,0x00,0xd2,0x20,0xd1,0x10,0x10,0x08,0x01,0xff,0xe4,0xbb,
+       0xa4,0x00,0x01,0xff,0xe5,0x9b,0xb9,0x00,0x10,0x08,0x01,0xff,0xe5,0xaf,0xa7,0x00,
+       0x01,0xff,0xe5,0xb6,0xba,0x00,0xd1,0x10,0x10,0x08,0x01,0xff,0xe6,0x80,0x9c,0x00,
+       0x01,0xff,0xe7,0x8e,0xb2,0x00,0x10,0x08,0x01,0xff,0xe7,0x91,0xa9,0x00,0x01,0xff,
+       0xe7,0xbe,0x9a,0x00,0xd3,0x40,0xd2,0x20,0xd1,0x10,0x10,0x08,0x01,0xff,0xe8,0x81,
+       0x86,0x00,0x01,0xff,0xe9,0x88,0xb4,0x00,0x10,0x08,0x01,0xff,0xe9,0x9b,0xb6,0x00,
+       0x01,0xff,0xe9,0x9d,0x88,0x00,0xd1,0x10,0x10,0x08,0x01,0xff,0xe9,0xa0,0x98,0x00,
+       0x01,0xff,0xe4,0xbe,0x8b,0x00,0x10,0x08,0x01,0xff,0xe7,0xa6,0xae,0x00,0x01,0xff,
+       0xe9,0x86,0xb4,0x00,0xd2,0x20,0xd1,0x10,0x10,0x08,0x01,0xff,0xe9,0x9a,0xb8,0x00,
+       0x01,0xff,0xe6,0x83,0xa1,0x00,0x10,0x08,0x01,0xff,0xe4,0xba,0x86,0x00,0x01,0xff,
+       0xe5,0x83,0x9a,0x00,0xd1,0x10,0x10,0x08,0x01,0xff,0xe5,0xaf,0xae,0x00,0x01,0xff,
+       0xe5,0xb0,0xbf,0x00,0x10,0x08,0x01,0xff,0xe6,0x96,0x99,0x00,0x01,0xff,0xe6,0xa8,
+       0x82,0x00,0xcf,0x86,0xe5,0x01,0x01,0xd4,0x80,0xd3,0x40,0xd2,0x20,0xd1,0x10,0x10,
+       0x08,0x01,0xff,0xe7,0x87,0x8e,0x00,0x01,0xff,0xe7,0x99,0x82,0x00,0x10,0x08,0x01,
+       0xff,0xe8,0x93,0xbc,0x00,0x01,0xff,0xe9,0x81,0xbc,0x00,0xd1,0x10,0x10,0x08,0x01,
+       0xff,0xe9,0xbe,0x8d,0x00,0x01,0xff,0xe6,0x9a,0x88,0x00,0x10,0x08,0x01,0xff,0xe9,
+       0x98,0xae,0x00,0x01,0xff,0xe5,0x8a,0x89,0x00,0xd2,0x20,0xd1,0x10,0x10,0x08,0x01,
+       0xff,0xe6,0x9d,0xbb,0x00,0x01,0xff,0xe6,0x9f,0xb3,0x00,0x10,0x08,0x01,0xff,0xe6,
+       0xb5,0x81,0x00,0x01,0xff,0xe6,0xba,0x9c,0x00,0xd1,0x10,0x10,0x08,0x01,0xff,0xe7,
+       0x90,0x89,0x00,0x01,0xff,0xe7,0x95,0x99,0x00,0x10,0x08,0x01,0xff,0xe7,0xa1,0xab,
+       0x00,0x01,0xff,0xe7,0xb4,0x90,0x00,0xd3,0x40,0xd2,0x20,0xd1,0x10,0x10,0x08,0x01,
+       0xff,0xe9,0xa1,0x9e,0x00,0x01,0xff,0xe5,0x85,0xad,0x00,0x10,0x08,0x01,0xff,0xe6,
+       0x88,0xae,0x00,0x01,0xff,0xe9,0x99,0xb8,0x00,0xd1,0x10,0x10,0x08,0x01,0xff,0xe5,
+       0x80,0xab,0x00,0x01,0xff,0xe5,0xb4,0x99,0x00,0x10,0x08,0x01,0xff,0xe6,0xb7,0xaa,
+       0x00,0x01,0xff,0xe8,0xbc,0xaa,0x00,0xd2,0x20,0xd1,0x10,0x10,0x08,0x01,0xff,0xe5,
+       0xbe,0x8b,0x00,0x01,0xff,0xe6,0x85,0x84,0x00,0x10,0x08,0x01,0xff,0xe6,0xa0,0x97,
+       0x00,0x01,0xff,0xe7,0x8e,0x87,0x00,0xd1,0x10,0x10,0x08,0x01,0xff,0xe9,0x9a,0x86,
+       0x00,0x01,0xff,0xe5,0x88,0xa9,0x00,0x10,0x08,0x01,0xff,0xe5,0x90,0x8f,0x00,0x01,
+       0xff,0xe5,0xb1,0xa5,0x00,0xd4,0x80,0xd3,0x40,0xd2,0x20,0xd1,0x10,0x10,0x08,0x01,
+       0xff,0xe6,0x98,0x93,0x00,0x01,0xff,0xe6,0x9d,0x8e,0x00,0x10,0x08,0x01,0xff,0xe6,
+       0xa2,0xa8,0x00,0x01,0xff,0xe6,0xb3,0xa5,0x00,0xd1,0x10,0x10,0x08,0x01,0xff,0xe7,
+       0x90,0x86,0x00,0x01,0xff,0xe7,0x97,0xa2,0x00,0x10,0x08,0x01,0xff,0xe7,0xbd,0xb9,
+       0x00,0x01,0xff,0xe8,0xa3,0x8f,0x00,0xd2,0x20,0xd1,0x10,0x10,0x08,0x01,0xff,0xe8,
+       0xa3,0xa1,0x00,0x01,0xff,0xe9,0x87,0x8c,0x00,0x10,0x08,0x01,0xff,0xe9,0x9b,0xa2,
+       0x00,0x01,0xff,0xe5,0x8c,0xbf,0x00,0xd1,0x10,0x10,0x08,0x01,0xff,0xe6,0xba,0xba,
+       0x00,0x01,0xff,0xe5,0x90,0x9d,0x00,0x10,0x08,0x01,0xff,0xe7,0x87,0x90,0x00,0x01,
+       0xff,0xe7,0x92,0x98,0x00,0xd3,0x40,0xd2,0x20,0xd1,0x10,0x10,0x08,0x01,0xff,0xe8,
+       0x97,0xba,0x00,0x01,0xff,0xe9,0x9a,0xa3,0x00,0x10,0x08,0x01,0xff,0xe9,0xb1,0x97,
+       0x00,0x01,0xff,0xe9,0xba,0x9f,0x00,0xd1,0x10,0x10,0x08,0x01,0xff,0xe6,0x9e,0x97,
+       0x00,0x01,0xff,0xe6,0xb7,0x8b,0x00,0x10,0x08,0x01,0xff,0xe8,0x87,0xa8,0x00,0x01,
+       0xff,0xe7,0xab,0x8b,0x00,0xd2,0x20,0xd1,0x10,0x10,0x08,0x01,0xff,0xe7,0xac,0xa0,
+       0x00,0x01,0xff,0xe7,0xb2,0x92,0x00,0x10,0x08,0x01,0xff,0xe7,0x8b,0x80,0x00,0x01,
+       0xff,0xe7,0x82,0x99,0x00,0xd1,0x10,0x10,0x08,0x01,0xff,0xe8,0xad,0x98,0x00,0x01,
+       0xff,0xe4,0xbb,0x80,0x00,0x10,0x08,0x01,0xff,0xe8,0x8c,0xb6,0x00,0x01,0xff,0xe5,
+       0x88,0xba,0x00,0xe2,0xad,0x06,0xe1,0xc4,0x03,0xe0,0xcb,0x01,0xcf,0x86,0xd5,0xe4,
+       0xd4,0x74,0xd3,0x40,0xd2,0x20,0xd1,0x10,0x10,0x08,0x01,0xff,0xe5,0x88,0x87,0x00,
+       0x01,0xff,0xe5,0xba,0xa6,0x00,0x10,0x08,0x01,0xff,0xe6,0x8b,0x93,0x00,0x01,0xff,
+       0xe7,0xb3,0x96,0x00,0xd1,0x10,0x10,0x08,0x01,0xff,0xe5,0xae,0x85,0x00,0x01,0xff,
+       0xe6,0xb4,0x9e,0x00,0x10,0x08,0x01,0xff,0xe6,0x9a,0xb4,0x00,0x01,0xff,0xe8,0xbc,
+       0xbb,0x00,0xd2,0x20,0xd1,0x10,0x10,0x08,0x01,0xff,0xe8,0xa1,0x8c,0x00,0x01,0xff,
+       0xe9,0x99,0x8d,0x00,0x10,0x08,0x01,0xff,0xe8,0xa6,0x8b,0x00,0x01,0xff,0xe5,0xbb,
+       0x93,0x00,0x91,0x10,0x10,0x08,0x01,0xff,0xe5,0x85,0x80,0x00,0x01,0xff,0xe5,0x97,
+       0x80,0x00,0x01,0x00,0xd3,0x34,0xd2,0x18,0xd1,0x0c,0x10,0x08,0x01,0xff,0xe5,0xa1,
+       0x9a,0x00,0x01,0x00,0x10,0x08,0x01,0xff,0xe6,0x99,0xb4,0x00,0x01,0x00,0xd1,0x0c,
+       0x10,0x04,0x01,0x00,0x01,0xff,0xe5,0x87,0x9e,0x00,0x10,0x08,0x01,0xff,0xe7,0x8c,
+       0xaa,0x00,0x01,0xff,0xe7,0x9b,0x8a,0x00,0xd2,0x20,0xd1,0x10,0x10,0x08,0x01,0xff,
+       0xe7,0xa4,0xbc,0x00,0x01,0xff,0xe7,0xa5,0x9e,0x00,0x10,0x08,0x01,0xff,0xe7,0xa5,
+       0xa5,0x00,0x01,0xff,0xe7,0xa6,0x8f,0x00,0xd1,0x10,0x10,0x08,0x01,0xff,0xe9,0x9d,
+       0x96,0x00,0x01,0xff,0xe7,0xb2,0xbe,0x00,0x10,0x08,0x01,0xff,0xe7,0xbe,0xbd,0x00,
+       0x01,0x00,0xd4,0x64,0xd3,0x30,0xd2,0x18,0xd1,0x0c,0x10,0x08,0x01,0xff,0xe8,0x98,
+       0x92,0x00,0x01,0x00,0x10,0x08,0x01,0xff,0xe8,0xab,0xb8,0x00,0x01,0x00,0xd1,0x0c,
+       0x10,0x04,0x01,0x00,0x01,0xff,0xe9,0x80,0xb8,0x00,0x10,0x08,0x01,0xff,0xe9,0x83,
+       0xbd,0x00,0x01,0x00,0xd2,0x14,0x51,0x04,0x01,0x00,0x10,0x08,0x01,0xff,0xe9,0xa3,
+       0xaf,0x00,0x01,0xff,0xe9,0xa3,0xbc,0x00,0xd1,0x10,0x10,0x08,0x01,0xff,0xe9,0xa4,
+       0xa8,0x00,0x01,0xff,0xe9,0xb6,0xb4,0x00,0x10,0x08,0x0d,0xff,0xe9,0x83,0x9e,0x00,
+       0x0d,0xff,0xe9,0x9a,0xb7,0x00,0xd3,0x40,0xd2,0x20,0xd1,0x10,0x10,0x08,0x06,0xff,
+       0xe4,0xbe,0xae,0x00,0x06,0xff,0xe5,0x83,0xa7,0x00,0x10,0x08,0x06,0xff,0xe5,0x85,
+       0x8d,0x00,0x06,0xff,0xe5,0x8b,0x89,0x00,0xd1,0x10,0x10,0x08,0x06,0xff,0xe5,0x8b,
+       0xa4,0x00,0x06,0xff,0xe5,0x8d,0x91,0x00,0x10,0x08,0x06,0xff,0xe5,0x96,0x9d,0x00,
+       0x06,0xff,0xe5,0x98,0x86,0x00,0xd2,0x20,0xd1,0x10,0x10,0x08,0x06,0xff,0xe5,0x99,
+       0xa8,0x00,0x06,0xff,0xe5,0xa1,0x80,0x00,0x10,0x08,0x06,0xff,0xe5,0xa2,0xa8,0x00,
+       0x06,0xff,0xe5,0xb1,0xa4,0x00,0xd1,0x10,0x10,0x08,0x06,0xff,0xe5,0xb1,0xae,0x00,
+       0x06,0xff,0xe6,0x82,0x94,0x00,0x10,0x08,0x06,0xff,0xe6,0x85,0xa8,0x00,0x06,0xff,
+       0xe6,0x86,0x8e,0x00,0xcf,0x86,0xe5,0x01,0x01,0xd4,0x80,0xd3,0x40,0xd2,0x20,0xd1,
+       0x10,0x10,0x08,0x06,0xff,0xe6,0x87,0xb2,0x00,0x06,0xff,0xe6,0x95,0x8f,0x00,0x10,
+       0x08,0x06,0xff,0xe6,0x97,0xa2,0x00,0x06,0xff,0xe6,0x9a,0x91,0x00,0xd1,0x10,0x10,
+       0x08,0x06,0xff,0xe6,0xa2,0x85,0x00,0x06,0xff,0xe6,0xb5,0xb7,0x00,0x10,0x08,0x06,
+       0xff,0xe6,0xb8,0x9a,0x00,0x06,0xff,0xe6,0xbc,0xa2,0x00,0xd2,0x20,0xd1,0x10,0x10,
+       0x08,0x06,0xff,0xe7,0x85,0xae,0x00,0x06,0xff,0xe7,0x88,0xab,0x00,0x10,0x08,0x06,
+       0xff,0xe7,0x90,0xa2,0x00,0x06,0xff,0xe7,0xa2,0x91,0x00,0xd1,0x10,0x10,0x08,0x06,
+       0xff,0xe7,0xa4,0xbe,0x00,0x06,0xff,0xe7,0xa5,0x89,0x00,0x10,0x08,0x06,0xff,0xe7,
+       0xa5,0x88,0x00,0x06,0xff,0xe7,0xa5,0x90,0x00,0xd3,0x40,0xd2,0x20,0xd1,0x10,0x10,
+       0x08,0x06,0xff,0xe7,0xa5,0x96,0x00,0x06,0xff,0xe7,0xa5,0x9d,0x00,0x10,0x08,0x06,
+       0xff,0xe7,0xa6,0x8d,0x00,0x06,0xff,0xe7,0xa6,0x8e,0x00,0xd1,0x10,0x10,0x08,0x06,
+       0xff,0xe7,0xa9,0x80,0x00,0x06,0xff,0xe7,0xaa,0x81,0x00,0x10,0x08,0x06,0xff,0xe7,
+       0xaf,0x80,0x00,0x06,0xff,0xe7,0xb7,0xb4,0x00,0xd2,0x20,0xd1,0x10,0x10,0x08,0x06,
+       0xff,0xe7,0xb8,0x89,0x00,0x06,0xff,0xe7,0xb9,0x81,0x00,0x10,0x08,0x06,0xff,0xe7,
+       0xbd,0xb2,0x00,0x06,0xff,0xe8,0x80,0x85,0x00,0xd1,0x10,0x10,0x08,0x06,0xff,0xe8,
+       0x87,0xad,0x00,0x06,0xff,0xe8,0x89,0xb9,0x00,0x10,0x08,0x06,0xff,0xe8,0x89,0xb9,
+       0x00,0x06,0xff,0xe8,0x91,0x97,0x00,0xd4,0x75,0xd3,0x40,0xd2,0x20,0xd1,0x10,0x10,
+       0x08,0x06,0xff,0xe8,0xa4,0x90,0x00,0x06,0xff,0xe8,0xa6,0x96,0x00,0x10,0x08,0x06,
+       0xff,0xe8,0xac,0x81,0x00,0x06,0xff,0xe8,0xac,0xb9,0x00,0xd1,0x10,0x10,0x08,0x06,
+       0xff,0xe8,0xb3,0x93,0x00,0x06,0xff,0xe8,0xb4,0x88,0x00,0x10,0x08,0x06,0xff,0xe8,
+       0xbe,0xb6,0x00,0x06,0xff,0xe9,0x80,0xb8,0x00,0xd2,0x20,0xd1,0x10,0x10,0x08,0x06,
+       0xff,0xe9,0x9b,0xa3,0x00,0x06,0xff,0xe9,0x9f,0xbf,0x00,0x10,0x08,0x06,0xff,0xe9,
+       0xa0,0xbb,0x00,0x0b,0xff,0xe6,0x81,0xb5,0x00,0x91,0x11,0x10,0x09,0x0b,0xff,0xf0,
+       0xa4,0x8b,0xae,0x00,0x0b,0xff,0xe8,0x88,0x98,0x00,0x00,0x00,0xd3,0x40,0xd2,0x20,
+       0xd1,0x10,0x10,0x08,0x08,0xff,0xe4,0xb8,0xa6,0x00,0x08,0xff,0xe5,0x86,0xb5,0x00,
+       0x10,0x08,0x08,0xff,0xe5,0x85,0xa8,0x00,0x08,0xff,0xe4,0xbe,0x80,0x00,0xd1,0x10,
+       0x10,0x08,0x08,0xff,0xe5,0x85,0x85,0x00,0x08,0xff,0xe5,0x86,0x80,0x00,0x10,0x08,
+       0x08,0xff,0xe5,0x8b,0x87,0x00,0x08,0xff,0xe5,0x8b,0xba,0x00,0xd2,0x20,0xd1,0x10,
+       0x10,0x08,0x08,0xff,0xe5,0x96,0x9d,0x00,0x08,0xff,0xe5,0x95,0x95,0x00,0x10,0x08,
+       0x08,0xff,0xe5,0x96,0x99,0x00,0x08,0xff,0xe5,0x97,0xa2,0x00,0xd1,0x10,0x10,0x08,
+       0x08,0xff,0xe5,0xa1,0x9a,0x00,0x08,0xff,0xe5,0xa2,0xb3,0x00,0x10,0x08,0x08,0xff,
+       0xe5,0xa5,0x84,0x00,0x08,0xff,0xe5,0xa5,0x94,0x00,0xe0,0x04,0x02,0xcf,0x86,0xe5,
+       0x01,0x01,0xd4,0x80,0xd3,0x40,0xd2,0x20,0xd1,0x10,0x10,0x08,0x08,0xff,0xe5,0xa9,
+       0xa2,0x00,0x08,0xff,0xe5,0xac,0xa8,0x00,0x10,0x08,0x08,0xff,0xe5,0xbb,0x92,0x00,
+       0x08,0xff,0xe5,0xbb,0x99,0x00,0xd1,0x10,0x10,0x08,0x08,0xff,0xe5,0xbd,0xa9,0x00,
+       0x08,0xff,0xe5,0xbe,0xad,0x00,0x10,0x08,0x08,0xff,0xe6,0x83,0x98,0x00,0x08,0xff,
+       0xe6,0x85,0x8e,0x00,0xd2,0x20,0xd1,0x10,0x10,0x08,0x08,0xff,0xe6,0x84,0x88,0x00,
+       0x08,0xff,0xe6,0x86,0x8e,0x00,0x10,0x08,0x08,0xff,0xe6,0x85,0xa0,0x00,0x08,0xff,
+       0xe6,0x87,0xb2,0x00,0xd1,0x10,0x10,0x08,0x08,0xff,0xe6,0x88,0xb4,0x00,0x08,0xff,
+       0xe6,0x8f,0x84,0x00,0x10,0x08,0x08,0xff,0xe6,0x90,0x9c,0x00,0x08,0xff,0xe6,0x91,
+       0x92,0x00,0xd3,0x40,0xd2,0x20,0xd1,0x10,0x10,0x08,0x08,0xff,0xe6,0x95,0x96,0x00,
+       0x08,0xff,0xe6,0x99,0xb4,0x00,0x10,0x08,0x08,0xff,0xe6,0x9c,0x97,0x00,0x08,0xff,
+       0xe6,0x9c,0x9b,0x00,0xd1,0x10,0x10,0x08,0x08,0xff,0xe6,0x9d,0x96,0x00,0x08,0xff,
+       0xe6,0xad,0xb9,0x00,0x10,0x08,0x08,0xff,0xe6,0xae,0xba,0x00,0x08,0xff,0xe6,0xb5,
+       0x81,0x00,0xd2,0x20,0xd1,0x10,0x10,0x08,0x08,0xff,0xe6,0xbb,0x9b,0x00,0x08,0xff,
+       0xe6,0xbb,0x8b,0x00,0x10,0x08,0x08,0xff,0xe6,0xbc,0xa2,0x00,0x08,0xff,0xe7,0x80,
+       0x9e,0x00,0xd1,0x10,0x10,0x08,0x08,0xff,0xe7,0x85,0xae,0x00,0x08,0xff,0xe7,0x9e,
+       0xa7,0x00,0x10,0x08,0x08,0xff,0xe7,0x88,0xb5,0x00,0x08,0xff,0xe7,0x8a,0xaf,0x00,
+       0xd4,0x80,0xd3,0x40,0xd2,0x20,0xd1,0x10,0x10,0x08,0x08,0xff,0xe7,0x8c,0xaa,0x00,
+       0x08,0xff,0xe7,0x91,0xb1,0x00,0x10,0x08,0x08,0xff,0xe7,0x94,0x86,0x00,0x08,0xff,
+       0xe7,0x94,0xbb,0x00,0xd1,0x10,0x10,0x08,0x08,0xff,0xe7,0x98,0x9d,0x00,0x08,0xff,
+       0xe7,0x98,0x9f,0x00,0x10,0x08,0x08,0xff,0xe7,0x9b,0x8a,0x00,0x08,0xff,0xe7,0x9b,
+       0x9b,0x00,0xd2,0x20,0xd1,0x10,0x10,0x08,0x08,0xff,0xe7,0x9b,0xb4,0x00,0x08,0xff,
+       0xe7,0x9d,0x8a,0x00,0x10,0x08,0x08,0xff,0xe7,0x9d,0x80,0x00,0x08,0xff,0xe7,0xa3,
+       0x8c,0x00,0xd1,0x10,0x10,0x08,0x08,0xff,0xe7,0xaa,0xb1,0x00,0x08,0xff,0xe7,0xaf,
+       0x80,0x00,0x10,0x08,0x08,0xff,0xe7,0xb1,0xbb,0x00,0x08,0xff,0xe7,0xb5,0x9b,0x00,
+       0xd3,0x40,0xd2,0x20,0xd1,0x10,0x10,0x08,0x08,0xff,0xe7,0xb7,0xb4,0x00,0x08,0xff,
+       0xe7,0xbc,0xbe,0x00,0x10,0x08,0x08,0xff,0xe8,0x80,0x85,0x00,0x08,0xff,0xe8,0x8d,
+       0x92,0x00,0xd1,0x10,0x10,0x08,0x08,0xff,0xe8,0x8f,0xaf,0x00,0x08,0xff,0xe8,0x9d,
+       0xb9,0x00,0x10,0x08,0x08,0xff,0xe8,0xa5,0x81,0x00,0x08,0xff,0xe8,0xa6,0x86,0x00,
+       0xd2,0x20,0xd1,0x10,0x10,0x08,0x08,0xff,0xe8,0xa6,0x96,0x00,0x08,0xff,0xe8,0xaa,
+       0xbf,0x00,0x10,0x08,0x08,0xff,0xe8,0xab,0xb8,0x00,0x08,0xff,0xe8,0xab,0x8b,0x00,
+       0xd1,0x10,0x10,0x08,0x08,0xff,0xe8,0xac,0x81,0x00,0x08,0xff,0xe8,0xab,0xbe,0x00,
+       0x10,0x08,0x08,0xff,0xe8,0xab,0xad,0x00,0x08,0xff,0xe8,0xac,0xb9,0x00,0xcf,0x86,
+       0x95,0xde,0xd4,0x81,0xd3,0x40,0xd2,0x20,0xd1,0x10,0x10,0x08,0x08,0xff,0xe8,0xae,
+       0x8a,0x00,0x08,0xff,0xe8,0xb4,0x88,0x00,0x10,0x08,0x08,0xff,0xe8,0xbc,0xb8,0x00,
+       0x08,0xff,0xe9,0x81,0xb2,0x00,0xd1,0x10,0x10,0x08,0x08,0xff,0xe9,0x86,0x99,0x00,
+       0x08,0xff,0xe9,0x89,0xb6,0x00,0x10,0x08,0x08,0xff,0xe9,0x99,0xbc,0x00,0x08,0xff,
+       0xe9,0x9b,0xa3,0x00,0xd2,0x20,0xd1,0x10,0x10,0x08,0x08,0xff,0xe9,0x9d,0x96,0x00,
+       0x08,0xff,0xe9,0x9f,0x9b,0x00,0x10,0x08,0x08,0xff,0xe9,0x9f,0xbf,0x00,0x08,0xff,
+       0xe9,0xa0,0x8b,0x00,0xd1,0x10,0x10,0x08,0x08,0xff,0xe9,0xa0,0xbb,0x00,0x08,0xff,
+       0xe9,0xac,0x92,0x00,0x10,0x08,0x08,0xff,0xe9,0xbe,0x9c,0x00,0x08,0xff,0xf0,0xa2,
+       0xa1,0x8a,0x00,0xd3,0x45,0xd2,0x22,0xd1,0x12,0x10,0x09,0x08,0xff,0xf0,0xa2,0xa1,
+       0x84,0x00,0x08,0xff,0xf0,0xa3,0x8f,0x95,0x00,0x10,0x08,0x08,0xff,0xe3,0xae,0x9d,
+       0x00,0x08,0xff,0xe4,0x80,0x98,0x00,0xd1,0x11,0x10,0x08,0x08,0xff,0xe4,0x80,0xb9,
+       0x00,0x08,0xff,0xf0,0xa5,0x89,0x89,0x00,0x10,0x09,0x08,0xff,0xf0,0xa5,0xb3,0x90,
+       0x00,0x08,0xff,0xf0,0xa7,0xbb,0x93,0x00,0x92,0x14,0x91,0x10,0x10,0x08,0x08,0xff,
+       0xe9,0xbd,0x83,0x00,0x08,0xff,0xe9,0xbe,0x8e,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+       0xe1,0x94,0x01,0xe0,0x08,0x01,0xcf,0x86,0xd5,0x42,0xd4,0x14,0x93,0x10,0x52,0x04,
+       0x01,0x00,0x51,0x04,0x01,0x00,0x10,0x04,0x01,0x00,0x00,0x00,0x00,0x00,0xd3,0x10,
+       0x92,0x0c,0x51,0x04,0x00,0x00,0x10,0x04,0x00,0x00,0x01,0x00,0x01,0x00,0x52,0x04,
+       0x00,0x00,0xd1,0x0d,0x10,0x04,0x00,0x00,0x04,0xff,0xd7,0x99,0xd6,0xb4,0x00,0x10,
+       0x04,0x01,0x1a,0x01,0xff,0xd7,0xb2,0xd6,0xb7,0x00,0xd4,0x42,0x53,0x04,0x01,0x00,
+       0xd2,0x16,0x51,0x04,0x01,0x00,0x10,0x09,0x01,0xff,0xd7,0xa9,0xd7,0x81,0x00,0x01,
+       0xff,0xd7,0xa9,0xd7,0x82,0x00,0xd1,0x16,0x10,0x0b,0x01,0xff,0xd7,0xa9,0xd6,0xbc,
+       0xd7,0x81,0x00,0x01,0xff,0xd7,0xa9,0xd6,0xbc,0xd7,0x82,0x00,0x10,0x09,0x01,0xff,
+       0xd7,0x90,0xd6,0xb7,0x00,0x01,0xff,0xd7,0x90,0xd6,0xb8,0x00,0xd3,0x43,0xd2,0x24,
+       0xd1,0x12,0x10,0x09,0x01,0xff,0xd7,0x90,0xd6,0xbc,0x00,0x01,0xff,0xd7,0x91,0xd6,
+       0xbc,0x00,0x10,0x09,0x01,0xff,0xd7,0x92,0xd6,0xbc,0x00,0x01,0xff,0xd7,0x93,0xd6,
+       0xbc,0x00,0xd1,0x12,0x10,0x09,0x01,0xff,0xd7,0x94,0xd6,0xbc,0x00,0x01,0xff,0xd7,
+       0x95,0xd6,0xbc,0x00,0x10,0x09,0x01,0xff,0xd7,0x96,0xd6,0xbc,0x00,0x00,0x00,0xd2,
+       0x24,0xd1,0x12,0x10,0x09,0x01,0xff,0xd7,0x98,0xd6,0xbc,0x00,0x01,0xff,0xd7,0x99,
+       0xd6,0xbc,0x00,0x10,0x09,0x01,0xff,0xd7,0x9a,0xd6,0xbc,0x00,0x01,0xff,0xd7,0x9b,
+       0xd6,0xbc,0x00,0xd1,0x0d,0x10,0x09,0x01,0xff,0xd7,0x9c,0xd6,0xbc,0x00,0x00,0x00,
+       0x10,0x09,0x01,0xff,0xd7,0x9e,0xd6,0xbc,0x00,0x00,0x00,0xcf,0x86,0x95,0x85,0x94,
+       0x81,0xd3,0x3e,0xd2,0x1f,0xd1,0x12,0x10,0x09,0x01,0xff,0xd7,0xa0,0xd6,0xbc,0x00,
+       0x01,0xff,0xd7,0xa1,0xd6,0xbc,0x00,0x10,0x04,0x00,0x00,0x01,0xff,0xd7,0xa3,0xd6,
+       0xbc,0x00,0xd1,0x0d,0x10,0x09,0x01,0xff,0xd7,0xa4,0xd6,0xbc,0x00,0x00,0x00,0x10,
+       0x09,0x01,0xff,0xd7,0xa6,0xd6,0xbc,0x00,0x01,0xff,0xd7,0xa7,0xd6,0xbc,0x00,0xd2,
+       0x24,0xd1,0x12,0x10,0x09,0x01,0xff,0xd7,0xa8,0xd6,0xbc,0x00,0x01,0xff,0xd7,0xa9,
+       0xd6,0xbc,0x00,0x10,0x09,0x01,0xff,0xd7,0xaa,0xd6,0xbc,0x00,0x01,0xff,0xd7,0x95,
+       0xd6,0xb9,0x00,0xd1,0x12,0x10,0x09,0x01,0xff,0xd7,0x91,0xd6,0xbf,0x00,0x01,0xff,
+       0xd7,0x9b,0xd6,0xbf,0x00,0x10,0x09,0x01,0xff,0xd7,0xa4,0xd6,0xbf,0x00,0x01,0x00,
+       0x01,0x00,0x01,0x00,0xd0,0x1a,0xcf,0x86,0x55,0x04,0x01,0x00,0x54,0x04,0x01,0x00,
+       0x93,0x0c,0x92,0x08,0x11,0x04,0x01,0x00,0x0c,0x00,0x0c,0x00,0x0c,0x00,0xcf,0x86,
+       0x95,0x24,0xd4,0x10,0x93,0x0c,0x92,0x08,0x11,0x04,0x0c,0x00,0x00,0x00,0x00,0x00,
+       0x00,0x00,0x93,0x10,0x92,0x0c,0x51,0x04,0x00,0x00,0x10,0x04,0x00,0x00,0x01,0x00,
+       0x01,0x00,0x01,0x00,0x01,0x00,0xd3,0x5a,0xd2,0x06,0xcf,0x06,0x01,0x00,0xd1,0x14,
+       0xd0,0x06,0xcf,0x06,0x01,0x00,0xcf,0x86,0x95,0x08,0x14,0x04,0x00,0x00,0x01,0x00,
+       0x01,0x00,0xd0,0x1a,0xcf,0x86,0x95,0x14,0x54,0x04,0x01,0x00,0x93,0x0c,0x92,0x08,
+       0x11,0x04,0x00,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0xcf,0x86,0xd5,0x0c,
+       0x94,0x08,0x13,0x04,0x01,0x00,0x00,0x00,0x05,0x00,0x54,0x04,0x05,0x00,0x53,0x04,
+       0x01,0x00,0x52,0x04,0x01,0x00,0x91,0x08,0x10,0x04,0x06,0x00,0x07,0x00,0x00,0x00,
+       0xd2,0xcc,0xd1,0xa4,0xd0,0x36,0xcf,0x86,0xd5,0x14,0x54,0x04,0x06,0x00,0x53,0x04,
+       0x08,0x00,0x92,0x08,0x11,0x04,0x08,0x00,0x00,0x00,0x00,0x00,0x94,0x1c,0xd3,0x10,
+       0x52,0x04,0x01,0xe6,0x51,0x04,0x0a,0xe6,0x10,0x04,0x0a,0xe6,0x10,0xdc,0x52,0x04,
+       0x10,0xdc,0x11,0x04,0x10,0xdc,0x11,0xe6,0x01,0x00,0xcf,0x86,0xd5,0x38,0xd4,0x24,
+       0xd3,0x14,0x52,0x04,0x01,0x00,0xd1,0x08,0x10,0x04,0x01,0x00,0x06,0x00,0x10,0x04,
+       0x06,0x00,0x07,0x00,0x92,0x0c,0x91,0x08,0x10,0x04,0x07,0x00,0x01,0x00,0x01,0x00,
+       0x01,0x00,0x93,0x10,0x92,0x0c,0x51,0x04,0x01,0x00,0x10,0x04,0x01,0x00,0x00,0x00,
+       0x01,0x00,0x01,0x00,0xd4,0x18,0xd3,0x10,0x52,0x04,0x01,0x00,0x51,0x04,0x01,0x00,
+       0x10,0x04,0x01,0x00,0x00,0x00,0x12,0x04,0x01,0x00,0x00,0x00,0x93,0x18,0xd2,0x0c,
+       0x51,0x04,0x01,0x00,0x10,0x04,0x01,0x00,0x06,0x00,0x91,0x08,0x10,0x04,0x01,0x00,
+       0x00,0x00,0x01,0x00,0x01,0x00,0xd0,0x06,0xcf,0x06,0x01,0x00,0xcf,0x86,0x55,0x04,
+       0x01,0x00,0x54,0x04,0x01,0x00,0x53,0x04,0x01,0x00,0x52,0x04,0x01,0x00,0xd1,0x08,
+       0x10,0x04,0x01,0x00,0x00,0x00,0x10,0x04,0x00,0x00,0x01,0x00,0xd1,0x50,0xd0,0x1e,
+       0xcf,0x86,0x95,0x18,0x94,0x14,0x93,0x10,0x92,0x0c,0x91,0x08,0x10,0x04,0x00,0x00,
+       0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0xcf,0x86,0xd5,0x18,
+       0x54,0x04,0x01,0x00,0x53,0x04,0x01,0x00,0x52,0x04,0x01,0x00,0x51,0x04,0x01,0x00,
+       0x10,0x04,0x01,0x00,0x06,0x00,0x94,0x14,0x93,0x10,0x92,0x0c,0x91,0x08,0x10,0x04,
+       0x06,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0xd0,0x1e,0xcf,0x86,
+       0x55,0x04,0x01,0x00,0x54,0x04,0x01,0x00,0x53,0x04,0x01,0x00,0x52,0x04,0x01,0x00,
+       0x51,0x04,0x01,0x00,0x10,0x04,0x01,0x00,0x00,0x00,0xcf,0x86,0xd5,0x38,0xd4,0x18,
+       0xd3,0x0c,0x92,0x08,0x11,0x04,0x00,0x00,0x01,0x00,0x01,0x00,0x92,0x08,0x11,0x04,
+       0x00,0x00,0x01,0x00,0x01,0x00,0xd3,0x0c,0x92,0x08,0x11,0x04,0x00,0x00,0x01,0x00,
+       0x01,0x00,0xd2,0x08,0x11,0x04,0x00,0x00,0x01,0x00,0x91,0x08,0x10,0x04,0x01,0x00,
+       0x00,0x00,0x00,0x00,0xd4,0x20,0xd3,0x10,0x52,0x04,0x01,0x00,0x51,0x04,0x01,0x00,
+       0x10,0x04,0x01,0x00,0x00,0x00,0x52,0x04,0x01,0x00,0x51,0x04,0x01,0x00,0x10,0x04,
+       0x01,0x00,0x00,0x00,0x53,0x04,0x00,0x00,0xd2,0x0c,0x91,0x08,0x10,0x04,0x00,0x00,
+       0x04,0x00,0x04,0x00,0x91,0x08,0x10,0x04,0x03,0x00,0x01,0x00,0x01,0x00,0x83,0xe2,
+       0x30,0x3e,0xe1,0x1a,0x3b,0xe0,0x97,0x39,0xcf,0x86,0xe5,0x3b,0x26,0xc4,0xe3,0x16,
+       0x14,0xe2,0xef,0x11,0xe1,0xd0,0x10,0xe0,0x60,0x07,0xcf,0x86,0xe5,0x53,0x03,0xe4,
+       0x4c,0x02,0xe3,0x3d,0x01,0xd2,0x94,0xd1,0x70,0xd0,0x4a,0xcf,0x86,0xd5,0x18,0x94,
+       0x14,0x53,0x04,0x07,0x00,0x52,0x04,0x07,0x00,0x91,0x08,0x10,0x04,0x00,0x00,0x07,
+       0x00,0x07,0x00,0x07,0x00,0xd4,0x14,0x93,0x10,0x52,0x04,0x07,0x00,0x51,0x04,0x07,
+       0x00,0x10,0x04,0x07,0x00,0x00,0x00,0x07,0x00,0x53,0x04,0x07,0x00,0xd2,0x0c,0x51,
+       0x04,0x07,0x00,0x10,0x04,0x07,0x00,0x00,0x00,0x51,0x04,0x07,0x00,0x10,0x04,0x00,
+       0x00,0x07,0x00,0xcf,0x86,0x95,0x20,0xd4,0x10,0x53,0x04,0x07,0x00,0x52,0x04,0x07,
+       0x00,0x11,0x04,0x07,0x00,0x00,0x00,0x53,0x04,0x07,0x00,0x52,0x04,0x07,0x00,0x11,
+       0x04,0x07,0x00,0x00,0x00,0x00,0x00,0xd0,0x06,0xcf,0x06,0x07,0x00,0xcf,0x86,0x55,
+       0x04,0x07,0x00,0x54,0x04,0x07,0x00,0x53,0x04,0x07,0x00,0x92,0x0c,0x51,0x04,0x07,
+       0x00,0x10,0x04,0x07,0x00,0x00,0x00,0x00,0x00,0xd1,0x40,0xd0,0x3a,0xcf,0x86,0xd5,
+       0x20,0x94,0x1c,0x93,0x18,0xd2,0x0c,0x51,0x04,0x07,0x00,0x10,0x04,0x07,0x00,0x00,
+       0x00,0x51,0x04,0x00,0x00,0x10,0x04,0x00,0x00,0x07,0x00,0x07,0x00,0x07,0x00,0x54,
+       0x04,0x07,0x00,0x93,0x10,0x52,0x04,0x07,0x00,0x51,0x04,0x00,0x00,0x10,0x04,0x00,
+       0x00,0x07,0x00,0x07,0x00,0xcf,0x06,0x08,0x00,0xd0,0x46,0xcf,0x86,0xd5,0x2c,0xd4,
+       0x20,0x53,0x04,0x08,0x00,0xd2,0x0c,0x51,0x04,0x08,0x00,0x10,0x04,0x08,0x00,0x10,
+       0x00,0xd1,0x08,0x10,0x04,0x10,0x00,0x12,0x00,0x10,0x04,0x12,0x00,0x00,0x00,0x53,
+       0x04,0x0a,0x00,0x12,0x04,0x0a,0x00,0x00,0x00,0x94,0x14,0x93,0x10,0x92,0x0c,0x91,
+       0x08,0x10,0x04,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xcf,
+       0x86,0xd5,0x08,0x14,0x04,0x00,0x00,0x0a,0x00,0x54,0x04,0x0a,0x00,0x53,0x04,0x0a,
+       0x00,0x52,0x04,0x0a,0x00,0x91,0x08,0x10,0x04,0x0a,0x00,0x0a,0xdc,0x00,0x00,0xd2,
+       0x5e,0xd1,0x06,0xcf,0x06,0x00,0x00,0xd0,0x1e,0xcf,0x86,0x95,0x18,0x54,0x04,0x0a,
+       0x00,0x53,0x04,0x0a,0x00,0x52,0x04,0x0a,0x00,0x91,0x08,0x10,0x04,0x0a,0x00,0x00,
+       0x00,0x00,0x00,0x0a,0x00,0xcf,0x86,0xd5,0x18,0x54,0x04,0x0a,0x00,0x93,0x10,0x92,
+       0x0c,0x91,0x08,0x10,0x04,0x0a,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xd4,
+       0x14,0x93,0x10,0x92,0x0c,0x91,0x08,0x10,0x04,0x10,0xdc,0x10,0x00,0x10,0x00,0x10,
+       0x00,0x10,0x00,0x53,0x04,0x10,0x00,0x12,0x04,0x10,0x00,0x00,0x00,0xd1,0x70,0xd0,
+       0x36,0xcf,0x86,0xd5,0x18,0x54,0x04,0x05,0x00,0x53,0x04,0x05,0x00,0x52,0x04,0x05,
+       0x00,0x51,0x04,0x05,0x00,0x10,0x04,0x05,0x00,0x10,0x00,0x94,0x18,0xd3,0x08,0x12,
+       0x04,0x05,0x00,0x00,0x00,0x52,0x04,0x00,0x00,0x91,0x08,0x10,0x04,0x00,0x00,0x13,
+       0x00,0x13,0x00,0x05,0x00,0xcf,0x86,0xd5,0x18,0x94,0x14,0x53,0x04,0x05,0x00,0x92,
+       0x0c,0x51,0x04,0x05,0x00,0x10,0x04,0x05,0x00,0x00,0x00,0x00,0x00,0x10,0x00,0x54,
+       0x04,0x10,0x00,0xd3,0x0c,0x52,0x04,0x10,0x00,0x11,0x04,0x10,0x00,0x10,0xe6,0x92,
+       0x0c,0x51,0x04,0x10,0xe6,0x10,0x04,0x10,0xe6,0x00,0x00,0x00,0x00,0xd0,0x1e,0xcf,
+       0x86,0x95,0x18,0x54,0x04,0x07,0x00,0x53,0x04,0x07,0x00,0x52,0x04,0x07,0x00,0x51,
+       0x04,0x07,0x00,0x10,0x04,0x00,0x00,0x07,0x00,0x08,0x00,0xcf,0x86,0x95,0x1c,0xd4,
+       0x0c,0x93,0x08,0x12,0x04,0x08,0x00,0x00,0x00,0x08,0x00,0x93,0x0c,0x52,0x04,0x08,
+       0x00,0x11,0x04,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xd3,0xba,0xd2,0x80,0xd1,
+       0x34,0xd0,0x1a,0xcf,0x86,0x55,0x04,0x05,0x00,0x94,0x10,0x93,0x0c,0x52,0x04,0x05,
+       0x00,0x11,0x04,0x05,0x00,0x07,0x00,0x05,0x00,0x05,0x00,0xcf,0x86,0x95,0x14,0x94,
+       0x10,0x53,0x04,0x05,0x00,0x52,0x04,0x05,0x00,0x11,0x04,0x05,0x00,0x07,0x00,0x07,
+       0x00,0x07,0x00,0xd0,0x2a,0xcf,0x86,0xd5,0x14,0x54,0x04,0x07,0x00,0x53,0x04,0x07,
+       0x00,0x52,0x04,0x07,0x00,0x11,0x04,0x07,0x00,0x00,0x00,0x94,0x10,0x53,0x04,0x07,
+       0x00,0x92,0x08,0x11,0x04,0x07,0x00,0x00,0x00,0x00,0x00,0x12,0x00,0xcf,0x86,0xd5,
+       0x10,0x54,0x04,0x12,0x00,0x93,0x08,0x12,0x04,0x12,0x00,0x00,0x00,0x12,0x00,0x54,
+       0x04,0x12,0x00,0x53,0x04,0x12,0x00,0x12,0x04,0x12,0x00,0x00,0x00,0xd1,0x34,0xd0,
+       0x12,0xcf,0x86,0x55,0x04,0x10,0x00,0x94,0x08,0x13,0x04,0x10,0x00,0x00,0x00,0x10,
+       0x00,0xcf,0x86,0x55,0x04,0x10,0x00,0x94,0x18,0xd3,0x08,0x12,0x04,0x10,0x00,0x00,
+       0x00,0x52,0x04,0x00,0x00,0x51,0x04,0x00,0x00,0x10,0x04,0x00,0x00,0x10,0x00,0x00,
+       0x00,0xcf,0x06,0x00,0x00,0xd2,0x06,0xcf,0x06,0x10,0x00,0xd1,0x40,0xd0,0x1e,0xcf,
+       0x86,0x55,0x04,0x10,0x00,0x54,0x04,0x10,0x00,0x93,0x10,0x52,0x04,0x10,0x00,0x51,
+       0x04,0x10,0x00,0x10,0x04,0x10,0x00,0x00,0x00,0x00,0x00,0xcf,0x86,0xd5,0x14,0x54,
+       0x04,0x10,0x00,0x93,0x0c,0x52,0x04,0x10,0x00,0x11,0x04,0x10,0x00,0x00,0x00,0x00,
+       0x00,0x94,0x08,0x13,0x04,0x10,0x00,0x00,0x00,0x00,0x00,0xcf,0x06,0x00,0x00,0xe4,
+       0xce,0x02,0xe3,0x45,0x01,0xd2,0xd0,0xd1,0x70,0xd0,0x52,0xcf,0x86,0xd5,0x20,0x94,
+       0x1c,0xd3,0x0c,0x52,0x04,0x07,0x00,0x11,0x04,0x07,0x00,0x00,0x00,0x92,0x0c,0x91,
+       0x08,0x10,0x04,0x07,0x00,0x00,0x00,0x07,0x00,0x07,0x00,0x07,0x00,0x54,0x04,0x07,
+       0x00,0xd3,0x10,0x52,0x04,0x07,0x00,0x51,0x04,0x07,0x00,0x10,0x04,0x00,0x00,0x07,
+       0x00,0xd2,0x0c,0x91,0x08,0x10,0x04,0x07,0x00,0x00,0x00,0x00,0x00,0xd1,0x08,0x10,
+       0x04,0x07,0x00,0x00,0x00,0x10,0x04,0x00,0x00,0x07,0x00,0xcf,0x86,0x95,0x18,0x54,
+       0x04,0x0b,0x00,0x93,0x10,0x52,0x04,0x0b,0x00,0x51,0x04,0x0b,0x00,0x10,0x04,0x00,
+       0x00,0x0b,0x00,0x0b,0x00,0x10,0x00,0xd0,0x32,0xcf,0x86,0xd5,0x18,0x54,0x04,0x10,
+       0x00,0x53,0x04,0x10,0x00,0x52,0x04,0x10,0x00,0x51,0x04,0x10,0x00,0x10,0x04,0x10,
+       0x00,0x00,0x00,0x94,0x14,0x93,0x10,0x52,0x04,0x00,0x00,0x51,0x04,0x00,0x00,0x10,
+       0x04,0x00,0x00,0x10,0x00,0x10,0x00,0x00,0x00,0xcf,0x86,0x55,0x04,0x00,0x00,0x54,
+       0x04,0x11,0x00,0xd3,0x14,0xd2,0x0c,0x51,0x04,0x11,0x00,0x10,0x04,0x11,0x00,0x00,
+       0x00,0x11,0x04,0x11,0x00,0x00,0x00,0x92,0x0c,0x51,0x04,0x00,0x00,0x10,0x04,0x00,
+       0x00,0x11,0x00,0x11,0x00,0xd1,0x40,0xd0,0x3a,0xcf,0x86,0xd5,0x1c,0x54,0x04,0x09,
+       0x00,0x53,0x04,0x09,0x00,0xd2,0x08,0x11,0x04,0x09,0x00,0x0b,0x00,0x51,0x04,0x00,
+       0x00,0x10,0x04,0x00,0x00,0x09,0x00,0x54,0x04,0x0a,0x00,0x53,0x04,0x0a,0x00,0xd2,
+       0x08,0x11,0x04,0x0a,0x00,0x00,0x00,0x51,0x04,0x00,0x00,0x10,0x04,0x00,0x00,0x0a,
+       0x00,0xcf,0x06,0x00,0x00,0xd0,0x1a,0xcf,0x86,0x55,0x04,0x0d,0x00,0x54,0x04,0x0d,
+       0x00,0x53,0x04,0x0d,0x00,0x52,0x04,0x00,0x00,0x11,0x04,0x11,0x00,0x0d,0x00,0xcf,
+       0x86,0x95,0x14,0x54,0x04,0x11,0x00,0x93,0x0c,0x92,0x08,0x11,0x04,0x00,0x00,0x11,
+       0x00,0x11,0x00,0x11,0x00,0x11,0x00,0xd2,0xec,0xd1,0xa4,0xd0,0x76,0xcf,0x86,0xd5,
+       0x48,0xd4,0x28,0xd3,0x14,0x52,0x04,0x08,0x00,0xd1,0x08,0x10,0x04,0x00,0x00,0x08,
+       0x00,0x10,0x04,0x08,0x00,0x00,0x00,0x52,0x04,0x00,0x00,0xd1,0x08,0x10,0x04,0x08,
+       0x00,0x08,0xdc,0x10,0x04,0x08,0x00,0x08,0xe6,0xd3,0x10,0x52,0x04,0x08,0x00,0x91,
+       0x08,0x10,0x04,0x00,0x00,0x08,0x00,0x08,0x00,0x92,0x0c,0x91,0x08,0x10,0x04,0x00,
+       0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x54,0x04,0x08,0x00,0xd3,0x0c,0x52,0x04,0x08,
+       0x00,0x11,0x04,0x14,0x00,0x00,0x00,0xd2,0x10,0xd1,0x08,0x10,0x04,0x08,0xe6,0x08,
+       0x01,0x10,0x04,0x08,0xdc,0x00,0x00,0x51,0x04,0x00,0x00,0x10,0x04,0x00,0x00,0x08,
+       0x09,0xcf,0x86,0x95,0x28,0xd4,0x14,0x53,0x04,0x08,0x00,0x92,0x0c,0x91,0x08,0x10,
+       0x04,0x14,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x53,0x04,0x08,0x00,0x92,0x0c,0x91,
+       0x08,0x10,0x04,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0b,0x00,0xd0,0x0a,0xcf,
+       0x86,0x15,0x04,0x10,0x00,0x00,0x00,0xcf,0x86,0x55,0x04,0x10,0x00,0xd4,0x24,0xd3,
+       0x14,0x52,0x04,0x10,0x00,0xd1,0x08,0x10,0x04,0x10,0x00,0x10,0xe6,0x10,0x04,0x10,
+       0xdc,0x00,0x00,0x92,0x0c,0x51,0x04,0x00,0x00,0x10,0x04,0x00,0x00,0x10,0x00,0x10,
+       0x00,0x93,0x10,0x52,0x04,0x10,0x00,0x51,0x04,0x10,0x00,0x10,0x04,0x10,0x00,0x00,
+       0x00,0x00,0x00,0xd1,0x54,0xd0,0x26,0xcf,0x86,0x55,0x04,0x0b,0x00,0x54,0x04,0x0b,
+       0x00,0xd3,0x0c,0x52,0x04,0x0b,0x00,0x11,0x04,0x0b,0x00,0x00,0x00,0x92,0x0c,0x91,
+       0x08,0x10,0x04,0x00,0x00,0x0b,0x00,0x0b,0x00,0x0b,0x00,0xcf,0x86,0xd5,0x14,0x54,
+       0x04,0x0b,0x00,0x93,0x0c,0x52,0x04,0x0b,0x00,0x11,0x04,0x0b,0x00,0x00,0x00,0x0b,
+       0x00,0x54,0x04,0x0b,0x00,0x93,0x10,0x92,0x0c,0x51,0x04,0x0b,0x00,0x10,0x04,0x0b,
+       0x00,0x00,0x00,0x00,0x00,0x0b,0x00,0xd0,0x42,0xcf,0x86,0xd5,0x28,0x54,0x04,0x10,
+       0x00,0xd3,0x0c,0x92,0x08,0x11,0x04,0x10,0x00,0x00,0x00,0x00,0x00,0xd2,0x0c,0x91,
+       0x08,0x10,0x04,0x00,0x00,0x10,0x00,0x10,0x00,0x91,0x08,0x10,0x04,0x10,0x00,0x00,
+       0x00,0x00,0x00,0x94,0x14,0x53,0x04,0x00,0x00,0x92,0x0c,0x91,0x08,0x10,0x04,0x00,
+       0x00,0x10,0x00,0x10,0x00,0x10,0x00,0x00,0x00,0xcf,0x06,0x00,0x00,0xd3,0x96,0xd2,
+       0x68,0xd1,0x24,0xd0,0x06,0xcf,0x06,0x0b,0x00,0xcf,0x86,0x95,0x18,0x94,0x14,0x53,
+       0x04,0x0b,0x00,0x92,0x0c,0x91,0x08,0x10,0x04,0x0b,0x00,0x00,0x00,0x00,0x00,0x00,
+       0x00,0x00,0x00,0x00,0x00,0xd0,0x1e,0xcf,0x86,0x55,0x04,0x11,0x00,0x54,0x04,0x11,
+       0x00,0x93,0x10,0x92,0x0c,0x51,0x04,0x11,0x00,0x10,0x04,0x11,0x00,0x00,0x00,0x00,
+       0x00,0x00,0x00,0xcf,0x86,0x55,0x04,0x11,0x00,0x54,0x04,0x11,0x00,0xd3,0x10,0x92,
+       0x0c,0x51,0x04,0x11,0x00,0x10,0x04,0x11,0x00,0x00,0x00,0x00,0x00,0x92,0x08,0x11,
+       0x04,0x00,0x00,0x11,0x00,0x11,0x00,0xd1,0x28,0xd0,0x22,0xcf,0x86,0x55,0x04,0x14,
+       0x00,0xd4,0x0c,0x93,0x08,0x12,0x04,0x14,0x00,0x14,0xe6,0x00,0x00,0x53,0x04,0x14,
+       0x00,0x92,0x08,0x11,0x04,0x14,0x00,0x00,0x00,0x00,0x00,0xcf,0x06,0x00,0x00,0xcf,
+       0x06,0x00,0x00,0xd2,0x2a,0xd1,0x24,0xd0,0x06,0xcf,0x06,0x00,0x00,0xcf,0x86,0x55,
+       0x04,0x00,0x00,0x54,0x04,0x0b,0x00,0x53,0x04,0x0b,0x00,0x52,0x04,0x0b,0x00,0x51,
+       0x04,0x0b,0x00,0x10,0x04,0x0b,0x00,0x00,0x00,0xcf,0x06,0x00,0x00,0xd1,0x58,0xd0,
+       0x12,0xcf,0x86,0x55,0x04,0x14,0x00,0x94,0x08,0x13,0x04,0x14,0x00,0x00,0x00,0x14,
+       0x00,0xcf,0x86,0x95,0x40,0xd4,0x24,0xd3,0x0c,0x52,0x04,0x14,0x00,0x11,0x04,0x14,
+       0x00,0x14,0xdc,0xd2,0x0c,0x51,0x04,0x14,0xe6,0x10,0x04,0x14,0xe6,0x14,0xdc,0x91,
+       0x08,0x10,0x04,0x14,0xe6,0x14,0xdc,0x14,0xdc,0xd3,0x10,0x92,0x0c,0x91,0x08,0x10,
+       0x04,0x14,0xdc,0x14,0x00,0x14,0x00,0x14,0x00,0x92,0x08,0x11,0x04,0x14,0x00,0x00,
+       0x00,0x00,0x00,0x00,0x00,0xd0,0x06,0xcf,0x06,0x00,0x00,0xcf,0x86,0x55,0x04,0x00,
+       0x00,0x54,0x04,0x15,0x00,0x93,0x10,0x52,0x04,0x15,0x00,0x51,0x04,0x15,0x00,0x10,
+       0x04,0x15,0x00,0x00,0x00,0x00,0x00,0xcf,0x86,0xe5,0x0f,0x06,0xe4,0xf8,0x03,0xe3,
+       0x02,0x02,0xd2,0xfb,0xd1,0x4c,0xd0,0x06,0xcf,0x06,0x0c,0x00,0xcf,0x86,0xd5,0x2c,
+       0xd4,0x1c,0xd3,0x10,0x52,0x04,0x0c,0x00,0x51,0x04,0x0c,0x00,0x10,0x04,0x0c,0x09,
+       0x0c,0x00,0x52,0x04,0x0c,0x00,0x11,0x04,0x0c,0x00,0x00,0x00,0x93,0x0c,0x92,0x08,
+       0x11,0x04,0x00,0x00,0x0c,0x00,0x0c,0x00,0x0c,0x00,0x54,0x04,0x0c,0x00,0x53,0x04,
+       0x00,0x00,0x52,0x04,0x00,0x00,0x51,0x04,0x00,0x00,0x10,0x04,0x00,0x00,0x10,0x09,
+       0xd0,0x69,0xcf,0x86,0xd5,0x32,0x54,0x04,0x0b,0x00,0x53,0x04,0x0b,0x00,0xd2,0x15,
+       0x51,0x04,0x0b,0x00,0x10,0x0d,0x0b,0xff,0xf0,0x91,0x82,0x99,0xf0,0x91,0x82,0xba,
+       0x00,0x0b,0x00,0x91,0x11,0x10,0x0d,0x0b,0xff,0xf0,0x91,0x82,0x9b,0xf0,0x91,0x82,
+       0xba,0x00,0x0b,0x00,0x0b,0x00,0xd4,0x1d,0x53,0x04,0x0b,0x00,0x92,0x15,0x51,0x04,
+       0x0b,0x00,0x10,0x04,0x0b,0x00,0x0b,0xff,0xf0,0x91,0x82,0xa5,0xf0,0x91,0x82,0xba,
+       0x00,0x0b,0x00,0x53,0x04,0x0b,0x00,0x92,0x10,0xd1,0x08,0x10,0x04,0x0b,0x00,0x0b,
+       0x09,0x10,0x04,0x0b,0x07,0x0b,0x00,0x0b,0x00,0xcf,0x86,0xd5,0x20,0x94,0x1c,0xd3,
+       0x0c,0x92,0x08,0x11,0x04,0x0b,0x00,0x00,0x00,0x00,0x00,0x52,0x04,0x00,0x00,0x91,
+       0x08,0x10,0x04,0x00,0x00,0x14,0x00,0x00,0x00,0x0d,0x00,0xd4,0x14,0x53,0x04,0x0d,
+       0x00,0x92,0x0c,0x91,0x08,0x10,0x04,0x0d,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x53,
+       0x04,0x0d,0x00,0x92,0x08,0x11,0x04,0x0d,0x00,0x00,0x00,0x00,0x00,0xd1,0x96,0xd0,
+       0x5c,0xcf,0x86,0xd5,0x18,0x94,0x14,0x93,0x10,0x92,0x0c,0x51,0x04,0x0d,0xe6,0x10,
+       0x04,0x0d,0xe6,0x0d,0x00,0x0d,0x00,0x0d,0x00,0x0d,0x00,0xd4,0x26,0x53,0x04,0x0d,
+       0x00,0x52,0x04,0x0d,0x00,0x51,0x04,0x0d,0x00,0x10,0x0d,0x0d,0xff,0xf0,0x91,0x84,
+       0xb1,0xf0,0x91,0x84,0xa7,0x00,0x0d,0xff,0xf0,0x91,0x84,0xb2,0xf0,0x91,0x84,0xa7,
+       0x00,0x93,0x18,0xd2,0x0c,0x51,0x04,0x0d,0x00,0x10,0x04,0x0d,0x00,0x0d,0x09,0x91,
+       0x08,0x10,0x04,0x0d,0x09,0x00,0x00,0x0d,0x00,0x0d,0x00,0xcf,0x86,0xd5,0x18,0x94,
+       0x14,0x93,0x10,0x52,0x04,0x0d,0x00,0x51,0x04,0x14,0x00,0x10,0x04,0x14,0x00,0x00,
+       0x00,0x00,0x00,0x10,0x00,0x54,0x04,0x10,0x00,0x93,0x18,0xd2,0x0c,0x51,0x04,0x10,
+       0x00,0x10,0x04,0x10,0x00,0x10,0x07,0x51,0x04,0x10,0x00,0x10,0x04,0x10,0x00,0x00,
+       0x00,0x00,0x00,0xd0,0x06,0xcf,0x06,0x0d,0x00,0xcf,0x86,0xd5,0x40,0xd4,0x2c,0xd3,
+       0x10,0x92,0x0c,0x91,0x08,0x10,0x04,0x0d,0x09,0x0d,0x00,0x0d,0x00,0x0d,0x00,0xd2,
+       0x10,0xd1,0x08,0x10,0x04,0x0d,0x00,0x11,0x00,0x10,0x04,0x11,0x07,0x11,0x00,0x91,
+       0x08,0x10,0x04,0x11,0x00,0x10,0x00,0x00,0x00,0x53,0x04,0x0d,0x00,0x92,0x0c,0x51,
+       0x04,0x0d,0x00,0x10,0x04,0x10,0x00,0x11,0x00,0x11,0x00,0xd4,0x14,0x93,0x10,0x92,
+       0x0c,0x91,0x08,0x10,0x04,0x00,0x00,0x10,0x00,0x10,0x00,0x10,0x00,0x10,0x00,0x93,
+       0x10,0x52,0x04,0x10,0x00,0x91,0x08,0x10,0x04,0x10,0x00,0x00,0x00,0x00,0x00,0x00,
+       0x00,0xd2,0xc8,0xd1,0x48,0xd0,0x42,0xcf,0x86,0xd5,0x18,0x54,0x04,0x10,0x00,0x93,
+       0x10,0x92,0x0c,0x51,0x04,0x10,0x00,0x10,0x04,0x00,0x00,0x10,0x00,0x10,0x00,0x10,
+       0x00,0x54,0x04,0x10,0x00,0xd3,0x14,0x52,0x04,0x10,0x00,0xd1,0x08,0x10,0x04,0x10,
+       0x00,0x10,0x09,0x10,0x04,0x10,0x07,0x10,0x00,0x52,0x04,0x10,0x00,0x51,0x04,0x10,
+       0x00,0x10,0x04,0x12,0x00,0x00,0x00,0xcf,0x06,0x00,0x00,0xd0,0x52,0xcf,0x86,0xd5,
+       0x3c,0xd4,0x28,0xd3,0x10,0x52,0x04,0x11,0x00,0x51,0x04,0x11,0x00,0x10,0x04,0x11,
+       0x00,0x00,0x00,0xd2,0x0c,0x91,0x08,0x10,0x04,0x11,0x00,0x00,0x00,0x11,0x00,0x51,
+       0x04,0x11,0x00,0x10,0x04,0x00,0x00,0x11,0x00,0x53,0x04,0x11,0x00,0x52,0x04,0x11,
+       0x00,0x51,0x04,0x11,0x00,0x10,0x04,0x00,0x00,0x11,0x00,0x94,0x10,0x53,0x04,0x11,
+       0x00,0x92,0x08,0x11,0x04,0x11,0x00,0x00,0x00,0x00,0x00,0x10,0x00,0xcf,0x86,0x55,
+       0x04,0x10,0x00,0xd4,0x18,0x53,0x04,0x10,0x00,0x92,0x10,0xd1,0x08,0x10,0x04,0x10,
+       0x00,0x10,0x07,0x10,0x04,0x10,0x09,0x00,0x00,0x00,0x00,0x53,0x04,0x10,0x00,0x92,
+       0x08,0x11,0x04,0x10,0x00,0x00,0x00,0x00,0x00,0xe1,0x27,0x01,0xd0,0x8a,0xcf,0x86,
+       0xd5,0x44,0xd4,0x2c,0xd3,0x18,0xd2,0x0c,0x91,0x08,0x10,0x04,0x11,0x00,0x10,0x00,
+       0x10,0x00,0x91,0x08,0x10,0x04,0x00,0x00,0x10,0x00,0x10,0x00,0x52,0x04,0x10,0x00,
+       0xd1,0x08,0x10,0x04,0x10,0x00,0x00,0x00,0x10,0x04,0x00,0x00,0x10,0x00,0x93,0x14,
+       0x92,0x10,0xd1,0x08,0x10,0x04,0x10,0x00,0x00,0x00,0x10,0x04,0x00,0x00,0x10,0x00,
+       0x10,0x00,0x10,0x00,0xd4,0x14,0x53,0x04,0x10,0x00,0x92,0x0c,0x91,0x08,0x10,0x04,
+       0x10,0x00,0x00,0x00,0x10,0x00,0x10,0x00,0xd3,0x18,0xd2,0x0c,0x91,0x08,0x10,0x04,
+       0x10,0x00,0x00,0x00,0x10,0x00,0x91,0x08,0x10,0x04,0x00,0x00,0x10,0x00,0x10,0x00,
+       0xd2,0x0c,0x51,0x04,0x10,0x00,0x10,0x04,0x00,0x00,0x14,0x07,0x91,0x08,0x10,0x04,
+       0x10,0x07,0x10,0x00,0x10,0x00,0xcf,0x86,0xd5,0x6a,0xd4,0x42,0xd3,0x14,0x52,0x04,
+       0x10,0x00,0xd1,0x08,0x10,0x04,0x10,0x00,0x00,0x00,0x10,0x04,0x00,0x00,0x10,0x00,
+       0xd2,0x19,0xd1,0x08,0x10,0x04,0x10,0x00,0x00,0x00,0x10,0x04,0x00,0x00,0x10,0xff,
+       0xf0,0x91,0x8d,0x87,0xf0,0x91,0x8c,0xbe,0x00,0x91,0x11,0x10,0x0d,0x10,0xff,0xf0,
+       0x91,0x8d,0x87,0xf0,0x91,0x8d,0x97,0x00,0x10,0x09,0x00,0x00,0xd3,0x18,0xd2,0x0c,
+       0x91,0x08,0x10,0x04,0x11,0x00,0x00,0x00,0x00,0x00,0x51,0x04,0x00,0x00,0x10,0x04,
+       0x00,0x00,0x10,0x00,0x52,0x04,0x00,0x00,0x91,0x08,0x10,0x04,0x00,0x00,0x10,0x00,
+       0x10,0x00,0xd4,0x1c,0xd3,0x0c,0x52,0x04,0x10,0x00,0x11,0x04,0x00,0x00,0x10,0xe6,
+       0x52,0x04,0x10,0xe6,0x91,0x08,0x10,0x04,0x10,0xe6,0x00,0x00,0x00,0x00,0x93,0x10,
+       0x52,0x04,0x10,0xe6,0x91,0x08,0x10,0x04,0x10,0xe6,0x00,0x00,0x00,0x00,0x00,0x00,
+       0xcf,0x06,0x00,0x00,0xe3,0x30,0x01,0xd2,0xb7,0xd1,0x48,0xd0,0x06,0xcf,0x06,0x12,
+       0x00,0xcf,0x86,0x95,0x3c,0xd4,0x1c,0x93,0x18,0xd2,0x0c,0x51,0x04,0x12,0x00,0x10,
+       0x04,0x12,0x09,0x12,0x00,0x51,0x04,0x12,0x00,0x10,0x04,0x12,0x07,0x12,0x00,0x12,
+       0x00,0x53,0x04,0x12,0x00,0xd2,0x0c,0x51,0x04,0x12,0x00,0x10,0x04,0x00,0x00,0x12,
+       0x00,0xd1,0x08,0x10,0x04,0x00,0x00,0x12,0x00,0x10,0x04,0x14,0xe6,0x15,0x00,0x00,
+       0x00,0xd0,0x45,0xcf,0x86,0x55,0x04,0x10,0x00,0x54,0x04,0x10,0x00,0x53,0x04,0x10,
+       0x00,0xd2,0x15,0x51,0x04,0x10,0x00,0x10,0x04,0x10,0x00,0x10,0xff,0xf0,0x91,0x92,
+       0xb9,0xf0,0x91,0x92,0xba,0x00,0xd1,0x11,0x10,0x0d,0x10,0xff,0xf0,0x91,0x92,0xb9,
+       0xf0,0x91,0x92,0xb0,0x00,0x10,0x00,0x10,0x0d,0x10,0xff,0xf0,0x91,0x92,0xb9,0xf0,
+       0x91,0x92,0xbd,0x00,0x10,0x00,0xcf,0x86,0x95,0x24,0xd4,0x14,0x93,0x10,0x92,0x0c,
+       0x51,0x04,0x10,0x00,0x10,0x04,0x10,0x09,0x10,0x07,0x10,0x00,0x00,0x00,0x53,0x04,
+       0x10,0x00,0x92,0x08,0x11,0x04,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xd1,0x06,
+       0xcf,0x06,0x00,0x00,0xd0,0x40,0xcf,0x86,0x55,0x04,0x10,0x00,0x54,0x04,0x10,0x00,
+       0xd3,0x0c,0x52,0x04,0x10,0x00,0x11,0x04,0x10,0x00,0x00,0x00,0xd2,0x1e,0x51,0x04,
+       0x10,0x00,0x10,0x0d,0x10,0xff,0xf0,0x91,0x96,0xb8,0xf0,0x91,0x96,0xaf,0x00,0x10,
+       0xff,0xf0,0x91,0x96,0xb9,0xf0,0x91,0x96,0xaf,0x00,0x51,0x04,0x10,0x00,0x10,0x04,
+       0x10,0x00,0x10,0x09,0xcf,0x86,0x95,0x2c,0xd4,0x1c,0xd3,0x10,0x92,0x0c,0x91,0x08,
+       0x10,0x04,0x10,0x07,0x10,0x00,0x10,0x00,0x10,0x00,0x92,0x08,0x11,0x04,0x10,0x00,
+       0x11,0x00,0x11,0x00,0x53,0x04,0x11,0x00,0x52,0x04,0x11,0x00,0x11,0x04,0x11,0x00,
+       0x00,0x00,0x00,0x00,0xd2,0xa0,0xd1,0x5c,0xd0,0x1e,0xcf,0x86,0x55,0x04,0x10,0x00,
+       0x54,0x04,0x10,0x00,0x53,0x04,0x10,0x00,0x52,0x04,0x10,0x00,0x51,0x04,0x10,0x00,
+       0x10,0x04,0x10,0x00,0x10,0x09,0xcf,0x86,0xd5,0x24,0xd4,0x14,0x93,0x10,0x52,0x04,
+       0x10,0x00,0x91,0x08,0x10,0x04,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x53,0x04,
+       0x10,0x00,0x92,0x08,0x11,0x04,0x10,0x00,0x00,0x00,0x00,0x00,0x94,0x14,0x53,0x04,
+       0x12,0x00,0x52,0x04,0x12,0x00,0x91,0x08,0x10,0x04,0x12,0x00,0x00,0x00,0x00,0x00,
+       0x00,0x00,0xd0,0x2a,0xcf,0x86,0x55,0x04,0x0d,0x00,0x54,0x04,0x0d,0x00,0xd3,0x10,
+       0x52,0x04,0x0d,0x00,0x51,0x04,0x0d,0x00,0x10,0x04,0x0d,0x09,0x0d,0x07,0x92,0x0c,
+       0x91,0x08,0x10,0x04,0x15,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xcf,0x86,0x95,0x14,
+       0x94,0x10,0x53,0x04,0x0d,0x00,0x92,0x08,0x11,0x04,0x0d,0x00,0x00,0x00,0x00,0x00,
+       0x00,0x00,0x00,0x00,0xd1,0x40,0xd0,0x3a,0xcf,0x86,0xd5,0x20,0x54,0x04,0x11,0x00,
+       0x53,0x04,0x11,0x00,0xd2,0x0c,0x51,0x04,0x11,0x00,0x10,0x04,0x14,0x00,0x00,0x00,
+       0x91,0x08,0x10,0x04,0x00,0x00,0x11,0x00,0x11,0x00,0x94,0x14,0x53,0x04,0x11,0x00,
+       0x92,0x0c,0x51,0x04,0x11,0x00,0x10,0x04,0x11,0x00,0x11,0x09,0x00,0x00,0x11,0x00,
+       0xcf,0x06,0x00,0x00,0xcf,0x06,0x00,0x00,0xe4,0x59,0x01,0xd3,0xb2,0xd2,0x5c,0xd1,
+       0x28,0xd0,0x22,0xcf,0x86,0x55,0x04,0x14,0x00,0x54,0x04,0x14,0x00,0x53,0x04,0x14,
+       0x00,0x92,0x10,0xd1,0x08,0x10,0x04,0x14,0x00,0x14,0x09,0x10,0x04,0x14,0x07,0x14,
+       0x00,0x00,0x00,0xcf,0x06,0x00,0x00,0xd0,0x0a,0xcf,0x86,0x15,0x04,0x00,0x00,0x10,
+       0x00,0xcf,0x86,0x55,0x04,0x10,0x00,0x54,0x04,0x10,0x00,0xd3,0x10,0x92,0x0c,0x51,
+       0x04,0x10,0x00,0x10,0x04,0x10,0x00,0x00,0x00,0x00,0x00,0x52,0x04,0x00,0x00,0x51,
+       0x04,0x00,0x00,0x10,0x04,0x00,0x00,0x10,0x00,0xd1,0x06,0xcf,0x06,0x00,0x00,0xd0,
+       0x1a,0xcf,0x86,0x55,0x04,0x00,0x00,0x94,0x10,0x53,0x04,0x15,0x00,0x92,0x08,0x11,
+       0x04,0x00,0x00,0x15,0x00,0x15,0x00,0x15,0x00,0xcf,0x86,0xd5,0x14,0x54,0x04,0x15,
+       0x00,0x53,0x04,0x15,0x00,0x92,0x08,0x11,0x04,0x00,0x00,0x15,0x00,0x15,0x00,0x94,
+       0x1c,0x93,0x18,0xd2,0x0c,0x91,0x08,0x10,0x04,0x15,0x09,0x15,0x00,0x15,0x00,0x91,
+       0x08,0x10,0x04,0x15,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xd2,0xa0,0xd1,
+       0x3c,0xd0,0x1e,0xcf,0x86,0x55,0x04,0x13,0x00,0x54,0x04,0x13,0x00,0x93,0x10,0x52,
+       0x04,0x13,0x00,0x91,0x08,0x10,0x04,0x13,0x09,0x13,0x00,0x13,0x00,0x13,0x00,0xcf,
+       0x86,0x95,0x18,0x94,0x14,0x93,0x10,0x52,0x04,0x13,0x00,0x51,0x04,0x13,0x00,0x10,
+       0x04,0x13,0x00,0x13,0x09,0x00,0x00,0x13,0x00,0x13,0x00,0xd0,0x46,0xcf,0x86,0xd5,
+       0x2c,0xd4,0x10,0x93,0x0c,0x52,0x04,0x13,0x00,0x11,0x04,0x15,0x00,0x13,0x00,0x13,
+       0x00,0x53,0x04,0x13,0x00,0xd2,0x0c,0x91,0x08,0x10,0x04,0x13,0x00,0x13,0x09,0x13,
+       0x00,0x91,0x08,0x10,0x04,0x13,0x00,0x14,0x00,0x13,0x00,0x94,0x14,0x93,0x10,0x92,
+       0x0c,0x51,0x04,0x13,0x00,0x10,0x04,0x13,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+       0x00,0xcf,0x86,0x55,0x04,0x10,0x00,0x54,0x04,0x10,0x00,0x53,0x04,0x10,0x00,0x92,
+       0x0c,0x91,0x08,0x10,0x04,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xcf,0x06,0x00,
+       0x00,0xe3,0xa9,0x01,0xd2,0xb0,0xd1,0x6c,0xd0,0x3e,0xcf,0x86,0xd5,0x18,0x94,0x14,
+       0x53,0x04,0x12,0x00,0x92,0x0c,0x91,0x08,0x10,0x04,0x12,0x00,0x00,0x00,0x12,0x00,
+       0x12,0x00,0x12,0x00,0x54,0x04,0x12,0x00,0xd3,0x10,0x52,0x04,0x12,0x00,0x51,0x04,
+       0x12,0x00,0x10,0x04,0x12,0x00,0x00,0x00,0x52,0x04,0x12,0x00,0x51,0x04,0x12,0x00,
+       0x10,0x04,0x12,0x00,0x12,0x09,0xcf,0x86,0xd5,0x14,0x94,0x10,0x93,0x0c,0x52,0x04,
+       0x12,0x00,0x11,0x04,0x12,0x00,0x00,0x00,0x00,0x00,0x12,0x00,0x94,0x14,0x53,0x04,
+       0x12,0x00,0x52,0x04,0x12,0x00,0x91,0x08,0x10,0x04,0x12,0x00,0x00,0x00,0x00,0x00,
+       0x12,0x00,0xd0,0x3e,0xcf,0x86,0xd5,0x14,0x54,0x04,0x12,0x00,0x93,0x0c,0x92,0x08,
+       0x11,0x04,0x00,0x00,0x12,0x00,0x12,0x00,0x12,0x00,0xd4,0x14,0x53,0x04,0x12,0x00,
+       0x92,0x0c,0x91,0x08,0x10,0x04,0x00,0x00,0x12,0x00,0x12,0x00,0x12,0x00,0x93,0x10,
+       0x52,0x04,0x12,0x00,0x51,0x04,0x12,0x00,0x10,0x04,0x12,0x00,0x00,0x00,0x00,0x00,
+       0xcf,0x06,0x00,0x00,0xd1,0xa0,0xd0,0x52,0xcf,0x86,0xd5,0x24,0x94,0x20,0xd3,0x10,
+       0x52,0x04,0x13,0x00,0x51,0x04,0x13,0x00,0x10,0x04,0x13,0x00,0x00,0x00,0x92,0x0c,
+       0x51,0x04,0x13,0x00,0x10,0x04,0x00,0x00,0x13,0x00,0x13,0x00,0x13,0x00,0x54,0x04,
+       0x13,0x00,0xd3,0x10,0x52,0x04,0x13,0x00,0x51,0x04,0x13,0x00,0x10,0x04,0x13,0x00,
+       0x00,0x00,0xd2,0x0c,0x51,0x04,0x00,0x00,0x10,0x04,0x13,0x00,0x00,0x00,0x51,0x04,
+       0x13,0x00,0x10,0x04,0x00,0x00,0x13,0x00,0xcf,0x86,0xd5,0x28,0xd4,0x18,0x93,0x14,
+       0xd2,0x0c,0x51,0x04,0x13,0x00,0x10,0x04,0x13,0x07,0x13,0x00,0x11,0x04,0x13,0x09,
+       0x13,0x00,0x00,0x00,0x53,0x04,0x13,0x00,0x92,0x08,0x11,0x04,0x13,0x00,0x00,0x00,
+       0x00,0x00,0x94,0x20,0xd3,0x10,0x52,0x04,0x14,0x00,0x51,0x04,0x14,0x00,0x10,0x04,
+       0x00,0x00,0x14,0x00,0x92,0x0c,0x91,0x08,0x10,0x04,0x14,0x00,0x00,0x00,0x14,0x00,
+       0x14,0x00,0x14,0x00,0xd0,0x52,0xcf,0x86,0xd5,0x3c,0xd4,0x14,0x53,0x04,0x14,0x00,
+       0x52,0x04,0x14,0x00,0x51,0x04,0x14,0x00,0x10,0x04,0x14,0x00,0x00,0x00,0xd3,0x18,
+       0xd2,0x0c,0x51,0x04,0x14,0x00,0x10,0x04,0x00,0x00,0x14,0x00,0x51,0x04,0x14,0x00,
+       0x10,0x04,0x14,0x00,0x14,0x09,0x92,0x0c,0x91,0x08,0x10,0x04,0x14,0x00,0x00,0x00,
+       0x00,0x00,0x00,0x00,0x94,0x10,0x53,0x04,0x14,0x00,0x92,0x08,0x11,0x04,0x14,0x00,
+       0x00,0x00,0x00,0x00,0x00,0x00,0xcf,0x06,0x00,0x00,0xd2,0x2a,0xd1,0x06,0xcf,0x06,
+       0x00,0x00,0xd0,0x06,0xcf,0x06,0x00,0x00,0xcf,0x86,0x55,0x04,0x00,0x00,0x54,0x04,
+       0x14,0x00,0x53,0x04,0x14,0x00,0x92,0x0c,0x91,0x08,0x10,0x04,0x14,0x00,0x00,0x00,
+       0x00,0x00,0x00,0x00,0xd1,0x06,0xcf,0x06,0x00,0x00,0xd0,0x06,0xcf,0x06,0x00,0x00,
+       0xcf,0x86,0x55,0x04,0x15,0x00,0x54,0x04,0x15,0x00,0xd3,0x0c,0x92,0x08,0x11,0x04,
+       0x15,0x00,0x00,0x00,0x00,0x00,0x52,0x04,0x00,0x00,0x51,0x04,0x00,0x00,0x10,0x04,
+       0x00,0x00,0x15,0x00,0xd0,0xca,0xcf,0x86,0xd5,0xc2,0xd4,0x54,0xd3,0x06,0xcf,0x06,
+       0x09,0x00,0xd2,0x06,0xcf,0x06,0x09,0x00,0xd1,0x24,0xd0,0x06,0xcf,0x06,0x09,0x00,
+       0xcf,0x86,0x55,0x04,0x09,0x00,0x94,0x14,0x53,0x04,0x09,0x00,0x52,0x04,0x09,0x00,
+       0x51,0x04,0x09,0x00,0x10,0x04,0x09,0x00,0x10,0x00,0x10,0x00,0xd0,0x1e,0xcf,0x86,
+       0x95,0x18,0x54,0x04,0x10,0x00,0x53,0x04,0x10,0x00,0x92,0x0c,0x91,0x08,0x10,0x04,
+       0x10,0x00,0x11,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xcf,0x06,0x00,0x00,0xd3,0x68,
+       0xd2,0x46,0xd1,0x40,0xd0,0x06,0xcf,0x06,0x09,0x00,0xcf,0x86,0x55,0x04,0x09,0x00,
+       0xd4,0x20,0xd3,0x10,0x92,0x0c,0x51,0x04,0x09,0x00,0x10,0x04,0x09,0x00,0x10,0x00,
+       0x10,0x00,0x52,0x04,0x10,0x00,0x51,0x04,0x10,0x00,0x10,0x04,0x10,0x00,0x00,0x00,
+       0x93,0x10,0x52,0x04,0x09,0x00,0x91,0x08,0x10,0x04,0x10,0x00,0x00,0x00,0x00,0x00,
+       0x00,0x00,0xcf,0x06,0x11,0x00,0xd1,0x1c,0xd0,0x06,0xcf,0x06,0x11,0x00,0xcf,0x86,
+       0x95,0x10,0x94,0x0c,0x93,0x08,0x12,0x04,0x11,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+       0x00,0x00,0xcf,0x06,0x00,0x00,0xcf,0x06,0x00,0x00,0xcf,0x06,0x00,0x00,0xcf,0x86,
+       0xd5,0x4c,0xd4,0x06,0xcf,0x06,0x0b,0x00,0xd3,0x40,0xd2,0x3a,0xd1,0x34,0xd0,0x2e,
+       0xcf,0x86,0x55,0x04,0x0b,0x00,0xd4,0x14,0x53,0x04,0x0b,0x00,0x52,0x04,0x0b,0x00,
+       0x51,0x04,0x0b,0x00,0x10,0x04,0x0b,0x00,0x00,0x00,0x53,0x04,0x15,0x00,0x92,0x0c,
+       0x91,0x08,0x10,0x04,0x15,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xcf,0x06,0x00,0x00,
+       0xcf,0x06,0x00,0x00,0xcf,0x06,0x00,0x00,0xcf,0x06,0x00,0x00,0xcf,0x06,0x00,0x00,
+       0xd1,0x4c,0xd0,0x44,0xcf,0x86,0xd5,0x3c,0xd4,0x06,0xcf,0x06,0x00,0x00,0xd3,0x06,
+       0xcf,0x06,0x11,0x00,0xd2,0x2a,0xd1,0x24,0xd0,0x06,0xcf,0x06,0x11,0x00,0xcf,0x86,
+       0x95,0x18,0x94,0x14,0x93,0x10,0x52,0x04,0x11,0x00,0x51,0x04,0x11,0x00,0x10,0x04,
+       0x11,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xcf,0x06,0x00,0x00,0xcf,0x06,
+       0x00,0x00,0xcf,0x06,0x00,0x00,0xcf,0x86,0xcf,0x06,0x00,0x00,0xe0,0xd2,0x01,0xcf,
+       0x86,0xd5,0x06,0xcf,0x06,0x00,0x00,0xe4,0x0b,0x01,0xd3,0x06,0xcf,0x06,0x0c,0x00,
+       0xd2,0x84,0xd1,0x50,0xd0,0x1e,0xcf,0x86,0x55,0x04,0x0c,0x00,0x54,0x04,0x0c,0x00,
+       0x53,0x04,0x0c,0x00,0x92,0x0c,0x91,0x08,0x10,0x04,0x0c,0x00,0x00,0x00,0x00,0x00,
+       0x00,0x00,0xcf,0x86,0xd5,0x18,0x54,0x04,0x10,0x00,0x53,0x04,0x10,0x00,0x52,0x04,
+       0x10,0x00,0x51,0x04,0x10,0x00,0x10,0x04,0x10,0x00,0x00,0x00,0x94,0x14,0x53,0x04,
+       0x10,0x00,0xd2,0x08,0x11,0x04,0x10,0x00,0x00,0x00,0x11,0x04,0x00,0x00,0x10,0x00,
+       0x00,0x00,0xd0,0x06,0xcf,0x06,0x00,0x00,0xcf,0x86,0xd5,0x08,0x14,0x04,0x00,0x00,
+       0x10,0x00,0xd4,0x10,0x53,0x04,0x10,0x00,0x52,0x04,0x10,0x00,0x11,0x04,0x10,0x00,
+       0x00,0x00,0x93,0x10,0x52,0x04,0x10,0x01,0x91,0x08,0x10,0x04,0x10,0x01,0x10,0x00,
+       0x00,0x00,0x00,0x00,0xd1,0x6c,0xd0,0x1e,0xcf,0x86,0x55,0x04,0x10,0x00,0x54,0x04,
+       0x10,0x00,0x93,0x10,0x52,0x04,0x10,0xe6,0x51,0x04,0x10,0xe6,0x10,0x04,0x10,0xe6,
+       0x10,0x00,0x10,0x00,0xcf,0x86,0xd5,0x24,0xd4,0x10,0x93,0x0c,0x52,0x04,0x10,0x00,
+       0x11,0x04,0x10,0x00,0x00,0x00,0x00,0x00,0x53,0x04,0x10,0x00,0x92,0x0c,0x51,0x04,
+       0x10,0x00,0x10,0x04,0x00,0x00,0x10,0x00,0x10,0x00,0xd4,0x14,0x93,0x10,0x92,0x0c,
+       0x51,0x04,0x10,0x00,0x10,0x04,0x00,0x00,0x10,0x00,0x10,0x00,0x10,0x00,0x53,0x04,
+       0x10,0x00,0x52,0x04,0x00,0x00,0x91,0x08,0x10,0x04,0x00,0x00,0x10,0x00,0x10,0x00,
+       0xd0,0x0e,0xcf,0x86,0x95,0x08,0x14,0x04,0x10,0x00,0x00,0x00,0x00,0x00,0xcf,0x06,
+       0x00,0x00,0xd3,0x06,0xcf,0x06,0x00,0x00,0xd2,0x30,0xd1,0x0c,0xd0,0x06,0xcf,0x06,
+       0x00,0x00,0xcf,0x06,0x14,0x00,0xd0,0x1e,0xcf,0x86,0x95,0x18,0x54,0x04,0x14,0x00,
+       0x53,0x04,0x14,0x00,0x92,0x0c,0x51,0x04,0x14,0x00,0x10,0x04,0x14,0x00,0x00,0x00,
+       0x00,0x00,0x00,0x00,0xcf,0x06,0x00,0x00,0xd1,0x4c,0xd0,0x06,0xcf,0x06,0x0d,0x00,
+       0xcf,0x86,0xd5,0x2c,0x94,0x28,0xd3,0x10,0x52,0x04,0x0d,0x00,0x91,0x08,0x10,0x04,
+       0x0d,0x00,0x15,0x00,0x15,0x00,0xd2,0x0c,0x51,0x04,0x15,0x00,0x10,0x04,0x15,0x00,
+       0x00,0x00,0x51,0x04,0x00,0x00,0x10,0x04,0x00,0x00,0x15,0x00,0x0d,0x00,0x54,0x04,
+       0x0d,0x00,0x53,0x04,0x0d,0x00,0x52,0x04,0x0d,0x00,0x51,0x04,0x0d,0x00,0x10,0x04,
+       0x0d,0x00,0x15,0x00,0xd0,0x1e,0xcf,0x86,0x95,0x18,0x94,0x14,0x53,0x04,0x15,0x00,
+       0x52,0x04,0x00,0x00,0x51,0x04,0x00,0x00,0x10,0x04,0x00,0x00,0x0d,0x00,0x0d,0x00,
+       0x00,0x00,0xcf,0x86,0x55,0x04,0x00,0x00,0x94,0x14,0x93,0x10,0x92,0x0c,0x91,0x08,
+       0x10,0x04,0x12,0x00,0x13,0x00,0x15,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xcf,0x86,
+       0xcf,0x06,0x12,0x00,0xe2,0xc5,0x01,0xd1,0x8e,0xd0,0x86,0xcf,0x86,0xd5,0x48,0xd4,
+       0x06,0xcf,0x06,0x12,0x00,0xd3,0x06,0xcf,0x06,0x12,0x00,0xd2,0x06,0xcf,0x06,0x12,
+       0x00,0xd1,0x06,0xcf,0x06,0x12,0x00,0xd0,0x06,0xcf,0x06,0x12,0x00,0xcf,0x86,0x55,
+       0x04,0x12,0x00,0xd4,0x14,0x53,0x04,0x12,0x00,0x52,0x04,0x12,0x00,0x91,0x08,0x10,
+       0x04,0x12,0x00,0x14,0x00,0x14,0x00,0x93,0x0c,0x92,0x08,0x11,0x04,0x14,0x00,0x15,
+       0x00,0x15,0x00,0x00,0x00,0xd4,0x36,0xd3,0x06,0xcf,0x06,0x12,0x00,0xd2,0x2a,0xd1,
+       0x06,0xcf,0x06,0x12,0x00,0xd0,0x06,0xcf,0x06,0x12,0x00,0xcf,0x86,0x55,0x04,0x12,
+       0x00,0x54,0x04,0x12,0x00,0x93,0x10,0x92,0x0c,0x51,0x04,0x12,0x00,0x10,0x04,0x12,
        0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xcf,0x06,0x00,0x00,0xcf,0x06,0x00,0x00,0xcf,
-       0x06,0x00,0x00,0xcf,0x06,0x00,0x00,0xcf,0x06,0x00,0x00,0xd1,0x4c,0xd0,0x44,0xcf,
-       0x86,0xd5,0x3c,0xd4,0x06,0xcf,0x06,0x00,0x00,0xd3,0x06,0xcf,0x06,0x11,0x00,0xd2,
-       0x2a,0xd1,0x24,0xd0,0x06,0xcf,0x06,0x11,0x00,0xcf,0x86,0x95,0x18,0x94,0x14,0x93,
-       0x10,0x52,0x04,0x11,0x00,0x51,0x04,0x11,0x00,0x10,0x04,0x11,0x00,0x00,0x00,0x00,
-       0x00,0x00,0x00,0x00,0x00,0xcf,0x06,0x00,0x00,0xcf,0x06,0x00,0x00,0xcf,0x06,0x00,
-       0x00,0xcf,0x86,0xcf,0x06,0x00,0x00,0xe0,0xd2,0x01,0xcf,0x86,0xd5,0x06,0xcf,0x06,
-       0x00,0x00,0xe4,0x0b,0x01,0xd3,0x06,0xcf,0x06,0x0c,0x00,0xd2,0x84,0xd1,0x50,0xd0,
-       0x1e,0xcf,0x86,0x55,0x04,0x0c,0x00,0x54,0x04,0x0c,0x00,0x53,0x04,0x0c,0x00,0x92,
-       0x0c,0x91,0x08,0x10,0x04,0x0c,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xcf,0x86,0xd5,
-       0x18,0x54,0x04,0x10,0x00,0x53,0x04,0x10,0x00,0x52,0x04,0x10,0x00,0x51,0x04,0x10,
-       0x00,0x10,0x04,0x10,0x00,0x00,0x00,0x94,0x14,0x53,0x04,0x10,0x00,0xd2,0x08,0x11,
-       0x04,0x10,0x00,0x00,0x00,0x11,0x04,0x00,0x00,0x10,0x00,0x00,0x00,0xd0,0x06,0xcf,
-       0x06,0x00,0x00,0xcf,0x86,0xd5,0x08,0x14,0x04,0x00,0x00,0x10,0x00,0xd4,0x10,0x53,
-       0x04,0x10,0x00,0x52,0x04,0x10,0x00,0x11,0x04,0x10,0x00,0x00,0x00,0x93,0x10,0x52,
-       0x04,0x10,0x01,0x91,0x08,0x10,0x04,0x10,0x01,0x10,0x00,0x00,0x00,0x00,0x00,0xd1,
-       0x6c,0xd0,0x1e,0xcf,0x86,0x55,0x04,0x10,0x00,0x54,0x04,0x10,0x00,0x93,0x10,0x52,
-       0x04,0x10,0xe6,0x51,0x04,0x10,0xe6,0x10,0x04,0x10,0xe6,0x10,0x00,0x10,0x00,0xcf,
-       0x86,0xd5,0x24,0xd4,0x10,0x93,0x0c,0x52,0x04,0x10,0x00,0x11,0x04,0x10,0x00,0x00,
-       0x00,0x00,0x00,0x53,0x04,0x10,0x00,0x92,0x0c,0x51,0x04,0x10,0x00,0x10,0x04,0x00,
-       0x00,0x10,0x00,0x10,0x00,0xd4,0x14,0x93,0x10,0x92,0x0c,0x51,0x04,0x10,0x00,0x10,
-       0x04,0x00,0x00,0x10,0x00,0x10,0x00,0x10,0x00,0x53,0x04,0x10,0x00,0x52,0x04,0x00,
-       0x00,0x91,0x08,0x10,0x04,0x00,0x00,0x10,0x00,0x10,0x00,0xd0,0x0e,0xcf,0x86,0x95,
-       0x08,0x14,0x04,0x10,0x00,0x00,0x00,0x00,0x00,0xcf,0x06,0x00,0x00,0xd3,0x06,0xcf,
-       0x06,0x00,0x00,0xd2,0x30,0xd1,0x0c,0xd0,0x06,0xcf,0x06,0x00,0x00,0xcf,0x06,0x14,
-       0x00,0xd0,0x1e,0xcf,0x86,0x95,0x18,0x54,0x04,0x14,0x00,0x53,0x04,0x14,0x00,0x92,
-       0x0c,0x51,0x04,0x14,0x00,0x10,0x04,0x14,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xcf,
-       0x06,0x00,0x00,0xd1,0x4c,0xd0,0x06,0xcf,0x06,0x0d,0x00,0xcf,0x86,0xd5,0x2c,0x94,
-       0x28,0xd3,0x10,0x52,0x04,0x0d,0x00,0x91,0x08,0x10,0x04,0x0d,0x00,0x15,0x00,0x15,
-       0x00,0xd2,0x0c,0x51,0x04,0x15,0x00,0x10,0x04,0x15,0x00,0x00,0x00,0x51,0x04,0x00,
-       0x00,0x10,0x04,0x00,0x00,0x15,0x00,0x0d,0x00,0x54,0x04,0x0d,0x00,0x53,0x04,0x0d,
-       0x00,0x52,0x04,0x0d,0x00,0x51,0x04,0x0d,0x00,0x10,0x04,0x0d,0x00,0x15,0x00,0xd0,
-       0x1e,0xcf,0x86,0x95,0x18,0x94,0x14,0x53,0x04,0x15,0x00,0x52,0x04,0x00,0x00,0x51,
-       0x04,0x00,0x00,0x10,0x04,0x00,0x00,0x0d,0x00,0x0d,0x00,0x00,0x00,0xcf,0x86,0x55,
-       0x04,0x00,0x00,0x94,0x14,0x93,0x10,0x92,0x0c,0x91,0x08,0x10,0x04,0x12,0x00,0x13,
-       0x00,0x15,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xcf,0x86,0xcf,0x06,0x12,0x00,0xe2,
-       0xc6,0x01,0xd1,0x8e,0xd0,0x86,0xcf,0x86,0xd5,0x48,0xd4,0x06,0xcf,0x06,0x12,0x00,
-       0xd3,0x06,0xcf,0x06,0x12,0x00,0xd2,0x06,0xcf,0x06,0x12,0x00,0xd1,0x06,0xcf,0x06,
-       0x12,0x00,0xd0,0x06,0xcf,0x06,0x12,0x00,0xcf,0x86,0x55,0x04,0x12,0x00,0xd4,0x14,
-       0x53,0x04,0x12,0x00,0x52,0x04,0x12,0x00,0x91,0x08,0x10,0x04,0x12,0x00,0x14,0x00,
-       0x14,0x00,0x93,0x0c,0x92,0x08,0x11,0x04,0x14,0x00,0x15,0x00,0x15,0x00,0x00,0x00,
-       0xd4,0x36,0xd3,0x06,0xcf,0x06,0x12,0x00,0xd2,0x2a,0xd1,0x06,0xcf,0x06,0x12,0x00,
-       0xd0,0x06,0xcf,0x06,0x12,0x00,0xcf,0x86,0x55,0x04,0x12,0x00,0x54,0x04,0x12,0x00,
-       0x93,0x10,0x92,0x0c,0x51,0x04,0x12,0x00,0x10,0x04,0x12,0x00,0x00,0x00,0x00,0x00,
-       0x00,0x00,0xcf,0x06,0x00,0x00,0xcf,0x06,0x00,0x00,0xcf,0x86,0xcf,0x06,0x00,0x00,
-       0xd0,0x08,0xcf,0x86,0xcf,0x06,0x00,0x00,0xcf,0x86,0xd5,0xa2,0xd4,0x9c,0xd3,0x74,
-       0xd2,0x26,0xd1,0x20,0xd0,0x1a,0xcf,0x86,0x95,0x14,0x94,0x10,0x93,0x0c,0x92,0x08,
-       0x11,0x04,0x0c,0x00,0x13,0x00,0x13,0x00,0x13,0x00,0x13,0x00,0x13,0x00,0xcf,0x06,
-       0x13,0x00,0xcf,0x06,0x13,0x00,0xd1,0x48,0xd0,0x1e,0xcf,0x86,0x95,0x18,0x54,0x04,
-       0x13,0x00,0x53,0x04,0x13,0x00,0x52,0x04,0x13,0x00,0x51,0x04,0x13,0x00,0x10,0x04,
-       0x13,0x00,0x00,0x00,0x00,0x00,0xcf,0x86,0xd5,0x18,0x54,0x04,0x00,0x00,0x93,0x10,
-       0x92,0x0c,0x51,0x04,0x15,0x00,0x10,0x04,0x15,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-       0x94,0x0c,0x93,0x08,0x12,0x04,0x00,0x00,0x15,0x00,0x00,0x00,0x13,0x00,0xcf,0x06,
-       0x13,0x00,0xd2,0x22,0xd1,0x06,0xcf,0x06,0x13,0x00,0xd0,0x06,0xcf,0x06,0x13,0x00,
-       0xcf,0x86,0x55,0x04,0x13,0x00,0x54,0x04,0x13,0x00,0x53,0x04,0x13,0x00,0x12,0x04,
-       0x13,0x00,0x00,0x00,0xcf,0x06,0x00,0x00,0xcf,0x06,0x00,0x00,0xd4,0x06,0xcf,0x06,
-       0x00,0x00,0xd3,0x7f,0xd2,0x79,0xd1,0x34,0xd0,0x06,0xcf,0x06,0x10,0x00,0xcf,0x86,
-       0x55,0x04,0x10,0x00,0xd4,0x14,0x53,0x04,0x10,0x00,0x92,0x0c,0x51,0x04,0x10,0x00,
-       0x10,0x04,0x10,0x00,0x00,0x00,0x00,0x00,0x53,0x04,0x10,0x00,0x52,0x04,0x10,0x00,
-       0x91,0x08,0x10,0x04,0x10,0x00,0x00,0x00,0x00,0x00,0xd0,0x3f,0xcf,0x86,0xd5,0x2c,
-       0xd4,0x14,0x53,0x04,0x10,0x00,0x92,0x0c,0x91,0x08,0x10,0x04,0x10,0x00,0x00,0x00,
-       0x00,0x00,0x00,0x00,0x53,0x04,0x10,0x00,0xd2,0x08,0x11,0x04,0x10,0x00,0x00,0x00,
-       0x51,0x04,0x10,0x00,0x10,0x04,0x10,0x01,0x10,0x00,0x94,0x0d,0x93,0x09,0x12,0x05,
-       0x10,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xcf,0x06,0x00,0x00,0xcf,0x06,0x00,
-       0x00,0xcf,0x06,0x00,0x00,0xe1,0x96,0x04,0xd0,0x08,0xcf,0x86,0xcf,0x06,0x00,0x00,
-       0xcf,0x86,0xe5,0x33,0x04,0xe4,0x83,0x02,0xe3,0xf8,0x01,0xd2,0x26,0xd1,0x06,0xcf,
-       0x06,0x05,0x00,0xd0,0x06,0xcf,0x06,0x05,0x00,0xcf,0x86,0x55,0x04,0x05,0x00,0x54,
-       0x04,0x05,0x00,0x93,0x0c,0x52,0x04,0x05,0x00,0x11,0x04,0x05,0x00,0x00,0x00,0x00,
-       0x00,0xd1,0xef,0xd0,0x2a,0xcf,0x86,0x55,0x04,0x05,0x00,0x94,0x20,0xd3,0x10,0x52,
-       0x04,0x05,0x00,0x51,0x04,0x05,0x00,0x10,0x04,0x05,0x00,0x00,0x00,0x92,0x0c,0x91,
-       0x08,0x10,0x04,0x00,0x00,0x0a,0x00,0x05,0x00,0x05,0x00,0x05,0x00,0xcf,0x86,0xd5,
-       0x2a,0x54,0x04,0x05,0x00,0x53,0x04,0x05,0x00,0x52,0x04,0x05,0x00,0x51,0x04,0x05,
-       0x00,0x10,0x0d,0x05,0xff,0xf0,0x9d,0x85,0x97,0xf0,0x9d,0x85,0xa5,0x00,0x05,0xff,
-       0xf0,0x9d,0x85,0x98,0xf0,0x9d,0x85,0xa5,0x00,0xd4,0x75,0xd3,0x61,0xd2,0x44,0xd1,
-       0x22,0x10,0x11,0x05,0xff,0xf0,0x9d,0x85,0x98,0xf0,0x9d,0x85,0xa5,0xf0,0x9d,0x85,
-       0xae,0x00,0x05,0xff,0xf0,0x9d,0x85,0x98,0xf0,0x9d,0x85,0xa5,0xf0,0x9d,0x85,0xaf,
-       0x00,0x10,0x11,0x05,0xff,0xf0,0x9d,0x85,0x98,0xf0,0x9d,0x85,0xa5,0xf0,0x9d,0x85,
-       0xb0,0x00,0x05,0xff,0xf0,0x9d,0x85,0x98,0xf0,0x9d,0x85,0xa5,0xf0,0x9d,0x85,0xb1,
-       0x00,0xd1,0x15,0x10,0x11,0x05,0xff,0xf0,0x9d,0x85,0x98,0xf0,0x9d,0x85,0xa5,0xf0,
-       0x9d,0x85,0xb2,0x00,0x05,0xd8,0x10,0x04,0x05,0xd8,0x05,0x01,0xd2,0x08,0x11,0x04,
-       0x05,0x01,0x05,0x00,0x91,0x08,0x10,0x04,0x05,0x00,0x05,0xe2,0x05,0xd8,0xd3,0x12,
-       0x92,0x0d,0x51,0x04,0x05,0xd8,0x10,0x04,0x05,0xd8,0x05,0xff,0x00,0x05,0xff,0x00,
-       0x92,0x0e,0x51,0x05,0x05,0xff,0x00,0x10,0x05,0x05,0xff,0x00,0x05,0xdc,0x05,0xdc,
+       0x86,0xcf,0x06,0x00,0x00,0xd0,0x08,0xcf,0x86,0xcf,0x06,0x00,0x00,0xcf,0x86,0xd5,
+       0xa2,0xd4,0x9c,0xd3,0x74,0xd2,0x26,0xd1,0x20,0xd0,0x1a,0xcf,0x86,0x95,0x14,0x94,
+       0x10,0x93,0x0c,0x92,0x08,0x11,0x04,0x0c,0x00,0x13,0x00,0x13,0x00,0x13,0x00,0x13,
+       0x00,0x13,0x00,0xcf,0x06,0x13,0x00,0xcf,0x06,0x13,0x00,0xd1,0x48,0xd0,0x1e,0xcf,
+       0x86,0x95,0x18,0x54,0x04,0x13,0x00,0x53,0x04,0x13,0x00,0x52,0x04,0x13,0x00,0x51,
+       0x04,0x13,0x00,0x10,0x04,0x13,0x00,0x00,0x00,0x00,0x00,0xcf,0x86,0xd5,0x18,0x54,
+       0x04,0x00,0x00,0x93,0x10,0x92,0x0c,0x51,0x04,0x15,0x00,0x10,0x04,0x15,0x00,0x00,
+       0x00,0x00,0x00,0x00,0x00,0x94,0x0c,0x93,0x08,0x12,0x04,0x00,0x00,0x15,0x00,0x00,
+       0x00,0x13,0x00,0xcf,0x06,0x13,0x00,0xd2,0x22,0xd1,0x06,0xcf,0x06,0x13,0x00,0xd0,
+       0x06,0xcf,0x06,0x13,0x00,0xcf,0x86,0x55,0x04,0x13,0x00,0x54,0x04,0x13,0x00,0x53,
+       0x04,0x13,0x00,0x12,0x04,0x13,0x00,0x00,0x00,0xcf,0x06,0x00,0x00,0xcf,0x06,0x00,
+       0x00,0xd4,0x06,0xcf,0x06,0x00,0x00,0xd3,0x7e,0xd2,0x78,0xd1,0x34,0xd0,0x06,0xcf,
+       0x06,0x10,0x00,0xcf,0x86,0x55,0x04,0x10,0x00,0xd4,0x14,0x53,0x04,0x10,0x00,0x92,
+       0x0c,0x51,0x04,0x10,0x00,0x10,0x04,0x10,0x00,0x00,0x00,0x00,0x00,0x53,0x04,0x10,
+       0x00,0x52,0x04,0x10,0x00,0x91,0x08,0x10,0x04,0x10,0x00,0x00,0x00,0x00,0x00,0xd0,
+       0x3e,0xcf,0x86,0xd5,0x2c,0xd4,0x14,0x53,0x04,0x10,0x00,0x92,0x0c,0x91,0x08,0x10,
+       0x04,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x53,0x04,0x10,0x00,0xd2,0x08,0x11,
+       0x04,0x10,0x00,0x00,0x00,0x51,0x04,0x10,0x00,0x10,0x04,0x10,0x01,0x10,0x00,0x94,
+       0x0c,0x93,0x08,0x12,0x04,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xcf,0x06,0x00,
+       0x00,0xcf,0x06,0x00,0x00,0xcf,0x06,0x00,0x00,0xe1,0x92,0x04,0xd0,0x08,0xcf,0x86,
+       0xcf,0x06,0x00,0x00,0xcf,0x86,0xe5,0x2f,0x04,0xe4,0x7f,0x02,0xe3,0xf4,0x01,0xd2,
+       0x26,0xd1,0x06,0xcf,0x06,0x05,0x00,0xd0,0x06,0xcf,0x06,0x05,0x00,0xcf,0x86,0x55,
+       0x04,0x05,0x00,0x54,0x04,0x05,0x00,0x93,0x0c,0x52,0x04,0x05,0x00,0x11,0x04,0x05,
+       0x00,0x00,0x00,0x00,0x00,0xd1,0xeb,0xd0,0x2a,0xcf,0x86,0x55,0x04,0x05,0x00,0x94,
+       0x20,0xd3,0x10,0x52,0x04,0x05,0x00,0x51,0x04,0x05,0x00,0x10,0x04,0x05,0x00,0x00,
+       0x00,0x92,0x0c,0x91,0x08,0x10,0x04,0x00,0x00,0x0a,0x00,0x05,0x00,0x05,0x00,0x05,
+       0x00,0xcf,0x86,0xd5,0x2a,0x54,0x04,0x05,0x00,0x53,0x04,0x05,0x00,0x52,0x04,0x05,
+       0x00,0x51,0x04,0x05,0x00,0x10,0x0d,0x05,0xff,0xf0,0x9d,0x85,0x97,0xf0,0x9d,0x85,
+       0xa5,0x00,0x05,0xff,0xf0,0x9d,0x85,0x98,0xf0,0x9d,0x85,0xa5,0x00,0xd4,0x75,0xd3,
+       0x61,0xd2,0x44,0xd1,0x22,0x10,0x11,0x05,0xff,0xf0,0x9d,0x85,0x98,0xf0,0x9d,0x85,
+       0xa5,0xf0,0x9d,0x85,0xae,0x00,0x05,0xff,0xf0,0x9d,0x85,0x98,0xf0,0x9d,0x85,0xa5,
+       0xf0,0x9d,0x85,0xaf,0x00,0x10,0x11,0x05,0xff,0xf0,0x9d,0x85,0x98,0xf0,0x9d,0x85,
+       0xa5,0xf0,0x9d,0x85,0xb0,0x00,0x05,0xff,0xf0,0x9d,0x85,0x98,0xf0,0x9d,0x85,0xa5,
+       0xf0,0x9d,0x85,0xb1,0x00,0xd1,0x15,0x10,0x11,0x05,0xff,0xf0,0x9d,0x85,0x98,0xf0,
+       0x9d,0x85,0xa5,0xf0,0x9d,0x85,0xb2,0x00,0x05,0xd8,0x10,0x04,0x05,0xd8,0x05,0x01,
+       0xd2,0x08,0x11,0x04,0x05,0x01,0x05,0x00,0x91,0x08,0x10,0x04,0x05,0x00,0x05,0xe2,
+       0x05,0xd8,0xd3,0x10,0x92,0x0c,0x51,0x04,0x05,0xd8,0x10,0x04,0x05,0xd8,0x05,0x00,
+       0x05,0x00,0x92,0x0c,0x51,0x04,0x05,0x00,0x10,0x04,0x05,0x00,0x05,0xdc,0x05,0xdc,
        0xd0,0x97,0xcf,0x86,0xd5,0x28,0x94,0x24,0xd3,0x18,0xd2,0x0c,0x51,0x04,0x05,0xdc,
        0x10,0x04,0x05,0xdc,0x05,0x00,0x91,0x08,0x10,0x04,0x05,0x00,0x05,0xe6,0x05,0xe6,
        0x92,0x08,0x11,0x04,0x05,0xe6,0x05,0xdc,0x05,0x00,0x05,0x00,0xd4,0x14,0x53,0x04,
@@ -4090,21 +4080,20 @@ static const unsigned char utf8data[64256] = {
        0x00,0xd3,0x06,0xcf,0x06,0x00,0x00,0xd2,0x06,0xcf,0x06,0x00,0x00,0xd1,0x06,0xcf,
        0x06,0x00,0x00,0xd0,0x06,0xcf,0x06,0x00,0x00,0xcf,0x86,0x55,0x04,0x00,0x00,0x54,
        0x04,0x00,0x00,0x53,0x04,0x00,0x00,0x52,0x04,0x00,0x00,0x11,0x04,0x00,0x00,0x02,
-       0x00,0xd4,0xd9,0xd3,0x81,0xd2,0x79,0xd1,0x71,0xd0,0x69,0xcf,0x86,0xd5,0x60,0xd4,
-       0x59,0xd3,0x52,0xd2,0x33,0xd1,0x2c,0xd0,0x25,0xcf,0x86,0x95,0x1e,0x94,0x19,0x93,
-       0x14,0x92,0x0f,0x91,0x0a,0x10,0x05,0x00,0xff,0x00,0x05,0xff,0x00,0x00,0xff,0x00,
-       0x00,0xff,0x00,0x00,0xff,0x00,0x00,0xff,0x00,0x05,0xff,0x00,0xcf,0x06,0x05,0xff,
-       0x00,0xcf,0x06,0x00,0xff,0x00,0xd1,0x07,0xcf,0x06,0x07,0xff,0x00,0xd0,0x07,0xcf,
-       0x06,0x07,0xff,0x00,0xcf,0x86,0x55,0x05,0x07,0xff,0x00,0x14,0x05,0x07,0xff,0x00,
-       0x00,0xff,0x00,0xcf,0x06,0x00,0xff,0x00,0xcf,0x06,0x00,0xff,0x00,0xcf,0x06,0x00,
-       0xff,0x00,0xcf,0x86,0xcf,0x06,0x00,0x00,0xcf,0x86,0xcf,0x06,0x00,0x00,0xcf,0x86,
-       0xcf,0x06,0x00,0x00,0xd2,0x08,0xcf,0x86,0xcf,0x06,0x00,0x00,0xd1,0x08,0xcf,0x86,
-       0xcf,0x06,0x00,0x00,0xd0,0x08,0xcf,0x86,0xcf,0x06,0x00,0x00,0xcf,0x86,0xd5,0x06,
-       0xcf,0x06,0x00,0x00,0xd4,0x06,0xcf,0x06,0x00,0x00,0xd3,0x06,0xcf,0x06,0x00,0x00,
-       0xd2,0x06,0xcf,0x06,0x00,0x00,0xd1,0x06,0xcf,0x06,0x00,0x00,0xd0,0x06,0xcf,0x06,
-       0x00,0x00,0xcf,0x86,0x55,0x04,0x00,0x00,0x54,0x04,0x00,0x00,0x53,0x04,0x00,0x00,
-       0x52,0x04,0x00,0x00,0x11,0x04,0x00,0x00,0x02,0x00,0xcf,0x86,0xcf,0x06,0x02,0x00,
-       0x81,0x80,0xcf,0x86,0x85,0x84,0xcf,0x86,0xcf,0x06,0x02,0x00,0x00,0x00,0x00,0x00
+       0x00,0xd4,0xc8,0xd3,0x70,0xd2,0x68,0xd1,0x60,0xd0,0x58,0xcf,0x86,0xd5,0x50,0xd4,
+       0x4a,0xd3,0x44,0xd2,0x2a,0xd1,0x24,0xd0,0x1e,0xcf,0x86,0x95,0x18,0x94,0x14,0x93,
+       0x10,0x92,0x0c,0x91,0x08,0x10,0x04,0x00,0x00,0x05,0x00,0x00,0x00,0x00,0x00,0x00,
+       0x00,0x00,0x00,0x05,0x00,0xcf,0x06,0x05,0x00,0xcf,0x06,0x00,0x00,0xd1,0x06,0xcf,
+       0x06,0x07,0x00,0xd0,0x06,0xcf,0x06,0x07,0x00,0xcf,0x86,0x55,0x04,0x07,0x00,0x14,
+       0x04,0x07,0x00,0x00,0x00,0xcf,0x06,0x00,0x00,0xcf,0x06,0x00,0x00,0xcf,0x06,0x00,
+       0x00,0xcf,0x86,0xcf,0x06,0x00,0x00,0xcf,0x86,0xcf,0x06,0x00,0x00,0xcf,0x86,0xcf,
+       0x06,0x00,0x00,0xd2,0x08,0xcf,0x86,0xcf,0x06,0x00,0x00,0xd1,0x08,0xcf,0x86,0xcf,
+       0x06,0x00,0x00,0xd0,0x08,0xcf,0x86,0xcf,0x06,0x00,0x00,0xcf,0x86,0xd5,0x06,0xcf,
+       0x06,0x00,0x00,0xd4,0x06,0xcf,0x06,0x00,0x00,0xd3,0x06,0xcf,0x06,0x00,0x00,0xd2,
+       0x06,0xcf,0x06,0x00,0x00,0xd1,0x06,0xcf,0x06,0x00,0x00,0xd0,0x06,0xcf,0x06,0x00,
+       0x00,0xcf,0x86,0x55,0x04,0x00,0x00,0x54,0x04,0x00,0x00,0x53,0x04,0x00,0x00,0x52,
+       0x04,0x00,0x00,0x11,0x04,0x00,0x00,0x02,0x00,0xcf,0x86,0xcf,0x06,0x02,0x00,0x81,
+       0x80,0xcf,0x86,0x85,0x84,0xcf,0x86,0xcf,0x06,0x02,0x00,0x00,0x00,0x00,0x00,0x00
 };
 
 struct utf8data_table utf8_data_table = {
index 68cdd89c97a3f91042cbbed588964f2402fe6864..7c0bd0b55f8800c1af264e24c432b3d1259eab6b 100644 (file)
@@ -692,6 +692,34 @@ void dup_userfaultfd_complete(struct list_head *fcs)
        }
 }
 
+void dup_userfaultfd_fail(struct list_head *fcs)
+{
+       struct userfaultfd_fork_ctx *fctx, *n;
+
+       /*
+        * An error has occurred on fork, we will tear memory down, but have
+        * allocated memory for fctx's and raised reference counts for both the
+        * original and child contexts (and on the mm for each as a result).
+        *
+        * These would ordinarily be taken care of by a user handling the event,
+        * but we are no longer doing so, so manually clean up here.
+        *
+        * mm tear down will take care of cleaning up VMA contexts.
+        */
+       list_for_each_entry_safe(fctx, n, fcs, list) {
+               struct userfaultfd_ctx *octx = fctx->orig;
+               struct userfaultfd_ctx *ctx = fctx->new;
+
+               atomic_dec(&octx->mmap_changing);
+               VM_BUG_ON(atomic_read(&octx->mmap_changing) < 0);
+               userfaultfd_ctx_put(octx);
+               userfaultfd_ctx_put(ctx);
+
+               list_del(&fctx->list);
+               kfree(fctx);
+       }
+}
+
 void mremap_userfaultfd_prep(struct vm_area_struct *vma,
                             struct vm_userfaultfd_ctx *vm_ctx)
 {
index 5f0494702e0b55a2343a3f8e08ed33e5e1974f81..5ca8d01068273dbdfd8c1326701a6be7d4df0244 100644 (file)
@@ -185,17 +185,20 @@ out:
 }
 
 /*
- * Free up the per-ag resources associated with the mount structure.
+ * Free up the per-ag resources  within the specified AG range.
  */
 void
-xfs_free_perag(
-       struct xfs_mount        *mp)
+xfs_free_perag_range(
+       struct xfs_mount        *mp,
+       xfs_agnumber_t          first_agno,
+       xfs_agnumber_t          end_agno)
+
 {
-       struct xfs_perag        *pag;
        xfs_agnumber_t          agno;
 
-       for (agno = 0; agno < mp->m_sb.sb_agcount; agno++) {
-               pag = xa_erase(&mp->m_perags, agno);
+       for (agno = first_agno; agno < end_agno; agno++) {
+               struct xfs_perag        *pag = xa_erase(&mp->m_perags, agno);
+
                ASSERT(pag);
                XFS_IS_CORRUPT(pag->pag_mount, atomic_read(&pag->pag_ref) != 0);
                xfs_defer_drain_free(&pag->pag_intents_drain);
@@ -270,54 +273,37 @@ xfs_agino_range(
        return __xfs_agino_range(mp, xfs_ag_block_count(mp, agno), first, last);
 }
 
-/*
- * Free perag within the specified AG range, it is only used to free unused
- * perags under the error handling path.
- */
-void
-xfs_free_unused_perag_range(
+int
+xfs_update_last_ag_size(
        struct xfs_mount        *mp,
-       xfs_agnumber_t          agstart,
-       xfs_agnumber_t          agend)
+       xfs_agnumber_t          prev_agcount)
 {
-       struct xfs_perag        *pag;
-       xfs_agnumber_t          index;
+       struct xfs_perag        *pag = xfs_perag_grab(mp, prev_agcount - 1);
 
-       for (index = agstart; index < agend; index++) {
-               pag = xa_erase(&mp->m_perags, index);
-               if (!pag)
-                       break;
-               xfs_buf_cache_destroy(&pag->pag_bcache);
-               xfs_defer_drain_free(&pag->pag_intents_drain);
-               kfree(pag);
-       }
+       if (!pag)
+               return -EFSCORRUPTED;
+       pag->block_count = __xfs_ag_block_count(mp, prev_agcount - 1,
+                       mp->m_sb.sb_agcount, mp->m_sb.sb_dblocks);
+       __xfs_agino_range(mp, pag->block_count, &pag->agino_min,
+                       &pag->agino_max);
+       xfs_perag_rele(pag);
+       return 0;
 }
 
 int
 xfs_initialize_perag(
        struct xfs_mount        *mp,
-       xfs_agnumber_t          agcount,
+       xfs_agnumber_t          old_agcount,
+       xfs_agnumber_t          new_agcount,
        xfs_rfsblock_t          dblocks,
        xfs_agnumber_t          *maxagi)
 {
        struct xfs_perag        *pag;
        xfs_agnumber_t          index;
-       xfs_agnumber_t          first_initialised = NULLAGNUMBER;
        int                     error;
 
-       /*
-        * Walk the current per-ag tree so we don't try to initialise AGs
-        * that already exist (growfs case). Allocate and insert all the
-        * AGs we don't find ready for initialisation.
-        */
-       for (index = 0; index < agcount; index++) {
-               pag = xfs_perag_get(mp, index);
-               if (pag) {
-                       xfs_perag_put(pag);
-                       continue;
-               }
-
-               pag = kzalloc(sizeof(*pag), GFP_KERNEL | __GFP_RETRY_MAYFAIL);
+       for (index = old_agcount; index < new_agcount; index++) {
+               pag = kzalloc(sizeof(*pag), GFP_KERNEL);
                if (!pag) {
                        error = -ENOMEM;
                        goto out_unwind_new_pags;
@@ -353,21 +339,17 @@ xfs_initialize_perag(
                /* Active ref owned by mount indicates AG is online. */
                atomic_set(&pag->pag_active_ref, 1);
 
-               /* first new pag is fully initialized */
-               if (first_initialised == NULLAGNUMBER)
-                       first_initialised = index;
-
                /*
                 * Pre-calculated geometry
                 */
-               pag->block_count = __xfs_ag_block_count(mp, index, agcount,
+               pag->block_count = __xfs_ag_block_count(mp, index, new_agcount,
                                dblocks);
                pag->min_block = XFS_AGFL_BLOCK(mp);
                __xfs_agino_range(mp, pag->block_count, &pag->agino_min,
                                &pag->agino_max);
        }
 
-       index = xfs_set_inode_alloc(mp, agcount);
+       index = xfs_set_inode_alloc(mp, new_agcount);
 
        if (maxagi)
                *maxagi = index;
@@ -381,8 +363,7 @@ out_remove_pag:
 out_free_pag:
        kfree(pag);
 out_unwind_new_pags:
-       /* unwind any prior newly initialized pags */
-       xfs_free_unused_perag_range(mp, first_initialised, agcount);
+       xfs_free_perag_range(mp, old_agcount, index);
        return error;
 }
 
index d9cccd093b60e06a5d16f79662471e67455329fc..9edfe0e9643964ab2d762b51b98347507cb7db46 100644 (file)
@@ -144,12 +144,13 @@ __XFS_AG_OPSTATE(prefers_metadata, PREFERS_METADATA)
 __XFS_AG_OPSTATE(allows_inodes, ALLOWS_INODES)
 __XFS_AG_OPSTATE(agfl_needs_reset, AGFL_NEEDS_RESET)
 
-void xfs_free_unused_perag_range(struct xfs_mount *mp, xfs_agnumber_t agstart,
-                       xfs_agnumber_t agend);
-int xfs_initialize_perag(struct xfs_mount *mp, xfs_agnumber_t agcount,
-                       xfs_rfsblock_t dcount, xfs_agnumber_t *maxagi);
+int xfs_initialize_perag(struct xfs_mount *mp, xfs_agnumber_t old_agcount,
+               xfs_agnumber_t agcount, xfs_rfsblock_t dcount,
+               xfs_agnumber_t *maxagi);
+void xfs_free_perag_range(struct xfs_mount *mp, xfs_agnumber_t first_agno,
+               xfs_agnumber_t end_agno);
 int xfs_initialize_perag_data(struct xfs_mount *mp, xfs_agnumber_t agno);
-void xfs_free_perag(struct xfs_mount *mp);
+int xfs_update_last_ag_size(struct xfs_mount *mp, xfs_agnumber_t prev_agcount);
 
 /* Passive AG references */
 struct xfs_perag *xfs_perag_get(struct xfs_mount *mp, xfs_agnumber_t agno);
index 59326f84f6a571581edf6074003a48a20cba0f76..22bdbb3e9980c414c4a6e17f47b06f9965ecf45c 100644 (file)
@@ -1923,7 +1923,7 @@ restart:
                                error = -EFSCORRUPTED;
                                goto error0;
                        }
-                       if (flen < bestrlen)
+                       if (flen <= bestrlen)
                                break;
                        busy = xfs_alloc_compute_aligned(args, fbno, flen,
                                        &rbno, &rlen, &busy_gen);
@@ -2766,7 +2766,6 @@ xfs_alloc_commit_autoreap(
                xfs_defer_item_unpause(tp, aarp->dfp);
 }
 
-#ifdef DEBUG
 /*
  * Check if an AGF has a free extent record whose length is equal to
  * args->minlen.
@@ -2806,7 +2805,6 @@ out:
 
        return error;
 }
-#endif
 
 /*
  * Decide whether to use this allocation group for this allocation.
@@ -2880,15 +2878,14 @@ xfs_alloc_fix_freelist(
        if (!xfs_alloc_space_available(args, need, alloc_flags))
                goto out_agbp_relse;
 
-#ifdef DEBUG
-       if (args->alloc_minlen_only) {
+       if (IS_ENABLED(CONFIG_XFS_DEBUG) && args->alloc_minlen_only) {
                int stat;
 
                error = xfs_exact_minlen_extent_available(args, agbp, &stat);
                if (error || !stat)
                        goto out_agbp_relse;
        }
-#endif
+
        /*
         * Make the freelist shorter if it's too long.
         *
index fae170825be06463b93d616fc9178f11cf533776..0165452e7cd05593e60450fdcc59dd0cb9287422 100644 (file)
@@ -53,11 +53,9 @@ typedef struct xfs_alloc_arg {
        int             datatype;       /* mask defining data type treatment */
        char            wasdel;         /* set if allocation was prev delayed */
        char            wasfromfl;      /* set if allocation is from freelist */
+       bool            alloc_minlen_only; /* allocate exact minlen extent */
        struct xfs_owner_info   oinfo;  /* owner of blocks being allocated */
        enum xfs_ag_resv_type   resv;   /* block reservation to use */
-#ifdef DEBUG
-       bool            alloc_minlen_only; /* allocate exact minlen extent */
-#endif
 } xfs_alloc_arg_t;
 
 /*
index f30bcc64100d56b7199fc6b73ee777f6a6e06aa9..c63da14eee04323682432f9307abab85371c99cd 100644 (file)
@@ -51,7 +51,6 @@ STATIC int xfs_attr_shortform_addname(xfs_da_args_t *args);
 STATIC int xfs_attr_leaf_get(xfs_da_args_t *args);
 STATIC int xfs_attr_leaf_removename(xfs_da_args_t *args);
 STATIC int xfs_attr_leaf_hasname(struct xfs_da_args *args, struct xfs_buf **bp);
-STATIC int xfs_attr_leaf_try_add(struct xfs_da_args *args);
 
 /*
  * Internal routines when attribute list is more than one block.
@@ -437,6 +436,33 @@ xfs_attr_hashval(
        return xfs_attr_hashname(name, namelen);
 }
 
+/* Save the current remote block info and clear the current pointers. */
+static void
+xfs_attr_save_rmt_blk(
+       struct xfs_da_args      *args)
+{
+       args->blkno2 = args->blkno;
+       args->index2 = args->index;
+       args->rmtblkno2 = args->rmtblkno;
+       args->rmtblkcnt2 = args->rmtblkcnt;
+       args->rmtvaluelen2 = args->rmtvaluelen;
+       args->rmtblkno = 0;
+       args->rmtblkcnt = 0;
+       args->rmtvaluelen = 0;
+}
+
+/* Set stored info about a remote block */
+static void
+xfs_attr_restore_rmt_blk(
+       struct xfs_da_args      *args)
+{
+       args->blkno = args->blkno2;
+       args->index = args->index2;
+       args->rmtblkno = args->rmtblkno2;
+       args->rmtblkcnt = args->rmtblkcnt2;
+       args->rmtvaluelen = args->rmtvaluelen2;
+}
+
 /*
  * PPTR_REPLACE operations require the caller to set the old and new names and
  * values explicitly.  Update the canonical fields to the new name and value
@@ -482,48 +508,73 @@ xfs_attr_complete_op(
        return replace_state;
 }
 
+/*
+ * Try to add an attribute to an inode in leaf form.
+ */
 static int
 xfs_attr_leaf_addname(
        struct xfs_attr_intent  *attr)
 {
        struct xfs_da_args      *args = attr->xattri_da_args;
+       struct xfs_buf          *bp;
        int                     error;
 
        ASSERT(xfs_attr_is_leaf(args->dp));
 
+       error = xfs_attr3_leaf_read(args->trans, args->dp, args->owner, 0, &bp);
+       if (error)
+               return error;
+
        /*
-        * Use the leaf buffer we may already hold locked as a result of
-        * a sf-to-leaf conversion.
+        * Look up the xattr name to set the insertion point for the new xattr.
         */
-       error = xfs_attr_leaf_try_add(args);
-
-       if (error == -ENOSPC) {
-               error = xfs_attr3_leaf_to_node(args);
-               if (error)
-                       return error;
+       error = xfs_attr3_leaf_lookup_int(bp, args);
+       switch (error) {
+       case -ENOATTR:
+               if (args->op_flags & XFS_DA_OP_REPLACE)
+                       goto out_brelse;
+               break;
+       case -EEXIST:
+               if (!(args->op_flags & XFS_DA_OP_REPLACE))
+                       goto out_brelse;
 
+               trace_xfs_attr_leaf_replace(args);
                /*
-                * We're not in leaf format anymore, so roll the transaction and
-                * retry the add to the newly allocated node block.
+                * Save the existing remote attr state so that the current
+                * values reflect the state of the new attribute we are about to
+                * add, not the attribute we just found and will remove later.
                 */
-               attr->xattri_dela_state = XFS_DAS_NODE_ADD;
-               goto out;
+               xfs_attr_save_rmt_blk(args);
+               break;
+       case 0:
+               break;
+       default:
+               goto out_brelse;
        }
-       if (error)
-               return error;
 
        /*
         * We need to commit and roll if we need to allocate remote xattr blocks
         * or perform more xattr manipulations. Otherwise there is nothing more
         * to do and we can return success.
         */
-       if (args->rmtblkno)
+       if (!xfs_attr3_leaf_add(bp, args)) {
+               error = xfs_attr3_leaf_to_node(args);
+               if (error)
+                       return error;
+
+               attr->xattri_dela_state = XFS_DAS_NODE_ADD;
+       } else if (args->rmtblkno) {
                attr->xattri_dela_state = XFS_DAS_LEAF_SET_RMT;
-       else
-               attr->xattri_dela_state = xfs_attr_complete_op(attr,
-                                                       XFS_DAS_LEAF_REPLACE);
-out:
+       } else {
+               attr->xattri_dela_state =
+                       xfs_attr_complete_op(attr, XFS_DAS_LEAF_REPLACE);
+       }
+
        trace_xfs_attr_leaf_addname_return(attr->xattri_dela_state, args->dp);
+       return 0;
+
+out_brelse:
+       xfs_trans_brelse(args->trans, bp);
        return error;
 }
 
@@ -546,7 +597,7 @@ xfs_attr_node_addname(
                return error;
 
        error = xfs_attr_node_try_addname(attr);
-       if (error == -ENOSPC) {
+       if (error == 1) {
                error = xfs_attr3_leaf_to_node(args);
                if (error)
                        return error;
@@ -1170,88 +1221,6 @@ xfs_attr_shortform_addname(
  * External routines when attribute list is one block
  *========================================================================*/
 
-/* Save the current remote block info and clear the current pointers. */
-static void
-xfs_attr_save_rmt_blk(
-       struct xfs_da_args      *args)
-{
-       args->blkno2 = args->blkno;
-       args->index2 = args->index;
-       args->rmtblkno2 = args->rmtblkno;
-       args->rmtblkcnt2 = args->rmtblkcnt;
-       args->rmtvaluelen2 = args->rmtvaluelen;
-       args->rmtblkno = 0;
-       args->rmtblkcnt = 0;
-       args->rmtvaluelen = 0;
-}
-
-/* Set stored info about a remote block */
-static void
-xfs_attr_restore_rmt_blk(
-       struct xfs_da_args      *args)
-{
-       args->blkno = args->blkno2;
-       args->index = args->index2;
-       args->rmtblkno = args->rmtblkno2;
-       args->rmtblkcnt = args->rmtblkcnt2;
-       args->rmtvaluelen = args->rmtvaluelen2;
-}
-
-/*
- * Tries to add an attribute to an inode in leaf form
- *
- * This function is meant to execute as part of a delayed operation and leaves
- * the transaction handling to the caller.  On success the attribute is added
- * and the inode and transaction are left dirty.  If there is not enough space,
- * the attr data is converted to node format and -ENOSPC is returned. Caller is
- * responsible for handling the dirty inode and transaction or adding the attr
- * in node format.
- */
-STATIC int
-xfs_attr_leaf_try_add(
-       struct xfs_da_args      *args)
-{
-       struct xfs_buf          *bp;
-       int                     error;
-
-       error = xfs_attr3_leaf_read(args->trans, args->dp, args->owner, 0, &bp);
-       if (error)
-               return error;
-
-       /*
-        * Look up the xattr name to set the insertion point for the new xattr.
-        */
-       error = xfs_attr3_leaf_lookup_int(bp, args);
-       switch (error) {
-       case -ENOATTR:
-               if (args->op_flags & XFS_DA_OP_REPLACE)
-                       goto out_brelse;
-               break;
-       case -EEXIST:
-               if (!(args->op_flags & XFS_DA_OP_REPLACE))
-                       goto out_brelse;
-
-               trace_xfs_attr_leaf_replace(args);
-               /*
-                * Save the existing remote attr state so that the current
-                * values reflect the state of the new attribute we are about to
-                * add, not the attribute we just found and will remove later.
-                */
-               xfs_attr_save_rmt_blk(args);
-               break;
-       case 0:
-               break;
-       default:
-               goto out_brelse;
-       }
-
-       return xfs_attr3_leaf_add(bp, args);
-
-out_brelse:
-       xfs_trans_brelse(args->trans, bp);
-       return error;
-}
-
 /*
  * Return EEXIST if attr is found, or ENOATTR if not
  */
@@ -1417,9 +1386,12 @@ error:
 /*
  * Add a name to a Btree-format attribute list.
  *
- * This will involve walking down the Btree, and may involve splitting
- * leaf nodes and even splitting intermediate nodes up to and including
- * the root node (a special case of an intermediate node).
+ * This will involve walking down the Btree, and may involve splitting leaf
+ * nodes and even splitting intermediate nodes up to and including the root
+ * node (a special case of an intermediate node).
+ *
+ * If the tree was still in single leaf format and needs to converted to
+ * real node format return 1 and let the caller handle that.
  */
 static int
 xfs_attr_node_try_addname(
@@ -1427,21 +1399,21 @@ xfs_attr_node_try_addname(
 {
        struct xfs_da_state             *state = attr->xattri_da_state;
        struct xfs_da_state_blk         *blk;
-       int                             error;
+       int                             error = 0;
 
        trace_xfs_attr_node_addname(state->args);
 
        blk = &state->path.blk[state->path.active-1];
        ASSERT(blk->magic == XFS_ATTR_LEAF_MAGIC);
 
-       error = xfs_attr3_leaf_add(blk->bp, state->args);
-       if (error == -ENOSPC) {
+       if (!xfs_attr3_leaf_add(blk->bp, state->args)) {
                if (state->path.active == 1) {
                        /*
                         * Its really a single leaf node, but it had
                         * out-of-line values so it looked like it *might*
                         * have been a b-tree. Let the caller deal with this.
                         */
+                       error = 1;
                        goto out;
                }
 
index e50d913ad32fdc2a19d517f6173b1d8d839d9e1e..fddb55605e0cc64471190f6622a70ad7edb4f043 100644 (file)
@@ -47,7 +47,7 @@
  */
 STATIC int xfs_attr3_leaf_create(struct xfs_da_args *args,
                                 xfs_dablk_t which_block, struct xfs_buf **bpp);
-STATIC int xfs_attr3_leaf_add_work(struct xfs_buf *leaf_buffer,
+STATIC void xfs_attr3_leaf_add_work(struct xfs_buf *leaf_buffer,
                                   struct xfs_attr3_icleaf_hdr *ichdr,
                                   struct xfs_da_args *args, int freemap_index);
 STATIC void xfs_attr3_leaf_compact(struct xfs_da_args *args,
@@ -995,10 +995,8 @@ xfs_attr_shortform_to_leaf(
                xfs_attr_sethash(&nargs);
                error = xfs_attr3_leaf_lookup_int(bp, &nargs); /* set a->index */
                ASSERT(error == -ENOATTR);
-               error = xfs_attr3_leaf_add(bp, &nargs);
-               ASSERT(error != -ENOSPC);
-               if (error)
-                       goto out;
+               if (!xfs_attr3_leaf_add(bp, &nargs))
+                       ASSERT(0);
                sfe = xfs_attr_sf_nextentry(sfe);
        }
        error = 0;
@@ -1333,6 +1331,9 @@ xfs_attr3_leaf_create(
 
 /*
  * Split the leaf node, rebalance, then add the new entry.
+ *
+ * Returns 0 if the entry was added, 1 if a further split is needed or a
+ * negative error number otherwise.
  */
 int
 xfs_attr3_leaf_split(
@@ -1340,8 +1341,9 @@ xfs_attr3_leaf_split(
        struct xfs_da_state_blk *oldblk,
        struct xfs_da_state_blk *newblk)
 {
-       xfs_dablk_t blkno;
-       int error;
+       bool                    added;
+       xfs_dablk_t             blkno;
+       int                     error;
 
        trace_xfs_attr_leaf_split(state->args);
 
@@ -1376,10 +1378,10 @@ xfs_attr3_leaf_split(
         */
        if (state->inleaf) {
                trace_xfs_attr_leaf_add_old(state->args);
-               error = xfs_attr3_leaf_add(oldblk->bp, state->args);
+               added = xfs_attr3_leaf_add(oldblk->bp, state->args);
        } else {
                trace_xfs_attr_leaf_add_new(state->args);
-               error = xfs_attr3_leaf_add(newblk->bp, state->args);
+               added = xfs_attr3_leaf_add(newblk->bp, state->args);
        }
 
        /*
@@ -1387,13 +1389,15 @@ xfs_attr3_leaf_split(
         */
        oldblk->hashval = xfs_attr_leaf_lasthash(oldblk->bp, NULL);
        newblk->hashval = xfs_attr_leaf_lasthash(newblk->bp, NULL);
-       return error;
+       if (!added)
+               return 1;
+       return 0;
 }
 
 /*
  * Add a name to the leaf attribute list structure.
  */
-int
+bool
 xfs_attr3_leaf_add(
        struct xfs_buf          *bp,
        struct xfs_da_args      *args)
@@ -1402,6 +1406,7 @@ xfs_attr3_leaf_add(
        struct xfs_attr3_icleaf_hdr ichdr;
        int                     tablesize;
        int                     entsize;
+       bool                    added = true;
        int                     sum;
        int                     tmp;
        int                     i;
@@ -1430,7 +1435,7 @@ xfs_attr3_leaf_add(
                if (ichdr.freemap[i].base < ichdr.firstused)
                        tmp += sizeof(xfs_attr_leaf_entry_t);
                if (ichdr.freemap[i].size >= tmp) {
-                       tmp = xfs_attr3_leaf_add_work(bp, &ichdr, args, i);
+                       xfs_attr3_leaf_add_work(bp, &ichdr, args, i);
                        goto out_log_hdr;
                }
                sum += ichdr.freemap[i].size;
@@ -1442,7 +1447,7 @@ xfs_attr3_leaf_add(
         * no good and we should just give up.
         */
        if (!ichdr.holes && sum < entsize)
-               return -ENOSPC;
+               return false;
 
        /*
         * Compact the entries to coalesce free space.
@@ -1455,24 +1460,24 @@ xfs_attr3_leaf_add(
         * free region, in freemap[0].  If it is not big enough, give up.
         */
        if (ichdr.freemap[0].size < (entsize + sizeof(xfs_attr_leaf_entry_t))) {
-               tmp = -ENOSPC;
+               added = false;
                goto out_log_hdr;
        }
 
-       tmp = xfs_attr3_leaf_add_work(bp, &ichdr, args, 0);
+       xfs_attr3_leaf_add_work(bp, &ichdr, args, 0);
 
 out_log_hdr:
        xfs_attr3_leaf_hdr_to_disk(args->geo, leaf, &ichdr);
        xfs_trans_log_buf(args->trans, bp,
                XFS_DA_LOGRANGE(leaf, &leaf->hdr,
                                xfs_attr3_leaf_hdr_size(leaf)));
-       return tmp;
+       return added;
 }
 
 /*
  * Add a name to a leaf attribute list structure.
  */
-STATIC int
+STATIC void
 xfs_attr3_leaf_add_work(
        struct xfs_buf          *bp,
        struct xfs_attr3_icleaf_hdr *ichdr,
@@ -1590,7 +1595,6 @@ xfs_attr3_leaf_add_work(
                }
        }
        ichdr->usedbytes += xfs_attr_leaf_entsize(leaf, args->index);
-       return 0;
 }
 
 /*
index bac219589896ad6c2bc623da6e34540f6cd8f6a5..589f810eedc0d846fa56e1d72c8b69dba03969a7 100644 (file)
@@ -76,7 +76,7 @@ int   xfs_attr3_leaf_split(struct xfs_da_state *state,
 int    xfs_attr3_leaf_lookup_int(struct xfs_buf *leaf,
                                        struct xfs_da_args *args);
 int    xfs_attr3_leaf_getvalue(struct xfs_buf *bp, struct xfs_da_args *args);
-int    xfs_attr3_leaf_add(struct xfs_buf *leaf_buffer,
+bool   xfs_attr3_leaf_add(struct xfs_buf *leaf_buffer,
                                 struct xfs_da_args *args);
 int    xfs_attr3_leaf_remove(struct xfs_buf *leaf_buffer,
                                    struct xfs_da_args *args);
index 8090e8249116d0b24d506b495455b996be555eac..36dd08d132931dfe0e39feffda2c90dcb5aa803e 100644 (file)
@@ -3477,31 +3477,19 @@ xfs_bmap_process_allocated_extent(
        xfs_bmap_alloc_account(ap);
 }
 
-#ifdef DEBUG
 static int
 xfs_bmap_exact_minlen_extent_alloc(
-       struct xfs_bmalloca     *ap)
+       struct xfs_bmalloca     *ap,
+       struct xfs_alloc_arg    *args)
 {
-       struct xfs_mount        *mp = ap->ip->i_mount;
-       struct xfs_alloc_arg    args = { .tp = ap->tp, .mp = mp };
-       xfs_fileoff_t           orig_offset;
-       xfs_extlen_t            orig_length;
-       int                     error;
-
-       ASSERT(ap->length);
-
        if (ap->minlen != 1) {
-               ap->blkno = NULLFSBLOCK;
-               ap->length = 0;
+               args->fsbno = NULLFSBLOCK;
                return 0;
        }
 
-       orig_offset = ap->offset;
-       orig_length = ap->length;
-
-       args.alloc_minlen_only = 1;
-
-       xfs_bmap_compute_alignments(ap, &args);
+       args->alloc_minlen_only = 1;
+       args->minlen = args->maxlen = ap->minlen;
+       args->total = ap->total;
 
        /*
         * Unlike the longest extent available in an AG, we don't track
@@ -3511,39 +3499,16 @@ xfs_bmap_exact_minlen_extent_alloc(
         * we need not be concerned about a drop in performance in
         * "debug only" code paths.
         */
-       ap->blkno = XFS_AGB_TO_FSB(mp, 0, 0);
+       ap->blkno = XFS_AGB_TO_FSB(ap->ip->i_mount, 0, 0);
 
-       args.oinfo = XFS_RMAP_OINFO_SKIP_UPDATE;
-       args.minlen = args.maxlen = ap->minlen;
-       args.total = ap->total;
-
-       args.alignment = 1;
-       args.minalignslop = 0;
-
-       args.minleft = ap->minleft;
-       args.wasdel = ap->wasdel;
-       args.resv = XFS_AG_RESV_NONE;
-       args.datatype = ap->datatype;
-
-       error = xfs_alloc_vextent_first_ag(&args, ap->blkno);
-       if (error)
-               return error;
-
-       if (args.fsbno != NULLFSBLOCK) {
-               xfs_bmap_process_allocated_extent(ap, &args, orig_offset,
-                       orig_length);
-       } else {
-               ap->blkno = NULLFSBLOCK;
-               ap->length = 0;
-       }
-
-       return 0;
+       /*
+        * Call xfs_bmap_btalloc_low_space here as it first does a "normal" AG
+        * iteration and then drops args->total to args->minlen, which might be
+        * required to find an allocation for the transaction reservation when
+        * the file system is very full.
+        */
+       return xfs_bmap_btalloc_low_space(ap, args);
 }
-#else
-
-#define xfs_bmap_exact_minlen_extent_alloc(bma) (-EFSCORRUPTED)
-
-#endif
 
 /*
  * If we are not low on available data blocks and we are allocating at
@@ -3801,8 +3766,11 @@ xfs_bmap_btalloc(
        /* Trim the allocation back to the maximum an AG can fit. */
        args.maxlen = min(ap->length, mp->m_ag_max_usable);
 
-       if ((ap->datatype & XFS_ALLOC_USERDATA) &&
-           xfs_inode_is_filestream(ap->ip))
+       if (unlikely(XFS_TEST_ERROR(false, mp,
+                       XFS_ERRTAG_BMAP_ALLOC_MINLEN_EXTENT)))
+               error = xfs_bmap_exact_minlen_extent_alloc(ap, &args);
+       else if ((ap->datatype & XFS_ALLOC_USERDATA) &&
+                       xfs_inode_is_filestream(ap->ip))
                error = xfs_bmap_btalloc_filestreams(ap, &args, stripe_align);
        else
                error = xfs_bmap_btalloc_best_length(ap, &args, stripe_align);
@@ -4176,43 +4144,6 @@ out:
        return error;
 }
 
-static int
-xfs_bmap_alloc_userdata(
-       struct xfs_bmalloca     *bma)
-{
-       struct xfs_mount        *mp = bma->ip->i_mount;
-       int                     whichfork = xfs_bmapi_whichfork(bma->flags);
-       int                     error;
-
-       /*
-        * Set the data type being allocated. For the data fork, the first data
-        * in the file is treated differently to all other allocations. For the
-        * attribute fork, we only need to ensure the allocated range is not on
-        * the busy list.
-        */
-       bma->datatype = XFS_ALLOC_NOBUSY;
-       if (whichfork == XFS_DATA_FORK || whichfork == XFS_COW_FORK) {
-               bma->datatype |= XFS_ALLOC_USERDATA;
-               if (bma->offset == 0)
-                       bma->datatype |= XFS_ALLOC_INITIAL_USER_DATA;
-
-               if (mp->m_dalign && bma->length >= mp->m_dalign) {
-                       error = xfs_bmap_isaeof(bma, whichfork);
-                       if (error)
-                               return error;
-               }
-
-               if (XFS_IS_REALTIME_INODE(bma->ip))
-                       return xfs_bmap_rtalloc(bma);
-       }
-
-       if (unlikely(XFS_TEST_ERROR(false, mp,
-                       XFS_ERRTAG_BMAP_ALLOC_MINLEN_EXTENT)))
-               return xfs_bmap_exact_minlen_extent_alloc(bma);
-
-       return xfs_bmap_btalloc(bma);
-}
-
 static int
 xfs_bmapi_allocate(
        struct xfs_bmalloca     *bma)
@@ -4230,15 +4161,32 @@ xfs_bmapi_allocate(
        else
                bma->minlen = 1;
 
-       if (bma->flags & XFS_BMAPI_METADATA) {
-               if (unlikely(XFS_TEST_ERROR(false, mp,
-                               XFS_ERRTAG_BMAP_ALLOC_MINLEN_EXTENT)))
-                       error = xfs_bmap_exact_minlen_extent_alloc(bma);
-               else
-                       error = xfs_bmap_btalloc(bma);
-       } else {
-               error = xfs_bmap_alloc_userdata(bma);
+       if (!(bma->flags & XFS_BMAPI_METADATA)) {
+               /*
+                * For the data and COW fork, the first data in the file is
+                * treated differently to all other allocations. For the
+                * attribute fork, we only need to ensure the allocated range
+                * is not on the busy list.
+                */
+               bma->datatype = XFS_ALLOC_NOBUSY;
+               if (whichfork == XFS_DATA_FORK || whichfork == XFS_COW_FORK) {
+                       bma->datatype |= XFS_ALLOC_USERDATA;
+                       if (bma->offset == 0)
+                               bma->datatype |= XFS_ALLOC_INITIAL_USER_DATA;
+
+                       if (mp->m_dalign && bma->length >= mp->m_dalign) {
+                               error = xfs_bmap_isaeof(bma, whichfork);
+                               if (error)
+                                       return error;
+                       }
+               }
        }
+
+       if ((bma->datatype & XFS_ALLOC_USERDATA) &&
+           XFS_IS_REALTIME_INODE(bma->ip))
+               error = xfs_bmap_rtalloc(bma);
+       else
+               error = xfs_bmap_btalloc(bma);
        if (error)
                return error;
        if (bma->blkno == NULLFSBLOCK)
index 16a529a8878083aee350d746c2d98fd307b83cef..17d9e6154f1978ce5a5cb82176eea4d6b9cd768d 100644 (file)
@@ -593,9 +593,8 @@ xfs_da3_split(
                switch (oldblk->magic) {
                case XFS_ATTR_LEAF_MAGIC:
                        error = xfs_attr3_leaf_split(state, oldblk, newblk);
-                       if ((error != 0) && (error != -ENOSPC)) {
+                       if (error < 0)
                                return error;   /* GROT: attr is inconsistent */
-                       }
                        if (!error) {
                                addblk = newblk;
                                break;
@@ -617,6 +616,8 @@ xfs_da3_split(
                                error = xfs_attr3_leaf_split(state, newblk,
                                                            &state->extrablk);
                        }
+                       if (error == 1)
+                               return -ENOSPC;
                        if (error)
                                return error;   /* GROT: attr inconsistent */
                        addblk = newblk;
index 49dc38acc66bf8000447de0e067720490379db98..4505f4829d53f1f4e4024f533f45a71d90265ca8 100644 (file)
@@ -801,7 +801,7 @@ xrep_bmap(
 {
        struct xrep_bmap        *rb;
        char                    *descr;
-       unsigned int            max_bmbt_recs;
+       xfs_extnum_t            max_bmbt_recs;
        bool                    large_extcount;
        int                     error = 0;
 
index a00ec7ae17925d9c38066764014fee7d91491e7b..c8d2196a04e15bd8a8348c2a51acb5e94b28189c 100644 (file)
@@ -657,7 +657,7 @@ xrep_ibt_build_new_trees(
         * Start by setting up the inobt staging cursor.
         */
        fsbno = XFS_AGB_TO_FSB(sc->mp, sc->sa.pag->pag_agno,
-                       XFS_IBT_BLOCK(sc->mp)),
+                       XFS_IBT_BLOCK(sc->mp));
        xrep_newbt_init_ag(&ri->new_inobt, sc, &XFS_RMAP_OINFO_INOBT, fsbno,
                        XFS_AG_RESV_NONE);
        ri->new_inobt.bload.claim_block = xrep_ibt_claim_block;
@@ -678,7 +678,7 @@ xrep_ibt_build_new_trees(
                        resv = XFS_AG_RESV_NONE;
 
                fsbno = XFS_AGB_TO_FSB(sc->mp, sc->sa.pag->pag_agno,
-                               XFS_FIBT_BLOCK(sc->mp)),
+                               XFS_FIBT_BLOCK(sc->mp));
                xrep_newbt_init_ag(&ri->new_finobt, sc, &XFS_RMAP_OINFO_INOBT,
                                fsbno, resv);
                ri->new_finobt.bload.claim_block = xrep_fibt_claim_block;
index 67478294f11ae8616195f259a841cdede1f5d2f9..155bbaaa496e44236a108128c4e7e69ed998dfd3 100644 (file)
@@ -1084,9 +1084,11 @@ xrep_metadata_inode_forks(
                return error;
 
        /* Make sure the attr fork looks ok before we delete it. */
-       error = xrep_metadata_inode_subtype(sc, XFS_SCRUB_TYPE_BMBTA);
-       if (error)
-               return error;
+       if (xfs_inode_hasattr(sc->ip)) {
+               error = xrep_metadata_inode_subtype(sc, XFS_SCRUB_TYPE_BMBTA);
+               if (error)
+                       return error;
+       }
 
        /* Clear the reflink flag since metadata never shares. */
        if (xfs_is_reflink_inode(sc->ip)) {
index 6dead20338e24c4dc7a57ec13fefb98a220bd764..559a3a57709748f9293034ff5711ef656b6eabf1 100644 (file)
@@ -116,7 +116,7 @@ xfs_end_ioend(
        if (unlikely(error)) {
                if (ioend->io_flags & IOMAP_F_SHARED) {
                        xfs_reflink_cancel_cow_range(ip, offset, size, true);
-                       xfs_bmap_punch_delalloc_range(ip, offset,
+                       xfs_bmap_punch_delalloc_range(ip, XFS_DATA_FORK, offset,
                                        offset + size);
                }
                goto done;
@@ -456,7 +456,7 @@ xfs_discard_folio(
         * byte of the next folio. Hence the end offset is only dependent on the
         * folio itself and not the start offset that is passed in.
         */
-       xfs_bmap_punch_delalloc_range(ip, pos,
+       xfs_bmap_punch_delalloc_range(ip, XFS_DATA_FORK, pos,
                                folio_pos(folio) + folio_size(folio));
 }
 
index 053d567c9108401b9130d5021ee526296562e995..4719ec90029cb713c5c894128192760728925a04 100644 (file)
@@ -442,11 +442,12 @@ out_unlock_iolock:
 void
 xfs_bmap_punch_delalloc_range(
        struct xfs_inode        *ip,
+       int                     whichfork,
        xfs_off_t               start_byte,
        xfs_off_t               end_byte)
 {
        struct xfs_mount        *mp = ip->i_mount;
-       struct xfs_ifork        *ifp = &ip->i_df;
+       struct xfs_ifork        *ifp = xfs_ifork_ptr(ip, whichfork);
        xfs_fileoff_t           start_fsb = XFS_B_TO_FSBT(mp, start_byte);
        xfs_fileoff_t           end_fsb = XFS_B_TO_FSB(mp, end_byte);
        struct xfs_bmbt_irec    got, del;
@@ -474,11 +475,14 @@ xfs_bmap_punch_delalloc_range(
                        continue;
                }
 
-               xfs_bmap_del_extent_delay(ip, XFS_DATA_FORK, &icur, &got, &del);
+               xfs_bmap_del_extent_delay(ip, whichfork, &icur, &got, &del);
                if (!xfs_iext_get_extent(ifp, &icur, &got))
                        break;
        }
 
+       if (whichfork == XFS_COW_FORK && !ifp->if_bytes)
+               xfs_inode_clear_cowblocks_tag(ip);
+
 out_unlock:
        xfs_iunlock(ip, XFS_ILOCK_EXCL);
 }
@@ -580,7 +584,7 @@ xfs_free_eofblocks(
         */
        if (ip->i_diflags & (XFS_DIFLAG_PREALLOC | XFS_DIFLAG_APPEND)) {
                if (ip->i_delayed_blks) {
-                       xfs_bmap_punch_delalloc_range(ip,
+                       xfs_bmap_punch_delalloc_range(ip, XFS_DATA_FORK,
                                round_up(XFS_ISIZE(ip), mp->m_sb.sb_blocksize),
                                LLONG_MAX);
                }
index eb0895bfb9dae44ef8a38e6ccea9e5b3928efab0..b29760d36e1ab1ef5e8392c1457180ce3ac9f59d 100644 (file)
@@ -30,7 +30,7 @@ xfs_bmap_rtalloc(struct xfs_bmalloca *ap)
 }
 #endif /* CONFIG_XFS_RT */
 
-void   xfs_bmap_punch_delalloc_range(struct xfs_inode *ip,
+void   xfs_bmap_punch_delalloc_range(struct xfs_inode *ip, int whichfork,
                xfs_off_t start_byte, xfs_off_t end_byte);
 
 struct kgetbmap {
index 09e893cf563cb98e740609743db74523148ee2c5..5180cbf5a90b4bef8ffd448ef753c1c667e0cf2e 100644 (file)
@@ -22,6 +22,9 @@
 #include "xfs_inode.h"
 #include "xfs_dir2.h"
 #include "xfs_quota.h"
+#include "xfs_alloc.h"
+#include "xfs_ag.h"
+#include "xfs_sb.h"
 
 /*
  * This is the number of entries in the l_buf_cancel_table used during
@@ -684,6 +687,67 @@ xlog_recover_do_inode_buffer(
        return 0;
 }
 
+/*
+ * Update the in-memory superblock and perag structures from the primary SB
+ * buffer.
+ *
+ * This is required because transactions running after growfs may require the
+ * updated values to be set in a previous fully commit transaction.
+ */
+static int
+xlog_recover_do_primary_sb_buffer(
+       struct xfs_mount                *mp,
+       struct xlog_recover_item        *item,
+       struct xfs_buf                  *bp,
+       struct xfs_buf_log_format       *buf_f,
+       xfs_lsn_t                       current_lsn)
+{
+       struct xfs_dsb                  *dsb = bp->b_addr;
+       xfs_agnumber_t                  orig_agcount = mp->m_sb.sb_agcount;
+       int                             error;
+
+       xlog_recover_do_reg_buffer(mp, item, bp, buf_f, current_lsn);
+
+       if (orig_agcount == 0) {
+               xfs_alert(mp, "Trying to grow file system without AGs");
+               return -EFSCORRUPTED;
+       }
+
+       /*
+        * Update the in-core super block from the freshly recovered on-disk one.
+        */
+       xfs_sb_from_disk(&mp->m_sb, dsb);
+
+       if (mp->m_sb.sb_agcount < orig_agcount) {
+               xfs_alert(mp, "Shrinking AG count in log recovery not supported");
+               return -EFSCORRUPTED;
+       }
+
+       /*
+        * Growfs can also grow the last existing AG.  In this case we also need
+        * to update the length in the in-core perag structure and values
+        * depending on it.
+        */
+       error = xfs_update_last_ag_size(mp, orig_agcount);
+       if (error)
+               return error;
+
+       /*
+        * Initialize the new perags, and also update various block and inode
+        * allocator setting based off the number of AGs or total blocks.
+        * Because of the latter this also needs to happen if the agcount did
+        * not change.
+        */
+       error = xfs_initialize_perag(mp, orig_agcount, mp->m_sb.sb_agcount,
+                       mp->m_sb.sb_dblocks, &mp->m_maxagi);
+       if (error) {
+               xfs_warn(mp, "Failed recovery per-ag init: %d", error);
+               return error;
+       }
+       mp->m_alloc_set_aside = xfs_alloc_set_aside(mp);
+       return 0;
+}
+
 /*
  * V5 filesystems know the age of the buffer on disk being recovered. We can
  * have newer objects on disk than we are replaying, and so for these cases we
@@ -967,6 +1031,12 @@ xlog_recover_buf_commit_pass2(
                dirty = xlog_recover_do_dquot_buffer(mp, log, item, bp, buf_f);
                if (!dirty)
                        goto out_release;
+       } else if ((xfs_blft_from_flags(buf_f) & XFS_BLFT_SB_BUF) &&
+                       xfs_buf_daddr(bp) == 0) {
+               error = xlog_recover_do_primary_sb_buffer(mp, item, bp, buf_f,
+                               current_lsn);
+               if (error)
+                       goto out_release;
        } else {
                xlog_recover_do_reg_buffer(mp, item, bp, buf_f, current_lsn);
        }
index 412b1d71b52b7d0f964b054c1718c5de9fde99e8..b19916b11fd563d693032c52d49fa38a272a9bd3 100644 (file)
@@ -347,10 +347,83 @@ xfs_file_splice_read(
        return ret;
 }
 
+/*
+ * Take care of zeroing post-EOF blocks when they might exist.
+ *
+ * Returns 0 if successfully, a negative error for a failure, or 1 if this
+ * function dropped the iolock and reacquired it exclusively and the caller
+ * needs to restart the write sanity checks.
+ */
+static ssize_t
+xfs_file_write_zero_eof(
+       struct kiocb            *iocb,
+       struct iov_iter         *from,
+       unsigned int            *iolock,
+       size_t                  count,
+       bool                    *drained_dio)
+{
+       struct xfs_inode        *ip = XFS_I(iocb->ki_filp->f_mapping->host);
+       loff_t                  isize;
+       int                     error;
+
+       /*
+        * We need to serialise against EOF updates that occur in IO completions
+        * here. We want to make sure that nobody is changing the size while
+        * we do this check until we have placed an IO barrier (i.e. hold
+        * XFS_IOLOCK_EXCL) that prevents new IO from being dispatched.  The
+        * spinlock effectively forms a memory barrier once we have
+        * XFS_IOLOCK_EXCL so we are guaranteed to see the latest EOF value and
+        * hence be able to correctly determine if we need to run zeroing.
+        */
+       spin_lock(&ip->i_flags_lock);
+       isize = i_size_read(VFS_I(ip));
+       if (iocb->ki_pos <= isize) {
+               spin_unlock(&ip->i_flags_lock);
+               return 0;
+       }
+       spin_unlock(&ip->i_flags_lock);
+
+       if (iocb->ki_flags & IOCB_NOWAIT)
+               return -EAGAIN;
+
+       if (!*drained_dio) {
+               /*
+                * If zeroing is needed and we are currently holding the iolock
+                * shared, we need to update it to exclusive which implies
+                * having to redo all checks before.
+                */
+               if (*iolock == XFS_IOLOCK_SHARED) {
+                       xfs_iunlock(ip, *iolock);
+                       *iolock = XFS_IOLOCK_EXCL;
+                       xfs_ilock(ip, *iolock);
+                       iov_iter_reexpand(from, count);
+               }
+
+               /*
+                * We now have an IO submission barrier in place, but AIO can do
+                * EOF updates during IO completion and hence we now need to
+                * wait for all of them to drain.  Non-AIO DIO will have drained
+                * before we are given the XFS_IOLOCK_EXCL, and so for most
+                * cases this wait is a no-op.
+                */
+               inode_dio_wait(VFS_I(ip));
+               *drained_dio = true;
+               return 1;
+       }
+
+       trace_xfs_zero_eof(ip, isize, iocb->ki_pos - isize);
+
+       xfs_ilock(ip, XFS_MMAPLOCK_EXCL);
+       error = xfs_zero_range(ip, isize, iocb->ki_pos - isize, NULL);
+       xfs_iunlock(ip, XFS_MMAPLOCK_EXCL);
+
+       return error;
+}
+
 /*
  * Common pre-write limit and setup checks.
  *
- * Called with the iolocked held either shared and exclusive according to
+ * Called with the iolock held either shared and exclusive according to
  * @iolock, and returns with it held.  Might upgrade the iolock to exclusive
  * if called for a direct write beyond i_size.
  */
@@ -360,13 +433,10 @@ xfs_file_write_checks(
        struct iov_iter         *from,
        unsigned int            *iolock)
 {
-       struct file             *file = iocb->ki_filp;
-       struct inode            *inode = file->f_mapping->host;
-       struct xfs_inode        *ip = XFS_I(inode);
-       ssize_t                 error = 0;
+       struct inode            *inode = iocb->ki_filp->f_mapping->host;
        size_t                  count = iov_iter_count(from);
        bool                    drained_dio = false;
-       loff_t                  isize;
+       ssize_t                 error;
 
 restart:
        error = generic_write_checks(iocb, from);
@@ -389,7 +459,7 @@ restart:
         * exclusively.
         */
        if (*iolock == XFS_IOLOCK_SHARED && !IS_NOSEC(inode)) {
-               xfs_iunlock(ip, *iolock);
+               xfs_iunlock(XFS_I(inode), *iolock);
                *iolock = XFS_IOLOCK_EXCL;
                error = xfs_ilock_iocb(iocb, *iolock);
                if (error) {
@@ -400,64 +470,24 @@ restart:
        }
 
        /*
-        * If the offset is beyond the size of the file, we need to zero any
+        * If the offset is beyond the size of the file, we need to zero all
         * blocks that fall between the existing EOF and the start of this
-        * write.  If zeroing is needed and we are currently holding the iolock
-        * shared, we need to update it to exclusive which implies having to
-        * redo all checks before.
+        * write.
         *
-        * We need to serialise against EOF updates that occur in IO completions
-        * here. We want to make sure that nobody is changing the size while we
-        * do this check until we have placed an IO barrier (i.e.  hold the
-        * XFS_IOLOCK_EXCL) that prevents new IO from being dispatched.  The
-        * spinlock effectively forms a memory barrier once we have the
-        * XFS_IOLOCK_EXCL so we are guaranteed to see the latest EOF value and
-        * hence be able to correctly determine if we need to run zeroing.
-        *
-        * We can do an unlocked check here safely as IO completion can only
-        * extend EOF. Truncate is locked out at this point, so the EOF can
-        * not move backwards, only forwards. Hence we only need to take the
-        * slow path and spin locks when we are at or beyond the current EOF.
+        * We can do an unlocked check for i_size here safely as I/O completion
+        * can only extend EOF.  Truncate is locked out at this point, so the
+        * EOF can not move backwards, only forwards. Hence we only need to take
+        * the slow path when we are at or beyond the current EOF.
         */
-       if (iocb->ki_pos <= i_size_read(inode))
-               goto out;
-
-       spin_lock(&ip->i_flags_lock);
-       isize = i_size_read(inode);
-       if (iocb->ki_pos > isize) {
-               spin_unlock(&ip->i_flags_lock);
-
-               if (iocb->ki_flags & IOCB_NOWAIT)
-                       return -EAGAIN;
-
-               if (!drained_dio) {
-                       if (*iolock == XFS_IOLOCK_SHARED) {
-                               xfs_iunlock(ip, *iolock);
-                               *iolock = XFS_IOLOCK_EXCL;
-                               xfs_ilock(ip, *iolock);
-                               iov_iter_reexpand(from, count);
-                       }
-                       /*
-                        * We now have an IO submission barrier in place, but
-                        * AIO can do EOF updates during IO completion and hence
-                        * we now need to wait for all of them to drain. Non-AIO
-                        * DIO will have drained before we are given the
-                        * XFS_IOLOCK_EXCL, and so for most cases this wait is a
-                        * no-op.
-                        */
-                       inode_dio_wait(inode);
-                       drained_dio = true;
+       if (iocb->ki_pos > i_size_read(inode)) {
+               error = xfs_file_write_zero_eof(iocb, from, iolock, count,
+                               &drained_dio);
+               if (error == 1)
                        goto restart;
-               }
-
-               trace_xfs_zero_eof(ip, isize, iocb->ki_pos - isize);
-               error = xfs_zero_range(ip, isize, iocb->ki_pos - isize, NULL);
                if (error)
                        return error;
-       } else
-               spin_unlock(&ip->i_flags_lock);
+       }
 
-out:
        return kiocb_modified(iocb);
 }
 
index e3aaa055559781b3a77cf7acfb81ca6c54094700..290ba8887d29e9b73fc535a872ed374b3ee69af8 100644 (file)
@@ -64,25 +64,31 @@ xfs_filestream_pick_ag(
        struct xfs_perag        *pag;
        struct xfs_perag        *max_pag = NULL;
        xfs_extlen_t            minlen = *longest;
-       xfs_extlen_t            free = 0, minfree, maxfree = 0;
+       xfs_extlen_t            minfree, maxfree = 0;
        xfs_agnumber_t          agno;
        bool                    first_pass = true;
-       int                     err;
 
        /* 2% of an AG's blocks must be free for it to be chosen. */
        minfree = mp->m_sb.sb_agblocks / 50;
 
 restart:
        for_each_perag_wrap(mp, start_agno, agno, pag) {
+               int             err;
+
                trace_xfs_filestream_scan(pag, pino);
+
                *longest = 0;
                err = xfs_bmap_longest_free_extent(pag, NULL, longest);
                if (err) {
-                       if (err != -EAGAIN)
-                               break;
-                       /* Couldn't lock the AGF, skip this AG. */
-                       err = 0;
-                       continue;
+                       if (err == -EAGAIN) {
+                               /* Couldn't lock the AGF, skip this AG. */
+                               err = 0;
+                               continue;
+                       }
+                       xfs_perag_rele(pag);
+                       if (max_pag)
+                               xfs_perag_rele(max_pag);
+                       return err;
                }
 
                /* Keep track of the AG with the most free blocks. */
@@ -107,8 +113,9 @@ restart:
                             !(flags & XFS_PICK_USERDATA) ||
                             (flags & XFS_PICK_LOWSPACE))) {
                                /* Break out, retaining the reference on the AG. */
-                               free = pag->pagf_freeblks;
-                               break;
+                               if (max_pag)
+                                       xfs_perag_rele(max_pag);
+                               goto done;
                        }
                }
 
@@ -116,57 +123,47 @@ restart:
                atomic_dec(&pag->pagf_fstrms);
        }
 
-       if (err) {
-               xfs_perag_rele(pag);
-               if (max_pag)
-                       xfs_perag_rele(max_pag);
-               return err;
+       /*
+        * Allow a second pass to give xfs_bmap_longest_free_extent() another
+        * attempt at locking AGFs that it might have skipped over before we
+        * fail.
+        */
+       if (first_pass) {
+               first_pass = false;
+               goto restart;
        }
 
-       if (!pag) {
-               /*
-                * Allow a second pass to give xfs_bmap_longest_free_extent()
-                * another attempt at locking AGFs that it might have skipped
-                * over before we fail.
-                */
-               if (first_pass) {
-                       first_pass = false;
-                       goto restart;
-               }
+       /*
+        * We must be low on data space, so run a final lowspace optimised
+        * selection pass if we haven't already.
+        */
+       if (!(flags & XFS_PICK_LOWSPACE)) {
+               flags |= XFS_PICK_LOWSPACE;
+               goto restart;
+       }
 
-               /*
-                * We must be low on data space, so run a final lowspace
-                * optimised selection pass if we haven't already.
-                */
-               if (!(flags & XFS_PICK_LOWSPACE)) {
-                       flags |= XFS_PICK_LOWSPACE;
-                       goto restart;
+       /*
+        * No unassociated AGs are available, so select the AG with the most
+        * free space, regardless of whether it's already in use by another
+        * filestream. It none suit, just use whatever AG we can grab.
+        */
+       if (!max_pag) {
+               for_each_perag_wrap(args->mp, 0, start_agno, pag) {
+                       max_pag = pag;
+                       break;
                }
 
-               /*
-                * No unassociated AGs are available, so select the AG with the
-                * most free space, regardless of whether it's already in use by
-                * another filestream. It none suit, just use whatever AG we can
-                * grab.
-                */
-               if (!max_pag) {
-                       for_each_perag_wrap(args->mp, 0, start_agno, args->pag)
-                               break;
-                       atomic_inc(&args->pag->pagf_fstrms);
-                       *longest = 0;
-               } else {
-                       pag = max_pag;
-                       free = maxfree;
-                       atomic_inc(&pag->pagf_fstrms);
-               }
-       } else if (max_pag) {
-               xfs_perag_rele(max_pag);
+               /* Bail if there are no AGs at all to select from. */
+               if (!max_pag)
+                       return -ENOSPC;
        }
 
-       trace_xfs_filestream_pick(pag, pino, free);
+       pag = max_pag;
+       atomic_inc(&pag->pagf_fstrms);
+done:
+       trace_xfs_filestream_pick(pag, pino);
        args->pag = pag;
        return 0;
-
 }
 
 static struct xfs_inode *
index 3643cc843f62711c3b52ec49c770f530923391fc..b247d895c276d2b436eafe16c1d8611422c531b7 100644 (file)
@@ -87,6 +87,7 @@ xfs_growfs_data_private(
        struct xfs_mount        *mp,            /* mount point for filesystem */
        struct xfs_growfs_data  *in)            /* growfs data input struct */
 {
+       xfs_agnumber_t          oagcount = mp->m_sb.sb_agcount;
        struct xfs_buf          *bp;
        int                     error;
        xfs_agnumber_t          nagcount;
@@ -94,7 +95,6 @@ xfs_growfs_data_private(
        xfs_rfsblock_t          nb, nb_div, nb_mod;
        int64_t                 delta;
        bool                    lastag_extended = false;
-       xfs_agnumber_t          oagcount;
        struct xfs_trans        *tp;
        struct aghdr_init_data  id = {};
        struct xfs_perag        *last_pag;
@@ -138,16 +138,14 @@ xfs_growfs_data_private(
        if (delta == 0)
                return 0;
 
-       oagcount = mp->m_sb.sb_agcount;
-       /* allocate the new per-ag structures */
-       if (nagcount > oagcount) {
-               error = xfs_initialize_perag(mp, nagcount, nb, &nagimax);
-               if (error)
-                       return error;
-       } else if (nagcount < oagcount) {
-               /* TODO: shrinking the entire AGs hasn't yet completed */
+       /* TODO: shrinking the entire AGs hasn't yet completed */
+       if (nagcount < oagcount)
                return -EINVAL;
-       }
+
+       /* allocate the new per-ag structures */
+       error = xfs_initialize_perag(mp, oagcount, nagcount, nb, &nagimax);
+       if (error)
+               return error;
 
        if (delta > 0)
                error = xfs_trans_alloc(mp, &M_RES(mp)->tr_growdata,
@@ -231,7 +229,7 @@ out_trans_cancel:
        xfs_trans_cancel(tp);
 out_free_unused_perag:
        if (nagcount > oagcount)
-               xfs_free_unused_perag_range(mp, oagcount, nagcount);
+               xfs_free_perag_range(mp, oagcount, nagcount);
        return error;
 }
 
index a680e5b82672b91264de5597cccdd8e990e9b085..6b119a7a324fa4e159a0aecaa007cfdce5a040c6 100644 (file)
@@ -1280,14 +1280,17 @@ xfs_inode_clear_eofblocks_tag(
 }
 
 /*
- * Set ourselves up to free CoW blocks from this file.  If it's already clean
- * then we can bail out quickly, but otherwise we must back off if the file
- * is undergoing some kind of write.
+ * Prepare to free COW fork blocks from an inode.
  */
 static bool
 xfs_prep_free_cowblocks(
-       struct xfs_inode        *ip)
+       struct xfs_inode        *ip,
+       struct xfs_icwalk       *icw)
 {
+       bool                    sync;
+
+       sync = icw && (icw->icw_flags & XFS_ICWALK_FLAG_SYNC);
+
        /*
         * Just clear the tag if we have an empty cow fork or none at all. It's
         * possible the inode was fully unshared since it was originally tagged.
@@ -1299,16 +1302,22 @@ xfs_prep_free_cowblocks(
        }
 
        /*
-        * If the mapping is dirty or under writeback we cannot touch the
-        * CoW fork.  Leave it alone if we're in the midst of a directio.
+        * A cowblocks trim of an inode can have a significant effect on
+        * fragmentation even when a reasonable COW extent size hint is set.
+        * Therefore, we prefer to not process cowblocks unless they are clean
+        * and idle. We can never process a cowblocks inode that is dirty or has
+        * in-flight I/O under any circumstances, because outstanding writeback
+        * or dio expects targeted COW fork blocks exist through write
+        * completion where they can be remapped into the data fork.
+        *
+        * Therefore, the heuristic used here is to never process inodes
+        * currently opened for write from background (i.e. non-sync) scans. For
+        * sync scans, use the pagecache/dio state of the inode to ensure we
+        * never free COW fork blocks out from under pending I/O.
         */
-       if ((VFS_I(ip)->i_state & I_DIRTY_PAGES) ||
-           mapping_tagged(VFS_I(ip)->i_mapping, PAGECACHE_TAG_DIRTY) ||
-           mapping_tagged(VFS_I(ip)->i_mapping, PAGECACHE_TAG_WRITEBACK) ||
-           atomic_read(&VFS_I(ip)->i_dio_count))
+       if (!sync && inode_is_open_for_write(VFS_I(ip)))
                return false;
-
-       return true;
+       return xfs_can_free_cowblocks(ip);
 }
 
 /*
@@ -1337,7 +1346,7 @@ xfs_inode_free_cowblocks(
        if (!xfs_iflags_test(ip, XFS_ICOWBLOCKS))
                return 0;
 
-       if (!xfs_prep_free_cowblocks(ip))
+       if (!xfs_prep_free_cowblocks(ip, icw))
                return 0;
 
        if (!xfs_icwalk_match(ip, icw))
@@ -1366,7 +1375,7 @@ xfs_inode_free_cowblocks(
         * Check again, nobody else should be able to dirty blocks or change
         * the reflink iflag now that we have the first two locks held.
         */
-       if (xfs_prep_free_cowblocks(ip))
+       if (xfs_prep_free_cowblocks(ip, icw))
                ret = xfs_reflink_cancel_cow_range(ip, 0, NULLFILEOFF, false);
        return ret;
 }
index bcc277fc0a83e9f2ca8805c639f01b04fef26e91..19dcb569a3e7f8acb202a7fbd9b7e0337eb5176e 100644 (file)
@@ -1409,7 +1409,7 @@ xfs_inactive(
 
        if (S_ISREG(VFS_I(ip)->i_mode) &&
            (ip->i_disk_size != 0 || XFS_ISIZE(ip) != 0 ||
-            ip->i_df.if_nextents > 0 || ip->i_delayed_blks > 0))
+            xfs_inode_has_filedata(ip)))
                truncate = 1;
 
        if (xfs_iflags_test(ip, XFS_IQUOTAUNCHECKED)) {
index 97ed912306fd066c461b53fec450f1b4727c8682..03944b6c5fba1ce4b2bf6ab94621690dcf0d0e5d 100644 (file)
@@ -292,6 +292,11 @@ static inline bool xfs_is_cow_inode(struct xfs_inode *ip)
        return xfs_is_reflink_inode(ip) || xfs_is_always_cow_inode(ip);
 }
 
+static inline bool xfs_inode_has_filedata(const struct xfs_inode *ip)
+{
+       return ip->i_df.if_nextents > 0 || ip->i_delayed_blks > 0;
+}
+
 /*
  * Check if an inode has any data in the COW fork.  This might be often false
  * even for inodes with the reflink flag when there is no pending COW operation.
index a20d426ef021f23c18b821dcd7b11e5e6741b0a2..2567fd2a0994b97ae5c570a4bad036d94bc88621 100644 (file)
@@ -481,7 +481,7 @@ xfs_ioctl_setattr_xflags(
 
        if (rtflag != XFS_IS_REALTIME_INODE(ip)) {
                /* Can't change realtime flag if any extents are allocated. */
-               if (ip->i_df.if_nextents || ip->i_delayed_blks)
+               if (xfs_inode_has_filedata(ip))
                        return -EINVAL;
 
                /*
@@ -602,7 +602,7 @@ xfs_ioctl_setattr_check_extsize(
        if (!fa->fsx_valid)
                return 0;
 
-       if (S_ISREG(VFS_I(ip)->i_mode) && ip->i_df.if_nextents &&
+       if (S_ISREG(VFS_I(ip)->i_mode) && xfs_inode_has_filedata(ip) &&
            XFS_FSB_TO_B(mp, ip->i_extsize) != fa->fsx_extsize)
                return -EINVAL;
 
index 1e11f48814c0d05822e9f9420eb82819599359de..86da16f54be9d78e7d752b7a14514d8d9e8d6335 100644 (file)
@@ -707,7 +707,7 @@ imap_needs_cow(
                return false;
 
        /* when zeroing we don't have to COW holes or unwritten extents */
-       if (flags & IOMAP_ZERO) {
+       if (flags & (IOMAP_UNSHARE | IOMAP_ZERO)) {
                if (!nimaps ||
                    imap->br_startblock == HOLESTARTBLOCK ||
                    imap->br_state == XFS_EXT_UNWRITTEN)
@@ -975,6 +975,7 @@ xfs_buffered_write_iomap_begin(
        int                     allocfork = XFS_DATA_FORK;
        int                     error = 0;
        unsigned int            lockmode = XFS_ILOCK_EXCL;
+       unsigned int            iomap_flags = 0;
        u64                     seq;
 
        if (xfs_is_shutdown(mp))
@@ -1145,6 +1146,11 @@ xfs_buffered_write_iomap_begin(
                }
        }
 
+       /*
+        * Flag newly allocated delalloc blocks with IOMAP_F_NEW so we punch
+        * them out if the write happens to fail.
+        */
+       iomap_flags |= IOMAP_F_NEW;
        if (allocfork == XFS_COW_FORK) {
                error = xfs_bmapi_reserve_delalloc(ip, allocfork, offset_fsb,
                                end_fsb - offset_fsb, prealloc_blocks, &cmap,
@@ -1162,19 +1168,11 @@ xfs_buffered_write_iomap_begin(
        if (error)
                goto out_unlock;
 
-       /*
-        * Flag newly allocated delalloc blocks with IOMAP_F_NEW so we punch
-        * them out if the write happens to fail.
-        */
-       seq = xfs_iomap_inode_sequence(ip, IOMAP_F_NEW);
-       xfs_iunlock(ip, lockmode);
        trace_xfs_iomap_alloc(ip, offset, count, allocfork, &imap);
-       return xfs_bmbt_to_iomap(ip, iomap, &imap, flags, IOMAP_F_NEW, seq);
-
 found_imap:
-       seq = xfs_iomap_inode_sequence(ip, 0);
+       seq = xfs_iomap_inode_sequence(ip, iomap_flags);
        xfs_iunlock(ip, lockmode);
-       return xfs_bmbt_to_iomap(ip, iomap, &imap, flags, 0, seq);
+       return xfs_bmbt_to_iomap(ip, iomap, &imap, flags, iomap_flags, seq);
 
 convert_delay:
        xfs_iunlock(ip, lockmode);
@@ -1188,20 +1186,20 @@ convert_delay:
        return 0;
 
 found_cow:
-       seq = xfs_iomap_inode_sequence(ip, 0);
        if (imap.br_startoff <= offset_fsb) {
-               error = xfs_bmbt_to_iomap(ip, srcmap, &imap, flags, 0, seq);
+               error = xfs_bmbt_to_iomap(ip, srcmap, &imap, flags, 0,
+                               xfs_iomap_inode_sequence(ip, 0));
                if (error)
                        goto out_unlock;
-               seq = xfs_iomap_inode_sequence(ip, IOMAP_F_SHARED);
-               xfs_iunlock(ip, lockmode);
-               return xfs_bmbt_to_iomap(ip, iomap, &cmap, flags,
-                                        IOMAP_F_SHARED, seq);
+       } else {
+               xfs_trim_extent(&cmap, offset_fsb,
+                               imap.br_startoff - offset_fsb);
        }
 
-       xfs_trim_extent(&cmap, offset_fsb, imap.br_startoff - offset_fsb);
+       iomap_flags |= IOMAP_F_SHARED;
+       seq = xfs_iomap_inode_sequence(ip, iomap_flags);
        xfs_iunlock(ip, lockmode);
-       return xfs_bmbt_to_iomap(ip, iomap, &cmap, flags, 0, seq);
+       return xfs_bmbt_to_iomap(ip, iomap, &cmap, flags, iomap_flags, seq);
 
 out_unlock:
        xfs_iunlock(ip, lockmode);
@@ -1215,7 +1213,10 @@ xfs_buffered_write_delalloc_punch(
        loff_t                  length,
        struct iomap            *iomap)
 {
-       xfs_bmap_punch_delalloc_range(XFS_I(inode), offset, offset + length);
+       xfs_bmap_punch_delalloc_range(XFS_I(inode),
+                       (iomap->flags & IOMAP_F_SHARED) ?
+                               XFS_COW_FORK : XFS_DATA_FORK,
+                       offset, offset + length);
 }
 
 static int
@@ -1227,8 +1228,30 @@ xfs_buffered_write_iomap_end(
        unsigned                flags,
        struct iomap            *iomap)
 {
-       iomap_file_buffered_write_punch_delalloc(inode, offset, length, written,
-                       flags, iomap, &xfs_buffered_write_delalloc_punch);
+       loff_t                  start_byte, end_byte;
+
+       /* If we didn't reserve the blocks, we're not allowed to punch them. */
+       if (iomap->type != IOMAP_DELALLOC || !(iomap->flags & IOMAP_F_NEW))
+               return 0;
+
+       /* Nothing to do if we've written the entire delalloc extent */
+       start_byte = iomap_last_written_block(inode, offset, written);
+       end_byte = round_up(offset + length, i_blocksize(inode));
+       if (start_byte >= end_byte)
+               return 0;
+
+       /* For zeroing operations the callers already hold invalidate_lock. */
+       if (flags & (IOMAP_UNSHARE | IOMAP_ZERO)) {
+               rwsem_assert_held_write(&inode->i_mapping->invalidate_lock);
+               iomap_write_delalloc_release(inode, start_byte, end_byte, flags,
+                               iomap, xfs_buffered_write_delalloc_punch);
+       } else {
+               filemap_invalidate_lock(inode->i_mapping);
+               iomap_write_delalloc_release(inode, start_byte, end_byte, flags,
+                               iomap, xfs_buffered_write_delalloc_punch);
+               filemap_invalidate_unlock(inode->i_mapping);
+       }
+
        return 0;
 }
 
@@ -1435,6 +1458,8 @@ xfs_zero_range(
 {
        struct inode            *inode = VFS_I(ip);
 
+       xfs_assert_ilocked(ip, XFS_IOLOCK_EXCL | XFS_MMAPLOCK_EXCL);
+
        if (IS_DAX(inode))
                return dax_zero_range(inode, pos, len, did_zero,
                                      &xfs_dax_write_iomap_ops);
index 54a098fe728584d6f32875bc6e00205171a23ce5..9a2221b4aa21ed2f4c5051855948dc3a2a0b3b36 100644 (file)
@@ -69,7 +69,7 @@ typedef __u32                 xfs_nlink_t;
 #include <asm/param.h>
 #include <linux/uaccess.h>
 #include <asm/byteorder.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #include "xfs_fs.h"
 #include "xfs_stats.h"
index 67c539cc9305c769a8597a5e87079911047d9543..13455854365fa3ced1d50d91cf558ac7a540bd48 100644 (file)
@@ -158,6 +158,4 @@ bool        xfs_log_check_lsn(struct xfs_mount *, xfs_lsn_t);
 
 bool     xlog_force_shutdown(struct xlog *log, uint32_t shutdown_flags);
 
-int xfs_attr_use_log_assist(struct xfs_mount *mp);
-
 #endif /* __XFS_LOG_H__ */
index 391a938d690c59712f01dca36bde51a91cac8156..80da0cf87d7a45df63b7a21187179d1ac0b6ce6f 100644 (file)
@@ -156,7 +156,6 @@ xlog_cil_insert_pcp_aggregate(
        struct xfs_cil          *cil,
        struct xfs_cil_ctx      *ctx)
 {
-       struct xlog_cil_pcp     *cilpcp;
        int                     cpu;
        int                     count = 0;
 
@@ -171,13 +170,11 @@ xlog_cil_insert_pcp_aggregate(
         * structures that could have a nonzero space_used.
         */
        for_each_cpu(cpu, &ctx->cil_pcpmask) {
-               int     old, prev;
+               struct xlog_cil_pcp     *cilpcp = per_cpu_ptr(cil->xc_pcp, cpu);
+               int                     old = READ_ONCE(cilpcp->space_used);
 
-               cilpcp = per_cpu_ptr(cil->xc_pcp, cpu);
-               do {
-                       old = cilpcp->space_used;
-                       prev = cmpxchg(&cilpcp->space_used, old, 0);
-               } while (old != prev);
+               while (!try_cmpxchg(&cilpcp->space_used, &old, 0))
+                       ;
                count += old;
        }
        atomic_add(count, &ctx->space_used);
index ec766b4bc8537b1377084a3eb8b07e1773817b32..704aaadb61cf29b3cd6b62c6075f74cfb3c62ffd 100644 (file)
@@ -1849,7 +1849,7 @@ xlog_find_item_ops(
  *        from the transaction. However, we can't do that until after we've
  *        replayed all the other items because they may be dependent on the
  *        cancelled buffer and replaying the cancelled buffer can remove it
- *        form the cancelled buffer table. Hence they have tobe done last.
+ *        form the cancelled buffer table. Hence they have to be done last.
  *
  *     3. Inode allocation buffers must be replayed before inode items that
  *        read the buffer and replay changes into it. For filesystems using the
@@ -3393,13 +3393,6 @@ xlog_do_recover(
        /* re-initialise in-core superblock and geometry structures */
        mp->m_features |= xfs_sb_version_to_features(sbp);
        xfs_reinit_percpu_counters(mp);
-       error = xfs_initialize_perag(mp, sbp->sb_agcount, sbp->sb_dblocks,
-                       &mp->m_maxagi);
-       if (error) {
-               xfs_warn(mp, "Failed post-recovery per-ag init: %d", error);
-               return error;
-       }
-       mp->m_alloc_set_aside = xfs_alloc_set_aside(mp);
 
        /* Normal transactions can now occur */
        clear_bit(XLOG_ACTIVE_RECOVERY, &log->l_opstate);
index 1fdd79c5bfa04efb6d4bc2baa5e5fca46d50306c..25bbcc3f4ee08ba57b7525261483f975455c5de2 100644 (file)
@@ -810,8 +810,8 @@ xfs_mountfs(
        /*
         * Allocate and initialize the per-ag data.
         */
-       error = xfs_initialize_perag(mp, sbp->sb_agcount, mp->m_sb.sb_dblocks,
-                       &mp->m_maxagi);
+       error = xfs_initialize_perag(mp, 0, sbp->sb_agcount,
+                       mp->m_sb.sb_dblocks, &mp->m_maxagi);
        if (error) {
                xfs_warn(mp, "Failed per-ag init: %d", error);
                goto out_free_dir;
@@ -1048,7 +1048,7 @@ xfs_mountfs(
                xfs_buftarg_drain(mp->m_logdev_targp);
        xfs_buftarg_drain(mp->m_ddev_targp);
  out_free_perag:
-       xfs_free_perag(mp);
+       xfs_free_perag_range(mp, 0, mp->m_sb.sb_agcount);
  out_free_dir:
        xfs_da_unmount(mp);
  out_remove_uuid:
@@ -1129,8 +1129,7 @@ xfs_unmountfs(
        xfs_errortag_clearall(mp);
 #endif
        shrinker_free(mp->m_inodegc_shrinker);
-       xfs_free_perag(mp);
-
+       xfs_free_perag_range(mp, 0, mp->m_sb.sb_agcount);
        xfs_errortag_del(mp);
        xfs_error_sysfs_del(mp);
        xchk_stats_unregister(mp->m_scrub_stats);
index 6fde6ec8092f0b96f1fcd084a4feeea4811ba898..5bf6682e701b5a730b3b11d914f445da1f05a349 100644 (file)
@@ -1595,6 +1595,9 @@ xfs_reflink_clear_inode_flag(
 
        ASSERT(xfs_is_reflink_inode(ip));
 
+       if (!xfs_can_free_cowblocks(ip))
+               return 0;
+
        error = xfs_reflink_inode_has_shared_extents(*tpp, ip, &needs_flag);
        if (error || needs_flag)
                return error;
index fb55e4ce49fa1019d2c9e6c4224c4bd7ccc55eee..4a58e4533671c06188e724bd1c387fd333917523 100644 (file)
@@ -6,6 +6,25 @@
 #ifndef __XFS_REFLINK_H
 #define __XFS_REFLINK_H 1
 
+/*
+ * Check whether it is safe to free COW fork blocks from an inode. It is unsafe
+ * to do so when an inode has dirty cache or I/O in-flight, even if no shared
+ * extents exist in the data fork, because outstanding I/O may target blocks
+ * that were speculatively allocated to the COW fork.
+ */
+static inline bool
+xfs_can_free_cowblocks(struct xfs_inode *ip)
+{
+       struct inode *inode = VFS_I(ip);
+
+       if ((inode->i_state & I_DIRTY_PAGES) ||
+           mapping_tagged(inode->i_mapping, PAGECACHE_TAG_DIRTY) ||
+           mapping_tagged(inode->i_mapping, PAGECACHE_TAG_WRITEBACK) ||
+           atomic_read(&inode->i_dio_count))
+               return false;
+       return true;
+}
+
 extern int xfs_reflink_trim_around_shared(struct xfs_inode *ip,
                struct xfs_bmbt_irec *irec, bool *shared);
 int xfs_bmap_trim_cow(struct xfs_inode *ip, struct xfs_bmbt_irec *imap,
index ee9f0b1f548dc1ef6de47db50e7740f67b20744a..fcb2bad4f76e4b5b71649b3dfcd484e8ca6c618f 100644 (file)
@@ -691,8 +691,8 @@ DEFINE_FILESTREAM_EVENT(xfs_filestream_lookup);
 DEFINE_FILESTREAM_EVENT(xfs_filestream_scan);
 
 TRACE_EVENT(xfs_filestream_pick,
-       TP_PROTO(struct xfs_perag *pag, xfs_ino_t ino, xfs_extlen_t free),
-       TP_ARGS(pag, ino, free),
+       TP_PROTO(struct xfs_perag *pag, xfs_ino_t ino),
+       TP_ARGS(pag, ino),
        TP_STRUCT__entry(
                __field(dev_t, dev)
                __field(xfs_ino_t, ino)
@@ -703,14 +703,9 @@ TRACE_EVENT(xfs_filestream_pick,
        TP_fast_assign(
                __entry->dev = pag->pag_mount->m_super->s_dev;
                __entry->ino = ino;
-               if (pag) {
-                       __entry->agno = pag->pag_agno;
-                       __entry->streams = atomic_read(&pag->pagf_fstrms);
-               } else {
-                       __entry->agno = NULLAGNUMBER;
-                       __entry->streams = 0;
-               }
-               __entry->free = free;
+               __entry->agno = pag->pag_agno;
+               __entry->streams = atomic_read(&pag->pagf_fstrms);
+               __entry->free = pag->pagf_freeblks;
        ),
        TP_printk("dev %d:%d ino 0x%llx agno 0x%x streams %d free %d",
                  MAJOR(__entry->dev), MINOR(__entry->dev),
index 8ccb65c2b419fb44cb5320fb36ac213f6659d260..ff9a688f1f9cf22bdaf57627e3f46b7aa1918ff4 100644 (file)
@@ -92,6 +92,7 @@ int zonefs_sysfs_register(struct super_block *sb)
        struct zonefs_sb_info *sbi = ZONEFS_SB(sb);
        int ret;
 
+       super_set_sysfs_name_id(sb);
        init_completion(&sbi->s_kobj_unregister);
        ret = kobject_init_and_add(&sbi->s_kobj, &zonefs_sb_ktype,
                                   zonefs_sysfs_root, "%s", sb->s_id);
index 76e44e102780e4f8ffe22cf331cc36f162c67f64..62d368bcd9eca5eb105b6be7d6bfa0b6183fb766 100644 (file)
@@ -65,7 +65,7 @@ struct cpc_desc {
        int write_cmd_status;
        int write_cmd_id;
        /* Lock used for RMW operations in cpc_write() */
-       spinlock_t rmw_lock;
+       raw_spinlock_t rmw_lock;
        struct cpc_register_resource cpc_regs[MAX_CPC_REG_ENT];
        struct acpi_psd_package domain_info;
        struct kobject kobj;
index 620b6da429d46f8ab270369d94693828100ffea2..1b43c3a77012db0722ea7c1164c3970f388f2ed6 100644 (file)
@@ -58,7 +58,6 @@ mandatory-y += tlbflush.h
 mandatory-y += topology.h
 mandatory-y += trace_clock.h
 mandatory-y += uaccess.h
-mandatory-y += unaligned.h
 mandatory-y += vermagic.h
 mandatory-y += vga.h
 mandatory-y += video.h
index a5be9e61a2a210d7b2ad69f1ee4bde7029588018..b276f783494c4b1b197e49a05f632e3fb02b9d3e 100644 (file)
@@ -11,7 +11,7 @@
 #include <asm-generic/access_ok.h>
 
 #ifdef CONFIG_UACCESS_MEMCPY
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 static __always_inline int
 __get_user_fn(size_t size, const void __user *from, void *to)
diff --git a/include/asm-generic/unaligned.h b/include/asm-generic/unaligned.h
deleted file mode 100644 (file)
index 95acdd7..0000000
+++ /dev/null
@@ -1,146 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-#ifndef __ASM_GENERIC_UNALIGNED_H
-#define __ASM_GENERIC_UNALIGNED_H
-
-/*
- * This is the most generic implementation of unaligned accesses
- * and should work almost anywhere.
- */
-#include <linux/unaligned/packed_struct.h>
-#include <asm/byteorder.h>
-#include <vdso/unaligned.h>
-
-#define get_unaligned(ptr)     __get_unaligned_t(typeof(*(ptr)), (ptr))
-#define put_unaligned(val, ptr) __put_unaligned_t(typeof(*(ptr)), (val), (ptr))
-
-static inline u16 get_unaligned_le16(const void *p)
-{
-       return le16_to_cpu(__get_unaligned_t(__le16, p));
-}
-
-static inline u32 get_unaligned_le32(const void *p)
-{
-       return le32_to_cpu(__get_unaligned_t(__le32, p));
-}
-
-static inline u64 get_unaligned_le64(const void *p)
-{
-       return le64_to_cpu(__get_unaligned_t(__le64, p));
-}
-
-static inline void put_unaligned_le16(u16 val, void *p)
-{
-       __put_unaligned_t(__le16, cpu_to_le16(val), p);
-}
-
-static inline void put_unaligned_le32(u32 val, void *p)
-{
-       __put_unaligned_t(__le32, cpu_to_le32(val), p);
-}
-
-static inline void put_unaligned_le64(u64 val, void *p)
-{
-       __put_unaligned_t(__le64, cpu_to_le64(val), p);
-}
-
-static inline u16 get_unaligned_be16(const void *p)
-{
-       return be16_to_cpu(__get_unaligned_t(__be16, p));
-}
-
-static inline u32 get_unaligned_be32(const void *p)
-{
-       return be32_to_cpu(__get_unaligned_t(__be32, p));
-}
-
-static inline u64 get_unaligned_be64(const void *p)
-{
-       return be64_to_cpu(__get_unaligned_t(__be64, p));
-}
-
-static inline void put_unaligned_be16(u16 val, void *p)
-{
-       __put_unaligned_t(__be16, cpu_to_be16(val), p);
-}
-
-static inline void put_unaligned_be32(u32 val, void *p)
-{
-       __put_unaligned_t(__be32, cpu_to_be32(val), p);
-}
-
-static inline void put_unaligned_be64(u64 val, void *p)
-{
-       __put_unaligned_t(__be64, cpu_to_be64(val), p);
-}
-
-static inline u32 __get_unaligned_be24(const u8 *p)
-{
-       return p[0] << 16 | p[1] << 8 | p[2];
-}
-
-static inline u32 get_unaligned_be24(const void *p)
-{
-       return __get_unaligned_be24(p);
-}
-
-static inline u32 __get_unaligned_le24(const u8 *p)
-{
-       return p[0] | p[1] << 8 | p[2] << 16;
-}
-
-static inline u32 get_unaligned_le24(const void *p)
-{
-       return __get_unaligned_le24(p);
-}
-
-static inline void __put_unaligned_be24(const u32 val, u8 *p)
-{
-       *p++ = (val >> 16) & 0xff;
-       *p++ = (val >> 8) & 0xff;
-       *p++ = val & 0xff;
-}
-
-static inline void put_unaligned_be24(const u32 val, void *p)
-{
-       __put_unaligned_be24(val, p);
-}
-
-static inline void __put_unaligned_le24(const u32 val, u8 *p)
-{
-       *p++ = val & 0xff;
-       *p++ = (val >> 8) & 0xff;
-       *p++ = (val >> 16) & 0xff;
-}
-
-static inline void put_unaligned_le24(const u32 val, void *p)
-{
-       __put_unaligned_le24(val, p);
-}
-
-static inline void __put_unaligned_be48(const u64 val, u8 *p)
-{
-       *p++ = (val >> 40) & 0xff;
-       *p++ = (val >> 32) & 0xff;
-       *p++ = (val >> 24) & 0xff;
-       *p++ = (val >> 16) & 0xff;
-       *p++ = (val >> 8) & 0xff;
-       *p++ = val & 0xff;
-}
-
-static inline void put_unaligned_be48(const u64 val, void *p)
-{
-       __put_unaligned_be48(val, p);
-}
-
-static inline u64 __get_unaligned_be48(const u8 *p)
-{
-       return (u64)p[0] << 40 | (u64)p[1] << 32 | (u64)p[2] << 24 |
-               p[3] << 16 | p[4] << 8 | p[5];
-}
-
-static inline u64 get_unaligned_be48(const void *p)
-{
-       return __get_unaligned_be48(p);
-}
-
-#endif /* __ASM_GENERIC_UNALIGNED_H */
index b3ea73b81944343d37afd0859d228b7fb2e86ab7..5bae6a55b3337966da4927e30b546747fc05164c 100644 (file)
@@ -15,7 +15,7 @@
 #ifndef _CRYPTO_CHACHA_H
 #define _CRYPTO_CHACHA_H
 
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include <linux/types.h>
 
 /* 32-bit stream position, then 96-bit nonce (RFC7539 convention) */
index 0717a53ae73223bccac75c55d051174ff38251bf..065f00e4bf40c5e00647467c221d9d5a8c4c6f27 100644 (file)
@@ -27,7 +27,7 @@
 #define _CRYPTO_ECC_H
 
 #include <crypto/ecc_curve.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 /* One digit is u64 qword. */
 #define ECC_CURVE_NIST_P192_DIGITS  3
index 196aa769f296867df68b245122e86a9364bed73b..e614594f88c1a139041f27c43aafd4d3c1baa53e 100644 (file)
@@ -6,7 +6,7 @@
 #ifndef _CRYPTO_INTERNAL_POLY1305_H
 #define _CRYPTO_INTERNAL_POLY1305_H
 
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include <linux/types.h>
 #include <crypto/poly1305.h>
 
index 2e0e7c3827d106301e44f8b570efe53e5911eb6d..0c342ed0d03825acb48dd98a2362e8a0dafc8e05 100644 (file)
@@ -14,7 +14,7 @@
 #include <linux/module.h>
 #include <linux/string.h>
 
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 typedef void (sha1_block_fn)(struct sha1_state *sst, u8 const *src, int blocks);
 
index ab904d82236fb8cef9e16798d2e9944c2439d7a2..e0418818d63c84bcb6deb3347c1f63dde058963a 100644 (file)
@@ -9,7 +9,7 @@
 #define _CRYPTO_SHA256_BASE_H
 
 #include <asm/byteorder.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include <crypto/internal/hash.h>
 #include <crypto/sha2.h>
 #include <linux/string.h>
index b370b3340b1620b50f565bd02c90505bad8ca430..679916a84cb2e305d35a857ce018159647be5d58 100644 (file)
@@ -14,7 +14,7 @@
 #include <linux/module.h>
 #include <linux/string.h>
 
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 typedef void (sha512_block_fn)(struct sha512_state *sst, u8 const *src,
                               int blocks);
index 2f3a32ab97bb9b6f10fce5bbeea8a71c2c7217c9..b33ed39c2bce38de846c24d64281ca5931441d0d 100644 (file)
@@ -14,7 +14,7 @@
 #include <linux/crypto.h>
 #include <linux/module.h>
 #include <linux/string.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 typedef void (sm3_block_fn)(struct sm3_state *sst, u8 const *src, int blocks);
 
index acbb917a00c636a59c5f92802ef83dbcafebf09e..2594f45777b5b4599f17ee38dbf353596db22206 100644 (file)
@@ -7,7 +7,7 @@
 #ifndef _CRYPTO_UTILS_H
 #define _CRYPTO_UTILS_H
 
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include <linux/compiler_attributes.h>
 #include <linux/types.h>
 
index e7cc17ee4934a5b12b38a55e1fa27ec411b7b9d1..afdd46ef04f70dcd1adedef2be302d67b508f035 100644 (file)
@@ -120,4 +120,8 @@ drm_kunit_helper_create_crtc(struct kunit *test,
                             const struct drm_crtc_funcs *funcs,
                             const struct drm_crtc_helper_funcs *helper_funcs);
 
+struct drm_display_mode *
+drm_kunit_display_mode_from_cea_vic(struct kunit *test, struct drm_device *dev,
+                                   u8 video_code);
+
 #endif // DRM_KUNIT_HELPERS_H_
index fe8edb917360793f3645e3399115fb7a15278f3c..9c437a057e5de15f321f8c47b8e69a90beec8b76 100644 (file)
@@ -574,7 +574,7 @@ void drm_sched_entity_modify_sched(struct drm_sched_entity *entity,
 
 void drm_sched_tdr_queue_imm(struct drm_gpu_scheduler *sched);
 void drm_sched_job_cleanup(struct drm_sched_job *job);
-void drm_sched_wakeup(struct drm_gpu_scheduler *sched, struct drm_sched_entity *entity);
+void drm_sched_wakeup(struct drm_gpu_scheduler *sched);
 bool drm_sched_wqueue_ready(struct drm_gpu_scheduler *sched);
 void drm_sched_wqueue_stop(struct drm_gpu_scheduler *sched);
 void drm_sched_wqueue_start(struct drm_gpu_scheduler *sched);
index 4b61b0e577209e4ea20803752bb55b6e44983bed..2eed0ffb5e8f83786586a4d5c31c4d2c256898a7 100644 (file)
@@ -16,7 +16,7 @@ struct backing_file_ctx {
        const struct cred *cred;
        struct file *user_file;
        void (*accessed)(struct file *);
-       void (*end_write)(struct file *);
+       void (*end_write)(struct file *, loff_t, ssize_t);
 };
 
 struct file *backing_file_open(const struct path *user_path, int flags,
index 19d8ca8ac960f75ae8ca37c302d9e1055ef92af4..bdadb0bb6cecd18c047b6548ae03134d43d4894a 100644 (file)
@@ -635,6 +635,7 @@ enum bpf_type_flag {
         */
        PTR_UNTRUSTED           = BIT(6 + BPF_BASE_TYPE_BITS),
 
+       /* MEM can be uninitialized. */
        MEM_UNINIT              = BIT(7 + BPF_BASE_TYPE_BITS),
 
        /* DYNPTR points to memory local to the bpf program. */
@@ -700,6 +701,13 @@ enum bpf_type_flag {
         */
        MEM_ALIGNED             = BIT(17 + BPF_BASE_TYPE_BITS),
 
+       /* MEM is being written to, often combined with MEM_UNINIT. Non-presence
+        * of MEM_WRITE means that MEM is only being read. MEM_WRITE without the
+        * MEM_UNINIT means that memory needs to be initialized since it is also
+        * read.
+        */
+       MEM_WRITE               = BIT(18 + BPF_BASE_TYPE_BITS),
+
        __BPF_TYPE_FLAG_MAX,
        __BPF_TYPE_LAST_FLAG    = __BPF_TYPE_FLAG_MAX - 1,
 };
@@ -758,10 +766,10 @@ enum bpf_arg_type {
        ARG_PTR_TO_SOCKET_OR_NULL       = PTR_MAYBE_NULL | ARG_PTR_TO_SOCKET,
        ARG_PTR_TO_STACK_OR_NULL        = PTR_MAYBE_NULL | ARG_PTR_TO_STACK,
        ARG_PTR_TO_BTF_ID_OR_NULL       = PTR_MAYBE_NULL | ARG_PTR_TO_BTF_ID,
-       /* pointer to memory does not need to be initialized, helper function must fill
-        * all bytes or clear them in error case.
+       /* Pointer to memory does not need to be initialized, since helper function
+        * fills all bytes or clears them in error case.
         */
-       ARG_PTR_TO_UNINIT_MEM           = MEM_UNINIT | ARG_PTR_TO_MEM,
+       ARG_PTR_TO_UNINIT_MEM           = MEM_UNINIT | MEM_WRITE | ARG_PTR_TO_MEM,
        /* Pointer to valid memory of size known at compile time. */
        ARG_PTR_TO_FIXED_SIZE_MEM       = MEM_FIXED_SIZE | ARG_PTR_TO_MEM,
 
index aaf004d943228af86aab2f6cf6694f9f48859e07..e45162ef59bb1a6d65489a26ce6f0b2d5cfb0bef 100644 (file)
@@ -33,6 +33,9 @@ int bpf_mem_alloc_percpu_init(struct bpf_mem_alloc *ma, struct obj_cgroup *objcg
 int bpf_mem_alloc_percpu_unit_init(struct bpf_mem_alloc *ma, int size);
 void bpf_mem_alloc_destroy(struct bpf_mem_alloc *ma);
 
+/* Check the allocation size for kmalloc equivalent allocator */
+int bpf_mem_alloc_check_size(bool percpu, size_t size);
+
 /* kmalloc/kfree equivalent: */
 void *bpf_mem_alloc(struct bpf_mem_alloc *ma, size_t size);
 void bpf_mem_free(struct bpf_mem_alloc *ma, void *ptr);
index 9f2a6b83b49e144782f036f023f61b7674ad3ba7..fa78f49d4a9a640deb19376eaafe77cfe00420e1 100644 (file)
@@ -146,6 +146,7 @@ BPF_LINK_TYPE(BPF_LINK_TYPE_XDP, xdp)
 BPF_LINK_TYPE(BPF_LINK_TYPE_NETFILTER, netfilter)
 BPF_LINK_TYPE(BPF_LINK_TYPE_TCX, tcx)
 BPF_LINK_TYPE(BPF_LINK_TYPE_NETKIT, netkit)
+BPF_LINK_TYPE(BPF_LINK_TYPE_SOCKMAP, sockmap)
 #endif
 #ifdef CONFIG_PERF_EVENTS
 BPF_LINK_TYPE(BPF_LINK_TYPE_PERF_EVENT, perf)
index 04f3ace5787be899ba93ba274df8515f80858e67..8fc1aed6411313b6deffcedb73aa9dcc75fe78ac 100644 (file)
@@ -6,7 +6,7 @@
 #include <linux/bug.h>
 #include <linux/slab.h>
 #include <linux/time.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #include <linux/ceph/types.h>
 
index 4497d0a6772cdf3d1235db36f015f247b04f2ed3..15fb566d3f46ab021a99d56edf1693ea616ef9e6 100644 (file)
@@ -4,7 +4,7 @@
 
 #include <linux/ceph/ceph_debug.h>
 
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include <linux/backing-dev.h>
 #include <linux/completion.h>
 #include <linux/exportfs.h>
index 2af44427107de9d7a9102f577e8d343e8b1afcfe..880fe85e35e99998fc535e54d6786d59bceaebf8 100644 (file)
@@ -454,4 +454,39 @@ do {                                                                       \
                __closure_wait_event(waitlist, _cond);                  \
 } while (0)
 
+#define __closure_wait_event_timeout(waitlist, _cond, _until)          \
+({                                                                     \
+       struct closure cl;                                              \
+       long _t;                                                        \
+                                                                       \
+       closure_init_stack(&cl);                                        \
+                                                                       \
+       while (1) {                                                     \
+               closure_wait(waitlist, &cl);                            \
+               if (_cond) {                                            \
+                       _t = max_t(long, 1L, _until - jiffies);         \
+                       break;                                          \
+               }                                                       \
+               _t = max_t(long, 0L, _until - jiffies);                 \
+               if (!_t)                                                \
+                       break;                                          \
+               closure_sync_timeout(&cl, _t);                          \
+       }                                                               \
+       closure_wake_up(waitlist);                                      \
+       closure_sync(&cl);                                              \
+       _t;                                                             \
+})
+
+/*
+ * Returns 0 if timeout expired, remaining time in jiffies (at least 1) if
+ * condition became true
+ */
+#define closure_wait_event_timeout(waitlist, _cond, _timeout)          \
+({                                                                     \
+       unsigned long _until = jiffies + _timeout;                      \
+       (_cond)                                                         \
+               ? max_t(long, 1L, _until - jiffies)                     \
+               : __closure_wait_event_timeout(waitlist, _cond, _until);\
+})
+
 #endif /* _LINUX_CLOSURE_H */
index f805adaa316e9a21a4c78ffcb5ffb07acb19055b..cd6f9aae311fca0f6d13a6534bdcbf24564d3fa3 100644 (file)
 #define __noscs __attribute__((__no_sanitize__("shadow-call-stack")))
 #endif
 
+#ifdef __SANITIZE_HWADDRESS__
+#define __no_sanitize_address __attribute__((__no_sanitize__("hwaddress")))
+#else
 #define __no_sanitize_address __attribute__((__no_sanitize_address__))
+#endif
 
 #if defined(__SANITIZE_THREAD__)
 #define __no_sanitize_thread __attribute__((__no_sanitize_thread__))
index e0e19d9c13231ce96218f15fcbf82c4316ebb986..7fe0981a7e4674f801201c11e7ebaf9c1b9e34d9 100644 (file)
@@ -1107,10 +1107,9 @@ static inline int parse_perf_domain(int cpu, const char *list_name,
                                    const char *cell_name,
                                    struct of_phandle_args *args)
 {
-       struct device_node *cpu_np;
        int ret;
 
-       cpu_np = of_cpu_device_node_get(cpu);
+       struct device_node *cpu_np __free(device_node) = of_cpu_device_node_get(cpu);
        if (!cpu_np)
                return -ENODEV;
 
@@ -1118,9 +1117,6 @@ static inline int parse_perf_domain(int cpu, const char *list_name,
                                         args);
        if (ret < 0)
                return ret;
-
-       of_node_put(cpu_np);
-
        return 0;
 }
 
index b4bde8d226979bd7c54271d1698af27959a118fb..667cb6db9019349c9db0233acf9e78ff6a6d9625 100644 (file)
@@ -1078,6 +1078,9 @@ int device_for_each_child(struct device *dev, void *data,
                          int (*fn)(struct device *dev, void *data));
 int device_for_each_child_reverse(struct device *dev, void *data,
                                  int (*fn)(struct device *dev, void *data));
+int device_for_each_child_reverse_from(struct device *parent,
+                                      struct device *from, const void *data,
+                                      int (*fn)(struct device *, const void *));
 struct device *device_find_child(struct device *dev, void *data,
                                 int (*match)(struct device *dev, void *data));
 struct device *device_find_child_by_name(struct device *parent,
index 30114c25ad12033c820a23503bf3e520273ae6fe..ecf203f010343a049935a68a55beae649693901a 100644 (file)
@@ -21,7 +21,7 @@
 #include <linux/netdevice.h>
 #include <linux/random.h>
 #include <linux/crc32.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include <asm/bitsperlong.h>
 
 #ifdef __KERNEL__
index 2944d4aa413b75564b25f2b5104fec5303d762ae..b1c5722f2b3ce4ba82e89716d5e27f85c67a8afd 100644 (file)
@@ -22,7 +22,6 @@
  * as this is the granularity returned by copy_fdset().
  */
 #define NR_OPEN_DEFAULT BITS_PER_LONG
-#define NR_OPEN_MAX ~0U
 
 struct fdtable {
        unsigned int max_fds;
@@ -106,7 +105,10 @@ struct task_struct;
 
 void put_files_struct(struct files_struct *fs);
 int unshare_files(void);
-struct files_struct *dup_fd(struct files_struct *, unsigned, int *) __latent_entropy;
+struct fd_range {
+       unsigned int from, to;
+};
+struct files_struct *dup_fd(struct files_struct *, struct fd_range *) __latent_entropy;
 void do_close_on_exec(struct files_struct *);
 int iterate_fd(struct files_struct *, unsigned,
                int (*)(const void *, struct file *, unsigned),
@@ -115,8 +117,6 @@ int iterate_fd(struct files_struct *, unsigned,
 extern int close_fd(unsigned int fd);
 extern int __close_range(unsigned int fd, unsigned int max_fd, unsigned int flags);
 extern struct file *file_close_fd(unsigned int fd);
-extern int unshare_fd(unsigned long unshare_flags, unsigned int max_fds,
-                     struct files_struct **new_fdp);
 
 extern struct kmem_cache *files_cachep;
 
index 955680c3bb5f2bf8415ff44286646f1b8f2d5a10..3abe614ef5f06003fc6ed5e8c5b1ac21db99b2ac 100644 (file)
@@ -3,6 +3,12 @@
  *
  * Copyright (C) 2024 Red Hat, Inc. All Rights Reserved.
  * Written by David Howells ([email protected])
+ *
+ * See:
+ *
+ *     Documentation/core-api/folio_queue.rst
+ *
+ * for a description of the API.
  */
 
 #ifndef _LINUX_FOLIO_QUEUE_H
@@ -33,6 +39,13 @@ struct folio_queue {
 #endif
 };
 
+/**
+ * folioq_init - Initialise a folio queue segment
+ * @folioq: The segment to initialise
+ *
+ * Initialise a folio queue segment.  Note that the folio pointers are
+ * left uninitialised.
+ */
 static inline void folioq_init(struct folio_queue *folioq)
 {
        folio_batch_init(&folioq->vec);
@@ -43,62 +56,155 @@ static inline void folioq_init(struct folio_queue *folioq)
        folioq->marks3 = 0;
 }
 
+/**
+ * folioq_nr_slots: Query the capacity of a folio queue segment
+ * @folioq: The segment to query
+ *
+ * Query the number of folios that a particular folio queue segment might hold.
+ * [!] NOTE: This must not be assumed to be the same for every segment!
+ */
 static inline unsigned int folioq_nr_slots(const struct folio_queue *folioq)
 {
        return PAGEVEC_SIZE;
 }
 
+/**
+ * folioq_count: Query the occupancy of a folio queue segment
+ * @folioq: The segment to query
+ *
+ * Query the number of folios that have been added to a folio queue segment.
+ * Note that this is not decreased as folios are removed from a segment.
+ */
 static inline unsigned int folioq_count(struct folio_queue *folioq)
 {
        return folio_batch_count(&folioq->vec);
 }
 
+/**
+ * folioq_full: Query if a folio queue segment is full
+ * @folioq: The segment to query
+ *
+ * Query if a folio queue segment is fully occupied.  Note that this does not
+ * change if folios are removed from a segment.
+ */
 static inline bool folioq_full(struct folio_queue *folioq)
 {
        //return !folio_batch_space(&folioq->vec);
        return folioq_count(folioq) >= folioq_nr_slots(folioq);
 }
 
+/**
+ * folioq_is_marked: Check first folio mark in a folio queue segment
+ * @folioq: The segment to query
+ * @slot: The slot number of the folio to query
+ *
+ * Determine if the first mark is set for the folio in the specified slot in a
+ * folio queue segment.
+ */
 static inline bool folioq_is_marked(const struct folio_queue *folioq, unsigned int slot)
 {
        return test_bit(slot, &folioq->marks);
 }
 
+/**
+ * folioq_mark: Set the first mark on a folio in a folio queue segment
+ * @folioq: The segment to modify
+ * @slot: The slot number of the folio to modify
+ *
+ * Set the first mark for the folio in the specified slot in a folio queue
+ * segment.
+ */
 static inline void folioq_mark(struct folio_queue *folioq, unsigned int slot)
 {
        set_bit(slot, &folioq->marks);
 }
 
+/**
+ * folioq_unmark: Clear the first mark on a folio in a folio queue segment
+ * @folioq: The segment to modify
+ * @slot: The slot number of the folio to modify
+ *
+ * Clear the first mark for the folio in the specified slot in a folio queue
+ * segment.
+ */
 static inline void folioq_unmark(struct folio_queue *folioq, unsigned int slot)
 {
        clear_bit(slot, &folioq->marks);
 }
 
+/**
+ * folioq_is_marked2: Check second folio mark in a folio queue segment
+ * @folioq: The segment to query
+ * @slot: The slot number of the folio to query
+ *
+ * Determine if the second mark is set for the folio in the specified slot in a
+ * folio queue segment.
+ */
 static inline bool folioq_is_marked2(const struct folio_queue *folioq, unsigned int slot)
 {
        return test_bit(slot, &folioq->marks2);
 }
 
+/**
+ * folioq_mark2: Set the second mark on a folio in a folio queue segment
+ * @folioq: The segment to modify
+ * @slot: The slot number of the folio to modify
+ *
+ * Set the second mark for the folio in the specified slot in a folio queue
+ * segment.
+ */
 static inline void folioq_mark2(struct folio_queue *folioq, unsigned int slot)
 {
        set_bit(slot, &folioq->marks2);
 }
 
+/**
+ * folioq_unmark2: Clear the second mark on a folio in a folio queue segment
+ * @folioq: The segment to modify
+ * @slot: The slot number of the folio to modify
+ *
+ * Clear the second mark for the folio in the specified slot in a folio queue
+ * segment.
+ */
 static inline void folioq_unmark2(struct folio_queue *folioq, unsigned int slot)
 {
        clear_bit(slot, &folioq->marks2);
 }
 
+/**
+ * folioq_is_marked3: Check third folio mark in a folio queue segment
+ * @folioq: The segment to query
+ * @slot: The slot number of the folio to query
+ *
+ * Determine if the third mark is set for the folio in the specified slot in a
+ * folio queue segment.
+ */
 static inline bool folioq_is_marked3(const struct folio_queue *folioq, unsigned int slot)
 {
        return test_bit(slot, &folioq->marks3);
 }
 
+/**
+ * folioq_mark3: Set the third mark on a folio in a folio queue segment
+ * @folioq: The segment to modify
+ * @slot: The slot number of the folio to modify
+ *
+ * Set the third mark for the folio in the specified slot in a folio queue
+ * segment.
+ */
 static inline void folioq_mark3(struct folio_queue *folioq, unsigned int slot)
 {
        set_bit(slot, &folioq->marks3);
 }
 
+/**
+ * folioq_unmark3: Clear the third mark on a folio in a folio queue segment
+ * @folioq: The segment to modify
+ * @slot: The slot number of the folio to modify
+ *
+ * Clear the third mark for the folio in the specified slot in a folio queue
+ * segment.
+ */
 static inline void folioq_unmark3(struct folio_queue *folioq, unsigned int slot)
 {
        clear_bit(slot, &folioq->marks3);
@@ -111,6 +217,19 @@ static inline unsigned int __folio_order(struct folio *folio)
        return folio->_flags_1 & 0xff;
 }
 
+/**
+ * folioq_append: Add a folio to a folio queue segment
+ * @folioq: The segment to add to
+ * @folio: The folio to add
+ *
+ * Add a folio to the tail of the sequence in a folio queue segment, increasing
+ * the occupancy count and returning the slot number for the folio just added.
+ * The folio size is extracted and stored in the queue and the marks are left
+ * unmodified.
+ *
+ * Note that it's left up to the caller to check that the segment capacity will
+ * not be exceeded and to extend the queue.
+ */
 static inline unsigned int folioq_append(struct folio_queue *folioq, struct folio *folio)
 {
        unsigned int slot = folioq->vec.nr++;
@@ -120,6 +239,19 @@ static inline unsigned int folioq_append(struct folio_queue *folioq, struct foli
        return slot;
 }
 
+/**
+ * folioq_append_mark: Add a folio to a folio queue segment
+ * @folioq: The segment to add to
+ * @folio: The folio to add
+ *
+ * Add a folio to the tail of the sequence in a folio queue segment, increasing
+ * the occupancy count and returning the slot number for the folio just added.
+ * The folio size is extracted and stored in the queue, the first mark is set
+ * and and the second and third marks are left unmodified.
+ *
+ * Note that it's left up to the caller to check that the segment capacity will
+ * not be exceeded and to extend the queue.
+ */
 static inline unsigned int folioq_append_mark(struct folio_queue *folioq, struct folio *folio)
 {
        unsigned int slot = folioq->vec.nr++;
@@ -130,21 +262,57 @@ static inline unsigned int folioq_append_mark(struct folio_queue *folioq, struct
        return slot;
 }
 
+/**
+ * folioq_folio: Get a folio from a folio queue segment
+ * @folioq: The segment to access
+ * @slot: The folio slot to access
+ *
+ * Retrieve the folio in the specified slot from a folio queue segment.  Note
+ * that no bounds check is made and if the slot hasn't been added into yet, the
+ * pointer will be undefined.  If the slot has been cleared, NULL will be
+ * returned.
+ */
 static inline struct folio *folioq_folio(const struct folio_queue *folioq, unsigned int slot)
 {
        return folioq->vec.folios[slot];
 }
 
+/**
+ * folioq_folio_order: Get the order of a folio from a folio queue segment
+ * @folioq: The segment to access
+ * @slot: The folio slot to access
+ *
+ * Retrieve the order of the folio in the specified slot from a folio queue
+ * segment.  Note that no bounds check is made and if the slot hasn't been
+ * added into yet, the order returned will be 0.
+ */
 static inline unsigned int folioq_folio_order(const struct folio_queue *folioq, unsigned int slot)
 {
        return folioq->orders[slot];
 }
 
+/**
+ * folioq_folio_size: Get the size of a folio from a folio queue segment
+ * @folioq: The segment to access
+ * @slot: The folio slot to access
+ *
+ * Retrieve the size of the folio in the specified slot from a folio queue
+ * segment.  Note that no bounds check is made and if the slot hasn't been
+ * added into yet, the size returned will be PAGE_SIZE.
+ */
 static inline size_t folioq_folio_size(const struct folio_queue *folioq, unsigned int slot)
 {
        return PAGE_SIZE << folioq_folio_order(folioq, slot);
 }
 
+/**
+ * folioq_clear: Clear a folio from a folio queue segment
+ * @folioq: The segment to clear
+ * @slot: The folio slot to clear
+ *
+ * Clear a folio from a sequence in a folio queue segment and clear its marks.
+ * The occupancy count is left unchanged.
+ */
 static inline void folioq_clear(struct folio_queue *folioq, unsigned int slot)
 {
        folioq->vec.folios[slot] = NULL;
index e3c603d01337650d562405500013f5c4cfed8eb6..3559446279c152c70b7f1f3e0154f6e66a5aba33 100644 (file)
@@ -3082,7 +3082,12 @@ extern loff_t default_llseek(struct file *file, loff_t offset, int whence);
 
 extern loff_t vfs_llseek(struct file *file, loff_t offset, int whence);
 
-extern int inode_init_always(struct super_block *, struct inode *);
+extern int inode_init_always_gfp(struct super_block *, struct inode *, gfp_t);
+static inline int inode_init_always(struct super_block *sb, struct inode *inode)
+{
+       return inode_init_always_gfp(sb, inode, GFP_NOFS);
+}
+
 extern void inode_init_once(struct inode *);
 extern void address_space_init_once(struct address_space *mapping);
 extern struct inode * igrab(struct inode *);
index c13e99cbbf8162bb395a48f3709cbd69ac009e7d..4b4bfef6f053a49557118c3592ef64fc7ce1ab39 100644 (file)
@@ -160,6 +160,12 @@ extern int get_tree_keyed(struct fs_context *fc,
 
 int setup_bdev_super(struct super_block *sb, int sb_flags,
                struct fs_context *fc);
+
+#define GET_TREE_BDEV_QUIET_LOOKUP             0x0001
+int get_tree_bdev_flags(struct fs_context *fc,
+               int (*fill_super)(struct super_block *sb,
+                                 struct fs_context *fc), unsigned int flags);
+
 extern int get_tree_bdev(struct fs_context *fc,
                               int (*fill_super)(struct super_block *sb,
                                                 struct fs_context *fc));
index df25fffdc0ae71580cc6866e950fad883f2e4c41..623ccfcbf39c3593f2eae3bb58f33e10f09e63c1 100644 (file)
@@ -59,7 +59,8 @@ static inline int enetc_mdio_read_c45(struct mii_bus *bus, int phy_id,
 static inline int enetc_mdio_write_c45(struct mii_bus *bus, int phy_id,
                                       int devad, int regnum, u16 value)
 { return -EINVAL; }
-struct enetc_hw *enetc_hw_alloc(struct device *dev, void __iomem *port_regs)
+static inline struct enetc_hw *enetc_hw_alloc(struct device *dev,
+                                             void __iomem *port_regs)
 { return ERR_PTR(-EINVAL); }
 
 #endif
index 8be029bc50b1e33f197b8e3be71983589f534778..3ecf7768e577940f9ea79393c38bc2550ce7ddb8 100644 (file)
@@ -217,7 +217,6 @@ struct fsnotify_group {
 
 #define FSNOTIFY_GROUP_USER    0x01 /* user allocated group */
 #define FSNOTIFY_GROUP_DUPS    0x02 /* allow multiple marks per object */
-#define FSNOTIFY_GROUP_NOFS    0x04 /* group lock is not direct reclaim safe */
        int flags;
        unsigned int owner_flags;       /* stored flags of mark_mutex owner */
 
@@ -268,22 +267,19 @@ struct fsnotify_group {
 static inline void fsnotify_group_lock(struct fsnotify_group *group)
 {
        mutex_lock(&group->mark_mutex);
-       if (group->flags & FSNOTIFY_GROUP_NOFS)
-               group->owner_flags = memalloc_nofs_save();
+       group->owner_flags = memalloc_nofs_save();
 }
 
 static inline void fsnotify_group_unlock(struct fsnotify_group *group)
 {
-       if (group->flags & FSNOTIFY_GROUP_NOFS)
-               memalloc_nofs_restore(group->owner_flags);
+       memalloc_nofs_restore(group->owner_flags);
        mutex_unlock(&group->mark_mutex);
 }
 
 static inline void fsnotify_group_assert_locked(struct fsnotify_group *group)
 {
        WARN_ON_ONCE(!mutex_is_locked(&group->mark_mutex));
-       if (group->flags & FSNOTIFY_GROUP_NOFS)
-               WARN_ON_ONCE(!(current->flags & PF_MEMALLOC_NOFS));
+       WARN_ON_ONCE(!(current->flags & PF_MEMALLOC_NOFS));
 }
 
 /* When calling fsnotify tell it if the data is a path or inode */
index 3bb87bf6bc658b92d5157fb7355729dac4d4dcca..455f855bc08484cc2a55c86cb5b00df672c61264 100644 (file)
@@ -59,6 +59,15 @@ enum hdmi_infoframe_type {
 #define HDMI_DRM_INFOFRAME_SIZE    26
 #define HDMI_VENDOR_INFOFRAME_SIZE  4
 
+/*
+ * HDMI 1.3a table 5-14 states that the largest InfoFrame_length is 27,
+ * not including the packet header or checksum byte. We include the
+ * checksum byte in HDMI_INFOFRAME_HEADER_SIZE, so this should allow
+ * HDMI_INFOFRAME_SIZE(MAX) to be the largest buffer we could ever need
+ * for any HDMI infoframe.
+ */
+#define HDMI_MAX_INFOFRAME_SIZE    27
+
 #define HDMI_INFOFRAME_SIZE(type)      \
        (HDMI_INFOFRAME_HEADER_SIZE + HDMI_ ## type ## _INFOFRAME_SIZE)
 
index 9c8119ed13a4b78cc2a321116a0028797563a56f..c4dde3aafcacdb9b2f073de79f3761a9bafa7100 100644 (file)
@@ -466,6 +466,7 @@ struct host1x_memory_context {
        refcount_t ref;
        struct pid *owner;
 
+       struct device_dma_parameters dma_parms;
        struct device dev;
        u64 dma_mask;
        u32 stream_id;
index 67d0ab3c3bbab60c6f0f526d56a3ba6835d4b939..ef5b80e48599c107a4fd92035f28d4c73c9c2600 100644 (file)
@@ -322,6 +322,24 @@ struct thpsize {
        (transparent_hugepage_flags &                                   \
         (1<<TRANSPARENT_HUGEPAGE_USE_ZERO_PAGE_FLAG))
 
+static inline bool vma_thp_disabled(struct vm_area_struct *vma,
+               unsigned long vm_flags)
+{
+       /*
+        * Explicitly disabled through madvise or prctl, or some
+        * architectures may disable THP for some mappings, for
+        * example, s390 kvm.
+        */
+       return (vm_flags & VM_NOHUGEPAGE) ||
+              test_bit(MMF_DISABLE_THP, &vma->vm_mm->flags);
+}
+
+static inline bool thp_disabled_by_hw(void)
+{
+       /* If the hardware/firmware marked hugepage support disabled. */
+       return transparent_hugepage_flags & (1 << TRANSPARENT_HUGEPAGE_UNSUPPORTED);
+}
+
 unsigned long thp_get_unmapped_area(struct file *filp, unsigned long addr,
                unsigned long len, unsigned long pgoff, unsigned long flags);
 unsigned long thp_get_unmapped_area_vmflags(struct file *filp, unsigned long addr,
index 30cef3b940ebed1b177056cf2f20857984e79688..456bca45ff05286c0c29503839183b99f7b19891 100644 (file)
@@ -20,7 +20,7 @@
 #include <linux/etherdevice.h>
 #include <linux/bitfield.h>
 #include <asm/byteorder.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 /*
  * DS bit usage
index 89a0be6ee0e23be40dcc7a268bdaf58a91b03aa9..cd866b020a01d67081788e1baa2d372ce1c79767 100644 (file)
@@ -339,12 +339,16 @@ struct input_handler {
  * @name: name given to the handle by handler that created it
  * @dev: input device the handle is attached to
  * @handler: handler that works with the device through this handle
+ * @handle_events: event sequence handler. It is set up by the input core
+ *     according to event handling method specified in the @handler. See
+ *     input_handle_setup_event_handler().
+ *     This method is being called by the input core with interrupts disabled
+ *     and dev->event_lock spinlock held and so it may not sleep.
  * @d_node: used to put the handle on device's list of attached handles
  * @h_node: used to put the handle on handler's list of handles from which
  *     it gets events
  */
 struct input_handle {
-
        void *private;
 
        int open;
@@ -353,6 +357,10 @@ struct input_handle {
        struct input_dev *dev;
        struct input_handler *handler;
 
+       unsigned int (*handle_events)(struct input_handle *handle,
+                                     struct input_value *vals,
+                                     unsigned int count);
+
        struct list_head        d_node;
        struct list_head        h_node;
 };
index 4ad12a3c8bae221366f3a9c03896d818f6e94c85..f61407e3b12192d78932d8c7ac737a5161da0bc9 100644 (file)
@@ -256,6 +256,39 @@ static inline const struct iomap *iomap_iter_srcmap(const struct iomap_iter *i)
        return &i->iomap;
 }
 
+/*
+ * Return the file offset for the first unchanged block after a short write.
+ *
+ * If nothing was written, round @pos down to point at the first block in
+ * the range, else round up to include the partially written block.
+ */
+static inline loff_t iomap_last_written_block(struct inode *inode, loff_t pos,
+               ssize_t written)
+{
+       if (unlikely(!written))
+               return round_down(pos, i_blocksize(inode));
+       return round_up(pos + written, i_blocksize(inode));
+}
+
+/*
+ * Check if the range needs to be unshared for a FALLOC_FL_UNSHARE_RANGE
+ * operation.
+ *
+ * Don't bother with blocks that are not shared to start with; or mappings that
+ * cannot be shared, such as inline data, delalloc reservations, holes or
+ * unwritten extents.
+ *
+ * Note that we use srcmap directly instead of iomap_iter_srcmap as unsharing
+ * requires providing a separate source map, and the presence of one is a good
+ * indicator that unsharing is needed, unlike IOMAP_F_SHARED which can be set
+ * for any data that goes into the COW fork for XFS.
+ */
+static inline bool iomap_want_unshare_iter(const struct iomap_iter *iter)
+{
+       return (iter->iomap.flags & IOMAP_F_SHARED) &&
+               iter->srcmap.type == IOMAP_MAPPED;
+}
+
 ssize_t iomap_file_buffered_write(struct kiocb *iocb, struct iov_iter *from,
                const struct iomap_ops *ops, void *private);
 int iomap_read_folio(struct folio *folio, const struct iomap_ops *ops);
@@ -276,9 +309,9 @@ vm_fault_t iomap_page_mkwrite(struct vm_fault *vmf,
 
 typedef void (*iomap_punch_t)(struct inode *inode, loff_t offset, loff_t length,
                struct iomap *iomap);
-void iomap_file_buffered_write_punch_delalloc(struct inode *inode, loff_t pos,
-               loff_t length, ssize_t written, unsigned flag,
-               struct iomap *iomap, iomap_punch_t punch);
+void iomap_write_delalloc_release(struct inode *inode, loff_t start_byte,
+               loff_t end_byte, unsigned flags, struct iomap *iomap,
+               iomap_punch_t punch);
 
 int iomap_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo,
                u64 start, u64 len, const struct iomap_ops *ops);
index ecabed6d3307528dd34c3fb2e02642d20771fc55..7f1f11a5e4e44b3b2efaf29c6512ede9ce6817ea 100644 (file)
@@ -66,10 +66,12 @@ struct its_vpe {
                                bool    enabled;
                                bool    group;
                        }                       sgi_config[16];
-                       atomic_t vmapp_count;
                };
        };
 
+       /* Track the VPE being mapped */
+       atomic_t vmapp_count;
+
        /*
         * Ensures mutual exclusion between affinity setting of the
         * vPE and vLPI operations using vpe->col_idx.
index 11690dacd98684ec49b965217ad3b934bef3d5cd..ec9c05044d4fed068b39844a4141c71a339b0e39 100644 (file)
@@ -54,12 +54,11 @@ static inline long mm_ksm_zero_pages(struct mm_struct *mm)
        return atomic_long_read(&mm->ksm_zero_pages);
 }
 
-static inline int ksm_fork(struct mm_struct *mm, struct mm_struct *oldmm)
+static inline void ksm_fork(struct mm_struct *mm, struct mm_struct *oldmm)
 {
+       /* Adding mm to ksm is best effort on fork. */
        if (test_bit(MMF_VM_MERGEABLE, &oldmm->flags))
-               return __ksm_enter(mm);
-
-       return 0;
+               __ksm_enter(mm);
 }
 
 static inline int ksm_execve(struct mm_struct *mm)
@@ -107,9 +106,8 @@ static inline int ksm_disable(struct mm_struct *mm)
        return 0;
 }
 
-static inline int ksm_fork(struct mm_struct *mm, struct mm_struct *oldmm)
+static inline void ksm_fork(struct mm_struct *mm, struct mm_struct *oldmm)
 {
-       return 0;
 }
 
 static inline int ksm_execve(struct mm_struct *mm)
index db567d26f7b94834eb19b7794a58da64ba68e7e1..45be36e5285ffb5de3c161ff450275997aac7232 100644 (file)
@@ -1313,8 +1313,6 @@ void mark_page_dirty(struct kvm *kvm, gfn_t gfn);
 
 struct kvm_memslots *kvm_vcpu_memslots(struct kvm_vcpu *vcpu);
 struct kvm_memory_slot *kvm_vcpu_gfn_to_memslot(struct kvm_vcpu *vcpu, gfn_t gfn);
-kvm_pfn_t kvm_vcpu_gfn_to_pfn_atomic(struct kvm_vcpu *vcpu, gfn_t gfn);
-kvm_pfn_t kvm_vcpu_gfn_to_pfn(struct kvm_vcpu *vcpu, gfn_t gfn);
 int kvm_vcpu_map(struct kvm_vcpu *vcpu, gpa_t gpa, struct kvm_host_map *map);
 void kvm_vcpu_unmap(struct kvm_vcpu *vcpu, struct kvm_host_map *map, bool dirty);
 unsigned long kvm_vcpu_gfn_to_hva(struct kvm_vcpu *vcpu, gfn_t gfn);
index 97f6de69f616d0fd0ae8a638819cf8b077a6ce0d..96d369112bfa037d7d05ed6ca1310115c6dbd60f 100644 (file)
@@ -2138,7 +2138,7 @@ struct mlx5_ifc_cmd_hca_cap_2_bits {
        u8         ts_cqe_metadata_size2wqe_counter[0x5];
        u8         reserved_at_250[0x10];
 
-       u8         reserved_at_260[0x120];
+       u8         reserved_at_260[0x20];
 
        u8         format_select_dw_gtpu_dw_0[0x8];
        u8         format_select_dw_gtpu_dw_1[0x8];
index ecf63d2b058255e1855fd35d7838674443b516f9..61fff5d34ed532fe03144208aee618e0dd0a18ec 100644 (file)
@@ -3818,8 +3818,9 @@ void *sparse_buffer_alloc(unsigned long size);
 struct page * __populate_section_memmap(unsigned long pfn,
                unsigned long nr_pages, int nid, struct vmem_altmap *altmap,
                struct dev_pagemap *pgmap);
-void pmd_init(void *addr);
 void pud_init(void *addr);
+void pmd_init(void *addr);
+void kernel_pte_init(void *addr);
 pgd_t *vmemmap_pgd_populate(unsigned long addr, int node);
 p4d_t *vmemmap_p4d_populate(pgd_t *pgd, unsigned long addr, int node);
 pud_t *vmemmap_pud_populate(p4d_t *p4d, unsigned long addr, int node);
index b4fa92a6e44b824661aa618b35deb57d925136ed..1b56796f6cb336914f148300e13c26cc7b6209dd 100644 (file)
@@ -15,7 +15,7 @@
 #include <linux/kernel.h>
 #include <linux/io.h>
 
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include <asm/barrier.h>
 
 #ifdef CONFIG_MTD_MAP_BANK_WIDTH_1
index e87b5e4883259a0723278ae3f1bee87e940af895..8896705ccd638bcb7d2ca8f3905351fc823f71b8 100644 (file)
@@ -3325,6 +3325,12 @@ static inline void netif_tx_wake_all_queues(struct net_device *dev)
 
 static __always_inline void netif_tx_stop_queue(struct netdev_queue *dev_queue)
 {
+       /* Paired with READ_ONCE() from dev_watchdog() */
+       WRITE_ONCE(dev_queue->trans_start, jiffies);
+
+       /* This barrier is paired with smp_mb() from dev_watchdog() */
+       smp_mb__before_atomic();
+
        /* Must be an atomic op see netif_txq_try_stop() */
        set_bit(__QUEUE_STATE_DRV_XOFF, &dev_queue->state);
 }
@@ -3451,6 +3457,12 @@ static inline void netdev_tx_sent_queue(struct netdev_queue *dev_queue,
        if (likely(dql_avail(&dev_queue->dql) >= 0))
                return;
 
+       /* Paired with READ_ONCE() from dev_watchdog() */
+       WRITE_ONCE(dev_queue->trans_start, jiffies);
+
+       /* This barrier is paired with smp_mb() from dev_watchdog() */
+       smp_mb__before_atomic();
+
        set_bit(__QUEUE_STATE_STACK_XOFF, &dev_queue->state);
 
        /*
@@ -5029,6 +5041,24 @@ void netif_set_tso_max_segs(struct net_device *dev, unsigned int segs);
 void netif_inherit_tso_max(struct net_device *to,
                           const struct net_device *from);
 
+static inline unsigned int
+netif_get_gro_max_size(const struct net_device *dev, const struct sk_buff *skb)
+{
+       /* pairs with WRITE_ONCE() in netif_set_gro(_ipv4)_max_size() */
+       return skb->protocol == htons(ETH_P_IPV6) ?
+              READ_ONCE(dev->gro_max_size) :
+              READ_ONCE(dev->gro_ipv4_max_size);
+}
+
+static inline unsigned int
+netif_get_gso_max_size(const struct net_device *dev, const struct sk_buff *skb)
+{
+       /* pairs with WRITE_ONCE() in netif_set_gso(_ipv4)_max_size() */
+       return skb->protocol == htons(ETH_P_IPV6) ?
+              READ_ONCE(dev->gso_max_size) :
+              READ_ONCE(dev->gso_ipv4_max_size);
+}
+
 static inline bool netif_is_macsec(const struct net_device *dev)
 {
        return dev->priv_flags & IFF_MACSEC;
index 853df3fcd4c208e8977909bd5051f4b616467041..b804346a974195927de579e67369cfd5e6054c78 100644 (file)
@@ -249,6 +249,7 @@ struct nfs_server {
        struct list_head        layouts;
        struct list_head        delegations;
        struct list_head        ss_copies;
+       struct list_head        ss_src_copies;
 
        unsigned long           delegation_gen;
        unsigned long           mig_gen;
index b353abe00357a11d7eb77b9d03bc59ba50646cd1..b0dd9b1eef4f9cd9dfdb48e0eb1b75f349ea2520 100644 (file)
@@ -65,10 +65,25 @@ struct nfsd_file *nfs_open_local_fh(nfs_uuid_t *,
                   struct rpc_clnt *, const struct cred *,
                   const struct nfs_fh *, const fmode_t);
 
+static inline void nfs_to_nfsd_file_put_local(struct nfsd_file *localio)
+{
+       /*
+        * Once reference to nfsd_serv is dropped, NFSD could be
+        * unloaded, so ensure safe return from nfsd_file_put_local()
+        * by always taking RCU.
+        */
+       rcu_read_lock();
+       nfs_to->nfsd_file_put_local(localio);
+       rcu_read_unlock();
+}
+
 #else   /* CONFIG_NFS_LOCALIO */
 static inline void nfsd_localio_ops_init(void)
 {
 }
+static inline void nfs_to_nfsd_file_put_local(struct nfsd_file *localio)
+{
+}
 #endif  /* CONFIG_NFS_LOCALIO */
 
 #endif  /* __LINUX_NFSLOCALIO_H */
index b6321fc4915987bf773460530516feec75ef2451..52b5ea663b9f092a9628dc71009e1e9ffd3724bc 100644 (file)
                                         PCPU_MIN_ALLOC_SHIFT)
 
 #ifdef CONFIG_RANDOM_KMALLOC_CACHES
-#define PERCPU_DYNAMIC_SIZE_SHIFT      12
+# if defined(CONFIG_LOCKDEP) && !defined(CONFIG_PAGE_SIZE_4KB)
+# define PERCPU_DYNAMIC_SIZE_SHIFT      13
+# else
+# define PERCPU_DYNAMIC_SIZE_SHIFT      12
+#endif /* LOCKDEP and PAGE_SIZE > 4KiB */
 #else
 #define PERCPU_DYNAMIC_SIZE_SHIFT      10
 #endif
index 1b5a953c6bbc4bbf31037148d5b1185a238eaadf..3a74f69e0b599f95d3a0deed3ca64611a74b7a0a 100644 (file)
@@ -10,7 +10,7 @@
 #ifndef _PTP_CLASSIFY_H_
 #define _PTP_CLASSIFY_H_
 
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include <linux/ip.h>
 #include <linux/ktime.h>
 #include <linux/skbuff.h>
index e6ee4258169a0e17838b4d05ce38cac28056a95f..bb343136ddd05d178f9ca03d797c1da1ef5496d3 100644 (file)
@@ -1681,8 +1681,8 @@ extern struct pid *cad_pid;
                                                 * I am cleaning dirty pages from some other bdi. */
 #define PF_KTHREAD             0x00200000      /* I am a kernel thread */
 #define PF_RANDOMIZE           0x00400000      /* Randomize virtual address space */
-#define PF_MEMALLOC_NORECLAIM  0x00800000      /* All allocation requests will clear __GFP_DIRECT_RECLAIM */
-#define PF_MEMALLOC_NOWARN     0x01000000      /* All allocation requests will inherit __GFP_NOWARN */
+#define PF__HOLE__00800000     0x00800000
+#define PF__HOLE__01000000     0x01000000
 #define PF__HOLE__02000000     0x02000000
 #define PF_NO_SETAFFINITY      0x04000000      /* Userland is not allowed to meddle with cpus_mask */
 #define PF_MCE_EARLY           0x08000000      /* Early kill for mce process policy */
@@ -2133,6 +2133,11 @@ static inline void set_task_cpu(struct task_struct *p, unsigned int cpu)
 
 #endif /* CONFIG_SMP */
 
+static inline bool task_is_runnable(struct task_struct *p)
+{
+       return p->on_rq && !p->se.sched_delayed;
+}
+
 extern bool sched_task_on_rq(struct task_struct *p);
 extern unsigned long get_wchan(struct task_struct *p);
 extern struct task_struct *cpu_curr_snapshot(int cpu);
index 07bb8d4181d7ee6a03aeb3c7dea2a17773861c45..928a626725e69ab4ce4b3b14a2ffa832499d5055 100644 (file)
@@ -251,25 +251,16 @@ static inline gfp_t current_gfp_context(gfp_t flags)
 {
        unsigned int pflags = READ_ONCE(current->flags);
 
-       if (unlikely(pflags & (PF_MEMALLOC_NOIO |
-                              PF_MEMALLOC_NOFS |
-                              PF_MEMALLOC_NORECLAIM |
-                              PF_MEMALLOC_NOWARN |
-                              PF_MEMALLOC_PIN))) {
+       if (unlikely(pflags & (PF_MEMALLOC_NOIO | PF_MEMALLOC_NOFS | PF_MEMALLOC_PIN))) {
                /*
-                * Stronger flags before weaker flags:
-                * NORECLAIM implies NOIO, which in turn implies NOFS
+                * NOIO implies both NOIO and NOFS and it is a weaker context
+                * so always make sure it makes precedence
                 */
-               if (pflags & PF_MEMALLOC_NORECLAIM)
-                       flags &= ~__GFP_DIRECT_RECLAIM;
-               else if (pflags & PF_MEMALLOC_NOIO)
+               if (pflags & PF_MEMALLOC_NOIO)
                        flags &= ~(__GFP_IO | __GFP_FS);
                else if (pflags & PF_MEMALLOC_NOFS)
                        flags &= ~__GFP_FS;
 
-               if (pflags & PF_MEMALLOC_NOWARN)
-                       flags |= __GFP_NOWARN;
-
                if (pflags & PF_MEMALLOC_PIN)
                        flags &= ~__GFP_MOVABLE;
        }
index b86ec2afc69101e62ded7480a3feb6798d971c62..2ec8f3014757cd78ef0d961e77f42db409db3b1c 100644 (file)
@@ -348,7 +348,7 @@ int security_dentry_create_files_as(struct dentry *dentry, int mode,
                                        struct cred *new);
 int security_path_notify(const struct path *path, u64 mask,
                                        unsigned int obj_type);
-int security_inode_alloc(struct inode *inode);
+int security_inode_alloc(struct inode *inode, gfp_t gfp);
 void security_inode_free(struct inode *inode);
 int security_inode_init_security(struct inode *inode, struct inode *dir,
                                 const struct qstr *qstr,
@@ -789,7 +789,7 @@ static inline int security_path_notify(const struct path *path, u64 mask,
        return 0;
 }
 
-static inline int security_inode_alloc(struct inode *inode)
+static inline int security_inode_alloc(struct inode *inode, gfp_t gfp)
 {
        return 0;
 }
index c3bca9c0bf2cf52f96243b2e033213adb31adf95..2996a3c28ef3eb289ba9c3bd9a286e483bb0a997 100644 (file)
@@ -258,8 +258,8 @@ struct geni_se {
 #define RX_DMA_PARITY_ERR              BIT(5)
 #define RX_DMA_BREAK                   GENMASK(8, 7)
 #define RX_GENI_GP_IRQ                 GENMASK(10, 5)
-#define RX_GENI_CANCEL_IRQ             BIT(11)
 #define RX_GENI_GP_IRQ_EXT             GENMASK(13, 12)
+#define RX_GENI_CANCEL_IRQ             BIT(14)
 
 /* SE_HW_PARAM_0 fields */
 #define TX_FIFO_WIDTH_MSK              GENMASK(29, 24)
index 37ae69365fe263565321b1993f6319442d9ce013..734dc1fa3b5bc3227dedacf0486c8d71a38992d5 100644 (file)
@@ -227,7 +227,7 @@ struct sdw_intel_ops {
 /**
  * struct sdw_intel_acpi_info - Soundwire Intel information found in ACPI tables
  * @handle: ACPI controller handle
- * @count: link count found with "sdw-master-count" property
+ * @count: link count found with "sdw-master-count" or "sdw-manager-list" property
  * @link_mask: bit-wise mask listing links enabled by BIOS menu
  *
  * this structure could be expanded to e.g. provide all the _ADR
index 2f8dc47f1eb07504903318682a58ec8735ac4c5d..5f775e104f9ab0084f3a1aed50cc6bc97ef4056a 100644 (file)
@@ -13,7 +13,7 @@
 
 #include <linux/uio.h>
 #include <asm/byteorder.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include <linux/scatterlist.h>
 
 struct bio_vec;
index cf5e7e891a776289105ad72237408a7613b13240..2964171856e00d2c97a2af04c44e0f3aa16c2ce6 100644 (file)
@@ -14,11 +14,14 @@ init_task_work(struct callback_head *twork, task_work_func_t func)
 }
 
 enum task_work_notify_mode {
-       TWA_NONE,
+       TWA_NONE = 0,
        TWA_RESUME,
        TWA_SIGNAL,
        TWA_SIGNAL_NO_IPI,
        TWA_NMI_CURRENT,
+
+       TWA_FLAGS = 0xff00,
+       TWAF_NO_ALLOC = 0x0100,
 };
 
 static inline bool task_work_pending(struct task_struct *task)
index 72744638c5b0fdecf4158839c5d565ac8a666d24..99c9c5a7252aabd4808d3e5df15dab54f1d2ef75 100644 (file)
@@ -251,12 +251,19 @@ static inline void tick_dep_set_task(struct task_struct *tsk,
        if (tick_nohz_full_enabled())
                tick_nohz_dep_set_task(tsk, bit);
 }
+
 static inline void tick_dep_clear_task(struct task_struct *tsk,
                                       enum tick_dep_bits bit)
 {
        if (tick_nohz_full_enabled())
                tick_nohz_dep_clear_task(tsk, bit);
 }
+
+static inline void tick_dep_init_task(struct task_struct *tsk)
+{
+       atomic_set(&tsk->tick_dep_mask, 0);
+}
+
 static inline void tick_dep_set_signal(struct task_struct *tsk,
                                       enum tick_dep_bits bit)
 {
@@ -290,6 +297,7 @@ static inline void tick_dep_set_task(struct task_struct *tsk,
                                     enum tick_dep_bits bit) { }
 static inline void tick_dep_clear_task(struct task_struct *tsk,
                                       enum tick_dep_bits bit) { }
+static inline void tick_dep_init_task(struct task_struct *tsk) { }
 static inline void tick_dep_set_signal(struct task_struct *tsk,
                                       enum tick_dep_bits bit) { }
 static inline void tick_dep_clear_signal(struct signal_struct *signal,
index e93ee8d936a9c8508b62c29189277ea0890dcf54..587b96b4418ed95c855342ceb8bd4cae7a83a5b7 100644 (file)
@@ -537,7 +537,7 @@ int tpm_buf_check_hmac_response(struct tpm_chip *chip, struct tpm_buf *buf,
                                int rc);
 void tpm2_end_auth_session(struct tpm_chip *chip);
 #else
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 static inline int tpm2_start_auth_session(struct tpm_chip *chip)
 {
index 39c7cf82b0c22189517f9b10cd528fea121340b2..43844510d5d0facfcb08c7d32798fe7e0fdd804c 100644 (file)
@@ -38,6 +38,7 @@
 #else
  #define can_do_masked_user_access() 0
  #define masked_user_access_begin(src) NULL
+ #define mask_user_address(src) (src)
 #endif
 
 /*
@@ -159,19 +160,27 @@ _inline_copy_from_user(void *to, const void __user *from, unsigned long n)
 {
        unsigned long res = n;
        might_fault();
-       if (!should_fail_usercopy() && likely(access_ok(from, n))) {
+       if (should_fail_usercopy())
+               goto fail;
+       if (can_do_masked_user_access())
+               from = mask_user_address(from);
+       else {
+               if (!access_ok(from, n))
+                       goto fail;
                /*
                 * Ensure that bad access_ok() speculation will not
                 * lead to nasty side effects *after* the copy is
                 * finished:
                 */
                barrier_nospec();
-               instrument_copy_from_user_before(to, from, n);
-               res = raw_copy_from_user(to, from, n);
-               instrument_copy_from_user_after(to, from, n, res);
        }
-       if (unlikely(res))
-               memset(to + (n - res), 0, res);
+       instrument_copy_from_user_before(to, from, n);
+       res = raw_copy_from_user(to, from, n);
+       instrument_copy_from_user_after(to, from, n, res);
+       if (likely(!res))
+               return 0;
+fail:
+       memset(to + (n - res), 0, res);
        return res;
 }
 extern __must_check unsigned long
diff --git a/include/linux/unaligned.h b/include/linux/unaligned.h
new file mode 100644 (file)
index 0000000..4a96510
--- /dev/null
@@ -0,0 +1,146 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef __LINUX_UNALIGNED_H
+#define __LINUX_UNALIGNED_H
+
+/*
+ * This is the most generic implementation of unaligned accesses
+ * and should work almost anywhere.
+ */
+#include <linux/unaligned/packed_struct.h>
+#include <asm/byteorder.h>
+#include <vdso/unaligned.h>
+
+#define get_unaligned(ptr)     __get_unaligned_t(typeof(*(ptr)), (ptr))
+#define put_unaligned(val, ptr) __put_unaligned_t(typeof(*(ptr)), (val), (ptr))
+
+static inline u16 get_unaligned_le16(const void *p)
+{
+       return le16_to_cpu(__get_unaligned_t(__le16, p));
+}
+
+static inline u32 get_unaligned_le32(const void *p)
+{
+       return le32_to_cpu(__get_unaligned_t(__le32, p));
+}
+
+static inline u64 get_unaligned_le64(const void *p)
+{
+       return le64_to_cpu(__get_unaligned_t(__le64, p));
+}
+
+static inline void put_unaligned_le16(u16 val, void *p)
+{
+       __put_unaligned_t(__le16, cpu_to_le16(val), p);
+}
+
+static inline void put_unaligned_le32(u32 val, void *p)
+{
+       __put_unaligned_t(__le32, cpu_to_le32(val), p);
+}
+
+static inline void put_unaligned_le64(u64 val, void *p)
+{
+       __put_unaligned_t(__le64, cpu_to_le64(val), p);
+}
+
+static inline u16 get_unaligned_be16(const void *p)
+{
+       return be16_to_cpu(__get_unaligned_t(__be16, p));
+}
+
+static inline u32 get_unaligned_be32(const void *p)
+{
+       return be32_to_cpu(__get_unaligned_t(__be32, p));
+}
+
+static inline u64 get_unaligned_be64(const void *p)
+{
+       return be64_to_cpu(__get_unaligned_t(__be64, p));
+}
+
+static inline void put_unaligned_be16(u16 val, void *p)
+{
+       __put_unaligned_t(__be16, cpu_to_be16(val), p);
+}
+
+static inline void put_unaligned_be32(u32 val, void *p)
+{
+       __put_unaligned_t(__be32, cpu_to_be32(val), p);
+}
+
+static inline void put_unaligned_be64(u64 val, void *p)
+{
+       __put_unaligned_t(__be64, cpu_to_be64(val), p);
+}
+
+static inline u32 __get_unaligned_be24(const u8 *p)
+{
+       return p[0] << 16 | p[1] << 8 | p[2];
+}
+
+static inline u32 get_unaligned_be24(const void *p)
+{
+       return __get_unaligned_be24(p);
+}
+
+static inline u32 __get_unaligned_le24(const u8 *p)
+{
+       return p[0] | p[1] << 8 | p[2] << 16;
+}
+
+static inline u32 get_unaligned_le24(const void *p)
+{
+       return __get_unaligned_le24(p);
+}
+
+static inline void __put_unaligned_be24(const u32 val, u8 *p)
+{
+       *p++ = (val >> 16) & 0xff;
+       *p++ = (val >> 8) & 0xff;
+       *p++ = val & 0xff;
+}
+
+static inline void put_unaligned_be24(const u32 val, void *p)
+{
+       __put_unaligned_be24(val, p);
+}
+
+static inline void __put_unaligned_le24(const u32 val, u8 *p)
+{
+       *p++ = val & 0xff;
+       *p++ = (val >> 8) & 0xff;
+       *p++ = (val >> 16) & 0xff;
+}
+
+static inline void put_unaligned_le24(const u32 val, void *p)
+{
+       __put_unaligned_le24(val, p);
+}
+
+static inline void __put_unaligned_be48(const u64 val, u8 *p)
+{
+       *p++ = (val >> 40) & 0xff;
+       *p++ = (val >> 32) & 0xff;
+       *p++ = (val >> 24) & 0xff;
+       *p++ = (val >> 16) & 0xff;
+       *p++ = (val >> 8) & 0xff;
+       *p++ = val & 0xff;
+}
+
+static inline void put_unaligned_be48(const u64 val, void *p)
+{
+       __put_unaligned_be48(val, p);
+}
+
+static inline u64 __get_unaligned_be48(const u8 *p)
+{
+       return (u64)p[0] << 40 | (u64)p[1] << 32 | (u64)p[2] << 24 |
+               p[3] << 16 | p[4] << 8 | p[5];
+}
+
+static inline u64 get_unaligned_be48(const void *p)
+{
+       return __get_unaligned_be48(p);
+}
+
+#endif /* __LINUX_UNALIGNED_H */
index 9fc6ce15c499a4a221ab6220889fa0126c128746..cb40f1a1d0811d4e8122fe300a1d63eaa2db7214 100644 (file)
@@ -249,6 +249,7 @@ static inline bool vma_can_userfault(struct vm_area_struct *vma,
 
 extern int dup_userfaultfd(struct vm_area_struct *, struct list_head *);
 extern void dup_userfaultfd_complete(struct list_head *);
+void dup_userfaultfd_fail(struct list_head *);
 
 extern void mremap_userfaultfd_prep(struct vm_area_struct *,
                                    struct vm_userfaultfd_ctx *);
@@ -351,6 +352,10 @@ static inline void dup_userfaultfd_complete(struct list_head *l)
 {
 }
 
+static inline void dup_userfaultfd_fail(struct list_head *l)
+{
+}
+
 static inline void mremap_userfaultfd_prep(struct vm_area_struct *vma,
                                           struct vm_userfaultfd_ctx *ctx)
 {
index 276ca543ef44d862d095243073da4fdad88bb889..02a9f4dc594d02372a6c1850cd600eff9d000d8d 100644 (file)
@@ -103,8 +103,10 @@ static inline int virtio_net_hdr_to_skb(struct sk_buff *skb,
 
                if (!skb_partial_csum_set(skb, start, off))
                        return -EINVAL;
+               if (skb_transport_offset(skb) < nh_min_len)
+                       return -EINVAL;
 
-               nh_min_len = max_t(u32, nh_min_len, skb_transport_offset(skb));
+               nh_min_len = skb_transport_offset(skb);
                p_off = nh_min_len + thlen;
                if (!pskb_may_pull(skb, p_off))
                        return -EINVAL;
index 5d655e109b2c0a14146a620955d163a02efd4cba..f66bc85c6411dd5d49eca7756577fea05feaf144 100644 (file)
@@ -403,6 +403,7 @@ int  bt_sock_register(int proto, const struct net_proto_family *ops);
 void bt_sock_unregister(int proto);
 void bt_sock_link(struct bt_sock_list *l, struct sock *s);
 void bt_sock_unlink(struct bt_sock_list *l, struct sock *s);
+bool bt_sock_linked(struct bt_sock_list *l, struct sock *s);
 struct sock *bt_sock_alloc(struct net *net, struct socket *sock,
                           struct proto *prot, int proto, gfp_t prio, int kern);
 int  bt_sock_recvmsg(struct socket *sock, struct msghdr *msg, size_t len,
index 313d0b972e06441d0a79ad1b2c7687e4320e82b4..d9c767cf773de9a89da8e675f4daaf720fbe8980 100644 (file)
@@ -27,7 +27,7 @@
 #ifndef __L2CAP_H
 #define __L2CAP_H
 
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include <linux/atomic.h>
 
 /* L2CAP defaults */
index f8667a3fda9ee2797d493e2701913ef3c1f93d82..76b9e08c10c2144d474fc861077becf220ebdce6 100644 (file)
@@ -25,7 +25,7 @@
 #include <net/netlabel.h>
 #include <net/request_sock.h>
 #include <linux/refcount.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 /* known doi values */
 #define CALIPSO_DOI_UNKNOWN          0x00000000
index 69ec1eb41a0906ccd83e00dc052e46e2e2c58e4d..941dc62f3027ccf027e8d165a84012459c91cace 100644 (file)
@@ -6129,6 +6129,50 @@ void wiphy_delayed_work_cancel(struct wiphy *wiphy,
 void wiphy_delayed_work_flush(struct wiphy *wiphy,
                              struct wiphy_delayed_work *dwork);
 
+/**
+ * wiphy_delayed_work_pending - Find out whether a wiphy delayable
+ * work item is currently pending.
+ *
+ * @wiphy: the wiphy, for debug purposes
+ * @dwork: the delayed work in question
+ *
+ * Return: true if timer is pending, false otherwise
+ *
+ * How wiphy_delayed_work_queue() works is by setting a timer which
+ * when it expires calls wiphy_work_queue() to queue the wiphy work.
+ * Because wiphy_delayed_work_queue() uses mod_timer(), if it is
+ * called twice and the second call happens before the first call
+ * deadline, the work will rescheduled for the second deadline and
+ * won't run before that.
+ *
+ * wiphy_delayed_work_pending() can be used to detect if calling
+ * wiphy_work_delayed_work_queue() would start a new work schedule
+ * or delayed a previous one. As seen below it cannot be used to
+ * detect precisely if the work has finished to execute nor if it
+ * is currently executing.
+ *
+ *      CPU0                                CPU1
+ * wiphy_delayed_work_queue(wk)
+ *  mod_timer(wk->timer)
+ *                                     wiphy_delayed_work_pending(wk) -> true
+ *
+ * [...]
+ * expire_timers(wk->timer)
+ *  detach_timer(wk->timer)
+ *                                     wiphy_delayed_work_pending(wk) -> false
+ *  wk->timer->function()                          |
+ *   wiphy_work_queue(wk)                          | delayed work pending
+ *    list_add_tail()                              | returns false but
+ *    queue_work(cfg80211_wiphy_work)              | wk->func() has not
+ *                                                 | been run yet
+ * [...]                                           |
+ *  cfg80211_wiphy_work()                          |
+ *   wk->func()                                    V
+ *
+ */
+bool wiphy_delayed_work_pending(struct wiphy *wiphy,
+                               struct wiphy_delayed_work *dwork);
+
 /**
  * enum ieee80211_ap_reg_power - regulatory power for an Access Point
  *
index c9111bb2f59ba48bbd1d4786b5d86871b7fb149a..d6780d7903f4a1566e23ed9fb77f4f7f25391854 100644 (file)
@@ -28,7 +28,7 @@
 #include <net/request_sock.h>
 #include <linux/atomic.h>
 #include <linux/refcount.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 /* known doi values */
 #define CIPSO_V4_DOI_UNKNOWN          0x00000000
index 9ab49bfeae789afc11338ac1c89bb081566554a8..c1d91f1d20f6c9badde002fc0f412a3ce73a89c5 100644 (file)
@@ -531,13 +531,12 @@ static inline int genlmsg_multicast(const struct genl_family *family,
  * @skb: netlink message as socket buffer
  * @portid: own netlink portid to avoid sending to yourself
  * @group: offset of multicast group in groups array
- * @flags: allocation flags
  *
  * This function must hold the RTNL or rcu_read_lock().
  */
 int genlmsg_multicast_allns(const struct genl_family *family,
                            struct sk_buff *skb, u32 portid,
-                           unsigned int group, gfp_t flags);
+                           unsigned int group);
 
 /**
  * genlmsg_unicast - unicast a netlink message
index 91762faecc13d55508a77bd20265884609dcfa5f..813e163ce27cc394b38f86bcb64e259f319012a2 100644 (file)
 #define __RADIOTAP_H
 
 #include <linux/kernel.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 /**
  * struct ieee80211_radiotap_header - base radiotap header
  */
 struct ieee80211_radiotap_header {
-       /**
-        * @it_version: radiotap version, always 0
-        */
-       uint8_t it_version;
-
-       /**
-        * @it_pad: padding (or alignment)
-        */
-       uint8_t it_pad;
-
-       /**
-        * @it_len: overall radiotap header length
-        */
-       __le16 it_len;
-
-       /**
-        * @it_present: (first) present word
-        */
-       __le32 it_present;
+       __struct_group(ieee80211_radiotap_header_fixed, hdr, __packed,
+               /**
+                * @it_version: radiotap version, always 0
+                */
+               uint8_t it_version;
+
+               /**
+                * @it_pad: padding (or alignment)
+                */
+               uint8_t it_pad;
+
+               /**
+                * @it_len: overall radiotap header length
+                */
+               __le16 it_len;
+
+               /**
+                * @it_present: (first) present word
+                */
+               __le32 it_present;
+       );
 
        /**
         * @it_optional: all remaining presence bitmaps
@@ -50,6 +52,9 @@ struct ieee80211_radiotap_header {
        __le32 it_optional[];
 } __packed;
 
+static_assert(offsetof(struct ieee80211_radiotap_header, it_optional) == sizeof(struct ieee80211_radiotap_header_fixed),
+             "struct member likely outside of __struct_group()");
+
 /* version is always 0 */
 #define PKTHDR_RADIOTAP_VERSION        0
 
index 6194fbb564c6897d906a90b2e24d33827f5ca9fa..6a070478254d84c87a0ec80df2ea7efddb47cad5 100644 (file)
@@ -354,7 +354,7 @@ static inline void ip_tunnel_init_flow(struct flowi4 *fl4,
        memset(fl4, 0, sizeof(*fl4));
 
        if (oif) {
-               fl4->flowi4_l3mdev = l3mdev_master_upper_ifindex_by_index_rcu(net, oif);
+               fl4->flowi4_l3mdev = l3mdev_master_upper_ifindex_by_index(net, oif);
                /* Legacy VRF/l3mdev use case */
                fl4->flowi4_oif = fl4->flowi4_l3mdev ? 0 : oif;
        }
index 954dff901b697d3288162d5a6193872cbc5a68b4..333e0fae6796c8497ef481f573f5f3ed11f3cf43 100644 (file)
@@ -22,7 +22,7 @@
 #include <net/cfg80211.h>
 #include <net/codel.h>
 #include <net/ieee80211_radiotap.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 /**
  * DOC: Introduction
index 1b5488fa2ff0e0a13ce37dee6d8df464959a8569..d72006a85f0236e16c572ad29a6e803dcd69adb5 100644 (file)
@@ -7,7 +7,7 @@
 #ifndef NET_MAC802154_H
 #define NET_MAC802154_H
 
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include <net/af_ieee802154.h>
 #include <linux/ieee802154.h>
 #include <linux/skbuff.h>
index 7b17c52e8ce2a43b09f778874f8871a55bc1a098..28d59ae94ca3b486ccc86d05aed26e998ad50c4d 100644 (file)
@@ -295,7 +295,7 @@ void mctp_neigh_remove_dev(struct mctp_dev *mdev);
 int mctp_routes_init(void);
 void mctp_routes_exit(void);
 
-void mctp_device_init(void);
+int mctp_device_init(void);
 void mctp_device_exit(void);
 
 #endif /* __NET_MCTP_H */
index 49708e7e13395d3c67d42b7221b9fef9f337b869..91ae20cb76485b9e81db1928fd5d6489cd400d6a 100644 (file)
@@ -2,7 +2,7 @@
 #ifndef _NET_NF_TABLES_H
 #define _NET_NF_TABLES_H
 
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include <linux/list.h>
 #include <linux/netfilter.h>
 #include <linux/netfilter/nfnetlink.h>
index d489d9250bff9e3116e9423d4959fae2a94ccb1e..ae60d66640954c8f354c298a8aa0a59dbb5387e8 100644 (file)
@@ -51,7 +51,6 @@ struct netns_xfrm {
        struct hlist_head       *policy_byidx;
        unsigned int            policy_idx_hmask;
        unsigned int            idx_generator;
-       struct hlist_head       policy_inexact[XFRM_POLICY_MAX];
        struct xfrm_policy_hash policy_bydst[XFRM_POLICY_MAX];
        unsigned int            policy_count[XFRM_POLICY_MAX * 2];
        struct work_struct      policy_hash_work;
index b45d57b5968af4d17a1fc002a75a0923aefabf12..2d3eb7cb4dfff0f6f62b2d9a35b433ceaa6c5bfd 100644 (file)
@@ -29,6 +29,15 @@ static inline enum rtnl_kinds rtnl_msgtype_kind(int msgtype)
        return msgtype & RTNL_KIND_MASK;
 }
 
+struct rtnl_msg_handler {
+       struct module *owner;
+       int protocol;
+       int msgtype;
+       rtnl_doit_func doit;
+       rtnl_dumpit_func dumpit;
+       int flags;
+};
+
 void rtnl_register(int protocol, int msgtype,
                   rtnl_doit_func, rtnl_dumpit_func, unsigned int flags);
 int rtnl_register_module(struct module *owner, int protocol, int msgtype,
@@ -36,6 +45,14 @@ int rtnl_register_module(struct module *owner, int protocol, int msgtype,
 int rtnl_unregister(int protocol, int msgtype);
 void rtnl_unregister_all(int protocol);
 
+int __rtnl_register_many(const struct rtnl_msg_handler *handlers, int n);
+void __rtnl_unregister_many(const struct rtnl_msg_handler *handlers, int n);
+
+#define rtnl_register_many(handlers)                           \
+       __rtnl_register_many(handlers, ARRAY_SIZE(handlers))
+#define rtnl_unregister_many(handlers)                         \
+       __rtnl_unregister_many(handlers, ARRAY_SIZE(handlers))
+
 static inline int rtnl_msg_family(const struct nlmsghdr *nlh)
 {
        if (nlmsg_len(nlh) >= sizeof(struct rtgenmsg))
index 79edd5b5e3c9139cac0af251f95cc63e173d05f5..5d74fa7e694cc85be91dbf01f0876b9feaa29115 100644 (file)
@@ -848,7 +848,6 @@ static inline void qdisc_calculate_pkt_len(struct sk_buff *skb,
 static inline int qdisc_enqueue(struct sk_buff *skb, struct Qdisc *sch,
                                struct sk_buff **to_free)
 {
-       qdisc_calculate_pkt_len(skb, sch);
        return sch->enqueue(skb, sch, to_free);
 }
 
index c58ca8dd561b7312ffc0836585c04d9fe917a124..f29c14448938753799953be3b6231d2cc3d6ab02 100644 (file)
@@ -894,6 +894,8 @@ static inline void sk_add_bind_node(struct sock *sk,
        hlist_for_each_entry_safe(__sk, tmp, list, sk_node)
 #define sk_for_each_bound(__sk, list) \
        hlist_for_each_entry(__sk, list, sk_bind_node)
+#define sk_for_each_bound_safe(__sk, tmp, list) \
+       hlist_for_each_entry_safe(__sk, tmp, list, sk_bind_node)
 
 /**
  * sk_for_each_entry_offset_rcu - iterate over a list at a given struct offset
@@ -2715,6 +2717,11 @@ static inline bool sk_is_stream_unix(const struct sock *sk)
        return sk->sk_family == AF_UNIX && sk->sk_type == SOCK_STREAM;
 }
 
+static inline bool sk_is_vsock(const struct sock *sk)
+{
+       return sk->sk_family == AF_VSOCK;
+}
+
 /**
  * sk_eat_skb - Release a skb if it is no longer needed
  * @sk: socket to eat this skb from
index b6bfdc6416c797751a415e4498911c9faa96fbe4..a0bdd58f401c0f7ac15191e8c56878707cb98566 100644 (file)
@@ -349,20 +349,25 @@ struct xfrm_if_cb {
 void xfrm_if_register_cb(const struct xfrm_if_cb *ifcb);
 void xfrm_if_unregister_cb(void);
 
+struct xfrm_dst_lookup_params {
+       struct net *net;
+       int tos;
+       int oif;
+       xfrm_address_t *saddr;
+       xfrm_address_t *daddr;
+       u32 mark;
+       __u8 ipproto;
+       union flowi_uli uli;
+};
+
 struct net_device;
 struct xfrm_type;
 struct xfrm_dst;
 struct xfrm_policy_afinfo {
        struct dst_ops          *dst_ops;
-       struct dst_entry        *(*dst_lookup)(struct net *net,
-                                              int tos, int oif,
-                                              const xfrm_address_t *saddr,
-                                              const xfrm_address_t *daddr,
-                                              u32 mark);
-       int                     (*get_saddr)(struct net *net, int oif,
-                                            xfrm_address_t *saddr,
-                                            xfrm_address_t *daddr,
-                                            u32 mark);
+       struct dst_entry        *(*dst_lookup)(const struct xfrm_dst_lookup_params *params);
+       int                     (*get_saddr)(xfrm_address_t *saddr,
+                                            const struct xfrm_dst_lookup_params *params);
        int                     (*fill_dst)(struct xfrm_dst *xdst,
                                            struct net_device *dev,
                                            const struct flowi *fl);
@@ -1764,10 +1769,7 @@ static inline int xfrm_user_policy(struct sock *sk, int optname,
 }
 #endif
 
-struct dst_entry *__xfrm_dst_lookup(struct net *net, int tos, int oif,
-                                   const xfrm_address_t *saddr,
-                                   const xfrm_address_t *daddr,
-                                   int family, u32 mark);
+struct dst_entry *__xfrm_dst_lookup(int family, const struct xfrm_dst_lookup_params *params);
 
 struct xfrm_policy *xfrm_policy_alloc(struct net *net, gfp_t gfp);
 
index 8ae07c0ecdf7ef1711cfd91299ac5c1001346cdf..1c4c1a69937a2b107876aa04a3fc2f49d4733567 100644 (file)
@@ -7,7 +7,7 @@
 #define IB_HDRS_H
 
 #include <linux/types.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include <rdma/ib_verbs.h>
 
 #define IB_SEQ_NAK     (3 << 29)
index 6a1115b02a0db85577fa8516b24008d4556cdb6b..dcae154edc266b8a95b04e328027dfb19e3a7ab9 100644 (file)
@@ -7,7 +7,7 @@
 
 #include <linux/kernel.h>
 #include <linux/bitfield.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 static inline u32 _iba_get8(const u8 *ptr)
 {
index 8e6c60090c624fca373c8637828f2faa2ff8f31a..d02b55261307e244bcbcd7a016c6bdd5efaa4977 100644 (file)
@@ -12,7 +12,7 @@
 
 #include <linux/sched.h>
 #include <linux/bsg-lib.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include <scsi/scsi.h>
 #include <scsi/scsi_netlink.h>
 #include <scsi/scsi_host.h>
index 7e39d486374a66adae8aad920aeb07575f59975b..b098ceadbe74bff4999442f625dfe522a934101a 100644 (file)
@@ -590,7 +590,7 @@ void snd_hdac_stream_sync_trigger(struct hdac_stream *azx_dev, bool set,
 void snd_hdac_stream_sync(struct hdac_stream *azx_dev, bool start,
                          unsigned int streams);
 void snd_hdac_stream_timecounter_init(struct hdac_stream *azx_dev,
-                                     unsigned int streams);
+                                     unsigned int streams, bool start);
 int snd_hdac_get_stream_stripe_ctl(struct hdac_bus *bus,
                                struct snd_pcm_substream *substream);
 
index 739df993aa5e464bb84c692f83d4565e4aea362b..4063a701081b4403bed86b186d5510fd3578ff57 100644 (file)
@@ -3,7 +3,7 @@
 #define TARGET_CORE_BACKEND_H
 
 #include <linux/types.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include <target/target_core_base.h>
 
 #define TRANSPORT_FLAG_PASSTHROUGH             0x1
index 450c44c83a5d21bad22485efbb5734c47edb0125..a0aed1a428a18370140dcd29bebdcfc06ff2a994 100644 (file)
@@ -331,7 +331,11 @@ enum yfs_cm_operation {
        EM(afs_edit_dir_delete,                 "delete") \
        EM(afs_edit_dir_delete_error,           "d_err ") \
        EM(afs_edit_dir_delete_inval,           "d_invl") \
-       E_(afs_edit_dir_delete_noent,           "d_nent")
+       EM(afs_edit_dir_delete_noent,           "d_nent") \
+       EM(afs_edit_dir_update_dd,              "u_ddot") \
+       EM(afs_edit_dir_update_error,           "u_fail") \
+       EM(afs_edit_dir_update_inval,           "u_invl") \
+       E_(afs_edit_dir_update_nodd,            "u_nodd")
 
 #define afs_edit_dir_reasons                             \
        EM(afs_edit_dir_for_create,             "Create") \
@@ -340,6 +344,7 @@ enum yfs_cm_operation {
        EM(afs_edit_dir_for_rename_0,           "Renam0") \
        EM(afs_edit_dir_for_rename_1,           "Renam1") \
        EM(afs_edit_dir_for_rename_2,           "Renam2") \
+       EM(afs_edit_dir_for_rename_sub,         "RnmSub") \
        EM(afs_edit_dir_for_rmdir,              "RmDir ") \
        EM(afs_edit_dir_for_silly_0,            "S_Ren0") \
        EM(afs_edit_dir_for_silly_1,            "S_Ren1") \
index bf60ad50011e77e35565b872d18dfbc2ba228ba8..af6b3827fb1d01094f899d6d03e15cf62de2df02 100644 (file)
@@ -1716,7 +1716,7 @@ DECLARE_EVENT_CLASS(btrfs_qgroup_extent,
        ),
 
        TP_fast_assign_btrfs(fs_info,
-               __entry->bytenr         = rec->bytenr,
+               __entry->bytenr         = rec->bytenr;
                __entry->num_bytes      = rec->num_bytes;
        ),
 
index 569f86a44aaaf44e7dd7809ca328837bc559ec27..b0f41265191c398ad98db665ffa29662495aa974 100644 (file)
@@ -121,7 +121,7 @@ TRACE_EVENT(dma_alloc,
 
        TP_STRUCT__entry(
                __string(device, dev_name(dev))
-               __field(u64, phys_addr)
+               __field(void *, virt_addr)
                __field(u64, dma_addr)
                __field(size_t, size)
                __field(gfp_t, flags)
@@ -130,18 +130,18 @@ TRACE_EVENT(dma_alloc,
 
        TP_fast_assign(
                __assign_str(device);
-               __entry->phys_addr = virt_to_phys(virt_addr);
+               __entry->virt_addr = virt_addr;
                __entry->dma_addr = dma_addr;
                __entry->size = size;
                __entry->flags = flags;
                __entry->attrs = attrs;
        ),
 
-       TP_printk("%s dma_addr=%llx size=%zu phys_addr=%llx flags=%s attrs=%s",
+       TP_printk("%s dma_addr=%llx size=%zu virt_addr=%p flags=%s attrs=%s",
                __get_str(device),
                __entry->dma_addr,
                __entry->size,
-               __entry->phys_addr,
+               __entry->virt_addr,
                show_gfp_flags(__entry->flags),
                decode_dma_attrs(__entry->attrs))
 );
@@ -153,7 +153,7 @@ TRACE_EVENT(dma_free,
 
        TP_STRUCT__entry(
                __string(device, dev_name(dev))
-               __field(u64, phys_addr)
+               __field(void *, virt_addr)
                __field(u64, dma_addr)
                __field(size_t, size)
                __field(unsigned long, attrs)
@@ -161,17 +161,17 @@ TRACE_EVENT(dma_free,
 
        TP_fast_assign(
                __assign_str(device);
-               __entry->phys_addr = virt_to_phys(virt_addr);
+               __entry->virt_addr = virt_addr;
                __entry->dma_addr = dma_addr;
                __entry->size = size;
                __entry->attrs = attrs;
        ),
 
-       TP_printk("%s dma_addr=%llx size=%zu phys_addr=%llx attrs=%s",
+       TP_printk("%s dma_addr=%llx size=%zu virt_addr=%p attrs=%s",
                __get_str(device),
                __entry->dma_addr,
                __entry->size,
-               __entry->phys_addr,
+               __entry->virt_addr,
                decode_dma_attrs(__entry->attrs))
 );
 
index b5f5369b63009fd03d395027b40b1e0b867697b6..9d5c00b0285c3483d4aefde12fb24172678e9381 100644 (file)
@@ -208,7 +208,7 @@ TRACE_EVENT(mm_khugepaged_scan_file,
 
 TRACE_EVENT(mm_khugepaged_collapse_file,
        TP_PROTO(struct mm_struct *mm, struct folio *new_folio, pgoff_t index,
-                       bool is_shmem, unsigned long addr, struct file *file,
+                       unsigned long addr, bool is_shmem, struct file *file,
                        int nr, int result),
        TP_ARGS(mm, new_folio, index, addr, is_shmem, file, nr, result),
        TP_STRUCT__entry(
@@ -233,7 +233,7 @@ TRACE_EVENT(mm_khugepaged_collapse_file,
                __entry->result = result;
        ),
 
-       TP_printk("mm=%p, hpage_pfn=0x%lx, index=%ld, addr=%ld, is_shmem=%d, filename=%s, nr=%d, result=%s",
+       TP_printk("mm=%p, hpage_pfn=0x%lx, index=%ld, addr=%lx, is_shmem=%d, filename=%s, nr=%d, result=%s",
                __entry->mm,
                __entry->hpfn,
                __entry->index,
index 76bd42a968155d0ad1fabcc0505319b0ffde5700..69975c9c682393fc3185c283d1229adcff61f759 100644 (file)
        EM(netfs_folio_trace_read,              "read")         \
        EM(netfs_folio_trace_read_done,         "read-done")    \
        EM(netfs_folio_trace_read_gaps,         "read-gaps")    \
-       EM(netfs_folio_trace_read_put,          "read-put")     \
        EM(netfs_folio_trace_read_unlock,       "read-unlock")  \
        EM(netfs_folio_trace_redirtied,         "redirtied")    \
        EM(netfs_folio_trace_store,             "store")        \
@@ -448,7 +447,8 @@ TRACE_EVENT(netfs_folio,
                             ),
 
            TP_fast_assign(
-                   __entry->ino = folio->mapping->host->i_ino;
+                   struct address_space *__m = READ_ONCE(folio->mapping);
+                   __entry->ino = __m ? __m->host->i_ino : 0;
                    __entry->why = why;
                    __entry->index = folio_index(folio);
                    __entry->nr = folio_nr_pages(folio);
index c6cd7c7aeeee94f40675a237447d987971302e49..4a939c90dc2e4bce8c48212161d782acb4cb73a7 100644 (file)
@@ -1121,6 +1121,9 @@ enum bpf_attach_type {
 
 #define MAX_BPF_ATTACH_TYPE __MAX_BPF_ATTACH_TYPE
 
+/* Add BPF_LINK_TYPE(type, name) in bpf_types.h to keep bpf_link_type_strs[]
+ * in sync with the definitions below.
+ */
 enum bpf_link_type {
        BPF_LINK_TYPE_UNSPEC = 0,
        BPF_LINK_TYPE_RAW_TRACEPOINT = 1,
@@ -6047,11 +6050,6 @@ enum {
        BPF_F_MARK_ENFORCE              = (1ULL << 6),
 };
 
-/* BPF_FUNC_clone_redirect and BPF_FUNC_redirect flags. */
-enum {
-       BPF_F_INGRESS                   = (1ULL << 0),
-};
-
 /* BPF_FUNC_skb_set_tunnel_key and BPF_FUNC_skb_get_tunnel_key flags. */
 enum {
        BPF_F_TUNINFO_IPV6              = (1ULL << 0),
@@ -6198,10 +6196,12 @@ enum {
        BPF_F_BPRM_SECUREEXEC   = (1ULL << 0),
 };
 
-/* Flags for bpf_redirect_map helper */
+/* Flags for bpf_redirect and bpf_redirect_map helpers */
 enum {
-       BPF_F_BROADCAST         = (1ULL << 3),
-       BPF_F_EXCLUDE_INGRESS   = (1ULL << 4),
+       BPF_F_INGRESS           = (1ULL << 0), /* used for skb path */
+       BPF_F_BROADCAST         = (1ULL << 3), /* used for XDP path */
+       BPF_F_EXCLUDE_INGRESS   = (1ULL << 4), /* used for XDP path */
+#define BPF_F_REDIRECT_FLAGS (BPF_F_INGRESS | BPF_F_BROADCAST | BPF_F_EXCLUDE_INGRESS)
 };
 
 #define __bpf_md_ptr(type, name)       \
index d6476ca5d7a69d75bed048f0ac9a1cd06ce8b63f..9e9079321380ab7a302338d590309a0b6982c060 100644 (file)
@@ -1694,7 +1694,7 @@ enum nft_flowtable_flags {
  *
  * @NFTA_FLOWTABLE_TABLE: name of the table containing the expression (NLA_STRING)
  * @NFTA_FLOWTABLE_NAME: name of this flow table (NLA_STRING)
- * @NFTA_FLOWTABLE_HOOK: netfilter hook configuration(NLA_U32)
+ * @NFTA_FLOWTABLE_HOOK: netfilter hook configuration (NLA_NESTED)
  * @NFTA_FLOWTABLE_USE: number of references to this flow table (NLA_U32)
  * @NFTA_FLOWTABLE_HANDLE: object handle (NLA_U64)
  * @NFTA_FLOWTABLE_FLAGS: flags (NLA_U32)
index c8dc5f8ea699627402dc2069615acd066f103981..12873639ea9644ea7264e5577c672dae54643489 100644 (file)
 /* use ioctl encoding for uring command */
 #define UBLK_F_CMD_IOCTL_ENCODE        (1UL << 6)
 
-/* Copy between request and user buffer by pread()/pwrite() */
+/*
+ *  Copy between request and user buffer by pread()/pwrite()
+ *
+ *  Not available for UBLK_F_UNPRIVILEGED_DEV, otherwise userspace may
+ *  deceive us by not filling request buffer, then kernel uninitialized
+ *  data may be leaked.
+ */
 #define UBLK_F_USER_COPY       (1UL << 7)
 
 /*
index 99333cbd3114ec4026e3ab77d1dda5f93614dffa..c117672d44394c8493a5629a26b3ebbbab60ce87 100644 (file)
@@ -88,7 +88,7 @@
 
 /* ABI version */
 #define SND_SOC_TPLG_ABI_VERSION       0x5     /* current version */
-#define SND_SOC_TPLG_ABI_VERSION_MIN   0x4     /* oldest version supported */
+#define SND_SOC_TPLG_ABI_VERSION_MIN   0x5     /* oldest version supported */
 
 /* Max size of TLV data */
 #define SND_SOC_TPLG_TLV_SIZE          32
diff --git a/include/video/da8xx-fb.h b/include/video/da8xx-fb.h
deleted file mode 100644 (file)
index 1d19ae6..0000000
+++ /dev/null
@@ -1,94 +0,0 @@
-/*
- * Header file for TI DA8XX LCD controller platform data.
- *
- * Copyright (C) 2008-2009 MontaVista Software Inc.
- * Copyright (C) 2008-2009 Texas Instruments Inc
- *
- * This file is licensed under the terms of the GNU General Public License
- * version 2. This program is licensed "as is" without any warranty of any
- * kind, whether express or implied.
- */
-
-#ifndef DA8XX_FB_H
-#define DA8XX_FB_H
-
-enum panel_shade {
-       MONOCHROME = 0,
-       COLOR_ACTIVE,
-       COLOR_PASSIVE,
-};
-
-enum raster_load_mode {
-       LOAD_DATA = 1,
-       LOAD_PALETTE,
-};
-
-enum da8xx_frame_complete {
-       DA8XX_FRAME_WAIT,
-       DA8XX_FRAME_NOWAIT,
-};
-
-struct da8xx_lcdc_platform_data {
-       const char manu_name[10];
-       void *controller_data;
-       const char type[25];
-};
-
-struct lcd_ctrl_config {
-       enum panel_shade panel_shade;
-
-       /* AC Bias Pin Frequency */
-       int ac_bias;
-
-       /* AC Bias Pin Transitions per Interrupt */
-       int ac_bias_intrpt;
-
-       /* DMA burst size */
-       int dma_burst_sz;
-
-       /* Bits per pixel */
-       int bpp;
-
-       /* FIFO DMA Request Delay */
-       int fdd;
-
-       /* TFT Alternative Signal Mapping (Only for active) */
-       unsigned char tft_alt_mode;
-
-       /* 12 Bit Per Pixel (5-6-5) Mode (Only for passive) */
-       unsigned char stn_565_mode;
-
-       /* Mono 8-bit Mode: 1=D0-D7 or 0=D0-D3 */
-       unsigned char mono_8bit_mode;
-
-       /* Horizontal and Vertical Sync Edge: 0=rising 1=falling */
-       unsigned char sync_edge;
-
-       /* Raster Data Order Select: 1=Most-to-least 0=Least-to-most */
-       unsigned char raster_order;
-
-       /* DMA FIFO threshold */
-       int fifo_th;
-};
-
-struct lcd_sync_arg {
-       int back_porch;
-       int front_porch;
-       int pulse_width;
-};
-
-/* ioctls */
-#define FBIOGET_CONTRAST       _IOR('F', 1, int)
-#define FBIOPUT_CONTRAST       _IOW('F', 2, int)
-#define FBIGET_BRIGHTNESS      _IOR('F', 3, int)
-#define FBIPUT_BRIGHTNESS      _IOW('F', 3, int)
-#define FBIGET_COLOR           _IOR('F', 5, int)
-#define FBIPUT_COLOR           _IOW('F', 6, int)
-#define FBIPUT_HSYNC           _IOW('F', 9, int)
-#define FBIPUT_VSYNC           _IOW('F', 10, int)
-
-/* Proprietary FB_SYNC_ flags */
-#define FB_SYNC_CLK_INVERT 0x40000000
-
-#endif  /* ifndef DA8XX_FB_H */
-
index daa96a22d257e94a04d4322cf4c558a4274c16df..c66a8461612ea788a81adb554863d3b7db1202ed 100644 (file)
@@ -35,6 +35,8 @@
 
 #include <linux/types.h>
 
+typedef int (*get_gsi_from_sbdf_t)(u32 sbdf);
+
 #ifdef CONFIG_XEN_DOM0
 #include <asm/xen/hypervisor.h>
 #include <xen/xen.h>
@@ -72,6 +74,8 @@ int xen_acpi_get_gsi_info(struct pci_dev *dev,
                                                  int *gsi_out,
                                                  int *trigger_out,
                                                  int *polarity_out);
+void xen_acpi_register_get_gsi_func(get_gsi_from_sbdf_t func);
+int xen_acpi_get_gsi_from_sbdf(u32 sbdf);
 #else
 static inline void xen_acpi_sleep_register(void)
 {
@@ -89,12 +93,12 @@ static inline int xen_acpi_get_gsi_info(struct pci_dev *dev,
 {
        return -1;
 }
-#endif
 
-#ifdef CONFIG_XEN_PCI_STUB
-int pcistub_get_gsi_from_sbdf(unsigned int sbdf);
-#else
-static inline int pcistub_get_gsi_from_sbdf(unsigned int sbdf)
+static inline void xen_acpi_register_get_gsi_func(get_gsi_from_sbdf_t func)
+{
+}
+
+static inline int xen_acpi_get_gsi_from_sbdf(u32 sbdf)
 {
        return -1;
 }
index fbd0cb06a50a5f178e4a206e57011dc34698b458..c521e1421ad4abd80080bce8cf1c68389cb65c69 100644 (file)
@@ -62,7 +62,7 @@ config LLD_VERSION
 
 config RUSTC_VERSION
        int
-       default $(shell,$(srctree)/scripts/rustc-version.sh $(RUSTC))
+       default $(rustc-version)
        help
          It does not depend on `RUST` since that one may need to use the version
          in a `depends on`.
@@ -78,6 +78,10 @@ config RUST_IS_AVAILABLE
          In particular, the Makefile target 'rustavailable' is useful to check
          why the Rust toolchain is not being detected.
 
+config RUSTC_LLVM_VERSION
+       int
+       default $(rustc-llvm-version)
+
 config CC_CAN_LINK
        bool
        default $(success,$(srctree)/scripts/cc-can-link.sh $(CC) $(CLANG_FLAGS) $(USERCFLAGS) $(USERLDFLAGS) $(m64-flag)) if 64BIT
@@ -1946,10 +1950,11 @@ config RUST
        depends on !GCC_PLUGIN_RANDSTRUCT
        depends on !RANDSTRUCT
        depends on !DEBUG_INFO_BTF || PAHOLE_HAS_LANG_EXCLUDE
-       depends on !CFI_CLANG || RUSTC_VERSION >= 107900 && $(cc-option,-fsanitize=kcfi -fsanitize-cfi-icall-experimental-normalize-integers)
+       depends on !CFI_CLANG || HAVE_CFI_ICALL_NORMALIZE_INTEGERS_RUSTC
        select CFI_ICALL_NORMALIZE_INTEGERS if CFI_CLANG
-       depends on !CALL_PADDING || RUSTC_VERSION >= 108000
+       depends on !CALL_PADDING || RUSTC_VERSION >= 108100
        depends on !KASAN_SW_TAGS
+       depends on !(MITIGATION_RETHUNK && KASAN) || RUSTC_VERSION >= 108300
        help
          Enables Rust support in the kernel.
 
index feb61d68dca68e6f71461af9b7c293d05f7ecd7f..b2736e3491b86222fb78012866e40bab0a2b05bc 100644 (file)
@@ -321,7 +321,7 @@ static __cold struct io_ring_ctx *io_ring_ctx_alloc(struct io_uring_params *p)
                            sizeof(struct io_kiocb));
        ret |= io_futex_cache_init(ctx);
        if (ret)
-               goto err;
+               goto free_ref;
        init_completion(&ctx->ref_comp);
        xa_init_flags(&ctx->personalities, XA_FLAGS_ALLOC1);
        mutex_init(&ctx->uring_lock);
@@ -349,6 +349,9 @@ static __cold struct io_ring_ctx *io_ring_ctx_alloc(struct io_uring_params *p)
        io_napi_init(ctx);
 
        return ctx;
+
+free_ref:
+       percpu_ref_exit(&ctx->refs);
 err:
        io_alloc_cache_free(&ctx->rsrc_node_cache, kfree);
        io_alloc_cache_free(&ctx->apoll_cache, kfree);
@@ -2038,7 +2041,7 @@ static int io_init_req(struct io_ring_ctx *ctx, struct io_kiocb *req,
        req->opcode = opcode = READ_ONCE(sqe->opcode);
        /* same numerical values with corresponding REQ_F_*, safe to copy */
        sqe_flags = READ_ONCE(sqe->flags);
-       req->flags = (io_req_flags_t) sqe_flags;
+       req->flags = (__force io_req_flags_t) sqe_flags;
        req->cqe.user_data = READ_ONCE(sqe->user_data);
        req->file = NULL;
        req->rsrc_node = NULL;
index 9d70b2cf7b1ece54c1a2579000315bc22ecd1cb5..70b6675941ff765076a4cf33e6a41a8e69babda1 100644 (file)
@@ -284,7 +284,14 @@ static inline bool io_sqring_full(struct io_ring_ctx *ctx)
 {
        struct io_rings *r = ctx->rings;
 
-       return READ_ONCE(r->sq.tail) - ctx->cached_sq_head == ctx->sq_entries;
+       /*
+        * SQPOLL must use the actual sqring head, as using the cached_sq_head
+        * is race prone if the SQPOLL thread has grabbed entries but not yet
+        * committed them to the ring. For !SQPOLL, this doesn't matter, but
+        * since this helper is just used for SQPOLL sqring waits (or POLLOUT),
+        * just read the actual sqring head unconditionally.
+        */
+       return READ_ONCE(r->sq.tail) - READ_ONCE(r->sq.head) == ctx->sq_entries;
 }
 
 static inline unsigned int io_sqring_entries(struct io_ring_ctx *ctx)
@@ -320,6 +327,7 @@ static inline int io_run_task_work(void)
                if (current->io_uring) {
                        unsigned int count = 0;
 
+                       __set_current_state(TASK_RUNNING);
                        tctx_task_work_run(current->io_uring, UINT_MAX, &count);
                        if (count)
                                ret = true;
index f10f5a22d66aeec7de8fedcd97d8c7187bc0a558..18507658a921d7b38c57c7a9f5abac38d84e924c 100644 (file)
@@ -1133,6 +1133,7 @@ int io_recv(struct io_kiocb *req, unsigned int issue_flags)
        int ret, min_ret = 0;
        bool force_nonblock = issue_flags & IO_URING_F_NONBLOCK;
        size_t len = sr->len;
+       bool mshot_finished;
 
        if (!(req->flags & REQ_F_POLLED) &&
            (sr->flags & IORING_RECVSEND_POLL_FIRST))
@@ -1187,6 +1188,7 @@ out_free:
                req_set_fail(req);
        }
 
+       mshot_finished = ret <= 0;
        if (ret > 0)
                ret += sr->done_io;
        else if (sr->done_io)
@@ -1194,7 +1196,7 @@ out_free:
        else
                io_kbuf_recycle(req, issue_flags);
 
-       if (!io_recv_finish(req, &ret, kmsg, ret <= 0, issue_flags))
+       if (!io_recv_finish(req, &ret, kmsg, mshot_finished, issue_flags))
                goto retry_multishot;
 
        return ret;
index 33a3d156a85b14fa50f2c31d840f2fdbaabc8ca1..6f3b6de230bd2b43cf3f4c35ec6b431711a5c64b 100644 (file)
@@ -1176,7 +1176,8 @@ static int io_clone_buffers(struct io_ring_ctx *ctx, struct io_ring_ctx *src_ctx
        for (i = 0; i < nbufs; i++) {
                struct io_mapped_ubuf *src = src_ctx->user_bufs[i];
 
-               refcount_inc(&src->refs);
+               if (src != &dummy_ubuf)
+                       refcount_inc(&src->refs);
                user_bufs[i] = src;
        }
 
index f023ff49c6883cbe00aab4979e7c2fd115e5cad2..155938f1009313600271ceece223190e34b860b6 100644 (file)
@@ -31,9 +31,19 @@ struct io_rw {
        rwf_t                           flags;
 };
 
-static inline bool io_file_supports_nowait(struct io_kiocb *req)
+static bool io_file_supports_nowait(struct io_kiocb *req, __poll_t mask)
 {
-       return req->flags & REQ_F_SUPPORT_NOWAIT;
+       /* If FMODE_NOWAIT is set for a file, we're golden */
+       if (req->flags & REQ_F_SUPPORT_NOWAIT)
+               return true;
+       /* No FMODE_NOWAIT, if we can poll, check the status */
+       if (io_file_can_poll(req)) {
+               struct poll_table_struct pt = { ._key = mask };
+
+               return vfs_poll(req->file, &pt) & mask;
+       }
+       /* No FMODE_NOWAIT support, and file isn't pollable. Tough luck. */
+       return false;
 }
 
 #ifdef CONFIG_COMPAT
@@ -796,8 +806,8 @@ static int io_rw_init_file(struct io_kiocb *req, fmode_t mode, int rw_type)
         * supports async. Otherwise it's impossible to use O_NONBLOCK files
         * reliably. If not, or it IOCB_NOWAIT is set, don't retry.
         */
-       if ((kiocb->ki_flags & IOCB_NOWAIT) ||
-           ((file->f_flags & O_NONBLOCK) && !io_file_supports_nowait(req)))
+       if (kiocb->ki_flags & IOCB_NOWAIT ||
+           ((file->f_flags & O_NONBLOCK && !(req->flags & REQ_F_SUPPORT_NOWAIT))))
                req->flags |= REQ_F_NOWAIT;
 
        if (ctx->flags & IORING_SETUP_IOPOLL) {
@@ -838,7 +848,7 @@ static int __io_read(struct io_kiocb *req, unsigned int issue_flags)
 
        if (force_nonblock) {
                /* If the file doesn't support async, just async punt */
-               if (unlikely(!io_file_supports_nowait(req)))
+               if (unlikely(!io_file_supports_nowait(req, EPOLLIN)))
                        return -EAGAIN;
                kiocb->ki_flags |= IOCB_NOWAIT;
        } else {
@@ -951,13 +961,6 @@ int io_read_mshot(struct io_kiocb *req, unsigned int issue_flags)
 
        ret = __io_read(req, issue_flags);
 
-       /*
-        * If the file doesn't support proper NOWAIT, then disable multishot
-        * and stay in single shot mode.
-        */
-       if (!io_file_supports_nowait(req))
-               req->flags &= ~REQ_F_APOLL_MULTISHOT;
-
        /*
         * If we get -EAGAIN, recycle our buffer and just let normal poll
         * handling arm it.
@@ -972,14 +975,15 @@ int io_read_mshot(struct io_kiocb *req, unsigned int issue_flags)
                if (issue_flags & IO_URING_F_MULTISHOT)
                        return IOU_ISSUE_SKIP_COMPLETE;
                return -EAGAIN;
-       }
-
-       /*
-        * Any successful return value will keep the multishot read armed.
-        */
-       if (ret > 0 && req->flags & REQ_F_APOLL_MULTISHOT) {
+       } else if (ret <= 0) {
+               io_kbuf_recycle(req, issue_flags);
+               if (ret < 0)
+                       req_set_fail(req);
+       } else {
                /*
-                * Put our buffer and post a CQE. If we fail to post a CQE, then
+                * Any successful return value will keep the multishot read
+                * armed, if it's still set. Put our buffer and post a CQE. If
+                * we fail to post a CQE, or multishot is no longer set, then
                 * jump to the termination path. This request is then done.
                 */
                cflags = io_put_kbuf(req, ret, issue_flags);
@@ -1010,6 +1014,25 @@ int io_read_mshot(struct io_kiocb *req, unsigned int issue_flags)
        return IOU_OK;
 }
 
+static bool io_kiocb_start_write(struct io_kiocb *req, struct kiocb *kiocb)
+{
+       struct inode *inode;
+       bool ret;
+
+       if (!(req->flags & REQ_F_ISREG))
+               return true;
+       if (!(kiocb->ki_flags & IOCB_NOWAIT)) {
+               kiocb_start_write(kiocb);
+               return true;
+       }
+
+       inode = file_inode(kiocb->ki_filp);
+       ret = sb_start_write_trylock(inode->i_sb);
+       if (ret)
+               __sb_writers_release(inode->i_sb, SB_FREEZE_WRITE);
+       return ret;
+}
+
 int io_write(struct io_kiocb *req, unsigned int issue_flags)
 {
        bool force_nonblock = issue_flags & IO_URING_F_NONBLOCK;
@@ -1026,7 +1049,7 @@ int io_write(struct io_kiocb *req, unsigned int issue_flags)
 
        if (force_nonblock) {
                /* If the file doesn't support async, just async punt */
-               if (unlikely(!io_file_supports_nowait(req)))
+               if (unlikely(!io_file_supports_nowait(req, EPOLLOUT)))
                        goto ret_eagain;
 
                /* Check if we can support NOWAIT. */
@@ -1047,8 +1070,8 @@ int io_write(struct io_kiocb *req, unsigned int issue_flags)
        if (unlikely(ret))
                return ret;
 
-       if (req->flags & REQ_F_ISREG)
-               kiocb_start_write(kiocb);
+       if (unlikely(!io_kiocb_start_write(req, kiocb)))
+               return -EAGAIN;
        kiocb->ki_flags |= IOCB_WRITE;
 
        if (likely(req->file->f_op->write_iter))
index 6292ac5f9bd139dafb39ecd8bb180be46cd7c7fd..3bc61628ab251e05d7837eb27dabc3b62bcc4783 100644 (file)
@@ -339,10 +339,6 @@ BTF_ID(func, bpf_lsm_path_chmod)
 BTF_ID(func, bpf_lsm_path_chown)
 #endif /* CONFIG_SECURITY_PATH */
 
-#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)
index 75e4fe83c509107374db4651b26f9512b3b45b93..5cd1c7a23848cc19f5fefd7f589090fa47434273 100644 (file)
@@ -3523,7 +3523,7 @@ end:
  *   (i + 1) * elem_size
  * where i is the repeat index and elem_size is the size of an element.
  */
-static int btf_repeat_fields(struct btf_field_info *info,
+static int btf_repeat_fields(struct btf_field_info *info, int info_cnt,
                             u32 field_cnt, u32 repeat_cnt, u32 elem_size)
 {
        u32 i, j;
@@ -3543,6 +3543,12 @@ static int btf_repeat_fields(struct btf_field_info *info,
                }
        }
 
+       /* The type of struct size or variable size is u32,
+        * so the multiplication will not overflow.
+        */
+       if (field_cnt * (repeat_cnt + 1) > info_cnt)
+               return -E2BIG;
+
        cur = field_cnt;
        for (i = 0; i < repeat_cnt; i++) {
                memcpy(&info[cur], &info[0], field_cnt * sizeof(info[0]));
@@ -3587,7 +3593,7 @@ static int btf_find_nested_struct(const struct btf *btf, const struct btf_type *
                info[i].off += off;
 
        if (nelems > 1) {
-               err = btf_repeat_fields(info, ret, nelems - 1, t->size);
+               err = btf_repeat_fields(info, info_cnt, ret, nelems - 1, t->size);
                if (err == 0)
                        ret *= nelems;
                else
@@ -3681,10 +3687,10 @@ static int btf_find_field_one(const struct btf *btf,
 
        if (ret == BTF_FIELD_IGNORE)
                return 0;
-       if (nelems > info_cnt)
+       if (!info_cnt)
                return -E2BIG;
        if (nelems > 1) {
-               ret = btf_repeat_fields(info, 1, nelems - 1, sz);
+               ret = btf_repeat_fields(info, info_cnt, 1, nelems - 1, sz);
                if (ret < 0)
                        return ret;
        }
@@ -8961,6 +8967,7 @@ int bpf_core_apply(struct bpf_core_ctx *ctx, const struct bpf_core_relo *relo,
        if (!type) {
                bpf_log(ctx->log, "relo #%u: bad type id %u\n",
                        relo_idx, relo->type_id);
+               kfree(specs);
                return -EINVAL;
        }
 
index e7113d700b87848b4446e8ee38764c1ff904307d..025d7e2214aeb4ce4e45db48d9a0222a8b700c98 100644 (file)
 DEFINE_STATIC_KEY_ARRAY_FALSE(cgroup_bpf_enabled_key, MAX_CGROUP_BPF_ATTACH_TYPE);
 EXPORT_SYMBOL(cgroup_bpf_enabled_key);
 
+/*
+ * cgroup bpf destruction makes heavy use of work items and there can be a lot
+ * of concurrent destructions.  Use a separate workqueue so that cgroup bpf
+ * destruction work items don't end up filling up max_active of system_wq
+ * which may lead to deadlock.
+ */
+static struct workqueue_struct *cgroup_bpf_destroy_wq;
+
+static int __init cgroup_bpf_wq_init(void)
+{
+       cgroup_bpf_destroy_wq = alloc_workqueue("cgroup_bpf_destroy", 0, 1);
+       if (!cgroup_bpf_destroy_wq)
+               panic("Failed to alloc workqueue for cgroup bpf destroy.\n");
+       return 0;
+}
+core_initcall(cgroup_bpf_wq_init);
+
 /* __always_inline is necessary to prevent indirect call through run_prog
  * function pointer.
  */
@@ -334,7 +351,7 @@ static void cgroup_bpf_release_fn(struct percpu_ref *ref)
        struct cgroup *cgrp = container_of(ref, struct cgroup, bpf.refcnt);
 
        INIT_WORK(&cgrp->bpf.release_work, cgroup_bpf_release);
-       queue_work(system_wq, &cgrp->bpf.release_work);
+       queue_work(cgroup_bpf_destroy_wq, &cgrp->bpf.release_work);
 }
 
 /* Get underlying bpf_prog of bpf_prog_list entry, regardless if it's through
index 4e07cc057d6f2e534cb675789512dc324b2eacce..5e77c58e06010e48f0e247d86ec9cf0c773d69f9 100644 (file)
@@ -40,7 +40,7 @@
 #include <linux/execmem.h>
 
 #include <asm/barrier.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 /* Registers */
 #define BPF_R0 regs[BPF_REG_0]
index 9e0e3b0a18e406f0fd9a3d7a970c2a7d59cd04f5..7878be18e9d264d97b8e99b5a0847616174046de 100644 (file)
@@ -333,9 +333,11 @@ static int dev_map_hash_get_next_key(struct bpf_map *map, void *key,
 
 static int dev_map_bpf_prog_run(struct bpf_prog *xdp_prog,
                                struct xdp_frame **frames, int n,
-                               struct net_device *dev)
+                               struct net_device *tx_dev,
+                               struct net_device *rx_dev)
 {
-       struct xdp_txq_info txq = { .dev = dev };
+       struct xdp_txq_info txq = { .dev = tx_dev };
+       struct xdp_rxq_info rxq = { .dev = rx_dev };
        struct xdp_buff xdp;
        int i, nframes = 0;
 
@@ -346,6 +348,7 @@ static int dev_map_bpf_prog_run(struct bpf_prog *xdp_prog,
 
                xdp_convert_frame_to_buff(xdpf, &xdp);
                xdp.txq = &txq;
+               xdp.rxq = &rxq;
 
                act = bpf_prog_run_xdp(xdp_prog, &xdp);
                switch (act) {
@@ -360,7 +363,7 @@ static int dev_map_bpf_prog_run(struct bpf_prog *xdp_prog,
                        bpf_warn_invalid_xdp_action(NULL, xdp_prog, act);
                        fallthrough;
                case XDP_ABORTED:
-                       trace_xdp_exception(dev, xdp_prog, act);
+                       trace_xdp_exception(tx_dev, xdp_prog, act);
                        fallthrough;
                case XDP_DROP:
                        xdp_return_frame_rx_napi(xdpf);
@@ -388,7 +391,7 @@ static void bq_xmit_all(struct xdp_dev_bulk_queue *bq, u32 flags)
        }
 
        if (bq->xdp_prog) {
-               to_send = dev_map_bpf_prog_run(bq->xdp_prog, bq->q, cnt, dev);
+               to_send = dev_map_bpf_prog_run(bq->xdp_prog, bq->q, cnt, dev, bq->dev_rx);
                if (!to_send)
                        goto out;
        }
index 1a43d06eab286c26e80be35ff2c6f426de3cf66a..3d45ebe8afb48dcbde3cfe6b88a1e02bc382f743 100644 (file)
@@ -111,7 +111,7 @@ const struct bpf_func_proto bpf_map_pop_elem_proto = {
        .gpl_only       = false,
        .ret_type       = RET_INTEGER,
        .arg1_type      = ARG_CONST_MAP_PTR,
-       .arg2_type      = ARG_PTR_TO_MAP_VALUE | MEM_UNINIT,
+       .arg2_type      = ARG_PTR_TO_MAP_VALUE | MEM_UNINIT | MEM_WRITE,
 };
 
 BPF_CALL_2(bpf_map_peek_elem, struct bpf_map *, map, void *, value)
@@ -124,7 +124,7 @@ const struct bpf_func_proto bpf_map_peek_elem_proto = {
        .gpl_only       = false,
        .ret_type       = RET_INTEGER,
        .arg1_type      = ARG_CONST_MAP_PTR,
-       .arg2_type      = ARG_PTR_TO_MAP_VALUE | MEM_UNINIT,
+       .arg2_type      = ARG_PTR_TO_MAP_VALUE | MEM_UNINIT | MEM_WRITE,
 };
 
 BPF_CALL_3(bpf_map_lookup_percpu_elem, struct bpf_map *, map, void *, key, u32, cpu)
@@ -538,7 +538,7 @@ const struct bpf_func_proto bpf_strtol_proto = {
        .arg1_type      = ARG_PTR_TO_MEM | MEM_RDONLY,
        .arg2_type      = ARG_CONST_SIZE,
        .arg3_type      = ARG_ANYTHING,
-       .arg4_type      = ARG_PTR_TO_FIXED_SIZE_MEM | MEM_UNINIT | MEM_ALIGNED,
+       .arg4_type      = ARG_PTR_TO_FIXED_SIZE_MEM | MEM_UNINIT | MEM_WRITE | MEM_ALIGNED,
        .arg4_size      = sizeof(s64),
 };
 
@@ -566,7 +566,7 @@ const struct bpf_func_proto bpf_strtoul_proto = {
        .arg1_type      = ARG_PTR_TO_MEM | MEM_RDONLY,
        .arg2_type      = ARG_CONST_SIZE,
        .arg3_type      = ARG_ANYTHING,
-       .arg4_type      = ARG_PTR_TO_FIXED_SIZE_MEM | MEM_UNINIT | MEM_ALIGNED,
+       .arg4_type      = ARG_PTR_TO_FIXED_SIZE_MEM | MEM_UNINIT | MEM_WRITE | MEM_ALIGNED,
        .arg4_size      = sizeof(u64),
 };
 
@@ -1742,7 +1742,7 @@ static const struct bpf_func_proto bpf_dynptr_from_mem_proto = {
        .arg1_type      = ARG_PTR_TO_UNINIT_MEM,
        .arg2_type      = ARG_CONST_SIZE_OR_ZERO,
        .arg3_type      = ARG_ANYTHING,
-       .arg4_type      = ARG_PTR_TO_DYNPTR | DYNPTR_TYPE_LOCAL | MEM_UNINIT,
+       .arg4_type      = ARG_PTR_TO_DYNPTR | DYNPTR_TYPE_LOCAL | MEM_UNINIT | MEM_WRITE,
 };
 
 BPF_CALL_5(bpf_dynptr_read, void *, dst, u32, len, const struct bpf_dynptr_kern *, src,
@@ -2851,21 +2851,47 @@ struct bpf_iter_bits {
        __u64 __opaque[2];
 } __aligned(8);
 
+#define BITS_ITER_NR_WORDS_MAX 511
+
 struct bpf_iter_bits_kern {
        union {
-               unsigned long *bits;
-               unsigned long bits_copy;
+               __u64 *bits;
+               __u64 bits_copy;
        };
-       u32 nr_bits;
+       int nr_bits;
        int bit;
 } __aligned(8);
 
+/* On 64-bit hosts, unsigned long and u64 have the same size, so passing
+ * a u64 pointer and an unsigned long pointer to find_next_bit() will
+ * return the same result, as both point to the same 8-byte area.
+ *
+ * For 32-bit little-endian hosts, using a u64 pointer or unsigned long
+ * pointer also makes no difference. This is because the first iterated
+ * unsigned long is composed of bits 0-31 of the u64 and the second unsigned
+ * long is composed of bits 32-63 of the u64.
+ *
+ * However, for 32-bit big-endian hosts, this is not the case. The first
+ * iterated unsigned long will be bits 32-63 of the u64, so swap these two
+ * ulong values within the u64.
+ */
+static void swap_ulong_in_u64(u64 *bits, unsigned int nr)
+{
+#if (BITS_PER_LONG == 32) && defined(__BIG_ENDIAN)
+       unsigned int i;
+
+       for (i = 0; i < nr; i++)
+               bits[i] = (bits[i] >> 32) | ((u64)(u32)bits[i] << 32);
+#endif
+}
+
 /**
  * bpf_iter_bits_new() - Initialize a new bits iterator for a given memory area
  * @it: The new bpf_iter_bits to be created
  * @unsafe_ptr__ign: A pointer pointing to a memory area to be iterated over
  * @nr_words: The size of the specified memory area, measured in 8-byte units.
- * Due to the limitation of memalloc, it can't be greater than 512.
+ * The maximum value of @nr_words is @BITS_ITER_NR_WORDS_MAX. This limit may be
+ * further reduced by the BPF memory allocator implementation.
  *
  * This function initializes a new bpf_iter_bits structure for iterating over
  * a memory area which is specified by the @unsafe_ptr__ign and @nr_words. It
@@ -2892,6 +2918,8 @@ bpf_iter_bits_new(struct bpf_iter_bits *it, const u64 *unsafe_ptr__ign, u32 nr_w
 
        if (!unsafe_ptr__ign || !nr_words)
                return -EINVAL;
+       if (nr_words > BITS_ITER_NR_WORDS_MAX)
+               return -E2BIG;
 
        /* Optimization for u64 mask */
        if (nr_bits == 64) {
@@ -2899,10 +2927,15 @@ bpf_iter_bits_new(struct bpf_iter_bits *it, const u64 *unsafe_ptr__ign, u32 nr_w
                if (err)
                        return -EFAULT;
 
+               swap_ulong_in_u64(&kit->bits_copy, nr_words);
+
                kit->nr_bits = nr_bits;
                return 0;
        }
 
+       if (bpf_mem_alloc_check_size(false, nr_bytes))
+               return -E2BIG;
+
        /* Fallback to memalloc */
        kit->bits = bpf_mem_alloc(&bpf_global_ma, nr_bytes);
        if (!kit->bits)
@@ -2914,6 +2947,8 @@ bpf_iter_bits_new(struct bpf_iter_bits *it, const u64 *unsafe_ptr__ign, u32 nr_w
                return err;
        }
 
+       swap_ulong_in_u64(kit->bits, nr_words);
+
        kit->nr_bits = nr_bits;
        return 0;
 }
@@ -2930,17 +2965,16 @@ bpf_iter_bits_new(struct bpf_iter_bits *it, const u64 *unsafe_ptr__ign, u32 nr_w
 __bpf_kfunc int *bpf_iter_bits_next(struct bpf_iter_bits *it)
 {
        struct bpf_iter_bits_kern *kit = (void *)it;
-       u32 nr_bits = kit->nr_bits;
-       const unsigned long *bits;
-       int bit;
+       int bit = kit->bit, nr_bits = kit->nr_bits;
+       const void *bits;
 
-       if (nr_bits == 0)
+       if (!nr_bits || bit >= nr_bits)
                return NULL;
 
        bits = nr_bits == 64 ? &kit->bits_copy : kit->bits;
-       bit = find_next_bit(bits, nr_bits, kit->bit + 1);
+       bit = find_next_bit(bits, nr_bits, bit + 1);
        if (bit >= nr_bits) {
-               kit->nr_bits = 0;
+               kit->bit = bit;
                return NULL;
        }
 
index d8fc5eba529dca1aa5802801c7339e111101180a..9aaf5124648bdabedd3b775c6d4bca9d27f5f4d4 100644 (file)
@@ -880,7 +880,7 @@ static int bpf_parse_param(struct fs_context *fc, struct fs_parameter *param)
                const struct btf_type *enum_t;
                const char *enum_pfx;
                u64 *delegate_msk, msk = 0;
-               char *p;
+               char *p, *str;
                int val;
 
                /* ignore errors, fallback to hex */
@@ -911,7 +911,8 @@ static int bpf_parse_param(struct fs_context *fc, struct fs_parameter *param)
                        return -EINVAL;
                }
 
-               while ((p = strsep(&param->string, ":"))) {
+               str = param->string;
+               while ((p = strsep(&str, ":"))) {
                        if (strcmp(p, "any") == 0) {
                                msk |= ~0ULL;
                        } else if (find_btf_enum_const(info.btf, enum_t, enum_pfx, p, &val)) {
index 5aebfc3051e3a63b84620283a98c6cd73949b56d..4a858fdb6476f894d1259a091477ca5d893f8992 100644 (file)
@@ -688,8 +688,7 @@ static void print_reg_state(struct bpf_verifier_env *env,
        if (t == SCALAR_VALUE && reg->precise)
                verbose(env, "P");
        if (t == SCALAR_VALUE && tnum_is_const(reg->var_off)) {
-               /* reg->off should be 0 for SCALAR_VALUE */
-               verbose_snum(env, reg->var_off.value + reg->off);
+               verbose_snum(env, reg->var_off.value);
                return;
        }
 
index 0218a5132ab562088e1821fffb5cb80294cef150..9b60eda0f727b36aee2b5a82f946a78a3e85fbce 100644 (file)
@@ -655,7 +655,7 @@ static int trie_get_next_key(struct bpf_map *map, void *_key, void *_next_key)
        if (!key || key->prefixlen > trie->max_prefixlen)
                goto find_leftmost;
 
-       node_stack = kmalloc_array(trie->max_prefixlen,
+       node_stack = kmalloc_array(trie->max_prefixlen + 1,
                                   sizeof(struct lpm_trie_node *),
                                   GFP_ATOMIC | __GFP_NOWARN);
        if (!node_stack)
index b3858a76e0b35891342810f9eb6cdcacf9690d9b..146f5b57cfb1cbffd7bb95aaeb01884f62ec6ab5 100644 (file)
@@ -35,6 +35,8 @@
  */
 #define LLIST_NODE_SZ sizeof(struct llist_node)
 
+#define BPF_MEM_ALLOC_SIZE_MAX 4096
+
 /* similar to kmalloc, but sizeof == 8 bucket is gone */
 static u8 size_index[24] __ro_after_init = {
        3,      /* 8 */
@@ -65,7 +67,7 @@ static u8 size_index[24] __ro_after_init = {
 
 static int bpf_mem_cache_idx(size_t size)
 {
-       if (!size || size > 4096)
+       if (!size || size > BPF_MEM_ALLOC_SIZE_MAX)
                return -1;
 
        if (size <= 192)
@@ -1005,3 +1007,13 @@ void notrace *bpf_mem_cache_alloc_flags(struct bpf_mem_alloc *ma, gfp_t flags)
 
        return !ret ? NULL : ret + LLIST_NODE_SZ;
 }
+
+int bpf_mem_alloc_check_size(bool percpu, size_t size)
+{
+       /* The size of percpu allocation doesn't have LLIST_NODE_SZ overhead */
+       if ((percpu && size > BPF_MEM_ALLOC_SIZE_MAX) ||
+           (!percpu && size > BPF_MEM_ALLOC_SIZE_MAX - LLIST_NODE_SZ))
+               return -E2BIG;
+
+       return 0;
+}
index e20b90c3613169facc3136c28c89cb965a27dcfc..e1cfe890e0be6486385c4e81816919f4d9170413 100644 (file)
@@ -29,7 +29,7 @@ struct bpf_ringbuf {
        u64 mask;
        struct page **pages;
        int nr_pages;
-       spinlock_t spinlock ____cacheline_aligned_in_smp;
+       raw_spinlock_t spinlock ____cacheline_aligned_in_smp;
        /* For user-space producer ring buffers, an atomic_t busy bit is used
         * to synchronize access to the ring buffers in the kernel, rather than
         * the spinlock that is used for kernel-producer ring buffers. This is
@@ -173,7 +173,7 @@ static struct bpf_ringbuf *bpf_ringbuf_alloc(size_t data_sz, int numa_node)
        if (!rb)
                return NULL;
 
-       spin_lock_init(&rb->spinlock);
+       raw_spin_lock_init(&rb->spinlock);
        atomic_set(&rb->busy, 0);
        init_waitqueue_head(&rb->waitq);
        init_irq_work(&rb->work, bpf_ringbuf_notify);
@@ -421,10 +421,10 @@ static void *__bpf_ringbuf_reserve(struct bpf_ringbuf *rb, u64 size)
        cons_pos = smp_load_acquire(&rb->consumer_pos);
 
        if (in_nmi()) {
-               if (!spin_trylock_irqsave(&rb->spinlock, flags))
+               if (!raw_spin_trylock_irqsave(&rb->spinlock, flags))
                        return NULL;
        } else {
-               spin_lock_irqsave(&rb->spinlock, flags);
+               raw_spin_lock_irqsave(&rb->spinlock, flags);
        }
 
        pend_pos = rb->pending_pos;
@@ -450,7 +450,7 @@ static void *__bpf_ringbuf_reserve(struct bpf_ringbuf *rb, u64 size)
         */
        if (new_prod_pos - cons_pos > rb->mask ||
            new_prod_pos - pend_pos > rb->mask) {
-               spin_unlock_irqrestore(&rb->spinlock, flags);
+               raw_spin_unlock_irqrestore(&rb->spinlock, flags);
                return NULL;
        }
 
@@ -462,7 +462,7 @@ static void *__bpf_ringbuf_reserve(struct bpf_ringbuf *rb, u64 size)
        /* pairs with consumer's smp_load_acquire() */
        smp_store_release(&rb->producer_pos, new_prod_pos);
 
-       spin_unlock_irqrestore(&rb->spinlock, flags);
+       raw_spin_unlock_irqrestore(&rb->spinlock, flags);
 
        return (void *)hdr + BPF_RINGBUF_HDR_SZ;
 }
@@ -632,7 +632,7 @@ const struct bpf_func_proto bpf_ringbuf_reserve_dynptr_proto = {
        .arg1_type      = ARG_CONST_MAP_PTR,
        .arg2_type      = ARG_ANYTHING,
        .arg3_type      = ARG_ANYTHING,
-       .arg4_type      = ARG_PTR_TO_DYNPTR | DYNPTR_TYPE_RINGBUF | MEM_UNINIT,
+       .arg4_type      = ARG_PTR_TO_DYNPTR | DYNPTR_TYPE_RINGBUF | MEM_UNINIT | MEM_WRITE,
 };
 
 BPF_CALL_2(bpf_ringbuf_submit_dynptr, struct bpf_dynptr_kern *, ptr, u64, flags)
index a8f1808a1ca54371d5b1fbc85c0290055e62bd4a..c5aa127ed4cc0149443222970a7ad67e2d86667c 100644 (file)
@@ -3069,13 +3069,17 @@ static void bpf_link_show_fdinfo(struct seq_file *m, struct file *filp)
 {
        const struct bpf_link *link = filp->private_data;
        const struct bpf_prog *prog = link->prog;
+       enum bpf_link_type type = link->type;
        char prog_tag[sizeof(prog->tag) * 2 + 1] = { };
 
-       seq_printf(m,
-                  "link_type:\t%s\n"
-                  "link_id:\t%u\n",
-                  bpf_link_type_strs[link->type],
-                  link->id);
+       if (type < ARRAY_SIZE(bpf_link_type_strs) && bpf_link_type_strs[type]) {
+               seq_printf(m, "link_type:\t%s\n", bpf_link_type_strs[type]);
+       } else {
+               WARN_ONCE(1, "missing BPF_LINK_TYPE(...) for link type %u\n", type);
+               seq_printf(m, "link_type:\t<%u>\n", type);
+       }
+       seq_printf(m, "link_id:\t%u\n", link->id);
+
        if (prog) {
                bin2hex(prog_tag, prog->tag, sizeof(prog->tag));
                seq_printf(m,
@@ -3565,15 +3569,16 @@ static void bpf_perf_link_dealloc(struct bpf_link *link)
 }
 
 static int bpf_perf_link_fill_common(const struct perf_event *event,
-                                    char __user *uname, u32 ulen,
+                                    char __user *uname, u32 *ulenp,
                                     u64 *probe_offset, u64 *probe_addr,
                                     u32 *fd_type, unsigned long *missed)
 {
        const char *buf;
-       u32 prog_id;
+       u32 prog_id, ulen;
        size_t len;
        int err;
 
+       ulen = *ulenp;
        if (!ulen ^ !uname)
                return -EINVAL;
 
@@ -3581,10 +3586,17 @@ static int bpf_perf_link_fill_common(const struct perf_event *event,
                                      probe_offset, probe_addr, missed);
        if (err)
                return err;
+
+       if (buf) {
+               len = strlen(buf);
+               *ulenp = len + 1;
+       } else {
+               *ulenp = 1;
+       }
        if (!uname)
                return 0;
+
        if (buf) {
-               len = strlen(buf);
                err = bpf_copy_to_user(uname, buf, ulen, len);
                if (err)
                        return err;
@@ -3609,7 +3621,7 @@ static int bpf_perf_link_fill_kprobe(const struct perf_event *event,
 
        uname = u64_to_user_ptr(info->perf_event.kprobe.func_name);
        ulen = info->perf_event.kprobe.name_len;
-       err = bpf_perf_link_fill_common(event, uname, ulen, &offset, &addr,
+       err = bpf_perf_link_fill_common(event, uname, &ulen, &offset, &addr,
                                        &type, &missed);
        if (err)
                return err;
@@ -3617,7 +3629,7 @@ static int bpf_perf_link_fill_kprobe(const struct perf_event *event,
                info->perf_event.type = BPF_PERF_EVENT_KRETPROBE;
        else
                info->perf_event.type = BPF_PERF_EVENT_KPROBE;
-
+       info->perf_event.kprobe.name_len = ulen;
        info->perf_event.kprobe.offset = offset;
        info->perf_event.kprobe.missed = missed;
        if (!kallsyms_show_value(current_cred()))
@@ -3639,7 +3651,7 @@ static int bpf_perf_link_fill_uprobe(const struct perf_event *event,
 
        uname = u64_to_user_ptr(info->perf_event.uprobe.file_name);
        ulen = info->perf_event.uprobe.name_len;
-       err = bpf_perf_link_fill_common(event, uname, ulen, &offset, &addr,
+       err = bpf_perf_link_fill_common(event, uname, &ulen, &offset, &addr,
                                        &type, NULL);
        if (err)
                return err;
@@ -3648,6 +3660,7 @@ static int bpf_perf_link_fill_uprobe(const struct perf_event *event,
                info->perf_event.type = BPF_PERF_EVENT_URETPROBE;
        else
                info->perf_event.type = BPF_PERF_EVENT_UPROBE;
+       info->perf_event.uprobe.name_len = ulen;
        info->perf_event.uprobe.offset = offset;
        info->perf_event.uprobe.cookie = event->bpf_cookie;
        return 0;
@@ -3673,12 +3686,18 @@ static int bpf_perf_link_fill_tracepoint(const struct perf_event *event,
 {
        char __user *uname;
        u32 ulen;
+       int err;
 
        uname = u64_to_user_ptr(info->perf_event.tracepoint.tp_name);
        ulen = info->perf_event.tracepoint.name_len;
+       err = bpf_perf_link_fill_common(event, uname, &ulen, NULL, NULL, NULL, NULL);
+       if (err)
+               return err;
+
        info->perf_event.type = BPF_PERF_EVENT_TRACEPOINT;
+       info->perf_event.tracepoint.name_len = ulen;
        info->perf_event.tracepoint.cookie = event->bpf_cookie;
-       return bpf_perf_link_fill_common(event, uname, ulen, NULL, NULL, NULL, NULL);
+       return 0;
 }
 
 static int bpf_perf_link_fill_perf_event(const struct perf_event *event,
@@ -5877,7 +5896,7 @@ static const struct bpf_func_proto bpf_kallsyms_lookup_name_proto = {
        .arg1_type      = ARG_PTR_TO_MEM,
        .arg2_type      = ARG_CONST_SIZE_OR_ZERO,
        .arg3_type      = ARG_ANYTHING,
-       .arg4_type      = ARG_PTR_TO_FIXED_SIZE_MEM | MEM_UNINIT | MEM_ALIGNED,
+       .arg4_type      = ARG_PTR_TO_FIXED_SIZE_MEM | MEM_UNINIT | MEM_WRITE | MEM_ALIGNED,
        .arg4_size      = sizeof(u64),
 };
 
index 02aa9db8d79616d3e0ebe62622a8738f41d34f28..5af9e130e500fa0a397760168c014b570ec8b260 100644 (file)
@@ -99,7 +99,7 @@ static struct task_struct *task_seq_get_next(struct bpf_iter_seq_task_common *co
                rcu_read_lock();
                pid = find_pid_ns(common->pid, common->ns);
                if (pid) {
-                       task = get_pid_task(pid, PIDTYPE_TGID);
+                       task = get_pid_task(pid, PIDTYPE_PID);
                        *tid = common->pid;
                }
                rcu_read_unlock();
index 9a7ed527e47e343070cf9ccb899ee1fc6fcfdd49..bb99bada7e2ed29071fc5a34e9f65c8704277a81 100644 (file)
@@ -2750,10 +2750,16 @@ static struct btf *__find_kfunc_desc_btf(struct bpf_verifier_env *env,
                b->module = mod;
                b->offset = offset;
 
+               /* sort() reorders entries by value, so b may no longer point
+                * to the right entry after this
+                */
                sort(tab->descs, tab->nr_descs, sizeof(tab->descs[0]),
                     kfunc_btf_cmp_by_off, NULL);
+       } else {
+               btf = b->btf;
        }
-       return b->btf;
+
+       return btf;
 }
 
 void bpf_free_kfunc_btf_tab(struct bpf_kfunc_btf_tab *tab)
@@ -6333,10 +6339,10 @@ static void coerce_reg_to_size_sx(struct bpf_reg_state *reg, int size)
 
        /* both of s64_max/s64_min positive or negative */
        if ((s64_max >= 0) == (s64_min >= 0)) {
-               reg->smin_value = reg->s32_min_value = s64_min;
-               reg->smax_value = reg->s32_max_value = s64_max;
-               reg->umin_value = reg->u32_min_value = s64_min;
-               reg->umax_value = reg->u32_max_value = s64_max;
+               reg->s32_min_value = reg->smin_value = s64_min;
+               reg->s32_max_value = reg->smax_value = s64_max;
+               reg->u32_min_value = reg->umin_value = s64_min;
+               reg->u32_max_value = reg->umax_value = s64_max;
                reg->var_off = tnum_range(s64_min, s64_max);
                return;
        }
@@ -6798,20 +6804,10 @@ static int check_stack_slot_within_bounds(struct bpf_verifier_env *env,
                                           struct bpf_func_state *state,
                                           enum bpf_access_type t)
 {
-       struct bpf_insn_aux_data *aux = &env->insn_aux_data[env->insn_idx];
-       int min_valid_off, max_bpf_stack;
-
-       /* If accessing instruction is a spill/fill from bpf_fastcall pattern,
-        * add room for all caller saved registers below MAX_BPF_STACK.
-        * In case if bpf_fastcall rewrite won't happen maximal stack depth
-        * would be checked by check_max_stack_depth_subprog().
-        */
-       max_bpf_stack = MAX_BPF_STACK;
-       if (aux->fastcall_pattern)
-               max_bpf_stack += CALLER_SAVED_REGS * BPF_REG_SIZE;
+       int min_valid_off;
 
        if (t == BPF_WRITE || env->allow_uninit_stack)
-               min_valid_off = -max_bpf_stack;
+               min_valid_off = -MAX_BPF_STACK;
        else
                min_valid_off = -state->allocated_stack;
 
@@ -7432,7 +7428,8 @@ mark:
 }
 
 static int check_helper_mem_access(struct bpf_verifier_env *env, int regno,
-                                  int access_size, bool zero_size_allowed,
+                                  int access_size, enum bpf_access_type access_type,
+                                  bool zero_size_allowed,
                                   struct bpf_call_arg_meta *meta)
 {
        struct bpf_reg_state *regs = cur_regs(env), *reg = &regs[regno];
@@ -7444,7 +7441,7 @@ static int check_helper_mem_access(struct bpf_verifier_env *env, int regno,
                return check_packet_access(env, regno, reg->off, access_size,
                                           zero_size_allowed);
        case PTR_TO_MAP_KEY:
-               if (meta && meta->raw_mode) {
+               if (access_type == BPF_WRITE) {
                        verbose(env, "R%d cannot write into %s\n", regno,
                                reg_type_str(env, reg->type));
                        return -EACCES;
@@ -7452,15 +7449,13 @@ static int check_helper_mem_access(struct bpf_verifier_env *env, int regno,
                return check_mem_region_access(env, regno, reg->off, access_size,
                                               reg->map_ptr->key_size, false);
        case PTR_TO_MAP_VALUE:
-               if (check_map_access_type(env, regno, reg->off, access_size,
-                                         meta && meta->raw_mode ? BPF_WRITE :
-                                         BPF_READ))
+               if (check_map_access_type(env, regno, reg->off, access_size, access_type))
                        return -EACCES;
                return check_map_access(env, regno, reg->off, access_size,
                                        zero_size_allowed, ACCESS_HELPER);
        case PTR_TO_MEM:
                if (type_is_rdonly_mem(reg->type)) {
-                       if (meta && meta->raw_mode) {
+                       if (access_type == BPF_WRITE) {
                                verbose(env, "R%d cannot write into %s\n", regno,
                                        reg_type_str(env, reg->type));
                                return -EACCES;
@@ -7471,7 +7466,7 @@ static int check_helper_mem_access(struct bpf_verifier_env *env, int regno,
                                               zero_size_allowed);
        case PTR_TO_BUF:
                if (type_is_rdonly_mem(reg->type)) {
-                       if (meta && meta->raw_mode) {
+                       if (access_type == BPF_WRITE) {
                                verbose(env, "R%d cannot write into %s\n", regno,
                                        reg_type_str(env, reg->type));
                                return -EACCES;
@@ -7499,7 +7494,6 @@ static int check_helper_mem_access(struct bpf_verifier_env *env, int regno,
                 * Dynamically check it now.
                 */
                if (!env->ops->convert_ctx_access) {
-                       enum bpf_access_type atype = meta && meta->raw_mode ? BPF_WRITE : BPF_READ;
                        int offset = access_size - 1;
 
                        /* Allow zero-byte read from PTR_TO_CTX */
@@ -7507,7 +7501,7 @@ static int check_helper_mem_access(struct bpf_verifier_env *env, int regno,
                                return zero_size_allowed ? 0 : -EACCES;
 
                        return check_mem_access(env, env->insn_idx, regno, offset, BPF_B,
-                                               atype, -1, false, false);
+                                               access_type, -1, false, false);
                }
 
                fallthrough;
@@ -7532,6 +7526,7 @@ static int check_helper_mem_access(struct bpf_verifier_env *env, int regno,
  */
 static int check_mem_size_reg(struct bpf_verifier_env *env,
                              struct bpf_reg_state *reg, u32 regno,
+                             enum bpf_access_type access_type,
                              bool zero_size_allowed,
                              struct bpf_call_arg_meta *meta)
 {
@@ -7547,15 +7542,12 @@ static int check_mem_size_reg(struct bpf_verifier_env *env,
         */
        meta->msize_max_value = reg->umax_value;
 
-       /* The register is SCALAR_VALUE; the access check
-        * happens using its boundaries.
+       /* The register is SCALAR_VALUE; the access check happens using
+        * its boundaries. For unprivileged variable accesses, disable
+        * raw mode so that the program is required to initialize all
+        * the memory that the helper could just partially fill up.
         */
        if (!tnum_is_const(reg->var_off))
-               /* For unprivileged variable accesses, disable raw
-                * mode so that the program is required to
-                * initialize all the memory that the helper could
-                * just partially fill up.
-                */
                meta = NULL;
 
        if (reg->smin_value < 0) {
@@ -7575,9 +7567,8 @@ static int check_mem_size_reg(struct bpf_verifier_env *env,
                        regno);
                return -EACCES;
        }
-       err = check_helper_mem_access(env, regno - 1,
-                                     reg->umax_value,
-                                     zero_size_allowed, meta);
+       err = check_helper_mem_access(env, regno - 1, reg->umax_value,
+                                     access_type, zero_size_allowed, meta);
        if (!err)
                err = mark_chain_precision(env, regno);
        return err;
@@ -7588,13 +7579,11 @@ static int check_mem_reg(struct bpf_verifier_env *env, struct bpf_reg_state *reg
 {
        bool may_be_null = type_may_be_null(reg->type);
        struct bpf_reg_state saved_reg;
-       struct bpf_call_arg_meta meta;
        int err;
 
        if (register_is_null(reg))
                return 0;
 
-       memset(&meta, 0, sizeof(meta));
        /* Assuming that the register contains a value check if the memory
         * access is safe. Temporarily save and restore the register's state as
         * the conversion shouldn't be visible to a caller.
@@ -7604,10 +7593,8 @@ static int check_mem_reg(struct bpf_verifier_env *env, struct bpf_reg_state *reg
                mark_ptr_not_null_reg(reg);
        }
 
-       err = check_helper_mem_access(env, regno, mem_size, true, &meta);
-       /* Check access for BPF_WRITE */
-       meta.raw_mode = true;
-       err = err ?: check_helper_mem_access(env, regno, mem_size, true, &meta);
+       err = check_helper_mem_access(env, regno, mem_size, BPF_READ, true, NULL);
+       err = err ?: check_helper_mem_access(env, regno, mem_size, BPF_WRITE, true, NULL);
 
        if (may_be_null)
                *reg = saved_reg;
@@ -7633,13 +7620,12 @@ static int check_kfunc_mem_size_reg(struct bpf_verifier_env *env, struct bpf_reg
                mark_ptr_not_null_reg(mem_reg);
        }
 
-       err = check_mem_size_reg(env, reg, regno, true, &meta);
-       /* Check access for BPF_WRITE */
-       meta.raw_mode = true;
-       err = err ?: check_mem_size_reg(env, reg, regno, true, &meta);
+       err = check_mem_size_reg(env, reg, regno, BPF_READ, true, &meta);
+       err = err ?: check_mem_size_reg(env, reg, regno, BPF_WRITE, true, &meta);
 
        if (may_be_null)
                *mem_reg = saved_reg;
+
        return err;
 }
 
@@ -8942,9 +8928,8 @@ skip_type_check:
                        verbose(env, "invalid map_ptr to access map->key\n");
                        return -EACCES;
                }
-               err = check_helper_mem_access(env, regno,
-                                             meta->map_ptr->key_size, false,
-                                             NULL);
+               err = check_helper_mem_access(env, regno, meta->map_ptr->key_size,
+                                             BPF_READ, false, NULL);
                break;
        case ARG_PTR_TO_MAP_VALUE:
                if (type_may_be_null(arg_type) && register_is_null(reg))
@@ -8959,9 +8944,9 @@ skip_type_check:
                        return -EACCES;
                }
                meta->raw_mode = arg_type & MEM_UNINIT;
-               err = check_helper_mem_access(env, regno,
-                                             meta->map_ptr->value_size, false,
-                                             meta);
+               err = check_helper_mem_access(env, regno, meta->map_ptr->value_size,
+                                             arg_type & MEM_WRITE ? BPF_WRITE : BPF_READ,
+                                             false, meta);
                break;
        case ARG_PTR_TO_PERCPU_BTF_ID:
                if (!reg->btf_id) {
@@ -9003,7 +8988,9 @@ skip_type_check:
                 */
                meta->raw_mode = arg_type & MEM_UNINIT;
                if (arg_type & MEM_FIXED_SIZE) {
-                       err = check_helper_mem_access(env, regno, fn->arg_size[arg], false, meta);
+                       err = check_helper_mem_access(env, regno, fn->arg_size[arg],
+                                                     arg_type & MEM_WRITE ? BPF_WRITE : BPF_READ,
+                                                     false, meta);
                        if (err)
                                return err;
                        if (arg_type & MEM_ALIGNED)
@@ -9011,10 +8998,16 @@ skip_type_check:
                }
                break;
        case ARG_CONST_SIZE:
-               err = check_mem_size_reg(env, reg, regno, false, meta);
+               err = check_mem_size_reg(env, reg, regno,
+                                        fn->arg_type[arg - 1] & MEM_WRITE ?
+                                        BPF_WRITE : BPF_READ,
+                                        false, meta);
                break;
        case ARG_CONST_SIZE_OR_ZERO:
-               err = check_mem_size_reg(env, reg, regno, true, meta);
+               err = check_mem_size_reg(env, reg, regno,
+                                        fn->arg_type[arg - 1] & MEM_WRITE ?
+                                        BPF_WRITE : BPF_READ,
+                                        true, meta);
                break;
        case ARG_PTR_TO_DYNPTR:
                err = process_dynptr_func(env, regno, insn_idx, arg_type, 0);
@@ -14264,12 +14257,13 @@ static int adjust_reg_min_max_vals(struct bpf_verifier_env *env,
         * r1 += 0x1
         * if r2 < 1000 goto ...
         * use r1 in memory access
-        * So remember constant delta between r2 and r1 and update r1 after
-        * 'if' condition.
+        * So for 64-bit alu remember constant delta between r2 and r1 and
+        * update r1 after 'if' condition.
         */
-       if (env->bpf_capable && BPF_OP(insn->code) == BPF_ADD &&
-           dst_reg->id && is_reg_const(src_reg, alu32)) {
-               u64 val = reg_const_value(src_reg, alu32);
+       if (env->bpf_capable &&
+           BPF_OP(insn->code) == BPF_ADD && !alu32 &&
+           dst_reg->id && is_reg_const(src_reg, false)) {
+               u64 val = reg_const_value(src_reg, false);
 
                if ((dst_reg->id & BPF_ADD_CONST) ||
                    /* prevent overflow in sync_linked_regs() later */
@@ -15326,8 +15320,12 @@ static void sync_linked_regs(struct bpf_verifier_state *vstate, struct bpf_reg_s
                        continue;
                if ((!(reg->id & BPF_ADD_CONST) && !(known_reg->id & BPF_ADD_CONST)) ||
                    reg->off == known_reg->off) {
+                       s32 saved_subreg_def = reg->subreg_def;
+
                        copy_register_state(reg, known_reg);
+                       reg->subreg_def = saved_subreg_def;
                } else {
+                       s32 saved_subreg_def = reg->subreg_def;
                        s32 saved_off = reg->off;
 
                        fake_reg.type = SCALAR_VALUE;
@@ -15340,6 +15338,7 @@ static void sync_linked_regs(struct bpf_verifier_state *vstate, struct bpf_reg_s
                         * otherwise another sync_linked_regs() will be incorrect.
                         */
                        reg->off = saved_off;
+                       reg->subreg_def = saved_subreg_def;
 
                        scalar32_min_max_add(reg, &fake_reg);
                        scalar_min_max_add(reg, &fake_reg);
@@ -17877,9 +17876,11 @@ static int is_state_visited(struct bpf_verifier_env *env, int insn_idx)
        struct bpf_verifier_state_list *sl, **pprev;
        struct bpf_verifier_state *cur = env->cur_state, *new, *loop_entry;
        int i, j, n, err, states_cnt = 0;
-       bool force_new_state = env->test_state_freq || is_force_checkpoint(env, insn_idx);
-       bool add_new_state = force_new_state;
-       bool force_exact;
+       bool force_new_state, add_new_state, force_exact;
+
+       force_new_state = env->test_state_freq || is_force_checkpoint(env, insn_idx) ||
+                         /* Avoid accumulating infinitely long jmp history */
+                         cur->jmp_history_cnt > 40;
 
        /* bpf progs typically have pruning point every 4 instructions
         * http://vger.kernel.org/bpfconf2019.html#session-1
@@ -17889,6 +17890,7 @@ static int is_state_visited(struct bpf_verifier_env *env, int insn_idx)
         * In tests that amounts to up to 50% reduction into total verifier
         * memory consumption and 20% verifier time speedup.
         */
+       add_new_state = force_new_state;
        if (env->jmps_processed - env->prev_jmps_processed >= 2 &&
            env->insn_processed - env->prev_insn_processed >= 8)
                add_new_state = true;
@@ -21201,7 +21203,7 @@ patch_map_ops_generic:
                        delta    += cnt - 1;
                        env->prog = prog = new_prog;
                        insn      = new_prog->insnsi + i + delta;
-                       continue;
+                       goto next_insn;
                }
 
                /* Implement bpf_kptr_xchg inline */
@@ -22310,7 +22312,7 @@ int bpf_check(struct bpf_prog **prog, union bpf_attr *attr, bpfptr_t uattr, __u3
        /* 'struct bpf_verifier_env' can be global, but since it's not small,
         * allocate/free it every time bpf_check() is called
         */
-       env = kzalloc(sizeof(struct bpf_verifier_env), GFP_KERNEL);
+       env = kvzalloc(sizeof(struct bpf_verifier_env), GFP_KERNEL);
        if (!env)
                return -ENOMEM;
 
@@ -22546,6 +22548,6 @@ err_unlock:
                mutex_unlock(&bpf_verifier_lock);
        vfree(env->insn_aux_data);
 err_free_env:
-       kfree(env);
+       kvfree(env);
        return ret;
 }
index 5886b95c6eaee60e12d5035e4eee41964ed47e9a..044c7ba1cc482bef96bfd87c441fa531f96b47e5 100644 (file)
@@ -5789,7 +5789,7 @@ static bool cgroup_check_hierarchy_limits(struct cgroup *parent)
 {
        struct cgroup *cgroup;
        int ret = false;
-       int level = 1;
+       int level = 0;
 
        lockdep_assert_held(&cgroup_mutex);
 
@@ -5797,7 +5797,7 @@ static bool cgroup_check_hierarchy_limits(struct cgroup *parent)
                if (cgroup->nr_descendants >= cgroup->max_descendants)
                        goto fail;
 
-               if (level > cgroup->max_depth)
+               if (level >= cgroup->max_depth)
                        goto fail;
 
                level++;
index 9d34d2364b5a504d8ca80a24377cdac3a445fbd6..f625172d4b676bcefc1713d12236cc5934bf16fd 100644 (file)
@@ -33,7 +33,7 @@
 #include <linux/reboot.h>
 #include <linux/uaccess.h>
 #include <asm/cacheflush.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include "debug_core.h"
 
 #define KGDB_MAX_THREAD_QUERY 17
index e3589c4287cb458c09352dc7895d9812a9cc7158..df27d08a723269f9d98a74508cc5084eeb823397 100644 (file)
@@ -9251,7 +9251,7 @@ static void perf_event_switch(struct task_struct *task,
                },
        };
 
-       if (!sched_in && task->on_rq) {
+       if (!sched_in && task_is_runnable(task)) {
                switch_event.event_id.header.misc |=
                                PERF_RECORD_MISC_SWITCH_OUT_PREEMPT;
        }
@@ -13959,7 +13959,7 @@ static void perf_event_clear_cpumask(unsigned int cpu)
        }
 
        /* migrate */
-       list_for_each_entry_rcu(pmu, &pmus, entry, lockdep_is_held(&pmus_srcu)) {
+       list_for_each_entry(pmu, &pmus, entry) {
                if (pmu->scope == PERF_PMU_SCOPE_NONE ||
                    WARN_ON_ONCE(pmu->scope >= PERF_PMU_MAX_SCOPE))
                        continue;
index 2ec796e2f0553591c8a19a8512bf790686991c73..4b52cb2ae6d620b2526de7e86291bdc137aa4f49 100644 (file)
@@ -1545,7 +1545,7 @@ static struct xol_area *__create_xol_area(unsigned long vaddr)
        if (!area->bitmap)
                goto free_area;
 
-       area->page = alloc_page(GFP_HIGHUSER);
+       area->page = alloc_page(GFP_HIGHUSER | __GFP_ZERO);
        if (!area->page)
                goto free_bitmap;
 
index 60c0b4868fd4993920f7a615a47f7e915b9a47b5..22f43721d031d48fd5be2606e86642334be9735f 100644 (file)
 #include <linux/rseq.h>
 #include <uapi/linux/pidfd.h>
 #include <linux/pidfs.h>
+#include <linux/tick.h>
 
 #include <asm/pgalloc.h>
 #include <linux/uaccess.h>
@@ -653,11 +654,6 @@ static __latent_entropy int dup_mmap(struct mm_struct *mm,
        mm->exec_vm = oldmm->exec_vm;
        mm->stack_vm = oldmm->stack_vm;
 
-       retval = ksm_fork(mm, oldmm);
-       if (retval)
-               goto out;
-       khugepaged_fork(mm, oldmm);
-
        /* Use __mt_dup() to efficiently build an identical maple tree. */
        retval = __mt_dup(&oldmm->mm_mt, &mm->mm_mt, GFP_KERNEL);
        if (unlikely(retval))
@@ -760,6 +756,8 @@ loop_out:
        vma_iter_free(&vmi);
        if (!retval) {
                mt_set_in_rcu(vmi.mas.tree);
+               ksm_fork(mm, oldmm);
+               khugepaged_fork(mm, oldmm);
        } else if (mpnt) {
                /*
                 * The entire maple tree has already been duplicated. If the
@@ -775,7 +773,10 @@ out:
        mmap_write_unlock(mm);
        flush_tlb_mm(oldmm);
        mmap_write_unlock(oldmm);
-       dup_userfaultfd_complete(&uf);
+       if (!retval)
+               dup_userfaultfd_complete(&uf);
+       else
+               dup_userfaultfd_fail(&uf);
 fail_uprobe_end:
        uprobe_end_dup_mmap();
        return retval;
@@ -1756,33 +1757,30 @@ static int copy_files(unsigned long clone_flags, struct task_struct *tsk,
                      int no_files)
 {
        struct files_struct *oldf, *newf;
-       int error = 0;
 
        /*
         * A background process may not have any files ...
         */
        oldf = current->files;
        if (!oldf)
-               goto out;
+               return 0;
 
        if (no_files) {
                tsk->files = NULL;
-               goto out;
+               return 0;
        }
 
        if (clone_flags & CLONE_FILES) {
                atomic_inc(&oldf->count);
-               goto out;
+               return 0;
        }
 
-       newf = dup_fd(oldf, NR_OPEN_MAX, &error);
-       if (!newf)
-               goto out;
+       newf = dup_fd(oldf, NULL);
+       if (IS_ERR(newf))
+               return PTR_ERR(newf);
 
        tsk->files = newf;
-       error = 0;
-out:
-       return error;
+       return 0;
 }
 
 static int copy_sighand(unsigned long clone_flags, struct task_struct *tsk)
@@ -2295,6 +2293,7 @@ __latent_entropy struct task_struct *copy_process(
        acct_clear_integrals(p);
 
        posix_cputimers_init(&p->posix_cputimers);
+       tick_dep_init_task(p);
 
        p->io_context = NULL;
        audit_set_context(p, NULL);
@@ -3238,17 +3237,16 @@ static int unshare_fs(unsigned long unshare_flags, struct fs_struct **new_fsp)
 /*
  * Unshare file descriptor table if it is being shared
  */
-int unshare_fd(unsigned long unshare_flags, unsigned int max_fds,
-              struct files_struct **new_fdp)
+static int unshare_fd(unsigned long unshare_flags, struct files_struct **new_fdp)
 {
        struct files_struct *fd = current->files;
-       int error = 0;
 
        if ((unshare_flags & CLONE_FILES) &&
            (fd && atomic_read(&fd->count) > 1)) {
-               *new_fdp = dup_fd(fd, max_fds, &error);
-               if (!*new_fdp)
-                       return error;
+               fd = dup_fd(fd, NULL);
+               if (IS_ERR(fd))
+                       return PTR_ERR(fd);
+               *new_fdp = fd;
        }
 
        return 0;
@@ -3306,7 +3304,7 @@ int ksys_unshare(unsigned long unshare_flags)
        err = unshare_fs(unshare_flags, &new_fs);
        if (err)
                goto bad_unshare_out;
-       err = unshare_fd(unshare_flags, NR_OPEN_MAX, &new_fd);
+       err = unshare_fd(unshare_flags, &new_fd);
        if (err)
                goto bad_unshare_cleanup_fs;
        err = unshare_userns(unshare_flags, &new_cred);
@@ -3398,7 +3396,7 @@ int unshare_files(void)
        struct files_struct *old, *copy = NULL;
        int error;
 
-       error = unshare_fd(CLONE_FILES, NR_OPEN_MAX, &copy);
+       error = unshare_fd(CLONE_FILES, &copy);
        if (error || !copy)
                return error;
 
index 44bbd7dbd2c87836a360d3791f848ef4d6a0dc7a..8d530d0949ff69178edaf368222df847d026c842 100644 (file)
@@ -109,7 +109,12 @@ static int __set_task_frozen(struct task_struct *p, void *arg)
 {
        unsigned int state = READ_ONCE(p->__state);
 
-       if (p->on_rq)
+       /*
+        * Allow freezing the sched_delayed tasks; they will not execute until
+        * ttwu() fixes them up, so it is safe to swap their state now, instead
+        * of waiting for them to get fully dequeued.
+        */
+       if (task_is_runnable(p))
                return 0;
 
        if (p != current && task_curr(p))
index 3a24d6b5f559ca4b2416104a3d346b0e88172ac8..396a067a8a56b59c54f5b478acd6d68a19faba89 100644 (file)
@@ -718,7 +718,7 @@ static int msi_domain_alloc(struct irq_domain *domain, unsigned int virq,
                ret = ops->msi_init(domain, info, virq + i, hwirq + i, arg);
                if (ret < 0) {
                        if (ops->msi_free) {
-                               for (i--; i > 0; i--)
+                               for (i--; i >= 0; i--)
                                        ops->msi_free(domain, info, virq + i);
                        }
                        irq_domain_free_irqs_top(domain, virq, nr_irqs);
index db4ceb0f503cca575efc5a8fc1350aead0efdff6..9bb36897b6c62d46a2f7f7af51b86ff545e3eecf 100644 (file)
@@ -623,6 +623,8 @@ void kthread_unpark(struct task_struct *k)
 {
        struct kthread *kthread = to_kthread(k);
 
+       if (!test_bit(KTHREAD_SHOULD_PARK, &kthread->flags))
+               return;
        /*
         * Newly created kthread was parked when the CPU was offline.
         * The binding was lost and we need to set it again.
index 6333f4ccf024be2cb5f8dfffc82f3ca679161415..4d7ee95df06e6792fa06207997d57cd4bb306f7a 100644 (file)
@@ -985,6 +985,15 @@ static bool rcu_tasks_is_holdout(struct task_struct *t)
        if (!READ_ONCE(t->on_rq))
                return false;
 
+       /*
+        * t->on_rq && !t->se.sched_delayed *could* be considered sleeping but
+        * since it is a spurious state (it will transition into the
+        * traditional blocked state or get woken up without outside
+        * dependencies), not considering it such should only affect timing.
+        *
+        * Be conservative for now and not include it.
+        */
+
        /*
         * Idle tasks (or idle injection) within the idle loop are RCU-tasks
         * quiescent states. But CPU boot code performed by the idle task
index a60616e69b66326c6fb68f0251653b11c7003819..b1f883fcd9185a5e22c10102d1024c40688f57fb 100644 (file)
@@ -3607,11 +3607,12 @@ kvfree_rcu_queue_batch(struct kfree_rcu_cpu *krcp)
                        }
 
                        // One work is per one batch, so there are three
-                       // "free channels", the batch can handle. It can
-                       // be that the work is in the pending state when
-                       // channels have been detached following by each
-                       // other.
+                       // "free channels", the batch can handle. Break
+                       // the loop since it is done with this CPU thus
+                       // queuing an RCU work is _always_ success here.
                        queued = queue_rcu_work(system_unbound_wq, &krwp->rcu_work);
+                       WARN_ON_ONCE(!queued);
+                       break;
                }
        }
 
index 97b99cd0692323eda39013951ed4e01eb9382a11..16865475120ba38c741aae897a3dc8d99f95d0ee 100644 (file)
@@ -554,13 +554,19 @@ static void __call_rcu_nocb_wake(struct rcu_data *rdp, bool was_alldone,
                        rcu_nocb_unlock(rdp);
                        wake_nocb_gp_defer(rdp, RCU_NOCB_WAKE_LAZY,
                                           TPS("WakeLazy"));
-               } else if (!irqs_disabled_flags(flags)) {
+               } else if (!irqs_disabled_flags(flags) && cpu_online(rdp->cpu)) {
                        /* ... if queue was empty ... */
                        rcu_nocb_unlock(rdp);
                        wake_nocb_gp(rdp, false);
                        trace_rcu_nocb_wake(rcu_state.name, rdp->cpu,
                                            TPS("WakeEmpty"));
                } else {
+                       /*
+                        * Don't do the wake-up upfront on fragile paths.
+                        * Also offline CPUs can't call swake_up_one_online() from
+                        * (soft-)IRQs. Rely on the final deferred wake-up from
+                        * rcutree_report_cpu_dead()
+                        */
                        rcu_nocb_unlock(rdp);
                        wake_nocb_gp_defer(rdp, RCU_NOCB_WAKE,
                                           TPS("WakeEmptyIsDeferred"));
index b730bd28b422a484bb4fc5e2591d2457c1088b38..4101016e8b205c8e2ffed5dfd20ce439603d53b7 100644 (file)
@@ -459,9 +459,7 @@ int walk_system_ram_res_rev(u64 start, u64 end, void *arg,
                        rams_size += 16;
                }
 
-               rams[i].start = res.start;
-               rams[i++].end = res.end;
-
+               rams[i++] = res;
                start = res.end + 1;
        }
 
index 42d2d8d20f5d54e868d344c1a73835977bc84a39..b8ef75b99eb2f788b518ba71fc1b35248595377f 100644 (file)
@@ -169,6 +169,8 @@ static void resource_test_intersection(struct kunit *test)
 #define RES_TEST_RAM3_SIZE     SZ_1M
 #define RES_TEST_TOTAL_SIZE    ((RES_TEST_WIN1_OFFSET + RES_TEST_WIN1_SIZE))
 
+KUNIT_DEFINE_ACTION_WRAPPER(kfree_wrapper, kfree, const void *);
+
 static void remove_free_resource(void *ctx)
 {
        struct resource *res = (struct resource *)ctx;
@@ -177,6 +179,14 @@ static void remove_free_resource(void *ctx)
        kfree(res);
 }
 
+static void resource_test_add_action_or_abort(
+       struct kunit *test, void (*action)(void *), void *ctx)
+{
+       KUNIT_ASSERT_EQ_MSG(test, 0,
+                           kunit_add_action_or_reset(test, action, ctx),
+                           "Fail to add action");
+}
+
 static void resource_test_request_region(struct kunit *test, struct resource *parent,
                                         resource_size_t start, resource_size_t size,
                                         const char *name, unsigned long flags)
@@ -185,7 +195,7 @@ static void resource_test_request_region(struct kunit *test, struct resource *pa
 
        res = __request_region(parent, start, size, name, flags);
        KUNIT_ASSERT_NOT_NULL(test, res);
-       kunit_add_action_or_reset(test, remove_free_resource, res);
+       resource_test_add_action_or_abort(test, remove_free_resource, res);
 }
 
 static void resource_test_insert_resource(struct kunit *test, struct resource *parent,
@@ -202,11 +212,11 @@ static void resource_test_insert_resource(struct kunit *test, struct resource *p
        res->end = start + size - 1;
        res->flags = flags;
        if (insert_resource(parent, res)) {
-               kfree(res);
+               resource_test_add_action_or_abort(test, kfree_wrapper, res);
                KUNIT_FAIL_AND_ABORT(test, "Fail to insert resource %pR\n", res);
        }
 
-       kunit_add_action_or_reset(test, remove_free_resource, res);
+       resource_test_add_action_or_abort(test, remove_free_resource, res);
 }
 
 static void resource_test_region_intersects(struct kunit *test)
@@ -220,7 +230,7 @@ static void resource_test_region_intersects(struct kunit *test)
                                       "test resources");
        KUNIT_ASSERT_NOT_ERR_OR_NULL(test, parent);
        start = parent->start;
-       kunit_add_action_or_reset(test, remove_free_resource, parent);
+       resource_test_add_action_or_abort(test, remove_free_resource, parent);
 
        resource_test_request_region(test, parent, start + RES_TEST_RAM0_OFFSET,
                                     RES_TEST_RAM0_SIZE, "Test System RAM 0", flags);
index 43e453ab7e20f81ea239919af19ef20c5358c93d..719e0ed1e97618cea8eefc9de08604c1b1fc76fd 100644 (file)
@@ -548,6 +548,11 @@ sched_core_dequeue(struct rq *rq, struct task_struct *p, int flags) { }
  *   ON_RQ_MIGRATING state is used for migration without holding both
  *   rq->locks. It indicates task_cpu() is not stable, see task_rq_lock().
  *
+ *   Additionally it is possible to be ->on_rq but still be considered not
+ *   runnable when p->se.sched_delayed is true. These tasks are on the runqueue
+ *   but will be dequeued as soon as they get picked again. See the
+ *   task_is_runnable() helper.
+ *
  * p->on_cpu <- { 0, 1 }:
  *
  *   is set by prepare_task() and cleared by finish_task() such that it will be
@@ -2012,11 +2017,6 @@ void enqueue_task(struct rq *rq, struct task_struct *p, int flags)
        if (!(flags & ENQUEUE_NOCLOCK))
                update_rq_clock(rq);
 
-       if (!(flags & ENQUEUE_RESTORE)) {
-               sched_info_enqueue(rq, p);
-               psi_enqueue(p, (flags & ENQUEUE_WAKEUP) && !(flags & ENQUEUE_MIGRATED));
-       }
-
        p->sched_class->enqueue_task(rq, p, flags);
        /*
         * Must be after ->enqueue_task() because ENQUEUE_DELAYED can clear
@@ -2024,6 +2024,11 @@ void enqueue_task(struct rq *rq, struct task_struct *p, int flags)
         */
        uclamp_rq_inc(rq, p);
 
+       if (!(flags & ENQUEUE_RESTORE)) {
+               sched_info_enqueue(rq, p);
+               psi_enqueue(p, flags & ENQUEUE_MIGRATED);
+       }
+
        if (sched_core_enabled(rq))
                sched_core_enqueue(rq, p);
 }
@@ -2041,7 +2046,7 @@ inline bool dequeue_task(struct rq *rq, struct task_struct *p, int flags)
 
        if (!(flags & DEQUEUE_SAVE)) {
                sched_info_dequeue(rq, p);
-               psi_dequeue(p, flags & DEQUEUE_SLEEP);
+               psi_dequeue(p, !(flags & DEQUEUE_SLEEP));
        }
 
        /*
@@ -3518,14 +3523,16 @@ out:
  * The caller (fork, wakeup) owns p->pi_lock, ->cpus_ptr is stable.
  */
 static inline
-int select_task_rq(struct task_struct *p, int cpu, int wake_flags)
+int select_task_rq(struct task_struct *p, int cpu, int *wake_flags)
 {
        lockdep_assert_held(&p->pi_lock);
 
-       if (p->nr_cpus_allowed > 1 && !is_migration_disabled(p))
-               cpu = p->sched_class->select_task_rq(p, cpu, wake_flags);
-       else
+       if (p->nr_cpus_allowed > 1 && !is_migration_disabled(p)) {
+               cpu = p->sched_class->select_task_rq(p, cpu, *wake_flags);
+               *wake_flags |= WF_RQ_SELECTED;
+       } else {
                cpu = cpumask_any(p->cpus_ptr);
+       }
 
        /*
         * In order not to call set_task_cpu() on a blocking task we need
@@ -3659,6 +3666,8 @@ ttwu_do_activate(struct rq *rq, struct task_struct *p, int wake_flags,
                rq->nr_uninterruptible--;
 
 #ifdef CONFIG_SMP
+       if (wake_flags & WF_RQ_SELECTED)
+               en_flags |= ENQUEUE_RQ_SELECTED;
        if (wake_flags & WF_MIGRATED)
                en_flags |= ENQUEUE_MIGRATED;
        else
@@ -4120,6 +4129,8 @@ int try_to_wake_up(struct task_struct *p, unsigned int state, int wake_flags)
        guard(preempt)();
        int cpu, success = 0;
 
+       wake_flags |= WF_TTWU;
+
        if (p == current) {
                /*
                 * We're waking current, this means 'p->on_rq' and 'task_cpu(p)
@@ -4252,7 +4263,7 @@ int try_to_wake_up(struct task_struct *p, unsigned int state, int wake_flags)
                 */
                smp_cond_load_acquire(&p->on_cpu, !VAL);
 
-               cpu = select_task_rq(p, p->wake_cpu, wake_flags | WF_TTWU);
+               cpu = select_task_rq(p, p->wake_cpu, &wake_flags);
                if (task_cpu(p) != cpu) {
                        if (p->in_iowait) {
                                delayacct_blkio_end(p);
@@ -4317,9 +4328,10 @@ static bool __task_needs_rq_lock(struct task_struct *p)
  * @arg: Argument to function.
  *
  * Fix the task in it's current state by avoiding wakeups and or rq operations
- * and call @func(@arg) on it.  This function can use ->on_rq and task_curr()
- * to work out what the state is, if required.  Given that @func can be invoked
- * with a runqueue lock held, it had better be quite lightweight.
+ * and call @func(@arg) on it.  This function can use task_is_runnable() and
+ * task_curr() to work out what the state is, if required.  Given that @func
+ * can be invoked with a runqueue lock held, it had better be quite
+ * lightweight.
  *
  * Returns:
  *   Whatever @func returns
@@ -4699,7 +4711,7 @@ int sched_fork(unsigned long clone_flags, struct task_struct *p)
        if (rt_prio(p->prio)) {
                p->sched_class = &rt_sched_class;
 #ifdef CONFIG_SCHED_CLASS_EXT
-       } else if (task_should_scx(p)) {
+       } else if (task_should_scx(p->policy)) {
                p->sched_class = &ext_sched_class;
 #endif
        } else {
@@ -4793,6 +4805,7 @@ void wake_up_new_task(struct task_struct *p)
 {
        struct rq_flags rf;
        struct rq *rq;
+       int wake_flags = WF_FORK;
 
        raw_spin_lock_irqsave(&p->pi_lock, rf.flags);
        WRITE_ONCE(p->__state, TASK_RUNNING);
@@ -4807,7 +4820,7 @@ void wake_up_new_task(struct task_struct *p)
         */
        p->recent_used_cpu = task_cpu(p);
        rseq_migrate(p);
-       __set_task_cpu(p, select_task_rq(p, task_cpu(p), WF_FORK));
+       __set_task_cpu(p, select_task_rq(p, task_cpu(p), &wake_flags));
 #endif
        rq = __task_rq_lock(p, &rf);
        update_rq_clock(rq);
@@ -4815,7 +4828,7 @@ void wake_up_new_task(struct task_struct *p)
 
        activate_task(rq, p, ENQUEUE_NOCLOCK | ENQUEUE_INITIAL);
        trace_sched_wakeup_new(p);
-       wakeup_preempt(rq, p, WF_FORK);
+       wakeup_preempt(rq, p, wake_flags);
 #ifdef CONFIG_SMP
        if (p->sched_class->task_woken) {
                /*
@@ -6537,6 +6550,7 @@ static void __sched notrace __schedule(int sched_mode)
         * as a preemption by schedule_debug() and RCU.
         */
        bool preempt = sched_mode > SM_NONE;
+       bool block = false;
        unsigned long *switch_count;
        unsigned long prev_state;
        struct rq_flags rf;
@@ -6622,6 +6636,7 @@ static void __sched notrace __schedule(int sched_mode)
                         * After this, schedule() must not care about p->state any more.
                         */
                        block_task(rq, prev, flags);
+                       block = true;
                }
                switch_count = &prev->nvcsw;
        }
@@ -6667,7 +6682,7 @@ picked:
 
                migrate_disable_switch(rq, prev);
                psi_account_irqtime(rq, prev, next);
-               psi_sched_switch(prev, next, !task_on_rq_queued(prev));
+               psi_sched_switch(prev, next, block);
 
                trace_sched_switch(preempt, prev, next, prev_state);
 
@@ -7010,20 +7025,20 @@ int default_wake_function(wait_queue_entry_t *curr, unsigned mode, int wake_flag
 }
 EXPORT_SYMBOL(default_wake_function);
 
-void __setscheduler_prio(struct task_struct *p, int prio)
+const struct sched_class *__setscheduler_class(int policy, int prio)
 {
        if (dl_prio(prio))
-               p->sched_class = &dl_sched_class;
-       else if (rt_prio(prio))
-               p->sched_class = &rt_sched_class;
+               return &dl_sched_class;
+
+       if (rt_prio(prio))
+               return &rt_sched_class;
+
 #ifdef CONFIG_SCHED_CLASS_EXT
-       else if (task_should_scx(p))
-               p->sched_class = &ext_sched_class;
+       if (task_should_scx(policy))
+               return &ext_sched_class;
 #endif
-       else
-               p->sched_class = &fair_sched_class;
 
-       p->prio = prio;
+       return &fair_sched_class;
 }
 
 #ifdef CONFIG_RT_MUTEXES
@@ -7069,7 +7084,7 @@ void rt_mutex_setprio(struct task_struct *p, struct task_struct *pi_task)
 {
        int prio, oldprio, queued, running, queue_flag =
                DEQUEUE_SAVE | DEQUEUE_MOVE | DEQUEUE_NOCLOCK;
-       const struct sched_class *prev_class;
+       const struct sched_class *prev_class, *next_class;
        struct rq_flags rf;
        struct rq *rq;
 
@@ -7127,6 +7142,11 @@ void rt_mutex_setprio(struct task_struct *p, struct task_struct *pi_task)
                queue_flag &= ~DEQUEUE_MOVE;
 
        prev_class = p->sched_class;
+       next_class = __setscheduler_class(p->policy, prio);
+
+       if (prev_class != next_class && p->se.sched_delayed)
+               dequeue_task(rq, p, DEQUEUE_SLEEP | DEQUEUE_DELAYED | DEQUEUE_NOCLOCK);
+
        queued = task_on_rq_queued(p);
        running = task_current(rq, p);
        if (queued)
@@ -7164,7 +7184,9 @@ void rt_mutex_setprio(struct task_struct *p, struct task_struct *pi_task)
                        p->rt.timeout = 0;
        }
 
-       __setscheduler_prio(p, prio);
+       p->sched_class = next_class;
+       p->prio = prio;
+
        check_class_changing(rq, p, prev_class);
 
        if (queued)
@@ -10458,7 +10480,9 @@ void task_tick_mm_cid(struct rq *rq, struct task_struct *curr)
                return;
        if (time_before(now, READ_ONCE(curr->mm->mm_cid_next_scan)))
                return;
-       task_work_add(curr, work, TWA_RESUME);
+
+       /* No page allocation under rq lock */
+       task_work_add(curr, work, TWA_RESUME | TWAF_NO_ALLOC);
 }
 
 void sched_mm_cid_exit_signals(struct task_struct *t)
index 9ce93d0bf4523a0a747721284cbf503a3c9d4a5d..be1b917dc8ce4c457109123d65cfe14c99642138 100644 (file)
@@ -2385,7 +2385,7 @@ static void set_next_task_dl(struct rq *rq, struct task_struct *p, bool first)
 
        deadline_queue_push_tasks(rq);
 
-       if (hrtick_enabled(rq))
+       if (hrtick_enabled_dl(rq))
                start_hrtick_dl(rq, &p->dl);
 }
 
index c09e3dc38c343b7a69fe3bcbdce01248f6aedb7a..b5f4b1a5ae98173866949e3a96fa86313fc61302 100644 (file)
@@ -18,6 +18,12 @@ enum scx_consts {
        SCX_EXIT_DUMP_DFL_LEN           = 32768,
 
        SCX_CPUPERF_ONE                 = SCHED_CAPACITY_SCALE,
+
+       /*
+        * Iterating all tasks may take a while. Periodically drop
+        * scx_tasks_lock to avoid causing e.g. CSD and RCU stalls.
+        */
+       SCX_OPS_TASK_ITER_BATCH         = 32,
 };
 
 enum scx_exit_kind {
@@ -624,6 +630,10 @@ struct sched_ext_ops {
        /**
         * exit - Clean up after the BPF scheduler
         * @info: Exit info
+        *
+        * ops.exit() is also called on ops.init() failure, which is a bit
+        * unusual. This is to allow rich reporting through @info on how
+        * ops.init() failed.
         */
        void (*exit)(struct scx_exit_info *info);
 
@@ -691,6 +701,7 @@ enum scx_enq_flags {
        /* expose select ENQUEUE_* flags as enums */
        SCX_ENQ_WAKEUP          = ENQUEUE_WAKEUP,
        SCX_ENQ_HEAD            = ENQUEUE_HEAD,
+       SCX_ENQ_CPU_SELECTED    = ENQUEUE_RQ_SELECTED,
 
        /* high 32bits are SCX specific */
 
@@ -778,7 +789,6 @@ enum scx_tg_flags {
 };
 
 enum scx_ops_enable_state {
-       SCX_OPS_PREPPING,
        SCX_OPS_ENABLING,
        SCX_OPS_ENABLED,
        SCX_OPS_DISABLING,
@@ -786,7 +796,6 @@ enum scx_ops_enable_state {
 };
 
 static const char *scx_ops_enable_state_str[] = {
-       [SCX_OPS_PREPPING]      = "prepping",
        [SCX_OPS_ENABLING]      = "enabling",
        [SCX_OPS_ENABLED]       = "enabled",
        [SCX_OPS_DISABLING]     = "disabling",
@@ -853,7 +862,9 @@ static DEFINE_MUTEX(scx_ops_enable_mutex);
 DEFINE_STATIC_KEY_FALSE(__scx_ops_enabled);
 DEFINE_STATIC_PERCPU_RWSEM(scx_fork_rwsem);
 static atomic_t scx_ops_enable_state_var = ATOMIC_INIT(SCX_OPS_DISABLED);
-static atomic_t scx_ops_bypass_depth = ATOMIC_INIT(0);
+static int scx_ops_bypass_depth;
+static DEFINE_RAW_SPINLOCK(__scx_ops_bypass_lock);
+static bool scx_ops_init_task_enabled;
 static bool scx_switching_all;
 DEFINE_STATIC_KEY_FALSE(__scx_switched_all);
 
@@ -925,8 +936,15 @@ static unsigned long __percpu *scx_kick_cpus_pnt_seqs;
  */
 static DEFINE_PER_CPU(struct task_struct *, direct_dispatch_task);
 
-/* dispatch queues */
-static struct scx_dispatch_q __cacheline_aligned_in_smp scx_dsq_global;
+/*
+ * Dispatch queues.
+ *
+ * The global DSQ (%SCX_DSQ_GLOBAL) is split per-node for scalability. This is
+ * to avoid live-locking in bypass mode where all tasks are dispatched to
+ * %SCX_DSQ_GLOBAL and all CPUs consume from it. If per-node split isn't
+ * sufficient, it can be further split.
+ */
+static struct scx_dispatch_q **global_dsqs;
 
 static const struct rhashtable_params dsq_hash_params = {
        .key_len                = 8,
@@ -1029,6 +1047,16 @@ static bool u32_before(u32 a, u32 b)
        return (s32)(a - b) < 0;
 }
 
+static struct scx_dispatch_q *find_global_dsq(struct task_struct *p)
+{
+       return global_dsqs[cpu_to_node(task_cpu(p))];
+}
+
+static struct scx_dispatch_q *find_user_dsq(u64 dsq_id)
+{
+       return rhashtable_lookup_fast(&dsq_hash, &dsq_id, dsq_hash_params);
+}
+
 /*
  * scx_kf_mask enforcement. Some kfuncs can only be called from specific SCX
  * ops. When invoking SCX ops, SCX_CALL_OP[_RET]() should be used to indicate
@@ -1252,86 +1280,104 @@ struct scx_task_iter {
        struct task_struct              *locked;
        struct rq                       *rq;
        struct rq_flags                 rf;
+       u32                             cnt;
 };
 
 /**
- * scx_task_iter_init - Initialize a task iterator
+ * scx_task_iter_start - Lock scx_tasks_lock and start a task iteration
  * @iter: iterator to init
  *
- * Initialize @iter. Must be called with scx_tasks_lock held. Once initialized,
- * @iter must eventually be exited with scx_task_iter_exit().
+ * Initialize @iter and return with scx_tasks_lock held. Once initialized, @iter
+ * must eventually be stopped with scx_task_iter_stop().
  *
- * scx_tasks_lock may be released between this and the first next() call or
- * between any two next() calls. If scx_tasks_lock is released between two
- * next() calls, the caller is responsible for ensuring that the task being
- * iterated remains accessible either through RCU read lock or obtaining a
- * reference count.
+ * scx_tasks_lock and the rq lock may be released using scx_task_iter_unlock()
+ * between this and the first next() call or between any two next() calls. If
+ * the locks are released between two next() calls, the caller is responsible
+ * for ensuring that the task being iterated remains accessible either through
+ * RCU read lock or obtaining a reference count.
  *
  * All tasks which existed when the iteration started are guaranteed to be
  * visited as long as they still exist.
  */
-static void scx_task_iter_init(struct scx_task_iter *iter)
+static void scx_task_iter_start(struct scx_task_iter *iter)
 {
-       lockdep_assert_held(&scx_tasks_lock);
-
        BUILD_BUG_ON(__SCX_DSQ_ITER_ALL_FLAGS &
                     ((1U << __SCX_DSQ_LNODE_PRIV_SHIFT) - 1));
 
+       spin_lock_irq(&scx_tasks_lock);
+
        iter->cursor = (struct sched_ext_entity){ .flags = SCX_TASK_CURSOR };
        list_add(&iter->cursor.tasks_node, &scx_tasks);
        iter->locked = NULL;
+       iter->cnt = 0;
+}
+
+static void __scx_task_iter_rq_unlock(struct scx_task_iter *iter)
+{
+       if (iter->locked) {
+               task_rq_unlock(iter->rq, iter->locked, &iter->rf);
+               iter->locked = NULL;
+       }
 }
 
 /**
- * scx_task_iter_rq_unlock - Unlock rq locked by a task iterator
- * @iter: iterator to unlock rq for
+ * scx_task_iter_unlock - Unlock rq and scx_tasks_lock held by a task iterator
+ * @iter: iterator to unlock
  *
  * If @iter is in the middle of a locked iteration, it may be locking the rq of
- * the task currently being visited. Unlock the rq if so. This function can be
- * safely called anytime during an iteration.
+ * the task currently being visited in addition to scx_tasks_lock. Unlock both.
+ * This function can be safely called anytime during an iteration.
+ */
+static void scx_task_iter_unlock(struct scx_task_iter *iter)
+{
+       __scx_task_iter_rq_unlock(iter);
+       spin_unlock_irq(&scx_tasks_lock);
+}
+
+/**
+ * scx_task_iter_relock - Lock scx_tasks_lock released by scx_task_iter_unlock()
+ * @iter: iterator to re-lock
  *
- * Returns %true if the rq @iter was locking is unlocked. %false if @iter was
- * not locking an rq.
+ * Re-lock scx_tasks_lock unlocked by scx_task_iter_unlock(). Note that it
+ * doesn't re-lock the rq lock. Must be called before other iterator operations.
  */
-static bool scx_task_iter_rq_unlock(struct scx_task_iter *iter)
+static void scx_task_iter_relock(struct scx_task_iter *iter)
 {
-       if (iter->locked) {
-               task_rq_unlock(iter->rq, iter->locked, &iter->rf);
-               iter->locked = NULL;
-               return true;
-       } else {
-               return false;
-       }
+       spin_lock_irq(&scx_tasks_lock);
 }
 
 /**
- * scx_task_iter_exit - Exit a task iterator
+ * scx_task_iter_stop - Stop a task iteration and unlock scx_tasks_lock
  * @iter: iterator to exit
  *
- * Exit a previously initialized @iter. Must be called with scx_tasks_lock held.
- * If the iterator holds a task's rq lock, that rq lock is released. See
- * scx_task_iter_init() for details.
+ * Exit a previously initialized @iter. Must be called with scx_tasks_lock held
+ * which is released on return. If the iterator holds a task's rq lock, that rq
+ * lock is also released. See scx_task_iter_start() for details.
  */
-static void scx_task_iter_exit(struct scx_task_iter *iter)
+static void scx_task_iter_stop(struct scx_task_iter *iter)
 {
-       lockdep_assert_held(&scx_tasks_lock);
-
-       scx_task_iter_rq_unlock(iter);
        list_del_init(&iter->cursor.tasks_node);
+       scx_task_iter_unlock(iter);
 }
 
 /**
  * scx_task_iter_next - Next task
  * @iter: iterator to walk
  *
- * Visit the next task. See scx_task_iter_init() for details.
+ * Visit the next task. See scx_task_iter_start() for details. Locks are dropped
+ * and re-acquired every %SCX_OPS_TASK_ITER_BATCH iterations to avoid causing
+ * stalls by holding scx_tasks_lock for too long.
  */
 static struct task_struct *scx_task_iter_next(struct scx_task_iter *iter)
 {
        struct list_head *cursor = &iter->cursor.tasks_node;
        struct sched_ext_entity *pos;
 
-       lockdep_assert_held(&scx_tasks_lock);
+       if (!(++iter->cnt % SCX_OPS_TASK_ITER_BATCH)) {
+               scx_task_iter_unlock(iter);
+               cond_resched();
+               scx_task_iter_relock(iter);
+       }
 
        list_for_each_entry(pos, cursor, tasks_node) {
                if (&pos->tasks_node == &scx_tasks)
@@ -1352,14 +1398,14 @@ static struct task_struct *scx_task_iter_next(struct scx_task_iter *iter)
  * @include_dead: Whether we should include dead tasks in the iteration
  *
  * Visit the non-idle task with its rq lock held. Allows callers to specify
- * whether they would like to filter out dead tasks. See scx_task_iter_init()
+ * whether they would like to filter out dead tasks. See scx_task_iter_start()
  * for details.
  */
 static struct task_struct *scx_task_iter_next_locked(struct scx_task_iter *iter)
 {
        struct task_struct *p;
 
-       scx_task_iter_rq_unlock(iter);
+       __scx_task_iter_rq_unlock(iter);
 
        while ((p = scx_task_iter_next(iter))) {
                /*
@@ -1637,7 +1683,7 @@ static void dispatch_enqueue(struct scx_dispatch_q *dsq, struct task_struct *p,
                        scx_ops_error("attempting to dispatch to a destroyed dsq");
                        /* fall back to the global dsq */
                        raw_spin_unlock(&dsq->lock);
-                       dsq = &scx_dsq_global;
+                       dsq = find_global_dsq(p);
                        raw_spin_lock(&dsq->lock);
                }
        }
@@ -1803,21 +1849,6 @@ static void dispatch_dequeue(struct rq *rq, struct task_struct *p)
                raw_spin_unlock(&dsq->lock);
 }
 
-static struct scx_dispatch_q *find_user_dsq(u64 dsq_id)
-{
-       return rhashtable_lookup_fast(&dsq_hash, &dsq_id, dsq_hash_params);
-}
-
-static struct scx_dispatch_q *find_non_local_dsq(u64 dsq_id)
-{
-       lockdep_assert(rcu_read_lock_any_held());
-
-       if (dsq_id == SCX_DSQ_GLOBAL)
-               return &scx_dsq_global;
-       else
-               return find_user_dsq(dsq_id);
-}
-
 static struct scx_dispatch_q *find_dsq_for_dispatch(struct rq *rq, u64 dsq_id,
                                                    struct task_struct *p)
 {
@@ -1830,16 +1861,20 @@ static struct scx_dispatch_q *find_dsq_for_dispatch(struct rq *rq, u64 dsq_id,
                s32 cpu = dsq_id & SCX_DSQ_LOCAL_CPU_MASK;
 
                if (!ops_cpu_valid(cpu, "in SCX_DSQ_LOCAL_ON dispatch verdict"))
-                       return &scx_dsq_global;
+                       return find_global_dsq(p);
 
                return &cpu_rq(cpu)->scx.local_dsq;
        }
 
-       dsq = find_non_local_dsq(dsq_id);
+       if (dsq_id == SCX_DSQ_GLOBAL)
+               dsq = find_global_dsq(p);
+       else
+               dsq = find_user_dsq(dsq_id);
+
        if (unlikely(!dsq)) {
                scx_ops_error("non-existent DSQ 0x%llx for %s[%d]",
                              dsq_id, p->comm, p->pid);
-               return &scx_dsq_global;
+               return find_global_dsq(p);
        }
 
        return dsq;
@@ -2011,7 +2046,7 @@ local_norefill:
 global:
        touch_core_sched(rq, p);        /* see the comment in local: */
        p->scx.slice = SCX_SLICE_DFL;
-       dispatch_enqueue(&scx_dsq_global, p, enq_flags);
+       dispatch_enqueue(find_global_dsq(p), p, enq_flags);
 }
 
 static bool task_runnable(const struct task_struct *p)
@@ -2357,6 +2392,7 @@ static bool consume_remote_task(struct rq *this_rq, struct task_struct *p,
        }
 }
 #else  /* CONFIG_SMP */
+static inline void move_remote_task_to_local_dsq(struct task_struct *p, u64 enq_flags, struct rq *src_rq, struct rq *dst_rq) { WARN_ON_ONCE(1); }
 static inline bool task_can_run_on_remote_rq(struct task_struct *p, struct rq *rq, bool trigger_error) { return false; }
 static inline bool consume_remote_task(struct rq *this_rq, struct task_struct *p, struct scx_dispatch_q *dsq, struct rq *task_rq) { return false; }
 #endif /* CONFIG_SMP */
@@ -2396,6 +2432,13 @@ retry:
        return false;
 }
 
+static bool consume_global_dsq(struct rq *rq)
+{
+       int node = cpu_to_node(cpu_of(rq));
+
+       return consume_dispatch_q(rq, global_dsqs[node]);
+}
+
 /**
  * dispatch_to_local_dsq - Dispatch a task to a local dsq
  * @rq: current rq which is locked
@@ -2429,7 +2472,8 @@ static void dispatch_to_local_dsq(struct rq *rq, struct scx_dispatch_q *dst_dsq,
 
 #ifdef CONFIG_SMP
        if (unlikely(!task_can_run_on_remote_rq(p, dst_rq, true))) {
-               dispatch_enqueue(&scx_dsq_global, p, enq_flags | SCX_ENQ_CLEAR_OPSS);
+               dispatch_enqueue(find_global_dsq(p), p,
+                                enq_flags | SCX_ENQ_CLEAR_OPSS);
                return;
        }
 
@@ -2629,7 +2673,7 @@ static int balance_one(struct rq *rq, struct task_struct *prev)
        if (rq->scx.local_dsq.nr)
                goto has_tasks;
 
-       if (consume_dispatch_q(rq, &scx_dsq_global))
+       if (consume_global_dsq(rq))
                goto has_tasks;
 
        if (!SCX_HAS_OP(dispatch) || scx_rq_bypassing(rq) || !scx_rq_online(rq))
@@ -2654,7 +2698,7 @@ static int balance_one(struct rq *rq, struct task_struct *prev)
 
                if (rq->scx.local_dsq.nr)
                        goto has_tasks;
-               if (consume_dispatch_q(rq, &scx_dsq_global))
+               if (consume_global_dsq(rq))
                        goto has_tasks;
 
                /*
@@ -2937,8 +2981,8 @@ static struct task_struct *pick_task_scx(struct rq *rq)
 
                if (unlikely(!p->scx.slice)) {
                        if (!scx_rq_bypassing(rq) && !scx_warned_zero_slice) {
-                               printk_deferred(KERN_WARNING "sched_ext: %s[%d] has zero slice in pick_next_task_scx()\n",
-                                               p->comm, p->pid);
+                               printk_deferred(KERN_WARNING "sched_ext: %s[%d] has zero slice in %s()\n",
+                                               p->comm, p->pid, __func__);
                                scx_warned_zero_slice = true;
                        }
                        p->scx.slice = SCX_SLICE_DFL;
@@ -3043,11 +3087,6 @@ static s32 scx_select_cpu_dfl(struct task_struct *p, s32 prev_cpu,
 
        *found = false;
 
-       if (!static_branch_likely(&scx_builtin_idle_enabled)) {
-               scx_ops_error("built-in idle tracking is disabled");
-               return prev_cpu;
-       }
-
        /*
         * If WAKE_SYNC, the waker's local DSQ is empty, and the system is
         * under utilized, wake up @p to the local DSQ of the waker. Checking
@@ -3058,22 +3097,13 @@ static s32 scx_select_cpu_dfl(struct task_struct *p, s32 prev_cpu,
         * there is an idle core elsewhere on the system.
         */
        cpu = smp_processor_id();
-       if ((wake_flags & SCX_WAKE_SYNC) && p->nr_cpus_allowed > 1 &&
+       if ((wake_flags & SCX_WAKE_SYNC) &&
            !cpumask_empty(idle_masks.cpu) && !(current->flags & PF_EXITING) &&
            cpu_rq(cpu)->scx.local_dsq.nr == 0) {
                if (cpumask_test_cpu(cpu, p->cpus_ptr))
                        goto cpu_found;
        }
 
-       if (p->nr_cpus_allowed == 1) {
-               if (test_and_clear_cpu_idle(prev_cpu)) {
-                       cpu = prev_cpu;
-                       goto cpu_found;
-               } else {
-                       return prev_cpu;
-               }
-       }
-
        /*
         * If CPU has SMT, any wholly idle CPU is likely a better pick than
         * partially idle @prev_cpu.
@@ -3121,7 +3151,7 @@ static int select_task_rq_scx(struct task_struct *p, int prev_cpu, int wake_flag
        if (unlikely(wake_flags & WF_EXEC))
                return prev_cpu;
 
-       if (SCX_HAS_OP(select_cpu)) {
+       if (SCX_HAS_OP(select_cpu) && !scx_rq_bypassing(task_rq(p))) {
                s32 cpu;
                struct task_struct **ddsp_taskp;
 
@@ -3186,7 +3216,7 @@ void __scx_update_idle(struct rq *rq, bool idle)
 {
        int cpu = cpu_of(rq);
 
-       if (SCX_HAS_OP(update_idle)) {
+       if (SCX_HAS_OP(update_idle) && !scx_rq_bypassing(rq)) {
                SCX_CALL_OP(SCX_KF_REST, update_idle, cpu_of(rq), idle);
                if (!static_branch_unlikely(&scx_builtin_idle_enabled))
                        return;
@@ -3550,7 +3580,7 @@ int scx_fork(struct task_struct *p)
 {
        percpu_rwsem_assert_held(&scx_fork_rwsem);
 
-       if (scx_enabled())
+       if (scx_ops_init_task_enabled)
                return scx_ops_init_task(p, task_group(p), true);
        else
                return 0;
@@ -3558,7 +3588,7 @@ int scx_fork(struct task_struct *p)
 
 void scx_post_fork(struct task_struct *p)
 {
-       if (scx_enabled()) {
+       if (scx_ops_init_task_enabled) {
                scx_set_task_state(p, SCX_TASK_READY);
 
                /*
@@ -3690,6 +3720,7 @@ bool scx_can_stop_tick(struct rq *rq)
 #ifdef CONFIG_EXT_GROUP_SCHED
 
 DEFINE_STATIC_PERCPU_RWSEM(scx_cgroup_rwsem);
+static bool scx_cgroup_enabled;
 static bool cgroup_warned_missing_weight;
 static bool cgroup_warned_missing_idle;
 
@@ -3709,8 +3740,7 @@ static void scx_cgroup_warn_missing_weight(struct task_group *tg)
 
 static void scx_cgroup_warn_missing_idle(struct task_group *tg)
 {
-       if (scx_ops_enable_state() == SCX_OPS_DISABLED ||
-           cgroup_warned_missing_idle)
+       if (!scx_cgroup_enabled || cgroup_warned_missing_idle)
                return;
 
        if (!tg->idle)
@@ -3731,15 +3761,18 @@ int scx_tg_online(struct task_group *tg)
 
        scx_cgroup_warn_missing_weight(tg);
 
-       if (SCX_HAS_OP(cgroup_init)) {
-               struct scx_cgroup_init_args args = { .weight = tg->scx_weight };
+       if (scx_cgroup_enabled) {
+               if (SCX_HAS_OP(cgroup_init)) {
+                       struct scx_cgroup_init_args args =
+                               { .weight = tg->scx_weight };
 
-               ret = SCX_CALL_OP_RET(SCX_KF_UNLOCKED, cgroup_init,
-                                     tg->css.cgroup, &args);
-               if (!ret)
+                       ret = SCX_CALL_OP_RET(SCX_KF_UNLOCKED, cgroup_init,
+                                             tg->css.cgroup, &args);
+                       if (ret)
+                               ret = ops_sanitize_err("cgroup_init", ret);
+               }
+               if (ret == 0)
                        tg->scx_flags |= SCX_TG_ONLINE | SCX_TG_INITED;
-               else
-                       ret = ops_sanitize_err("cgroup_init", ret);
        } else {
                tg->scx_flags |= SCX_TG_ONLINE;
        }
@@ -3770,7 +3803,7 @@ int scx_cgroup_can_attach(struct cgroup_taskset *tset)
        /* released in scx_finish/cancel_attach() */
        percpu_down_read(&scx_cgroup_rwsem);
 
-       if (!scx_enabled())
+       if (!scx_cgroup_enabled)
                return 0;
 
        cgroup_taskset_for_each(p, css, tset) {
@@ -3813,7 +3846,7 @@ err:
 
 void scx_move_task(struct task_struct *p)
 {
-       if (!scx_enabled())
+       if (!scx_cgroup_enabled)
                return;
 
        /*
@@ -3849,7 +3882,7 @@ void scx_cgroup_cancel_attach(struct cgroup_taskset *tset)
        struct cgroup_subsys_state *css;
        struct task_struct *p;
 
-       if (!scx_enabled())
+       if (!scx_cgroup_enabled)
                goto out_unlock;
 
        cgroup_taskset_for_each(p, css, tset) {
@@ -3866,7 +3899,7 @@ void scx_group_set_weight(struct task_group *tg, unsigned long weight)
 {
        percpu_down_read(&scx_cgroup_rwsem);
 
-       if (tg->scx_weight != weight) {
+       if (scx_cgroup_enabled && tg->scx_weight != weight) {
                if (SCX_HAS_OP(cgroup_set_weight))
                        SCX_CALL_OP(SCX_KF_UNLOCKED, cgroup_set_weight,
                                    tg_cgrp(tg), weight);
@@ -4038,6 +4071,8 @@ static void scx_cgroup_exit(void)
 
        percpu_rwsem_assert_held(&scx_cgroup_rwsem);
 
+       scx_cgroup_enabled = false;
+
        /*
         * scx_tg_on/offline() are excluded through scx_cgroup_rwsem. If we walk
         * cgroups and exit all the inited ones, all online cgroups are exited.
@@ -4104,6 +4139,7 @@ static int scx_cgroup_init(void)
                                      css->cgroup, &args);
                if (ret) {
                        css_put(css);
+                       scx_ops_error("ops.cgroup_init() failed (%d)", ret);
                        return ret;
                }
                tg->scx_flags |= SCX_TG_INITED;
@@ -4113,6 +4149,9 @@ static int scx_cgroup_init(void)
        }
        rcu_read_unlock();
 
+       WARN_ON_ONCE(scx_cgroup_enabled);
+       scx_cgroup_enabled = true;
+
        return 0;
 }
 
@@ -4218,14 +4257,14 @@ static const struct kset_uevent_ops scx_uevent_ops = {
  * Used by sched_fork() and __setscheduler_prio() to pick the matching
  * sched_class. dl/rt are already handled.
  */
-bool task_should_scx(struct task_struct *p)
+bool task_should_scx(int policy)
 {
        if (!scx_enabled() ||
            unlikely(scx_ops_enable_state() == SCX_OPS_DISABLING))
                return false;
        if (READ_ONCE(scx_switching_all))
                return true;
-       return p->policy == SCHED_EXT;
+       return policy == SCHED_EXT;
 }
 
 /**
@@ -4240,36 +4279,40 @@ bool task_should_scx(struct task_struct *p)
  * the DISABLING state and then cycling the queued tasks through dequeue/enqueue
  * to force global FIFO scheduling.
  *
- * a. ops.enqueue() is ignored and tasks are queued in simple global FIFO order.
- *    %SCX_OPS_ENQ_LAST is also ignored.
+ * - ops.select_cpu() is ignored and the default select_cpu() is used.
+ *
+ * - ops.enqueue() is ignored and tasks are queued in simple global FIFO order.
+ *   %SCX_OPS_ENQ_LAST is also ignored.
  *
- * b. ops.dispatch() is ignored.
+ * - ops.dispatch() is ignored.
  *
- * c. balance_scx() does not set %SCX_RQ_BAL_KEEP on non-zero slice as slice
- *    can't be trusted. Whenever a tick triggers, the running task is rotated to
- *    the tail of the queue with core_sched_at touched.
+ * - balance_scx() does not set %SCX_RQ_BAL_KEEP on non-zero slice as slice
+ *   can't be trusted. Whenever a tick triggers, the running task is rotated to
+ *   the tail of the queue with core_sched_at touched.
  *
- * d. pick_next_task() suppresses zero slice warning.
+ * - pick_next_task() suppresses zero slice warning.
  *
- * e. scx_bpf_kick_cpu() is disabled to avoid irq_work malfunction during PM
- *    operations.
+ * - scx_bpf_kick_cpu() is disabled to avoid irq_work malfunction during PM
+ *   operations.
  *
- * f. scx_prio_less() reverts to the default core_sched_at order.
+ * - scx_prio_less() reverts to the default core_sched_at order.
  */
 static void scx_ops_bypass(bool bypass)
 {
-       int depth, cpu;
+       int cpu;
+       unsigned long flags;
 
+       raw_spin_lock_irqsave(&__scx_ops_bypass_lock, flags);
        if (bypass) {
-               depth = atomic_inc_return(&scx_ops_bypass_depth);
-               WARN_ON_ONCE(depth <= 0);
-               if (depth != 1)
-                       return;
+               scx_ops_bypass_depth++;
+               WARN_ON_ONCE(scx_ops_bypass_depth <= 0);
+               if (scx_ops_bypass_depth != 1)
+                       goto unlock;
        } else {
-               depth = atomic_dec_return(&scx_ops_bypass_depth);
-               WARN_ON_ONCE(depth < 0);
-               if (depth != 0)
-                       return;
+               scx_ops_bypass_depth--;
+               WARN_ON_ONCE(scx_ops_bypass_depth < 0);
+               if (scx_ops_bypass_depth != 0)
+                       goto unlock;
        }
 
        /*
@@ -4286,7 +4329,7 @@ static void scx_ops_bypass(bool bypass)
                struct rq_flags rf;
                struct task_struct *p, *n;
 
-               rq_lock_irqsave(rq, &rf);
+               rq_lock(rq, &rf);
 
                if (bypass) {
                        WARN_ON_ONCE(rq->scx.flags & SCX_RQ_BYPASSING);
@@ -4322,11 +4365,13 @@ static void scx_ops_bypass(bool bypass)
                        sched_enq_and_set_task(&ctx);
                }
 
-               rq_unlock_irqrestore(rq, &rf);
+               rq_unlock(rq, &rf);
 
-               /* kick to restore ticks */
+               /* resched to restore ticks and idle state */
                resched_cpu(cpu);
        }
+unlock:
+       raw_spin_unlock_irqrestore(&__scx_ops_bypass_lock, flags);
 }
 
 static void free_exit_info(struct scx_exit_info *ei)
@@ -4431,27 +4476,34 @@ static void scx_ops_disable_workfn(struct kthread_work *work)
        WRITE_ONCE(scx_switching_all, false);
 
        /*
-        * Avoid racing against fork and cgroup changes. See scx_ops_enable()
-        * for explanation on the locking order.
+        * Shut down cgroup support before tasks so that the cgroup attach path
+        * doesn't race against scx_ops_exit_task().
         */
-       percpu_down_write(&scx_fork_rwsem);
-       cpus_read_lock();
        scx_cgroup_lock();
+       scx_cgroup_exit();
+       scx_cgroup_unlock();
 
-       spin_lock_irq(&scx_tasks_lock);
-       scx_task_iter_init(&sti);
        /*
         * The BPF scheduler is going away. All tasks including %TASK_DEAD ones
         * must be switched out and exited synchronously.
         */
+       percpu_down_write(&scx_fork_rwsem);
+
+       scx_ops_init_task_enabled = false;
+
+       scx_task_iter_start(&sti);
        while ((p = scx_task_iter_next_locked(&sti))) {
                const struct sched_class *old_class = p->sched_class;
+               const struct sched_class *new_class =
+                       __setscheduler_class(p->policy, p->prio);
                struct sched_enq_and_set_ctx ctx;
 
+               if (old_class != new_class && p->se.sched_delayed)
+                       dequeue_task(task_rq(p), p, DEQUEUE_SLEEP | DEQUEUE_DELAYED);
+
                sched_deq_and_put_task(p, DEQUEUE_SAVE | DEQUEUE_MOVE, &ctx);
 
-               p->scx.slice = min_t(u64, p->scx.slice, SCX_SLICE_DFL);
-               __setscheduler_prio(p, p->prio);
+               p->sched_class = new_class;
                check_class_changing(task_rq(p), p, old_class);
 
                sched_enq_and_set_task(&ctx);
@@ -4459,25 +4511,19 @@ static void scx_ops_disable_workfn(struct kthread_work *work)
                check_class_changed(task_rq(p), p, old_class, p->prio);
                scx_ops_exit_task(p);
        }
-       scx_task_iter_exit(&sti);
-       spin_unlock_irq(&scx_tasks_lock);
+       scx_task_iter_stop(&sti);
+       percpu_up_write(&scx_fork_rwsem);
 
        /* no task is on scx, turn off all the switches and flush in-progress calls */
-       static_branch_disable_cpuslocked(&__scx_ops_enabled);
+       static_branch_disable(&__scx_ops_enabled);
        for (i = SCX_OPI_BEGIN; i < SCX_OPI_END; i++)
-               static_branch_disable_cpuslocked(&scx_has_op[i]);
-       static_branch_disable_cpuslocked(&scx_ops_enq_last);
-       static_branch_disable_cpuslocked(&scx_ops_enq_exiting);
-       static_branch_disable_cpuslocked(&scx_ops_cpu_preempt);
-       static_branch_disable_cpuslocked(&scx_builtin_idle_enabled);
+               static_branch_disable(&scx_has_op[i]);
+       static_branch_disable(&scx_ops_enq_last);
+       static_branch_disable(&scx_ops_enq_exiting);
+       static_branch_disable(&scx_ops_cpu_preempt);
+       static_branch_disable(&scx_builtin_idle_enabled);
        synchronize_rcu();
 
-       scx_cgroup_exit();
-
-       scx_cgroup_unlock();
-       cpus_read_unlock();
-       percpu_up_write(&scx_fork_rwsem);
-
        if (ei->kind >= SCX_EXIT_ERROR) {
                pr_err("sched_ext: BPF scheduler \"%s\" disabled (%s)\n",
                       scx_ops.name, ei->reason);
@@ -4929,7 +4975,7 @@ static int scx_ops_enable(struct sched_ext_ops *ops, struct bpf_link *link)
        struct scx_task_iter sti;
        struct task_struct *p;
        unsigned long timeout;
-       int i, cpu, ret;
+       int i, cpu, node, ret;
 
        if (!cpumask_equal(housekeeping_cpumask(HK_TYPE_DOMAIN),
                           cpu_possible_mask)) {
@@ -4948,6 +4994,34 @@ static int scx_ops_enable(struct sched_ext_ops *ops, struct bpf_link *link)
                }
        }
 
+       if (!global_dsqs) {
+               struct scx_dispatch_q **dsqs;
+
+               dsqs = kcalloc(nr_node_ids, sizeof(dsqs[0]), GFP_KERNEL);
+               if (!dsqs) {
+                       ret = -ENOMEM;
+                       goto err_unlock;
+               }
+
+               for_each_node_state(node, N_POSSIBLE) {
+                       struct scx_dispatch_q *dsq;
+
+                       dsq = kzalloc_node(sizeof(*dsq), GFP_KERNEL, node);
+                       if (!dsq) {
+                               for_each_node_state(node, N_POSSIBLE)
+                                       kfree(dsqs[node]);
+                               kfree(dsqs);
+                               ret = -ENOMEM;
+                               goto err_unlock;
+                       }
+
+                       init_dsq(dsq, SCX_DSQ_GLOBAL);
+                       dsqs[node] = dsq;
+               }
+
+               global_dsqs = dsqs;
+       }
+
        if (scx_ops_enable_state() != SCX_OPS_DISABLED) {
                ret = -EBUSY;
                goto err_unlock;
@@ -4971,12 +5045,12 @@ static int scx_ops_enable(struct sched_ext_ops *ops, struct bpf_link *link)
        }
 
        /*
-        * Set scx_ops, transition to PREPPING and clear exit info to arm the
+        * Set scx_ops, transition to ENABLING and clear exit info to arm the
         * disable path. Failure triggers full disabling from here on.
         */
        scx_ops = *ops;
 
-       WARN_ON_ONCE(scx_ops_set_enable_state(SCX_OPS_PREPPING) !=
+       WARN_ON_ONCE(scx_ops_set_enable_state(SCX_OPS_ENABLING) !=
                     SCX_OPS_DISABLED);
 
        atomic_set(&scx_exit_kind, SCX_EXIT_NONE);
@@ -4997,7 +5071,9 @@ static int scx_ops_enable(struct sched_ext_ops *ops, struct bpf_link *link)
                ret = SCX_CALL_OP_RET(SCX_KF_UNLOCKED, init);
                if (ret) {
                        ret = ops_sanitize_err("init", ret);
-                       goto err_disable_unlock_cpus;
+                       cpus_read_unlock();
+                       scx_ops_error("ops.init() failed (%d)", ret);
+                       goto err_disable;
                }
        }
 
@@ -5005,6 +5081,7 @@ static int scx_ops_enable(struct sched_ext_ops *ops, struct bpf_link *link)
                if (((void (**)(void))ops)[i])
                        static_branch_enable_cpuslocked(&scx_has_op[i]);
 
+       check_hotplug_seq(ops);
        cpus_read_unlock();
 
        ret = validate_ops(ops);
@@ -5032,57 +5109,40 @@ static int scx_ops_enable(struct sched_ext_ops *ops, struct bpf_link *link)
                           scx_watchdog_timeout / 2);
 
        /*
-        * Lock out forks, cgroup on/offlining and moves before opening the
-        * floodgate so that they don't wander into the operations prematurely.
-        *
-        * We don't need to keep the CPUs stable but static_branch_*() requires
-        * cpus_read_lock() and scx_cgroup_rwsem must nest inside
-        * cpu_hotplug_lock because of the following dependency chain:
-        *
-        *   cpu_hotplug_lock --> cgroup_threadgroup_rwsem --> scx_cgroup_rwsem
-        *
-        * So, we need to do cpus_read_lock() before scx_cgroup_lock() and use
-        * static_branch_*_cpuslocked().
-        *
-        * Note that cpu_hotplug_lock must nest inside scx_fork_rwsem due to the
-        * following dependency chain:
-        *
-        *   scx_fork_rwsem --> pernet_ops_rwsem --> cpu_hotplug_lock
+        * Once __scx_ops_enabled is set, %current can be switched to SCX
+        * anytime. This can lead to stalls as some BPF schedulers (e.g.
+        * userspace scheduling) may not function correctly before all tasks are
+        * switched. Init in bypass mode to guarantee forward progress.
         */
-       percpu_down_write(&scx_fork_rwsem);
-       cpus_read_lock();
-       scx_cgroup_lock();
-
-       check_hotplug_seq(ops);
+       scx_ops_bypass(true);
 
        for (i = SCX_OPI_NORMAL_BEGIN; i < SCX_OPI_NORMAL_END; i++)
                if (((void (**)(void))ops)[i])
-                       static_branch_enable_cpuslocked(&scx_has_op[i]);
+                       static_branch_enable(&scx_has_op[i]);
 
        if (ops->flags & SCX_OPS_ENQ_LAST)
-               static_branch_enable_cpuslocked(&scx_ops_enq_last);
+               static_branch_enable(&scx_ops_enq_last);
 
        if (ops->flags & SCX_OPS_ENQ_EXITING)
-               static_branch_enable_cpuslocked(&scx_ops_enq_exiting);
+               static_branch_enable(&scx_ops_enq_exiting);
        if (scx_ops.cpu_acquire || scx_ops.cpu_release)
-               static_branch_enable_cpuslocked(&scx_ops_cpu_preempt);
+               static_branch_enable(&scx_ops_cpu_preempt);
 
        if (!ops->update_idle || (ops->flags & SCX_OPS_KEEP_BUILTIN_IDLE)) {
                reset_idle_masks();
-               static_branch_enable_cpuslocked(&scx_builtin_idle_enabled);
+               static_branch_enable(&scx_builtin_idle_enabled);
        } else {
-               static_branch_disable_cpuslocked(&scx_builtin_idle_enabled);
+               static_branch_disable(&scx_builtin_idle_enabled);
        }
 
        /*
-        * All cgroups should be initialized before letting in tasks. cgroup
-        * on/offlining and task migrations are already locked out.
+        * Lock out forks, cgroup on/offlining and moves before opening the
+        * floodgate so that they don't wander into the operations prematurely.
         */
-       ret = scx_cgroup_init();
-       if (ret)
-               goto err_disable_unlock_all;
+       percpu_down_write(&scx_fork_rwsem);
 
-       static_branch_enable_cpuslocked(&__scx_ops_enabled);
+       WARN_ON_ONCE(scx_ops_init_task_enabled);
+       scx_ops_init_task_enabled = true;
 
        /*
         * Enable ops for every task. Fork is excluded by scx_fork_rwsem
@@ -5090,10 +5150,19 @@ static int scx_ops_enable(struct sched_ext_ops *ops, struct bpf_link *link)
         * leaving as sched_ext_free() can handle both prepped and enabled
         * tasks. Prep all tasks first and then enable them with preemption
         * disabled.
+        *
+        * All cgroups should be initialized before scx_ops_init_task() so that
+        * the BPF scheduler can reliably track each task's cgroup membership
+        * from scx_ops_init_task(). Lock out cgroup on/offlining and task
+        * migrations while tasks are being initialized so that
+        * scx_cgroup_can_attach() never sees uninitialized tasks.
         */
-       spin_lock_irq(&scx_tasks_lock);
+       scx_cgroup_lock();
+       ret = scx_cgroup_init();
+       if (ret)
+               goto err_disable_unlock_all;
 
-       scx_task_iter_init(&sti);
+       scx_task_iter_start(&sti);
        while ((p = scx_task_iter_next_locked(&sti))) {
                /*
                 * @p may already be dead, have lost all its usages counts and
@@ -5103,84 +5172,67 @@ static int scx_ops_enable(struct sched_ext_ops *ops, struct bpf_link *link)
                if (!tryget_task_struct(p))
                        continue;
 
-               scx_task_iter_rq_unlock(&sti);
-               spin_unlock_irq(&scx_tasks_lock);
+               scx_task_iter_unlock(&sti);
 
                ret = scx_ops_init_task(p, task_group(p), false);
                if (ret) {
                        put_task_struct(p);
-                       spin_lock_irq(&scx_tasks_lock);
-                       scx_task_iter_exit(&sti);
-                       spin_unlock_irq(&scx_tasks_lock);
-                       pr_err("sched_ext: ops.init_task() failed (%d) for %s[%d] while loading\n",
-                              ret, p->comm, p->pid);
+                       scx_task_iter_relock(&sti);
+                       scx_task_iter_stop(&sti);
+                       scx_ops_error("ops.init_task() failed (%d) for %s[%d]",
+                                     ret, p->comm, p->pid);
                        goto err_disable_unlock_all;
                }
 
+               scx_set_task_state(p, SCX_TASK_READY);
+
                put_task_struct(p);
-               spin_lock_irq(&scx_tasks_lock);
+               scx_task_iter_relock(&sti);
        }
-       scx_task_iter_exit(&sti);
+       scx_task_iter_stop(&sti);
+       scx_cgroup_unlock();
+       percpu_up_write(&scx_fork_rwsem);
 
        /*
-        * All tasks are prepped but are still ops-disabled. Ensure that
-        * %current can't be scheduled out and switch everyone.
-        * preempt_disable() is necessary because we can't guarantee that
-        * %current won't be starved if scheduled out while switching.
+        * All tasks are READY. It's safe to turn on scx_enabled() and switch
+        * all eligible tasks.
         */
-       preempt_disable();
-
-       /*
-        * From here on, the disable path must assume that tasks have ops
-        * enabled and need to be recovered.
-        *
-        * Transition to ENABLING fails iff the BPF scheduler has already
-        * triggered scx_bpf_error(). Returning an error code here would lose
-        * the recorded error information. Exit indicating success so that the
-        * error is notified through ops.exit() with all the details.
-        */
-       if (!scx_ops_tryset_enable_state(SCX_OPS_ENABLING, SCX_OPS_PREPPING)) {
-               preempt_enable();
-               spin_unlock_irq(&scx_tasks_lock);
-               WARN_ON_ONCE(atomic_read(&scx_exit_kind) == SCX_EXIT_NONE);
-               ret = 0;
-               goto err_disable_unlock_all;
-       }
+       WRITE_ONCE(scx_switching_all, !(ops->flags & SCX_OPS_SWITCH_PARTIAL));
+       static_branch_enable(&__scx_ops_enabled);
 
        /*
-        * We're fully committed and can't fail. The PREPPED -> ENABLED
+        * We're fully committed and can't fail. The task READY -> ENABLED
         * transitions here are synchronized against sched_ext_free() through
         * scx_tasks_lock.
         */
-       WRITE_ONCE(scx_switching_all, !(ops->flags & SCX_OPS_SWITCH_PARTIAL));
-
-       scx_task_iter_init(&sti);
+       percpu_down_write(&scx_fork_rwsem);
+       scx_task_iter_start(&sti);
        while ((p = scx_task_iter_next_locked(&sti))) {
                const struct sched_class *old_class = p->sched_class;
+               const struct sched_class *new_class =
+                       __setscheduler_class(p->policy, p->prio);
                struct sched_enq_and_set_ctx ctx;
 
+               if (old_class != new_class && p->se.sched_delayed)
+                       dequeue_task(task_rq(p), p, DEQUEUE_SLEEP | DEQUEUE_DELAYED);
+
                sched_deq_and_put_task(p, DEQUEUE_SAVE | DEQUEUE_MOVE, &ctx);
 
-               scx_set_task_state(p, SCX_TASK_READY);
-               __setscheduler_prio(p, p->prio);
+               p->scx.slice = SCX_SLICE_DFL;
+               p->sched_class = new_class;
                check_class_changing(task_rq(p), p, old_class);
 
                sched_enq_and_set_task(&ctx);
 
                check_class_changed(task_rq(p), p, old_class, p->prio);
        }
-       scx_task_iter_exit(&sti);
-
-       spin_unlock_irq(&scx_tasks_lock);
-       preempt_enable();
-       scx_cgroup_unlock();
-       cpus_read_unlock();
+       scx_task_iter_stop(&sti);
        percpu_up_write(&scx_fork_rwsem);
 
-       /* see above ENABLING transition for the explanation on exiting with 0 */
+       scx_ops_bypass(false);
+
        if (!scx_ops_tryset_enable_state(SCX_OPS_ENABLED, SCX_OPS_ENABLING)) {
                WARN_ON_ONCE(atomic_read(&scx_exit_kind) == SCX_EXIT_NONE);
-               ret = 0;
                goto err_disable;
        }
 
@@ -5212,14 +5264,21 @@ err_unlock:
 err_disable_unlock_all:
        scx_cgroup_unlock();
        percpu_up_write(&scx_fork_rwsem);
-err_disable_unlock_cpus:
-       cpus_read_unlock();
+       scx_ops_bypass(false);
 err_disable:
        mutex_unlock(&scx_ops_enable_mutex);
-       /* must be fully disabled before returning */
-       scx_ops_disable(SCX_EXIT_ERROR);
+       /*
+        * Returning an error code here would not pass all the error information
+        * to userspace. Record errno using scx_ops_error() for cases
+        * scx_ops_error() wasn't already invoked and exit indicating success so
+        * that the error is notified through ops.exit() with all the details.
+        *
+        * Flush scx_ops_disable_work to ensure that error is reported before
+        * init completion.
+        */
+       scx_ops_error("scx_ops_enable() failed (%d)", ret);
        kthread_flush_work(&scx_ops_disable_work);
-       return ret;
+       return 0;
 }
 
 
@@ -5782,7 +5841,6 @@ void __init init_sched_ext_class(void)
                   SCX_TG_ONLINE);
 
        BUG_ON(rhashtable_init(&dsq_hash, &dsq_hash_params));
-       init_dsq(&scx_dsq_global, SCX_DSQ_GLOBAL);
 #ifdef CONFIG_SMP
        BUG_ON(!alloc_cpumask_var(&idle_masks.cpu, GFP_KERNEL));
        BUG_ON(!alloc_cpumask_var(&idle_masks.smt, GFP_KERNEL));
@@ -5840,16 +5898,21 @@ __bpf_kfunc_start_defs();
 __bpf_kfunc s32 scx_bpf_select_cpu_dfl(struct task_struct *p, s32 prev_cpu,
                                       u64 wake_flags, bool *is_idle)
 {
-       if (!scx_kf_allowed(SCX_KF_SELECT_CPU)) {
-               *is_idle = false;
-               return prev_cpu;
+       if (!static_branch_likely(&scx_builtin_idle_enabled)) {
+               scx_ops_error("built-in idle tracking is disabled");
+               goto prev_cpu;
        }
+
+       if (!scx_kf_allowed(SCX_KF_SELECT_CPU))
+               goto prev_cpu;
+
 #ifdef CONFIG_SMP
        return scx_select_cpu_dfl(p, prev_cpu, wake_flags, is_idle);
-#else
+#endif
+
+prev_cpu:
        *is_idle = false;
        return prev_cpu;
-#endif
 }
 
 __bpf_kfunc_end_defs();
@@ -6058,7 +6121,7 @@ static bool scx_dispatch_from_dsq(struct bpf_iter_scx_dsq_kern *kit,
        if (dst_dsq->id == SCX_DSQ_LOCAL) {
                dst_rq = container_of(dst_dsq, struct rq, scx.local_dsq);
                if (!task_can_run_on_remote_rq(p, dst_rq, true)) {
-                       dst_dsq = &scx_dsq_global;
+                       dst_dsq = find_global_dsq(p);
                        dst_rq = src_rq;
                }
        } else {
@@ -6175,7 +6238,7 @@ __bpf_kfunc bool scx_bpf_consume(u64 dsq_id)
 
        flush_dispatch_buf(dspc->rq);
 
-       dsq = find_non_local_dsq(dsq_id);
+       dsq = find_user_dsq(dsq_id);
        if (unlikely(!dsq)) {
                scx_ops_error("invalid DSQ ID 0x%016llx", dsq_id);
                return false;
@@ -6496,7 +6559,7 @@ __bpf_kfunc s32 scx_bpf_dsq_nr_queued(u64 dsq_id)
                        goto out;
                }
        } else {
-               dsq = find_non_local_dsq(dsq_id);
+               dsq = find_user_dsq(dsq_id);
                if (dsq) {
                        ret = READ_ONCE(dsq->nr);
                        goto out;
@@ -6545,7 +6608,7 @@ __bpf_kfunc int bpf_iter_scx_dsq_new(struct bpf_iter_scx_dsq *it, u64 dsq_id,
        if (flags & ~__SCX_DSQ_ITER_USER_FLAGS)
                return -EINVAL;
 
-       kit->dsq = find_non_local_dsq(dsq_id);
+       kit->dsq = find_user_dsq(dsq_id);
        if (!kit->dsq)
                return -ENOENT;
 
index 246019519231cf03ccd6bf68376b54e5f3119e6c..b1675bb59fc4610f59b8868dcc029a3b58008d18 100644 (file)
@@ -18,7 +18,7 @@ bool scx_can_stop_tick(struct rq *rq);
 void scx_rq_activate(struct rq *rq);
 void scx_rq_deactivate(struct rq *rq);
 int scx_check_setscheduler(struct task_struct *p, int policy);
-bool task_should_scx(struct task_struct *p);
+bool task_should_scx(int policy);
 void init_sched_ext_class(void);
 
 static inline u32 scx_cpuperf_target(s32 cpu)
index 225b31aaee558a5bd6cfbc85eac9647d84c1a762..2d16c8545c71ed129f58e6c05820183a644fa741 100644 (file)
@@ -1247,7 +1247,7 @@ static void update_curr(struct cfs_rq *cfs_rq)
 
        account_cfs_rq_runtime(cfs_rq, delta_exec);
 
-       if (rq->nr_running == 1)
+       if (cfs_rq->nr_running == 1)
                return;
 
        if (resched || did_preempt_short(cfs_rq, curr)) {
@@ -3369,7 +3369,7 @@ retry_pids:
                vma = vma_next(&vmi);
        }
 
-       do {
+       for (; vma; vma = vma_next(&vmi)) {
                if (!vma_migratable(vma) || !vma_policy_mof(vma) ||
                        is_vm_hugetlb_page(vma) || (vma->vm_flags & VM_MIXEDMAP)) {
                        trace_sched_skip_vma_numa(mm, vma, NUMAB_SKIP_UNSUITABLE);
@@ -3491,7 +3491,7 @@ retry_pids:
                 */
                if (vma_pids_forced)
                        break;
-       } for_each_vma(vmi, vma);
+       }
 
        /*
         * If no VMAs are remaining and VMAs were skipped due to the PID
@@ -5625,8 +5625,9 @@ pick_next_entity(struct rq *rq, struct cfs_rq *cfs_rq)
        struct sched_entity *se = pick_eevdf(cfs_rq);
        if (se->sched_delayed) {
                dequeue_entities(rq, se, DEQUEUE_SLEEP | DEQUEUE_DELAYED);
-               SCHED_WARN_ON(se->sched_delayed);
-               SCHED_WARN_ON(se->on_rq);
+               /*
+                * Must not reference @se again, see __block_task().
+                */
                return NULL;
        }
        return se;
@@ -6058,10 +6059,13 @@ void unthrottle_cfs_rq(struct cfs_rq *cfs_rq)
        for_each_sched_entity(se) {
                struct cfs_rq *qcfs_rq = cfs_rq_of(se);
 
-               if (se->on_rq) {
-                       SCHED_WARN_ON(se->sched_delayed);
+               /* Handle any unfinished DELAY_DEQUEUE business first. */
+               if (se->sched_delayed) {
+                       int flags = DEQUEUE_SLEEP | DEQUEUE_DELAYED;
+
+                       dequeue_entity(qcfs_rq, se, flags);
+               } else if (se->on_rq)
                        break;
-               }
                enqueue_entity(qcfs_rq, se, ENQUEUE_WAKEUP);
 
                if (cfs_rq_is_idle(group_cfs_rq(se)))
@@ -7173,7 +7177,11 @@ static int dequeue_entities(struct rq *rq, struct sched_entity *se, int flags)
                /* Fix-up what dequeue_task_fair() skipped */
                hrtick_update(rq);
 
-               /* Fix-up what block_task() skipped. */
+               /*
+                * Fix-up what block_task() skipped.
+                *
+                * Must be last, @p might not be valid after this.
+                */
                __block_task(rq, p);
        }
 
@@ -7190,12 +7198,14 @@ static bool dequeue_task_fair(struct rq *rq, struct task_struct *p, int flags)
        if (!(p->se.sched_delayed && (task_on_rq_migrating(p) || (flags & DEQUEUE_SAVE))))
                util_est_dequeue(&rq->cfs, p);
 
-       if (dequeue_entities(rq, &p->se, flags) < 0) {
-               util_est_update(&rq->cfs, p, DEQUEUE_SLEEP);
+       util_est_update(&rq->cfs, p, flags & DEQUEUE_SLEEP);
+       if (dequeue_entities(rq, &p->se, flags) < 0)
                return false;
-       }
 
-       util_est_update(&rq->cfs, p, flags & DEQUEUE_SLEEP);
+       /*
+        * Must not reference @p after dequeue_entities(DEQUEUE_DELAYED).
+        */
+
        hrtick_update(rq);
        return true;
 }
@@ -13174,22 +13184,6 @@ static void attach_task_cfs_rq(struct task_struct *p)
 static void switched_from_fair(struct rq *rq, struct task_struct *p)
 {
        detach_task_cfs_rq(p);
-       /*
-        * Since this is called after changing class, this is a little weird
-        * and we cannot use DEQUEUE_DELAYED.
-        */
-       if (p->se.sched_delayed) {
-               /* First, dequeue it from its new class' structures */
-               dequeue_task(rq, p, DEQUEUE_NOCLOCK | DEQUEUE_SLEEP);
-               /*
-                * Now, clean up the fair_sched_class side of things
-                * related to sched_delayed being true and that wasn't done
-                * due to the generic dequeue not using DEQUEUE_DELAYED.
-                */
-               finish_delayed_dequeue_entity(&p->se);
-               p->se.rel_deadline = 0;
-               __block_task(rq, p);
-       }
 }
 
 static void switched_to_fair(struct rq *rq, struct task_struct *p)
index 020d58967d4e8e13197f6547a35f0de7bbb7efe3..84dad1511d1e48bf7e1bbac46a93ab968a428ed0 100644 (file)
@@ -769,12 +769,13 @@ static void record_times(struct psi_group_cpu *groupc, u64 now)
 }
 
 static void psi_group_change(struct psi_group *group, int cpu,
-                            unsigned int clear, unsigned int set, u64 now,
+                            unsigned int clear, unsigned int set,
                             bool wake_clock)
 {
        struct psi_group_cpu *groupc;
        unsigned int t, m;
        u32 state_mask;
+       u64 now;
 
        lockdep_assert_rq_held(cpu_rq(cpu));
        groupc = per_cpu_ptr(group->pcpu, cpu);
@@ -789,6 +790,7 @@ static void psi_group_change(struct psi_group *group, int cpu,
         * SOME and FULL time these may have resulted in.
         */
        write_seqcount_begin(&groupc->seq);
+       now = cpu_clock(cpu);
 
        /*
         * Start with TSK_ONCPU, which doesn't have a corresponding
@@ -899,18 +901,15 @@ void psi_task_change(struct task_struct *task, int clear, int set)
 {
        int cpu = task_cpu(task);
        struct psi_group *group;
-       u64 now;
 
        if (!task->pid)
                return;
 
        psi_flags_change(task, clear, set);
 
-       now = cpu_clock(cpu);
-
        group = task_psi_group(task);
        do {
-               psi_group_change(group, cpu, clear, set, now, true);
+               psi_group_change(group, cpu, clear, set, true);
        } while ((group = group->parent));
 }
 
@@ -919,7 +918,6 @@ void psi_task_switch(struct task_struct *prev, struct task_struct *next,
 {
        struct psi_group *group, *common = NULL;
        int cpu = task_cpu(prev);
-       u64 now = cpu_clock(cpu);
 
        if (next->pid) {
                psi_flags_change(next, 0, TSK_ONCPU);
@@ -936,7 +934,7 @@ void psi_task_switch(struct task_struct *prev, struct task_struct *next,
                                break;
                        }
 
-                       psi_group_change(group, cpu, 0, TSK_ONCPU, now, true);
+                       psi_group_change(group, cpu, 0, TSK_ONCPU, true);
                } while ((group = group->parent));
        }
 
@@ -974,7 +972,7 @@ void psi_task_switch(struct task_struct *prev, struct task_struct *next,
                do {
                        if (group == common)
                                break;
-                       psi_group_change(group, cpu, clear, set, now, wake_clock);
+                       psi_group_change(group, cpu, clear, set, wake_clock);
                } while ((group = group->parent));
 
                /*
@@ -986,7 +984,7 @@ void psi_task_switch(struct task_struct *prev, struct task_struct *next,
                if ((prev->psi_flags ^ next->psi_flags) & ~TSK_ONCPU) {
                        clear &= ~TSK_ONCPU;
                        for (; group; group = group->parent)
-                               psi_group_change(group, cpu, clear, set, now, wake_clock);
+                               psi_group_change(group, cpu, clear, set, wake_clock);
                }
        }
 }
@@ -997,8 +995,8 @@ void psi_account_irqtime(struct rq *rq, struct task_struct *curr, struct task_st
        int cpu = task_cpu(curr);
        struct psi_group *group;
        struct psi_group_cpu *groupc;
-       u64 now, irq;
        s64 delta;
+       u64 irq;
 
        if (static_branch_likely(&psi_disabled))
                return;
@@ -1011,7 +1009,6 @@ void psi_account_irqtime(struct rq *rq, struct task_struct *curr, struct task_st
        if (prev && task_psi_group(prev) == group)
                return;
 
-       now = cpu_clock(cpu);
        irq = irq_time_read(cpu);
        delta = (s64)(irq - rq->psi_irq_time);
        if (delta < 0)
@@ -1019,12 +1016,15 @@ void psi_account_irqtime(struct rq *rq, struct task_struct *curr, struct task_st
        rq->psi_irq_time = irq;
 
        do {
+               u64 now;
+
                if (!group->enabled)
                        continue;
 
                groupc = per_cpu_ptr(group->pcpu, cpu);
 
                write_seqcount_begin(&groupc->seq);
+               now = cpu_clock(cpu);
 
                record_times(groupc, now);
                groupc->times[PSI_IRQ_FULL] += delta;
@@ -1223,11 +1223,9 @@ void psi_cgroup_restart(struct psi_group *group)
        for_each_possible_cpu(cpu) {
                struct rq *rq = cpu_rq(cpu);
                struct rq_flags rf;
-               u64 now;
 
                rq_lock_irq(rq, &rf);
-               now = cpu_clock(cpu);
-               psi_group_change(group, cpu, 0, 0, now, true);
+               psi_group_change(group, cpu, 0, 0, true);
                rq_unlock_irq(rq, &rf);
        }
 }
index b1c3588a8f0039ca260f237b5c1967e3a5d6710b..6c54a57275ccfdc685db48ef89a5dc01515696bb 100644 (file)
@@ -2292,6 +2292,7 @@ static inline int task_on_rq_migrating(struct task_struct *p)
 #define WF_SYNC                        0x10 /* Waker goes to sleep after wakeup */
 #define WF_MIGRATED            0x20 /* Internal use, task got migrated */
 #define WF_CURRENT_CPU         0x40 /* Prefer to move the wakee to the current CPU. */
+#define WF_RQ_SELECTED         0x80 /* ->select_task_rq() was called */
 
 #ifdef CONFIG_SMP
 static_assert(WF_EXEC == SD_BALANCE_EXEC);
@@ -2334,6 +2335,7 @@ extern const u32          sched_prio_to_wmult[40];
  * ENQUEUE_HEAD      - place at front of runqueue (tail if not specified)
  * ENQUEUE_REPLENISH - CBS (replenish runtime and postpone deadline)
  * ENQUEUE_MIGRATED  - the task was migrated during wakeup
+ * ENQUEUE_RQ_SELECTED - ->select_task_rq() was called
  *
  */
 
@@ -2360,6 +2362,7 @@ extern const u32          sched_prio_to_wmult[40];
 #define ENQUEUE_INITIAL                0x80
 #define ENQUEUE_MIGRATING      0x100
 #define ENQUEUE_DELAYED                0x200
+#define ENQUEUE_RQ_SELECTED    0x400
 
 #define RETRY_TASK             ((void *)-1UL)
 
@@ -2766,8 +2769,6 @@ static inline void sub_nr_running(struct rq *rq, unsigned count)
 
 static inline void __block_task(struct rq *rq, struct task_struct *p)
 {
-       WRITE_ONCE(p->on_rq, 0);
-       ASSERT_EXCLUSIVE_WRITER(p->on_rq);
        if (p->sched_contributes_to_load)
                rq->nr_uninterruptible++;
 
@@ -2775,6 +2776,38 @@ static inline void __block_task(struct rq *rq, struct task_struct *p)
                atomic_inc(&rq->nr_iowait);
                delayacct_blkio_start();
        }
+
+       ASSERT_EXCLUSIVE_WRITER(p->on_rq);
+
+       /*
+        * The moment this write goes through, ttwu() can swoop in and migrate
+        * this task, rendering our rq->__lock ineffective.
+        *
+        * __schedule()                         try_to_wake_up()
+        *   LOCK rq->__lock                      LOCK p->pi_lock
+        *   pick_next_task()
+        *     pick_next_task_fair()
+        *       pick_next_entity()
+        *         dequeue_entities()
+        *           __block_task()
+        *             RELEASE p->on_rq = 0       if (p->on_rq && ...)
+        *                                          break;
+        *
+        *                                        ACQUIRE (after ctrl-dep)
+        *
+        *                                        cpu = select_task_rq();
+        *                                        set_task_cpu(p, cpu);
+        *                                        ttwu_queue()
+        *                                          ttwu_do_activate()
+        *                                            LOCK rq->__lock
+        *                                            activate_task()
+        *                                              STORE p->on_rq = 1
+        *   UNLOCK rq->__lock
+        *
+        * Callers must ensure to not reference @p after this -- we no longer
+        * own it.
+        */
+       smp_store_release(&p->on_rq, 0);
 }
 
 extern void activate_task(struct rq *rq, struct task_struct *p, int flags);
@@ -3797,7 +3830,7 @@ static inline int rt_effective_prio(struct task_struct *p, int prio)
 
 extern int __sched_setscheduler(struct task_struct *p, const struct sched_attr *attr, bool user, bool pi);
 extern int __sched_setaffinity(struct task_struct *p, struct affinity_context *ctx);
-extern void __setscheduler_prio(struct task_struct *p, int prio);
+extern const struct sched_class *__setscheduler_class(int policy, int prio);
 extern void set_load_weight(struct task_struct *p, bool update_load);
 extern void enqueue_task(struct rq *rq, struct task_struct *p, int flags);
 extern bool dequeue_task(struct rq *rq, struct task_struct *p, int flags);
index 237780aa3c534a6a9b82deb3f68cc19ed3cf2fd6..767e098a3bd132de3e0328ff8f3997b6af349a57 100644 (file)
@@ -119,45 +119,63 @@ static inline void psi_account_irqtime(struct rq *rq, struct task_struct *curr,
 /*
  * PSI tracks state that persists across sleeps, such as iowaits and
  * memory stalls. As a result, it has to distinguish between sleeps,
- * where a task's runnable state changes, and requeues, where a task
- * and its state are being moved between CPUs and runqueues.
+ * where a task's runnable state changes, and migrations, where a task
+ * and its runnable state are being moved between CPUs and runqueues.
+ *
+ * A notable case is a task whose dequeue is delayed. PSI considers
+ * those sleeping, but because they are still on the runqueue they can
+ * go through migration requeues. In this case, *sleeping* states need
+ * to be transferred.
  */
-static inline void psi_enqueue(struct task_struct *p, bool wakeup)
+static inline void psi_enqueue(struct task_struct *p, bool migrate)
 {
-       int clear = 0, set = TSK_RUNNING;
+       int clear = 0, set = 0;
 
        if (static_branch_likely(&psi_disabled))
                return;
 
-       if (p->in_memstall)
-               set |= TSK_MEMSTALL_RUNNING;
-
-       if (!wakeup) {
+       if (p->se.sched_delayed) {
+               /* CPU migration of "sleeping" task */
+               SCHED_WARN_ON(!migrate);
                if (p->in_memstall)
                        set |= TSK_MEMSTALL;
+               if (p->in_iowait)
+                       set |= TSK_IOWAIT;
+       } else if (migrate) {
+               /* CPU migration of runnable task */
+               set = TSK_RUNNING;
+               if (p->in_memstall)
+                       set |= TSK_MEMSTALL | TSK_MEMSTALL_RUNNING;
        } else {
+               /* Wakeup of new or sleeping task */
                if (p->in_iowait)
                        clear |= TSK_IOWAIT;
+               set = TSK_RUNNING;
+               if (p->in_memstall)
+                       set |= TSK_MEMSTALL_RUNNING;
        }
 
        psi_task_change(p, clear, set);
 }
 
-static inline void psi_dequeue(struct task_struct *p, bool sleep)
+static inline void psi_dequeue(struct task_struct *p, bool migrate)
 {
        if (static_branch_likely(&psi_disabled))
                return;
 
+       /*
+        * When migrating a task to another CPU, clear all psi
+        * state. The enqueue callback above will work it out.
+        */
+       if (migrate)
+               psi_task_change(p, p->psi_flags, 0);
+
        /*
         * A voluntary sleep is a dequeue followed by a task switch. To
         * avoid walking all ancestors twice, psi_task_switch() handles
         * TSK_RUNNING and TSK_IOWAIT for us when it moves TSK_ONCPU.
         * Do nothing here.
         */
-       if (sleep)
-               return;
-
-       psi_task_change(p, p->psi_flags, 0);
 }
 
 static inline void psi_ttwu_dequeue(struct task_struct *p)
@@ -190,8 +208,8 @@ static inline void psi_sched_switch(struct task_struct *prev,
 }
 
 #else /* CONFIG_PSI */
-static inline void psi_enqueue(struct task_struct *p, bool wakeup) {}
-static inline void psi_dequeue(struct task_struct *p, bool sleep) {}
+static inline void psi_enqueue(struct task_struct *p, bool migrate) {}
+static inline void psi_dequeue(struct task_struct *p, bool migrate) {}
 static inline void psi_ttwu_dequeue(struct task_struct *p) {}
 static inline void psi_sched_switch(struct task_struct *prev,
                                    struct task_struct *next,
index aa70beee9895de48685ac22ba48b97b706c5e395..24f9f90b6574e57481a2d4e5dfbeb831b8a0f367 100644 (file)
@@ -529,7 +529,7 @@ int __sched_setscheduler(struct task_struct *p,
 {
        int oldpolicy = -1, policy = attr->sched_policy;
        int retval, oldprio, newprio, queued, running;
-       const struct sched_class *prev_class;
+       const struct sched_class *prev_class, *next_class;
        struct balance_callback *head;
        struct rq_flags rf;
        int reset_on_fork;
@@ -706,6 +706,12 @@ change:
                        queue_flags &= ~DEQUEUE_MOVE;
        }
 
+       prev_class = p->sched_class;
+       next_class = __setscheduler_class(policy, newprio);
+
+       if (prev_class != next_class && p->se.sched_delayed)
+               dequeue_task(rq, p, DEQUEUE_SLEEP | DEQUEUE_DELAYED | DEQUEUE_NOCLOCK);
+
        queued = task_on_rq_queued(p);
        running = task_current(rq, p);
        if (queued)
@@ -713,11 +719,10 @@ change:
        if (running)
                put_prev_task(rq, p);
 
-       prev_class = p->sched_class;
-
        if (!(attr->sched_flags & SCHED_FLAG_KEEP_PARAMS)) {
                __setscheduler_params(p, attr);
-               __setscheduler_prio(p, newprio);
+               p->sched_class = next_class;
+               p->prio = newprio;
        }
        __setscheduler_uclamp(p, attr);
        check_class_changing(rq, p, prev_class);
index 5d14d639ac71b54a24dac49acd02f6c2c7e58e04..c969f1f26be58a87babfb7f05464e612bec1bc98 100644 (file)
@@ -55,15 +55,26 @@ int task_work_add(struct task_struct *task, struct callback_head *work,
                  enum task_work_notify_mode notify)
 {
        struct callback_head *head;
+       int flags = notify & TWA_FLAGS;
 
+       notify &= ~TWA_FLAGS;
        if (notify == TWA_NMI_CURRENT) {
                if (WARN_ON_ONCE(task != current))
                        return -EINVAL;
                if (!IS_ENABLED(CONFIG_IRQ_WORK))
                        return -EINVAL;
        } else {
-               /* record the work call stack in order to print it in KASAN reports */
-               kasan_record_aux_stack(work);
+               /*
+                * Record the work call stack in order to print it in KASAN
+                * reports.
+                *
+                * Note that stack allocation can fail if TWAF_NO_ALLOC flag
+                * is set and new page is needed to expand the stack buffer.
+                */
+               if (flags & TWAF_NO_ALLOC)
+                       kasan_record_aux_stack_noalloc(work);
+               else
+                       kasan_record_aux_stack(work);
        }
 
        head = READ_ONCE(task->task_works);
index c2f3d0c490d5e223aafe138122033672fe422f8e..1af0bb2cc45c0aab843f77eb156992de469c8fb9 100644 (file)
@@ -309,6 +309,9 @@ static int pc_clock_settime(clockid_t id, const struct timespec64 *ts)
        struct posix_clock_desc cd;
        int err;
 
+       if (!timespec64_valid_strict(ts))
+               return -EINVAL;
+
        err = get_clock_desc(id, &cd);
        if (err)
                return err;
index 753a184c70907a0f11f5041b82ef8d6a317e5921..f203f000da1ad803deef3bcc05eea022b648be91 100644 (file)
@@ -434,6 +434,12 @@ static void tick_nohz_kick_task(struct task_struct *tsk)
         *   smp_mb__after_spin_lock()
         *   tick_nohz_task_switch()
         *     LOAD p->tick_dep_mask
+        *
+        * XXX given a task picks up the dependency on schedule(), should we
+        * only care about tasks that are currently on the CPU instead of all
+        * that are on the runqueue?
+        *
+        * That is, does this want to be: task_on_cpu() / task_curr()?
         */
        if (!sched_task_on_rq(tsk))
                return;
index a582cd25ca876616a5ade9fbd719c4688e636d93..630b763e52402f4c64bbf006ecdc8ecada6a04df 100644 (file)
@@ -1202,7 +1202,7 @@ static const struct bpf_func_proto bpf_get_func_arg_proto = {
        .ret_type       = RET_INTEGER,
        .arg1_type      = ARG_PTR_TO_CTX,
        .arg2_type      = ARG_ANYTHING,
-       .arg3_type      = ARG_PTR_TO_FIXED_SIZE_MEM | MEM_UNINIT | MEM_ALIGNED,
+       .arg3_type      = ARG_PTR_TO_FIXED_SIZE_MEM | MEM_UNINIT | MEM_WRITE | MEM_ALIGNED,
        .arg3_size      = sizeof(u64),
 };
 
@@ -1219,7 +1219,7 @@ static const struct bpf_func_proto bpf_get_func_ret_proto = {
        .func           = get_func_ret,
        .ret_type       = RET_INTEGER,
        .arg1_type      = ARG_PTR_TO_CTX,
-       .arg2_type      = ARG_PTR_TO_FIXED_SIZE_MEM | MEM_UNINIT | MEM_ALIGNED,
+       .arg2_type      = ARG_PTR_TO_FIXED_SIZE_MEM | MEM_UNINIT | MEM_WRITE | MEM_ALIGNED,
        .arg2_size      = sizeof(u64),
 };
 
@@ -2216,8 +2216,6 @@ void perf_event_detach_bpf_prog(struct perf_event *event)
 
        old_array = bpf_event_rcu_dereference(event->tp_event->prog_array);
        ret = bpf_prog_array_copy(old_array, event->prog, NULL, 0, &new_array);
-       if (ret == -ENOENT)
-               goto unlock;
        if (ret < 0) {
                bpf_prog_array_delete_safe(old_array, event->prog);
        } else {
@@ -3133,7 +3131,8 @@ static int bpf_uprobe_multi_link_fill_link_info(const struct bpf_link *link,
        struct bpf_uprobe_multi_link *umulti_link;
        u32 ucount = info->uprobe_multi.count;
        int err = 0, i;
-       long left;
+       char *p, *buf;
+       long left = 0;
 
        if (!upath ^ !upath_size)
                return -EINVAL;
@@ -3147,26 +3146,23 @@ static int bpf_uprobe_multi_link_fill_link_info(const struct bpf_link *link,
        info->uprobe_multi.pid = umulti_link->task ?
                                 task_pid_nr_ns(umulti_link->task, task_active_pid_ns(current)) : 0;
 
-       if (upath) {
-               char *p, *buf;
-
-               upath_size = min_t(u32, upath_size, PATH_MAX);
-
-               buf = kmalloc(upath_size, GFP_KERNEL);
-               if (!buf)
-                       return -ENOMEM;
-               p = d_path(&umulti_link->path, buf, upath_size);
-               if (IS_ERR(p)) {
-                       kfree(buf);
-                       return PTR_ERR(p);
-               }
-               upath_size = buf + upath_size - p;
-               left = copy_to_user(upath, p, upath_size);
+       upath_size = upath_size ? min_t(u32, upath_size, PATH_MAX) : PATH_MAX;
+       buf = kmalloc(upath_size, GFP_KERNEL);
+       if (!buf)
+               return -ENOMEM;
+       p = d_path(&umulti_link->path, buf, upath_size);
+       if (IS_ERR(p)) {
                kfree(buf);
-               if (left)
-                       return -EFAULT;
-               info->uprobe_multi.path_size = upath_size;
+               return PTR_ERR(p);
        }
+       upath_size = buf + upath_size - p;
+
+       if (upath)
+               left = copy_to_user(upath, p, upath_size);
+       kfree(buf);
+       if (left)
+               return -EFAULT;
+       info->uprobe_multi.path_size = upath_size;
 
        if (!uoffsets && !ucookies && !uref_ctr_offsets)
                return 0;
index d7d4fb403f6f0f7c6277a22a0a8768c3e85862e6..69e226a48daa922852df5a2491d1f91784098697 100644 (file)
@@ -1160,19 +1160,14 @@ void fgraph_update_pid_func(void)
 static int start_graph_tracing(void)
 {
        unsigned long **ret_stack_list;
-       int ret, cpu;
+       int ret;
 
-       ret_stack_list = kmalloc(SHADOW_STACK_SIZE, GFP_KERNEL);
+       ret_stack_list = kcalloc(FTRACE_RETSTACK_ALLOC_SIZE,
+                                sizeof(*ret_stack_list), GFP_KERNEL);
 
        if (!ret_stack_list)
                return -ENOMEM;
 
-       /* The cpu_boot init_task->ret_stack will never be freed */
-       for_each_online_cpu(cpu) {
-               if (!idle_task(cpu)->ret_stack)
-                       ftrace_graph_init_idle_task(idle_task(cpu), cpu);
-       }
-
        do {
                ret = alloc_retstack_tasklist(ret_stack_list);
        } while (ret == -EAGAIN);
@@ -1242,13 +1237,33 @@ static void ftrace_graph_disable_direct(bool disable_branch)
        fgraph_direct_gops = &fgraph_stub;
 }
 
+/* The cpu_boot init_task->ret_stack will never be freed */
+static int fgraph_cpu_init(unsigned int cpu)
+{
+       if (!idle_task(cpu)->ret_stack)
+               ftrace_graph_init_idle_task(idle_task(cpu), cpu);
+       return 0;
+}
+
 int register_ftrace_graph(struct fgraph_ops *gops)
 {
+       static bool fgraph_initialized;
        int command = 0;
        int ret = 0;
        int i = -1;
 
-       mutex_lock(&ftrace_lock);
+       guard(mutex)(&ftrace_lock);
+
+       if (!fgraph_initialized) {
+               ret = cpuhp_setup_state(CPUHP_AP_ONLINE_DYN, "fgraph:online",
+                                       fgraph_cpu_init, NULL);
+               if (ret < 0) {
+                       pr_warn("fgraph: Error to init cpu hotplug support\n");
+                       return ret;
+               }
+               fgraph_initialized = true;
+               ret = 0;
+       }
 
        if (!fgraph_array[0]) {
                /* The array must always have real data on it */
@@ -1258,10 +1273,8 @@ int register_ftrace_graph(struct fgraph_ops *gops)
        }
 
        i = fgraph_lru_alloc_index();
-       if (i < 0 || WARN_ON_ONCE(fgraph_array[i] != &fgraph_stub)) {
-               ret = -ENOSPC;
-               goto out;
-       }
+       if (i < 0 || WARN_ON_ONCE(fgraph_array[i] != &fgraph_stub))
+               return -ENOSPC;
        gops->idx = i;
 
        ftrace_graph_active++;
@@ -1298,8 +1311,6 @@ error:
                gops->saved_func = NULL;
                fgraph_lru_release_index(i);
        }
-out:
-       mutex_unlock(&ftrace_lock);
        return ret;
 }
 
index 77dc0b25140e6244f511542e41f4410abe5eb88a..3ea4f7bb1837ce74fa44d95b07cd5f2f8acf02e8 100644 (file)
@@ -2337,9 +2337,12 @@ static struct trace_buffer *alloc_buffer(unsigned long size, unsigned flags,
        if (!buffer->buffers[cpu])
                goto fail_free_buffers;
 
-       ret = cpuhp_state_add_instance(CPUHP_TRACE_RB_PREPARE, &buffer->node);
-       if (ret < 0)
-               goto fail_free_buffers;
+       /* If already mapped, do not hook to CPU hotplug */
+       if (!start) {
+               ret = cpuhp_state_add_instance(CPUHP_TRACE_RB_PREPARE, &buffer->node);
+               if (ret < 0)
+                       goto fail_free_buffers;
+       }
 
        mutex_init(&buffer->mutex);
 
@@ -6725,39 +6728,38 @@ int ring_buffer_subbuf_order_set(struct trace_buffer *buffer, int order)
        }
 
        for_each_buffer_cpu(buffer, cpu) {
+               struct buffer_data_page *old_free_data_page;
+               struct list_head old_pages;
+               unsigned long flags;
 
                if (!cpumask_test_cpu(cpu, buffer->cpumask))
                        continue;
 
                cpu_buffer = buffer->buffers[cpu];
 
+               raw_spin_lock_irqsave(&cpu_buffer->reader_lock, flags);
+
                /* Clear the head bit to make the link list normal to read */
                rb_head_page_deactivate(cpu_buffer);
 
-               /* Now walk the list and free all the old sub buffers */
-               list_for_each_entry_safe(bpage, tmp, cpu_buffer->pages, list) {
-                       list_del_init(&bpage->list);
-                       free_buffer_page(bpage);
-               }
-               /* The above loop stopped an the last page needing to be freed */
-               bpage = list_entry(cpu_buffer->pages, struct buffer_page, list);
-               free_buffer_page(bpage);
-
-               /* Free the current reader page */
-               free_buffer_page(cpu_buffer->reader_page);
+               /*
+                * Collect buffers from the cpu_buffer pages list and the
+                * reader_page on old_pages, so they can be freed later when not
+                * under a spinlock. The pages list is a linked list with no
+                * head, adding old_pages turns it into a regular list with
+                * old_pages being the head.
+                */
+               list_add(&old_pages, cpu_buffer->pages);
+               list_add(&cpu_buffer->reader_page->list, &old_pages);
 
                /* One page was allocated for the reader page */
                cpu_buffer->reader_page = list_entry(cpu_buffer->new_pages.next,
                                                     struct buffer_page, list);
                list_del_init(&cpu_buffer->reader_page->list);
 
-               /* The cpu_buffer pages are a link list with no head */
+               /* Install the new pages, remove the head from the list */
                cpu_buffer->pages = cpu_buffer->new_pages.next;
-               cpu_buffer->new_pages.next->prev = cpu_buffer->new_pages.prev;
-               cpu_buffer->new_pages.prev->next = cpu_buffer->new_pages.next;
-
-               /* Clear the new_pages list */
-               INIT_LIST_HEAD(&cpu_buffer->new_pages);
+               list_del_init(&cpu_buffer->new_pages);
 
                cpu_buffer->head_page
                        = list_entry(cpu_buffer->pages, struct buffer_page, list);
@@ -6766,11 +6768,20 @@ int ring_buffer_subbuf_order_set(struct trace_buffer *buffer, int order)
                cpu_buffer->nr_pages = cpu_buffer->nr_pages_to_update;
                cpu_buffer->nr_pages_to_update = 0;
 
-               free_pages((unsigned long)cpu_buffer->free_page, old_order);
+               old_free_data_page = cpu_buffer->free_page;
                cpu_buffer->free_page = NULL;
 
                rb_head_page_activate(cpu_buffer);
 
+               raw_spin_unlock_irqrestore(&cpu_buffer->reader_lock, flags);
+
+               /* Free old sub buffers */
+               list_for_each_entry_safe(bpage, tmp, &old_pages, list) {
+                       list_del_init(&bpage->list);
+                       free_buffer_page(bpage);
+               }
+               free_pages((unsigned long)old_free_data_page, old_order);
+
                rb_check_pages(cpu_buffer);
        }
 
index c01375adc4714a563c71dc0aeeb2b30c78cc9478..a8f52b6527ca3aad4fb52945f5d221b4973b2e23 100644 (file)
@@ -3697,8 +3697,8 @@ static void test_can_verify(void)
 void trace_check_vprintf(struct trace_iterator *iter, const char *fmt,
                         va_list ap)
 {
-       long text_delta = iter->tr->text_delta;
-       long data_delta = iter->tr->data_delta;
+       long text_delta = 0;
+       long data_delta = 0;
        const char *p = fmt;
        const char *str;
        bool good;
@@ -3710,6 +3710,17 @@ void trace_check_vprintf(struct trace_iterator *iter, const char *fmt,
        if (static_branch_unlikely(&trace_no_verify))
                goto print;
 
+       /*
+        * When the kernel is booted with the tp_printk command line
+        * parameter, trace events go directly through to printk().
+        * It also is checked by this function, but it does not
+        * have an associated trace_array (tr) for it.
+        */
+       if (iter->tr) {
+               text_delta = iter->tr->text_delta;
+               data_delta = iter->tr->data_delta;
+       }
+
        /* Don't bother checking when doing a ftrace_dump() */
        if (iter->fmt == static_fmt_buf)
                goto print;
@@ -10610,10 +10621,10 @@ __init static void enable_instances(void)
                 * cannot be deleted by user space, so keep the reference
                 * to it.
                 */
-               if (start)
+               if (start) {
                        tr->flags |= TRACE_ARRAY_FL_BOOT;
-               else
-                       trace_array_put(tr);
+                       tr->ref++;
+               }
 
                while ((tok = strsep(&curr_str, ","))) {
                        early_enable_events(tr, tok, true);
index b0e0ec85912e98870bbe6b0e2563d58e3377a755..ebda68ee9abff9013580b2fcee0b55a405b60b57 100644 (file)
@@ -912,6 +912,11 @@ static int __trace_eprobe_create(int argc, const char *argv[])
                }
        }
 
+       if (argc - 2 > MAX_TRACE_ARGS) {
+               ret = -E2BIG;
+               goto error;
+       }
+
        mutex_lock(&event_mutex);
        event_call = find_and_get_event(sys_name, sys_event);
        ep = alloc_event_probe(group, event, event_call, argc - 2);
@@ -937,7 +942,7 @@ static int __trace_eprobe_create(int argc, const char *argv[])
 
        argc -= 2; argv += 2;
        /* parse arguments */
-       for (i = 0; i < argc && i < MAX_TRACE_ARGS; i++) {
+       for (i = 0; i < argc; i++) {
                trace_probe_log_set_index(i + 2);
                ret = trace_eprobe_tp_update_arg(ep, argv, i);
                if (ret)
index a079abd8955b56579b9ed0638357caed3efcdf41..c62d1629cffecd72f01b54f8586b7b02ed671a5d 100644 (file)
@@ -1187,6 +1187,10 @@ static int __trace_fprobe_create(int argc, const char *argv[])
                argc = new_argc;
                argv = new_argv;
        }
+       if (argc > MAX_TRACE_ARGS) {
+               ret = -E2BIG;
+               goto out;
+       }
 
        ret = traceprobe_expand_dentry_args(argc, argv, &dbuf);
        if (ret)
@@ -1203,7 +1207,7 @@ static int __trace_fprobe_create(int argc, const char *argv[])
        }
 
        /* parse arguments */
-       for (i = 0; i < argc && i < MAX_TRACE_ARGS; i++) {
+       for (i = 0; i < argc; i++) {
                trace_probe_log_set_index(i + 2);
                ctx.offset = 0;
                ret = traceprobe_parse_probe_arg(&tf->tp, i, argv[i], &ctx);
index b791524a6536ac9178d5ae23e3036143d6f1d63d..3bd6071441ade91da67af348abfd8044d1e02e69 100644 (file)
@@ -520,6 +520,8 @@ static void hwlat_hotplug_workfn(struct work_struct *dummy)
        if (!hwlat_busy || hwlat_data.thread_mode != MODE_PER_CPU)
                goto out_unlock;
 
+       if (!cpu_online(cpu))
+               goto out_unlock;
        if (!cpumask_test_cpu(cpu, tr->tracing_cpumask))
                goto out_unlock;
 
index 61a6da808203e07328b9ec6e3d03fd1f286ae34a..263fac44d3ca32ad0aee21c7e65ac744f1034ca7 100644 (file)
@@ -1013,6 +1013,10 @@ static int __trace_kprobe_create(int argc, const char *argv[])
                argc = new_argc;
                argv = new_argv;
        }
+       if (argc > MAX_TRACE_ARGS) {
+               ret = -E2BIG;
+               goto out;
+       }
 
        ret = traceprobe_expand_dentry_args(argc, argv, &dbuf);
        if (ret)
@@ -1029,7 +1033,7 @@ static int __trace_kprobe_create(int argc, const char *argv[])
        }
 
        /* parse arguments */
-       for (i = 0; i < argc && i < MAX_TRACE_ARGS; i++) {
+       for (i = 0; i < argc; i++) {
                trace_probe_log_set_index(i + 2);
                ctx.offset = 0;
                ret = traceprobe_parse_probe_arg(&tk->tp, i, argv[i], &ctx);
index 1439064f65d60c27347c91a4796034d56d8e79b8..a50ed23bee777b4a7d48af0a7080ec23fcb325a7 100644 (file)
@@ -1953,12 +1953,8 @@ static void stop_kthread(unsigned int cpu)
 {
        struct task_struct *kthread;
 
-       mutex_lock(&interface_lock);
-       kthread = per_cpu(per_cpu_osnoise_var, cpu).kthread;
+       kthread = xchg_relaxed(&(per_cpu(per_cpu_osnoise_var, cpu).kthread), NULL);
        if (kthread) {
-               per_cpu(per_cpu_osnoise_var, cpu).kthread = NULL;
-               mutex_unlock(&interface_lock);
-
                if (cpumask_test_and_clear_cpu(cpu, &kthread_cpumask) &&
                    !WARN_ON(!test_bit(OSN_WORKLOAD, &osnoise_options))) {
                        kthread_stop(kthread);
@@ -1972,7 +1968,6 @@ static void stop_kthread(unsigned int cpu)
                        put_task_struct(kthread);
                }
        } else {
-               mutex_unlock(&interface_lock);
                /* if no workload, just return */
                if (!test_bit(OSN_WORKLOAD, &osnoise_options)) {
                        /*
@@ -1994,8 +1989,12 @@ static void stop_per_cpu_kthreads(void)
 {
        int cpu;
 
-       for_each_possible_cpu(cpu)
+       cpus_read_lock();
+
+       for_each_online_cpu(cpu)
                stop_kthread(cpu);
+
+       cpus_read_unlock();
 }
 
 /*
@@ -2007,6 +2006,10 @@ static int start_kthread(unsigned int cpu)
        void *main = osnoise_main;
        char comm[24];
 
+       /* Do not start a new thread if it is already running */
+       if (per_cpu(per_cpu_osnoise_var, cpu).kthread)
+               return 0;
+
        if (timerlat_enabled()) {
                snprintf(comm, 24, "timerlat/%d", cpu);
                main = timerlat_main;
@@ -2061,11 +2064,10 @@ static int start_per_cpu_kthreads(void)
                if (cpumask_test_and_clear_cpu(cpu, &kthread_cpumask)) {
                        struct task_struct *kthread;
 
-                       kthread = per_cpu(per_cpu_osnoise_var, cpu).kthread;
+                       kthread = xchg_relaxed(&(per_cpu(per_cpu_osnoise_var, cpu).kthread), NULL);
                        if (!WARN_ON(!kthread))
                                kthread_stop(kthread);
                }
-               per_cpu(per_cpu_osnoise_var, cpu).kthread = NULL;
        }
 
        for_each_cpu(cpu, current_mask) {
@@ -2095,6 +2097,8 @@ static void osnoise_hotplug_workfn(struct work_struct *dummy)
        mutex_lock(&interface_lock);
        cpus_read_lock();
 
+       if (!cpu_online(cpu))
+               goto out_unlock;
        if (!cpumask_test_cpu(cpu, &osnoise_cpumask))
                goto out_unlock;
 
index 39877c80d6cb9ace8163e2bfd16525629562ba82..16a5e368e7b77ca866895f271e33b6881e49cc4c 100644 (file)
@@ -276,7 +276,7 @@ int traceprobe_parse_event_name(const char **pevent, const char **pgroup,
                }
                trace_probe_log_err(offset, NO_EVENT_NAME);
                return -EINVAL;
-       } else if (len > MAX_EVENT_NAME_LEN) {
+       } else if (len >= MAX_EVENT_NAME_LEN) {
                trace_probe_log_err(offset, EVENT_TOO_LONG);
                return -EINVAL;
        }
index c4ad7cd7e7780304a1799d3ec076b6e4bb5a1c1e..1469dd8075fa3967a27ac355db1f0ea5c8aa3c80 100644 (file)
@@ -1485,7 +1485,7 @@ trace_selftest_startup_wakeup(struct tracer *trace, struct trace_array *tr)
        /* reset the max latency */
        tr->max_latency = 0;
 
-       while (p->on_rq) {
+       while (task_is_runnable(p)) {
                /*
                 * Sleep to make sure the -deadline thread is asleep too.
                 * On virtual machines we can't rely on timings,
index c40531d2cbadde432d8cd0d231986b98e2b3490e..b30fc8fcd0956aa1ea638d8bb36169ecdae64d05 100644 (file)
@@ -565,6 +565,8 @@ static int __trace_uprobe_create(int argc, const char **argv)
 
        if (argc < 2)
                return -ECANCELED;
+       if (argc - 2 > MAX_TRACE_ARGS)
+               return -E2BIG;
 
        if (argv[0][1] == ':')
                event = &argv[0][2];
@@ -690,7 +692,7 @@ static int __trace_uprobe_create(int argc, const char **argv)
        tu->filename = filename;
 
        /* parse arguments */
-       for (i = 0; i < argc && i < MAX_TRACE_ARGS; i++) {
+       for (i = 0; i < argc; i++) {
                struct traceprobe_parse_context ctx = {
                        .flags = (is_return ? TPARG_FL_RETURN : 0) | TPARG_FL_USER,
                };
@@ -875,6 +877,7 @@ struct uprobe_cpu_buffer {
 };
 static struct uprobe_cpu_buffer __percpu *uprobe_cpu_buffer;
 static int uprobe_buffer_refcnt;
+#define MAX_UCB_BUFFER_SIZE PAGE_SIZE
 
 static int uprobe_buffer_init(void)
 {
@@ -979,6 +982,11 @@ static struct uprobe_cpu_buffer *prepare_uprobe_buffer(struct trace_uprobe *tu,
        ucb = uprobe_buffer_get();
        ucb->dsize = tu->tp.size + dsize;
 
+       if (WARN_ON_ONCE(ucb->dsize > MAX_UCB_BUFFER_SIZE)) {
+               ucb->dsize = MAX_UCB_BUFFER_SIZE;
+               dsize = MAX_UCB_BUFFER_SIZE - tu->tp.size;
+       }
+
        store_trace_args(ucb->buf, &tu->tp, regs, NULL, esize, dsize);
 
        *ucbp = ucb;
@@ -998,9 +1006,6 @@ static void __uprobe_trace_func(struct trace_uprobe *tu,
 
        WARN_ON(call != trace_file->event_call);
 
-       if (WARN_ON_ONCE(ucb->dsize > PAGE_SIZE))
-               return;
-
        if (trace_trigger_soft_disabled(trace_file))
                return;
 
index 7b1f581a2907302569cace47dabcf9f283ed4ae1..f9e8a5dd790f340485282d64167a39042c4cfac8 100644 (file)
@@ -78,7 +78,7 @@
 #include <linux/kernel.h>
 #include <linux/bitops.h>
 #include <linux/crc32.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #include <linux/sw842.h>
 
index 7315f643817ae1021f1e4b3dd27b424f49e3f761..7312ae7c3cc57b9d7e12286b4218206811d9705b 100644 (file)
@@ -3060,7 +3060,7 @@ config RUST_BUILD_ASSERT_ALLOW
        bool "Allow unoptimized build-time assertions"
        depends on RUST
        help
-         Controls how are `build_error!` and `build_assert!` handled during build.
+         Controls how `build_error!` and `build_assert!` are handled during the build.
 
          If calls to them exist in the binary, it may indicate a violated invariant
          or that the optimizer failed to verify the invariant during compilation.
index 290641d92ac176ca56fa009fa77383e0d5c24753..c4b0f376fb3410beac1e5223e3afdf85c7e16b81 100644 (file)
@@ -5,6 +5,7 @@
 #include <linux/elf.h>
 #include <linux/kernel.h>
 #include <linux/pagemap.h>
+#include <linux/secretmem.h>
 
 #define BUILD_ID 3
 
@@ -64,6 +65,10 @@ static int freader_get_folio(struct freader *r, loff_t file_off)
 
        freader_put_folio(r);
 
+       /* reject secretmem folios created with memfd_secret() */
+       if (secretmem_mapping(r->file->f_mapping))
+               return -EFAULT;
+
        r->folio = filemap_get_folio(r->file->f_mapping, file_off >> PAGE_SHIFT);
 
        /* if sleeping is allowed, wait for the page, if necessary */
index afa8a2d4f317336ce7eab95c1dd00d37cc63433d..d1fbbb7c2ec3d05f169b7df0f7abd66edb30b35c 100644 (file)
@@ -228,6 +228,9 @@ bool codetag_unload_module(struct module *mod)
        if (!mod)
                return true;
 
+       /* await any module's kfree_rcu() operations to complete */
+       kvfree_rcu_barrier();
+
        mutex_lock(&codetag_lock);
        list_for_each_entry(cttype, &codetag_types, link) {
                struct codetag_module *found = NULL;
index 827fe89922fff03b9be8e1fcc2d26541c06713bb..eafe14d021f5aa09c4a3ce334cc21a1a0ce2c196 100644 (file)
@@ -6,7 +6,7 @@
 #include <crypto/aes.h>
 #include <linux/crypto.h>
 #include <linux/module.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 /*
  * Emit the sbox as volatile const to prevent the compiler from doing
index 3b6dcfdd962823619f91f17bfab07bc1b4286d94..09682136b57c691ba3c6a6029d6396318cfad64f 100644 (file)
@@ -14,7 +14,7 @@
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/bug.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 static const u8 blake2s_sigma[10][16] = {
        { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 },
index b748fd3d256e41cb00d9c77fa463d41632769cac..3cdda3b5ee060decfae1e285ffa5edff3bb48ffe 100644 (file)
@@ -10,7 +10,7 @@
 #include <linux/export.h>
 #include <linux/bitops.h>
 #include <linux/string.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include <crypto/chacha.h>
 
 static void chacha_permute(u32 *x, int nrounds)
index fa43deda2660d8e3ad92e88718a6eec2b1e3afc2..2ea61c28be4fa8b34db4751783fefc704e502349 100644 (file)
@@ -7,7 +7,7 @@
 #include <crypto/chacha.h>
 #include <crypto/poly1305.h>
 
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include <linux/bug.h>
 #include <linux/init.h>
 #include <linux/mm.h>
index fa6a9440fc95e3e9344514e4797153b40758b69b..a839c0ac60b2ac19150f7617c3c391539fe1220b 100644 (file)
@@ -13,7 +13,7 @@
 #include <crypto/poly1305.h>
 #include <crypto/scatterwalk.h>
 
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/mm.h>
index 2fde0ec33dbd0873147c064ac9afec8eccd7e690..2e0ba634e2991a4f66ce8df63f1e422788dda07d 100644 (file)
@@ -10,7 +10,7 @@
  * with 128-bit integer types.
  */
 
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include <crypto/curve25519.h>
 #include <linux/string.h>
 
index c40e5d9132343f524b1cee137c5c706e3baaba4b..c4204133afb76d00ad5ee592828e97655014e325 100644 (file)
@@ -10,7 +10,7 @@
  * integer types.
  */
 
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include <crypto/curve25519.h>
 #include <linux/string.h>
 
index 9518658b97cf1b5678d326662f62ac3f8efbfcd6..d3423b34a8e9b7fb95fd2c74bdbd2ef02cbb348d 100644 (file)
@@ -17,7 +17,7 @@
 #include <linux/string.h>
 #include <linux/types.h>
 
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #include <crypto/des.h>
 #include <crypto/internal/des.h>
index 243d8677cc515da0c3c95c2fefaa95c648c2140a..a2afd10349c9254c9cda1a5cab38aa45eabef5f6 100644 (file)
@@ -59,7 +59,7 @@
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include <crypto/algapi.h>
 #include <linux/module.h>
 
index 892a246216b9c22082a3e40d5acc805e65d4b08d..7e6ff1ce3e9b63fb4fdfbbf43355f97d25fb005e 100644 (file)
@@ -21,7 +21,7 @@ int mpi_mul(MPI w, MPI u, MPI v)
        int usign, vsign, sign_product;
        int assign_wp = 0;
        mpi_ptr_t tmp_limb = NULL;
-       int err;
+       int err = 0;
 
        if (u->nlimbs < v->nlimbs) {
                /* Swap U and V. */
index 7fb71845cc8464fd8beeb5be2b65b79d1193fcd0..0a4a2d99e36549d9056ae0adfc4acc95bbd7002d 100644 (file)
@@ -7,7 +7,7 @@
  */
 
 #include <linux/kernel.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include <crypto/internal/poly1305.h>
 
 void poly1305_core_setkey(struct poly1305_core_key *key,
index 988702c9b3b2167210b4f18b20e0228f677eacd4..530287531b2ee2b23210f74212928d2c7b0410a5 100644 (file)
@@ -7,7 +7,7 @@
  */
 
 #include <linux/kernel.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include <crypto/internal/poly1305.h>
 
 void poly1305_core_setkey(struct poly1305_core_key *key,
index 5d8378d23e952ad605932fec2986d816d99e3e12..6e80214ebad8be7b03f755a2d19a8790305f345f 100644 (file)
@@ -10,7 +10,7 @@
 #include <crypto/internal/poly1305.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 void poly1305_init_generic(struct poly1305_desc_ctx *desc,
                           const u8 key[POLY1305_KEY_SIZE])
index 6d2922747cabbea0107413eebcde2f941fc04a58..ebb60519ae93912ae939fcec581bd1c5b314bbd6 100644 (file)
@@ -12,7 +12,7 @@
 #include <linux/bitops.h>
 #include <linux/string.h>
 #include <crypto/sha1.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 /*
  * If you have 32 registers or more, the compiler can (and should)
index 3f42d203c7bca22fa94c3e3295ef34d6057ecd2b..04c1f2557e6c2752b9998e2eee9a2df471521428 100644 (file)
@@ -11,7 +11,7 @@
  * Copyright (c) 2014 Red Hat Inc.
  */
 
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include <crypto/sha256_base.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
index 3733641414082e5fd4dc12b88ef7564b45b94bbb..87da2a6dd161e1c8b7313fe691055f1591fcb7f3 100644 (file)
@@ -5,7 +5,7 @@
  * Copyright (c) 2006 Herbert Xu <[email protected]>
  */
 
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include <crypto/utils.h>
 #include <linux/module.h>
 
index e6327391b6b66350af40846c0c48733de04ce291..c0dbb3cea915eb91d8f4ac26c38c4785bbf19770 100644 (file)
@@ -16,7 +16,7 @@
 #include <linux/decompress/mm.h>
 #include <linux/compiler.h>
 
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 /*
  * Note: Uncompressed chunk size is used in the compressor side
index 64c1358500ce4e9cd274cce2ed43744fdb938406..57a9e93743e1f94aefc7cd29903378d2a273ff1f 100644 (file)
@@ -28,7 +28,7 @@
 #include <linux/decompress/mm.h>
 
 #include <linux/compiler.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 static const unsigned char lzop_magic[] = {
        0x89, 0x4c, 0x5a, 0x4f, 0x00, 0x0d, 0x0a, 0x1a, 0x0a };
index 06833d404398d747b41138fbd58e03ab5e5f688a..c3db7c3a764365b01e78f8ed0b7f782f33a5ce34 100644 (file)
@@ -9,7 +9,7 @@
 #include <linux/kernel.h>
 #include <linux/minmax.h>
 #include <linux/export.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 const char hex_asc[] = "0123456789abcdef";
 EXPORT_SYMBOL(hex_asc);
index 97003155bfac89ba3db77503c0b2f4093acd65c8..908e75a28d90bda63cdb4dc83ad90059ee8ef5b7 100644 (file)
@@ -461,6 +461,8 @@ size_t copy_page_from_iter_atomic(struct page *page, size_t offset,
                size_t bytes, struct iov_iter *i)
 {
        size_t n, copied = 0;
+       bool uses_kmap = IS_ENABLED(CONFIG_DEBUG_KMAP_LOCAL_FORCE_MAP) ||
+                        PageHighMem(page);
 
        if (!page_copy_sane(page, offset, bytes))
                return 0;
@@ -471,7 +473,7 @@ size_t copy_page_from_iter_atomic(struct page *page, size_t offset,
                char *p;
 
                n = bytes - copied;
-               if (PageHighMem(page)) {
+               if (uses_kmap) {
                        page += offset / PAGE_SIZE;
                        offset %= PAGE_SIZE;
                        n = min_t(size_t, n, PAGE_SIZE - offset);
@@ -482,7 +484,7 @@ size_t copy_page_from_iter_atomic(struct page *page, size_t offset,
                kunmap_atomic(p);
                copied += n;
                offset += n;
-       } while (PageHighMem(page) && copied != bytes && n > 0);
+       } while (uses_kmap && copied != bytes && n > 0);
 
        return copied;
 }
@@ -1021,19 +1023,22 @@ static ssize_t iter_folioq_get_pages(struct iov_iter *iter,
                size_t offset = iov_offset, fsize = folioq_folio_size(folioq, slot);
                size_t part = PAGE_SIZE - offset % PAGE_SIZE;
 
-               part = umin(part, umin(maxsize - extracted, fsize - offset));
-               count -= part;
-               iov_offset += part;
-               extracted += part;
+               if (offset < fsize) {
+                       part = umin(part, umin(maxsize - extracted, fsize - offset));
+                       count -= part;
+                       iov_offset += part;
+                       extracted += part;
+
+                       *pages = folio_page(folio, offset / PAGE_SIZE);
+                       get_page(*pages);
+                       pages++;
+                       maxpages--;
+               }
 
-               *pages = folio_page(folio, offset / PAGE_SIZE);
-               get_page(*pages);
-               pages++;
-               maxpages--;
                if (maxpages == 0 || extracted >= maxsize)
                        break;
 
-               if (offset >= fsize) {
+               if (iov_offset >= fsize) {
                        iov_offset = 0;
                        slot++;
                        if (slot == folioq_nr_slots(folioq) && folioq->next) {
index 90bb67994688d929905e062728ff0cb610b8b60c..b0bbeeb74b9ec782926998a0c246b036b754d61e 100644 (file)
@@ -37,7 +37,7 @@
 #include "lz4defs.h"
 #include <linux/module.h>
 #include <linux/kernel.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 static const int LZ4_minLength = (MFLIMIT + 1);
 static const int LZ4_64Klimit = ((64 * KB) + (MFLIMIT - 1));
index 59fe69a638000ec000a49fad540fd2715c7c07a1..0e31e6da5ce7102bda1b0d1aa431650c37b767e4 100644 (file)
@@ -38,7 +38,7 @@
 #include <linux/init.h>
 #include <linux/module.h>
 #include <linux/kernel.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 /*-*****************************
  *     Decompression functions
index 330aa539b46e645d57474c55c0880f75949a3243..cb358d6bde5a7fb7ada0c14733de579d48d06cad 100644 (file)
@@ -35,7 +35,7 @@
  *     Sven Schmidt <[email protected]>
  */
 
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #include <linux/bitops.h>
 #include <linux/string.h>       /* memset, memcpy */
index 9d31e7126606acc90aace1f5361c260fcd987536..47d6d43ea9578c93cfbd44b3420426cab1826638 100644 (file)
@@ -14,7 +14,7 @@
 
 #include <linux/module.h>
 #include <linux/kernel.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include <linux/lzo.h>
 #include "lzodefs.h"
 
index 7892a40cf765b980038d139ca8fb707e48f25409..c94f4928e1888be8de03585081e0a34bd2f5c6da 100644 (file)
@@ -16,7 +16,7 @@
 #include <linux/module.h>
 #include <linux/kernel.h>
 #endif
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include <linux/lzo.h>
 #include "lzodefs.h"
 
index 20990ecba2ddb4eddb88067f78ecaf19d63b3f5d..3619301dda2ebeaaba8a73837389b6ee3c7e1a3f 100644 (file)
@@ -2196,6 +2196,8 @@ static inline void mas_node_or_none(struct ma_state *mas,
 
 /*
  * mas_wr_node_walk() - Find the correct offset for the index in the @mas.
+ *                      If @mas->index cannot be found within the containing
+ *                      node, we traverse to the last entry in the node.
  * @wr_mas: The maple write state
  *
  * Uses mas_slot_locked() and does not need to worry about dead nodes.
@@ -3532,7 +3534,7 @@ static bool mas_wr_walk(struct ma_wr_state *wr_mas)
        return true;
 }
 
-static bool mas_wr_walk_index(struct ma_wr_state *wr_mas)
+static void mas_wr_walk_index(struct ma_wr_state *wr_mas)
 {
        struct ma_state *mas = wr_mas->mas;
 
@@ -3541,11 +3543,9 @@ static bool mas_wr_walk_index(struct ma_wr_state *wr_mas)
                wr_mas->content = mas_slot_locked(mas, wr_mas->slots,
                                                  mas->offset);
                if (ma_is_leaf(wr_mas->type))
-                       return true;
+                       return;
                mas_wr_walk_traverse(wr_mas);
-
        }
-       return true;
 }
 /*
  * mas_extend_spanning_null() - Extend a store of a %NULL to include surrounding %NULLs.
@@ -3765,8 +3765,8 @@ static noinline void mas_wr_spanning_store(struct ma_wr_state *wr_mas)
        memset(&b_node, 0, sizeof(struct maple_big_node));
        /* Copy l_mas and store the value in b_node. */
        mas_store_b_node(&l_wr_mas, &b_node, l_mas.end);
-       /* Copy r_mas into b_node. */
-       if (r_mas.offset <= r_mas.end)
+       /* Copy r_mas into b_node if there is anything to copy. */
+       if (r_mas.max > r_mas.last)
                mas_mab_cp(&r_mas, r_mas.offset, r_mas.end,
                           &b_node, b_node.b_end + 1);
        else
@@ -4218,7 +4218,7 @@ static inline void mas_wr_store_type(struct ma_wr_state *wr_mas)
 
        /* Potential spanning rebalance collapsing a node */
        if (new_end < mt_min_slots[wr_mas->type]) {
-               if (!mte_is_root(mas->node)) {
+               if (!mte_is_root(mas->node) && !(mas->mas_flags & MA_STATE_BULK)) {
                        mas->store_type = wr_rebalance;
                        return;
                }
index 234f9d0bd081a5cbc34e866a577e93834da93370..fd108fe0d095a70ae815ee15721117378f6b63d8 100644 (file)
@@ -76,7 +76,7 @@ objpool_init_percpu_slots(struct objpool_head *pool, int nr_objs,
                 * mimimal size of vmalloc is one page since vmalloc would
                 * always align the requested size to page size
                 */
-               if (pool->gfp & GFP_ATOMIC)
+               if ((pool->gfp & GFP_ATOMIC) == GFP_ATOMIC)
                        slot = kmalloc_node(size, pool->gfp, cpu_to_node(i));
                else
                        slot = __vmalloc_node(size, sizeof(void *), pool->gfp,
index 54e1809a38fd9f7a14f5c038637e7750cb8e7073..6e1581b9a616126e13458370e14aaa3ac4917ac7 100644 (file)
@@ -1,7 +1,7 @@
 // SPDX-License-Identifier: GPL-2.0
 /* Copyright (C) 2018-2019, Intel Corporation. */
 
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include <linux/crc32.h>
 #include <linux/device.h>
 #include <linux/firmware.h>
index 32060b8526681f069d97b1ffa1d53d3cc1e3e620..0a5a0e3600c8a758c222b54a40b7fa3153baf0e0 100644 (file)
@@ -40,7 +40,7 @@
 #include <linux/sched.h>
 #include <linux/bitops.h>
 #include <linux/slab.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 /**
  *     prandom_u32_state - seeded pseudo-random number generator.
index 15bc5b6f368c9db971a3e72a4210ea61b5b86fd3..9e4e88752d2ed22984bf5bd13498c09081cf54ce 100644 (file)
@@ -10,7 +10,7 @@
  */
 
 #include <linux/siphash.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #if defined(CONFIG_DCACHE_WORD_ACCESS) && BITS_PER_LONG == 64
 #include <linux/dcache.h>
index 6e3a1e5a7142f797fe20a28967657f50a466d4ee..33564f965958c3b983301ece007ebcba5cdfdbf0 100644 (file)
@@ -141,7 +141,7 @@ static void test_kmalloc_redzone_access(struct kunit *test)
 {
        struct kmem_cache *s = test_kmem_cache_create("TestSlub_RZ_kmalloc", 32,
                                SLAB_KMALLOC|SLAB_STORE_USER|SLAB_RED_ZONE);
-       u8 *p = __kmalloc_cache_noprof(s, GFP_KERNEL, 18);
+       u8 *p = alloc_hooks(__kmalloc_cache_noprof(s, GFP_KERNEL, 18));
 
        kasan_disable_current();
 
@@ -164,10 +164,16 @@ struct test_kfree_rcu_struct {
 
 static void test_kfree_rcu(struct kunit *test)
 {
-       struct kmem_cache *s = test_kmem_cache_create("TestSlub_kfree_rcu",
-                               sizeof(struct test_kfree_rcu_struct),
-                               SLAB_NO_MERGE);
-       struct test_kfree_rcu_struct *p = kmem_cache_alloc(s, GFP_KERNEL);
+       struct kmem_cache *s;
+       struct test_kfree_rcu_struct *p;
+
+       if (IS_BUILTIN(CONFIG_SLUB_KUNIT_TEST))
+               kunit_skip(test, "can't do kfree_rcu() when test is built-in");
+
+       s = test_kmem_cache_create("TestSlub_kfree_rcu",
+                                  sizeof(struct test_kfree_rcu_struct),
+                                  SLAB_NO_MERGE);
+       p = kmem_cache_alloc(s, GFP_KERNEL);
 
        kfree_rcu(p, rcu);
        kmem_cache_destroy(s);
@@ -177,13 +183,13 @@ static void test_kfree_rcu(struct kunit *test)
 
 static void test_leak_destroy(struct kunit *test)
 {
-       struct kmem_cache *s = test_kmem_cache_create("TestSlub_kfree_rcu",
+       struct kmem_cache *s = test_kmem_cache_create("TestSlub_leak_destroy",
                                                        64, SLAB_NO_MERGE);
        kmem_cache_alloc(s, GFP_KERNEL);
 
        kmem_cache_destroy(s);
 
-       KUNIT_EXPECT_EQ(test, 1, slab_errors);
+       KUNIT_EXPECT_EQ(test, 2, slab_errors);
 }
 
 static int test_init(struct kunit *test)
index 966da44bfc8693f17380a140da58c69fea43302a..76327b51e36f25fffae386d2b8016d1f2586688f 100644 (file)
@@ -27,7 +27,7 @@
 
 #include <asm/page.h>
 #include <asm/rwonce.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include <asm/word-at-a-time.h>
 
 #ifndef __HAVE_ARCH_STRNCASECMP
index 09f022ba1c0538b459fc5e3563b3d6f63e4621ae..c5e2ec9303c5d35fa41335a1b6873f75e71ab18a 100644 (file)
@@ -51,7 +51,7 @@
 
 #include <asm/page.h>          /* for PAGE_SIZE */
 #include <asm/byteorder.h>     /* cpu_to_le16 */
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #include <linux/string_helpers.h>
 #include "kstrtox.h"
index d5bb9ff106078d8e258c466dba1ff072b90543ac..b5bd567aa6b3e6f2fca48e8085e1ee79b7237e37 100644 (file)
@@ -38,7 +38,7 @@
  * - xxHash source repository: https://github.com/Cyan4973/xxHash
  */
 
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include <linux/errno.h>
 #include <linux/compiler.h>
 #include <linux/kernel.h>
index 5f1294a1408cc595abf3206a270611e68a812feb..8409784b163912de8879320a2476d41962f85c83 100644 (file)
@@ -12,7 +12,7 @@
 #ifdef __KERNEL__
 #      include <linux/xz.h>
 #      include <linux/kernel.h>
-#      include <asm/unaligned.h>
+#      include <linux/unaligned.h>
        /* XZ_PREBOOT may be defined only via decompress_unxz.c. */
 #      ifndef XZ_PREBOOT
 #              include <linux/slab.h>
index 1d9cc03924ca9aacb3c1f1a6b4f5ad5f1eabbc9f..c22a2e69bf46676ee932c2cc013812b625ab2bad 100644 (file)
@@ -15,7 +15,7 @@
 /*-****************************************
 *  Dependencies
 ******************************************/
-#include <asm/unaligned.h>  /* get_unaligned, put_unaligned* */
+#include <linux/unaligned.h>  /* get_unaligned, put_unaligned* */
 #include <linux/compiler.h>  /* inline */
 #include <linux/swab.h>  /* swab32, swab64 */
 #include <linux/types.h>  /* size_t, ptrdiff_t */
index 4c9f5ea13271d1f90163e75a35adf619ada3a5cd..33fa51d608dc517490c47790ad053816a1baf57a 100644 (file)
@@ -1085,7 +1085,6 @@ config HMM_MIRROR
        depends on MMU
 
 config GET_FREE_REGION
-       depends on SPARSEMEM
        bool
 
 config DEVICE_PRIVATE
index 1c9b596057a7ccbed809b6085902112e638f3504..7b5c7b307da99c453d343473cb585ec1a8077324 100644 (file)
@@ -67,6 +67,7 @@ static void damon_sysfs_test_add_targets(struct kunit *test)
        damon_destroy_ctx(ctx);
        kfree(sysfs_targets->targets_arr);
        kfree(sysfs_targets);
+       kfree(sysfs_target->regions);
        kfree(sysfs_target);
 }
 
index 3ca89e0279a7006ef7497cb1bffc802c5f407f2e..2fb328880b509e356315dd814169b91528a57b97 100644 (file)
@@ -109,18 +109,7 @@ unsigned long __thp_vma_allowable_orders(struct vm_area_struct *vma,
        if (!vma->vm_mm)                /* vdso */
                return 0;
 
-       /*
-        * Explicitly disabled through madvise or prctl, or some
-        * architectures may disable THP for some mappings, for
-        * example, s390 kvm.
-        * */
-       if ((vm_flags & VM_NOHUGEPAGE) ||
-           test_bit(MMF_DISABLE_THP, &vma->vm_mm->flags))
-               return 0;
-       /*
-        * If the hardware/firmware marked hugepage support disabled.
-        */
-       if (transparent_hugepage_flags & (1 << TRANSPARENT_HUGEPAGE_UNSUPPORTED))
+       if (thp_disabled_by_hw() || vma_thp_disabled(vma, vm_flags))
                return 0;
 
        /* khugepaged doesn't collapse DAX vma, but page fault is fine. */
@@ -1586,7 +1575,7 @@ int copy_huge_pmd(struct mm_struct *dst_mm, struct mm_struct *src_mm,
        int ret = -ENOMEM;
 
        pmd = pmdp_get_lockless(src_pmd);
-       if (unlikely(pmd_special(pmd))) {
+       if (unlikely(pmd_present(pmd) && pmd_special(pmd))) {
                dst_ptl = pmd_lock(dst_mm, dst_pmd);
                src_ptl = pmd_lockptr(src_mm, src_pmd);
                spin_lock_nested(src_ptl, SINGLE_DEPTH_NESTING);
index 89895f38f722423c02744f359799db4bb7f12dc2..ac607c306292f406bfdc88dcb379b3c7ecda0036 100644 (file)
@@ -106,6 +106,10 @@ static void __ref zero_pte_populate(pmd_t *pmd, unsigned long addr,
        }
 }
 
+void __weak __meminit kernel_pte_init(void *addr)
+{
+}
+
 static int __ref zero_pmd_populate(pud_t *pud, unsigned long addr,
                                unsigned long end)
 {
@@ -126,8 +130,10 @@ static int __ref zero_pmd_populate(pud_t *pud, unsigned long addr,
 
                        if (slab_is_available())
                                p = pte_alloc_one_kernel(&init_mm);
-                       else
+                       else {
                                p = early_alloc(PAGE_SIZE, NUMA_NO_NODE);
+                               kernel_pte_init(p);
+                       }
                        if (!p)
                                return -ENOMEM;
 
index f9c39898eaff6563a4aae6274b2cc7fdb5dc22d0..b538c3d48386a57f98b68899f6fc45f509af596f 100644 (file)
@@ -2227,7 +2227,7 @@ rollback:
        folio_put(new_folio);
 out:
        VM_BUG_ON(!list_empty(&pagelist));
-       trace_mm_khugepaged_collapse_file(mm, new_folio, index, is_shmem, addr, file, HPAGE_PMD_NR, result);
+       trace_mm_khugepaged_collapse_file(mm, new_folio, index, addr, is_shmem, file, HPAGE_PMD_NR, result);
        return result;
 }
 
@@ -2252,7 +2252,7 @@ static int hpage_collapse_scan_file(struct mm_struct *mm, unsigned long addr,
                        continue;
 
                if (xa_is_value(folio)) {
-                       ++swap;
+                       swap += 1 << xas_get_order(&xas);
                        if (cc->is_khugepaged &&
                            swap > khugepaged_max_ptes_swap) {
                                result = SCAN_EXCEED_SWAP_PTE;
@@ -2299,7 +2299,7 @@ static int hpage_collapse_scan_file(struct mm_struct *mm, unsigned long addr,
                 * is just too costly...
                 */
 
-               present++;
+               present += folio_nr_pages(folio);
 
                if (need_resched()) {
                        xas_pause(&xas);
index 2366578015adebdf6f281e7ee4295afaf6bfc22d..bdf77a3ec47bc26a8560c41a7ab0d485a9f99367 100644 (file)
@@ -4181,17 +4181,14 @@ fallback:
        return __alloc_swap_folio(vmf);
 }
 #else /* !CONFIG_TRANSPARENT_HUGEPAGE */
-static inline bool can_swapin_thp(struct vm_fault *vmf, pte_t *ptep, int nr_pages)
-{
-       return false;
-}
-
 static struct folio *alloc_swap_folio(struct vm_fault *vmf)
 {
        return __alloc_swap_folio(vmf);
 }
 #endif /* CONFIG_TRANSPARENT_HUGEPAGE */
 
+static DECLARE_WAIT_QUEUE_HEAD(swapcache_wq);
+
 /*
  * We enter with non-exclusive mmap_lock (to exclude vma changes,
  * but allow concurrent faults), and pte mapped but not yet locked.
@@ -4204,6 +4201,7 @@ vm_fault_t do_swap_page(struct vm_fault *vmf)
 {
        struct vm_area_struct *vma = vmf->vma;
        struct folio *swapcache, *folio = NULL;
+       DECLARE_WAITQUEUE(wait, current);
        struct page *page;
        struct swap_info_struct *si = NULL;
        rmap_t rmap_flags = RMAP_NONE;
@@ -4302,7 +4300,9 @@ vm_fault_t do_swap_page(struct vm_fault *vmf)
                                         * Relax a bit to prevent rapid
                                         * repeated page faults.
                                         */
+                                       add_wait_queue(&swapcache_wq, &wait);
                                        schedule_timeout_uninterruptible(1);
+                                       remove_wait_queue(&swapcache_wq, &wait);
                                        goto out_page;
                                }
                                need_clear_cache = true;
@@ -4609,8 +4609,11 @@ unlock:
                pte_unmap_unlock(vmf->pte, vmf->ptl);
 out:
        /* Clear the swap cache pin for direct swapin after PTL unlock */
-       if (need_clear_cache)
+       if (need_clear_cache) {
                swapcache_clear(si, entry, nr_pages);
+               if (waitqueue_active(&swapcache_wq))
+                       wake_up(&swapcache_wq);
+       }
        if (si)
                put_swap_device(si);
        return ret;
@@ -4625,8 +4628,11 @@ out_release:
                folio_unlock(swapcache);
                folio_put(swapcache);
        }
-       if (need_clear_cache)
+       if (need_clear_cache) {
                swapcache_clear(si, entry, nr_pages);
+               if (waitqueue_active(&swapcache_wq))
+                       wake_up(&swapcache_wq);
+       }
        if (si)
                put_swap_device(si);
        return ret;
@@ -4925,6 +4931,15 @@ vm_fault_t do_set_pmd(struct vm_fault *vmf, struct page *page)
        pmd_t entry;
        vm_fault_t ret = VM_FAULT_FALLBACK;
 
+       /*
+        * It is too late to allocate a small folio, we already have a large
+        * folio in the pagecache: especially s390 KVM cannot tolerate any
+        * PMD mappings, but PTE-mapped THP are fine. So let's simply refuse any
+        * PMD mappings if THPs are disabled.
+        */
+       if (thp_disabled_by_hw() || vma_thp_disabled(vma, vma->vm_flags))
+               return ret;
+
        if (!thp_vma_suitable_order(vma, haddr, PMD_ORDER))
                return ret;
 
@@ -6346,7 +6361,8 @@ static inline void pfnmap_args_setup(struct follow_pfnmap_args *args,
 static inline void pfnmap_lockdep_assert(struct vm_area_struct *vma)
 {
 #ifdef CONFIG_LOCKDEP
-       struct address_space *mapping = vma->vm_file->f_mapping;
+       struct file *file = vma->vm_file;
+       struct address_space *mapping = file ? file->f_mapping : NULL;
 
        if (mapping)
                lockdep_assert(lockdep_is_held(&vma->vm_file->f_mapping->i_mmap_rwsem) ||
index dd4b35a25aeb7d1a7037a625d7deacc02764f48f..1e0e34cb993f18c8fe08534a2bbab605b3c70f6e 100644 (file)
--- a/mm/mmap.c
+++ b/mm/mmap.c
@@ -1371,7 +1371,7 @@ unsigned long mmap_region(struct file *file, unsigned long addr,
        struct maple_tree mt_detach;
        unsigned long end = addr + len;
        bool writable_file_mapping = false;
-       int error = -ENOMEM;
+       int error;
        VMA_ITERATOR(vmi, mm, addr);
        VMG_STATE(vmg, mm, &vmi, addr, end, vm_flags, pgoff);
 
@@ -1396,8 +1396,10 @@ unsigned long mmap_region(struct file *file, unsigned long addr,
        }
 
        /* Check against address space limit. */
-       if (!may_expand_vm(mm, vm_flags, pglen - vms.nr_pages))
+       if (!may_expand_vm(mm, vm_flags, pglen - vms.nr_pages)) {
+               error = -ENOMEM;
                goto abort_munmap;
+       }
 
        /*
         * Private writable mapping: check memory availability
@@ -1405,14 +1407,24 @@ unsigned long mmap_region(struct file *file, unsigned long addr,
        if (accountable_mapping(file, vm_flags)) {
                charged = pglen;
                charged -= vms.nr_accounted;
-               if (charged && security_vm_enough_memory_mm(mm, charged))
-                       goto abort_munmap;
+               if (charged) {
+                       error = security_vm_enough_memory_mm(mm, charged);
+                       if (error)
+                               goto abort_munmap;
+               }
 
                vms.nr_accounted = 0;
                vm_flags |= VM_ACCOUNT;
                vmg.flags = vm_flags;
        }
 
+       /*
+        * clear PTEs while the vma is still in the tree so that rmap
+        * cannot race with the freeing later in the truncate scenario.
+        * This is also needed for call_mmap(), which is why vm_ops
+        * close function is called.
+        */
+       vms_clean_up_area(&vms, &mas_detach);
        vma = vma_merge_new_range(&vmg);
        if (vma)
                goto expanded;
@@ -1422,8 +1434,10 @@ unsigned long mmap_region(struct file *file, unsigned long addr,
         * not unmapped, but the maps are removed from the list.
         */
        vma = vm_area_alloc(mm);
-       if (!vma)
+       if (!vma) {
+               error = -ENOMEM;
                goto unacct_error;
+       }
 
        vma_iter_config(&vmi, addr, end);
        vma_set_range(vma, addr, end, pgoff);
@@ -1432,11 +1446,6 @@ unsigned long mmap_region(struct file *file, unsigned long addr,
 
        if (file) {
                vma->vm_file = get_file(file);
-               /*
-                * call_mmap() may map PTE, so ensure there are no existing PTEs
-                * and call the vm_ops close function if one exists.
-                */
-               vms_clean_up_area(&vms, &mas_detach);
                error = call_mmap(file, vma);
                if (error)
                        goto unmap_and_free_vma;
@@ -1453,9 +1462,10 @@ unsigned long mmap_region(struct file *file, unsigned long addr,
                 * Expansion is handled above, merging is handled below.
                 * Drivers should not alter the address of the VMA.
                 */
-               error = -EINVAL;
-               if (WARN_ON((addr != vma->vm_start)))
+               if (WARN_ON((addr != vma->vm_start))) {
+                       error = -EINVAL;
                        goto close_and_free_vma;
+               }
 
                vma_iter_config(&vmi, addr, end);
                /*
@@ -1500,13 +1510,15 @@ unsigned long mmap_region(struct file *file, unsigned long addr,
        }
 
        /* Allow architectures to sanity-check the vm_flags */
-       error = -EINVAL;
-       if (!arch_validate_flags(vma->vm_flags))
+       if (!arch_validate_flags(vma->vm_flags)) {
+               error = -EINVAL;
                goto close_and_free_vma;
+       }
 
-       error = -ENOMEM;
-       if (vma_iter_prealloc(&vmi, vma))
+       if (vma_iter_prealloc(&vmi, vma)) {
+               error = -ENOMEM;
                goto close_and_free_vma;
+       }
 
        /* Lock the VMA since it is modified after insertion into VMA tree */
        vma_start_write(vma);
@@ -1630,6 +1642,7 @@ SYSCALL_DEFINE5(remap_file_pages, unsigned long, start, unsigned long, size,
        unsigned long populate = 0;
        unsigned long ret = -EINVAL;
        struct file *file;
+       vm_flags_t vm_flags;
 
        pr_warn_once("%s (%d) uses deprecated remap_file_pages() syscall. See Documentation/mm/remap_file_pages.rst.\n",
                     current->comm, current->pid);
@@ -1646,12 +1659,60 @@ SYSCALL_DEFINE5(remap_file_pages, unsigned long, start, unsigned long, size,
        if (pgoff + (size >> PAGE_SHIFT) < pgoff)
                return ret;
 
-       if (mmap_write_lock_killable(mm))
+       if (mmap_read_lock_killable(mm))
+               return -EINTR;
+
+       /*
+        * Look up VMA under read lock first so we can perform the security
+        * without holding locks (which can be problematic). We reacquire a
+        * write lock later and check nothing changed underneath us.
+        */
+       vma = vma_lookup(mm, start);
+
+       if (!vma || !(vma->vm_flags & VM_SHARED)) {
+               mmap_read_unlock(mm);
+               return -EINVAL;
+       }
+
+       prot |= vma->vm_flags & VM_READ ? PROT_READ : 0;
+       prot |= vma->vm_flags & VM_WRITE ? PROT_WRITE : 0;
+       prot |= vma->vm_flags & VM_EXEC ? PROT_EXEC : 0;
+
+       flags &= MAP_NONBLOCK;
+       flags |= MAP_SHARED | MAP_FIXED | MAP_POPULATE;
+       if (vma->vm_flags & VM_LOCKED)
+               flags |= MAP_LOCKED;
+
+       /* Save vm_flags used to calculate prot and flags, and recheck later. */
+       vm_flags = vma->vm_flags;
+       file = get_file(vma->vm_file);
+
+       mmap_read_unlock(mm);
+
+       /* Call outside mmap_lock to be consistent with other callers. */
+       ret = security_mmap_file(file, prot, flags);
+       if (ret) {
+               fput(file);
+               return ret;
+       }
+
+       ret = -EINVAL;
+
+       /* OK security check passed, take write lock + let it rip. */
+       if (mmap_write_lock_killable(mm)) {
+               fput(file);
                return -EINTR;
+       }
 
        vma = vma_lookup(mm, start);
 
-       if (!vma || !(vma->vm_flags & VM_SHARED))
+       if (!vma)
+               goto out;
+
+       /* Make sure things didn't change under us. */
+       if (vma->vm_flags != vm_flags)
+               goto out;
+       if (vma->vm_file != file)
                goto out;
 
        if (start + size > vma->vm_end) {
@@ -1679,25 +1740,11 @@ SYSCALL_DEFINE5(remap_file_pages, unsigned long, start, unsigned long, size,
                        goto out;
        }
 
-       prot |= vma->vm_flags & VM_READ ? PROT_READ : 0;
-       prot |= vma->vm_flags & VM_WRITE ? PROT_WRITE : 0;
-       prot |= vma->vm_flags & VM_EXEC ? PROT_EXEC : 0;
-
-       flags &= MAP_NONBLOCK;
-       flags |= MAP_SHARED | MAP_FIXED | MAP_POPULATE;
-       if (vma->vm_flags & VM_LOCKED)
-               flags |= MAP_LOCKED;
-
-       file = get_file(vma->vm_file);
-       ret = security_mmap_file(vma->vm_file, prot, flags);
-       if (ret)
-               goto out_fput;
        ret = do_mmap(vma->vm_file, start, size,
                        prot, flags, 0, pgoff, &populate, NULL);
-out_fput:
-       fput(file);
 out:
        mmap_write_unlock(mm);
+       fput(file);
        if (populate)
                mm_populate(ret, populate);
        if (!IS_ERR_VALUE(ret))
@@ -1744,7 +1791,8 @@ static int do_brk_flags(struct vma_iterator *vmi, struct vm_area_struct *vma,
                VMG_STATE(vmg, mm, vmi, addr, addr + len, flags, PHYS_PFN(addr));
 
                vmg.prev = vma;
-               vma_iter_next_range(vmi);
+               /* vmi is positioned at prev, which this mode expects. */
+               vmg.merge_flags = VMG_FLAG_JUST_EXPAND;
 
                if (vma_merge_new_range(&vmg))
                        goto out;
index 24712f8dbb6b5c6564f85ccc5316be3904ba4c80..dda09e957a5d4c2546934b796e862e5e0213b311 100644 (file)
@@ -238,6 +238,7 @@ static bool move_normal_pmd(struct vm_area_struct *vma, unsigned long old_addr,
 {
        spinlock_t *old_ptl, *new_ptl;
        struct mm_struct *mm = vma->vm_mm;
+       bool res = false;
        pmd_t pmd;
 
        if (!arch_supports_page_table_move())
@@ -277,19 +278,25 @@ static bool move_normal_pmd(struct vm_area_struct *vma, unsigned long old_addr,
        if (new_ptl != old_ptl)
                spin_lock_nested(new_ptl, SINGLE_DEPTH_NESTING);
 
-       /* Clear the pmd */
        pmd = *old_pmd;
+
+       /* Racing with collapse? */
+       if (unlikely(!pmd_present(pmd) || pmd_leaf(pmd)))
+               goto out_unlock;
+       /* Clear the pmd */
        pmd_clear(old_pmd);
+       res = true;
 
        VM_BUG_ON(!pmd_none(*new_pmd));
 
        pmd_populate(mm, new_pmd, pmd_pgtable(pmd));
        flush_tlb_range(vma, old_addr, old_addr + PMD_SIZE);
+out_unlock:
        if (new_ptl != old_ptl)
                spin_unlock(new_ptl);
        spin_unlock(old_ptl);
 
-       return true;
+       return res;
 }
 #else
 static inline bool move_normal_pmd(struct vm_area_struct *vma,
index be52b93a9c5804c8499dc6741f48482c76877b18..a3877e9bc878ad6257b658facbfab00b9f33f6ef 100644 (file)
@@ -349,7 +349,7 @@ static void __init numa_clear_kernel_node_hotplug(void)
        for_each_reserved_mem_region(mb_region) {
                int nid = memblock_get_region_node(mb_region);
 
-               if (nid != MAX_NUMNODES)
+               if (numa_valid_node(nid))
                        node_set(nid, reserved_nodemask);
        }
 
index 8afab64814dc455a15fd4bf71da301440734f30d..94a2ffe2800897f4635afc3d9cbace88b7236ea5 100644 (file)
@@ -2893,12 +2893,12 @@ struct page *rmqueue_buddy(struct zone *preferred_zone, struct zone *zone,
                        page = __rmqueue(zone, order, migratetype, alloc_flags);
 
                        /*
-                        * If the allocation fails, allow OOM handling access
-                        * to HIGHATOMIC reserves as failing now is worse than
-                        * failing a high-order atomic allocation in the
-                        * future.
+                        * If the allocation fails, allow OOM handling and
+                        * order-0 (atomic) allocs access to HIGHATOMIC
+                        * reserves as failing now is worse than failing a
+                        * high-order atomic allocation in the future.
                         */
-                       if (!page && (alloc_flags & ALLOC_OOM))
+                       if (!page && (alloc_flags & (ALLOC_OOM|ALLOC_NON_BLOCK)))
                                page = __rmqueue_smallest(zone, order, MIGRATE_HIGHATOMIC);
 
                        if (!page) {
index 461ea3bbd8d991e74767eaae655d60231edefcc3..5f9f01532e67a4a3eebeba4c06e26201802bcc0a 100644 (file)
@@ -744,7 +744,8 @@ struct folio *folio_walk_start(struct folio_walk *fw,
        pud = pudp_get(pudp);
        if (pud_none(pud))
                goto not_found;
-       if (IS_ENABLED(CONFIG_PGTABLE_HAS_HUGE_LEAVES) && pud_leaf(pud)) {
+       if (IS_ENABLED(CONFIG_PGTABLE_HAS_HUGE_LEAVES) &&
+           (!pud_present(pud) || pud_leaf(pud))) {
                ptl = pud_lock(vma->vm_mm, pudp);
                pud = pudp_get(pudp);
 
@@ -753,6 +754,10 @@ struct folio *folio_walk_start(struct folio_walk *fw,
                fw->pudp = pudp;
                fw->pud = pud;
 
+               /*
+                * TODO: FW_MIGRATION support for PUD migration entries
+                * once there are relevant users.
+                */
                if (!pud_present(pud) || pud_devmap(pud) || pud_special(pud)) {
                        spin_unlock(ptl);
                        goto not_found;
@@ -769,12 +774,13 @@ struct folio *folio_walk_start(struct folio_walk *fw,
        }
 
 pmd_table:
-       VM_WARN_ON_ONCE(pud_leaf(*pudp));
+       VM_WARN_ON_ONCE(!pud_present(pud) || pud_leaf(pud));
        pmdp = pmd_offset(pudp, addr);
        pmd = pmdp_get_lockless(pmdp);
        if (pmd_none(pmd))
                goto not_found;
-       if (IS_ENABLED(CONFIG_PGTABLE_HAS_HUGE_LEAVES) && pmd_leaf(pmd)) {
+       if (IS_ENABLED(CONFIG_PGTABLE_HAS_HUGE_LEAVES) &&
+           (!pmd_present(pmd) || pmd_leaf(pmd))) {
                ptl = pmd_lock(vma->vm_mm, pmdp);
                pmd = pmdp_get(pmdp);
 
@@ -786,7 +792,7 @@ pmd_table:
                if (pmd_none(pmd)) {
                        spin_unlock(ptl);
                        goto not_found;
-               } else if (!pmd_leaf(pmd)) {
+               } else if (pmd_present(pmd) && !pmd_leaf(pmd)) {
                        spin_unlock(ptl);
                        goto pte_table;
                } else if (pmd_present(pmd)) {
@@ -812,7 +818,7 @@ pmd_table:
        }
 
 pte_table:
-       VM_WARN_ON_ONCE(pmd_leaf(pmdp_get_lockless(pmdp)));
+       VM_WARN_ON_ONCE(!pmd_present(pmd) || pmd_leaf(pmd));
        ptep = pte_offset_map_lock(vma->vm_mm, pmdp, addr, &ptl);
        if (!ptep)
                goto not_found;
index 3afb5ad701e14ad87b6e5173b2974f1309399b8e..399552814fd0ffaa00c598bb60f3203e5378c220 100644 (file)
@@ -238,7 +238,7 @@ SYSCALL_DEFINE1(memfd_secret, unsigned int, flags)
        /* make sure local flags do not confict with global fcntl.h */
        BUILD_BUG_ON(SECRETMEM_FLAGS_MASK & O_CLOEXEC);
 
-       if (!secretmem_enable)
+       if (!secretmem_enable || !can_set_direct_map())
                return -ENOSYS;
 
        if (flags & ~(SECRETMEM_FLAGS_MASK | O_CLOEXEC))
@@ -280,7 +280,7 @@ static struct file_system_type secretmem_fs = {
 
 static int __init secretmem_init(void)
 {
-       if (!secretmem_enable)
+       if (!secretmem_enable || !can_set_direct_map())
                return 0;
 
        secretmem_mnt = kern_mount(&secretmem_fs);
index 4f11b55063631976af81e4221c7366b768db6690..4ba1d00fabdaa2c30f1d9dd83d81e825812f6fbc 100644 (file)
@@ -1166,7 +1166,9 @@ static int shmem_getattr(struct mnt_idmap *idmap,
        stat->attributes_mask |= (STATX_ATTR_APPEND |
                        STATX_ATTR_IMMUTABLE |
                        STATX_ATTR_NODUMP);
+       inode_lock_shared(inode);
        generic_fillattr(idmap, request_mask, inode, stat);
+       inode_unlock_shared(inode);
 
        if (shmem_huge_global_enabled(inode, 0, 0, false, NULL, 0))
                stat->blksize = HPAGE_PMD_SIZE;
@@ -1664,12 +1666,7 @@ unsigned long shmem_allowable_huge_orders(struct inode *inode,
        loff_t i_size;
        int order;
 
-       if (vma && ((vm_flags & VM_NOHUGEPAGE) ||
-           test_bit(MMF_DISABLE_THP, &vma->vm_mm->flags)))
-               return 0;
-
-       /* If the hardware/firmware marked hugepage support disabled. */
-       if (transparent_hugepage_flags & (1 << TRANSPARENT_HUGEPAGE_UNSUPPORTED))
+       if (thp_disabled_by_hw() || (vma && vma_thp_disabled(vma, vm_flags)))
                return 0;
 
        global_huge = shmem_huge_global_enabled(inode, index, write_end,
index f22fb760b2866124d9d873d28b5a7fa6867aeb90..6c6fe6d630ce3d919c29bafd15b401324618da1a 100644 (file)
--- a/mm/slab.h
+++ b/mm/slab.h
@@ -310,7 +310,7 @@ struct kmem_cache {
 };
 
 #if defined(CONFIG_SYSFS) && !defined(CONFIG_SLUB_TINY)
-#define SLAB_SUPPORTS_SYSFS
+#define SLAB_SUPPORTS_SYSFS 1
 void sysfs_slab_unlink(struct kmem_cache *s);
 void sysfs_slab_release(struct kmem_cache *s);
 #else
@@ -546,6 +546,12 @@ static inline bool kmem_cache_debug_flags(struct kmem_cache *s, slab_flags_t fla
        return false;
 }
 
+#if IS_ENABLED(CONFIG_SLUB_DEBUG) && IS_ENABLED(CONFIG_KUNIT)
+bool slab_in_kunit_test(void);
+#else
+static inline bool slab_in_kunit_test(void) { return false; }
+#endif
+
 #ifdef CONFIG_SLAB_OBJ_EXT
 
 /*
index 7443244656150325fb2a7d0158a71821e1418062..552b92dfdac775c3aee9a1bb116c85ca527835cc 100644 (file)
@@ -508,8 +508,9 @@ void kmem_cache_destroy(struct kmem_cache *s)
        kasan_cache_shutdown(s);
 
        err = __kmem_cache_shutdown(s);
-       WARN(err, "%s %s: Slab cache still has objects when called from %pS",
-            __func__, s->name, (void *)_RET_IP_);
+       if (!slab_in_kunit_test())
+               WARN(err, "%s %s: Slab cache still has objects when called from %pS",
+                    __func__, s->name, (void *)_RET_IP_);
 
        list_del(&s->list);
 
@@ -1208,7 +1209,7 @@ __do_krealloc(const void *p, size_t new_size, gfp_t flags)
                /* Zero out spare memory. */
                if (want_init_on_alloc(flags)) {
                        kasan_disable_current();
-                       memset((void *)p + new_size, 0, ks - new_size);
+                       memset(kasan_reset_tag(p) + new_size, 0, ks - new_size);
                        kasan_enable_current();
                }
 
index 21f71cb6cc06d951a657290421f41170bb3c76cf..5b832512044e3ead8ccde2c02308bd8954246db5 100644 (file)
--- a/mm/slub.c
+++ b/mm/slub.c
@@ -827,7 +827,7 @@ static bool slab_add_kunit_errors(void)
        return true;
 }
 
-static bool slab_in_kunit_test(void)
+bool slab_in_kunit_test(void)
 {
        struct kunit_resource *resource;
 
@@ -843,7 +843,6 @@ static bool slab_in_kunit_test(void)
 }
 #else
 static inline bool slab_add_kunit_errors(void) { return false; }
-static inline bool slab_in_kunit_test(void) { return false; }
 #endif
 
 static inline unsigned int size_from_object(struct kmem_cache *s)
@@ -5436,6 +5435,8 @@ static void list_slab_objects(struct kmem_cache *s, struct slab *slab,
        for_each_object(p, s, addr, slab->objects) {
 
                if (!test_bit(__obj_to_index(s, addr, p), object_map)) {
+                       if (slab_add_kunit_errors())
+                               continue;
                        pr_err("Object 0x%p @offset=%tu\n", p, p - addr);
                        print_tracking(s, p);
                }
index edcc7a6b0f6f2072e730e45a43a96eefded18302..c0388b2e959da6c374d3736dbdb20bd41996c5f1 100644 (file)
@@ -184,6 +184,10 @@ static void * __meminit vmemmap_alloc_block_zero(unsigned long size, int node)
        return p;
 }
 
+void __weak __meminit kernel_pte_init(void *addr)
+{
+}
+
 pmd_t * __meminit vmemmap_pmd_populate(pud_t *pud, unsigned long addr, int node)
 {
        pmd_t *pmd = pmd_offset(pud, addr);
@@ -191,6 +195,7 @@ pmd_t * __meminit vmemmap_pmd_populate(pud_t *pud, unsigned long addr, int node)
                void *p = vmemmap_alloc_block_zero(PAGE_SIZE, node);
                if (!p)
                        return NULL;
+               kernel_pte_init(p);
                pmd_populate_kernel(&init_mm, pmd, p);
        }
        return pmd;
index 0cded32414a1f13f70ebd87f5b37bbaa4821b427..b0915f3fab315f06fb9aa90b89c93347cc2459c3 100644 (file)
@@ -194,9 +194,6 @@ static int __try_to_reclaim_swap(struct swap_info_struct *si,
        if (IS_ERR(folio))
                return 0;
 
-       /* offset could point to the middle of a large folio */
-       entry = folio->swap;
-       offset = swp_offset(entry);
        nr_pages = folio_nr_pages(folio);
        ret = -nr_pages;
 
@@ -210,6 +207,10 @@ static int __try_to_reclaim_swap(struct swap_info_struct *si,
        if (!folio_trylock(folio))
                goto out;
 
+       /* offset could point to the middle of a large folio */
+       entry = folio->swap;
+       offset = swp_offset(entry);
+
        need_reclaim = ((flags & TTRS_ANYWAY) ||
                        ((flags & TTRS_UNMAPPED) && !folio_mapped(folio)) ||
                        ((flags & TTRS_FULL) && mem_cgroup_swap_full(folio)));
@@ -2312,7 +2313,7 @@ static int unuse_mm(struct mm_struct *mm, unsigned int type)
 
        mmap_read_lock(mm);
        for_each_vma(vmi, vma) {
-               if (vma->anon_vma) {
+               if (vma->anon_vma && !is_vm_hugetlb_page(vma)) {
                        ret = unuse_vma(vma, type);
                        if (ret)
                                break;
index 4737afcb064c94e276f4c0e17249d2c597d2f8bf..b21ffec33f8e06212564d9d91c107374f854bf71 100644 (file)
--- a/mm/vma.c
+++ b/mm/vma.c
@@ -917,6 +917,7 @@ struct vm_area_struct *vma_merge_new_range(struct vma_merge_struct *vmg)
        pgoff_t pgoff = vmg->pgoff;
        pgoff_t pglen = PHYS_PFN(end - start);
        bool can_merge_left, can_merge_right;
+       bool just_expand = vmg->merge_flags & VMG_FLAG_JUST_EXPAND;
 
        mmap_assert_write_locked(vmg->mm);
        VM_WARN_ON(vmg->vma);
@@ -930,7 +931,7 @@ struct vm_area_struct *vma_merge_new_range(struct vma_merge_struct *vmg)
                return NULL;
 
        can_merge_left = can_vma_merge_left(vmg);
-       can_merge_right = can_vma_merge_right(vmg, can_merge_left);
+       can_merge_right = !just_expand && can_vma_merge_right(vmg, can_merge_left);
 
        /* If we can merge with the next VMA, adjust vmg accordingly. */
        if (can_merge_right) {
@@ -953,7 +954,11 @@ struct vm_area_struct *vma_merge_new_range(struct vma_merge_struct *vmg)
                if (can_merge_right && !can_merge_remove_vma(next))
                        vmg->end = end;
 
-               vma_prev(vmg->vmi); /* Equivalent to going to the previous range */
+               /* In expand-only case we are already positioned at prev. */
+               if (!just_expand) {
+                       /* Equivalent to going to the previous range. */
+                       vma_prev(vmg->vmi);
+               }
        }
 
        /*
@@ -967,12 +972,14 @@ struct vm_area_struct *vma_merge_new_range(struct vma_merge_struct *vmg)
        }
 
        /* If expansion failed, reset state. Allows us to retry merge later. */
-       vmg->vma = NULL;
-       vmg->start = start;
-       vmg->end = end;
-       vmg->pgoff = pgoff;
-       if (vmg->vma == prev)
-               vma_iter_set(vmg->vmi, start);
+       if (!just_expand) {
+               vmg->vma = NULL;
+               vmg->start = start;
+               vmg->end = end;
+               vmg->pgoff = pgoff;
+               if (vmg->vma == prev)
+                       vma_iter_set(vmg->vmi, start);
+       }
 
        return NULL;
 }
index 819f994cf727994d611d907375c0de95f2a6671d..55457cb682008f5d8f188f0bf4e657adddd3fdac 100644 (file)
--- a/mm/vma.h
+++ b/mm/vma.h
@@ -59,6 +59,17 @@ enum vma_merge_state {
        VMA_MERGE_SUCCESS,
 };
 
+enum vma_merge_flags {
+       VMG_FLAG_DEFAULT = 0,
+       /*
+        * If we can expand, simply do so. We know there is nothing to merge to
+        * the right. Does not reset state upon failure to merge. The VMA
+        * iterator is assumed to be positioned at the previous VMA, rather than
+        * at the gap.
+        */
+       VMG_FLAG_JUST_EXPAND = 1 << 0,
+};
+
 /* Represents a VMA merge operation. */
 struct vma_merge_struct {
        struct mm_struct *mm;
@@ -75,6 +86,7 @@ struct vma_merge_struct {
        struct mempolicy *policy;
        struct vm_userfaultfd_ctx uffd_ctx;
        struct anon_vma_name *anon_name;
+       enum vma_merge_flags merge_flags;
        enum vma_merge_state state;
 };
 
@@ -99,6 +111,7 @@ static inline pgoff_t vma_pgoff_offset(struct vm_area_struct *vma,
                .flags = flags_,                                        \
                .pgoff = pgoff_,                                        \
                .state = VMA_MERGE_START,                               \
+               .merge_flags = VMG_FLAG_DEFAULT,                        \
        }
 
 #define VMG_VMA_STATE(name, vmi_, prev_, vma_, start_, end_)   \
@@ -118,6 +131,7 @@ static inline pgoff_t vma_pgoff_offset(struct vm_area_struct *vma,
                .uffd_ctx = vma_->vm_userfaultfd_ctx,           \
                .anon_name = anon_vma_name(vma_),               \
                .state = VMA_MERGE_START,                       \
+               .merge_flags = VMG_FLAG_DEFAULT,                \
        }
 
 #ifdef CONFIG_DEBUG_VM_MAPLE_TREE
@@ -241,15 +255,9 @@ static inline void vms_abort_munmap_vmas(struct vma_munmap_struct *vms,
         * failure method of leaving a gap where the MAP_FIXED mapping failed.
         */
        mas_set_range(mas, vms->start, vms->end - 1);
-       if (unlikely(mas_store_gfp(mas, NULL, GFP_KERNEL))) {
-               pr_warn_once("%s: (%d) Unable to abort munmap() operation\n",
-                            current->comm, current->pid);
-               /* Leaving vmas detached and in-tree may hamper recovery */
-               reattach_vmas(mas_detach);
-       } else {
-               /* Clean up the insertion of the unfortunate gap */
-               vms_complete_munmap_vmas(vms, mas_detach);
-       }
+       mas_store_gfp(mas, NULL, GFP_KERNEL|__GFP_NOFAIL);
+       /* Clean up the insertion of the unfortunate gap */
+       vms_complete_munmap_vmas(vms, mas_detach);
 }
 
 int
index 749cdc110c745944cd455ae9c5a4c373f631341d..eb4e8440c50711ad927930a7173d2f3d4b1d1bf2 100644 (file)
@@ -4963,8 +4963,8 @@ static void lru_gen_shrink_node(struct pglist_data *pgdat, struct scan_control *
 
        blk_finish_plug(&plug);
 done:
-       /* kswapd should never fail */
-       pgdat->kswapd_failures = 0;
+       if (sc->nr_reclaimed > reclaimed)
+               pgdat->kswapd_failures = 0;
 }
 
 /******************************************************************************
index 449914ea99198abdc60dbe676d228b9725244a9f..162013952074b03794a57980def61f31cb2a432b 100644 (file)
@@ -190,7 +190,6 @@ static struct shrinker *zswap_shrinker;
  *              section for context.
  * pool - the zswap_pool the entry's data is in
  * handle - zpool allocation handle that stores the compressed page data
- * value - value of the same-value filled pages which have same content
  * objcg - the obj_cgroup that the compressed memory is charged to
  * lru - handle to the pool's lru used to evict pages.
  */
index 6a743d0043012b8a5b431d00a9e4d0e3195a8adf..27f0ab146026b475ba71093799fbe96d55bb2b4c 100644 (file)
@@ -16,7 +16,7 @@
 #include <net/llc.h>
 #include <net/llc_pdu.h>
 #include <net/garp.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 static unsigned int garp_join_time __read_mostly = 200;
 module_param(garp_join_time, uint, 0644);
index 3154d74094932eaf927cdeeb5d92ce5c663840aa..e0c96d0da8d599c60582c9fa020e1e3934fe2b47 100644 (file)
@@ -16,7 +16,7 @@
 #include <linux/slab.h>
 #include <linux/module.h>
 #include <net/mrp.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 static unsigned int mrp_join_time __read_mostly = 200;
 module_param(mrp_join_time, uint, 0644);
index 63f988f0c9e8e7132a4e852e9a319760db560514..ee967fd25312cbe3999044700d71a756cf21eb74 100644 (file)
@@ -43,6 +43,8 @@ config NET_9P_XEN
 config NET_9P_USBG
        bool "9P USB Gadget Transport"
        depends on USB_GADGET=y || USB_GADGET=NET_9P
+       select CONFIGFS_FS
+       select USB_LIBCOMPOSITE
        help
          This builds support for a transport for 9pfs over
          usb gadget.
index 5cd94721d974f4428d9a642c13bf325ee15fd2be..09f8ced9f8bb7f5174904e0f154a13eb64de9387 100644 (file)
@@ -977,8 +977,10 @@ error:
 struct p9_client *p9_client_create(const char *dev_name, char *options)
 {
        int err;
+       static atomic_t seqno = ATOMIC_INIT(0);
        struct p9_client *clnt;
        char *client_id;
+       char *cache_name;
 
        clnt = kmalloc(sizeof(*clnt), GFP_KERNEL);
        if (!clnt)
@@ -1035,15 +1037,23 @@ struct p9_client *p9_client_create(const char *dev_name, char *options)
        if (err)
                goto close_trans;
 
+       cache_name = kasprintf(GFP_KERNEL,
+               "9p-fcall-cache-%u", atomic_inc_return(&seqno));
+       if (!cache_name) {
+               err = -ENOMEM;
+               goto close_trans;
+       }
+
        /* P9_HDRSZ + 4 is the smallest packet header we can have that is
         * followed by data accessed from userspace by read
         */
        clnt->fcall_cache =
-               kmem_cache_create_usercopy("9p-fcall-cache", clnt->msize,
+               kmem_cache_create_usercopy(cache_name, clnt->msize,
                                           0, 0, P9_HDRSZ + 4,
                                           clnt->msize - (P9_HDRSZ + 4),
                                           NULL);
 
+       kfree(cache_name);
        return clnt;
 
 close_trans:
index 4c7e855343245b62e5e6ba3b16b2b69244f493a5..801eff8a40e5543ea136ae797ab340158b409825 100644 (file)
@@ -7,7 +7,7 @@
 #include "distributed-arp-table.h"
 #include "main.h"
 
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include <linux/atomic.h>
 #include <linux/bitops.h>
 #include <linux/byteorder/generic.h>
index 67604ccec2f42739a554bc93d7834ebc4177589c..0b4d0a8bd361416c3417dd4407e38d00dbfa72b1 100644 (file)
@@ -185,6 +185,28 @@ void bt_sock_unlink(struct bt_sock_list *l, struct sock *sk)
 }
 EXPORT_SYMBOL(bt_sock_unlink);
 
+bool bt_sock_linked(struct bt_sock_list *l, struct sock *s)
+{
+       struct sock *sk;
+
+       if (!l || !s)
+               return false;
+
+       read_lock(&l->lock);
+
+       sk_for_each(sk, &l->head) {
+               if (s == sk) {
+                       read_unlock(&l->lock);
+                       return true;
+               }
+       }
+
+       read_unlock(&l->lock);
+
+       return false;
+}
+EXPORT_SYMBOL(bt_sock_linked);
+
 void bt_accept_enqueue(struct sock *parent, struct sock *sk, bool bh)
 {
        const struct cred *old_cred;
@@ -825,11 +847,14 @@ cleanup_sysfs:
        bt_sysfs_cleanup();
 cleanup_led:
        bt_leds_cleanup();
+       debugfs_remove_recursive(bt_debugfs);
        return err;
 }
 
 static void __exit bt_exit(void)
 {
+       iso_exit();
+
        mgmt_exit();
 
        sco_exit();
index ec45f77fce2181c21f2cd2173720194bc662619b..d44987d4515c0b6eb4766b40e25b4ba5b689584b 100644 (file)
@@ -29,7 +29,7 @@
 #include <linux/kthread.h>
 #include <linux/file.h>
 #include <linux/etherdevice.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #include <net/bluetooth/bluetooth.h>
 #include <net/bluetooth/l2cap.h>
@@ -745,8 +745,7 @@ static int __init bnep_init(void)
        if (flt[0])
                BT_INFO("BNEP filters: %s", flt);
 
-       bnep_sock_init();
-       return 0;
+       return bnep_sock_init();
 }
 
 static void __exit bnep_exit(void)
index ec97a4bab1c9f8aedadaa30a5e3c71e9b756bf86..c18df3a086075f8336bad80a08f101fc0105bd69 100644 (file)
@@ -5,7 +5,7 @@
 
 #include <linux/devcoredump.h>
 
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include <net/bluetooth/bluetooth.h>
 #include <net/bluetooth/hci_core.h>
 
index 0df19f2f4af94499defe78897e8c78fd0dbc2daf..5c89a05e8b290583529467e14193dbb68ddf49aa 100644 (file)
@@ -5,7 +5,7 @@
  * Copyright (C) 2021 Intel Corporation
  */
 
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 void eir_create(struct hci_dev *hdev, u8 *data);
 
index d083117ee36c3b00e95210f5daf2781dfdec019e..c4c74b82ed211cfeb8ee0cb1c939e96240920b68 100644 (file)
@@ -289,6 +289,9 @@ static int hci_enhanced_setup_sync(struct hci_dev *hdev, void *data)
 
        kfree(conn_handle);
 
+       if (!hci_conn_valid(hdev, conn))
+               return -ECANCELED;
+
        bt_dev_dbg(hdev, "hcon %p", conn);
 
        configure_datapath_sync(hdev, &conn->codec);
index d6976db02c06c757d106f67641936ffbcea29a7f..96d097b21d13f2f52cee5f998fe2174ae8b97a06 100644 (file)
@@ -33,7 +33,7 @@
 #include <linux/property.h>
 #include <linux/suspend.h>
 #include <linux/wait.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #include <net/bluetooth/bluetooth.h>
 #include <net/bluetooth/hci_core.h>
@@ -1644,12 +1644,12 @@ void hci_adv_instances_clear(struct hci_dev *hdev)
        struct adv_info *adv_instance, *n;
 
        if (hdev->adv_instance_timeout) {
-               cancel_delayed_work(&hdev->adv_instance_expire);
+               disable_delayed_work(&hdev->adv_instance_expire);
                hdev->adv_instance_timeout = 0;
        }
 
        list_for_each_entry_safe(adv_instance, n, &hdev->adv_instances, list) {
-               cancel_delayed_work_sync(&adv_instance->rpa_expired_cb);
+               disable_delayed_work_sync(&adv_instance->rpa_expired_cb);
                list_del(&adv_instance->list);
                kfree(adv_instance);
        }
@@ -2685,11 +2685,11 @@ void hci_unregister_dev(struct hci_dev *hdev)
        list_del(&hdev->list);
        write_unlock(&hci_dev_list_lock);
 
-       cancel_work_sync(&hdev->rx_work);
-       cancel_work_sync(&hdev->cmd_work);
-       cancel_work_sync(&hdev->tx_work);
-       cancel_work_sync(&hdev->power_on);
-       cancel_work_sync(&hdev->error_reset);
+       disable_work_sync(&hdev->rx_work);
+       disable_work_sync(&hdev->cmd_work);
+       disable_work_sync(&hdev->tx_work);
+       disable_work_sync(&hdev->power_on);
+       disable_work_sync(&hdev->error_reset);
 
        hci_cmd_sync_clear(hdev);
 
@@ -2796,8 +2796,14 @@ static void hci_cancel_cmd_sync(struct hci_dev *hdev, int err)
 {
        bt_dev_dbg(hdev, "err 0x%2.2x", err);
 
-       cancel_delayed_work_sync(&hdev->cmd_timer);
-       cancel_delayed_work_sync(&hdev->ncmd_timer);
+       if (hci_dev_test_flag(hdev, HCI_UNREGISTER)) {
+               disable_delayed_work_sync(&hdev->cmd_timer);
+               disable_delayed_work_sync(&hdev->ncmd_timer);
+       } else  {
+               cancel_delayed_work_sync(&hdev->cmd_timer);
+               cancel_delayed_work_sync(&hdev->ncmd_timer);
+       }
+
        atomic_set(&hdev->cmd_cnt, 1);
 
        hci_cmd_sync_cancel_sync(hdev, err);
@@ -3782,6 +3788,8 @@ static void hci_acldata_packet(struct hci_dev *hdev, struct sk_buff *skb)
 
        hci_dev_lock(hdev);
        conn = hci_conn_hash_lookup_handle(hdev, handle);
+       if (conn && hci_dev_test_flag(hdev, HCI_MGMT))
+               mgmt_device_connected(hdev, conn, NULL, 0);
        hci_dev_unlock(hdev);
 
        if (conn) {
index 1c82dcdf6e8fc76e4a0a5e690c68ad9653c2942d..0bbad90ddd6f87e87c03859bae48a7901d39b634 100644 (file)
@@ -25,7 +25,7 @@
 
 /* Bluetooth HCI event handling. */
 
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include <linux/crypto.h>
 #include <crypto/algapi.h>
 
@@ -3706,7 +3706,7 @@ static void hci_remote_features_evt(struct hci_dev *hdev, void *data,
                goto unlock;
        }
 
-       if (!ev->status && !test_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags)) {
+       if (!ev->status) {
                struct hci_cp_remote_name_req cp;
                memset(&cp, 0, sizeof(cp));
                bacpy(&cp.bdaddr, &conn->dst);
@@ -5324,19 +5324,16 @@ static void hci_user_confirm_request_evt(struct hci_dev *hdev, void *data,
                goto unlock;
        }
 
-       /* If no side requires MITM protection; auto-accept */
+       /* If no side requires MITM protection; use JUST_CFM method */
        if ((!loc_mitm || conn->remote_cap == HCI_IO_NO_INPUT_OUTPUT) &&
            (!rem_mitm || conn->io_capability == HCI_IO_NO_INPUT_OUTPUT)) {
 
-               /* If we're not the initiators request authorization to
-                * proceed from user space (mgmt_user_confirm with
-                * confirm_hint set to 1). The exception is if neither
-                * side had MITM or if the local IO capability is
-                * NoInputNoOutput, in which case we do auto-accept
+               /* If we're not the initiator of request authorization and the
+                * local IO capability is not NoInputNoOutput, use JUST_WORKS
+                * method (mgmt_user_confirm with confirm_hint set to 1).
                 */
                if (!test_bit(HCI_CONN_AUTH_PEND, &conn->flags) &&
-                   conn->io_capability != HCI_IO_NO_INPUT_OUTPUT &&
-                   (loc_mitm || rem_mitm)) {
+                   conn->io_capability != HCI_IO_NO_INPUT_OUTPUT) {
                        bt_dev_dbg(hdev, "Confirming auto-accept as acceptor");
                        confirm_hint = 1;
                        goto confirm;
index 69c2ba1e843eb4bb0effcffba307f227b7bb0a70..2272e1849ebd894a6b83f665d8fa45610778463c 100644 (file)
@@ -27,7 +27,7 @@
 #include <linux/export.h>
 #include <linux/utsname.h>
 #include <linux/sched.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #include <net/bluetooth/bluetooth.h>
 #include <net/bluetooth/hci_core.h>
index 40ccdef168d7da0f939a6832bf472b66bf206de7..c0203a2b5107560c3f33012bcb771588baf3b17a 100644 (file)
@@ -206,6 +206,12 @@ struct sk_buff *__hci_cmd_sync_sk(struct hci_dev *hdev, u16 opcode, u32 plen,
                return ERR_PTR(err);
        }
 
+       /* If command return a status event skb will be set to NULL as there are
+        * no parameters.
+        */
+       if (!skb)
+               return ERR_PTR(-ENODATA);
+
        return skb;
 }
 EXPORT_SYMBOL(__hci_cmd_sync_sk);
@@ -255,6 +261,11 @@ int __hci_cmd_sync_status_sk(struct hci_dev *hdev, u16 opcode, u32 plen,
        u8 status;
 
        skb = __hci_cmd_sync_sk(hdev, opcode, plen, param, event, timeout, sk);
+
+       /* If command return a status event, skb will be set to -ENODATA */
+       if (skb == ERR_PTR(-ENODATA))
+               return 0;
+
        if (IS_ERR(skb)) {
                if (!event)
                        bt_dev_err(hdev, "Opcode 0x%4.4x failed: %ld", opcode,
@@ -262,13 +273,6 @@ int __hci_cmd_sync_status_sk(struct hci_dev *hdev, u16 opcode, u32 plen,
                return PTR_ERR(skb);
        }
 
-       /* If command return a status event skb will be set to NULL as there are
-        * no parameters, in case of failure IS_ERR(skb) would have be set to
-        * the actual error would be found with PTR_ERR(skb).
-        */
-       if (!skb)
-               return 0;
-
        status = skb->data[0];
 
        kfree_skb(skb);
@@ -5131,9 +5135,15 @@ int hci_dev_close_sync(struct hci_dev *hdev)
 
        bt_dev_dbg(hdev, "");
 
-       cancel_delayed_work(&hdev->power_off);
-       cancel_delayed_work(&hdev->ncmd_timer);
-       cancel_delayed_work(&hdev->le_scan_disable);
+       if (hci_dev_test_flag(hdev, HCI_UNREGISTER)) {
+               disable_delayed_work(&hdev->power_off);
+               disable_delayed_work(&hdev->ncmd_timer);
+               disable_delayed_work(&hdev->le_scan_disable);
+       } else {
+               cancel_delayed_work(&hdev->power_off);
+               cancel_delayed_work(&hdev->ncmd_timer);
+               cancel_delayed_work(&hdev->le_scan_disable);
+       }
 
        hci_cmd_sync_cancel_sync(hdev, ENODEV);
 
index d5e00d0dd1a04b6da30423131d165d7089e5f580..7a83e400ac77a0a0df41b206643bae6fc031631b 100644 (file)
@@ -93,6 +93,16 @@ static struct sock *iso_get_sock(bdaddr_t *src, bdaddr_t *dst,
 #define ISO_CONN_TIMEOUT       (HZ * 40)
 #define ISO_DISCONN_TIMEOUT    (HZ * 2)
 
+static struct sock *iso_sock_hold(struct iso_conn *conn)
+{
+       if (!conn || !bt_sock_linked(&iso_sk_list, conn->sk))
+               return NULL;
+
+       sock_hold(conn->sk);
+
+       return conn->sk;
+}
+
 static void iso_sock_timeout(struct work_struct *work)
 {
        struct iso_conn *conn = container_of(work, struct iso_conn,
@@ -100,9 +110,7 @@ static void iso_sock_timeout(struct work_struct *work)
        struct sock *sk;
 
        iso_conn_lock(conn);
-       sk = conn->sk;
-       if (sk)
-               sock_hold(sk);
+       sk = iso_sock_hold(conn);
        iso_conn_unlock(conn);
 
        if (!sk)
@@ -209,9 +217,7 @@ static void iso_conn_del(struct hci_conn *hcon, int err)
 
        /* Kill socket */
        iso_conn_lock(conn);
-       sk = conn->sk;
-       if (sk)
-               sock_hold(sk);
+       sk = iso_sock_hold(conn);
        iso_conn_unlock(conn);
 
        if (sk) {
@@ -2301,13 +2307,9 @@ int iso_init(void)
 
        hci_register_cb(&iso_cb);
 
-       if (IS_ERR_OR_NULL(bt_debugfs))
-               return 0;
-
-       if (!iso_debugfs) {
+       if (!IS_ERR_OR_NULL(bt_debugfs))
                iso_debugfs = debugfs_create_file("iso", 0444, bt_debugfs,
                                                  NULL, &iso_debugfs_fops);
-       }
 
        iso_inited = true;
 
index 9988ba382b686ad8a59c72dcf65749138af0afb5..6544c1ed714344f54780a498623c964bcddbd8d1 100644 (file)
@@ -4066,17 +4066,9 @@ response:
 static int l2cap_connect_req(struct l2cap_conn *conn,
                             struct l2cap_cmd_hdr *cmd, u16 cmd_len, u8 *data)
 {
-       struct hci_dev *hdev = conn->hcon->hdev;
-       struct hci_conn *hcon = conn->hcon;
-
        if (cmd_len < sizeof(struct l2cap_conn_req))
                return -EPROTO;
 
-       hci_dev_lock(hdev);
-       if (hci_dev_test_flag(hdev, HCI_MGMT))
-               mgmt_device_connected(hdev, hcon, NULL, 0);
-       hci_dev_unlock(hdev);
-
        l2cap_connect(conn, cmd, data, L2CAP_CONN_RSP);
        return 0;
 }
index e4f564d6f6fbfb8ed659e025b2498c249d1667b3..a429661b676a83ec2d34ed7e228195f39a153f9f 100644 (file)
@@ -25,7 +25,7 @@
 /* Bluetooth HCI Management interface */
 
 #include <linux/module.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #include <net/bluetooth/bluetooth.h>
 #include <net/bluetooth/hci_core.h>
@@ -1453,10 +1453,15 @@ static void cmd_status_rsp(struct mgmt_pending_cmd *cmd, void *data)
 
 static void cmd_complete_rsp(struct mgmt_pending_cmd *cmd, void *data)
 {
-       if (cmd->cmd_complete) {
-               u8 *status = data;
+       struct cmd_lookup *match = data;
+
+       /* dequeue cmd_sync entries using cmd as data as that is about to be
+        * removed/freed.
+        */
+       hci_cmd_sync_dequeue(match->hdev, NULL, cmd, NULL);
 
-               cmd->cmd_complete(cmd, *status);
+       if (cmd->cmd_complete) {
+               cmd->cmd_complete(cmd, match->mgmt_status);
                mgmt_pending_remove(cmd);
 
                return;
@@ -9394,12 +9399,12 @@ void mgmt_index_added(struct hci_dev *hdev)
 void mgmt_index_removed(struct hci_dev *hdev)
 {
        struct mgmt_ev_ext_index ev;
-       u8 status = MGMT_STATUS_INVALID_INDEX;
+       struct cmd_lookup match = { NULL, hdev, MGMT_STATUS_INVALID_INDEX };
 
        if (test_bit(HCI_QUIRK_RAW_DEVICE, &hdev->quirks))
                return;
 
-       mgmt_pending_foreach(0, hdev, cmd_complete_rsp, &status);
+       mgmt_pending_foreach(0, hdev, cmd_complete_rsp, &match);
 
        if (hci_dev_test_flag(hdev, HCI_UNCONFIGURED)) {
                mgmt_index_event(MGMT_EV_UNCONF_INDEX_REMOVED, hdev, NULL, 0,
@@ -9450,7 +9455,7 @@ void mgmt_power_on(struct hci_dev *hdev, int err)
 void __mgmt_power_off(struct hci_dev *hdev)
 {
        struct cmd_lookup match = { NULL, hdev };
-       u8 status, zero_cod[] = { 0, 0, 0 };
+       u8 zero_cod[] = { 0, 0, 0 };
 
        mgmt_pending_foreach(MGMT_OP_SET_POWERED, hdev, settings_rsp, &match);
 
@@ -9462,11 +9467,11 @@ void __mgmt_power_off(struct hci_dev *hdev)
         * status responses.
         */
        if (hci_dev_test_flag(hdev, HCI_UNREGISTER))
-               status = MGMT_STATUS_INVALID_INDEX;
+               match.mgmt_status = MGMT_STATUS_INVALID_INDEX;
        else
-               status = MGMT_STATUS_NOT_POWERED;
+               match.mgmt_status = MGMT_STATUS_NOT_POWERED;
 
-       mgmt_pending_foreach(0, hdev, cmd_complete_rsp, &status);
+       mgmt_pending_foreach(0, hdev, cmd_complete_rsp, &match);
 
        if (memcmp(hdev->dev_class, zero_cod, sizeof(zero_cod)) != 0) {
                mgmt_limited_event(MGMT_EV_CLASS_OF_DEV_CHANGED, hdev,
index 0115f783bde8055f9f0b8b46a9a84321e75abe39..17ab909a7c07f07fa9659eec76a777f514c2a29a 100644 (file)
@@ -21,7 +21,7 @@
    SOFTWARE IS DISCLAIMED.
 */
 
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #include <net/bluetooth/bluetooth.h>
 #include <net/bluetooth/hci_core.h>
index 1d34d8497033299907d341212c2977b2b1d9b870..ad5177e3a69b7732b330ce67329ba143efac9b92 100644 (file)
@@ -28,7 +28,7 @@
 #include <linux/module.h>
 #include <linux/debugfs.h>
 #include <linux/kthread.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #include <net/bluetooth/bluetooth.h>
 #include <net/bluetooth/hci_core.h>
index 37d63d768afb8c6b304102400b2dafefcc2ee659..f48250e3f2e103c75d5937e1608e43c123aa3297 100644 (file)
@@ -865,9 +865,7 @@ static int rfcomm_sock_ioctl(struct socket *sock, unsigned int cmd, unsigned lon
 
        if (err == -ENOIOCTLCMD) {
 #ifdef CONFIG_BT_RFCOMM_TTY
-               lock_sock(sk);
                err = rfcomm_dev_ioctl(sk, cmd, (void __user *) arg);
-               release_sock(sk);
 #else
                err = -EOPNOTSUPP;
 #endif
index a5ac160c592eb94dc93936932d77b05f8c825295..1c7252a3686694284b0b1e1101e3d16b90d906c4 100644 (file)
@@ -76,6 +76,16 @@ struct sco_pinfo {
 #define SCO_CONN_TIMEOUT       (HZ * 40)
 #define SCO_DISCONN_TIMEOUT    (HZ * 2)
 
+static struct sock *sco_sock_hold(struct sco_conn *conn)
+{
+       if (!conn || !bt_sock_linked(&sco_sk_list, conn->sk))
+               return NULL;
+
+       sock_hold(conn->sk);
+
+       return conn->sk;
+}
+
 static void sco_sock_timeout(struct work_struct *work)
 {
        struct sco_conn *conn = container_of(work, struct sco_conn,
@@ -87,9 +97,7 @@ static void sco_sock_timeout(struct work_struct *work)
                sco_conn_unlock(conn);
                return;
        }
-       sk = conn->sk;
-       if (sk)
-               sock_hold(sk);
+       sk = sco_sock_hold(conn);
        sco_conn_unlock(conn);
 
        if (!sk)
@@ -194,9 +202,7 @@ static void sco_conn_del(struct hci_conn *hcon, int err)
 
        /* Kill socket */
        sco_conn_lock(conn);
-       sk = conn->sk;
-       if (sk)
-               sock_hold(sk);
+       sk = sco_sock_hold(conn);
        sco_conn_unlock(conn);
 
        if (sk) {
index 6d7a442ceb89be15501069655a51671d6ddfaf0e..501ec4249fedc3d34fe39aff50eea66f82b88a11 100644 (file)
@@ -246,6 +246,7 @@ static void reset_ctx(struct xdp_page_head *head)
        head->ctx.data_meta = head->orig_ctx.data_meta;
        head->ctx.data_end = head->orig_ctx.data_end;
        xdp_update_frame_from_buff(&head->ctx, head->frame);
+       head->frame->mem = head->orig_ctx.rxq->mem;
 }
 
 static int xdp_recv_frames(struct xdp_frame **frames, int nframes,
index ad7a42b505ef9b9f98a44fc50bc11e39a9f1646c..642b8ccaae8ea2cd534514e575702ae3b1c30d1d 100644 (file)
@@ -18,7 +18,7 @@
 #include <linux/random.h>
 #include <linux/slab.h>
 #include <linux/atomic.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include <linux/if_vlan.h>
 #include <net/switchdev.h>
 #include <trace/events/bridge.h>
index bc37e47ad8299ea50736a1016a5a43783579800c..1a52a0bca086d693d3fb20a305a084a7a0313ef4 100644 (file)
@@ -1674,7 +1674,7 @@ int br_mdb_get(struct net_device *dev, struct nlattr *tb[], u32 portid, u32 seq,
        spin_lock_bh(&br->multicast_lock);
 
        mp = br_mdb_ip_get(br, &group);
-       if (!mp) {
+       if (!mp || (!mp->ports && !mp->host_joined)) {
                NL_SET_ERR_MSG_MOD(extack, "MDB entry not found");
                err = -ENOENT;
                goto unlock;
index 0e8bc0ea6175066481c38963b22c2375c8a15d23..1d458e9da660c94fecab9983f209b6dbc9263c98 100644 (file)
@@ -33,6 +33,7 @@
 #include <net/ip.h>
 #include <net/ipv6.h>
 #include <net/addrconf.h>
+#include <net/dst_metadata.h>
 #include <net/route.h>
 #include <net/netfilter/br_netfilter.h>
 #include <net/netns/generic.h>
@@ -879,6 +880,10 @@ static int br_nf_dev_queue_xmit(struct net *net, struct sock *sk, struct sk_buff
                return br_dev_queue_push_xmit(net, sk, skb);
        }
 
+       /* Fragmentation on metadata/template dst is not supported */
+       if (unlikely(!skb_valid_dst(skb)))
+               goto drop;
+
        /* This is wrong! We should preserve the original fragment
         * boundaries by preserving frag_list rather than refragmenting.
         */
index f17dbac7d82843091f9131acc68a5a9132fa2eda..6b97ae47f85524a9ab1362114df0a34cdcd3f270 100644 (file)
@@ -1920,7 +1920,10 @@ int __init br_netlink_init(void)
 {
        int err;
 
-       br_vlan_rtnl_init();
+       err = br_vlan_rtnl_init();
+       if (err)
+               goto out;
+
        rtnl_af_register(&br_af_ops);
 
        err = rtnl_link_register(&br_link_ops);
@@ -1931,6 +1934,7 @@ int __init br_netlink_init(void)
 
 out_af:
        rtnl_af_unregister(&br_af_ops);
+out:
        return err;
 }
 
index d4bedc87b1d8f1bcf96c714fc80078227470550a..041f6e571a20979554375e068eb8accd563d0472 100644 (file)
@@ -1571,7 +1571,7 @@ void br_vlan_get_stats(const struct net_bridge_vlan *v,
 void br_vlan_port_event(struct net_bridge_port *p, unsigned long event);
 int br_vlan_bridge_event(struct net_device *dev, unsigned long event,
                         void *ptr);
-void br_vlan_rtnl_init(void);
+int br_vlan_rtnl_init(void);
 void br_vlan_rtnl_uninit(void);
 void br_vlan_notify(const struct net_bridge *br,
                    const struct net_bridge_port *p,
@@ -1802,8 +1802,9 @@ static inline int br_vlan_bridge_event(struct net_device *dev,
        return 0;
 }
 
-static inline void br_vlan_rtnl_init(void)
+static inline int br_vlan_rtnl_init(void)
 {
+       return 0;
 }
 
 static inline void br_vlan_rtnl_uninit(void)
index 0e4572f3133079d7cf62720910c0d01111c79edc..7895489ac6fe7ca47cf001c0fea267d5dcbd4371 100644 (file)
@@ -17,7 +17,7 @@
 #include <net/llc.h>
 #include <net/llc_pdu.h>
 #include <net/stp.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #include "br_private.h"
 #include "br_private_stp.h"
index 9c2fffb827ab195cf9a01281e4790361e0b14bfe..89f51ea4cabece56952530ed574b4235f472104c 100644 (file)
@@ -2296,19 +2296,18 @@ static int br_vlan_rtm_process(struct sk_buff *skb, struct nlmsghdr *nlh,
        return err;
 }
 
-void br_vlan_rtnl_init(void)
+static const struct rtnl_msg_handler br_vlan_rtnl_msg_handlers[] = {
+       {THIS_MODULE, PF_BRIDGE, RTM_NEWVLAN, br_vlan_rtm_process, NULL, 0},
+       {THIS_MODULE, PF_BRIDGE, RTM_DELVLAN, br_vlan_rtm_process, NULL, 0},
+       {THIS_MODULE, PF_BRIDGE, RTM_GETVLAN, NULL, br_vlan_rtm_dump, 0},
+};
+
+int br_vlan_rtnl_init(void)
 {
-       rtnl_register_module(THIS_MODULE, PF_BRIDGE, RTM_GETVLAN, NULL,
-                            br_vlan_rtm_dump, 0);
-       rtnl_register_module(THIS_MODULE, PF_BRIDGE, RTM_NEWVLAN,
-                            br_vlan_rtm_process, NULL, 0);
-       rtnl_register_module(THIS_MODULE, PF_BRIDGE, RTM_DELVLAN,
-                            br_vlan_rtm_process, NULL, 0);
+       return rtnl_register_many(br_vlan_rtnl_msg_handlers);
 }
 
 void br_vlan_rtnl_uninit(void)
 {
-       rtnl_unregister(PF_BRIDGE, RTM_GETVLAN);
-       rtnl_unregister(PF_BRIDGE, RTM_NEWVLAN);
-       rtnl_unregister(PF_BRIDGE, RTM_DELVLAN);
+       rtnl_unregister_many(br_vlan_rtnl_msg_handlers);
 }
index 7b0af33bdb97fd6ef1c15c6028993ee942b5806c..3c335057f2555f7d8172b701179a688ff7dcc7d8 100644 (file)
@@ -9,7 +9,7 @@
 #include <linux/stddef.h>
 #include <linux/spinlock.h>
 #include <linux/slab.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include <net/caif/caif_layer.h>
 #include <net/caif/cfsrvl.h>
 #include <net/caif/cfpkt.h>
index cd479f5f22f61c316cb236632eea73d5924c3156..8453e14d301b63a84f3d505a1f3dc08f88fe8f7b 100644 (file)
@@ -3512,7 +3512,7 @@ static netdev_features_t gso_features_check(const struct sk_buff *skb,
        if (gso_segs > READ_ONCE(dev->gso_max_segs))
                return features & ~NETIF_F_GSO_MASK;
 
-       if (unlikely(skb->len >= READ_ONCE(dev->gso_max_size)))
+       if (unlikely(skb->len >= netif_get_gso_max_size(dev, skb)))
                return features & ~NETIF_F_GSO_MASK;
 
        if (!skb_shinfo(skb)->gso_type) {
@@ -3639,6 +3639,9 @@ int skb_csum_hwoffload_help(struct sk_buff *skb,
                return 0;
 
        if (features & (NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM)) {
+               if (vlan_get_protocol(skb) == htons(ETH_P_IPV6) &&
+                   skb_network_header_len(skb) != sizeof(struct ipv6hdr))
+                       goto sw_checksum;
                switch (skb->csum_offset) {
                case offsetof(struct tcphdr, check):
                case offsetof(struct udphdr, check):
@@ -3646,6 +3649,7 @@ int skb_csum_hwoffload_help(struct sk_buff *skb,
                }
        }
 
+sw_checksum:
        return skb_checksum_help(skb);
 }
 EXPORT_SYMBOL(skb_csum_hwoffload_help);
@@ -3758,7 +3762,7 @@ static void qdisc_pkt_len_init(struct sk_buff *skb)
                                                sizeof(_tcphdr), &_tcphdr);
                        if (likely(th))
                                hdr_len += __tcp_hdrlen(th);
-               } else {
+               } else if (shinfo->gso_type & SKB_GSO_UDP_L4) {
                        struct udphdr _udphdr;
 
                        if (skb_header_pointer(skb, hdr_len,
@@ -3766,10 +3770,14 @@ static void qdisc_pkt_len_init(struct sk_buff *skb)
                                hdr_len += sizeof(struct udphdr);
                }
 
-               if (shinfo->gso_type & SKB_GSO_DODGY)
-                       gso_segs = DIV_ROUND_UP(skb->len - hdr_len,
-                                               shinfo->gso_size);
+               if (unlikely(shinfo->gso_type & SKB_GSO_DODGY)) {
+                       int payload = skb->len - hdr_len;
 
+                       /* Malicious packet. */
+                       if (payload <= 0)
+                               return;
+                       gso_segs = DIV_ROUND_UP(payload, shinfo->gso_size);
+               }
                qdisc_skb_cb(skb)->pkt_len += (gso_segs - 1) * hdr_len;
        }
 }
index 2e0ae3328232f159cbd51ed341eeb34dbf08a031..6efd4cccc9ddd2792f6bdf5ae8aebd2974777d6c 100644 (file)
@@ -37,7 +37,7 @@
 #include <trace/events/napi.h>
 #include <trace/events/devlink.h>
 
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #define TRACE_ON 1
 #define TRACE_OFF 0
index 95f533844f17f119c09f335ccf9bf09515dd3606..9552a90d4772dce49b5fe94d2f1d8da6979d9908 100644 (file)
@@ -109,9 +109,6 @@ static void dst_destroy(struct dst_entry *dst)
                child = xdst->child;
        }
 #endif
-       if (!(dst->flags & DST_NOCOUNT))
-               dst_entries_add(dst->ops, -1);
-
        if (dst->ops->destroy)
                dst->ops->destroy(dst);
        netdev_put(dst->dev, &dst->dev_tracker);
@@ -159,17 +156,27 @@ void dst_dev_put(struct dst_entry *dst)
 }
 EXPORT_SYMBOL(dst_dev_put);
 
+static void dst_count_dec(struct dst_entry *dst)
+{
+       if (!(dst->flags & DST_NOCOUNT))
+               dst_entries_add(dst->ops, -1);
+}
+
 void dst_release(struct dst_entry *dst)
 {
-       if (dst && rcuref_put(&dst->__rcuref))
+       if (dst && rcuref_put(&dst->__rcuref)) {
+               dst_count_dec(dst);
                call_rcu_hurry(&dst->rcu_head, dst_destroy_rcu);
+       }
 }
 EXPORT_SYMBOL(dst_release);
 
 void dst_release_immediate(struct dst_entry *dst)
 {
-       if (dst && rcuref_put(&dst->__rcuref))
+       if (dst && rcuref_put(&dst->__rcuref)) {
+               dst_count_dec(dst);
                dst_destroy(dst);
+       }
 }
 EXPORT_SYMBOL(dst_release_immediate);
 
index cd3524cb326b0e6c950f997666414b11bbdb1113..e31ee8be2de072387590c8035b0842a655d3f453 100644 (file)
@@ -42,7 +42,7 @@
 #include <linux/errno.h>
 #include <linux/timer.h>
 #include <linux/uaccess.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include <linux/filter.h>
 #include <linux/ratelimit.h>
 #include <linux/seccomp.h>
@@ -2438,9 +2438,9 @@ out:
 
 /* Internal, non-exposed redirect flags. */
 enum {
-       BPF_F_NEIGH     = (1ULL << 1),
-       BPF_F_PEER      = (1ULL << 2),
-       BPF_F_NEXTHOP   = (1ULL << 3),
+       BPF_F_NEIGH     = (1ULL << 16),
+       BPF_F_PEER      = (1ULL << 17),
+       BPF_F_NEXTHOP   = (1ULL << 18),
 #define BPF_F_REDIRECT_INTERNAL        (BPF_F_NEIGH | BPF_F_PEER | BPF_F_NEXTHOP)
 };
 
@@ -2450,6 +2450,8 @@ BPF_CALL_3(bpf_clone_redirect, struct sk_buff *, skb, u32, ifindex, u64, flags)
        struct sk_buff *clone;
        int ret;
 
+       BUILD_BUG_ON(BPF_F_REDIRECT_INTERNAL & BPF_F_REDIRECT_FLAGS);
+
        if (unlikely(flags & (~(BPF_F_INGRESS) | BPF_F_REDIRECT_INTERNAL)))
                return -EINVAL;
 
@@ -6279,24 +6281,16 @@ BPF_CALL_5(bpf_skb_check_mtu, struct sk_buff *, skb,
 {
        int ret = BPF_MTU_CHK_RET_FRAG_NEEDED;
        struct net_device *dev = skb->dev;
-       int skb_len, dev_len;
-       int mtu = 0;
-
-       if (unlikely(flags & ~(BPF_MTU_CHK_SEGS))) {
-               ret = -EINVAL;
-               goto out;
-       }
+       int mtu, dev_len, skb_len;
 
-       if (unlikely(flags & BPF_MTU_CHK_SEGS && (len_diff || *mtu_len))) {
-               ret = -EINVAL;
-               goto out;
-       }
+       if (unlikely(flags & ~(BPF_MTU_CHK_SEGS)))
+               return -EINVAL;
+       if (unlikely(flags & BPF_MTU_CHK_SEGS && (len_diff || *mtu_len)))
+               return -EINVAL;
 
        dev = __dev_via_ifindex(dev, ifindex);
-       if (unlikely(!dev)) {
-               ret = -ENODEV;
-               goto out;
-       }
+       if (unlikely(!dev))
+               return -ENODEV;
 
        mtu = READ_ONCE(dev->mtu);
        dev_len = mtu + dev->hard_header_len;
@@ -6331,19 +6325,15 @@ BPF_CALL_5(bpf_xdp_check_mtu, struct xdp_buff *, xdp,
        struct net_device *dev = xdp->rxq->dev;
        int xdp_len = xdp->data_end - xdp->data;
        int ret = BPF_MTU_CHK_RET_SUCCESS;
-       int mtu = 0, dev_len;
+       int mtu, dev_len;
 
        /* XDP variant doesn't support multi-buffer segment check (yet) */
-       if (unlikely(flags)) {
-               ret = -EINVAL;
-               goto out;
-       }
+       if (unlikely(flags))
+               return -EINVAL;
 
        dev = __dev_via_ifindex(dev, ifindex);
-       if (unlikely(!dev)) {
-               ret = -ENODEV;
-               goto out;
-       }
+       if (unlikely(!dev))
+               return -ENODEV;
 
        mtu = READ_ONCE(dev->mtu);
        dev_len = mtu + dev->hard_header_len;
@@ -6355,7 +6345,7 @@ BPF_CALL_5(bpf_xdp_check_mtu, struct xdp_buff *, xdp,
        xdp_len += len_diff; /* minus result pass check */
        if (xdp_len > dev_len)
                ret = BPF_MTU_CHK_RET_FRAG_NEEDED;
-out:
+
        *mtu_len = mtu;
        return ret;
 }
@@ -6366,7 +6356,7 @@ static const struct bpf_func_proto bpf_skb_check_mtu_proto = {
        .ret_type       = RET_INTEGER,
        .arg1_type      = ARG_PTR_TO_CTX,
        .arg2_type      = ARG_ANYTHING,
-       .arg3_type      = ARG_PTR_TO_FIXED_SIZE_MEM | MEM_UNINIT | MEM_ALIGNED,
+       .arg3_type      = ARG_PTR_TO_FIXED_SIZE_MEM | MEM_WRITE | MEM_ALIGNED,
        .arg3_size      = sizeof(u32),
        .arg4_type      = ARG_ANYTHING,
        .arg5_type      = ARG_ANYTHING,
@@ -6378,7 +6368,7 @@ static const struct bpf_func_proto bpf_xdp_check_mtu_proto = {
        .ret_type       = RET_INTEGER,
        .arg1_type      = ARG_PTR_TO_CTX,
        .arg2_type      = ARG_ANYTHING,
-       .arg3_type      = ARG_PTR_TO_FIXED_SIZE_MEM | MEM_UNINIT | MEM_ALIGNED,
+       .arg3_type      = ARG_PTR_TO_FIXED_SIZE_MEM | MEM_WRITE | MEM_ALIGNED,
        .arg3_size      = sizeof(u32),
        .arg4_type      = ARG_ANYTHING,
        .arg5_type      = ARG_ANYTHING,
index 802b4a0624009eca637a52698ed1f19228252f87..d1f44084e978fb50b3af9827abd649c7a7176c5e 100644 (file)
@@ -98,7 +98,6 @@ int skb_gro_receive(struct sk_buff *p, struct sk_buff *skb)
        unsigned int headlen = skb_headlen(skb);
        unsigned int len = skb_gro_len(skb);
        unsigned int delta_truesize;
-       unsigned int gro_max_size;
        unsigned int new_truesize;
        struct sk_buff *lp;
        int segs;
@@ -112,12 +111,8 @@ int skb_gro_receive(struct sk_buff *p, struct sk_buff *skb)
        if (p->pp_recycle != skb->pp_recycle)
                return -ETOOMANYREFS;
 
-       /* pairs with WRITE_ONCE() in netif_set_gro(_ipv4)_max_size() */
-       gro_max_size = p->protocol == htons(ETH_P_IPV6) ?
-                       READ_ONCE(p->dev->gro_max_size) :
-                       READ_ONCE(p->dev->gro_ipv4_max_size);
-
-       if (unlikely(p->len + len >= gro_max_size || NAPI_GRO_CB(skb)->flush))
+       if (unlikely(p->len + len >= netif_get_gro_max_size(p->dev, p) ||
+                    NAPI_GRO_CB(skb)->flush))
                return -E2BIG;
 
        if (unlikely(p->len + len >= GRO_LEGACY_MAX_SIZE)) {
index 6aef976bc1da20a66edcde19d76d8412d5378032..f2fa34b1d78d8dc3599b7536ebc0f3587845e46c 100644 (file)
@@ -23,7 +23,7 @@
 #include <linux/net_dropmon.h>
 #include <linux/slab.h>
 
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include <asm/bitops.h>
 
 #define CREATE_TRACE_POINTS
index ca52cbe0f63cf6ae394da3cf1ed4cc7cd8a7254e..aa49b92e9194babab17b2e039daf092a524c5b88 100644 (file)
@@ -34,7 +34,7 @@
 #include <net/addrconf.h>
 #include <net/ndisc.h>
 #include <net/ip6_checksum.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include <trace/events/napi.h>
 #include <linux/kconfig.h>
 
index f0a52098708584aa27461b7ee941fa324adcaf20..2ba5cd965d3faed91f3ddcb075eef597032aaa71 100644 (file)
@@ -384,6 +384,35 @@ void rtnl_unregister_all(int protocol)
 }
 EXPORT_SYMBOL_GPL(rtnl_unregister_all);
 
+int __rtnl_register_many(const struct rtnl_msg_handler *handlers, int n)
+{
+       const struct rtnl_msg_handler *handler;
+       int i, err;
+
+       for (i = 0, handler = handlers; i < n; i++, handler++) {
+               err = rtnl_register_internal(handler->owner, handler->protocol,
+                                            handler->msgtype, handler->doit,
+                                            handler->dumpit, handler->flags);
+               if (err) {
+                       __rtnl_unregister_many(handlers, i);
+                       break;
+               }
+       }
+
+       return err;
+}
+EXPORT_SYMBOL_GPL(__rtnl_register_many);
+
+void __rtnl_unregister_many(const struct rtnl_msg_handler *handlers, int n)
+{
+       const struct rtnl_msg_handler *handler;
+       int i;
+
+       for (i = n - 1, handler = handlers + n - 1; i >= 0; i--, handler--)
+               rtnl_unregister(handler->protocol, handler->msgtype);
+}
+EXPORT_SYMBOL_GPL(__rtnl_unregister_many);
+
 static LIST_HEAD(link_ops);
 
 static const struct rtnl_link_ops *rtnl_link_ops_get(const char *kind)
@@ -2003,7 +2032,7 @@ static const struct nla_policy ifla_policy[IFLA_MAX+1] = {
        [IFLA_NUM_TX_QUEUES]    = { .type = NLA_U32 },
        [IFLA_NUM_RX_QUEUES]    = { .type = NLA_U32 },
        [IFLA_GSO_MAX_SEGS]     = { .type = NLA_U32 },
-       [IFLA_GSO_MAX_SIZE]     = { .type = NLA_U32 },
+       [IFLA_GSO_MAX_SIZE]     = NLA_POLICY_MIN(NLA_U32, MAX_TCP_HEADER + 1),
        [IFLA_PHYS_PORT_ID]     = { .type = NLA_BINARY, .len = MAX_PHYS_ITEM_ID_LEN },
        [IFLA_CARRIER_CHANGES]  = { .type = NLA_U32 },  /* ignored */
        [IFLA_PHYS_SWITCH_ID]   = { .type = NLA_BINARY, .len = MAX_PHYS_ITEM_ID_LEN },
@@ -2028,7 +2057,7 @@ static const struct nla_policy ifla_policy[IFLA_MAX+1] = {
        [IFLA_TSO_MAX_SIZE]     = { .type = NLA_REJECT },
        [IFLA_TSO_MAX_SEGS]     = { .type = NLA_REJECT },
        [IFLA_ALLMULTI]         = { .type = NLA_REJECT },
-       [IFLA_GSO_IPV4_MAX_SIZE]        = { .type = NLA_U32 },
+       [IFLA_GSO_IPV4_MAX_SIZE]        = NLA_POLICY_MIN(NLA_U32, MAX_TCP_HEADER + 1),
        [IFLA_GRO_IPV4_MAX_SIZE]        = { .type = NLA_U32 },
 };
 
index fe87f9bd8f16acff2f9d26b605237536e380333c..039be95c40cf6fa429d33e0f42ee606188045992 100644 (file)
@@ -85,7 +85,7 @@
 
 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
 
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include <linux/capability.h>
 #include <linux/errno.h>
 #include <linux/errqueue.h>
index 242c91a6e3d3870ec6da6fa095d180a933d1d3d4..78347d7d25ef31525f8ec0a755a18e5793ad92c0 100644 (file)
@@ -647,6 +647,8 @@ BPF_CALL_4(bpf_sk_redirect_map, struct sk_buff *, skb,
        sk = __sock_map_lookup_elem(map, key);
        if (unlikely(!sk || !sock_map_redirect_allowed(sk)))
                return SK_DROP;
+       if ((flags & BPF_F_INGRESS) && sk_is_vsock(sk))
+               return SK_DROP;
 
        skb_bpf_set_redir(skb, sk, flags & BPF_F_INGRESS);
        return SK_PASS;
@@ -675,6 +677,8 @@ BPF_CALL_4(bpf_msg_redirect_map, struct sk_msg *, msg,
                return SK_DROP;
        if (!(flags & BPF_F_INGRESS) && !sk_is_tcp(sk))
                return SK_DROP;
+       if (sk_is_vsock(sk))
+               return SK_DROP;
 
        msg->flags = flags;
        msg->sk_redir = sk;
@@ -1249,6 +1253,8 @@ BPF_CALL_4(bpf_sk_redirect_hash, struct sk_buff *, skb,
        sk = __sock_hash_lookup_elem(map, key);
        if (unlikely(!sk || !sock_map_redirect_allowed(sk)))
                return SK_DROP;
+       if ((flags & BPF_F_INGRESS) && sk_is_vsock(sk))
+               return SK_DROP;
 
        skb_bpf_set_redir(skb, sk, flags & BPF_F_INGRESS);
        return SK_PASS;
@@ -1277,6 +1283,8 @@ BPF_CALL_4(bpf_msg_redirect_hash, struct sk_msg *, msg,
                return SK_DROP;
        if (!(flags & BPF_F_INGRESS) && !sk_is_tcp(sk))
                return SK_DROP;
+       if (sk_is_vsock(sk))
+               return SK_DROP;
 
        msg->flags = flags;
        msg->sk_redir = sk;
@@ -1752,6 +1760,10 @@ static int sock_map_link_update_prog(struct bpf_link *link,
                ret = -EINVAL;
                goto out;
        }
+       if (!sockmap_link->map) {
+               ret = -ENOLINK;
+               goto out;
+       }
 
        ret = sock_map_prog_link_lookup(sockmap_link->map, &pprog, &plink,
                                        sockmap_link->attach_type);
index e00796e3b146a506cb2c37d0d77ca1a6e2548d32..6df997b9076e9842f3de7bb3e34599d8ff4e4fd4 100644 (file)
@@ -3,7 +3,7 @@
 #include <linux/if_vlan.h>
 #include <net/ip.h>
 #include <net/tso.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 void tso_build_hdr(const struct sk_buff *skb, char *hdr, struct tso_t *tso,
                   int size, bool is_last)
index ca8670f78ac624a198e5eb458454e6bcfbea02cc..f349d16dd8f65cb63f98ddf3186e00d6e5694263 100644 (file)
@@ -22,7 +22,7 @@
 #include "../dccp.h"
 #include "ccid3.h"
 
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #ifdef CONFIG_IP_DCCP_CCID3_DEBUG
 static bool ccid3_debug;
index d24cad05001e52f06889f3e9751eb91d384d2072..db62d47670249e7867da95a04f86788e635de857 100644 (file)
@@ -10,7 +10,7 @@
 #include <linux/dccp.h>
 #include <linux/module.h>
 #include <linux/types.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include <linux/kernel.h>
 #include <linux/skbuff.h>
 
index 668c729946ea676591a641e9a87e9b2277e07819..1664547deffd07361148df72c27440d939747116 100644 (file)
@@ -1577,6 +1577,7 @@ EXPORT_SYMBOL_GPL(dsa_unregister_switch);
 void dsa_switch_shutdown(struct dsa_switch *ds)
 {
        struct net_device *conduit, *user_dev;
+       LIST_HEAD(close_list);
        struct dsa_port *dp;
 
        mutex_lock(&dsa2_mutex);
@@ -1586,10 +1587,16 @@ void dsa_switch_shutdown(struct dsa_switch *ds)
 
        rtnl_lock();
 
+       dsa_switch_for_each_cpu_port(dp, ds)
+               list_add(&dp->conduit->close_list, &close_list);
+
+       dev_close_many(&close_list, true);
+
        dsa_switch_for_each_user_port(dp, ds) {
                conduit = dsa_port_to_conduit(dp);
                user_dev = dp->user;
 
+               netif_device_detach(user_dev);
                netdev_upper_dev_unlink(conduit, user_dev);
        }
 
index 74eda9b30608e65c8c1c0afe965b5b4d589ea7e0..64f660d2334b77fa97e7d6d586a021d63ac5f6e2 100644 (file)
@@ -1392,6 +1392,14 @@ dsa_user_add_cls_matchall_mirred(struct net_device *dev,
        if (!dsa_user_dev_check(act->dev))
                return -EOPNOTSUPP;
 
+       to_dp = dsa_user_to_port(act->dev);
+
+       if (dp->ds != to_dp->ds) {
+               NL_SET_ERR_MSG_MOD(extack,
+                                  "Cross-chip mirroring not implemented");
+               return -EOPNOTSUPP;
+       }
+
        mall_tc_entry = kzalloc(sizeof(*mall_tc_entry), GFP_KERNEL);
        if (!mall_tc_entry)
                return -ENOMEM;
@@ -1399,9 +1407,6 @@ dsa_user_add_cls_matchall_mirred(struct net_device *dev,
        mall_tc_entry->cookie = cls->cookie;
        mall_tc_entry->type = DSA_PORT_MALL_MIRROR;
        mirror = &mall_tc_entry->mirror;
-
-       to_dp = dsa_user_to_port(act->dev);
-
        mirror->to_local_port = to_dp->index;
        mirror->ingress = ingress;
 
index 8cc0e2f4159de7415ecccb1a1ab4a876f968375f..740af8541d2ffdf91dd799aceb416c75be78e117 100644 (file)
@@ -37,7 +37,7 @@
 #include <net/cipso_ipv4.h>
 #include <linux/atomic.h>
 #include <linux/bug.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 /* List of available DOI definitions */
 /* XXX - This currently assumes a minimal number of different DOIs in use,
index ab76744383cf3827a7b1d8118bb22879adc7f9a2..7cf5f7d0d0de23b3f1036a56f0229bdeb4857210 100644 (file)
@@ -298,17 +298,19 @@ static struct in_device *inetdev_init(struct net_device *dev)
        /* Account for reference dev->ip_ptr (below) */
        refcount_set(&in_dev->refcnt, 1);
 
-       err = devinet_sysctl_register(in_dev);
-       if (err) {
-               in_dev->dead = 1;
-               neigh_parms_release(&arp_tbl, in_dev->arp_parms);
-               in_dev_put(in_dev);
-               in_dev = NULL;
-               goto out;
+       if (dev != blackhole_netdev) {
+               err = devinet_sysctl_register(in_dev);
+               if (err) {
+                       in_dev->dead = 1;
+                       neigh_parms_release(&arp_tbl, in_dev->arp_parms);
+                       in_dev_put(in_dev);
+                       in_dev = NULL;
+                       goto out;
+               }
+               ip_mc_init_dev(in_dev);
+               if (dev->flags & IFF_UP)
+                       ip_mc_up(in_dev);
        }
-       ip_mc_init_dev(in_dev);
-       if (dev->flags & IFF_UP)
-               ip_mc_up(in_dev);
 
        /* we can receive as soon as ip_ptr is set -- do this last */
        rcu_assign_pointer(dev->ip_ptr, in_dev);
@@ -347,6 +349,19 @@ static void inetdev_destroy(struct in_device *in_dev)
        in_dev_put(in_dev);
 }
 
+static int __init inet_blackhole_dev_init(void)
+{
+       int err = 0;
+
+       rtnl_lock();
+       if (!inetdev_init(blackhole_netdev))
+               err = -ENOMEM;
+       rtnl_unlock();
+
+       return err;
+}
+late_initcall(inet_blackhole_dev_init);
+
 int inet_addr_onlink(struct in_device *in_dev, __be32 a, __be32 b)
 {
        const struct in_ifaddr *ifa;
index 2c5632d4fddbe8ad96f6c35b9ed770d09126eb5d..2b698f8419fe2be31a21c31a855abfadfffb5fed 100644 (file)
@@ -1045,21 +1045,31 @@ static bool reqsk_queue_unlink(struct request_sock *req)
                found = __sk_nulls_del_node_init_rcu(sk);
                spin_unlock(lock);
        }
-       if (timer_pending(&req->rsk_timer) && del_timer_sync(&req->rsk_timer))
-               reqsk_put(req);
+
        return found;
 }
 
-bool inet_csk_reqsk_queue_drop(struct sock *sk, struct request_sock *req)
+static bool __inet_csk_reqsk_queue_drop(struct sock *sk,
+                                       struct request_sock *req,
+                                       bool from_timer)
 {
        bool unlinked = reqsk_queue_unlink(req);
 
+       if (!from_timer && timer_delete_sync(&req->rsk_timer))
+               reqsk_put(req);
+
        if (unlinked) {
                reqsk_queue_removed(&inet_csk(sk)->icsk_accept_queue, req);
                reqsk_put(req);
        }
+
        return unlinked;
 }
+
+bool inet_csk_reqsk_queue_drop(struct sock *sk, struct request_sock *req)
+{
+       return __inet_csk_reqsk_queue_drop(sk, req, false);
+}
 EXPORT_SYMBOL(inet_csk_reqsk_queue_drop);
 
 void inet_csk_reqsk_queue_drop_and_put(struct sock *sk, struct request_sock *req)
@@ -1152,7 +1162,7 @@ static void reqsk_timer_handler(struct timer_list *t)
 
                if (!inet_ehash_insert(req_to_sk(nreq), req_to_sk(oreq), NULL)) {
                        /* delete timer */
-                       inet_csk_reqsk_queue_drop(sk_listener, nreq);
+                       __inet_csk_reqsk_queue_drop(sk_listener, nreq, true);
                        goto no_ownership;
                }
 
@@ -1178,7 +1188,8 @@ no_ownership:
        }
 
 drop:
-       inet_csk_reqsk_queue_drop_and_put(oreq->rsk_listener, oreq);
+       __inet_csk_reqsk_queue_drop(sk_listener, oreq, true);
+       reqsk_put(req);
 }
 
 static bool reqsk_queue_hash_req(struct request_sock *req,
index 5f6fd382af38a32d9e22633cdb2e9fd01f1795e4..f1f31ebfc7934467fd10776c3cb221f9cff9f9dd 100644 (file)
@@ -662,11 +662,11 @@ static netdev_tx_t ipgre_xmit(struct sk_buff *skb,
                if (skb_cow_head(skb, 0))
                        goto free_skb;
 
-               tnl_params = (const struct iphdr *)skb->data;
-
-               if (!pskb_network_may_pull(skb, pull_len))
+               if (!pskb_may_pull(skb, pull_len))
                        goto free_skb;
 
+               tnl_params = (const struct iphdr *)skb->data;
+
                /* ip_tunnel_xmit() needs skb->data pointing to gre header. */
                skb_pull(skb, pull_len);
                skb_reset_mac_header(skb);
index a9e22a098872fa3a1a18b5654afc4944dec0ded9..68aedb8877b9f4e2c6bc9e7afe2f90afb96a76ec 100644 (file)
@@ -17,7 +17,7 @@
 #include <linux/slab.h>
 #include <linux/types.h>
 #include <linux/uaccess.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include <linux/skbuff.h>
 #include <linux/ip.h>
 #include <linux/icmp.h>
index d591c73e2c0e53efefb8fb9262610cbbd1dd71ea..25505f9b724c33d2c3ec2fca5355d7fdd4e01c14 100644 (file)
@@ -218,7 +218,7 @@ static struct ip_tunnel *ip_tunnel_find(struct ip_tunnel_net *itn,
 
        ip_tunnel_flags_copy(flags, parms->i_flags);
 
-       hlist_for_each_entry_rcu(t, head, hash_node) {
+       hlist_for_each_entry_rcu(t, head, hash_node, lockdep_rtnl_is_held()) {
                if (local == t->parms.iph.saddr &&
                    remote == t->parms.iph.daddr &&
                    link == READ_ONCE(t->parms.link) &&
index f4aed0789d69dce64377446d7cfded9c5ecd5f51..ec94ee1051c77f9af8f13d0842978f8cee5d7da7 100644 (file)
@@ -53,8 +53,9 @@ void nf_dup_ipv4(struct net *net, struct sk_buff *skb, unsigned int hooknum,
 {
        struct iphdr *iph;
 
+       local_bh_disable();
        if (this_cpu_read(nf_skb_duplicated))
-               return;
+               goto out;
        /*
         * Copy the skb, and route the copy. Will later return %XT_CONTINUE for
         * the original skb, which should continue on its way as if nothing has
@@ -62,7 +63,7 @@ void nf_dup_ipv4(struct net *net, struct sk_buff *skb, unsigned int hooknum,
         */
        skb = pskb_copy(skb, GFP_ATOMIC);
        if (skb == NULL)
-               return;
+               goto out;
 
 #if IS_ENABLED(CONFIG_NF_CONNTRACK)
        /* Avoid counting cloned packets towards the original connection. */
@@ -91,6 +92,8 @@ void nf_dup_ipv4(struct net *net, struct sk_buff *skb, unsigned int hooknum,
        } else {
                kfree_skb(skb);
        }
+out:
+       local_bh_enable();
 }
 EXPORT_SYMBOL_GPL(nf_dup_ipv4);
 
index 00da1332bbf1a6191b11d134fd6234b6b456c9fd..09fff5d424efc25d3e18934b20a0e0b4c5667bd1 100644 (file)
@@ -65,6 +65,7 @@ void nft_fib4_eval(const struct nft_expr *expr, struct nft_regs *regs,
                .flowi4_scope = RT_SCOPE_UNIVERSE,
                .flowi4_iif = LOOPBACK_IFINDEX,
                .flowi4_uid = sock_net_uid(nft_net(pkt), NULL),
+               .flowi4_l3mdev = l3mdev_master_ifindex_rcu(nft_in(pkt)),
        };
        const struct net_device *oif;
        const struct net_device *found;
@@ -83,9 +84,6 @@ void nft_fib4_eval(const struct nft_expr *expr, struct nft_regs *regs,
        else
                oif = NULL;
 
-       if (priv->flags & NFTA_FIB_F_IIF)
-               fl4.flowi4_l3mdev = l3mdev_master_ifindex_rcu(oif);
-
        if (nft_hook(pkt) == NF_INET_PRE_ROUTING &&
            nft_fib_is_loopback(pkt->skb, nft_in(pkt))) {
                nft_fib_store_result(dest, priv, nft_in(pkt));
index e7658c5d6b79d7367689afbe8638b5638dc588e6..370993c03d31363c0f82a003d9e5b0ca3bbed721 100644 (file)
@@ -221,11 +221,11 @@ static int tcp_bpf_recvmsg_parser(struct sock *sk,
                                  int flags,
                                  int *addr_len)
 {
-       struct tcp_sock *tcp = tcp_sk(sk);
        int peek = flags & MSG_PEEK;
-       u32 seq = tcp->copied_seq;
        struct sk_psock *psock;
+       struct tcp_sock *tcp;
        int copied = 0;
+       u32 seq;
 
        if (unlikely(flags & MSG_ERRQUEUE))
                return inet_recv_error(sk, msg, len, addr_len);
@@ -238,7 +238,8 @@ static int tcp_bpf_recvmsg_parser(struct sock *sk,
                return tcp_recvmsg(sk, msg, len, flags, addr_len);
 
        lock_sock(sk);
-
+       tcp = tcp_sk(sk);
+       seq = tcp->copied_seq;
        /* We may have received data on the sk_receive_queue pre-accept and
         * then we can not use read_skb in this context because we haven't
         * assigned a sk_socket yet so have no link to the ops. The work-around
index 9f314dfa149058997b36fbcfa7e9718edebf76da..2d844e1f867f0a67187fcd7f5eed2e30156f2bd7 100644 (file)
@@ -75,7 +75,7 @@
 #include <net/proto_memory.h>
 #include <net/inet_common.h>
 #include <linux/ipsec.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include <linux/errqueue.h>
 #include <trace/events/tcp.h>
 #include <linux/jump_label_ratelimit.h>
@@ -2473,8 +2473,22 @@ static bool tcp_skb_spurious_retrans(const struct tcp_sock *tp,
  */
 static inline bool tcp_packet_delayed(const struct tcp_sock *tp)
 {
-       return tp->retrans_stamp &&
-              tcp_tsopt_ecr_before(tp, tp->retrans_stamp);
+       const struct sock *sk = (const struct sock *)tp;
+
+       if (tp->retrans_stamp &&
+           tcp_tsopt_ecr_before(tp, tp->retrans_stamp))
+               return true;  /* got echoed TS before first retransmission */
+
+       /* Check if nothing was retransmitted (retrans_stamp==0), which may
+        * happen in fast recovery due to TSQ. But we ignore zero retrans_stamp
+        * in TCP_SYN_SENT, since when we set FLAG_SYN_ACKED we also clear
+        * retrans_stamp even if we had retransmitted the SYN.
+        */
+       if (!tp->retrans_stamp &&          /* no record of a retransmit/SYN? */
+           sk->sk_state != TCP_SYN_SENT)  /* not the FLAG_SYN_ACKED case? */
+               return true;  /* nothing was retransmitted */
+
+       return false;
 }
 
 /* Undo procedures. */
@@ -2508,6 +2522,16 @@ static bool tcp_any_retrans_done(const struct sock *sk)
        return false;
 }
 
+/* If loss recovery is finished and there are no retransmits out in the
+ * network, then we clear retrans_stamp so that upon the next loss recovery
+ * retransmits_timed_out() and timestamp-undo are using the correct value.
+ */
+static void tcp_retrans_stamp_cleanup(struct sock *sk)
+{
+       if (!tcp_any_retrans_done(sk))
+               tcp_sk(sk)->retrans_stamp = 0;
+}
+
 static void DBGUNDO(struct sock *sk, const char *msg)
 {
 #if FASTRETRANS_DEBUG > 1
@@ -2875,6 +2899,9 @@ void tcp_enter_recovery(struct sock *sk, bool ece_ack)
        struct tcp_sock *tp = tcp_sk(sk);
        int mib_idx;
 
+       /* Start the clock with our fast retransmit, for undo and ETIMEDOUT. */
+       tcp_retrans_stamp_cleanup(sk);
+
        if (tcp_is_reno(tp))
                mib_idx = LINUX_MIB_TCPRENORECOVERY;
        else
@@ -6657,10 +6684,17 @@ static void tcp_rcv_synrecv_state_fastopen(struct sock *sk)
        if (inet_csk(sk)->icsk_ca_state == TCP_CA_Loss && !tp->packets_out)
                tcp_try_undo_recovery(sk);
 
-       /* Reset rtx states to prevent spurious retransmits_timed_out() */
        tcp_update_rto_time(tp);
-       tp->retrans_stamp = 0;
        inet_csk(sk)->icsk_retransmits = 0;
+       /* In tcp_fastopen_synack_timer() on the first SYNACK RTO we set
+        * retrans_stamp but don't enter CA_Loss, so in case that happened we
+        * need to zero retrans_stamp here to prevent spurious
+        * retransmits_timed_out(). However, if the ACK of our SYNACK caused us
+        * to enter CA_Recovery then we need to leave retrans_stamp as it was
+        * set entering CA_Recovery, for correct retransmits_timed_out() and
+        * undo behavior.
+        */
+       tcp_retrans_stamp_cleanup(sk);
 
        /* Once we leave TCP_SYN_RECV or TCP_FIN_WAIT_1,
         * we no longer need req so release it.
index e4ad3311e14895ab898a653c3a29cd8af3e42dff..2308665b51c5388814e5b61a262a1636d897c4a9 100644 (file)
@@ -101,8 +101,14 @@ static struct sk_buff *tcp4_gso_segment(struct sk_buff *skb,
        if (!pskb_may_pull(skb, sizeof(struct tcphdr)))
                return ERR_PTR(-EINVAL);
 
-       if (skb_shinfo(skb)->gso_type & SKB_GSO_FRAGLIST)
-               return __tcp4_gso_segment_list(skb, features);
+       if (skb_shinfo(skb)->gso_type & SKB_GSO_FRAGLIST) {
+               struct tcphdr *th = tcp_hdr(skb);
+
+               if (skb_pagelen(skb) - th->doff * 4 == skb_shinfo(skb)->gso_size)
+                       return __tcp4_gso_segment_list(skb, features);
+
+               skb->ip_summed = CHECKSUM_NONE;
+       }
 
        if (unlikely(skb->ip_summed != CHECKSUM_PARTIAL)) {
                const struct iphdr *iph = ip_hdr(skb);
index 4fd746bd4d54f621601b20c3821e71370a4a615a..68804fd01dafc48101ca8c3f15991dbe02a0dd6f 100644 (file)
@@ -2342,10 +2342,7 @@ static bool tcp_can_coalesce_send_queue_head(struct sock *sk, int len)
                if (len <= skb->len)
                        break;
 
-               if (unlikely(TCP_SKB_CB(skb)->eor) ||
-                   tcp_has_tx_tstamp(skb) ||
-                   !skb_pure_zcopy_same(skb, next) ||
-                   skb_frags_readable(skb) != skb_frags_readable(next))
+               if (tcp_has_tx_tstamp(skb) || !tcp_skb_can_collapse(skb, next))
                        return false;
 
                len -= skb->len;
index 8accbf4cb2956a7334e2b455de55404a56e016ba..2849b273b131076cf8300633d6642a6b84468235 100644 (file)
@@ -951,8 +951,10 @@ static int udp_send_skb(struct sk_buff *skb, struct flowi4 *fl4,
                        skb_shinfo(skb)->gso_type = SKB_GSO_UDP_L4;
                        skb_shinfo(skb)->gso_segs = DIV_ROUND_UP(datalen,
                                                                 cork->gso_size);
+
+                       /* Don't checksum the payload, skb will get segmented */
+                       goto csum_partial;
                }
-               goto csum_partial;
        }
 
        if (is_udplite)                                  /*     UDP-Lite      */
index d842303587af93fc58454c0a2da1b6f70c55eec8..a5be6e4ed326fbdc6a9b3889db4da903f7f25d37 100644 (file)
@@ -296,8 +296,26 @@ struct sk_buff *__udp_gso_segment(struct sk_buff *gso_skb,
                return NULL;
        }
 
-       if (skb_shinfo(gso_skb)->gso_type & SKB_GSO_FRAGLIST)
-               return __udp_gso_segment_list(gso_skb, features, is_ipv6);
+       if (skb_shinfo(gso_skb)->gso_type & SKB_GSO_FRAGLIST) {
+                /* Detect modified geometry and pass those to skb_segment. */
+               if (skb_pagelen(gso_skb) - sizeof(*uh) == skb_shinfo(gso_skb)->gso_size)
+                       return __udp_gso_segment_list(gso_skb, features, is_ipv6);
+
+                /* Setup csum, as fraglist skips this in udp4_gro_receive. */
+               gso_skb->csum_start = skb_transport_header(gso_skb) - gso_skb->head;
+               gso_skb->csum_offset = offsetof(struct udphdr, check);
+               gso_skb->ip_summed = CHECKSUM_PARTIAL;
+
+               uh = udp_hdr(gso_skb);
+               if (is_ipv6)
+                       uh->check = ~udp_v6_check(gso_skb->len,
+                                                 &ipv6_hdr(gso_skb)->saddr,
+                                                 &ipv6_hdr(gso_skb)->daddr, 0);
+               else
+                       uh->check = ~udp_v4_check(gso_skb->len,
+                                                 ip_hdr(gso_skb)->saddr,
+                                                 ip_hdr(gso_skb)->daddr, 0);
+       }
 
        skb_pull(gso_skb, sizeof(*uh));
 
index 0294fef577fab134c451d6180cd8aab87fc8ab01..7e1c2faed1ff9931b599107955fa24a7d284d734 100644 (file)
 #include <net/ip.h>
 #include <net/l3mdev.h>
 
-static struct dst_entry *__xfrm4_dst_lookup(struct net *net, struct flowi4 *fl4,
-                                           int tos, int oif,
-                                           const xfrm_address_t *saddr,
-                                           const xfrm_address_t *daddr,
-                                           u32 mark)
+static struct dst_entry *__xfrm4_dst_lookup(struct flowi4 *fl4,
+                                           const struct xfrm_dst_lookup_params *params)
 {
        struct rtable *rt;
 
        memset(fl4, 0, sizeof(*fl4));
-       fl4->daddr = daddr->a4;
-       fl4->flowi4_tos = tos;
-       fl4->flowi4_l3mdev = l3mdev_master_ifindex_by_index(net, oif);
-       fl4->flowi4_mark = mark;
-       if (saddr)
-               fl4->saddr = saddr->a4;
-
-       rt = __ip_route_output_key(net, fl4);
+       fl4->daddr = params->daddr->a4;
+       fl4->flowi4_tos = params->tos;
+       fl4->flowi4_l3mdev = l3mdev_master_ifindex_by_index(params->net,
+                                                           params->oif);
+       fl4->flowi4_mark = params->mark;
+       if (params->saddr)
+               fl4->saddr = params->saddr->a4;
+       fl4->flowi4_proto = params->ipproto;
+       fl4->uli = params->uli;
+
+       rt = __ip_route_output_key(params->net, fl4);
        if (!IS_ERR(rt))
                return &rt->dst;
 
        return ERR_CAST(rt);
 }
 
-static struct dst_entry *xfrm4_dst_lookup(struct net *net, int tos, int oif,
-                                         const xfrm_address_t *saddr,
-                                         const xfrm_address_t *daddr,
-                                         u32 mark)
+static struct dst_entry *xfrm4_dst_lookup(const struct xfrm_dst_lookup_params *params)
 {
        struct flowi4 fl4;
 
-       return __xfrm4_dst_lookup(net, &fl4, tos, oif, saddr, daddr, mark);
+       return __xfrm4_dst_lookup(&fl4, params);
 }
 
-static int xfrm4_get_saddr(struct net *net, int oif,
-                          xfrm_address_t *saddr, xfrm_address_t *daddr,
-                          u32 mark)
+static int xfrm4_get_saddr(xfrm_address_t *saddr,
+                          const struct xfrm_dst_lookup_params *params)
 {
        struct dst_entry *dst;
        struct flowi4 fl4;
 
-       dst = __xfrm4_dst_lookup(net, &fl4, 0, oif, NULL, daddr, mark);
+       dst = __xfrm4_dst_lookup(&fl4, params);
        if (IS_ERR(dst))
                return -EHOSTUNREACH;
 
index d680beb91b0a22a281740f526f62fec307b7f28c..94dceac528842c47c18e71ad75e9d16ae373b4f2 100644 (file)
@@ -85,7 +85,7 @@
 #include <linux/netconf.h>
 #include <linux/random.h>
 #include <linux/uaccess.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #include <linux/proc_fs.h>
 #include <linux/seq_file.h>
index eb8ee1e9373a74ab03017f941b9c8ac724508ee6..dbcea9fee6262def4558a15f187adcc6e485eb7b 100644 (file)
@@ -29,7 +29,7 @@
 #include <net/calipso.h>
 #include <linux/atomic.h>
 #include <linux/bug.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include <linux/crc-ccitt.h>
 
 /* Maximium size of the calipso option including
index a0a2de30be3e7b6fa9aa34dcc6a918e566713e07..0c39c77fe8a8a4c7589cdd9e6b7fb78e6f0ef88b 100644 (file)
@@ -47,11 +47,12 @@ static bool nf_dup_ipv6_route(struct net *net, struct sk_buff *skb,
 void nf_dup_ipv6(struct net *net, struct sk_buff *skb, unsigned int hooknum,
                 const struct in6_addr *gw, int oif)
 {
+       local_bh_disable();
        if (this_cpu_read(nf_skb_duplicated))
-               return;
+               goto out;
        skb = pskb_copy(skb, GFP_ATOMIC);
        if (skb == NULL)
-               return;
+               goto out;
 
 #if IS_ENABLED(CONFIG_NF_CONNTRACK)
        nf_reset_ct(skb);
@@ -69,6 +70,8 @@ void nf_dup_ipv6(struct net *net, struct sk_buff *skb, unsigned int hooknum,
        } else {
                kfree_skb(skb);
        }
+out:
+       local_bh_enable();
 }
 EXPORT_SYMBOL_GPL(nf_dup_ipv6);
 
index 7db0437140bf22390e2f40f3b892978379e08a15..9ae2b2725bf99ab0c6057032996b7f249fb6f45c 100644 (file)
@@ -268,12 +268,12 @@ static int nf_reject6_fill_skb_dst(struct sk_buff *skb_in)
 void nf_send_reset6(struct net *net, struct sock *sk, struct sk_buff *oldskb,
                    int hook)
 {
-       struct sk_buff *nskb;
-       struct tcphdr _otcph;
-       const struct tcphdr *otcph;
-       unsigned int otcplen, hh_len;
        const struct ipv6hdr *oip6h = ipv6_hdr(oldskb);
        struct dst_entry *dst = NULL;
+       const struct tcphdr *otcph;
+       struct sk_buff *nskb;
+       struct tcphdr _otcph;
+       unsigned int otcplen;
        struct flowi6 fl6;
 
        if ((!(ipv6_addr_type(&oip6h->saddr) & IPV6_ADDR_UNICAST)) ||
@@ -312,9 +312,8 @@ void nf_send_reset6(struct net *net, struct sock *sk, struct sk_buff *oldskb,
        if (IS_ERR(dst))
                return;
 
-       hh_len = (dst->dev->hard_header_len + 15)&~15;
-       nskb = alloc_skb(hh_len + 15 + dst->header_len + sizeof(struct ipv6hdr)
-                        + sizeof(struct tcphdr) + dst->trailer_len,
+       nskb = alloc_skb(LL_MAX_HEADER + sizeof(struct ipv6hdr) +
+                        sizeof(struct tcphdr) + dst->trailer_len,
                         GFP_ATOMIC);
 
        if (!nskb) {
@@ -327,7 +326,7 @@ void nf_send_reset6(struct net *net, struct sock *sk, struct sk_buff *oldskb,
 
        nskb->mark = fl6.flowi6_mark;
 
-       skb_reserve(nskb, hh_len + dst->header_len);
+       skb_reserve(nskb, LL_MAX_HEADER);
        nf_reject_ip6hdr_put(nskb, oldskb, IPPROTO_TCP, ip6_dst_hoplimit(dst));
        nf_reject_ip6_tcphdr_put(nskb, oldskb, otcph, otcplen);
 
index 36dc14b34388c8ff49ee621d9aa4ddd1df1d2727..c9f1634b3838aeff4cd5002545f4ac496ce0bdc6 100644 (file)
@@ -41,8 +41,6 @@ static int nft_fib6_flowi_init(struct flowi6 *fl6, const struct nft_fib *priv,
        if (ipv6_addr_type(&fl6->daddr) & IPV6_ADDR_LINKLOCAL) {
                lookup_flags |= RT6_LOOKUP_F_IFACE;
                fl6->flowi6_oif = get_ifindex(dev ? dev : pkt->skb->dev);
-       } else if (priv->flags & NFTA_FIB_F_IIF) {
-               fl6->flowi6_l3mdev = l3mdev_master_ifindex_rcu(dev);
        }
 
        if (ipv6_addr_type(&fl6->saddr) & IPV6_ADDR_UNICAST)
@@ -75,6 +73,8 @@ static u32 __nft_fib6_eval_type(const struct nft_fib *priv,
        else if (priv->flags & NFTA_FIB_F_OIF)
                dev = nft_out(pkt);
 
+       fl6.flowi6_l3mdev = l3mdev_master_ifindex_rcu(dev);
+
        nft_fib6_flowi_init(&fl6, priv, pkt, dev, iph);
 
        if (dev && nf_ipv6_chk_addr(nft_net(pkt), &fl6.daddr, dev, true))
@@ -165,6 +165,7 @@ void nft_fib6_eval(const struct nft_expr *expr, struct nft_regs *regs,
                .flowi6_iif = LOOPBACK_IFINDEX,
                .flowi6_proto = pkt->tprot,
                .flowi6_uid = sock_net_uid(nft_net(pkt), NULL),
+               .flowi6_l3mdev = l3mdev_master_ifindex_rcu(nft_in(pkt)),
        };
        struct rt6_info *rt;
        int lookup_flags;
index 23971903e66de82d2232def158d5faf3885c3d5a..a45bf17cb2a172d4612cb42f51481b97bbf364cd 100644 (file)
@@ -159,8 +159,14 @@ static struct sk_buff *tcp6_gso_segment(struct sk_buff *skb,
        if (!pskb_may_pull(skb, sizeof(*th)))
                return ERR_PTR(-EINVAL);
 
-       if (skb_shinfo(skb)->gso_type & SKB_GSO_FRAGLIST)
-               return __tcp6_gso_segment_list(skb, features);
+       if (skb_shinfo(skb)->gso_type & SKB_GSO_FRAGLIST) {
+               struct tcphdr *th = tcp_hdr(skb);
+
+               if (skb_pagelen(skb) - th->doff * 4 == skb_shinfo(skb)->gso_size)
+                       return __tcp6_gso_segment_list(skb, features);
+
+               skb->ip_summed = CHECKSUM_NONE;
+       }
 
        if (unlikely(skb->ip_summed != CHECKSUM_PARTIAL)) {
                const struct ipv6hdr *ipv6h = ipv6_hdr(skb);
index 52dfbb2ff1a80eb26dfb38598764dfaf2610ee84..0cef8ae5d1ea18accdbde8e82032afe69e69275b 100644 (file)
@@ -1266,8 +1266,10 @@ static int udp_v6_send_skb(struct sk_buff *skb, struct flowi6 *fl6,
                        skb_shinfo(skb)->gso_type = SKB_GSO_UDP_L4;
                        skb_shinfo(skb)->gso_segs = DIV_ROUND_UP(datalen,
                                                                 cork->gso_size);
+
+                       /* Don't checksum the payload, skb will get segmented */
+                       goto csum_partial;
                }
-               goto csum_partial;
        }
 
        if (is_udplite)
index b1d81c4270ab3a1fd7bd08564c362c906f5f78ae..1f19b6f14484c6fd74fccb67ecb8f18da038a55a 100644 (file)
 #include <net/ip6_route.h>
 #include <net/l3mdev.h>
 
-static struct dst_entry *xfrm6_dst_lookup(struct net *net, int tos, int oif,
-                                         const xfrm_address_t *saddr,
-                                         const xfrm_address_t *daddr,
-                                         u32 mark)
+static struct dst_entry *xfrm6_dst_lookup(const struct xfrm_dst_lookup_params *params)
 {
        struct flowi6 fl6;
        struct dst_entry *dst;
        int err;
 
        memset(&fl6, 0, sizeof(fl6));
-       fl6.flowi6_l3mdev = l3mdev_master_ifindex_by_index(net, oif);
-       fl6.flowi6_mark = mark;
-       memcpy(&fl6.daddr, daddr, sizeof(fl6.daddr));
-       if (saddr)
-               memcpy(&fl6.saddr, saddr, sizeof(fl6.saddr));
+       fl6.flowi6_l3mdev = l3mdev_master_ifindex_by_index(params->net,
+                                                          params->oif);
+       fl6.flowi6_mark = params->mark;
+       memcpy(&fl6.daddr, params->daddr, sizeof(fl6.daddr));
+       if (params->saddr)
+               memcpy(&fl6.saddr, params->saddr, sizeof(fl6.saddr));
 
-       dst = ip6_route_output(net, NULL, &fl6);
+       fl6.flowi4_proto = params->ipproto;
+       fl6.uli = params->uli;
+
+       dst = ip6_route_output(params->net, NULL, &fl6);
 
        err = dst->error;
        if (dst->error) {
@@ -50,15 +51,14 @@ static struct dst_entry *xfrm6_dst_lookup(struct net *net, int tos, int oif,
        return dst;
 }
 
-static int xfrm6_get_saddr(struct net *net, int oif,
-                          xfrm_address_t *saddr, xfrm_address_t *daddr,
-                          u32 mark)
+static int xfrm6_get_saddr(xfrm_address_t *saddr,
+                          const struct xfrm_dst_lookup_params *params)
 {
        struct dst_entry *dst;
        struct net_device *dev;
        struct inet6_dev *idev;
 
-       dst = xfrm6_dst_lookup(net, 0, oif, NULL, daddr, mark);
+       dst = xfrm6_dst_lookup(params);
        if (IS_ERR(dst))
                return -EHOSTUNREACH;
 
@@ -68,7 +68,8 @@ static int xfrm6_get_saddr(struct net *net, int oif,
                return -EHOSTUNREACH;
        }
        dev = idev->dev;
-       ipv6_dev_get_saddr(dev_net(dev), dev, &daddr->in6, 0, &saddr->in6);
+       ipv6_dev_get_saddr(dev_net(dev), dev, &params->daddr->in6, 0,
+                          &saddr->in6);
        dst_release(dst);
        return 0;
 }
index 284f1dec1b56dd07b4e6e22af3088233b4a25069..59457c0c14aab811b6157819ca4c9ac1eb579b6f 100644 (file)
@@ -116,7 +116,7 @@ static int l2tp_tunnel_notify(struct genl_family *family,
                                  NLM_F_ACK, tunnel, cmd);
 
        if (ret >= 0) {
-               ret = genlmsg_multicast_allns(family, msg, 0, 0, GFP_ATOMIC);
+               ret = genlmsg_multicast_allns(family, msg, 0, 0);
                /* We don't care if no one is listening */
                if (ret == -ESRCH)
                        ret = 0;
@@ -144,7 +144,7 @@ static int l2tp_session_notify(struct genl_family *family,
                                   NLM_F_ACK, session, cmd);
 
        if (ret >= 0) {
-               ret = genlmsg_multicast_allns(family, msg, 0, 0, GFP_ATOMIC);
+               ret = genlmsg_multicast_allns(family, msg, 0, 0);
                /* We don't care if no one is listening */
                if (ret == -ESRCH)
                        ret = 0;
index 13438cc0a6b139b6cb10c15ce894153706514811..cf0f7780fb109e1c063826760aef36cb61bb9062 100644 (file)
@@ -96,7 +96,7 @@ config MAC80211_DEBUGFS
 
 config MAC80211_MESSAGE_TRACING
        bool "Trace all mac80211 debug messages"
-       depends on MAC80211
+       depends on MAC80211 && TRACING
        help
          Select this option to have mac80211 register the
          mac80211_msg trace subsystem with tracepoints to
index 847304a3a29a9631174cb63823f119f844f57759..6dfc61a9acd4a57480e13eb81fad7a53215531d7 100644 (file)
@@ -3046,6 +3046,7 @@ static int ieee80211_set_tx_power(struct wiphy *wiphy,
        enum nl80211_tx_power_setting txp_type = type;
        bool update_txp_type = false;
        bool has_monitor = false;
+       int old_power = local->user_power_level;
 
        lockdep_assert_wiphy(local->hw.wiphy);
 
@@ -3128,6 +3129,10 @@ static int ieee80211_set_tx_power(struct wiphy *wiphy,
                }
        }
 
+       if (local->emulate_chanctx &&
+           (old_power != local->user_power_level))
+               ieee80211_hw_conf_chan(local);
+
        return 0;
 }
 
@@ -3138,7 +3143,8 @@ static int ieee80211_get_tx_power(struct wiphy *wiphy,
        struct ieee80211_local *local = wiphy_priv(wiphy);
        struct ieee80211_sub_if_data *sdata = IEEE80211_WDEV_TO_SUB_IF(wdev);
 
-       if (local->ops->get_txpower)
+       if (local->ops->get_txpower &&
+           (sdata->flags & IEEE80211_SDATA_IN_DRIVER))
                return drv_get_txpower(local, sdata, dbm);
 
        if (local->emulate_chanctx)
@@ -4826,12 +4832,12 @@ void ieee80211_color_change_finalize_work(struct wiphy *wiphy,
        ieee80211_color_change_finalize(link);
 }
 
-void ieee80211_color_collision_detection_work(struct work_struct *work)
+void ieee80211_color_collision_detection_work(struct wiphy *wiphy,
+                                             struct wiphy_work *work)
 {
-       struct delayed_work *delayed_work = to_delayed_work(work);
        struct ieee80211_link_data *link =
-               container_of(delayed_work, struct ieee80211_link_data,
-                            color_collision_detect_work);
+               container_of(work, struct ieee80211_link_data,
+                            color_collision_detect_work.work);
        struct ieee80211_sub_if_data *sdata = link->sdata;
 
        cfg80211_obss_color_collision_notify(sdata->dev, link->color_bitmap,
@@ -4884,7 +4890,8 @@ ieee80211_obss_color_collision_notify(struct ieee80211_vif *vif,
                return;
        }
 
-       if (delayed_work_pending(&link->color_collision_detect_work)) {
+       if (wiphy_delayed_work_pending(sdata->local->hw.wiphy,
+                                      &link->color_collision_detect_work)) {
                rcu_read_unlock();
                return;
        }
@@ -4893,9 +4900,9 @@ ieee80211_obss_color_collision_notify(struct ieee80211_vif *vif,
        /* queue the color collision detection event every 500 ms in order to
         * avoid sending too much netlink messages to userspace.
         */
-       ieee80211_queue_delayed_work(&sdata->local->hw,
-                                    &link->color_collision_detect_work,
-                                    msecs_to_jiffies(500));
+       wiphy_delayed_work_queue(sdata->local->hw.wiphy,
+                                &link->color_collision_detect_work,
+                                msecs_to_jiffies(500));
 
        rcu_read_unlock();
 }
index 4f0390918b60027bc7eb7c7b30e840a983f91a76..3d3c9139ff5e4503e23479551b29560d5fda2191 100644 (file)
@@ -892,9 +892,10 @@ struct ieee80211_chanctx {
        /* temporary data for search algorithm etc. */
        struct ieee80211_chan_req req;
 
-       struct ieee80211_chanctx_conf conf;
-
        bool radar_detected;
+
+       /* MUST be last - ends in a flexible-array member. */
+       struct ieee80211_chanctx_conf conf;
 };
 
 struct mac80211_qos_map {
@@ -1053,7 +1054,7 @@ struct ieee80211_link_data {
        } csa;
 
        struct wiphy_work color_change_finalize_work;
-       struct delayed_work color_collision_detect_work;
+       struct wiphy_delayed_work color_collision_detect_work;
        u64 color_bitmap;
 
        /* context reservation -- protected with wiphy mutex */
@@ -2005,7 +2006,8 @@ int ieee80211_channel_switch(struct wiphy *wiphy, struct net_device *dev,
 /* color change handling */
 void ieee80211_color_change_finalize_work(struct wiphy *wiphy,
                                          struct wiphy_work *work);
-void ieee80211_color_collision_detection_work(struct work_struct *work);
+void ieee80211_color_collision_detection_work(struct wiphy *wiphy,
+                                             struct wiphy_work *work);
 
 /* interface handling */
 #define MAC80211_SUPPORTED_FEATURES_TX (NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM | \
index eecdd2265eaa6351ff6653f6af7b3ce7dc72b0f7..67ecfea2298294debe442d2103e3c82d4fc63712 100644 (file)
@@ -18,7 +18,7 @@
 #include <linux/slab.h>
 #include <linux/export.h>
 #include <net/mac80211.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include "ieee80211_i.h"
 #include "driver-ops.h"
 #include "debugfs_key.h"
@@ -987,6 +987,26 @@ void ieee80211_reenable_keys(struct ieee80211_sub_if_data *sdata)
        }
 }
 
+static void
+ieee80211_key_iter(struct ieee80211_hw *hw,
+                  struct ieee80211_vif *vif,
+                  struct ieee80211_key *key,
+                  void (*iter)(struct ieee80211_hw *hw,
+                               struct ieee80211_vif *vif,
+                               struct ieee80211_sta *sta,
+                               struct ieee80211_key_conf *key,
+                               void *data),
+                  void *iter_data)
+{
+       /* skip keys of station in removal process */
+       if (key->sta && key->sta->removed)
+               return;
+       if (!(key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE))
+               return;
+       iter(hw, vif, key->sta ? &key->sta->sta : NULL,
+            &key->conf, iter_data);
+}
+
 void ieee80211_iter_keys(struct ieee80211_hw *hw,
                         struct ieee80211_vif *vif,
                         void (*iter)(struct ieee80211_hw *hw,
@@ -1005,16 +1025,13 @@ void ieee80211_iter_keys(struct ieee80211_hw *hw,
        if (vif) {
                sdata = vif_to_sdata(vif);
                list_for_each_entry_safe(key, tmp, &sdata->key_list, list)
-                       iter(hw, &sdata->vif,
-                            key->sta ? &key->sta->sta : NULL,
-                            &key->conf, iter_data);
+                       ieee80211_key_iter(hw, vif, key, iter, iter_data);
        } else {
                list_for_each_entry(sdata, &local->interfaces, list)
                        list_for_each_entry_safe(key, tmp,
                                                 &sdata->key_list, list)
-                               iter(hw, &sdata->vif,
-                                    key->sta ? &key->sta->sta : NULL,
-                                    &key->conf, iter_data);
+                               ieee80211_key_iter(hw, &sdata->vif, key,
+                                                  iter, iter_data);
        }
 }
 EXPORT_SYMBOL(ieee80211_iter_keys);
@@ -1031,17 +1048,8 @@ _ieee80211_iter_keys_rcu(struct ieee80211_hw *hw,
 {
        struct ieee80211_key *key;
 
-       list_for_each_entry_rcu(key, &sdata->key_list, list) {
-               /* skip keys of station in removal process */
-               if (key->sta && key->sta->removed)
-                       continue;
-               if (!(key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE))
-                       continue;
-
-               iter(hw, &sdata->vif,
-                    key->sta ? &key->sta->sta : NULL,
-                    &key->conf, iter_data);
-       }
+       list_for_each_entry_rcu(key, &sdata->key_list, list)
+               ieee80211_key_iter(hw, &sdata->vif, key, iter, iter_data);
 }
 
 void ieee80211_iter_keys_rcu(struct ieee80211_hw *hw,
index 0bbac64d5fa0132b748f775256d9c93b55ecc07d..46092fbcde90ebaef21d3086cb60698c0ef28a8f 100644 (file)
@@ -41,8 +41,8 @@ void ieee80211_link_init(struct ieee80211_sub_if_data *sdata,
                        ieee80211_csa_finalize_work);
        wiphy_work_init(&link->color_change_finalize_work,
                        ieee80211_color_change_finalize_work);
-       INIT_DELAYED_WORK(&link->color_collision_detect_work,
-                         ieee80211_color_collision_detection_work);
+       wiphy_delayed_work_init(&link->color_collision_detect_work,
+                               ieee80211_color_collision_detection_work);
        INIT_LIST_HEAD(&link->assigned_chanctx_list);
        INIT_LIST_HEAD(&link->reserved_chanctx_list);
        wiphy_delayed_work_init(&link->dfs_cac_timer_work,
@@ -72,7 +72,8 @@ void ieee80211_link_stop(struct ieee80211_link_data *link)
        if (link->sdata->vif.type == NL80211_IFTYPE_STATION)
                ieee80211_mgd_stop_link(link);
 
-       cancel_delayed_work_sync(&link->color_collision_detect_work);
+       wiphy_delayed_work_cancel(link->sdata->local->hw.wiphy,
+                                 &link->color_collision_detect_work);
        wiphy_work_cancel(link->sdata->local->hw.wiphy,
                          &link->color_change_finalize_work);
        wiphy_work_cancel(link->sdata->local->hw.wiphy,
index 89084690350fd7cb6f7311298cd2497098384c2b..ee1211a213d702acd8d35f0e2bc8ce626b33a584 100644 (file)
@@ -167,6 +167,8 @@ static u32 ieee80211_calc_hw_conf_chan(struct ieee80211_local *local,
        }
 
        power = ieee80211_chandef_max_power(&chandef);
+       if (local->user_power_level != IEEE80211_UNSET_POWER_LEVEL)
+               power = min(local->user_power_level, power);
 
        rcu_read_lock();
        list_for_each_entry_rcu(sdata, &local->interfaces, list) {
index f94e4be0be12ca3cf2976165c7b9e170716d4abf..640239f4425b165088b201eff060daccea9e49bc 100644 (file)
@@ -7,7 +7,7 @@
  */
 
 #include <linux/slab.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include "ieee80211_i.h"
 #include "mesh.h"
 #include "wme.h"
index 024f48db6b05b8ac4e42368e1bd11a080c709f10..579d0f24ac9d61fee91c9d14ae574fc5145d827a 100644 (file)
@@ -7,7 +7,7 @@
 
 #include <linux/slab.h>
 #include <linux/etherdevice.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include "wme.h"
 #include "mesh.h"
 
index a57502d9ffec45ea87f14f7d4cdecf6ae002ebe6..8a1afc93e7499ec91cdc0c07ad90a70356b13638 100644 (file)
@@ -6,7 +6,7 @@
 #include <linux/types.h>
 #include <linux/bitops.h>
 #include <linux/ieee80211.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #include "michael.h"
 
index 735e78adb0db881060bcb8abad442210c94b51bf..0303972c23e4cb4e8778929eb68c6a75f0f7ad6a 100644 (file)
@@ -23,7 +23,7 @@
 #include <linux/slab.h>
 #include <linux/export.h>
 #include <net/mac80211.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #include "ieee80211_i.h"
 #include "driver-ops.h"
index 9ef14e475c90601ddc50c85554e8166c0d3b5a99..f4c51e4a1e29a608aff0af66e318a397334ce1f6 100644 (file)
@@ -16,7 +16,7 @@
 #include <linux/etherdevice.h>
 #include <linux/rtnetlink.h>
 #include <net/mac80211.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #include "ieee80211_i.h"
 #include "driver-ops.h"
index 59ad24a71141f6dfbea06444a058fb6e639866de..694b43091fec6b6a607aa88cb2fdb37f13520def 100644 (file)
@@ -22,7 +22,7 @@
 #include <kunit/visibility.h>
 #include <net/mac80211.h>
 #include <net/ieee80211_radiotap.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #include "ieee80211_i.h"
 #include "driver-ops.h"
index d1cf987de13bb016f202c4f88b91a0140f9fc158..b41b867f43b2e6707997c2ef3bc8470a012ac0f3 100644 (file)
@@ -11,7 +11,7 @@
 #include <linux/export.h>
 #include <linux/etherdevice.h>
 #include <net/mac80211.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include "ieee80211_i.h"
 #include "rate.h"
 #include "mesh.h"
index e7f57bb18f6e00255e75a465cd7ddb1c7282e6f4..880a1fa8705a0632b8d489dbfe22bc53797211d9 100644 (file)
@@ -9,7 +9,7 @@
 #include <linux/types.h>
 #include <linux/netdevice.h>
 #include <linux/export.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #include <net/mac80211.h>
 #include "driver-ops.h"
index a9ee869822592969c2b7916fc1f06779f72870b2..0ff8b56f58070849c87e22ee0f900f5cf59a1d74 100644 (file)
@@ -24,7 +24,7 @@
 #include <net/mac80211.h>
 #include <net/codel.h>
 #include <net/codel_impl.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include <net/fq_impl.h>
 #include <net/gso.h>
 
index 5c01e121481ab4c5378c852a5e07a40c0a7f0d00..93b8668079a7e875e3b95f4e62d4d9b14ff0033b 100644 (file)
@@ -16,7 +16,7 @@
 #include <linux/mm.h>
 #include <linux/scatterlist.h>
 #include <linux/slab.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #include <net/mac80211.h>
 #include "ieee80211_i.h"
index 047a33797020c4df31d1db0835b795a142788bef..293afa3f57c50378fe16cf7606d9e218fa8d5c72 100644 (file)
@@ -12,7 +12,7 @@
 #include <linux/compiler.h>
 #include <linux/ieee80211.h>
 #include <linux/gfp.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include <net/mac80211.h>
 #include <crypto/aes.h>
 #include <crypto/utils.h>
index e40a988d6c80e7b4673822f7e0fb56ad7feffd52..aac359b5c71dfe4de78758a9a2c464b93b3be95e 100644 (file)
@@ -13,7 +13,7 @@
 #include <linux/module.h>
 #include <linux/netdevice.h>
 #include <linux/crc-ccitt.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #include <net/mac802154.h>
 #include <net/ieee802154_netdev.h>
index 1c0eeaa76560cdf0e533aad07fe6e555a0687f6d..a6dab3cc3ad85823e9000ecdc1a62415d3fb248a 100644 (file)
@@ -176,6 +176,7 @@ void mac802154_scan_worker(struct work_struct *work)
        struct ieee802154_local *local =
                container_of(work, struct ieee802154_local, scan_work.work);
        struct cfg802154_scan_request *scan_req;
+       enum nl802154_scan_types scan_req_type;
        struct ieee802154_sub_if_data *sdata;
        unsigned int scan_duration = 0;
        struct wpan_phy *wpan_phy;
@@ -209,6 +210,7 @@ void mac802154_scan_worker(struct work_struct *work)
        }
 
        wpan_phy = scan_req->wpan_phy;
+       scan_req_type = scan_req->type;
        scan_req_duration = scan_req->duration;
 
        /* Look for the next valid chan */
@@ -246,7 +248,7 @@ void mac802154_scan_worker(struct work_struct *work)
                goto end_scan;
        }
 
-       if (scan_req->type == NL802154_SCAN_ACTIVE) {
+       if (scan_req_type == NL802154_SCAN_ACTIVE) {
                ret = mac802154_transmit_beacon_req(local, sdata);
                if (ret)
                        dev_err(&sdata->dev->dev,
index 6fbed5bb5c3e0d5f838c92c8ad50494814982d34..337d6faf0d2af77dffbc293b0d74f8ad7545f8b7 100644 (file)
@@ -12,7 +12,7 @@
 #include <linux/netdevice.h>
 #include <linux/if_arp.h>
 #include <linux/crc-ccitt.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #include <net/rtnetlink.h>
 #include <net/ieee802154_netdev.h>
index 43288b408fde3b51726eb6f62137509100d2d410..f6de136008f6f9b029e7dacc2e75dce1cd7fd075 100644 (file)
@@ -756,10 +756,14 @@ static __init int mctp_init(void)
        if (rc)
                goto err_unreg_routes;
 
-       mctp_device_init();
+       rc = mctp_device_init();
+       if (rc)
+               goto err_unreg_neigh;
 
        return 0;
 
+err_unreg_neigh:
+       mctp_neigh_exit();
 err_unreg_routes:
        mctp_routes_exit();
 err_unreg_proto:
index acb97b2574289628ea6ea1da02433eef119e6d8b..85cc5f31f1e7c0a0c3f51c5e924d9424dec27b5a 100644 (file)
@@ -524,25 +524,31 @@ static struct notifier_block mctp_dev_nb = {
        .priority = ADDRCONF_NOTIFY_PRIORITY,
 };
 
-void __init mctp_device_init(void)
+static const struct rtnl_msg_handler mctp_device_rtnl_msg_handlers[] = {
+       {THIS_MODULE, PF_MCTP, RTM_NEWADDR, mctp_rtm_newaddr, NULL, 0},
+       {THIS_MODULE, PF_MCTP, RTM_DELADDR, mctp_rtm_deladdr, NULL, 0},
+       {THIS_MODULE, PF_MCTP, RTM_GETADDR, NULL, mctp_dump_addrinfo, 0},
+};
+
+int __init mctp_device_init(void)
 {
-       register_netdevice_notifier(&mctp_dev_nb);
+       int err;
 
-       rtnl_register_module(THIS_MODULE, PF_MCTP, RTM_GETADDR,
-                            NULL, mctp_dump_addrinfo, 0);
-       rtnl_register_module(THIS_MODULE, PF_MCTP, RTM_NEWADDR,
-                            mctp_rtm_newaddr, NULL, 0);
-       rtnl_register_module(THIS_MODULE, PF_MCTP, RTM_DELADDR,
-                            mctp_rtm_deladdr, NULL, 0);
+       register_netdevice_notifier(&mctp_dev_nb);
        rtnl_af_register(&mctp_af_ops);
+
+       err = rtnl_register_many(mctp_device_rtnl_msg_handlers);
+       if (err) {
+               rtnl_af_unregister(&mctp_af_ops);
+               unregister_netdevice_notifier(&mctp_dev_nb);
+       }
+
+       return err;
 }
 
 void __exit mctp_device_exit(void)
 {
+       rtnl_unregister_many(mctp_device_rtnl_msg_handlers);
        rtnl_af_unregister(&mctp_af_ops);
-       rtnl_unregister(PF_MCTP, RTM_DELADDR);
-       rtnl_unregister(PF_MCTP, RTM_NEWADDR);
-       rtnl_unregister(PF_MCTP, RTM_GETADDR);
-
        unregister_netdevice_notifier(&mctp_dev_nb);
 }
index ffa0f9e0983fba13d3de3b72f35af8357e154a05..590f642413e4ef113a1a9fa96cb548b98cb55621 100644 (file)
@@ -322,22 +322,29 @@ static struct pernet_operations mctp_net_ops = {
        .exit = mctp_neigh_net_exit,
 };
 
+static const struct rtnl_msg_handler mctp_neigh_rtnl_msg_handlers[] = {
+       {THIS_MODULE, PF_MCTP, RTM_NEWNEIGH, mctp_rtm_newneigh, NULL, 0},
+       {THIS_MODULE, PF_MCTP, RTM_DELNEIGH, mctp_rtm_delneigh, NULL, 0},
+       {THIS_MODULE, PF_MCTP, RTM_GETNEIGH, NULL, mctp_rtm_getneigh, 0},
+};
+
 int __init mctp_neigh_init(void)
 {
-       rtnl_register_module(THIS_MODULE, PF_MCTP, RTM_NEWNEIGH,
-                            mctp_rtm_newneigh, NULL, 0);
-       rtnl_register_module(THIS_MODULE, PF_MCTP, RTM_DELNEIGH,
-                            mctp_rtm_delneigh, NULL, 0);
-       rtnl_register_module(THIS_MODULE, PF_MCTP, RTM_GETNEIGH,
-                            NULL, mctp_rtm_getneigh, 0);
-
-       return register_pernet_subsys(&mctp_net_ops);
+       int err;
+
+       err = register_pernet_subsys(&mctp_net_ops);
+       if (err)
+               return err;
+
+       err = rtnl_register_many(mctp_neigh_rtnl_msg_handlers);
+       if (err)
+               unregister_pernet_subsys(&mctp_net_ops);
+
+       return err;
 }
 
-void __exit mctp_neigh_exit(void)
+void mctp_neigh_exit(void)
 {
+       rtnl_unregister_many(mctp_neigh_rtnl_msg_handlers);
        unregister_pernet_subsys(&mctp_net_ops);
-       rtnl_unregister(PF_MCTP, RTM_GETNEIGH);
-       rtnl_unregister(PF_MCTP, RTM_DELNEIGH);
-       rtnl_unregister(PF_MCTP, RTM_NEWNEIGH);
 }
index eefd7834d9a009a98325c391cd9c09696db99db7..597e9cf5aa64445474287a3fee02ba760db15796 100644 (file)
@@ -1474,26 +1474,39 @@ static struct pernet_operations mctp_net_ops = {
        .exit = mctp_routes_net_exit,
 };
 
+static const struct rtnl_msg_handler mctp_route_rtnl_msg_handlers[] = {
+       {THIS_MODULE, PF_MCTP, RTM_NEWROUTE, mctp_newroute, NULL, 0},
+       {THIS_MODULE, PF_MCTP, RTM_DELROUTE, mctp_delroute, NULL, 0},
+       {THIS_MODULE, PF_MCTP, RTM_GETROUTE, NULL, mctp_dump_rtinfo, 0},
+};
+
 int __init mctp_routes_init(void)
 {
+       int err;
+
        dev_add_pack(&mctp_packet_type);
 
-       rtnl_register_module(THIS_MODULE, PF_MCTP, RTM_GETROUTE,
-                            NULL, mctp_dump_rtinfo, 0);
-       rtnl_register_module(THIS_MODULE, PF_MCTP, RTM_NEWROUTE,
-                            mctp_newroute, NULL, 0);
-       rtnl_register_module(THIS_MODULE, PF_MCTP, RTM_DELROUTE,
-                            mctp_delroute, NULL, 0);
+       err = register_pernet_subsys(&mctp_net_ops);
+       if (err)
+               goto err_pernet;
+
+       err = rtnl_register_many(mctp_route_rtnl_msg_handlers);
+       if (err)
+               goto err_rtnl;
 
-       return register_pernet_subsys(&mctp_net_ops);
+       return 0;
+
+err_rtnl:
+       unregister_pernet_subsys(&mctp_net_ops);
+err_pernet:
+       dev_remove_pack(&mctp_packet_type);
+       return err;
 }
 
 void mctp_routes_exit(void)
 {
+       rtnl_unregister_many(mctp_route_rtnl_msg_handlers);
        unregister_pernet_subsys(&mctp_net_ops);
-       rtnl_unregister(PF_MCTP, RTM_DELROUTE);
-       rtnl_unregister(PF_MCTP, RTM_NEWROUTE);
-       rtnl_unregister(PF_MCTP, RTM_GETROUTE);
        dev_remove_pack(&mctp_packet_type);
 }
 
index aba983531ed3239cb58b7b451c02a7419a6706f8..df62638b6498434d5fd8e657f19685f6b08b8074 100644 (file)
@@ -2728,6 +2728,15 @@ static struct rtnl_af_ops mpls_af_ops __read_mostly = {
        .get_stats_af_size = mpls_get_stats_af_size,
 };
 
+static const struct rtnl_msg_handler mpls_rtnl_msg_handlers[] __initdata_or_module = {
+       {THIS_MODULE, PF_MPLS, RTM_NEWROUTE, mpls_rtm_newroute, NULL, 0},
+       {THIS_MODULE, PF_MPLS, RTM_DELROUTE, mpls_rtm_delroute, NULL, 0},
+       {THIS_MODULE, PF_MPLS, RTM_GETROUTE, mpls_getroute, mpls_dump_routes, 0},
+       {THIS_MODULE, PF_MPLS, RTM_GETNETCONF,
+        mpls_netconf_get_devconf, mpls_netconf_dump_devconf,
+        RTNL_FLAG_DUMP_UNLOCKED},
+};
+
 static int __init mpls_init(void)
 {
        int err;
@@ -2746,24 +2755,25 @@ static int __init mpls_init(void)
 
        rtnl_af_register(&mpls_af_ops);
 
-       rtnl_register_module(THIS_MODULE, PF_MPLS, RTM_NEWROUTE,
-                            mpls_rtm_newroute, NULL, 0);
-       rtnl_register_module(THIS_MODULE, PF_MPLS, RTM_DELROUTE,
-                            mpls_rtm_delroute, NULL, 0);
-       rtnl_register_module(THIS_MODULE, PF_MPLS, RTM_GETROUTE,
-                            mpls_getroute, mpls_dump_routes, 0);
-       rtnl_register_module(THIS_MODULE, PF_MPLS, RTM_GETNETCONF,
-                            mpls_netconf_get_devconf,
-                            mpls_netconf_dump_devconf,
-                            RTNL_FLAG_DUMP_UNLOCKED);
-       err = ipgre_tunnel_encap_add_mpls_ops();
+       err = rtnl_register_many(mpls_rtnl_msg_handlers);
        if (err)
+               goto out_unregister_rtnl_af;
+
+       err = ipgre_tunnel_encap_add_mpls_ops();
+       if (err) {
                pr_err("Can't add mpls over gre tunnel ops\n");
+               goto out_unregister_rtnl;
+       }
 
        err = 0;
 out:
        return err;
 
+out_unregister_rtnl:
+       rtnl_unregister_many(mpls_rtnl_msg_handlers);
+out_unregister_rtnl_af:
+       rtnl_af_unregister(&mpls_af_ops);
+       dev_remove_pack(&mpls_packet_type);
 out_unregister_pernet:
        unregister_pernet_subsys(&mpls_net_ops);
        goto out;
index a8931349933c11688be1f0e321d902e8030b8531..b08ba959ac4fd485bb833043ff58d4c8bac8a37a 100644 (file)
@@ -22,7 +22,7 @@
 
 #include <linux/kernel.h>
 #include <crypto/sha2.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #include "protocol.h"
 
index 38c2efc82b948d9afd35c4d5bcd45d9e5422a88d..19eb9292bd6093a760b41f98c1774fd2490c48e3 100644 (file)
@@ -17,6 +17,7 @@ static const struct snmp_mib mptcp_snmp_list[] = {
        SNMP_MIB_ITEM("MPCapableFallbackSYNACK", MPTCP_MIB_MPCAPABLEACTIVEFALLBACK),
        SNMP_MIB_ITEM("MPCapableSYNTXDrop", MPTCP_MIB_MPCAPABLEACTIVEDROP),
        SNMP_MIB_ITEM("MPCapableSYNTXDisabled", MPTCP_MIB_MPCAPABLEACTIVEDISABLED),
+       SNMP_MIB_ITEM("MPCapableEndpAttempt", MPTCP_MIB_MPCAPABLEENDPATTEMPT),
        SNMP_MIB_ITEM("MPFallbackTokenInit", MPTCP_MIB_TOKENFALLBACKINIT),
        SNMP_MIB_ITEM("MPTCPRetrans", MPTCP_MIB_RETRANSSEGS),
        SNMP_MIB_ITEM("MPJoinNoTokenFound", MPTCP_MIB_JOINNOTOKEN),
@@ -32,6 +33,8 @@ static const struct snmp_mib mptcp_snmp_list[] = {
        SNMP_MIB_ITEM("MPJoinSynTxBindErr", MPTCP_MIB_JOINSYNTXBINDERR),
        SNMP_MIB_ITEM("MPJoinSynTxConnectErr", MPTCP_MIB_JOINSYNTXCONNECTERR),
        SNMP_MIB_ITEM("DSSNotMatching", MPTCP_MIB_DSSNOMATCH),
+       SNMP_MIB_ITEM("DSSCorruptionFallback", MPTCP_MIB_DSSCORRUPTIONFALLBACK),
+       SNMP_MIB_ITEM("DSSCorruptionReset", MPTCP_MIB_DSSCORRUPTIONRESET),
        SNMP_MIB_ITEM("InfiniteMapTx", MPTCP_MIB_INFINITEMAPTX),
        SNMP_MIB_ITEM("InfiniteMapRx", MPTCP_MIB_INFINITEMAPRX),
        SNMP_MIB_ITEM("DSSNoMatchTCP", MPTCP_MIB_DSSTCPMISMATCH),
index c8ffe18a872217afa24e3af212fe90a3fb8d1c7f..128282982843a07614a46f9b2c2f7c708306c769 100644 (file)
@@ -12,6 +12,7 @@ enum linux_mptcp_mib_field {
        MPTCP_MIB_MPCAPABLEACTIVEFALLBACK, /* Client-side fallback during 3-way handshake */
        MPTCP_MIB_MPCAPABLEACTIVEDROP,  /* Client-side fallback due to a MPC drop */
        MPTCP_MIB_MPCAPABLEACTIVEDISABLED, /* Client-side disabled due to past issues */
+       MPTCP_MIB_MPCAPABLEENDPATTEMPT, /* Prohibited MPC to port-based endp */
        MPTCP_MIB_TOKENFALLBACKINIT,    /* Could not init/allocate token */
        MPTCP_MIB_RETRANSSEGS,          /* Segments retransmitted at the MPTCP-level */
        MPTCP_MIB_JOINNOTOKEN,          /* Received MP_JOIN but the token was not found */
@@ -27,6 +28,8 @@ enum linux_mptcp_mib_field {
        MPTCP_MIB_JOINSYNTXBINDERR,     /* Not able to bind() the address when sending a SYN + MP_JOIN */
        MPTCP_MIB_JOINSYNTXCONNECTERR,  /* Not able to connect() when sending a SYN + MP_JOIN */
        MPTCP_MIB_DSSNOMATCH,           /* Received a new mapping that did not match the previous one */
+       MPTCP_MIB_DSSCORRUPTIONFALLBACK,/* DSS corruption detected, fallback */
+       MPTCP_MIB_DSSCORRUPTIONRESET,   /* DSS corruption detected, MPJ subflow reset */
        MPTCP_MIB_INFINITEMAPTX,        /* Sent an infinite mapping */
        MPTCP_MIB_INFINITEMAPRX,        /* Received an infinite mapping */
        MPTCP_MIB_DSSTCPMISMATCH,       /* DSS-mapping did not map with TCP's sequence numbers */
index 64fe0e7d87d7323583ef9ee5909c833a78e727c2..db586a5b3866f66a24431d7f2cab566f89102885 100644 (file)
@@ -860,7 +860,8 @@ static void mptcp_pm_nl_rm_addr_or_subflow(struct mptcp_sock *msk,
                        int how = RCV_SHUTDOWN | SEND_SHUTDOWN;
                        u8 id = subflow_get_local_id(subflow);
 
-                       if (inet_sk_state_load(ssk) == TCP_CLOSE)
+                       if ((1 << inet_sk_state_load(ssk)) &
+                           (TCPF_FIN_WAIT1 | TCPF_FIN_WAIT2 | TCPF_CLOSING | TCPF_CLOSE))
                                continue;
                        if (rm_type == MPTCP_MIB_RMADDR && remote_id != rm_id)
                                continue;
@@ -872,12 +873,12 @@ static void mptcp_pm_nl_rm_addr_or_subflow(struct mptcp_sock *msk,
                                 i, rm_id, id, remote_id, msk->mpc_endpoint_id);
                        spin_unlock_bh(&msk->pm.lock);
                        mptcp_subflow_shutdown(sk, ssk, how);
+                       removed |= subflow->request_join;
 
                        /* the following takes care of updating the subflows counter */
                        mptcp_close_ssk(sk, ssk, subflow);
                        spin_lock_bh(&msk->pm.lock);
 
-                       removed |= subflow->request_join;
                        if (rm_type == MPTCP_MIB_RMSUBFLOW)
                                __MPTCP_INC_STATS(sock_net(sk), rm_type);
                }
@@ -1120,6 +1121,7 @@ static int mptcp_pm_nl_create_listen_socket(struct sock *sk,
         */
        inet_sk_state_store(newsk, TCP_LISTEN);
        lock_sock(ssk);
+       WRITE_ONCE(mptcp_subflow_ctx(ssk)->pm_listener, true);
        err = __inet_listen_sk(ssk, backlog);
        if (!err)
                mptcp_event_pm_listener(ssk, MPTCP_EVENT_LISTENER_CREATED);
index c2317919fc148a67a81ded795359bd613c9b0dff..d263091659e076587bc3406dfdcb4409adb3247e 100644 (file)
@@ -620,6 +620,18 @@ static bool mptcp_check_data_fin(struct sock *sk)
        return ret;
 }
 
+static void mptcp_dss_corruption(struct mptcp_sock *msk, struct sock *ssk)
+{
+       if (READ_ONCE(msk->allow_infinite_fallback)) {
+               MPTCP_INC_STATS(sock_net(ssk),
+                               MPTCP_MIB_DSSCORRUPTIONFALLBACK);
+               mptcp_do_fallback(ssk);
+       } else {
+               MPTCP_INC_STATS(sock_net(ssk), MPTCP_MIB_DSSCORRUPTIONRESET);
+               mptcp_subflow_reset(ssk);
+       }
+}
+
 static bool __mptcp_move_skbs_from_subflow(struct mptcp_sock *msk,
                                           struct sock *ssk,
                                           unsigned int *bytes)
@@ -692,10 +704,16 @@ static bool __mptcp_move_skbs_from_subflow(struct mptcp_sock *msk,
                                moved += len;
                        seq += len;
 
-                       if (WARN_ON_ONCE(map_remaining < len))
-                               break;
+                       if (unlikely(map_remaining < len)) {
+                               DEBUG_NET_WARN_ON_ONCE(1);
+                               mptcp_dss_corruption(msk, ssk);
+                       }
                } else {
-                       WARN_ON_ONCE(!fin);
+                       if (unlikely(!fin)) {
+                               DEBUG_NET_WARN_ON_ONCE(1);
+                               mptcp_dss_corruption(msk, ssk);
+                       }
+
                        sk_eat_skb(ssk, skb);
                        done = true;
                }
@@ -2846,8 +2864,10 @@ static int mptcp_init_sock(struct sock *sk)
        if (unlikely(!net->mib.mptcp_statistics) && !mptcp_mib_alloc(net))
                return -ENOMEM;
 
+       rcu_read_lock();
        ret = mptcp_init_sched(mptcp_sk(sk),
                               mptcp_sched_find(mptcp_get_scheduler(net)));
+       rcu_read_unlock();
        if (ret)
                return ret;
 
index 74417aae08d0f488bc358ce6cd931540650bb7be..568a72702b080d7610425ce5c3a409c7b88da13a 100644 (file)
@@ -535,6 +535,7 @@ struct mptcp_subflow_context {
                __unused : 8;
        bool    data_avail;
        bool    scheduled;
+       bool    pm_listener;        /* a listener managed by the kernel PM? */
        u32     remote_nonce;
        u64     thmac;
        u32     local_nonce;
index 1040b3b9696b74b12c1f8c027e5a323c558900f0..6170f2fff71e4f9d64837f2ebf4d81bba224fafb 100644 (file)
@@ -132,6 +132,13 @@ static void subflow_add_reset_reason(struct sk_buff *skb, u8 reason)
        }
 }
 
+static int subflow_reset_req_endp(struct request_sock *req, struct sk_buff *skb)
+{
+       SUBFLOW_REQ_INC_STATS(req, MPTCP_MIB_MPCAPABLEENDPATTEMPT);
+       subflow_add_reset_reason(skb, MPTCP_RST_EPROHIBIT);
+       return -EPERM;
+}
+
 /* Init mptcp request socket.
  *
  * Returns an error code if a JOIN has failed and a TCP reset
@@ -165,6 +172,8 @@ static int subflow_check_req(struct request_sock *req,
        if (opt_mp_capable) {
                SUBFLOW_REQ_INC_STATS(req, MPTCP_MIB_MPCAPABLEPASSIVE);
 
+               if (unlikely(listener->pm_listener))
+                       return subflow_reset_req_endp(req, skb);
                if (opt_mp_join)
                        return 0;
        } else if (opt_mp_join) {
@@ -172,6 +181,8 @@ static int subflow_check_req(struct request_sock *req,
 
                if (mp_opt.backup)
                        SUBFLOW_REQ_INC_STATS(req, MPTCP_MIB_JOINSYNBACKUPRX);
+       } else if (unlikely(listener->pm_listener)) {
+               return subflow_reset_req_endp(req, skb);
        }
 
        if (opt_mp_capable && listener->request_mptcp) {
@@ -975,8 +986,10 @@ static bool skb_is_fully_mapped(struct sock *ssk, struct sk_buff *skb)
        unsigned int skb_consumed;
 
        skb_consumed = tcp_sk(ssk)->copied_seq - TCP_SKB_CB(skb)->seq;
-       if (WARN_ON_ONCE(skb_consumed >= skb->len))
+       if (unlikely(skb_consumed >= skb->len)) {
+               DEBUG_NET_WARN_ON_ONCE(1);
                return true;
+       }
 
        return skb->len - skb_consumed <= subflow->map_data_len -
                                          mptcp_subflow_get_map_offset(subflow);
@@ -1280,7 +1293,7 @@ static bool subflow_can_fallback(struct mptcp_subflow_context *subflow)
        else if (READ_ONCE(msk->csum_enabled))
                return !subflow->valid_csum_seen;
        else
-               return !subflow->fully_established;
+               return READ_ONCE(msk->allow_infinite_fallback);
 }
 
 static void mptcp_subflow_fail(struct mptcp_sock *msk, struct sock *ssk)
index 5ecf611c882009d647909e52a686286e090ba6c3..5cf55bde366d1813865ac5da17d232b5eadb2a3e 100644 (file)
@@ -1954,6 +1954,8 @@ void ncsi_unregister_dev(struct ncsi_dev *nd)
        list_del_rcu(&ndp->node);
        spin_unlock_irqrestore(&ncsi_dev_lock, flags);
 
+       disable_work_sync(&ndp->work);
+
        kfree(ndp);
 }
 EXPORT_SYMBOL_GPL(ncsi_unregister_dev);
index f53899d12416229f77cf8beb4017f0e233178773..d8a284999544b0eba56aac280208b5cc4ca928f7 100644 (file)
@@ -35,7 +35,7 @@
 #include <linux/gfp.h>
 #include <net/protocol.h>
 #include <net/tcp.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #include <net/ip_vs.h>
 
index be74c0906dda92e13e2ddef6cebd268c955d5336..3402675bf5215b95757be33af388b8325501ef2a 100644 (file)
@@ -51,7 +51,7 @@
 #include <linux/kernel.h>
 #include <linux/sched/signal.h>
 
-#include <asm/unaligned.h>             /* Used for ntoh_seq and hton_seq */
+#include <linux/unaligned.h>           /* Used for ntoh_seq and hton_seq */
 
 #include <net/ip.h>
 #include <net/sock.h>
index 5257d5e7eb09d82aaa233f2417dfbca3e4c1f97f..3d64a4511fcfdd93b0d34c0fbed8bc6f8515ec4b 100644 (file)
@@ -23,6 +23,7 @@ static unsigned int nf_hook_run_bpf(void *bpf_prog, struct sk_buff *skb,
 struct bpf_nf_link {
        struct bpf_link link;
        struct nf_hook_ops hook_ops;
+       netns_tracker ns_tracker;
        struct net *net;
        u32 dead;
        const struct nf_defrag_hook *defrag_hook;
@@ -120,6 +121,7 @@ static void bpf_nf_link_release(struct bpf_link *link)
        if (!cmpxchg(&nf_link->dead, 0, 1)) {
                nf_unregister_net_hook(nf_link->net, &nf_link->hook_ops);
                bpf_nf_disable_defrag(nf_link);
+               put_net_track(nf_link->net, &nf_link->ns_tracker);
        }
 }
 
@@ -150,11 +152,12 @@ static int bpf_nf_link_fill_link_info(const struct bpf_link *link,
                                      struct bpf_link_info *info)
 {
        struct bpf_nf_link *nf_link = container_of(link, struct bpf_nf_link, link);
+       const struct nf_defrag_hook *hook = nf_link->defrag_hook;
 
        info->netfilter.pf = nf_link->hook_ops.pf;
        info->netfilter.hooknum = nf_link->hook_ops.hooknum;
        info->netfilter.priority = nf_link->hook_ops.priority;
-       info->netfilter.flags = 0;
+       info->netfilter.flags = hook ? BPF_F_NETFILTER_IP_DEFRAG : 0;
 
        return 0;
 }
@@ -257,6 +260,8 @@ int bpf_nf_link_attach(const union bpf_attr *attr, struct bpf_prog *prog)
                return err;
        }
 
+       get_net_track(net, &link->ns_tracker, GFP_KERNEL);
+
        return bpf_link_settle(&link_primer);
 }
 
index ae493599a3ef03415f6c40e942cdab700acb84c6..0c1d086e96cb3f69a6849b1fca6666714c4e0a98 100644 (file)
@@ -14,7 +14,7 @@
 #include <linux/skbuff.h>
 #include <linux/ipv6.h>
 #include <net/ip6_checksum.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #include <net/tcp.h>
 
index 5b140c12b7dfa40efc9bec6f2588c4350fed6bfb..3fa3f5dfb26444a4a1d7835fdda00e585b76c690 100644 (file)
@@ -5,7 +5,7 @@
 
 #include <linux/module.h>
 #include <linux/skbuff.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include <net/tcp.h>
 #include <net/netns/generic.h>
 #include <linux/proc_fs.h>
index 2f82a444d21bf3e1b5598577635497066c5e838d..af9206a3afd181f33213e5dac0f9c4b299d63ecf 100644 (file)
@@ -5,7 +5,7 @@
  * Development of this code funded by Astaro AG (http://www.astaro.com/)
  */
 
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/module.h>
index 6bfd335162414a817f7ec4f974f7e4ed7e4be3d2..b8d03364566c1f92367f89cbc2698f261130ed19 100644 (file)
@@ -5,7 +5,7 @@
  * Development of this code funded by Astaro AG (http://www.astaro.com/)
  */
 
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include <linux/kernel.h>
 #include <linux/netlink.h>
 #include <linux/netfilter.h>
index 330609a76fb202f7f8c54d2c695f16df3016f118..7dfc5343dae46f3d117092667272175de9346819 100644 (file)
@@ -904,6 +904,9 @@ static void nft_payload_set_eval(const struct nft_expr *expr,
            ((priv->base != NFT_PAYLOAD_TRANSPORT_HEADER &&
              priv->base != NFT_PAYLOAD_INNER_HEADER) ||
             skb->ip_summed != CHECKSUM_PARTIAL)) {
+               if (offset + priv->len > skb->len)
+                       goto err;
+
                fsum = skb_checksum(skb, offset, priv->len, 0);
                tsum = csum_partial(src, priv->len, 0);
 
index da5d929c7c85bfd066aa783ae441149e581dbbef..709840612f0dfdc812c3da4a0007c27196e4c866 100644 (file)
@@ -1269,7 +1269,7 @@ struct xt_table *xt_find_table_lock(struct net *net, u_int8_t af,
 
        /* and once again: */
        list_for_each_entry(t, &xt_net->tables[af], list)
-               if (strcmp(t->name, name) == 0)
+               if (strcmp(t->name, name) == 0 && owner == t->me)
                        return t;
 
        module_put(owner);
index c8a639f561684107cdab4332b6c3aff30e81fdb1..9d99f5a3d1764bd84e3e04d2aca739840b0b51da 100644 (file)
@@ -63,24 +63,37 @@ static int checksum_tg_check(const struct xt_tgchk_param *par)
        return 0;
 }
 
-static struct xt_target checksum_tg_reg __read_mostly = {
-       .name           = "CHECKSUM",
-       .family         = NFPROTO_UNSPEC,
-       .target         = checksum_tg,
-       .targetsize     = sizeof(struct xt_CHECKSUM_info),
-       .table          = "mangle",
-       .checkentry     = checksum_tg_check,
-       .me             = THIS_MODULE,
+static struct xt_target checksum_tg_reg[] __read_mostly = {
+       {
+               .name           = "CHECKSUM",
+               .family         = NFPROTO_IPV4,
+               .target         = checksum_tg,
+               .targetsize     = sizeof(struct xt_CHECKSUM_info),
+               .table          = "mangle",
+               .checkentry     = checksum_tg_check,
+               .me             = THIS_MODULE,
+       },
+#if IS_ENABLED(CONFIG_IP6_NF_IPTABLES)
+       {
+               .name           = "CHECKSUM",
+               .family         = NFPROTO_IPV6,
+               .target         = checksum_tg,
+               .targetsize     = sizeof(struct xt_CHECKSUM_info),
+               .table          = "mangle",
+               .checkentry     = checksum_tg_check,
+               .me             = THIS_MODULE,
+       },
+#endif
 };
 
 static int __init checksum_tg_init(void)
 {
-       return xt_register_target(&checksum_tg_reg);
+       return xt_register_targets(checksum_tg_reg, ARRAY_SIZE(checksum_tg_reg));
 }
 
 static void __exit checksum_tg_exit(void)
 {
-       xt_unregister_target(&checksum_tg_reg);
+       xt_unregister_targets(checksum_tg_reg, ARRAY_SIZE(checksum_tg_reg));
 }
 
 module_init(checksum_tg_init);
index 0accac98dea784d48d764794b872669019721dfb..0ae8d8a1216e1921c6e8bfa91cd6a8246c48f337 100644 (file)
@@ -38,9 +38,9 @@ static struct xt_target classify_tg_reg[] __read_mostly = {
        {
                .name       = "CLASSIFY",
                .revision   = 0,
-               .family     = NFPROTO_UNSPEC,
+               .family     = NFPROTO_IPV4,
                .hooks      = (1 << NF_INET_LOCAL_OUT) | (1 << NF_INET_FORWARD) |
-                             (1 << NF_INET_POST_ROUTING),
+                             (1 << NF_INET_POST_ROUTING),
                .target     = classify_tg,
                .targetsize = sizeof(struct xt_classify_target_info),
                .me         = THIS_MODULE,
@@ -54,6 +54,18 @@ static struct xt_target classify_tg_reg[] __read_mostly = {
                .targetsize = sizeof(struct xt_classify_target_info),
                .me         = THIS_MODULE,
        },
+#if IS_ENABLED(CONFIG_IP6_NF_IPTABLES)
+       {
+               .name       = "CLASSIFY",
+               .revision   = 0,
+               .family     = NFPROTO_IPV6,
+               .hooks      = (1 << NF_INET_LOCAL_OUT) | (1 << NF_INET_FORWARD) |
+                             (1 << NF_INET_POST_ROUTING),
+               .target     = classify_tg,
+               .targetsize = sizeof(struct xt_classify_target_info),
+               .me         = THIS_MODULE,
+       },
+#endif
 };
 
 static int __init classify_tg_init(void)
index 76acecf3e757a0fe4687f06ea2781661defac396..1494b3ee30e11e46b7abc5761c44a787c9dfd7bc 100644 (file)
@@ -114,25 +114,39 @@ static void connsecmark_tg_destroy(const struct xt_tgdtor_param *par)
        nf_ct_netns_put(par->net, par->family);
 }
 
-static struct xt_target connsecmark_tg_reg __read_mostly = {
-       .name       = "CONNSECMARK",
-       .revision   = 0,
-       .family     = NFPROTO_UNSPEC,
-       .checkentry = connsecmark_tg_check,
-       .destroy    = connsecmark_tg_destroy,
-       .target     = connsecmark_tg,
-       .targetsize = sizeof(struct xt_connsecmark_target_info),
-       .me         = THIS_MODULE,
+static struct xt_target connsecmark_tg_reg[] __read_mostly = {
+       {
+               .name       = "CONNSECMARK",
+               .revision   = 0,
+               .family     = NFPROTO_IPV4,
+               .checkentry = connsecmark_tg_check,
+               .destroy    = connsecmark_tg_destroy,
+               .target     = connsecmark_tg,
+               .targetsize = sizeof(struct xt_connsecmark_target_info),
+               .me         = THIS_MODULE,
+       },
+#if IS_ENABLED(CONFIG_IP6_NF_IPTABLES)
+       {
+               .name       = "CONNSECMARK",
+               .revision   = 0,
+               .family     = NFPROTO_IPV6,
+               .checkentry = connsecmark_tg_check,
+               .destroy    = connsecmark_tg_destroy,
+               .target     = connsecmark_tg,
+               .targetsize = sizeof(struct xt_connsecmark_target_info),
+               .me         = THIS_MODULE,
+       },
+#endif
 };
 
 static int __init connsecmark_tg_init(void)
 {
-       return xt_register_target(&connsecmark_tg_reg);
+       return xt_register_targets(connsecmark_tg_reg, ARRAY_SIZE(connsecmark_tg_reg));
 }
 
 static void __exit connsecmark_tg_exit(void)
 {
-       xt_unregister_target(&connsecmark_tg_reg);
+       xt_unregister_targets(connsecmark_tg_reg, ARRAY_SIZE(connsecmark_tg_reg));
 }
 
 module_init(connsecmark_tg_init);
index 2be2f7a7b60f4ec1d5bd5dfa4fc3a656825321ef..3ba94c34297cf5e24bfd7bcbce6b6977bd7204c2 100644 (file)
@@ -313,10 +313,30 @@ static void xt_ct_tg_destroy_v1(const struct xt_tgdtor_param *par)
        xt_ct_tg_destroy(par, par->targinfo);
 }
 
+static unsigned int
+notrack_tg(struct sk_buff *skb, const struct xt_action_param *par)
+{
+       /* Previously seen (loopback)? Ignore. */
+       if (skb->_nfct != 0)
+               return XT_CONTINUE;
+
+       nf_ct_set(skb, NULL, IP_CT_UNTRACKED);
+
+       return XT_CONTINUE;
+}
+
 static struct xt_target xt_ct_tg_reg[] __read_mostly = {
+       {
+               .name           = "NOTRACK",
+               .revision       = 0,
+               .family         = NFPROTO_IPV4,
+               .target         = notrack_tg,
+               .table          = "raw",
+               .me             = THIS_MODULE,
+       },
        {
                .name           = "CT",
-               .family         = NFPROTO_UNSPEC,
+               .family         = NFPROTO_IPV4,
                .targetsize     = sizeof(struct xt_ct_target_info),
                .usersize       = offsetof(struct xt_ct_target_info, ct),
                .checkentry     = xt_ct_tg_check_v0,
@@ -327,7 +347,7 @@ static struct xt_target xt_ct_tg_reg[] __read_mostly = {
        },
        {
                .name           = "CT",
-               .family         = NFPROTO_UNSPEC,
+               .family         = NFPROTO_IPV4,
                .revision       = 1,
                .targetsize     = sizeof(struct xt_ct_target_info_v1),
                .usersize       = offsetof(struct xt_ct_target_info, ct),
@@ -339,7 +359,7 @@ static struct xt_target xt_ct_tg_reg[] __read_mostly = {
        },
        {
                .name           = "CT",
-               .family         = NFPROTO_UNSPEC,
+               .family         = NFPROTO_IPV4,
                .revision       = 2,
                .targetsize     = sizeof(struct xt_ct_target_info_v1),
                .usersize       = offsetof(struct xt_ct_target_info, ct),
@@ -349,49 +369,61 @@ static struct xt_target xt_ct_tg_reg[] __read_mostly = {
                .table          = "raw",
                .me             = THIS_MODULE,
        },
-};
-
-static unsigned int
-notrack_tg(struct sk_buff *skb, const struct xt_action_param *par)
-{
-       /* Previously seen (loopback)? Ignore. */
-       if (skb->_nfct != 0)
-               return XT_CONTINUE;
-
-       nf_ct_set(skb, NULL, IP_CT_UNTRACKED);
-
-       return XT_CONTINUE;
-}
-
-static struct xt_target notrack_tg_reg __read_mostly = {
-       .name           = "NOTRACK",
-       .revision       = 0,
-       .family         = NFPROTO_UNSPEC,
-       .target         = notrack_tg,
-       .table          = "raw",
-       .me             = THIS_MODULE,
+#if IS_ENABLED(CONFIG_IP6_NF_IPTABLES)
+       {
+               .name           = "NOTRACK",
+               .revision       = 0,
+               .family         = NFPROTO_IPV6,
+               .target         = notrack_tg,
+               .table          = "raw",
+               .me             = THIS_MODULE,
+       },
+       {
+               .name           = "CT",
+               .family         = NFPROTO_IPV6,
+               .targetsize     = sizeof(struct xt_ct_target_info),
+               .usersize       = offsetof(struct xt_ct_target_info, ct),
+               .checkentry     = xt_ct_tg_check_v0,
+               .destroy        = xt_ct_tg_destroy_v0,
+               .target         = xt_ct_target_v0,
+               .table          = "raw",
+               .me             = THIS_MODULE,
+       },
+       {
+               .name           = "CT",
+               .family         = NFPROTO_IPV6,
+               .revision       = 1,
+               .targetsize     = sizeof(struct xt_ct_target_info_v1),
+               .usersize       = offsetof(struct xt_ct_target_info, ct),
+               .checkentry     = xt_ct_tg_check_v1,
+               .destroy        = xt_ct_tg_destroy_v1,
+               .target         = xt_ct_target_v1,
+               .table          = "raw",
+               .me             = THIS_MODULE,
+       },
+       {
+               .name           = "CT",
+               .family         = NFPROTO_IPV6,
+               .revision       = 2,
+               .targetsize     = sizeof(struct xt_ct_target_info_v1),
+               .usersize       = offsetof(struct xt_ct_target_info, ct),
+               .checkentry     = xt_ct_tg_check_v2,
+               .destroy        = xt_ct_tg_destroy_v1,
+               .target         = xt_ct_target_v1,
+               .table          = "raw",
+               .me             = THIS_MODULE,
+       },
+#endif
 };
 
 static int __init xt_ct_tg_init(void)
 {
-       int ret;
-
-       ret = xt_register_target(&notrack_tg_reg);
-       if (ret < 0)
-               return ret;
-
-       ret = xt_register_targets(xt_ct_tg_reg, ARRAY_SIZE(xt_ct_tg_reg));
-       if (ret < 0) {
-               xt_unregister_target(&notrack_tg_reg);
-               return ret;
-       }
-       return 0;
+       return xt_register_targets(xt_ct_tg_reg, ARRAY_SIZE(xt_ct_tg_reg));
 }
 
 static void __exit xt_ct_tg_exit(void)
 {
        xt_unregister_targets(xt_ct_tg_reg, ARRAY_SIZE(xt_ct_tg_reg));
-       xt_unregister_target(&notrack_tg_reg);
 }
 
 module_init(xt_ct_tg_init);
index db720efa811d58cb4dffa14fe0dccfa8dcb152c8..f8b25b6f5da7367d93b44a2fce4e9b32e1eeb1b5 100644 (file)
@@ -458,28 +458,49 @@ static void idletimer_tg_destroy_v1(const struct xt_tgdtor_param *par)
 
 static struct xt_target idletimer_tg[] __read_mostly = {
        {
-       .name           = "IDLETIMER",
-       .family         = NFPROTO_UNSPEC,
-       .target         = idletimer_tg_target,
-       .targetsize     = sizeof(struct idletimer_tg_info),
-       .usersize       = offsetof(struct idletimer_tg_info, timer),
-       .checkentry     = idletimer_tg_checkentry,
-       .destroy        = idletimer_tg_destroy,
-       .me             = THIS_MODULE,
+               .name           = "IDLETIMER",
+               .family         = NFPROTO_IPV4,
+               .target         = idletimer_tg_target,
+               .targetsize     = sizeof(struct idletimer_tg_info),
+               .usersize       = offsetof(struct idletimer_tg_info, timer),
+               .checkentry     = idletimer_tg_checkentry,
+               .destroy        = idletimer_tg_destroy,
+               .me             = THIS_MODULE,
        },
        {
-       .name           = "IDLETIMER",
-       .family         = NFPROTO_UNSPEC,
-       .revision       = 1,
-       .target         = idletimer_tg_target_v1,
-       .targetsize     = sizeof(struct idletimer_tg_info_v1),
-       .usersize       = offsetof(struct idletimer_tg_info_v1, timer),
-       .checkentry     = idletimer_tg_checkentry_v1,
-       .destroy        = idletimer_tg_destroy_v1,
-       .me             = THIS_MODULE,
+               .name           = "IDLETIMER",
+               .family         = NFPROTO_IPV4,
+               .revision       = 1,
+               .target         = idletimer_tg_target_v1,
+               .targetsize     = sizeof(struct idletimer_tg_info_v1),
+               .usersize       = offsetof(struct idletimer_tg_info_v1, timer),
+               .checkentry     = idletimer_tg_checkentry_v1,
+               .destroy        = idletimer_tg_destroy_v1,
+               .me             = THIS_MODULE,
        },
-
-
+#if IS_ENABLED(CONFIG_IP6_NF_IPTABLES)
+       {
+               .name           = "IDLETIMER",
+               .family         = NFPROTO_IPV6,
+               .target         = idletimer_tg_target,
+               .targetsize     = sizeof(struct idletimer_tg_info),
+               .usersize       = offsetof(struct idletimer_tg_info, timer),
+               .checkentry     = idletimer_tg_checkentry,
+               .destroy        = idletimer_tg_destroy,
+               .me             = THIS_MODULE,
+       },
+       {
+               .name           = "IDLETIMER",
+               .family         = NFPROTO_IPV6,
+               .revision       = 1,
+               .target         = idletimer_tg_target_v1,
+               .targetsize     = sizeof(struct idletimer_tg_info_v1),
+               .usersize       = offsetof(struct idletimer_tg_info_v1, timer),
+               .checkentry     = idletimer_tg_checkentry_v1,
+               .destroy        = idletimer_tg_destroy_v1,
+               .me             = THIS_MODULE,
+       },
+#endif
 };
 
 static struct class *idletimer_tg_class;
index 36c9720ad8d6d4360960d5de495a626d0f73dbfe..f7b0286d106ac1368baceb7809348213c266f34f 100644 (file)
@@ -175,26 +175,41 @@ static void led_tg_destroy(const struct xt_tgdtor_param *par)
        kfree(ledinternal);
 }
 
-static struct xt_target led_tg_reg __read_mostly = {
-       .name           = "LED",
-       .revision       = 0,
-       .family         = NFPROTO_UNSPEC,
-       .target         = led_tg,
-       .targetsize     = sizeof(struct xt_led_info),
-       .usersize       = offsetof(struct xt_led_info, internal_data),
-       .checkentry     = led_tg_check,
-       .destroy        = led_tg_destroy,
-       .me             = THIS_MODULE,
+static struct xt_target led_tg_reg[] __read_mostly = {
+       {
+               .name           = "LED",
+               .revision       = 0,
+               .family         = NFPROTO_IPV4,
+               .target         = led_tg,
+               .targetsize     = sizeof(struct xt_led_info),
+               .usersize       = offsetof(struct xt_led_info, internal_data),
+               .checkentry     = led_tg_check,
+               .destroy        = led_tg_destroy,
+               .me             = THIS_MODULE,
+       },
+#if IS_ENABLED(CONFIG_IP6_NF_IPTABLES)
+       {
+               .name           = "LED",
+               .revision       = 0,
+               .family         = NFPROTO_IPV6,
+               .target         = led_tg,
+               .targetsize     = sizeof(struct xt_led_info),
+               .usersize       = offsetof(struct xt_led_info, internal_data),
+               .checkentry     = led_tg_check,
+               .destroy        = led_tg_destroy,
+               .me             = THIS_MODULE,
+       },
+#endif
 };
 
 static int __init led_tg_init(void)
 {
-       return xt_register_target(&led_tg_reg);
+       return xt_register_targets(led_tg_reg, ARRAY_SIZE(led_tg_reg));
 }
 
 static void __exit led_tg_exit(void)
 {
-       xt_unregister_target(&led_tg_reg);
+       xt_unregister_targets(led_tg_reg, ARRAY_SIZE(led_tg_reg));
 }
 
 module_init(led_tg_init);
index e660c3710a10968909b98b5236536996cbb8462b..6dcf4bc7e30b2ae364a1cd9ac8df954a90905c52 100644 (file)
@@ -64,25 +64,39 @@ static void nflog_tg_destroy(const struct xt_tgdtor_param *par)
        nf_logger_put(par->family, NF_LOG_TYPE_ULOG);
 }
 
-static struct xt_target nflog_tg_reg __read_mostly = {
-       .name       = "NFLOG",
-       .revision   = 0,
-       .family     = NFPROTO_UNSPEC,
-       .checkentry = nflog_tg_check,
-       .destroy    = nflog_tg_destroy,
-       .target     = nflog_tg,
-       .targetsize = sizeof(struct xt_nflog_info),
-       .me         = THIS_MODULE,
+static struct xt_target nflog_tg_reg[] __read_mostly = {
+       {
+               .name       = "NFLOG",
+               .revision   = 0,
+               .family     = NFPROTO_IPV4,
+               .checkentry = nflog_tg_check,
+               .destroy    = nflog_tg_destroy,
+               .target     = nflog_tg,
+               .targetsize = sizeof(struct xt_nflog_info),
+               .me         = THIS_MODULE,
+       },
+#if IS_ENABLED(CONFIG_IP6_NF_IPTABLES)
+       {
+               .name       = "NFLOG",
+               .revision   = 0,
+               .family     = NFPROTO_IPV6,
+               .checkentry = nflog_tg_check,
+               .destroy    = nflog_tg_destroy,
+               .target     = nflog_tg,
+               .targetsize = sizeof(struct xt_nflog_info),
+               .me         = THIS_MODULE,
+       },
+#endif
 };
 
 static int __init nflog_tg_init(void)
 {
-       return xt_register_target(&nflog_tg_reg);
+       return xt_register_targets(nflog_tg_reg, ARRAY_SIZE(nflog_tg_reg));
 }
 
 static void __exit nflog_tg_exit(void)
 {
-       xt_unregister_target(&nflog_tg_reg);
+       xt_unregister_targets(nflog_tg_reg, ARRAY_SIZE(nflog_tg_reg));
 }
 
 module_init(nflog_tg_init);
index 80f6624e23554b30090b4a86b763ad279f5e44ac..4f49cfc27831204b3ce05b6fa1fd724b9ce86e2f 100644 (file)
@@ -179,16 +179,31 @@ static void xt_rateest_tg_destroy(const struct xt_tgdtor_param *par)
        xt_rateest_put(par->net, info->est);
 }
 
-static struct xt_target xt_rateest_tg_reg __read_mostly = {
-       .name       = "RATEEST",
-       .revision   = 0,
-       .family     = NFPROTO_UNSPEC,
-       .target     = xt_rateest_tg,
-       .checkentry = xt_rateest_tg_checkentry,
-       .destroy    = xt_rateest_tg_destroy,
-       .targetsize = sizeof(struct xt_rateest_target_info),
-       .usersize   = offsetof(struct xt_rateest_target_info, est),
-       .me         = THIS_MODULE,
+static struct xt_target xt_rateest_tg_reg[] __read_mostly = {
+       {
+               .name       = "RATEEST",
+               .revision   = 0,
+               .family     = NFPROTO_IPV4,
+               .target     = xt_rateest_tg,
+               .checkentry = xt_rateest_tg_checkentry,
+               .destroy    = xt_rateest_tg_destroy,
+               .targetsize = sizeof(struct xt_rateest_target_info),
+               .usersize   = offsetof(struct xt_rateest_target_info, est),
+               .me         = THIS_MODULE,
+       },
+#if IS_ENABLED(CONFIG_IP6_NF_IPTABLES)
+       {
+               .name       = "RATEEST",
+               .revision   = 0,
+               .family     = NFPROTO_IPV6,
+               .target     = xt_rateest_tg,
+               .checkentry = xt_rateest_tg_checkentry,
+               .destroy    = xt_rateest_tg_destroy,
+               .targetsize = sizeof(struct xt_rateest_target_info),
+               .usersize   = offsetof(struct xt_rateest_target_info, est),
+               .me         = THIS_MODULE,
+       },
+#endif
 };
 
 static __net_init int xt_rateest_net_init(struct net *net)
@@ -214,12 +229,12 @@ static int __init xt_rateest_tg_init(void)
 
        if (err)
                return err;
-       return xt_register_target(&xt_rateest_tg_reg);
+       return xt_register_targets(xt_rateest_tg_reg, ARRAY_SIZE(xt_rateest_tg_reg));
 }
 
 static void __exit xt_rateest_tg_fini(void)
 {
-       xt_unregister_target(&xt_rateest_tg_reg);
+       xt_unregister_targets(xt_rateest_tg_reg, ARRAY_SIZE(xt_rateest_tg_reg));
        unregister_pernet_subsys(&xt_rateest_net_ops);
 }
 
index 498a0bf6f0444a80dd88f05299bf0a7b505dd587..5bc5ea505eb9e02e95d1175e8f2094f2cd5ea3b8 100644 (file)
@@ -157,7 +157,7 @@ static struct xt_target secmark_tg_reg[] __read_mostly = {
        {
                .name           = "SECMARK",
                .revision       = 0,
-               .family         = NFPROTO_UNSPEC,
+               .family         = NFPROTO_IPV4,
                .checkentry     = secmark_tg_check_v0,
                .destroy        = secmark_tg_destroy,
                .target         = secmark_tg_v0,
@@ -167,7 +167,7 @@ static struct xt_target secmark_tg_reg[] __read_mostly = {
        {
                .name           = "SECMARK",
                .revision       = 1,
-               .family         = NFPROTO_UNSPEC,
+               .family         = NFPROTO_IPV4,
                .checkentry     = secmark_tg_check_v1,
                .destroy        = secmark_tg_destroy,
                .target         = secmark_tg_v1,
@@ -175,6 +175,29 @@ static struct xt_target secmark_tg_reg[] __read_mostly = {
                .usersize       = offsetof(struct xt_secmark_target_info_v1, secid),
                .me             = THIS_MODULE,
        },
+#if IS_ENABLED(CONFIG_IP6_NF_IPTABLES)
+       {
+               .name           = "SECMARK",
+               .revision       = 0,
+               .family         = NFPROTO_IPV6,
+               .checkentry     = secmark_tg_check_v0,
+               .destroy        = secmark_tg_destroy,
+               .target         = secmark_tg_v0,
+               .targetsize     = sizeof(struct xt_secmark_target_info),
+               .me             = THIS_MODULE,
+       },
+       {
+               .name           = "SECMARK",
+               .revision       = 1,
+               .family         = NFPROTO_IPV6,
+               .checkentry     = secmark_tg_check_v1,
+               .destroy        = secmark_tg_destroy,
+               .target         = secmark_tg_v1,
+               .targetsize     = sizeof(struct xt_secmark_target_info_v1),
+               .usersize       = offsetof(struct xt_secmark_target_info_v1, secid),
+               .me             = THIS_MODULE,
+       },
+#endif
 };
 
 static int __init secmark_tg_init(void)
index 5582dce98cae7d0796988d30e4b4e8e6832d6452..a642ff09fc8e8cff04fb53b9a6c97b10d68d1bad 100644 (file)
@@ -29,25 +29,39 @@ trace_tg(struct sk_buff *skb, const struct xt_action_param *par)
        return XT_CONTINUE;
 }
 
-static struct xt_target trace_tg_reg __read_mostly = {
-       .name           = "TRACE",
-       .revision       = 0,
-       .family         = NFPROTO_UNSPEC,
-       .table          = "raw",
-       .target         = trace_tg,
-       .checkentry     = trace_tg_check,
-       .destroy        = trace_tg_destroy,
-       .me             = THIS_MODULE,
+static struct xt_target trace_tg_reg[] __read_mostly = {
+       {
+               .name           = "TRACE",
+               .revision       = 0,
+               .family         = NFPROTO_IPV4,
+               .table          = "raw",
+               .target         = trace_tg,
+               .checkentry     = trace_tg_check,
+               .destroy        = trace_tg_destroy,
+               .me             = THIS_MODULE,
+       },
+#if IS_ENABLED(CONFIG_IP6_NF_IPTABLES)
+       {
+               .name           = "TRACE",
+               .revision       = 0,
+               .family         = NFPROTO_IPV6,
+               .table          = "raw",
+               .target         = trace_tg,
+               .checkentry     = trace_tg_check,
+               .destroy        = trace_tg_destroy,
+               .me             = THIS_MODULE,
+       },
+#endif
 };
 
 static int __init trace_tg_init(void)
 {
-       return xt_register_target(&trace_tg_reg);
+       return xt_register_targets(trace_tg_reg, ARRAY_SIZE(trace_tg_reg));
 }
 
 static void __exit trace_tg_exit(void)
 {
-       xt_unregister_target(&trace_tg_reg);
+       xt_unregister_targets(trace_tg_reg, ARRAY_SIZE(trace_tg_reg));
 }
 
 module_init(trace_tg_init);
index e9b2181e8c425f24ab580ad6ff6856b8e7fd98f3..a7708894310716f154d6c66da5ce30a909d509eb 100644 (file)
@@ -208,13 +208,24 @@ static struct xt_match addrtype_mt_reg[] __read_mostly = {
        },
        {
                .name           = "addrtype",
-               .family         = NFPROTO_UNSPEC,
+               .family         = NFPROTO_IPV4,
                .revision       = 1,
                .match          = addrtype_mt_v1,
                .checkentry     = addrtype_mt_checkentry_v1,
                .matchsize      = sizeof(struct xt_addrtype_info_v1),
                .me             = THIS_MODULE
-       }
+       },
+#if IS_ENABLED(CONFIG_IP6_NF_IPTABLES)
+       {
+               .name           = "addrtype",
+               .family         = NFPROTO_IPV6,
+               .revision       = 1,
+               .match          = addrtype_mt_v1,
+               .checkentry     = addrtype_mt_checkentry_v1,
+               .matchsize      = sizeof(struct xt_addrtype_info_v1),
+               .me             = THIS_MODULE
+       },
+#endif
 };
 
 static int __init addrtype_mt_init(void)
index a047a545371e18cbfa17a182ec3457a4ade2fd75..908fd5f2c3c84814a35390cd96e53a43e3759468 100644 (file)
@@ -146,24 +146,37 @@ static void xt_cluster_mt_destroy(const struct xt_mtdtor_param *par)
        nf_ct_netns_put(par->net, par->family);
 }
 
-static struct xt_match xt_cluster_match __read_mostly = {
-       .name           = "cluster",
-       .family         = NFPROTO_UNSPEC,
-       .match          = xt_cluster_mt,
-       .checkentry     = xt_cluster_mt_checkentry,
-       .matchsize      = sizeof(struct xt_cluster_match_info),
-       .destroy        = xt_cluster_mt_destroy,
-       .me             = THIS_MODULE,
+static struct xt_match xt_cluster_match[] __read_mostly = {
+       {
+               .name           = "cluster",
+               .family         = NFPROTO_IPV4,
+               .match          = xt_cluster_mt,
+               .checkentry     = xt_cluster_mt_checkentry,
+               .matchsize      = sizeof(struct xt_cluster_match_info),
+               .destroy        = xt_cluster_mt_destroy,
+               .me             = THIS_MODULE,
+       },
+#if IS_ENABLED(CONFIG_IP6_NF_IPTABLES)
+       {
+               .name           = "cluster",
+               .family         = NFPROTO_IPV6,
+               .match          = xt_cluster_mt,
+               .checkentry     = xt_cluster_mt_checkentry,
+               .matchsize      = sizeof(struct xt_cluster_match_info),
+               .destroy        = xt_cluster_mt_destroy,
+               .me             = THIS_MODULE,
+       },
+#endif
 };
 
 static int __init xt_cluster_mt_init(void)
 {
-       return xt_register_match(&xt_cluster_match);
+       return xt_register_matches(xt_cluster_match, ARRAY_SIZE(xt_cluster_match));
 }
 
 static void __exit xt_cluster_mt_fini(void)
 {
-       xt_unregister_match(&xt_cluster_match);
+       xt_unregister_matches(xt_cluster_match, ARRAY_SIZE(xt_cluster_match));
 }
 
 MODULE_AUTHOR("Pablo Neira Ayuso <[email protected]>");
index 93cb018c3055f8fb660a2558fd86cac07285d47b..2aabdcea8707236244984357c0d079acc5ffcb39 100644 (file)
@@ -111,9 +111,11 @@ static int connbytes_mt_check(const struct xt_mtchk_param *par)
                return -EINVAL;
 
        ret = nf_ct_netns_get(par->net, par->family);
-       if (ret < 0)
+       if (ret < 0) {
                pr_info_ratelimited("cannot load conntrack support for proto=%u\n",
                                    par->family);
+               return ret;
+       }
 
        /*
         * This filter cannot function correctly unless connection tracking
index 0e762277bcf8f95ec0c9e35ec645f6e7af048609..0189f8b6b0bd15e7b0714de41359964b6e6990aa 100644 (file)
@@ -117,26 +117,41 @@ static void connlimit_mt_destroy(const struct xt_mtdtor_param *par)
        nf_ct_netns_put(par->net, par->family);
 }
 
-static struct xt_match connlimit_mt_reg __read_mostly = {
-       .name       = "connlimit",
-       .revision   = 1,
-       .family     = NFPROTO_UNSPEC,
-       .checkentry = connlimit_mt_check,
-       .match      = connlimit_mt,
-       .matchsize  = sizeof(struct xt_connlimit_info),
-       .usersize   = offsetof(struct xt_connlimit_info, data),
-       .destroy    = connlimit_mt_destroy,
-       .me         = THIS_MODULE,
+static struct xt_match connlimit_mt_reg[] __read_mostly = {
+       {
+               .name       = "connlimit",
+               .revision   = 1,
+               .family     = NFPROTO_IPV4,
+               .checkentry = connlimit_mt_check,
+               .match      = connlimit_mt,
+               .matchsize  = sizeof(struct xt_connlimit_info),
+               .usersize   = offsetof(struct xt_connlimit_info, data),
+               .destroy    = connlimit_mt_destroy,
+               .me         = THIS_MODULE,
+       },
+#if IS_ENABLED(CONFIG_IP6_NF_IPTABLES)
+       {
+               .name       = "connlimit",
+               .revision   = 1,
+               .family     = NFPROTO_IPV6,
+               .checkentry = connlimit_mt_check,
+               .match      = connlimit_mt,
+               .matchsize  = sizeof(struct xt_connlimit_info),
+               .usersize   = offsetof(struct xt_connlimit_info, data),
+               .destroy    = connlimit_mt_destroy,
+               .me         = THIS_MODULE,
+       },
+#endif
 };
 
 static int __init connlimit_mt_init(void)
 {
-       return xt_register_match(&connlimit_mt_reg);
+       return xt_register_matches(connlimit_mt_reg, ARRAY_SIZE(connlimit_mt_reg));
 }
 
 static void __exit connlimit_mt_exit(void)
 {
-       xt_unregister_match(&connlimit_mt_reg);
+       xt_unregister_matches(connlimit_mt_reg, ARRAY_SIZE(connlimit_mt_reg));
 }
 
 module_init(connlimit_mt_init);
index ad3c033db64e70dd642a63e9b48914fc0ac12cb9..4277084de2e70c995f49cadd411cab70473b3ad9 100644 (file)
@@ -151,7 +151,7 @@ static struct xt_target connmark_tg_reg[] __read_mostly = {
        {
                .name           = "CONNMARK",
                .revision       = 1,
-               .family         = NFPROTO_UNSPEC,
+               .family         = NFPROTO_IPV4,
                .checkentry     = connmark_tg_check,
                .target         = connmark_tg,
                .targetsize     = sizeof(struct xt_connmark_tginfo1),
@@ -161,13 +161,35 @@ static struct xt_target connmark_tg_reg[] __read_mostly = {
        {
                .name           = "CONNMARK",
                .revision       = 2,
-               .family         = NFPROTO_UNSPEC,
+               .family         = NFPROTO_IPV4,
                .checkentry     = connmark_tg_check,
                .target         = connmark_tg_v2,
                .targetsize     = sizeof(struct xt_connmark_tginfo2),
                .destroy        = connmark_tg_destroy,
                .me             = THIS_MODULE,
-       }
+       },
+#if IS_ENABLED(CONFIG_IP6_NF_IPTABLES)
+       {
+               .name           = "CONNMARK",
+               .revision       = 1,
+               .family         = NFPROTO_IPV6,
+               .checkentry     = connmark_tg_check,
+               .target         = connmark_tg,
+               .targetsize     = sizeof(struct xt_connmark_tginfo1),
+               .destroy        = connmark_tg_destroy,
+               .me             = THIS_MODULE,
+       },
+       {
+               .name           = "CONNMARK",
+               .revision       = 2,
+               .family         = NFPROTO_IPV6,
+               .checkentry     = connmark_tg_check,
+               .target         = connmark_tg_v2,
+               .targetsize     = sizeof(struct xt_connmark_tginfo2),
+               .destroy        = connmark_tg_destroy,
+               .me             = THIS_MODULE,
+       },
+#endif
 };
 
 static struct xt_match connmark_mt_reg __read_mostly = {
index 1ad74b5920b533abb1a1814b1fd0c86511433022..65b965ca40ea7ea5d9feff381b433bf267a424c4 100644 (file)
@@ -39,13 +39,35 @@ mark_mt(const struct sk_buff *skb, struct xt_action_param *par)
        return ((skb->mark & info->mask) == info->mark) ^ info->invert;
 }
 
-static struct xt_target mark_tg_reg __read_mostly = {
-       .name           = "MARK",
-       .revision       = 2,
-       .family         = NFPROTO_UNSPEC,
-       .target         = mark_tg,
-       .targetsize     = sizeof(struct xt_mark_tginfo2),
-       .me             = THIS_MODULE,
+static struct xt_target mark_tg_reg[] __read_mostly = {
+       {
+               .name           = "MARK",
+               .revision       = 2,
+               .family         = NFPROTO_IPV4,
+               .target         = mark_tg,
+               .targetsize     = sizeof(struct xt_mark_tginfo2),
+               .me             = THIS_MODULE,
+       },
+#if IS_ENABLED(CONFIG_IP_NF_ARPTABLES)
+       {
+               .name           = "MARK",
+               .revision       = 2,
+               .family         = NFPROTO_ARP,
+               .target         = mark_tg,
+               .targetsize     = sizeof(struct xt_mark_tginfo2),
+               .me             = THIS_MODULE,
+       },
+#endif
+#if IS_ENABLED(CONFIG_IP6_NF_IPTABLES)
+       {
+               .name           = "MARK",
+               .revision       = 2,
+               .family         = NFPROTO_IPV6,
+               .target         = mark_tg,
+               .targetsize     = sizeof(struct xt_mark_tginfo2),
+               .me             = THIS_MODULE,
+       },
+#endif
 };
 
 static struct xt_match mark_mt_reg __read_mostly = {
@@ -61,12 +83,12 @@ static int __init mark_mt_init(void)
 {
        int ret;
 
-       ret = xt_register_target(&mark_tg_reg);
+       ret = xt_register_targets(mark_tg_reg, ARRAY_SIZE(mark_tg_reg));
        if (ret < 0)
                return ret;
        ret = xt_register_match(&mark_mt_reg);
        if (ret < 0) {
-               xt_unregister_target(&mark_tg_reg);
+               xt_unregister_targets(mark_tg_reg, ARRAY_SIZE(mark_tg_reg));
                return ret;
        }
        return 0;
@@ -75,7 +97,7 @@ static int __init mark_mt_init(void)
 static void __exit mark_mt_exit(void)
 {
        xt_unregister_match(&mark_mt_reg);
-       xt_unregister_target(&mark_tg_reg);
+       xt_unregister_targets(mark_tg_reg, ARRAY_SIZE(mark_tg_reg));
 }
 
 module_init(mark_mt_init);
index 0b7a89db3ab74e13837ec697d0343cd9839f38b1..0a9287fadb47a2afaf0babe675738bc43051c5a7 100644 (file)
@@ -2136,8 +2136,9 @@ void __netlink_clear_multicast_users(struct sock *ksk, unsigned int group)
 {
        struct sock *sk;
        struct netlink_table *tbl = &nl_table[ksk->sk_protocol];
+       struct hlist_node *tmp;
 
-       sk_for_each_bound(sk, &tbl->mc_list)
+       sk_for_each_bound_safe(sk, tmp, &tbl->mc_list)
                netlink_update_socket_mc(nlk_sk(sk), group, 0);
 }
 
index feb54c63a1165f25bdeb95daa11080374ad91761..07ad65774fe298a1fea8e67413521252fc31ed20 100644 (file)
@@ -1501,15 +1501,11 @@ static int genl_ctrl_event(int event, const struct genl_family *family,
        if (IS_ERR(msg))
                return PTR_ERR(msg);
 
-       if (!family->netnsok) {
+       if (!family->netnsok)
                genlmsg_multicast_netns(&genl_ctrl, &init_net, msg, 0,
                                        0, GFP_KERNEL);
-       } else {
-               rcu_read_lock();
-               genlmsg_multicast_allns(&genl_ctrl, msg, 0,
-                                       0, GFP_ATOMIC);
-               rcu_read_unlock();
-       }
+       else
+               genlmsg_multicast_allns(&genl_ctrl, msg, 0, 0);
 
        return 0;
 }
@@ -1929,23 +1925,23 @@ problem:
 
 core_initcall(genl_init);
 
-static int genlmsg_mcast(struct sk_buff *skb, u32 portid, unsigned long group,
-                        gfp_t flags)
+static int genlmsg_mcast(struct sk_buff *skb, u32 portid, unsigned long group)
 {
        struct sk_buff *tmp;
        struct net *net, *prev = NULL;
        bool delivered = false;
        int err;
 
+       rcu_read_lock();
        for_each_net_rcu(net) {
                if (prev) {
-                       tmp = skb_clone(skb, flags);
+                       tmp = skb_clone(skb, GFP_ATOMIC);
                        if (!tmp) {
                                err = -ENOMEM;
                                goto error;
                        }
                        err = nlmsg_multicast(prev->genl_sock, tmp,
-                                             portid, group, flags);
+                                             portid, group, GFP_ATOMIC);
                        if (!err)
                                delivered = true;
                        else if (err != -ESRCH)
@@ -1954,27 +1950,31 @@ static int genlmsg_mcast(struct sk_buff *skb, u32 portid, unsigned long group,
 
                prev = net;
        }
+       err = nlmsg_multicast(prev->genl_sock, skb, portid, group, GFP_ATOMIC);
+
+       rcu_read_unlock();
 
-       err = nlmsg_multicast(prev->genl_sock, skb, portid, group, flags);
        if (!err)
                delivered = true;
        else if (err != -ESRCH)
                return err;
        return delivered ? 0 : -ESRCH;
  error:
+       rcu_read_unlock();
+
        kfree_skb(skb);
        return err;
 }
 
 int genlmsg_multicast_allns(const struct genl_family *family,
                            struct sk_buff *skb, u32 portid,
-                           unsigned int group, gfp_t flags)
+                           unsigned int group)
 {
        if (WARN_ON_ONCE(group >= family->n_mcgrps))
                return -EINVAL;
 
        group = family->mcgrp_offset + group;
-       return genlmsg_mcast(skb, portid, group, flags);
+       return genlmsg_mcast(skb, portid, group);
 }
 EXPORT_SYMBOL(genlmsg_multicast_allns);
 
index 2b582da1e88c05720825197a72d20c12b243c333..a27efa4faa4ef46e64efe6744790c47ec34147ac 100644 (file)
@@ -13,7 +13,7 @@
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/slab.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include <net/sock.h>
 
 #include <linux/if_phonet.h>
index 7008d402499d5bb161128899b004b08d79569ec2..894e5c72d6bfff7e2b634b7f6d19d023da695e31 100644 (file)
@@ -285,23 +285,17 @@ static int route_dumpit(struct sk_buff *skb, struct netlink_callback *cb)
        return err;
 }
 
+static const struct rtnl_msg_handler phonet_rtnl_msg_handlers[] __initdata_or_module = {
+       {THIS_MODULE, PF_PHONET, RTM_NEWADDR, addr_doit, NULL, 0},
+       {THIS_MODULE, PF_PHONET, RTM_DELADDR, addr_doit, NULL, 0},
+       {THIS_MODULE, PF_PHONET, RTM_GETADDR, NULL, getaddr_dumpit, 0},
+       {THIS_MODULE, PF_PHONET, RTM_NEWROUTE, route_doit, NULL, 0},
+       {THIS_MODULE, PF_PHONET, RTM_DELROUTE, route_doit, NULL, 0},
+       {THIS_MODULE, PF_PHONET, RTM_GETROUTE, NULL, route_dumpit,
+        RTNL_FLAG_DUMP_UNLOCKED},
+};
+
 int __init phonet_netlink_register(void)
 {
-       int err = rtnl_register_module(THIS_MODULE, PF_PHONET, RTM_NEWADDR,
-                                      addr_doit, NULL, 0);
-       if (err)
-               return err;
-
-       /* Further rtnl_register_module() cannot fail */
-       rtnl_register_module(THIS_MODULE, PF_PHONET, RTM_DELADDR,
-                            addr_doit, NULL, 0);
-       rtnl_register_module(THIS_MODULE, PF_PHONET, RTM_GETADDR,
-                            NULL, getaddr_dumpit, 0);
-       rtnl_register_module(THIS_MODULE, PF_PHONET, RTM_NEWROUTE,
-                            route_doit, NULL, 0);
-       rtnl_register_module(THIS_MODULE, PF_PHONET, RTM_DELROUTE,
-                            route_doit, NULL, 0);
-       rtnl_register_module(THIS_MODULE, PF_PHONET, RTM_GETROUTE,
-                            NULL, route_dumpit, RTNL_FLAG_DUMP_UNLOCKED);
-       return 0;
+       return rtnl_register_many(phonet_rtnl_msg_handlers);
 }
index 80d682f89b23325237ad9527a3788d8eb1edd6a1..d0fd37bdcfe9c8653192b8c7d9f07a55e938fb90 100644 (file)
@@ -1056,7 +1056,7 @@ bool rxrpc_direct_abort(struct sk_buff *skb, enum rxrpc_abort_reason why,
 int rxrpc_io_thread(void *data);
 static inline void rxrpc_wake_up_io_thread(struct rxrpc_local *local)
 {
-       wake_up_process(local->io_thread);
+       wake_up_process(READ_ONCE(local->io_thread));
 }
 
 static inline bool rxrpc_protocol_error(struct sk_buff *skb, enum rxrpc_abort_reason why)
index 0300baa9afcd394278a202da512e5bc6bd2d4f71..07c74c77d80214b006c49b975ce73d3a46952708 100644 (file)
@@ -27,11 +27,17 @@ int rxrpc_encap_rcv(struct sock *udp_sk, struct sk_buff *skb)
 {
        struct sk_buff_head *rx_queue;
        struct rxrpc_local *local = rcu_dereference_sk_user_data(udp_sk);
+       struct task_struct *io_thread;
 
        if (unlikely(!local)) {
                kfree_skb(skb);
                return 0;
        }
+       io_thread = READ_ONCE(local->io_thread);
+       if (!io_thread) {
+               kfree_skb(skb);
+               return 0;
+       }
        if (skb->tstamp == 0)
                skb->tstamp = ktime_get_real();
 
@@ -47,7 +53,7 @@ int rxrpc_encap_rcv(struct sock *udp_sk, struct sk_buff *skb)
 #endif
 
        skb_queue_tail(rx_queue, skb);
-       rxrpc_wake_up_io_thread(local);
+       wake_up_process(io_thread);
        return 0;
 }
 
@@ -565,7 +571,7 @@ int rxrpc_io_thread(void *data)
        __set_current_state(TASK_RUNNING);
        rxrpc_see_local(local, rxrpc_local_stop);
        rxrpc_destroy_local(local);
-       local->io_thread = NULL;
+       WRITE_ONCE(local->io_thread, NULL);
        rxrpc_see_local(local, rxrpc_local_stopped);
        return 0;
 }
index 504453c688d751fe11cbfbe18e1d20c0623f9a77..f9623ace22016f622ce2b4a5ccfac0e5112cf741 100644 (file)
@@ -232,7 +232,7 @@ static int rxrpc_open_socket(struct rxrpc_local *local, struct net *net)
        }
 
        wait_for_completion(&local->io_thread_ready);
-       local->io_thread = io_thread;
+       WRITE_ONCE(local->io_thread, io_thread);
        _leave(" = 0");
        return 0;
 
index 894b8fa68e5e9546ad2dd17372420976d7eb76c0..23d18fe5de9f0d356c936b4ed80b24c18ddfeeb9 100644 (file)
@@ -303,6 +303,11 @@ static int rxrpc_send_data(struct rxrpc_sock *rx,
        sk_clear_bit(SOCKWQ_ASYNC_NOSPACE, sk);
 
 reload:
+       txb = call->tx_pending;
+       call->tx_pending = NULL;
+       if (txb)
+               rxrpc_see_txbuf(txb, rxrpc_txbuf_see_send_more);
+
        ret = -EPIPE;
        if (sk->sk_shutdown & SEND_SHUTDOWN)
                goto maybe_error;
@@ -329,11 +334,6 @@ reload:
                        goto maybe_error;
        }
 
-       txb = call->tx_pending;
-       call->tx_pending = NULL;
-       if (txb)
-               rxrpc_see_txbuf(txb, rxrpc_txbuf_see_send_more);
-
        do {
                if (!txb) {
                        size_t remain;
index 2714c4ed928e5adc668f5ecd40a0b53d03c13a4a..eecad65fec92ca9339e0d0c2848c02336824d564 100644 (file)
@@ -1498,8 +1498,29 @@ int tcf_action_init(struct net *net, struct tcf_proto *tp, struct nlattr *nla,
                        bool skip_sw = tc_skip_sw(fl_flags);
                        bool skip_hw = tc_skip_hw(fl_flags);
 
-                       if (tc_act_bind(act->tcfa_flags))
+                       if (tc_act_bind(act->tcfa_flags)) {
+                               /* Action is created by classifier and is not
+                                * standalone. Check that the user did not set
+                                * any action flags different than the
+                                * classifier flags, and inherit the flags from
+                                * the classifier for the compatibility case
+                                * where no flags were specified at all.
+                                */
+                               if ((tc_act_skip_sw(act->tcfa_flags) && !skip_sw) ||
+                                   (tc_act_skip_hw(act->tcfa_flags) && !skip_hw)) {
+                                       NL_SET_ERR_MSG(extack,
+                                                      "Mismatch between action and filter offload flags");
+                                       err = -EINVAL;
+                                       goto err;
+                               }
+                               if (skip_sw)
+                                       act->tcfa_flags |= TCA_ACT_FLAGS_SKIP_SW;
+                               if (skip_hw)
+                                       act->tcfa_flags |= TCA_ACT_FLAGS_SKIP_HW;
                                continue;
+                       }
+
+                       /* Action is standalone */
                        if (skip_sw != tc_act_skip_sw(act->tcfa_flags) ||
                            skip_hw != tc_act_skip_hw(act->tcfa_flags)) {
                                NL_SET_ERR_MSG(extack,
index 17d97bbe890fd519a9a24b57ec5eae8c353e20e1..bbc778c233c892eae5a4d8aac29630c0639fce4d 100644 (file)
@@ -1518,6 +1518,7 @@ int tcf_block_get_ext(struct tcf_block **p_block, struct Qdisc *q,
        return 0;
 
 err_dev_insert:
+       tcf_block_offload_unbind(block, q, ei);
 err_block_offload_bind:
        tcf_chain0_head_change_cb_del(block, ei);
 err_chain0_head_change_cb_add:
index c90ad7ea26b4697cbedf25a51fc1b92771040c4e..64b637f18bc7d40509bf5c9f7679cfbc2922af1c 100644 (file)
@@ -10,7 +10,7 @@
 #include <linux/kernel.h>
 #include <linux/skbuff.h>
 #include <linux/tc_ematch/tc_em_cmp.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include <net/pkt_cls.h>
 
 static inline int cmp_needs_transformation(struct tcf_em_cmp *cmp)
index 74afc210527d237cca3b48166be5918f802eb326..a1d27bc039a364d5088d0e1a9083bc61b0e267e9 100644 (file)
@@ -593,7 +593,6 @@ out:
                pkt_len = 1;
        qdisc_skb_cb(skb)->pkt_len = pkt_len;
 }
-EXPORT_SYMBOL(__qdisc_calculate_pkt_len);
 
 void qdisc_warn_nonwc(const char *txt, struct Qdisc *qdisc)
 {
@@ -792,7 +791,7 @@ void qdisc_tree_reduce_backlog(struct Qdisc *sch, int n, int len)
        drops = max_t(int, n, 0);
        rcu_read_lock();
        while ((parentid = sch->parent)) {
-               if (TC_H_MAJ(parentid) == TC_H_MAJ(TC_H_INGRESS))
+               if (parentid == TC_H_ROOT)
                        break;
 
                if (sch->flags & TCQ_F_NOPARENT)
@@ -1201,6 +1200,12 @@ skip:
                        return -EINVAL;
                }
 
+               if (new &&
+                   !(parent->flags & TCQ_F_MQROOT) &&
+                   rcu_access_pointer(new->stab)) {
+                       NL_SET_ERR_MSG(extack, "STAB not supported on a non root");
+                       return -EINVAL;
+               }
                err = cops->graft(parent, cl, new, &old, extack);
                if (err)
                        return err;
index 2af24547a82c49efc64528fd27087144c4f43b7c..38ec18f73de43aed565c653fffb838f54e7c824b 100644 (file)
@@ -512,9 +512,15 @@ static void dev_watchdog(struct timer_list *t)
                                struct netdev_queue *txq;
 
                                txq = netdev_get_tx_queue(dev, i);
-                               trans_start = READ_ONCE(txq->trans_start);
                                if (!netif_xmit_stopped(txq))
                                        continue;
+
+                               /* Paired with WRITE_ONCE() + smp_mb...() in
+                                * netdev_tx_sent_queue() and netif_tx_stop_queue().
+                                */
+                               smp_mb();
+                               trans_start = READ_ONCE(txq->trans_start);
+
                                if (time_after(jiffies, trans_start + dev->watchdog_timeo)) {
                                        timedout_ms = jiffies_to_msecs(jiffies - trans_start);
                                        atomic_long_inc(&txq->trans_timeout);
index 8498d0606b248b6e0aeb27950d07efc4bc2de441..8623dc0bafc09b1ab590976a0986d19d2e63a088 100644 (file)
@@ -1965,7 +1965,8 @@ static int taprio_change(struct Qdisc *sch, struct nlattr *opt,
 
                taprio_start_sched(sch, start, new_admin);
 
-               rcu_assign_pointer(q->admin_sched, new_admin);
+               admin = rcu_replace_pointer(q->admin_sched, new_admin,
+                                           lockdep_rtnl_is_held());
                if (admin)
                        call_rcu(&admin->rcu, taprio_free_sched_cb);
 
@@ -2373,9 +2374,6 @@ static int taprio_dump(struct Qdisc *sch, struct sk_buff *skb)
        struct tc_mqprio_qopt opt = { 0 };
        struct nlattr *nest, *sched_nest;
 
-       oper = rtnl_dereference(q->oper_sched);
-       admin = rtnl_dereference(q->admin_sched);
-
        mqprio_qopt_reconstruct(dev, &opt);
 
        nest = nla_nest_start_noflag(skb, TCA_OPTIONS);
@@ -2396,18 +2394,23 @@ static int taprio_dump(struct Qdisc *sch, struct sk_buff *skb)
            nla_put_u32(skb, TCA_TAPRIO_ATTR_TXTIME_DELAY, q->txtime_delay))
                goto options_error;
 
+       rcu_read_lock();
+
+       oper = rtnl_dereference(q->oper_sched);
+       admin = rtnl_dereference(q->admin_sched);
+
        if (oper && taprio_dump_tc_entries(skb, q, oper))
-               goto options_error;
+               goto options_error_rcu;
 
        if (oper && dump_schedule(skb, oper))
-               goto options_error;
+               goto options_error_rcu;
 
        if (!admin)
                goto done;
 
        sched_nest = nla_nest_start_noflag(skb, TCA_TAPRIO_ATTR_ADMIN_SCHED);
        if (!sched_nest)
-               goto options_error;
+               goto options_error_rcu;
 
        if (dump_schedule(skb, admin))
                goto admin_error;
@@ -2415,11 +2418,15 @@ static int taprio_dump(struct Qdisc *sch, struct sk_buff *skb)
        nla_nest_end(skb, sched_nest);
 
 done:
+       rcu_read_unlock();
        return nla_nest_end(skb, nest);
 
 admin_error:
        nla_nest_cancel(skb, sched_nest);
 
+options_error_rcu:
+       rcu_read_unlock();
+
 options_error:
        nla_nest_cancel(skb, nest);
 
index 32f76f1298da814ac90c270622e12aa3bcfe5f53..36ee34f483d703ffcfe5ca9e6cc554fba24c75ef 100644 (file)
@@ -8531,6 +8531,7 @@ static int sctp_listen_start(struct sock *sk, int backlog)
        struct sctp_endpoint *ep = sp->ep;
        struct crypto_shash *tfm = NULL;
        char alg[32];
+       int err;
 
        /* Allocate HMAC for generating cookie. */
        if (!sp->hmac && sp->sctp_hmac_alg) {
@@ -8557,17 +8558,26 @@ static int sctp_listen_start(struct sock *sk, int backlog)
         */
        inet_sk_set_state(sk, SCTP_SS_LISTENING);
        if (!ep->base.bind_addr.port) {
-               if (sctp_autobind(sk))
-                       return -EAGAIN;
+               if (sctp_autobind(sk)) {
+                       err = -EAGAIN;
+                       goto err;
+               }
        } else {
                if (sctp_get_port(sk, inet_sk(sk)->inet_num)) {
-                       inet_sk_set_state(sk, SCTP_SS_CLOSED);
-                       return -EADDRINUSE;
+                       err = -EADDRINUSE;
+                       goto err;
                }
        }
 
        WRITE_ONCE(sk->sk_max_ack_backlog, backlog);
-       return sctp_hash_endpoint(ep);
+       err = sctp_hash_endpoint(ep);
+       if (err)
+               goto err;
+
+       return 0;
+err:
+       inet_sk_set_state(sk, SCTP_SS_CLOSED);
+       return err;
 }
 
 /*
index a5b2041600f95958f5d2f85a6fa4601683279dcb..a944e7dcb8b9670f2351e489d78e85a25951a83f 100644 (file)
@@ -108,12 +108,23 @@ static struct inet_protosw smc_inet6_protosw = {
 };
 #endif /* CONFIG_IPV6 */
 
+static unsigned int smc_sync_mss(struct sock *sk, u32 pmtu)
+{
+       /* No need pass it through to clcsock, mss can always be set by
+        * sock_create_kern or smc_setsockopt.
+        */
+       return 0;
+}
+
 static int smc_inet_init_sock(struct sock *sk)
 {
        struct net *net = sock_net(sk);
 
        /* init common smc sock */
        smc_sk_init(net, sk, IPPROTO_SMC);
+
+       inet_csk(sk)->icsk_sync_mss = smc_sync_mss;
+
        /* create clcsock */
        return smc_create_clcsk(net, sk, sk->sk_family);
 }
index 1dd362326c0a8e220eb43122b05d6d8f4805eb1b..a04aa0e882f87d0f139b90f8c9d12e5d0ad5ac32 100644 (file)
@@ -753,7 +753,7 @@ static int smc_pnet_add_pnetid(struct net *net, u8 *pnetid)
 
        write_lock(&sn->pnetids_ndev.lock);
        list_for_each_entry(pi, &sn->pnetids_ndev.list, list) {
-               if (smc_pnet_match(pnetid, pe->pnetid)) {
+               if (smc_pnet_match(pnetid, pi->pnetid)) {
                        refcount_inc(&pi->refcnt);
                        kfree(pe);
                        goto unlock;
index 0021065a600a0379295d642d0830a757d043b894..994c0cd4fddbf17c92a2c99594e713bf4ce62a72 100644 (file)
@@ -648,8 +648,10 @@ void smc_wr_free_link(struct smc_link *lnk)
        smc_wr_tx_wait_no_pending_sends(lnk);
        percpu_ref_kill(&lnk->wr_reg_refs);
        wait_for_completion(&lnk->reg_ref_comp);
+       percpu_ref_exit(&lnk->wr_reg_refs);
        percpu_ref_kill(&lnk->wr_tx_refs);
        wait_for_completion(&lnk->tx_ref_comp);
+       percpu_ref_exit(&lnk->wr_tx_refs);
 
        if (lnk->wr_rx_dma_addr) {
                ib_dma_unmap_single(ibdev, lnk->wr_rx_dma_addr,
@@ -912,11 +914,13 @@ int smc_wr_create_link(struct smc_link *lnk)
        init_waitqueue_head(&lnk->wr_reg_wait);
        rc = percpu_ref_init(&lnk->wr_reg_refs, smcr_wr_reg_refs_free, 0, GFP_KERNEL);
        if (rc)
-               goto dma_unmap;
+               goto cancel_ref;
        init_completion(&lnk->reg_ref_comp);
        init_waitqueue_head(&lnk->wr_rx_empty_wait);
        return rc;
 
+cancel_ref:
+       percpu_ref_exit(&lnk->wr_tx_refs);
 dma_unmap:
        if (lnk->wr_rx_v2_dma_addr) {
                ib_dma_unmap_single(ibdev, lnk->wr_rx_v2_dma_addr,
index 601ad74930efb01384fa955a331d3221c4ff5f0e..042451f01c6520b85496213e6b3d8d2116ab2533 100644 (file)
@@ -1574,8 +1574,13 @@ int __sock_create(struct net *net, int family, int type, int protocol,
        rcu_read_unlock();
 
        err = pf->create(net, sock, protocol, kern);
-       if (err < 0)
+       if (err < 0) {
+               /* ->create should release the allocated sock->sk object on error
+                * but it may leave the dangling pointer
+                */
+               sock->sk = NULL;
                goto out_module_put;
+       }
 
        /*
         * Now to bump the refcnt of the [loadable] module that owns this
index 7e7f4e0390c7f017ade735f849776db0df9a088c..79879b7d39cb4f267b0d7ef54370bdaae83783d5 100644 (file)
@@ -1321,7 +1321,7 @@ static int
 svc_process_common(struct svc_rqst *rqstp)
 {
        struct xdr_stream       *xdr = &rqstp->rq_res_stream;
-       struct svc_program      *progp;
+       struct svc_program      *progp = NULL;
        const struct svc_procedure *procp = NULL;
        struct svc_serv         *serv = rqstp->rq_server;
        struct svc_process_info process;
@@ -1351,12 +1351,9 @@ svc_process_common(struct svc_rqst *rqstp)
        rqstp->rq_vers = be32_to_cpup(p++);
        rqstp->rq_proc = be32_to_cpup(p);
 
-       for (pr = 0; pr < serv->sv_nprogs; pr++) {
-               progp = &serv->sv_programs[pr];
-
-               if (rqstp->rq_prog == progp->pg_prog)
-                       break;
-       }
+       for (pr = 0; pr < serv->sv_nprogs; pr++)
+               if (rqstp->rq_prog == serv->sv_programs[pr].pg_prog)
+                       progp = &serv->sv_programs[pr];
 
        /*
         * Decode auth data, and add verifier to reply buffer.
index 8507cd4d892170dcaf166056e4013aa821c1fcee..28c68b5f682382ea2906e6c56db0793b313a5efc 100644 (file)
@@ -153,6 +153,7 @@ static void rpcrdma_remove_one(struct ib_device *device,
        }
 
        trace_rpcrdma_client_remove_one_done(device);
+       xa_destroy(&rd->rd_xa);
        kfree(rd);
 }
 
index d72953f29258273744b60723aedd0907c1d37772..ae3fb9bc8a21688a43324c7577aab880b048ee1f 100644 (file)
@@ -94,7 +94,7 @@
 
 #include <linux/slab.h>
 #include <linux/spinlock.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include <rdma/ib_verbs.h>
 #include <rdma/rdma_cm.h>
 
index bb5436b719e05126e250596b61b39230204620c3..96154a2367a1106f749dd42663375df3b4126bb8 100644 (file)
  */
 
 #include <linux/spinlock.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #include <rdma/ib_verbs.h>
 #include <rdma/rdma_cm.h>
index 9ba5f600ea43c88917e457e1cc594e8c3d9c042b..2d8ce4ff3265b5fab2ce5905f23c90e4cc2f5c09 100644 (file)
@@ -7,7 +7,7 @@
 #if !defined(_TLS_TRACE_H_) || defined(TRACE_HEADER_MULTI_READ)
 #define _TLS_TRACE_H_
 
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include <linux/tracepoint.h>
 
 struct sock;
index 85e4239217346b6ecf8020ddc3b9469455573348..b58c3818f284f19aeb303c3fa6193ab717a81d29 100644 (file)
@@ -96,7 +96,7 @@ out_rcu:
 
 /* Caller need to hold vsock->tx_lock on vq */
 static int virtio_transport_send_skb(struct sk_buff *skb, struct virtqueue *vq,
-                                    struct virtio_vsock *vsock)
+                                    struct virtio_vsock *vsock, gfp_t gfp)
 {
        int ret, in_sg = 0, out_sg = 0;
        struct scatterlist **sgs;
@@ -140,7 +140,7 @@ static int virtio_transport_send_skb(struct sk_buff *skb, struct virtqueue *vq,
                }
        }
 
-       ret = virtqueue_add_sgs(vq, sgs, out_sg, in_sg, skb, GFP_KERNEL);
+       ret = virtqueue_add_sgs(vq, sgs, out_sg, in_sg, skb, gfp);
        /* Usually this means that there is no more space available in
         * the vq
         */
@@ -178,7 +178,7 @@ virtio_transport_send_pkt_work(struct work_struct *work)
 
                reply = virtio_vsock_skb_reply(skb);
 
-               ret = virtio_transport_send_skb(skb, vq, vsock);
+               ret = virtio_transport_send_skb(skb, vq, vsock, GFP_KERNEL);
                if (ret < 0) {
                        virtio_vsock_skb_queue_head(&vsock->send_pkt_queue, skb);
                        break;
@@ -221,7 +221,7 @@ static int virtio_transport_send_skb_fast_path(struct virtio_vsock *vsock, struc
        if (unlikely(ret == 0))
                return -EBUSY;
 
-       ret = virtio_transport_send_skb(skb, vq, vsock);
+       ret = virtio_transport_send_skb(skb, vq, vsock, GFP_ATOMIC);
        if (ret == 0)
                virtqueue_kick(vq);
 
index 884ee128851e5ce8b01c78fcb95a408986f62936..ccbd2bc0d2109aea4f19e79a0438f85893e1d89c 100644 (file)
@@ -1707,6 +1707,7 @@ int virtio_transport_read_skb(struct vsock_sock *vsk, skb_read_actor_t recv_acto
 {
        struct virtio_vsock_sock *vvs = vsk->trans;
        struct sock *sk = sk_vsock(vsk);
+       struct virtio_vsock_hdr *hdr;
        struct sk_buff *skb;
        int off = 0;
        int err;
@@ -1716,10 +1717,19 @@ int virtio_transport_read_skb(struct vsock_sock *vsk, skb_read_actor_t recv_acto
         * works for types other than dgrams.
         */
        skb = __skb_recv_datagram(sk, &vvs->rx_queue, MSG_DONTWAIT, &off, &err);
+       if (!skb) {
+               spin_unlock_bh(&vvs->rx_lock);
+               return err;
+       }
+
+       hdr = virtio_vsock_hdr(skb);
+       if (le32_to_cpu(hdr->flags) & VIRTIO_VSOCK_SEQ_EOM)
+               vvs->msg_count--;
+
+       virtio_transport_dec_rx_pkt(vvs, le32_to_cpu(hdr->len));
        spin_unlock_bh(&vvs->rx_lock);
 
-       if (!skb)
-               return err;
+       virtio_transport_send_credit_update(vsk);
 
        return recv_actor(sk, skb);
 }
index c42c5cc18f324108e044772e957c8d42c92ead8c..4aa6e74ec2957b28b9e9d8ce0b5f4d5c289a9276 100644 (file)
@@ -114,14 +114,6 @@ static int vsock_bpf_recvmsg(struct sock *sk, struct msghdr *msg,
        return copied;
 }
 
-/* Copy of original proto with updated sock_map methods */
-static struct proto vsock_bpf_prot = {
-       .close = sock_map_close,
-       .recvmsg = vsock_bpf_recvmsg,
-       .sock_is_readable = sk_msg_is_readable,
-       .unhash = sock_map_unhash,
-};
-
 static void vsock_bpf_rebuild_protos(struct proto *prot, const struct proto *base)
 {
        *prot        = *base;
index 661adfc776444408f300dfa5fde6361567cf9c11..74ca18833df172a1f911a6ef9c62c7685ac36c8a 100644 (file)
@@ -1236,6 +1236,7 @@ static void _cfg80211_unregister_wdev(struct wireless_dev *wdev,
        /* deleted from the list, so can't be found from nl80211 any more */
        cqm_config = rcu_access_pointer(wdev->cqm_config);
        kfree_rcu(cqm_config, rcu_head);
+       RCU_INIT_POINTER(wdev->cqm_config, NULL);
 
        /*
         * Ensure that all events have been processed and
@@ -1704,6 +1705,13 @@ void wiphy_delayed_work_flush(struct wiphy *wiphy,
 }
 EXPORT_SYMBOL_GPL(wiphy_delayed_work_flush);
 
+bool wiphy_delayed_work_pending(struct wiphy *wiphy,
+                               struct wiphy_delayed_work *dwork)
+{
+       return timer_pending(&dwork->timer);
+}
+EXPORT_SYMBOL_GPL(wiphy_delayed_work_pending);
+
 static int __init cfg80211_init(void)
 {
        int err;
index 9ab777e0bd4d3493619ed73b279a80a84ce476e2..d7d099f7118ab5d5c745905abdea85d246c2b7b2 100644 (file)
@@ -17986,10 +17986,8 @@ void nl80211_common_reg_change_event(enum nl80211_commands cmd_id,
 
        genlmsg_end(msg, hdr);
 
-       rcu_read_lock();
        genlmsg_multicast_allns(&nl80211_fam, msg, 0,
-                               NL80211_MCGRP_REGULATORY, GFP_ATOMIC);
-       rcu_read_unlock();
+                               NL80211_MCGRP_REGULATORY);
 
        return;
 
@@ -18722,10 +18720,8 @@ void nl80211_send_beacon_hint_event(struct wiphy *wiphy,
 
        genlmsg_end(msg, hdr);
 
-       rcu_read_lock();
        genlmsg_multicast_allns(&nl80211_fam, msg, 0,
-                               NL80211_MCGRP_REGULATORY, GFP_ATOMIC);
-       rcu_read_unlock();
+                               NL80211_MCGRP_REGULATORY);
 
        return;
 
index ae2e1a8964611e3138623b5e9885ed079ab40674..b7e3e46ec16dd5987aa67a743658dedc75f82077 100644 (file)
@@ -18,7 +18,7 @@
 #include <linux/export.h>
 #include <net/cfg80211.h>
 #include <net/ieee80211_radiotap.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 /* function prototypes and related defs are in include/net/cfg80211.h */
 
index 59a90bf3c0d65bbd3e669625a20ffbe25f4cce9c..d0aed41ded2f19c1d7c6165e15d8385665b53c59 100644 (file)
@@ -3050,6 +3050,10 @@ cfg80211_parse_ml_elem_sta_data(struct wiphy *wiphy,
                freq = ieee80211_channel_to_freq_khz(ap_info->channel, band);
                data.channel = ieee80211_get_channel_khz(wiphy, freq);
 
+               /* Skip if RNR element specifies an unsupported channel */
+               if (!data.channel)
+                       continue;
+
                /* Skip if BSS entry generated from MBSSID or DIRECT source
                 * frame data available already.
                 */
index f123b7c9ec82594fd2c4b5275f3fc737ad5449cb..b33c4591e09a4f289f1e067a5a657854452f7f0f 100644 (file)
@@ -269,6 +269,8 @@ int xfrm_dev_state_add(struct net *net, struct xfrm_state *x,
 
        dev = dev_get_by_index(net, xuo->ifindex);
        if (!dev) {
+               struct xfrm_dst_lookup_params params;
+
                if (!(xuo->flags & XFRM_OFFLOAD_INBOUND)) {
                        saddr = &x->props.saddr;
                        daddr = &x->id.daddr;
@@ -277,9 +279,12 @@ int xfrm_dev_state_add(struct net *net, struct xfrm_state *x,
                        daddr = &x->props.saddr;
                }
 
-               dst = __xfrm_dst_lookup(net, 0, 0, saddr, daddr,
-                                       x->props.family,
-                                       xfrm_smark_get(0, x));
+               memset(&params, 0, sizeof(params));
+               params.net = net;
+               params.saddr = saddr;
+               params.daddr = daddr;
+               params.mark = xfrm_smark_get(0, x);
+               dst = __xfrm_dst_lookup(x->props.family, &params);
                if (IS_ERR(dst))
                        return (is_packet_offload) ? -EINVAL : 0;
 
index 914bac03b52ad42517835fbd6000b78b802720e9..a2ea9dbac90b36fefd6a7d3978ae51854de82553 100644 (file)
@@ -270,10 +270,8 @@ static const struct xfrm_if_cb *xfrm_if_get_cb(void)
        return rcu_dereference(xfrm_if_cb);
 }
 
-struct dst_entry *__xfrm_dst_lookup(struct net *net, int tos, int oif,
-                                   const xfrm_address_t *saddr,
-                                   const xfrm_address_t *daddr,
-                                   int family, u32 mark)
+struct dst_entry *__xfrm_dst_lookup(int family,
+                                   const struct xfrm_dst_lookup_params *params)
 {
        const struct xfrm_policy_afinfo *afinfo;
        struct dst_entry *dst;
@@ -282,7 +280,7 @@ struct dst_entry *__xfrm_dst_lookup(struct net *net, int tos, int oif,
        if (unlikely(afinfo == NULL))
                return ERR_PTR(-EAFNOSUPPORT);
 
-       dst = afinfo->dst_lookup(net, tos, oif, saddr, daddr, mark);
+       dst = afinfo->dst_lookup(params);
 
        rcu_read_unlock();
 
@@ -296,6 +294,7 @@ static inline struct dst_entry *xfrm_dst_lookup(struct xfrm_state *x,
                                                xfrm_address_t *prev_daddr,
                                                int family, u32 mark)
 {
+       struct xfrm_dst_lookup_params params;
        struct net *net = xs_net(x);
        xfrm_address_t *saddr = &x->props.saddr;
        xfrm_address_t *daddr = &x->id.daddr;
@@ -310,7 +309,29 @@ static inline struct dst_entry *xfrm_dst_lookup(struct xfrm_state *x,
                daddr = x->coaddr;
        }
 
-       dst = __xfrm_dst_lookup(net, tos, oif, saddr, daddr, family, mark);
+       params.net = net;
+       params.saddr = saddr;
+       params.daddr = daddr;
+       params.tos = tos;
+       params.oif = oif;
+       params.mark = mark;
+       params.ipproto = x->id.proto;
+       if (x->encap) {
+               switch (x->encap->encap_type) {
+               case UDP_ENCAP_ESPINUDP:
+                       params.ipproto = IPPROTO_UDP;
+                       params.uli.ports.sport = x->encap->encap_sport;
+                       params.uli.ports.dport = x->encap->encap_dport;
+                       break;
+               case TCP_ENCAP_ESPINTCP:
+                       params.ipproto = IPPROTO_TCP;
+                       params.uli.ports.sport = x->encap->encap_sport;
+                       params.uli.ports.dport = x->encap->encap_dport;
+                       break;
+               }
+       }
+
+       dst = __xfrm_dst_lookup(family, &params);
 
        if (!IS_ERR(dst)) {
                if (prev_saddr != saddr)
@@ -2432,15 +2453,15 @@ int __xfrm_sk_clone_policy(struct sock *sk, const struct sock *osk)
 }
 
 static int
-xfrm_get_saddr(struct net *net, int oif, xfrm_address_t *local,
-              xfrm_address_t *remote, unsigned short family, u32 mark)
+xfrm_get_saddr(unsigned short family, xfrm_address_t *saddr,
+              const struct xfrm_dst_lookup_params *params)
 {
        int err;
        const struct xfrm_policy_afinfo *afinfo = xfrm_policy_get_afinfo(family);
 
        if (unlikely(afinfo == NULL))
                return -EINVAL;
-       err = afinfo->get_saddr(net, oif, local, remote, mark);
+       err = afinfo->get_saddr(saddr, params);
        rcu_read_unlock();
        return err;
 }
@@ -2469,9 +2490,14 @@ xfrm_tmpl_resolve_one(struct xfrm_policy *policy, const struct flowi *fl,
                        remote = &tmpl->id.daddr;
                        local = &tmpl->saddr;
                        if (xfrm_addr_any(local, tmpl->encap_family)) {
-                               error = xfrm_get_saddr(net, fl->flowi_oif,
-                                                      &tmp, remote,
-                                                      tmpl->encap_family, 0);
+                               struct xfrm_dst_lookup_params params;
+
+                               memset(&params, 0, sizeof(params));
+                               params.net = net;
+                               params.oif = fl->flowi_oif;
+                               params.daddr = remote;
+                               error = xfrm_get_saddr(tmpl->encap_family, &tmp,
+                                                      &params);
                                if (error)
                                        goto fail;
                                local = &tmp;
@@ -4180,7 +4206,6 @@ static int __net_init xfrm_policy_init(struct net *net)
 
                net->xfrm.policy_count[dir] = 0;
                net->xfrm.policy_count[XFRM_POLICY_MAX + dir] = 0;
-               INIT_HLIST_HEAD(&net->xfrm.policy_inexact[dir]);
 
                htab = &net->xfrm.policy_bydst[dir];
                htab->table = xfrm_hash_alloc(sz);
@@ -4234,8 +4259,6 @@ static void xfrm_policy_fini(struct net *net)
        for (dir = 0; dir < XFRM_POLICY_MAX; dir++) {
                struct xfrm_policy_hash *htab;
 
-               WARN_ON(!hlist_empty(&net->xfrm.policy_inexact[dir]));
-
                htab = &net->xfrm.policy_bydst[dir];
                sz = (htab->hmask + 1) * sizeof(struct hlist_head);
                WARN_ON(!hlist_empty(htab->table));
index 55f039ec3d59001c9fcdb56be39ce657c8b959ba..e3b8ce89831abff86310077f760a7296f9608394 100644 (file)
@@ -33,7 +33,7 @@
 #if IS_ENABLED(CONFIG_IPV6)
 #include <linux/in6.h>
 #endif
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 static int verify_one_alg(struct nlattr **attrs, enum xfrm_attr_type_t type,
                          struct netlink_ext_ack *extack)
@@ -201,6 +201,7 @@ static int verify_newsa_info(struct xfrm_usersa_info *p,
 {
        int err;
        u8 sa_dir = attrs[XFRMA_SA_DIR] ? nla_get_u8(attrs[XFRMA_SA_DIR]) : 0;
+       u16 family = p->sel.family;
 
        err = -EINVAL;
        switch (p->family) {
@@ -221,7 +222,10 @@ static int verify_newsa_info(struct xfrm_usersa_info *p,
                goto out;
        }
 
-       switch (p->sel.family) {
+       if (!family && !(p->flags & XFRM_STATE_AF_UNSPEC))
+               family = p->family;
+
+       switch (family) {
        case AF_UNSPEC:
                break;
 
@@ -1098,7 +1102,9 @@ static int copy_to_user_auth(struct xfrm_algo_auth *auth, struct sk_buff *skb)
        if (!nla)
                return -EMSGSIZE;
        ap = nla_data(nla);
-       memcpy(ap, auth, sizeof(struct xfrm_algo_auth));
+       strscpy_pad(ap->alg_name, auth->alg_name, sizeof(ap->alg_name));
+       ap->alg_key_len = auth->alg_key_len;
+       ap->alg_trunc_len = auth->alg_trunc_len;
        if (redact_secret && auth->alg_key_len)
                memset(ap->alg_key, 0, (auth->alg_key_len + 7) / 8);
        else
index a721d466bee4b267156a9566712e85f36a647058..b7c7483123b7ab1664f229feb1c17c4b7b19172d 100644 (file)
@@ -24,3 +24,8 @@
 # These functions use the `__preserve_most` calling convention, which neither bindgen
 # nor Rust currently understand, and which Clang currently declares to be unstable.
 --blocklist-function __list_.*_report
+
+# These constants are sometimes not recognized by bindgen depending on config.
+# We use const helpers to aid bindgen, to avoid conflicts when constants are
+# recognized, block generation of the non-helper constants.
+--blocklist-item ARCH_SLAB_MINALIGN
index 200db7e6279f0f11f59da15ed2cbb0332a9d830e..a17ca8cdb50ca0a8412c600eea6143d18488099a 100644 (file)
@@ -7,3 +7,9 @@ void rust_helper_mutex_lock(struct mutex *lock)
 {
        mutex_lock(lock);
 }
+
+void rust_helper___mutex_init(struct mutex *mutex, const char *name,
+                             struct lock_class_key *key)
+{
+       __mutex_init(mutex, name, key);
+}
index 851018eef885e7a10a5c13f3af0b203bae8287ee..c8199ee079eff10db8ae26793be6e3410c123197 100644 (file)
@@ -51,18 +51,9 @@ impl Device {
     ///
     /// It must also be ensured that `bindings::device::release` can be called from any thread.
     /// While not officially documented, this should be the case for any `struct device`.
-    pub unsafe fn from_raw(ptr: *mut bindings::device) -> ARef<Self> {
-        // SAFETY: By the safety requirements, ptr is valid.
-        // Initially increase the reference count by one to compensate for the final decrement once
-        // this newly created `ARef<Device>` instance is dropped.
-        unsafe { bindings::get_device(ptr) };
-
-        // CAST: `Self` is a `repr(transparent)` wrapper around `bindings::device`.
-        let ptr = ptr.cast::<Self>();
-
-        // SAFETY: `ptr` is valid by the safety requirements of this function. By the above call to
-        // `bindings::get_device` we also own a reference to the underlying `struct device`.
-        unsafe { ARef::from_raw(ptr::NonNull::new_unchecked(ptr)) }
+    pub unsafe fn get_device(ptr: *mut bindings::device) -> ARef<Self> {
+        // SAFETY: By the safety requirements ptr is valid
+        unsafe { Self::as_ref(ptr) }.into()
     }
 
     /// Obtain the raw `struct device *`.
index dee5b4b18aec403f38746a0fbd595929b7fc3ad4..13a374a5cdb743a5860c6980c641c10bb03d7810 100644 (file)
@@ -44,7 +44,7 @@ impl FwFunc {
 ///
 /// # fn no_run() -> Result<(), Error> {
 /// # // SAFETY: *NOT* safe, just for the example to get an `ARef<Device>` instance
-/// # let dev = unsafe { Device::from_raw(core::ptr::null_mut()) };
+/// # let dev = unsafe { Device::get_device(core::ptr::null_mut()) };
 ///
 /// let fw = Firmware::request(c_str!("path/to/firmware.bin"), &dev)?;
 /// let blob = fw.data();
index 0ba77276ae7ef2fcfce362761ccc4c20e2955dd5..824da0e9738a0153712f701830803c5d48c48aa8 100644 (file)
@@ -18,7 +18,7 @@ pub fn err(args: fmt::Arguments<'_>) {
     #[cfg(CONFIG_PRINTK)]
     unsafe {
         bindings::_printk(
-            b"\x013%pA\0".as_ptr() as _,
+            c"\x013%pA".as_ptr() as _,
             &args as *const _ as *const c_void,
         );
     }
@@ -34,7 +34,7 @@ pub fn info(args: fmt::Arguments<'_>) {
     #[cfg(CONFIG_PRINTK)]
     unsafe {
         bindings::_printk(
-            b"\x016%pA\0".as_ptr() as _,
+            c"\x016%pA".as_ptr() as _,
             &args as *const _ as *const c_void,
         );
     }
index 22a3bfa5a9e96a1dd9cf76bd34a8d992458870b4..b5f4b3ce6b48203507f89bcc4b0bf7b076be6247 100644 (file)
@@ -44,8 +44,8 @@ pub mod net;
 pub mod page;
 pub mod prelude;
 pub mod print;
-pub mod sizes;
 pub mod rbtree;
+pub mod sizes;
 mod static_assert;
 #[doc(hidden)]
 pub mod std_vendor;
index babc731bd5f6261b3239b00d6ec5ad9c63ebec52..ce2ee8d8786587c5f3686172693bd04ac7641366 100644 (file)
@@ -83,8 +83,12 @@ pub struct LockedBy<T: ?Sized, U: ?Sized> {
 // SAFETY: `LockedBy` can be transferred across thread boundaries iff the data it protects can.
 unsafe impl<T: ?Sized + Send, U: ?Sized> Send for LockedBy<T, U> {}
 
-// SAFETY: `LockedBy` serialises the interior mutability it provides, so it is `Sync` as long as the
-// data it protects is `Send`.
+// SAFETY: If `T` is not `Sync`, then parallel shared access to this `LockedBy` allows you to use
+// `access_mut` to hand out `&mut T` on one thread at the time. The requirement that `T: Send` is
+// sufficient to allow that.
+//
+// If `T` is `Sync`, then the `access` method also becomes available, which allows you to obtain
+// several `&T` from several threads at once. However, this is okay as `T` is `Sync`.
 unsafe impl<T: ?Sized + Send, U: ?Sized> Sync for LockedBy<T, U> {}
 
 impl<T, U> LockedBy<T, U> {
@@ -118,7 +122,10 @@ impl<T: ?Sized, U> LockedBy<T, U> {
     ///
     /// Panics if `owner` is different from the data protected by the lock used in
     /// [`new`](LockedBy::new).
-    pub fn access<'a>(&'a self, owner: &'a U) -> &'a T {
+    pub fn access<'a>(&'a self, owner: &'a U) -> &'a T
+    where
+        T: Sync,
+    {
         build_assert!(
             size_of::<U>() > 0,
             "`U` cannot be a ZST because `owner` wouldn't be unique"
@@ -127,7 +134,10 @@ impl<T: ?Sized, U> LockedBy<T, U> {
             panic!("mismatched owners");
         }
 
-        // SAFETY: `owner` is evidence that the owner is locked.
+        // SAFETY: `owner` is evidence that there are only shared references to the owner for the
+        // duration of 'a, so it's not possible to use `Self::access_mut` to obtain a mutable
+        // reference to the inner value that aliases with this shared reference. The type is `Sync`
+        // so there are no other requirements.
         unsafe { &*self.data.get() }
     }
 
index 785a491e599689b7f1f3c33d22c19d5ebc63ba53..33193ca6e8030e659d6b321acaea1acd42c387a4 100644 (file)
@@ -65,6 +65,9 @@ cc-option-bit = $(if-success,$(CC) -Werror $(1) -E -x c /dev/null -o /dev/null,$
 m32-flag := $(cc-option-bit,-m32)
 m64-flag := $(cc-option-bit,-m64)
 
+rustc-version := $(shell,$(srctree)/scripts/rustc-version.sh $(RUSTC))
+rustc-llvm-version := $(shell,$(srctree)/scripts/rustc-llvm-version.sh $(RUSTC))
+
 # $(rustc-option,<flag>)
 # Return y if the Rust compiler supports <flag>, n otherwise
 # Calls to this should be guarded so that they are not evaluated if
index 057305eae85c6da49d1cf110a48bd49adee4d0fd..e0842496d26ed773cba4cf9e6a0df50e9713705b 100644 (file)
@@ -53,13 +53,11 @@ cc-option = $(call __cc-option, $(CC),\
 
 # cc-option-yn
 # Usage: flag := $(call cc-option-yn,-march=winchip-c6)
-cc-option-yn = $(call try-run,\
-       $(CC) -Werror $(KBUILD_CPPFLAGS) $(KBUILD_CFLAGS) $(1) -c -x c /dev/null -o "$$TMP",y,n)
+cc-option-yn = $(if $(call cc-option,$1),y,n)
 
 # cc-disable-warning
 # Usage: cflags-y += $(call cc-disable-warning,unused-but-set-variable)
-cc-disable-warning = $(call try-run,\
-       $(CC) -Werror $(KBUILD_CPPFLAGS) $(KBUILD_CFLAGS) -W$(strip $(1)) -c -x c /dev/null -o "$$TMP",-Wno-$(strip $(1)))
+cc-disable-warning = $(if $(call cc-option,-W$(strip $1)),-Wno-$(strip $1))
 
 # gcc-min-version
 # Usage: cflags-$(call gcc-min-version, 70100) += -foo
@@ -75,8 +73,11 @@ ld-option = $(call try-run, $(LD) $(KBUILD_LDFLAGS) $(1) -v,$(1),$(2),$(3))
 
 # __rustc-option
 # Usage: MY_RUSTFLAGS += $(call __rustc-option,$(RUSTC),$(MY_RUSTFLAGS),-Cinstrument-coverage,-Zinstrument-coverage)
+# TODO: remove RUSTC_BOOTSTRAP=1 when we raise the minimum GNU Make version to 4.4
 __rustc-option = $(call try-run,\
-       $(1) $(2) $(3) --crate-type=rlib /dev/null --out-dir=$$TMPOUT -o "$$TMP",$(3),$(4))
+       echo '#![allow(missing_docs)]#![feature(no_core)]#![no_core]' | RUSTC_BOOTSTRAP=1\
+       $(1) --sysroot=/dev/null $(filter-out --sysroot=/dev/null,$(2)) $(3)\
+       --crate-type=rlib --out-dir=$(TMPOUT) --emit=obj=- - >/dev/null,$(3),$(4))
 
 # rustc-option
 # Usage: rustflags-y += $(call rustc-option,-Cinstrument-coverage,-Zinstrument-coverage)
@@ -85,5 +86,4 @@ rustc-option = $(call __rustc-option, $(RUSTC),\
 
 # rustc-option-yn
 # Usage: flag := $(call rustc-option-yn,-Cinstrument-coverage)
-rustc-option-yn = $(call try-run,\
-       $(RUSTC) $(KBUILD_RUSTFLAGS) $(1) --crate-type=rlib /dev/null --out-dir=$$TMPOUT -o "$$TMP",y,n)
+rustc-option-yn = $(if $(call rustc-option,$1),y,n)
index 46009d5f14867901202daddd18db7b9d3c8d01db..8d56c0815f338f053f622108f49e7f054cc52f9f 100644 (file)
@@ -34,12 +34,14 @@ $(obj)/dtbs-list: $(dtb-y) FORCE
 # Assembly file to wrap dtb(o)
 # ---------------------------------------------------------------------------
 
+builtin-dtb-section = $(if $(filter arch/$(SRCARCH)/boot/dts%, $(obj)),.dtb.init.rodata,.rodata)
+
 # Generate an assembly file to wrap the output of the device tree compiler
 quiet_cmd_wrap_S_dtb = WRAP    $@
       cmd_wrap_S_dtb = {                                                               \
                symbase=__$(patsubst .%,%,$(suffix $<))_$(subst -,_,$(notdir $*));      \
                echo '\#include <asm-generic/vmlinux.lds.h>';                           \
-               echo '.section .dtb.init.rodata,"a"';                                   \
+               echo '.section $(builtin-dtb-section),"a"';                             \
                echo '.balign STRUCT_ALIGNMENT';                                        \
                echo ".global $${symbase}_begin";                                       \
                echo "$${symbase}_begin:";                                              \
index 11d53f240a2bc7f13b9fef5c1aeb5be3409be60d..74bcb9e7f7a4516473481468a0fcf700c3bead33 100644 (file)
@@ -62,6 +62,10 @@ rpm-sources: linux.tar.gz
 
 PHONY += rpm-pkg srcrpm-pkg binrpm-pkg
 
+ifneq ($(CC),$(HOSTCC))
+rpm-no-devel = --without=devel
+endif
+
 rpm-pkg:    private build-type := a
 srcrpm-pkg: private build-type := s
 binrpm-pkg: private build-type := b
@@ -72,7 +76,8 @@ rpm-pkg srcrpm-pkg binrpm-pkg: rpmbuild/SPECS/kernel.spec
        --define='_topdir $(abspath rpmbuild)' \
        $(if $(filter a b, $(build-type)), \
                --target $(UTS_MACHINE)-linux --build-in-place --noprep --define='_smp_mflags %{nil}' \
-               $$(rpm -q rpm >/dev/null 2>&1 || echo --nodeps)) \
+               $$(rpm -q rpm >/dev/null 2>&1 || echo --nodeps) \
+               $(rpm-no-devel)) \
        $(RPMOPTS))
 
 # deb-pkg srcdeb-pkg bindeb-pkg
index fea1e2b7906369644b605348f7b4ed356edf87c7..8bdcaadca709d2a83cf55e756aba0de87a870b29 100644 (file)
@@ -127,6 +127,36 @@ static inline void list_del(struct list_head *entry)
        entry->prev = LIST_POISON2;
 }
 
+/**
+ * list_replace - replace old entry by new one
+ * @old : the element to be replaced
+ * @new : the new element to insert
+ *
+ * If @old was empty, it will be overwritten.
+ */
+static inline void list_replace(struct list_head *old,
+                               struct list_head *new)
+{
+       new->next = old->next;
+       new->next->prev = new;
+       new->prev = old->prev;
+       new->prev->next = new;
+}
+
+/**
+ * list_replace_init - replace old entry by new one and initialize the old one
+ * @old : the element to be replaced
+ * @new : the new element to insert
+ *
+ * If @old was empty, it will be overwritten.
+ */
+static inline void list_replace_init(struct list_head *old,
+                                    struct list_head *new)
+{
+       list_replace(old, new);
+       INIT_LIST_HEAD(old);
+}
+
 /**
  * list_move - delete from one list and add as another's head
  * @list: the entry to move
@@ -150,6 +180,26 @@ static inline void list_move_tail(struct list_head *list,
        list_add_tail(list, head);
 }
 
+/**
+ * list_is_first -- tests whether @list is the first entry in list @head
+ * @list: the entry to test
+ * @head: the head of the list
+ */
+static inline int list_is_first(const struct list_head *list, const struct list_head *head)
+{
+       return list->prev == head;
+}
+
+/**
+ * list_is_last - tests whether @list is the last entry in list @head
+ * @list: the entry to test
+ * @head: the head of the list
+ */
+static inline int list_is_last(const struct list_head *list, const struct list_head *head)
+{
+       return list->next == head;
+}
+
 /**
  * list_is_head - tests whether @list is the list @head
  * @list: the entry to test
index 78738ef412de2e42ac82eb0718462c2ea7f2e853..16f92c4a775a13f053c636598df70702b8fe7c4d 100644 (file)
@@ -47,6 +47,7 @@ static struct expr *expr_lookup(enum expr_type type, void *l, void *r)
        e->type = type;
        e->left._initdata = l;
        e->right._initdata = r;
+       e->val_is_valid = false;
 
        hash_add(expr_hashtable, &e->node, hash);
 
index 4addd33749bbaafad0359a776fc5103399c19129..6587ac86d0d52b53e14d619770a23de924fa62cd 100644 (file)
@@ -533,6 +533,7 @@ bool menu_is_empty(struct menu *menu)
 
 bool menu_is_visible(struct menu *menu)
 {
+       struct menu *child;
        struct symbol *sym;
        tristate visible;
 
@@ -551,7 +552,17 @@ bool menu_is_visible(struct menu *menu)
        } else
                visible = menu->prompt->visible.tri = expr_calc_value(menu->prompt->visible.expr);
 
-       return visible != no;
+       if (visible != no)
+               return true;
+
+       if (!sym || sym_get_tristate_value(menu->sym) == no)
+               return false;
+
+       for (child = menu->list; child; child = child->next)
+               if (menu_is_visible(child))
+                       return true;
+
+       return false;
 }
 
 const char *menu_get_prompt(const struct menu *menu)
index 1ad60f9e164e496c989f8d6ce6d37bc9b2ab62c9..bc43fb67c7c41e6db263a636ae165dbfa22e99d5 100644 (file)
@@ -159,8 +159,14 @@ config_stmt: config_entry_start config_option_list
                        yynerrs++;
                }
 
-               list_add_tail(&current_entry->sym->choice_link,
-                             &current_choice->choice_members);
+               /*
+                * If the same symbol appears twice in a choice block, the list
+                * node would be added twice, leading to a broken linked list.
+                * list_empty() ensures that this symbol has not yet added.
+                */
+               if (list_empty(&current_entry->sym->choice_link))
+                       list_add_tail(&current_entry->sym->choice_link,
+                                     &current_choice->choice_members);
        }
 
        printd(DEBUG_PARSE, "%s:%d:endconfig\n", cur_filename, cur_lineno);
index 97fce13e551ef3ab41c204380838e182a4128c65..e260cab1c2afff347aa6e8d773c6058f11a3a7b6 100644 (file)
@@ -1166,7 +1166,7 @@ void ConfigInfoView::clicked(const QUrl &url)
 {
        QByteArray str = url.toEncoded();
        const std::size_t count = str.size();
-       char *data = new char[count + 1];
+       char *data = new char[count + 2];  // '$' + '\0'
        struct symbol **result;
        struct menu *m = NULL;
 
@@ -1505,6 +1505,8 @@ ConfigMainWindow::ConfigMainWindow(void)
        connect(helpText, &ConfigInfoView::menuSelected,
                this, &ConfigMainWindow::setMenuLink);
 
+       conf_read(NULL);
+
        QString listMode = configSettings->value("/listMode", "symbol").toString();
        if (listMode == "single")
                showSingleView();
@@ -1906,8 +1908,6 @@ int main(int ac, char** av)
        configApp->connect(configApp, SIGNAL(lastWindowClosed()), SLOT(quit()));
        configApp->connect(configApp, SIGNAL(aboutToQuit()), v, SLOT(saveSettings()));
 
-       conf_read(NULL);
-
        v->show();
        configApp->exec();
 
index 99dce93a41888d486925344838bcb40917033cea..c4cc11aa558f5f5dc4ef3a78475cbbe827f48308 100644 (file)
@@ -567,12 +567,12 @@ static int do_acpi_entry(const char *filename,
                        void *symval, char *alias)
 {
        DEF_FIELD_ADDR(symval, acpi_device_id, id);
-       DEF_FIELD_ADDR(symval, acpi_device_id, cls);
-       DEF_FIELD_ADDR(symval, acpi_device_id, cls_msk);
+       DEF_FIELD(symval, acpi_device_id, cls);
+       DEF_FIELD(symval, acpi_device_id, cls_msk);
 
        if (id && strlen((const char *)*id))
                sprintf(alias, "acpi*:%s:*", *id);
-       else if (cls) {
+       else {
                int i, byte_shift, cnt = 0;
                unsigned int msk;
 
@@ -580,10 +580,10 @@ static int do_acpi_entry(const char *filename,
                cnt = 6;
                for (i = 1; i <= 3; i++) {
                        byte_shift = 8 * (3-i);
-                       msk = (*cls_msk >> byte_shift) & 0xFF;
+                       msk = (cls_msk >> byte_shift) & 0xFF;
                        if (msk)
                                sprintf(&alias[cnt], "%02x",
-                                       (*cls >> byte_shift) & 0xFF);
+                                       (cls >> byte_shift) & 0xFF);
                        else
                                sprintf(&alias[cnt], "??");
                        cnt += 2;
@@ -743,7 +743,7 @@ static void do_input(char *alias,
        for (i = min / BITS_PER_LONG; i < max / BITS_PER_LONG + 1; i++)
                arr[i] = TO_NATIVE(arr[i]);
        for (i = min; i < max; i++)
-               if (arr[i / BITS_PER_LONG] & (1L << (i%BITS_PER_LONG)))
+               if (arr[i / BITS_PER_LONG] & (1ULL << (i%BITS_PER_LONG)))
                        sprintf(alias + strlen(alias), "%X,*", i);
 }
 
index e7d2da45b0df80d10a28ddd31582579ccf205573..6de9af17599d7cf7b6caeed56440360db805bac7 100644 (file)
@@ -392,7 +392,7 @@ out_file:
 /* Calc and record src checksum. */
 void get_src_version(const char *modname, char sum[], unsigned sumlen)
 {
-       char *buf;
+       char *buf, *pos;
        struct md4_ctx md;
        char *fname;
        char filelist[PATH_MAX + 1];
@@ -401,9 +401,10 @@ void get_src_version(const char *modname, char sum[], unsigned sumlen)
        snprintf(filelist, sizeof(filelist), "%s.mod", modname);
 
        buf = read_text_file(filelist);
+       pos = buf;
 
        md4_init(&md);
-       while ((fname = strsep(&buf, "\n"))) {
+       while ((fname = strsep(&pos, "\n"))) {
                if (!*fname)
                        continue;
                if (!(is_static_library(fname)) &&
index c1757db6aa8a8030f07c53ebf22b4b43fe4d3c80..441b0bb66e0d0c66362ece081f5a2d314708db87 100755 (executable)
@@ -74,7 +74,6 @@ install_linux_image () {
 
                mkdir -p "${pdir}/DEBIAN"
                cat <<-EOF > "${pdir}/DEBIAN/${script}"
-
                #!/bin/sh
 
                set -e
@@ -124,7 +123,7 @@ install_kernel_headers () {
        pdir=debian/$1
        version=${1#linux-headers-}
 
-       "${srctree}/scripts/package/install-extmod-build" "${pdir}/usr/src/linux-headers-${version}"
+       CC="${DEB_HOST_GNU_TYPE}-gcc" "${srctree}/scripts/package/install-extmod-build" "${pdir}/usr/src/linux-headers-${version}"
 
        mkdir -p $pdir/lib/modules/$version/
        ln -s /usr/src/linux-headers-$version $pdir/lib/modules/$version/build
index d2c9cacecc0c30247db2eeb0b846173162fadbe8..7ec1f061a519c70ad33a5434608d1060b26b089a 100755 (executable)
@@ -44,13 +44,11 @@ mkdir -p "${destdir}"
        fi
 } | tar -c -f - -T - | tar -xf - -C "${destdir}"
 
-# When ${CC} and ${HOSTCC} differ, we are likely cross-compiling. Rebuild host
-# programs using ${CC}. This assumes CC=${CROSS_COMPILE}gcc, which is usually
-# the case for package building. It does not cross-compile when CC=clang.
+# When ${CC} and ${HOSTCC} differ, rebuild host programs using ${CC}.
 #
 # This caters to host programs that participate in Kbuild. objtool and
 # resolve_btfids are out of scope.
-if [ "${CC}" != "${HOSTCC}" ] && is_enabled CONFIG_CC_CAN_LINK; then
+if [ "${CC}" != "${HOSTCC}" ]; then
        echo "Rebuilding host programs with ${CC}..."
 
        cat <<-'EOF' >  "${destdir}/Kbuild"
index 10637d403777697db10b6e3c3dba502045cd67be..fc3b7fa709fcf2610bed22ff2953a4e4fc0d217a 100755 (executable)
@@ -179,6 +179,8 @@ fi
 
 echo $debarch > debian/arch
 
+host_gnu=$(dpkg-architecture -a "${debarch}" -q DEB_HOST_GNU_TYPE | sed 's/_/-/g')
+
 # Generate a simple changelog template
 cat <<EOF > debian/changelog
 $sourcename ($packageversion) $distribution; urgency=low
@@ -196,7 +198,11 @@ Priority: optional
 Maintainer: $maintainer
 Rules-Requires-Root: no
 Build-Depends: debhelper-compat (= 12)
-Build-Depends-Arch: bc, bison, cpio, flex, kmod, libelf-dev:native, libssl-dev:native, rsync
+Build-Depends-Arch: bc, bison, cpio, flex,
+ gcc-${host_gnu} <!pkg.${sourcename}.nokernelheaders>,
+ kmod, libelf-dev:native,
+ libssl-dev:native, libssl-dev <!pkg.${sourcename}.nokernelheaders>,
+ rsync
 Homepage: https://www.kernel.org/
 
 Package: $packagename-$version
@@ -224,6 +230,7 @@ cat <<EOF >> debian/control
 
 Package: linux-headers-$version
 Architecture: $debarch
+Build-Profiles: <!pkg.${sourcename}.nokernelheaders>
 Description: Linux kernel headers for $version on $debarch
  This package provides kernel header files for $version on $debarch
  .
@@ -238,6 +245,7 @@ cat <<EOF >> debian/control
 Package: linux-image-$version-dbg
 Section: debug
 Architecture: $debarch
+Build-Profiles: <!pkg.${sourcename}.nokerneldbg>
 Description: Linux kernel debugging symbols for $version
  This package will come in handy if you need to debug the kernel. It provides
  all the necessary debug symbols for the kernel and its modules.
diff --git a/scripts/rustc-llvm-version.sh b/scripts/rustc-llvm-version.sh
new file mode 100755 (executable)
index 0000000..a500d1a
--- /dev/null
@@ -0,0 +1,22 @@
+#!/bin/sh
+# SPDX-License-Identifier: GPL-2.0
+#
+# Usage: $ ./rustc-llvm-version.sh rustc
+#
+# Print the LLVM version that the Rust compiler uses in a 6 digit form.
+
+# Convert the version string x.y.z to a canonical up-to-6-digits form.
+get_canonical_version()
+{
+       IFS=.
+       set -- $1
+       echo $((10000 * $1 + 100 * $2 + $3))
+}
+
+if output=$("$@" --version --verbose 2>/dev/null | grep -E 'LLVM.*[0-9]+\.[0-9]+\.[0-9]+'); then
+       set -- $output
+       get_canonical_version $3
+else
+       echo 0
+       exit 1
+fi
index 2cff851ebfd7e13b955693be9f5818ac6f8bbf03..c9d5ca3d8d08de237102f1ffe3f310636ae0d6ff 100644 (file)
@@ -340,7 +340,7 @@ choice
        config RANDSTRUCT_FULL
                bool "Fully randomize structure layout"
                depends on CC_HAS_RANDSTRUCT || GCC_PLUGINS
-               select MODVERSIONS if MODULES
+               select MODVERSIONS if MODULES && !COMPILE_TEST
                help
                  Fully randomize the member layout of sensitive
                  structures as much as possible, which may have both a
@@ -356,7 +356,7 @@ choice
        config RANDSTRUCT_PERFORMANCE
                bool "Limit randomization of structure layout to cache-lines"
                depends on GCC_PLUGINS
-               select MODVERSIONS if MODULES
+               select MODVERSIONS if MODULES && !COMPILE_TEST
                help
                  Randomization of sensitive kernel structures will make a
                  best effort at restricting randomization to cacheline-sized
index 5a570235427d87cb8cc7513abb77a7891a7ab246..3483c595f999fc55f71b6b179044f809f12a6c45 100644 (file)
@@ -13,7 +13,7 @@
  * All policy is validated before it is used.
  */
 
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include <kunit/visibility.h>
 #include <linux/ctype.h>
 #include <linux/errno.h>
index 3ab582606ed2add5aa2cf4df41c20dcd33e98a99..3c75bf267da4680f1d5dcecc2f77350f4562123c 100644 (file)
@@ -31,6 +31,25 @@ config IPE_BOOT_POLICY
 
          If unsure, leave blank.
 
+config IPE_POLICY_SIG_SECONDARY_KEYRING
+       bool "IPE policy update verification with secondary keyring"
+       default y
+       depends on SECONDARY_TRUSTED_KEYRING
+       help
+         Also allow the secondary trusted keyring to verify IPE policy
+         updates.
+
+         If unsure, answer Y.
+
+config IPE_POLICY_SIG_PLATFORM_KEYRING
+       bool "IPE policy update verification with platform keyring"
+       default y
+       depends on INTEGRITY_PLATFORM_KEYRING
+       help
+         Also allow the platform keyring to verify IPE policy updates.
+
+         If unsure, answer Y.
+
 menu "IPE Trust Providers"
 
 config IPE_PROP_DM_VERITY
index d8e7db857a2ea10b394c3959f649ce6b1d05fcfa..b628f696e32be42e49177fb146a5b63ce08207cf 100644 (file)
@@ -106,8 +106,8 @@ int ipe_update_policy(struct inode *root, const char *text, size_t textlen,
                goto err;
        }
 
-       if (ver_to_u64(old) > ver_to_u64(new)) {
-               rc = -EINVAL;
+       if (ver_to_u64(old) >= ver_to_u64(new)) {
+               rc = -ESTALE;
                goto err;
        }
 
@@ -169,9 +169,21 @@ struct ipe_policy *ipe_new_policy(const char *text, size_t textlen,
                        goto err;
                }
 
-               rc = verify_pkcs7_signature(NULL, 0, new->pkcs7, pkcs7len, NULL,
+               rc = verify_pkcs7_signature(NULL, 0, new->pkcs7, pkcs7len,
+#ifdef CONFIG_IPE_POLICY_SIG_SECONDARY_KEYRING
+                                           VERIFY_USE_SECONDARY_KEYRING,
+#else
+                                           NULL,
+#endif
                                            VERIFYING_UNSPECIFIED_SIGNATURE,
                                            set_pkcs7_data, new);
+#ifdef CONFIG_IPE_POLICY_SIG_PLATFORM_KEYRING
+               if (rc == -ENOKEY || rc == -EKEYREJECTED)
+                       rc = verify_pkcs7_signature(NULL, 0, new->pkcs7, pkcs7len,
+                                                   VERIFY_USE_PLATFORM_KEYRING,
+                                                   VERIFYING_UNSPECIFIED_SIGNATURE,
+                                                   set_pkcs7_data, new);
+#endif
                if (rc)
                        goto err;
        } else {
index 8b7dd73d94c16aeb1f58319cbf27094f880a52ea..024be262702fed97514b543ea8fb20706ca4506d 100644 (file)
@@ -14,7 +14,7 @@
 #include <keys/trusted-type.h>
 #include <keys/trusted_tpm.h>
 
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #include "tpm2key.asn1.h"
 
index 6875eb4a59fcc140a9aee1c9abef5e3859171351..c5981e558bc2643b485778edf5c5c20f725ccb00 100644 (file)
@@ -740,19 +740,20 @@ static int lsm_file_alloc(struct file *file)
 /**
  * lsm_inode_alloc - allocate a composite inode blob
  * @inode: the inode that needs a blob
+ * @gfp: allocation flags
  *
  * Allocate the inode blob for all the modules
  *
  * Returns 0, or -ENOMEM if memory can't be allocated.
  */
-static int lsm_inode_alloc(struct inode *inode)
+static int lsm_inode_alloc(struct inode *inode, gfp_t gfp)
 {
        if (!lsm_inode_cache) {
                inode->i_security = NULL;
                return 0;
        }
 
-       inode->i_security = kmem_cache_zalloc(lsm_inode_cache, GFP_NOFS);
+       inode->i_security = kmem_cache_zalloc(lsm_inode_cache, gfp);
        if (inode->i_security == NULL)
                return -ENOMEM;
        return 0;
@@ -1678,6 +1679,7 @@ int security_path_notify(const struct path *path, u64 mask,
 /**
  * security_inode_alloc() - Allocate an inode LSM blob
  * @inode: the inode
+ * @gfp: allocation flags
  *
  * Allocate and attach a security structure to @inode->i_security.  The
  * i_security field is initialized to NULL when the inode structure is
@@ -1685,9 +1687,9 @@ int security_path_notify(const struct path *path, u64 mask,
  *
  * Return: Return 0 if operation was successful.
  */
-int security_inode_alloc(struct inode *inode)
+int security_inode_alloc(struct inode *inode, gfp_t gfp)
 {
-       int rc = lsm_inode_alloc(inode);
+       int rc = lsm_inode_alloc(inode, gfp);
 
        if (unlikely(rc))
                return rc;
index 90eccc6cd46492c58d1a73fdf0c0ef70ecc9c8b9..1e0dd1a6d0b0e9aa01b6fe4cadb43b8c6b7de058 100644 (file)
@@ -13,21 +13,6 @@ config SECURITY_TOMOYO
          found at <https://tomoyo.sourceforge.net/>.
          If you are unsure how to answer this question, answer N.
 
-config SECURITY_TOMOYO_LKM
-       bool "Cut out most of TOMOYO's code to a loadable kernel module"
-       default n
-       depends on SECURITY_TOMOYO
-       depends on MODULES
-       help
-         Say Y here if you want to include TOMOYO without bloating
-         vmlinux file. If you say Y, most of TOMOYO code is cut out to
-         a loadable kernel module named tomoyo.ko . This option will be
-         useful for kernels built by Linux distributors where TOMOYO is
-         included but TOMOYO is not enabled by default. Please be sure
-         to explicitly load tomoyo.ko if you want to activate TOMOYO
-         without calling userspace policy loader, for tomoyo.ko is
-         loaded immediately before calling userspace policy loader.
-
 config SECURITY_TOMOYO_MAX_ACCEPT_ENTRY
        int "Default maximal count for learning mode"
        default 2048
index 287a7d16fa150cb27250833b9441913d951f7264..55c67b9846a932d836ade6d6f0864820426bdbe7 100644 (file)
@@ -1,11 +1,5 @@
 # SPDX-License-Identifier: GPL-2.0
-tomoyo-objs := audit.o common.o condition.o domain.o environ.o file.o gc.o group.o memory.o mount.o network.o proxy.o realpath.o securityfs_if.o util.o
-obj-y += init.o load_policy.o
-ifdef CONFIG_SECURITY_TOMOYO_LKM
-obj-m += tomoyo.o
-else
-obj-y += tomoyo.o
-endif
+obj-y = audit.o common.o condition.o domain.o environ.o file.o gc.o group.o load_policy.o memory.o mount.o network.o realpath.o securityfs_if.o tomoyo.o util.o
 
 targets += builtin-policy.h
 
index c0ef014f8009aa992bcf5394247e776c6179a66e..5c7b059a332aac494a95b1f99415dd2eef6a2900 100644 (file)
@@ -998,13 +998,8 @@ static bool tomoyo_select_domain(struct tomoyo_io_buffer *head,
                        p = find_task_by_pid_ns(pid, &init_pid_ns);
                else
                        p = find_task_by_vpid(pid);
-               if (p) {
+               if (p)
                        domain = tomoyo_task(p)->domain_info;
-#ifdef CONFIG_SECURITY_TOMOYO_LKM
-                       if (!domain)
-                               domain = &tomoyo_kernel_domain;
-#endif
-               }
                rcu_read_unlock();
        } else if (!strncmp(data, "domain=", 7)) {
                if (tomoyo_domain_def(data + 7))
@@ -1715,13 +1710,8 @@ static void tomoyo_read_pid(struct tomoyo_io_buffer *head)
                p = find_task_by_pid_ns(pid, &init_pid_ns);
        else
                p = find_task_by_vpid(pid);
-       if (p) {
+       if (p)
                domain = tomoyo_task(p)->domain_info;
-#ifdef CONFIG_SECURITY_TOMOYO_LKM
-               if (!domain)
-                       domain = &tomoyo_kernel_domain;
-#endif
-       }
        rcu_read_unlock();
        if (!domain)
                return;
index 4f6c52a9f478016d175dcc7bd53f91ff41407df3..0e8e2e959aef4ec0a96c1bd98aa53c2a87da4e69 100644 (file)
@@ -978,7 +978,6 @@ int tomoyo_get_mode(const struct tomoyo_policy_namespace *ns, const u8 profile,
 int tomoyo_init_request_info(struct tomoyo_request_info *r,
                             struct tomoyo_domain_info *domain,
                             const u8 index);
-int __init tomoyo_interface_init(void);
 int tomoyo_mkdev_perm(const u8 operation, const struct path *path,
                      const unsigned int mode, unsigned int dev);
 int tomoyo_mount_permission(const char *dev_name, const struct path *path,
@@ -1215,14 +1214,10 @@ static inline void tomoyo_put_group(struct tomoyo_group *group)
  *
  * Returns pointer to "struct tomoyo_task" for specified thread.
  */
-#ifdef CONFIG_SECURITY_TOMOYO_LKM
-extern struct tomoyo_task *tomoyo_task(struct task_struct *task);
-#else
 static inline struct tomoyo_task *tomoyo_task(struct task_struct *task)
 {
        return task->security + tomoyo_blob_sizes.lbs_task;
 }
-#endif
 
 /**
  * tomoyo_same_name_union - Check for duplicated "struct tomoyo_name_union" entry.
@@ -1289,71 +1284,4 @@ static inline struct tomoyo_policy_namespace *tomoyo_current_namespace(void)
                pos =  srcu_dereference((head)->next, &tomoyo_ss);      \
        for ( ; pos != (head); pos = srcu_dereference(pos->next, &tomoyo_ss))
 
-#ifdef CONFIG_SECURITY_TOMOYO_LKM
-
-#define LSM_HOOK(RET, DEFAULT, NAME, ...) typedef RET (NAME##_t)(__VA_ARGS__);
-#include <linux/lsm_hook_defs.h>
-#undef LSM_HOOK
-
-struct tomoyo_hooks {
-       cred_prepare_t *cred_prepare;
-       bprm_committed_creds_t *bprm_committed_creds;
-       task_alloc_t *task_alloc;
-       task_free_t *task_free;
-       bprm_check_security_t *bprm_check_security;
-       file_fcntl_t *file_fcntl;
-       file_open_t *file_open;
-       file_truncate_t *file_truncate;
-       path_truncate_t *path_truncate;
-       path_unlink_t *path_unlink;
-       path_mkdir_t *path_mkdir;
-       path_rmdir_t *path_rmdir;
-       path_symlink_t *path_symlink;
-       path_mknod_t *path_mknod;
-       path_link_t *path_link;
-       path_rename_t *path_rename;
-       inode_getattr_t *inode_getattr;
-       file_ioctl_t *file_ioctl;
-       file_ioctl_compat_t *file_ioctl_compat;
-       path_chmod_t *path_chmod;
-       path_chown_t *path_chown;
-       path_chroot_t *path_chroot;
-       sb_mount_t *sb_mount;
-       sb_umount_t *sb_umount;
-       sb_pivotroot_t *sb_pivotroot;
-       socket_bind_t *socket_bind;
-       socket_connect_t *socket_connect;
-       socket_listen_t *socket_listen;
-       socket_sendmsg_t *socket_sendmsg;
-};
-
-extern void tomoyo_register_hooks(const struct tomoyo_hooks *tomoyo_hooks);
-
-struct tomoyo_operations {
-       void (*check_profile)(void);
-       int enabled;
-};
-
-extern struct tomoyo_operations tomoyo_ops;
-
-/*
- * Temporary hack: functions needed by tomoyo.ko . This will be removed
- * after all functions are marked as EXPORT_STMBOL_GPL().
- */
-struct tomoyo_tmp_exports {
-       struct task_struct * (*find_task_by_vpid)(pid_t nr);
-       struct task_struct * (*find_task_by_pid_ns)(pid_t nr, struct pid_namespace *ns);
-       void (*put_filesystem)(struct file_system_type *fs);
-       struct file * (*get_mm_exe_file)(struct mm_struct *mm);
-       char * (*d_absolute_path)(const struct path *path, char *buf, int buflen);
-};
-extern const struct tomoyo_tmp_exports tomoyo_tmp_exports;
-#define find_task_by_vpid tomoyo_tmp_exports.find_task_by_vpid
-#define find_task_by_pid_ns tomoyo_tmp_exports.find_task_by_pid_ns
-#define put_filesystem tomoyo_tmp_exports.put_filesystem
-#define get_mm_exe_file tomoyo_tmp_exports.get_mm_exe_file
-#define d_absolute_path tomoyo_tmp_exports.d_absolute_path
-
-#endif /* defined(CONFIG_SECURITY_TOMOYO_LKM) */
-
 #endif /* !defined(_SECURITY_TOMOYO_COMMON_H) */
index 6eccca150839877557110bc5e9e29a304eb44445..026e29ea3796c38fb78874356f7ddb3af6be6a3b 100644 (file)
@@ -9,9 +9,6 @@
 #include <linux/kthread.h>
 #include <linux/slab.h>
 
-/* Lock for GC. */
-DEFINE_SRCU(tomoyo_ss);
-
 /**
  * tomoyo_memory_free - Free memory for elements.
  *
diff --git a/security/tomoyo/hooks.h b/security/tomoyo/hooks.h
deleted file mode 100644 (file)
index 58929bb..0000000
+++ /dev/null
@@ -1,515 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*
- * security/tomoyo/hooks.h
- *
- * Copyright (C) 2005-2011  NTT DATA CORPORATION
- */
-
-#include "common.h"
-
-/**
- * tomoyo_domain - Get "struct tomoyo_domain_info" for current thread.
- *
- * Returns pointer to "struct tomoyo_domain_info" for current thread.
- */
-struct tomoyo_domain_info *tomoyo_domain(void)
-{
-       struct tomoyo_task *s = tomoyo_task(current);
-
-       return s->domain_info;
-}
-
-/**
- * tomoyo_cred_prepare - Target for security_prepare_creds().
- *
- * @new: Pointer to "struct cred".
- * @old: Pointer to "struct cred".
- * @gfp: Memory allocation flags.
- *
- * Returns 0.
- */
-static int tomoyo_cred_prepare(struct cred *new, const struct cred *old,
-                              gfp_t gfp)
-{
-       /* Restore old_domain_info saved by previous execve() request. */
-       struct tomoyo_task *s = tomoyo_task(current);
-
-       if (s->old_domain_info && !current->in_execve) {
-               atomic_dec(&s->domain_info->users);
-               s->domain_info = s->old_domain_info;
-               s->old_domain_info = NULL;
-       }
-       return 0;
-}
-
-/**
- * tomoyo_bprm_committed_creds - Target for security_bprm_committed_creds().
- *
- * @bprm: Pointer to "struct linux_binprm".
- */
-static void tomoyo_bprm_committed_creds(const struct linux_binprm *bprm)
-{
-       /* Clear old_domain_info saved by execve() request. */
-       struct tomoyo_task *s = tomoyo_task(current);
-
-       atomic_dec(&s->old_domain_info->users);
-       s->old_domain_info = NULL;
-}
-
-/**
- * tomoyo_bprm_check_security - Target for security_bprm_check().
- *
- * @bprm: Pointer to "struct linux_binprm".
- *
- * Returns 0 on success, negative value otherwise.
- */
-static int tomoyo_bprm_check_security(struct linux_binprm *bprm)
-{
-       struct tomoyo_task *s = tomoyo_task(current);
-
-       /*
-        * Execute permission is checked against pathname passed to execve()
-        * using current domain.
-        */
-       if (!s->old_domain_info) {
-               const int idx = tomoyo_read_lock();
-               const int err = tomoyo_find_next_domain(bprm);
-
-               tomoyo_read_unlock(idx);
-               return err;
-       }
-       /*
-        * Read permission is checked against interpreters using next domain.
-        */
-       return tomoyo_check_open_permission(s->domain_info,
-                                           &bprm->file->f_path, O_RDONLY);
-}
-
-/**
- * tomoyo_inode_getattr - Target for security_inode_getattr().
- *
- * @path: Pointer to "struct path".
- *
- * Returns 0 on success, negative value otherwise.
- */
-static int tomoyo_inode_getattr(const struct path *path)
-{
-       return tomoyo_path_perm(TOMOYO_TYPE_GETATTR, path, NULL);
-}
-
-/**
- * tomoyo_path_truncate - Target for security_path_truncate().
- *
- * @path: Pointer to "struct path".
- *
- * Returns 0 on success, negative value otherwise.
- */
-static int tomoyo_path_truncate(const struct path *path)
-{
-       return tomoyo_path_perm(TOMOYO_TYPE_TRUNCATE, path, NULL);
-}
-
-/**
- * tomoyo_file_truncate - Target for security_file_truncate().
- *
- * @file: Pointer to "struct file".
- *
- * Returns 0 on success, negative value otherwise.
- */
-static int tomoyo_file_truncate(struct file *file)
-{
-       return tomoyo_path_truncate(&file->f_path);
-}
-
-/**
- * tomoyo_path_unlink - Target for security_path_unlink().
- *
- * @parent: Pointer to "struct path".
- * @dentry: Pointer to "struct dentry".
- *
- * Returns 0 on success, negative value otherwise.
- */
-static int tomoyo_path_unlink(const struct path *parent, struct dentry *dentry)
-{
-       struct path path = { .mnt = parent->mnt, .dentry = dentry };
-
-       return tomoyo_path_perm(TOMOYO_TYPE_UNLINK, &path, NULL);
-}
-
-/**
- * tomoyo_path_mkdir - Target for security_path_mkdir().
- *
- * @parent: Pointer to "struct path".
- * @dentry: Pointer to "struct dentry".
- * @mode:   DAC permission mode.
- *
- * Returns 0 on success, negative value otherwise.
- */
-static int tomoyo_path_mkdir(const struct path *parent, struct dentry *dentry,
-                            umode_t mode)
-{
-       struct path path = { .mnt = parent->mnt, .dentry = dentry };
-
-       return tomoyo_path_number_perm(TOMOYO_TYPE_MKDIR, &path,
-                                      mode & S_IALLUGO);
-}
-
-/**
- * tomoyo_path_rmdir - Target for security_path_rmdir().
- *
- * @parent: Pointer to "struct path".
- * @dentry: Pointer to "struct dentry".
- *
- * Returns 0 on success, negative value otherwise.
- */
-static int tomoyo_path_rmdir(const struct path *parent, struct dentry *dentry)
-{
-       struct path path = { .mnt = parent->mnt, .dentry = dentry };
-
-       return tomoyo_path_perm(TOMOYO_TYPE_RMDIR, &path, NULL);
-}
-
-/**
- * tomoyo_path_symlink - Target for security_path_symlink().
- *
- * @parent:   Pointer to "struct path".
- * @dentry:   Pointer to "struct dentry".
- * @old_name: Symlink's content.
- *
- * Returns 0 on success, negative value otherwise.
- */
-static int tomoyo_path_symlink(const struct path *parent, struct dentry *dentry,
-                              const char *old_name)
-{
-       struct path path = { .mnt = parent->mnt, .dentry = dentry };
-
-       return tomoyo_path_perm(TOMOYO_TYPE_SYMLINK, &path, old_name);
-}
-
-/**
- * tomoyo_path_mknod - Target for security_path_mknod().
- *
- * @parent: Pointer to "struct path".
- * @dentry: Pointer to "struct dentry".
- * @mode:   DAC permission mode.
- * @dev:    Device attributes.
- *
- * Returns 0 on success, negative value otherwise.
- */
-static int tomoyo_path_mknod(const struct path *parent, struct dentry *dentry,
-                            umode_t mode, unsigned int dev)
-{
-       struct path path = { .mnt = parent->mnt, .dentry = dentry };
-       int type = TOMOYO_TYPE_CREATE;
-       const unsigned int perm = mode & S_IALLUGO;
-
-       switch (mode & S_IFMT) {
-       case S_IFCHR:
-               type = TOMOYO_TYPE_MKCHAR;
-               break;
-       case S_IFBLK:
-               type = TOMOYO_TYPE_MKBLOCK;
-               break;
-       default:
-               goto no_dev;
-       }
-       return tomoyo_mkdev_perm(type, &path, perm, dev);
- no_dev:
-       switch (mode & S_IFMT) {
-       case S_IFIFO:
-               type = TOMOYO_TYPE_MKFIFO;
-               break;
-       case S_IFSOCK:
-               type = TOMOYO_TYPE_MKSOCK;
-               break;
-       }
-       return tomoyo_path_number_perm(type, &path, perm);
-}
-
-/**
- * tomoyo_path_link - Target for security_path_link().
- *
- * @old_dentry: Pointer to "struct dentry".
- * @new_dir:    Pointer to "struct path".
- * @new_dentry: Pointer to "struct dentry".
- *
- * Returns 0 on success, negative value otherwise.
- */
-static int tomoyo_path_link(struct dentry *old_dentry, const struct path *new_dir,
-                           struct dentry *new_dentry)
-{
-       struct path path1 = { .mnt = new_dir->mnt, .dentry = old_dentry };
-       struct path path2 = { .mnt = new_dir->mnt, .dentry = new_dentry };
-
-       return tomoyo_path2_perm(TOMOYO_TYPE_LINK, &path1, &path2);
-}
-
-/**
- * tomoyo_path_rename - Target for security_path_rename().
- *
- * @old_parent: Pointer to "struct path".
- * @old_dentry: Pointer to "struct dentry".
- * @new_parent: Pointer to "struct path".
- * @new_dentry: Pointer to "struct dentry".
- * @flags: Rename options.
- *
- * Returns 0 on success, negative value otherwise.
- */
-static int tomoyo_path_rename(const struct path *old_parent,
-                             struct dentry *old_dentry,
-                             const struct path *new_parent,
-                             struct dentry *new_dentry,
-                             const unsigned int flags)
-{
-       struct path path1 = { .mnt = old_parent->mnt, .dentry = old_dentry };
-       struct path path2 = { .mnt = new_parent->mnt, .dentry = new_dentry };
-
-       if (flags & RENAME_EXCHANGE) {
-               const int err = tomoyo_path2_perm(TOMOYO_TYPE_RENAME, &path2,
-                               &path1);
-
-               if (err)
-                       return err;
-       }
-       return tomoyo_path2_perm(TOMOYO_TYPE_RENAME, &path1, &path2);
-}
-
-/**
- * tomoyo_file_fcntl - Target for security_file_fcntl().
- *
- * @file: Pointer to "struct file".
- * @cmd:  Command for fcntl().
- * @arg:  Argument for @cmd.
- *
- * Returns 0 on success, negative value otherwise.
- */
-static int tomoyo_file_fcntl(struct file *file, unsigned int cmd,
-                            unsigned long arg)
-{
-       if (!(cmd == F_SETFL && ((arg ^ file->f_flags) & O_APPEND)))
-               return 0;
-       return tomoyo_check_open_permission(tomoyo_domain(), &file->f_path,
-                                           O_WRONLY | (arg & O_APPEND));
-}
-
-/**
- * tomoyo_file_open - Target for security_file_open().
- *
- * @f: Pointer to "struct file".
- *
- * Returns 0 on success, negative value otherwise.
- */
-static int tomoyo_file_open(struct file *f)
-{
-       /* Don't check read permission here if called from execve(). */
-       /* Illogically, FMODE_EXEC is in f_flags, not f_mode. */
-       if (f->f_flags & __FMODE_EXEC)
-               return 0;
-       return tomoyo_check_open_permission(tomoyo_domain(), &f->f_path,
-                                           f->f_flags);
-}
-
-/**
- * tomoyo_file_ioctl - Target for security_file_ioctl().
- *
- * @file: Pointer to "struct file".
- * @cmd:  Command for ioctl().
- * @arg:  Argument for @cmd.
- *
- * Returns 0 on success, negative value otherwise.
- */
-static int tomoyo_file_ioctl(struct file *file, unsigned int cmd,
-                            unsigned long arg)
-{
-       return tomoyo_path_number_perm(TOMOYO_TYPE_IOCTL, &file->f_path, cmd);
-}
-
-/**
- * tomoyo_path_chmod - Target for security_path_chmod().
- *
- * @path: Pointer to "struct path".
- * @mode: DAC permission mode.
- *
- * Returns 0 on success, negative value otherwise.
- */
-static int tomoyo_path_chmod(const struct path *path, umode_t mode)
-{
-       return tomoyo_path_number_perm(TOMOYO_TYPE_CHMOD, path,
-                                      mode & S_IALLUGO);
-}
-
-/**
- * tomoyo_path_chown - Target for security_path_chown().
- *
- * @path: Pointer to "struct path".
- * @uid:  Owner ID.
- * @gid:  Group ID.
- *
- * Returns 0 on success, negative value otherwise.
- */
-static int tomoyo_path_chown(const struct path *path, kuid_t uid, kgid_t gid)
-{
-       int error = 0;
-
-       if (uid_valid(uid))
-               error = tomoyo_path_number_perm(TOMOYO_TYPE_CHOWN, path,
-                                               from_kuid(&init_user_ns, uid));
-       if (!error && gid_valid(gid))
-               error = tomoyo_path_number_perm(TOMOYO_TYPE_CHGRP, path,
-                                               from_kgid(&init_user_ns, gid));
-       return error;
-}
-
-/**
- * tomoyo_path_chroot - Target for security_path_chroot().
- *
- * @path: Pointer to "struct path".
- *
- * Returns 0 on success, negative value otherwise.
- */
-static int tomoyo_path_chroot(const struct path *path)
-{
-       return tomoyo_path_perm(TOMOYO_TYPE_CHROOT, path, NULL);
-}
-
-/**
- * tomoyo_sb_mount - Target for security_sb_mount().
- *
- * @dev_name: Name of device file. Maybe NULL.
- * @path:     Pointer to "struct path".
- * @type:     Name of filesystem type. Maybe NULL.
- * @flags:    Mount options.
- * @data:     Optional data. Maybe NULL.
- *
- * Returns 0 on success, negative value otherwise.
- */
-static int tomoyo_sb_mount(const char *dev_name, const struct path *path,
-                          const char *type, unsigned long flags, void *data)
-{
-       return tomoyo_mount_permission(dev_name, path, type, flags, data);
-}
-
-/**
- * tomoyo_sb_umount - Target for security_sb_umount().
- *
- * @mnt:   Pointer to "struct vfsmount".
- * @flags: Unmount options.
- *
- * Returns 0 on success, negative value otherwise.
- */
-static int tomoyo_sb_umount(struct vfsmount *mnt, int flags)
-{
-       struct path path = { .mnt = mnt, .dentry = mnt->mnt_root };
-
-       return tomoyo_path_perm(TOMOYO_TYPE_UMOUNT, &path, NULL);
-}
-
-/**
- * tomoyo_sb_pivotroot - Target for security_sb_pivotroot().
- *
- * @old_path: Pointer to "struct path".
- * @new_path: Pointer to "struct path".
- *
- * Returns 0 on success, negative value otherwise.
- */
-static int tomoyo_sb_pivotroot(const struct path *old_path, const struct path *new_path)
-{
-       return tomoyo_path2_perm(TOMOYO_TYPE_PIVOT_ROOT, new_path, old_path);
-}
-
-/**
- * tomoyo_socket_listen - Check permission for listen().
- *
- * @sock:    Pointer to "struct socket".
- * @backlog: Backlog parameter.
- *
- * Returns 0 on success, negative value otherwise.
- */
-static int tomoyo_socket_listen(struct socket *sock, int backlog)
-{
-       return tomoyo_socket_listen_permission(sock);
-}
-
-/**
- * tomoyo_socket_connect - Check permission for connect().
- *
- * @sock:     Pointer to "struct socket".
- * @addr:     Pointer to "struct sockaddr".
- * @addr_len: Size of @addr.
- *
- * Returns 0 on success, negative value otherwise.
- */
-static int tomoyo_socket_connect(struct socket *sock, struct sockaddr *addr,
-                                int addr_len)
-{
-       return tomoyo_socket_connect_permission(sock, addr, addr_len);
-}
-
-/**
- * tomoyo_socket_bind - Check permission for bind().
- *
- * @sock:     Pointer to "struct socket".
- * @addr:     Pointer to "struct sockaddr".
- * @addr_len: Size of @addr.
- *
- * Returns 0 on success, negative value otherwise.
- */
-static int tomoyo_socket_bind(struct socket *sock, struct sockaddr *addr,
-                             int addr_len)
-{
-       return tomoyo_socket_bind_permission(sock, addr, addr_len);
-}
-
-/**
- * tomoyo_socket_sendmsg - Check permission for sendmsg().
- *
- * @sock: Pointer to "struct socket".
- * @msg:  Pointer to "struct msghdr".
- * @size: Size of message.
- *
- * Returns 0 on success, negative value otherwise.
- */
-static int tomoyo_socket_sendmsg(struct socket *sock, struct msghdr *msg,
-                                int size)
-{
-       return tomoyo_socket_sendmsg_permission(sock, msg, size);
-}
-
-/**
- * tomoyo_task_alloc - Target for security_task_alloc().
- *
- * @task:        Pointer to "struct task_struct".
- * @clone_flags: clone() flags.
- *
- * Returns 0.
- */
-static int tomoyo_task_alloc(struct task_struct *task,
-                            unsigned long clone_flags)
-{
-       struct tomoyo_task *old = tomoyo_task(current);
-       struct tomoyo_task *new = tomoyo_task(task);
-
-       new->domain_info = old->domain_info;
-       atomic_inc(&new->domain_info->users);
-       new->old_domain_info = NULL;
-       return 0;
-}
-
-/**
- * tomoyo_task_free - Target for security_task_free().
- *
- * @task: Pointer to "struct task_struct".
- */
-static void tomoyo_task_free(struct task_struct *task)
-{
-       struct tomoyo_task *s = tomoyo_task(task);
-
-       if (s->domain_info) {
-               atomic_dec(&s->domain_info->users);
-               s->domain_info = NULL;
-       }
-       if (s->old_domain_info) {
-               atomic_dec(&s->old_domain_info->users);
-               s->old_domain_info = NULL;
-       }
-}
diff --git a/security/tomoyo/init.c b/security/tomoyo/init.c
deleted file mode 100644 (file)
index 034e7db..0000000
+++ /dev/null
@@ -1,366 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*
- * security/tomoyo/init.c
- *
- * Copyright (C) 2005-2011  NTT DATA CORPORATION
- */
-
-#include <linux/lsm_hooks.h>
-#include <uapi/linux/lsm.h>
-#include "common.h"
-
-#ifndef CONFIG_SECURITY_TOMOYO_LKM
-
-#include "hooks.h"
-
-#else
-
-#define DEFINE_STATIC_CALL_PROXY(NAME)                         \
-       static NAME##_t tomoyo_##NAME;                          \
-       DEFINE_STATIC_CALL_RET0(tomoyo_##NAME, tomoyo_##NAME);
-DEFINE_STATIC_CALL_PROXY(cred_prepare)
-DEFINE_STATIC_CALL_PROXY(bprm_committed_creds)
-DEFINE_STATIC_CALL_PROXY(bprm_check_security)
-DEFINE_STATIC_CALL_PROXY(inode_getattr)
-DEFINE_STATIC_CALL_PROXY(path_truncate)
-DEFINE_STATIC_CALL_PROXY(file_truncate)
-DEFINE_STATIC_CALL_PROXY(path_unlink)
-DEFINE_STATIC_CALL_PROXY(path_mkdir)
-DEFINE_STATIC_CALL_PROXY(path_rmdir)
-DEFINE_STATIC_CALL_PROXY(path_symlink)
-DEFINE_STATIC_CALL_PROXY(path_mknod)
-DEFINE_STATIC_CALL_PROXY(path_link)
-DEFINE_STATIC_CALL_PROXY(path_rename)
-DEFINE_STATIC_CALL_PROXY(file_fcntl)
-DEFINE_STATIC_CALL_PROXY(file_open)
-DEFINE_STATIC_CALL_PROXY(file_ioctl)
-DEFINE_STATIC_CALL_PROXY(path_chmod)
-DEFINE_STATIC_CALL_PROXY(path_chown)
-DEFINE_STATIC_CALL_PROXY(path_chroot)
-DEFINE_STATIC_CALL_PROXY(sb_mount)
-DEFINE_STATIC_CALL_PROXY(sb_umount)
-DEFINE_STATIC_CALL_PROXY(sb_pivotroot)
-DEFINE_STATIC_CALL_PROXY(socket_listen)
-DEFINE_STATIC_CALL_PROXY(socket_connect)
-DEFINE_STATIC_CALL_PROXY(socket_bind)
-DEFINE_STATIC_CALL_PROXY(socket_sendmsg)
-DEFINE_STATIC_CALL_PROXY(task_alloc)
-DEFINE_STATIC_CALL_PROXY(task_free)
-#undef DEFINE_STATIC_CALL_PROXY
-
-static int tomoyo_cred_prepare(struct cred *new, const struct cred *old, gfp_t gfp)
-{
-       return static_call(tomoyo_cred_prepare)(new, old, gfp);
-}
-
-static void tomoyo_bprm_committed_creds(const struct linux_binprm *bprm)
-{
-       static_call(tomoyo_bprm_committed_creds)(bprm);
-}
-
-static int tomoyo_bprm_check_security(struct linux_binprm *bprm)
-{
-       return static_call(tomoyo_bprm_check_security)(bprm);
-}
-
-static int tomoyo_inode_getattr(const struct path *path)
-{
-       return static_call(tomoyo_inode_getattr)(path);
-}
-
-static int tomoyo_path_truncate(const struct path *path)
-{
-       return static_call(tomoyo_path_truncate)(path);
-}
-
-static int tomoyo_file_truncate(struct file *file)
-{
-       return static_call(tomoyo_file_truncate)(file);
-}
-
-static int tomoyo_path_unlink(const struct path *parent, struct dentry *dentry)
-{
-       return static_call(tomoyo_path_unlink)(parent, dentry);
-}
-
-static int tomoyo_path_mkdir(const struct path *parent, struct dentry *dentry, umode_t mode)
-{
-       return static_call(tomoyo_path_mkdir)(parent, dentry, mode);
-}
-
-static int tomoyo_path_rmdir(const struct path *parent, struct dentry *dentry)
-{
-       return static_call(tomoyo_path_rmdir)(parent, dentry);
-}
-
-static int tomoyo_path_symlink(const struct path *parent, struct dentry *dentry,
-                              const char *old_name)
-{
-       return static_call(tomoyo_path_symlink)(parent, dentry, old_name);
-}
-
-static int tomoyo_path_mknod(const struct path *parent, struct dentry *dentry,
-                            umode_t mode, unsigned int dev)
-{
-       return static_call(tomoyo_path_mknod)(parent, dentry, mode, dev);
-}
-
-static int tomoyo_path_link(struct dentry *old_dentry, const struct path *new_dir,
-                           struct dentry *new_dentry)
-{
-       return static_call(tomoyo_path_link)(old_dentry, new_dir, new_dentry);
-}
-
-static int tomoyo_path_rename(const struct path *old_parent, struct dentry *old_dentry,
-                             const struct path *new_parent, struct dentry *new_dentry,
-                             const unsigned int flags)
-{
-       return static_call(tomoyo_path_rename)(old_parent, old_dentry, new_parent, new_dentry, flags);
-}
-
-static int tomoyo_file_fcntl(struct file *file, unsigned int cmd, unsigned long arg)
-{
-       return static_call(tomoyo_file_fcntl)(file, cmd, arg);
-}
-
-static int tomoyo_file_open(struct file *f)
-{
-       return static_call(tomoyo_file_open)(f);
-}
-
-static int tomoyo_file_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
-{
-       return static_call(tomoyo_file_ioctl)(file, cmd, arg);
-}
-
-static int tomoyo_path_chmod(const struct path *path, umode_t mode)
-{
-       return static_call(tomoyo_path_chmod)(path, mode);
-}
-
-static int tomoyo_path_chown(const struct path *path, kuid_t uid, kgid_t gid)
-{
-       return static_call(tomoyo_path_chown)(path, uid, gid);
-}
-
-static int tomoyo_path_chroot(const struct path *path)
-{
-       return static_call(tomoyo_path_chroot)(path);
-}
-
-static int tomoyo_sb_mount(const char *dev_name, const struct path *path,
-                          const char *type, unsigned long flags, void *data)
-{
-       return static_call(tomoyo_sb_mount)(dev_name, path, type, flags, data);
-}
-
-static int tomoyo_sb_umount(struct vfsmount *mnt, int flags)
-{
-       return static_call(tomoyo_sb_umount)(mnt, flags);
-}
-
-static int tomoyo_sb_pivotroot(const struct path *old_path, const struct path *new_path)
-{
-       return static_call(tomoyo_sb_pivotroot)(old_path, new_path);
-}
-
-static int tomoyo_socket_listen(struct socket *sock, int backlog)
-{
-       return static_call(tomoyo_socket_listen)(sock, backlog);
-}
-
-static int tomoyo_socket_connect(struct socket *sock, struct sockaddr *addr, int addr_len)
-{
-       return static_call(tomoyo_socket_connect)(sock, addr, addr_len);
-}
-
-static int tomoyo_socket_bind(struct socket *sock, struct sockaddr *addr, int addr_len)
-{
-       return static_call(tomoyo_socket_bind)(sock, addr, addr_len);
-}
-
-static int tomoyo_socket_sendmsg(struct socket *sock, struct msghdr *msg, int size)
-{
-       return static_call(tomoyo_socket_sendmsg)(sock, msg, size);
-}
-
-static int tomoyo_task_alloc(struct task_struct *task, unsigned long clone_flags)
-{
-       return static_call(tomoyo_task_alloc)(task, clone_flags);
-}
-
-static void tomoyo_task_free(struct task_struct *task)
-{
-       static_call(tomoyo_task_free)(task);
-}
-
-void tomoyo_register_hooks(const struct tomoyo_hooks *tomoyo_hooks)
-{
-       static void *registered;
-
-       if (cmpxchg(&registered, NULL, &registered))
-               panic("%s was called twice!\n", __func__);
-       static_call_update(tomoyo_task_free, tomoyo_hooks->task_free);
-       static_call_update(tomoyo_task_alloc, tomoyo_hooks->task_alloc);
-       static_call_update(tomoyo_cred_prepare, tomoyo_hooks->cred_prepare);
-       static_call_update(tomoyo_bprm_committed_creds, tomoyo_hooks->bprm_committed_creds);
-       static_call_update(tomoyo_bprm_check_security, tomoyo_hooks->bprm_check_security);
-       static_call_update(tomoyo_inode_getattr, tomoyo_hooks->inode_getattr);
-       static_call_update(tomoyo_path_truncate, tomoyo_hooks->path_truncate);
-       static_call_update(tomoyo_file_truncate, tomoyo_hooks->file_truncate);
-       static_call_update(tomoyo_path_unlink, tomoyo_hooks->path_unlink);
-       static_call_update(tomoyo_path_mkdir, tomoyo_hooks->path_mkdir);
-       static_call_update(tomoyo_path_rmdir, tomoyo_hooks->path_rmdir);
-       static_call_update(tomoyo_path_symlink, tomoyo_hooks->path_symlink);
-       static_call_update(tomoyo_path_mknod, tomoyo_hooks->path_mknod);
-       static_call_update(tomoyo_path_link, tomoyo_hooks->path_link);
-       static_call_update(tomoyo_path_rename, tomoyo_hooks->path_rename);
-       static_call_update(tomoyo_file_fcntl, tomoyo_hooks->file_fcntl);
-       static_call_update(tomoyo_file_open, tomoyo_hooks->file_open);
-       static_call_update(tomoyo_file_ioctl, tomoyo_hooks->file_ioctl);
-       static_call_update(tomoyo_path_chmod, tomoyo_hooks->path_chmod);
-       static_call_update(tomoyo_path_chown, tomoyo_hooks->path_chown);
-       static_call_update(tomoyo_path_chroot, tomoyo_hooks->path_chroot);
-       static_call_update(tomoyo_sb_mount, tomoyo_hooks->sb_mount);
-       static_call_update(tomoyo_sb_umount, tomoyo_hooks->sb_umount);
-       static_call_update(tomoyo_sb_pivotroot, tomoyo_hooks->sb_pivotroot);
-       static_call_update(tomoyo_socket_listen, tomoyo_hooks->socket_listen);
-       static_call_update(tomoyo_socket_connect, tomoyo_hooks->socket_connect);
-       static_call_update(tomoyo_socket_bind, tomoyo_hooks->socket_bind);
-       static_call_update(tomoyo_socket_sendmsg, tomoyo_hooks->socket_sendmsg);
-}
-EXPORT_SYMBOL_GPL(tomoyo_register_hooks);
-
-/*
- * Temporary hack: functions needed by tomoyo.ko . This hack will be removed
- * after all functions are marked as EXPORT_STMBOL_GPL().
- */
-#undef find_task_by_vpid
-#undef find_task_by_pid_ns
-#undef put_filesystem
-#undef get_mm_exe_file
-#undef d_absolute_path
-const struct tomoyo_tmp_exports tomoyo_tmp_exports = {
-       .find_task_by_vpid = find_task_by_vpid,
-       .find_task_by_pid_ns = find_task_by_pid_ns,
-       .put_filesystem = put_filesystem,
-       .get_mm_exe_file = get_mm_exe_file,
-       .d_absolute_path = d_absolute_path,
-};
-EXPORT_SYMBOL_GPL(tomoyo_tmp_exports);
-
-#endif
-
-#ifndef CONFIG_SECURITY_TOMOYO_OMIT_USERSPACE_LOADER
-static int tomoyo_bprm_creds_for_exec(struct linux_binprm *bprm)
-{
-       /*
-        * Load policy if /sbin/tomoyo-init exists and /sbin/init is requested
-        * for the first time.
-        */
-       if (!tomoyo_policy_loaded)
-               tomoyo_load_policy(bprm->filename);
-       return 0;
-}
-#endif
-
-struct lsm_blob_sizes tomoyo_blob_sizes __ro_after_init = {
-       .lbs_task = sizeof(struct tomoyo_task),
-};
-
-static const struct lsm_id tomoyo_lsmid = {
-       .name = "tomoyo",
-       .id = LSM_ID_TOMOYO,
-};
-
-/* tomoyo_hooks is used for registering TOMOYO. */
-static struct security_hook_list tomoyo_hooks[] __ro_after_init = {
-       LSM_HOOK_INIT(cred_prepare, tomoyo_cred_prepare),
-       LSM_HOOK_INIT(bprm_committed_creds, tomoyo_bprm_committed_creds),
-       LSM_HOOK_INIT(task_alloc, tomoyo_task_alloc),
-       LSM_HOOK_INIT(task_free, tomoyo_task_free),
-#ifndef CONFIG_SECURITY_TOMOYO_OMIT_USERSPACE_LOADER
-       LSM_HOOK_INIT(bprm_creds_for_exec, tomoyo_bprm_creds_for_exec),
-#endif
-       LSM_HOOK_INIT(bprm_check_security, tomoyo_bprm_check_security),
-       LSM_HOOK_INIT(file_fcntl, tomoyo_file_fcntl),
-       LSM_HOOK_INIT(file_open, tomoyo_file_open),
-       LSM_HOOK_INIT(file_truncate, tomoyo_file_truncate),
-       LSM_HOOK_INIT(path_truncate, tomoyo_path_truncate),
-       LSM_HOOK_INIT(path_unlink, tomoyo_path_unlink),
-       LSM_HOOK_INIT(path_mkdir, tomoyo_path_mkdir),
-       LSM_HOOK_INIT(path_rmdir, tomoyo_path_rmdir),
-       LSM_HOOK_INIT(path_symlink, tomoyo_path_symlink),
-       LSM_HOOK_INIT(path_mknod, tomoyo_path_mknod),
-       LSM_HOOK_INIT(path_link, tomoyo_path_link),
-       LSM_HOOK_INIT(path_rename, tomoyo_path_rename),
-       LSM_HOOK_INIT(inode_getattr, tomoyo_inode_getattr),
-       LSM_HOOK_INIT(file_ioctl, tomoyo_file_ioctl),
-       LSM_HOOK_INIT(file_ioctl_compat, tomoyo_file_ioctl),
-       LSM_HOOK_INIT(path_chmod, tomoyo_path_chmod),
-       LSM_HOOK_INIT(path_chown, tomoyo_path_chown),
-       LSM_HOOK_INIT(path_chroot, tomoyo_path_chroot),
-       LSM_HOOK_INIT(sb_mount, tomoyo_sb_mount),
-       LSM_HOOK_INIT(sb_umount, tomoyo_sb_umount),
-       LSM_HOOK_INIT(sb_pivotroot, tomoyo_sb_pivotroot),
-       LSM_HOOK_INIT(socket_bind, tomoyo_socket_bind),
-       LSM_HOOK_INIT(socket_connect, tomoyo_socket_connect),
-       LSM_HOOK_INIT(socket_listen, tomoyo_socket_listen),
-       LSM_HOOK_INIT(socket_sendmsg, tomoyo_socket_sendmsg),
-};
-
-int tomoyo_enabled __ro_after_init = 1;
-
-/* Has /sbin/init started? */
-bool tomoyo_policy_loaded;
-
-#ifdef CONFIG_SECURITY_TOMOYO_LKM
-EXPORT_SYMBOL_GPL(tomoyo_blob_sizes);
-EXPORT_SYMBOL_GPL(tomoyo_policy_loaded);
-
-struct tomoyo_operations tomoyo_ops;
-EXPORT_SYMBOL_GPL(tomoyo_ops);
-
-/**
- * tomoyo_init - Reserve hooks for TOMOYO Linux.
- *
- * Returns 0.
- */
-static int __init tomoyo_init(void)
-{
-       /* register ourselves with the security framework */
-       security_add_hooks(tomoyo_hooks, ARRAY_SIZE(tomoyo_hooks), &tomoyo_lsmid);
-       tomoyo_ops.enabled = tomoyo_enabled;
-       pr_info("Hooks for initializing TOMOYO Linux are ready\n");
-       return 0;
-}
-#else
-/**
- * tomoyo_init - Register TOMOYO Linux as a LSM module.
- *
- * Returns 0.
- */
-static int __init tomoyo_init(void)
-{
-       struct tomoyo_task *s = tomoyo_task(current);
-
-       /* register ourselves with the security framework */
-       security_add_hooks(tomoyo_hooks, ARRAY_SIZE(tomoyo_hooks),
-                          &tomoyo_lsmid);
-       pr_info("TOMOYO Linux initialized\n");
-       s->domain_info = &tomoyo_kernel_domain;
-       atomic_inc(&tomoyo_kernel_domain.users);
-       s->old_domain_info = NULL;
-       tomoyo_mm_init();
-
-       return 0;
-}
-#endif
-
-DEFINE_LSM(tomoyo) = {
-       .name = "tomoyo",
-       .enabled = &tomoyo_enabled,
-       .flags = LSM_FLAG_LEGACY_MAJOR,
-       .blobs = &tomoyo_blob_sizes,
-       .init = tomoyo_init,
-};
index 6a2a72354a64180fde2729b5babe7f4303018426..363b65be87ab768ed4993df1e5a361892958b3ab 100644 (file)
@@ -97,14 +97,6 @@ void tomoyo_load_policy(const char *filename)
        if (!tomoyo_policy_loader_exists())
                return;
        done = true;
-#ifdef CONFIG_SECURITY_TOMOYO_LKM
-       /* Load tomoyo.ko if not yet loaded. */
-       if (!tomoyo_ops.check_profile)
-               request_module("tomoyo");
-       /* Check if tomoyo.ko was successfully loaded. */
-       if (!tomoyo_ops.check_profile)
-               panic("Failed to load tomoyo module.");
-#endif
        pr_info("Calling %s to load policy. Please wait.\n", tomoyo_loader);
        argv[0] = (char *) tomoyo_loader;
        argv[1] = NULL;
@@ -112,11 +104,7 @@ void tomoyo_load_policy(const char *filename)
        envp[1] = "PATH=/sbin:/bin:/usr/sbin:/usr/bin";
        envp[2] = NULL;
        call_usermodehelper(argv[0], argv, envp, UMH_WAIT_PROC);
-#ifdef CONFIG_SECURITY_TOMOYO_LKM
-       tomoyo_ops.check_profile();
-#else
        tomoyo_check_profile();
-#endif
 }
 
 #endif
diff --git a/security/tomoyo/proxy.c b/security/tomoyo/proxy.c
deleted file mode 100644 (file)
index 1618cc0..0000000
+++ /dev/null
@@ -1,82 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*
- * security/tomoyo/proxy.c
- *
- * Copyright (C) 2005-2011  NTT DATA CORPORATION
- */
-
-#include <linux/security.h>
-#include "common.h"
-
-#ifdef CONFIG_SECURITY_TOMOYO_LKM
-
-struct tomoyo_task *tomoyo_task(struct task_struct *task)
-{
-       struct tomoyo_task *s = task->security + tomoyo_blob_sizes.lbs_task;
-
-       if (unlikely(!s->domain_info)) {
-               if (likely(task == current)) {
-                       s->domain_info = &tomoyo_kernel_domain;
-                       atomic_inc(&tomoyo_kernel_domain.users);
-               } else {
-                       /* Caller handles s->domain_info == NULL case. */
-               }
-       }
-       return s;
-}
-
-#include "hooks.h"
-
-/**
- * tomoyo_runtime_init - Register TOMOYO Linux as a loadable LSM module.
- *
- * Returns 0 if TOMOYO is enabled, -EINVAL otherwise.
- */
-static int __init tomoyo_runtime_init(void)
-{
-       const struct tomoyo_hooks tomoyo_hooks = {
-               .cred_prepare = tomoyo_cred_prepare,
-               .bprm_committed_creds = tomoyo_bprm_committed_creds,
-               .task_alloc = tomoyo_task_alloc,
-               .task_free = tomoyo_task_free,
-               .bprm_check_security = tomoyo_bprm_check_security,
-               .file_fcntl = tomoyo_file_fcntl,
-               .file_open = tomoyo_file_open,
-               .file_truncate = tomoyo_file_truncate,
-               .path_truncate = tomoyo_path_truncate,
-               .path_unlink = tomoyo_path_unlink,
-               .path_mkdir = tomoyo_path_mkdir,
-               .path_rmdir = tomoyo_path_rmdir,
-               .path_symlink = tomoyo_path_symlink,
-               .path_mknod = tomoyo_path_mknod,
-               .path_link = tomoyo_path_link,
-               .path_rename = tomoyo_path_rename,
-               .inode_getattr = tomoyo_inode_getattr,
-               .file_ioctl = tomoyo_file_ioctl,
-               .file_ioctl_compat = tomoyo_file_ioctl,
-               .path_chmod = tomoyo_path_chmod,
-               .path_chown = tomoyo_path_chown,
-               .path_chroot = tomoyo_path_chroot,
-               .sb_mount = tomoyo_sb_mount,
-               .sb_umount = tomoyo_sb_umount,
-               .sb_pivotroot = tomoyo_sb_pivotroot,
-               .socket_bind = tomoyo_socket_bind,
-               .socket_connect = tomoyo_socket_connect,
-               .socket_listen = tomoyo_socket_listen,
-               .socket_sendmsg = tomoyo_socket_sendmsg,
-       };
-
-       if (!tomoyo_ops.enabled)
-               return -EINVAL;
-       tomoyo_ops.check_profile = tomoyo_check_profile;
-       pr_info("TOMOYO Linux initialized\n");
-       tomoyo_task(current);
-       tomoyo_mm_init();
-       tomoyo_interface_init();
-       tomoyo_register_hooks(&tomoyo_hooks);
-       return 0;
-}
-module_init(tomoyo_runtime_init);
-MODULE_LICENSE("GPL");
-
-#endif
index a3b821b7f4771a140011b8f708a8baeed0b212de..a2705798476f9a7972c2ccdcef5d6a9d06f80401 100644 (file)
@@ -229,19 +229,17 @@ static void __init tomoyo_create_entry(const char *name, const umode_t mode,
 }
 
 /**
- * tomoyo_interface_init - Initialize /sys/kernel/security/tomoyo/ interface.
+ * tomoyo_initerface_init - Initialize /sys/kernel/security/tomoyo/ interface.
  *
  * Returns 0.
  */
-int __init tomoyo_interface_init(void)
+static int __init tomoyo_initerface_init(void)
 {
        struct tomoyo_domain_info *domain;
        struct dentry *tomoyo_dir;
 
-#ifndef CONFIG_SECURITY_TOMOYO_LKM
        if (!tomoyo_enabled)
                return 0;
-#endif
        domain = tomoyo_domain();
        /* Don't create securityfs entries unless registered. */
        if (domain != &tomoyo_kernel_domain)
@@ -272,6 +270,4 @@ int __init tomoyo_interface_init(void)
        return 0;
 }
 
-#ifndef CONFIG_SECURITY_TOMOYO_LKM
-fs_initcall(tomoyo_interface_init);
-#endif
+fs_initcall(tomoyo_initerface_init);
diff --git a/security/tomoyo/tomoyo.c b/security/tomoyo/tomoyo.c
new file mode 100644 (file)
index 0000000..04a92c3
--- /dev/null
@@ -0,0 +1,623 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * security/tomoyo/tomoyo.c
+ *
+ * Copyright (C) 2005-2011  NTT DATA CORPORATION
+ */
+
+#include <linux/lsm_hooks.h>
+#include <uapi/linux/lsm.h>
+#include "common.h"
+
+/**
+ * tomoyo_domain - Get "struct tomoyo_domain_info" for current thread.
+ *
+ * Returns pointer to "struct tomoyo_domain_info" for current thread.
+ */
+struct tomoyo_domain_info *tomoyo_domain(void)
+{
+       struct tomoyo_task *s = tomoyo_task(current);
+
+       if (s->old_domain_info && !current->in_execve) {
+               atomic_dec(&s->old_domain_info->users);
+               s->old_domain_info = NULL;
+       }
+       return s->domain_info;
+}
+
+/**
+ * tomoyo_cred_prepare - Target for security_prepare_creds().
+ *
+ * @new: Pointer to "struct cred".
+ * @old: Pointer to "struct cred".
+ * @gfp: Memory allocation flags.
+ *
+ * Returns 0.
+ */
+static int tomoyo_cred_prepare(struct cred *new, const struct cred *old,
+                              gfp_t gfp)
+{
+       /* Restore old_domain_info saved by previous execve() request. */
+       struct tomoyo_task *s = tomoyo_task(current);
+
+       if (s->old_domain_info && !current->in_execve) {
+               atomic_dec(&s->domain_info->users);
+               s->domain_info = s->old_domain_info;
+               s->old_domain_info = NULL;
+       }
+       return 0;
+}
+
+/**
+ * tomoyo_bprm_committed_creds - Target for security_bprm_committed_creds().
+ *
+ * @bprm: Pointer to "struct linux_binprm".
+ */
+static void tomoyo_bprm_committed_creds(const struct linux_binprm *bprm)
+{
+       /* Clear old_domain_info saved by execve() request. */
+       struct tomoyo_task *s = tomoyo_task(current);
+
+       atomic_dec(&s->old_domain_info->users);
+       s->old_domain_info = NULL;
+}
+
+#ifndef CONFIG_SECURITY_TOMOYO_OMIT_USERSPACE_LOADER
+/**
+ * tomoyo_bprm_creds_for_exec - Target for security_bprm_creds_for_exec().
+ *
+ * @bprm: Pointer to "struct linux_binprm".
+ *
+ * Returns 0.
+ */
+static int tomoyo_bprm_creds_for_exec(struct linux_binprm *bprm)
+{
+       /*
+        * Load policy if /sbin/tomoyo-init exists and /sbin/init is requested
+        * for the first time.
+        */
+       if (!tomoyo_policy_loaded)
+               tomoyo_load_policy(bprm->filename);
+       return 0;
+}
+#endif
+
+/**
+ * tomoyo_bprm_check_security - Target for security_bprm_check().
+ *
+ * @bprm: Pointer to "struct linux_binprm".
+ *
+ * Returns 0 on success, negative value otherwise.
+ */
+static int tomoyo_bprm_check_security(struct linux_binprm *bprm)
+{
+       struct tomoyo_task *s = tomoyo_task(current);
+
+       /*
+        * Execute permission is checked against pathname passed to execve()
+        * using current domain.
+        */
+       if (!s->old_domain_info) {
+               const int idx = tomoyo_read_lock();
+               const int err = tomoyo_find_next_domain(bprm);
+
+               tomoyo_read_unlock(idx);
+               return err;
+       }
+       /*
+        * Read permission is checked against interpreters using next domain.
+        */
+       return tomoyo_check_open_permission(s->domain_info,
+                                           &bprm->file->f_path, O_RDONLY);
+}
+
+/**
+ * tomoyo_inode_getattr - Target for security_inode_getattr().
+ *
+ * @path: Pointer to "struct path".
+ *
+ * Returns 0 on success, negative value otherwise.
+ */
+static int tomoyo_inode_getattr(const struct path *path)
+{
+       return tomoyo_path_perm(TOMOYO_TYPE_GETATTR, path, NULL);
+}
+
+/**
+ * tomoyo_path_truncate - Target for security_path_truncate().
+ *
+ * @path: Pointer to "struct path".
+ *
+ * Returns 0 on success, negative value otherwise.
+ */
+static int tomoyo_path_truncate(const struct path *path)
+{
+       return tomoyo_path_perm(TOMOYO_TYPE_TRUNCATE, path, NULL);
+}
+
+/**
+ * tomoyo_file_truncate - Target for security_file_truncate().
+ *
+ * @file: Pointer to "struct file".
+ *
+ * Returns 0 on success, negative value otherwise.
+ */
+static int tomoyo_file_truncate(struct file *file)
+{
+       return tomoyo_path_truncate(&file->f_path);
+}
+
+/**
+ * tomoyo_path_unlink - Target for security_path_unlink().
+ *
+ * @parent: Pointer to "struct path".
+ * @dentry: Pointer to "struct dentry".
+ *
+ * Returns 0 on success, negative value otherwise.
+ */
+static int tomoyo_path_unlink(const struct path *parent, struct dentry *dentry)
+{
+       struct path path = { .mnt = parent->mnt, .dentry = dentry };
+
+       return tomoyo_path_perm(TOMOYO_TYPE_UNLINK, &path, NULL);
+}
+
+/**
+ * tomoyo_path_mkdir - Target for security_path_mkdir().
+ *
+ * @parent: Pointer to "struct path".
+ * @dentry: Pointer to "struct dentry".
+ * @mode:   DAC permission mode.
+ *
+ * Returns 0 on success, negative value otherwise.
+ */
+static int tomoyo_path_mkdir(const struct path *parent, struct dentry *dentry,
+                            umode_t mode)
+{
+       struct path path = { .mnt = parent->mnt, .dentry = dentry };
+
+       return tomoyo_path_number_perm(TOMOYO_TYPE_MKDIR, &path,
+                                      mode & S_IALLUGO);
+}
+
+/**
+ * tomoyo_path_rmdir - Target for security_path_rmdir().
+ *
+ * @parent: Pointer to "struct path".
+ * @dentry: Pointer to "struct dentry".
+ *
+ * Returns 0 on success, negative value otherwise.
+ */
+static int tomoyo_path_rmdir(const struct path *parent, struct dentry *dentry)
+{
+       struct path path = { .mnt = parent->mnt, .dentry = dentry };
+
+       return tomoyo_path_perm(TOMOYO_TYPE_RMDIR, &path, NULL);
+}
+
+/**
+ * tomoyo_path_symlink - Target for security_path_symlink().
+ *
+ * @parent:   Pointer to "struct path".
+ * @dentry:   Pointer to "struct dentry".
+ * @old_name: Symlink's content.
+ *
+ * Returns 0 on success, negative value otherwise.
+ */
+static int tomoyo_path_symlink(const struct path *parent, struct dentry *dentry,
+                              const char *old_name)
+{
+       struct path path = { .mnt = parent->mnt, .dentry = dentry };
+
+       return tomoyo_path_perm(TOMOYO_TYPE_SYMLINK, &path, old_name);
+}
+
+/**
+ * tomoyo_path_mknod - Target for security_path_mknod().
+ *
+ * @parent: Pointer to "struct path".
+ * @dentry: Pointer to "struct dentry".
+ * @mode:   DAC permission mode.
+ * @dev:    Device attributes.
+ *
+ * Returns 0 on success, negative value otherwise.
+ */
+static int tomoyo_path_mknod(const struct path *parent, struct dentry *dentry,
+                            umode_t mode, unsigned int dev)
+{
+       struct path path = { .mnt = parent->mnt, .dentry = dentry };
+       int type = TOMOYO_TYPE_CREATE;
+       const unsigned int perm = mode & S_IALLUGO;
+
+       switch (mode & S_IFMT) {
+       case S_IFCHR:
+               type = TOMOYO_TYPE_MKCHAR;
+               break;
+       case S_IFBLK:
+               type = TOMOYO_TYPE_MKBLOCK;
+               break;
+       default:
+               goto no_dev;
+       }
+       return tomoyo_mkdev_perm(type, &path, perm, dev);
+ no_dev:
+       switch (mode & S_IFMT) {
+       case S_IFIFO:
+               type = TOMOYO_TYPE_MKFIFO;
+               break;
+       case S_IFSOCK:
+               type = TOMOYO_TYPE_MKSOCK;
+               break;
+       }
+       return tomoyo_path_number_perm(type, &path, perm);
+}
+
+/**
+ * tomoyo_path_link - Target for security_path_link().
+ *
+ * @old_dentry: Pointer to "struct dentry".
+ * @new_dir:    Pointer to "struct path".
+ * @new_dentry: Pointer to "struct dentry".
+ *
+ * Returns 0 on success, negative value otherwise.
+ */
+static int tomoyo_path_link(struct dentry *old_dentry, const struct path *new_dir,
+                           struct dentry *new_dentry)
+{
+       struct path path1 = { .mnt = new_dir->mnt, .dentry = old_dentry };
+       struct path path2 = { .mnt = new_dir->mnt, .dentry = new_dentry };
+
+       return tomoyo_path2_perm(TOMOYO_TYPE_LINK, &path1, &path2);
+}
+
+/**
+ * tomoyo_path_rename - Target for security_path_rename().
+ *
+ * @old_parent: Pointer to "struct path".
+ * @old_dentry: Pointer to "struct dentry".
+ * @new_parent: Pointer to "struct path".
+ * @new_dentry: Pointer to "struct dentry".
+ * @flags: Rename options.
+ *
+ * Returns 0 on success, negative value otherwise.
+ */
+static int tomoyo_path_rename(const struct path *old_parent,
+                             struct dentry *old_dentry,
+                             const struct path *new_parent,
+                             struct dentry *new_dentry,
+                             const unsigned int flags)
+{
+       struct path path1 = { .mnt = old_parent->mnt, .dentry = old_dentry };
+       struct path path2 = { .mnt = new_parent->mnt, .dentry = new_dentry };
+
+       if (flags & RENAME_EXCHANGE) {
+               const int err = tomoyo_path2_perm(TOMOYO_TYPE_RENAME, &path2,
+                               &path1);
+
+               if (err)
+                       return err;
+       }
+       return tomoyo_path2_perm(TOMOYO_TYPE_RENAME, &path1, &path2);
+}
+
+/**
+ * tomoyo_file_fcntl - Target for security_file_fcntl().
+ *
+ * @file: Pointer to "struct file".
+ * @cmd:  Command for fcntl().
+ * @arg:  Argument for @cmd.
+ *
+ * Returns 0 on success, negative value otherwise.
+ */
+static int tomoyo_file_fcntl(struct file *file, unsigned int cmd,
+                            unsigned long arg)
+{
+       if (!(cmd == F_SETFL && ((arg ^ file->f_flags) & O_APPEND)))
+               return 0;
+       return tomoyo_check_open_permission(tomoyo_domain(), &file->f_path,
+                                           O_WRONLY | (arg & O_APPEND));
+}
+
+/**
+ * tomoyo_file_open - Target for security_file_open().
+ *
+ * @f: Pointer to "struct file".
+ *
+ * Returns 0 on success, negative value otherwise.
+ */
+static int tomoyo_file_open(struct file *f)
+{
+       /* Don't check read permission here if called from execve(). */
+       /* Illogically, FMODE_EXEC is in f_flags, not f_mode. */
+       if (f->f_flags & __FMODE_EXEC)
+               return 0;
+       return tomoyo_check_open_permission(tomoyo_domain(), &f->f_path,
+                                           f->f_flags);
+}
+
+/**
+ * tomoyo_file_ioctl - Target for security_file_ioctl().
+ *
+ * @file: Pointer to "struct file".
+ * @cmd:  Command for ioctl().
+ * @arg:  Argument for @cmd.
+ *
+ * Returns 0 on success, negative value otherwise.
+ */
+static int tomoyo_file_ioctl(struct file *file, unsigned int cmd,
+                            unsigned long arg)
+{
+       return tomoyo_path_number_perm(TOMOYO_TYPE_IOCTL, &file->f_path, cmd);
+}
+
+/**
+ * tomoyo_path_chmod - Target for security_path_chmod().
+ *
+ * @path: Pointer to "struct path".
+ * @mode: DAC permission mode.
+ *
+ * Returns 0 on success, negative value otherwise.
+ */
+static int tomoyo_path_chmod(const struct path *path, umode_t mode)
+{
+       return tomoyo_path_number_perm(TOMOYO_TYPE_CHMOD, path,
+                                      mode & S_IALLUGO);
+}
+
+/**
+ * tomoyo_path_chown - Target for security_path_chown().
+ *
+ * @path: Pointer to "struct path".
+ * @uid:  Owner ID.
+ * @gid:  Group ID.
+ *
+ * Returns 0 on success, negative value otherwise.
+ */
+static int tomoyo_path_chown(const struct path *path, kuid_t uid, kgid_t gid)
+{
+       int error = 0;
+
+       if (uid_valid(uid))
+               error = tomoyo_path_number_perm(TOMOYO_TYPE_CHOWN, path,
+                                               from_kuid(&init_user_ns, uid));
+       if (!error && gid_valid(gid))
+               error = tomoyo_path_number_perm(TOMOYO_TYPE_CHGRP, path,
+                                               from_kgid(&init_user_ns, gid));
+       return error;
+}
+
+/**
+ * tomoyo_path_chroot - Target for security_path_chroot().
+ *
+ * @path: Pointer to "struct path".
+ *
+ * Returns 0 on success, negative value otherwise.
+ */
+static int tomoyo_path_chroot(const struct path *path)
+{
+       return tomoyo_path_perm(TOMOYO_TYPE_CHROOT, path, NULL);
+}
+
+/**
+ * tomoyo_sb_mount - Target for security_sb_mount().
+ *
+ * @dev_name: Name of device file. Maybe NULL.
+ * @path:     Pointer to "struct path".
+ * @type:     Name of filesystem type. Maybe NULL.
+ * @flags:    Mount options.
+ * @data:     Optional data. Maybe NULL.
+ *
+ * Returns 0 on success, negative value otherwise.
+ */
+static int tomoyo_sb_mount(const char *dev_name, const struct path *path,
+                          const char *type, unsigned long flags, void *data)
+{
+       return tomoyo_mount_permission(dev_name, path, type, flags, data);
+}
+
+/**
+ * tomoyo_sb_umount - Target for security_sb_umount().
+ *
+ * @mnt:   Pointer to "struct vfsmount".
+ * @flags: Unmount options.
+ *
+ * Returns 0 on success, negative value otherwise.
+ */
+static int tomoyo_sb_umount(struct vfsmount *mnt, int flags)
+{
+       struct path path = { .mnt = mnt, .dentry = mnt->mnt_root };
+
+       return tomoyo_path_perm(TOMOYO_TYPE_UMOUNT, &path, NULL);
+}
+
+/**
+ * tomoyo_sb_pivotroot - Target for security_sb_pivotroot().
+ *
+ * @old_path: Pointer to "struct path".
+ * @new_path: Pointer to "struct path".
+ *
+ * Returns 0 on success, negative value otherwise.
+ */
+static int tomoyo_sb_pivotroot(const struct path *old_path, const struct path *new_path)
+{
+       return tomoyo_path2_perm(TOMOYO_TYPE_PIVOT_ROOT, new_path, old_path);
+}
+
+/**
+ * tomoyo_socket_listen - Check permission for listen().
+ *
+ * @sock:    Pointer to "struct socket".
+ * @backlog: Backlog parameter.
+ *
+ * Returns 0 on success, negative value otherwise.
+ */
+static int tomoyo_socket_listen(struct socket *sock, int backlog)
+{
+       return tomoyo_socket_listen_permission(sock);
+}
+
+/**
+ * tomoyo_socket_connect - Check permission for connect().
+ *
+ * @sock:     Pointer to "struct socket".
+ * @addr:     Pointer to "struct sockaddr".
+ * @addr_len: Size of @addr.
+ *
+ * Returns 0 on success, negative value otherwise.
+ */
+static int tomoyo_socket_connect(struct socket *sock, struct sockaddr *addr,
+                                int addr_len)
+{
+       return tomoyo_socket_connect_permission(sock, addr, addr_len);
+}
+
+/**
+ * tomoyo_socket_bind - Check permission for bind().
+ *
+ * @sock:     Pointer to "struct socket".
+ * @addr:     Pointer to "struct sockaddr".
+ * @addr_len: Size of @addr.
+ *
+ * Returns 0 on success, negative value otherwise.
+ */
+static int tomoyo_socket_bind(struct socket *sock, struct sockaddr *addr,
+                             int addr_len)
+{
+       return tomoyo_socket_bind_permission(sock, addr, addr_len);
+}
+
+/**
+ * tomoyo_socket_sendmsg - Check permission for sendmsg().
+ *
+ * @sock: Pointer to "struct socket".
+ * @msg:  Pointer to "struct msghdr".
+ * @size: Size of message.
+ *
+ * Returns 0 on success, negative value otherwise.
+ */
+static int tomoyo_socket_sendmsg(struct socket *sock, struct msghdr *msg,
+                                int size)
+{
+       return tomoyo_socket_sendmsg_permission(sock, msg, size);
+}
+
+struct lsm_blob_sizes tomoyo_blob_sizes __ro_after_init = {
+       .lbs_task = sizeof(struct tomoyo_task),
+};
+
+/**
+ * tomoyo_task_alloc - Target for security_task_alloc().
+ *
+ * @task:        Pointer to "struct task_struct".
+ * @clone_flags: clone() flags.
+ *
+ * Returns 0.
+ */
+static int tomoyo_task_alloc(struct task_struct *task,
+                            unsigned long clone_flags)
+{
+       struct tomoyo_task *old = tomoyo_task(current);
+       struct tomoyo_task *new = tomoyo_task(task);
+
+       new->domain_info = old->domain_info;
+       atomic_inc(&new->domain_info->users);
+       new->old_domain_info = NULL;
+       return 0;
+}
+
+/**
+ * tomoyo_task_free - Target for security_task_free().
+ *
+ * @task: Pointer to "struct task_struct".
+ */
+static void tomoyo_task_free(struct task_struct *task)
+{
+       struct tomoyo_task *s = tomoyo_task(task);
+
+       if (s->domain_info) {
+               atomic_dec(&s->domain_info->users);
+               s->domain_info = NULL;
+       }
+       if (s->old_domain_info) {
+               atomic_dec(&s->old_domain_info->users);
+               s->old_domain_info = NULL;
+       }
+}
+
+static const struct lsm_id tomoyo_lsmid = {
+       .name = "tomoyo",
+       .id = LSM_ID_TOMOYO,
+};
+
+/*
+ * tomoyo_security_ops is a "struct security_operations" which is used for
+ * registering TOMOYO.
+ */
+static struct security_hook_list tomoyo_hooks[] __ro_after_init = {
+       LSM_HOOK_INIT(cred_prepare, tomoyo_cred_prepare),
+       LSM_HOOK_INIT(bprm_committed_creds, tomoyo_bprm_committed_creds),
+       LSM_HOOK_INIT(task_alloc, tomoyo_task_alloc),
+       LSM_HOOK_INIT(task_free, tomoyo_task_free),
+#ifndef CONFIG_SECURITY_TOMOYO_OMIT_USERSPACE_LOADER
+       LSM_HOOK_INIT(bprm_creds_for_exec, tomoyo_bprm_creds_for_exec),
+#endif
+       LSM_HOOK_INIT(bprm_check_security, tomoyo_bprm_check_security),
+       LSM_HOOK_INIT(file_fcntl, tomoyo_file_fcntl),
+       LSM_HOOK_INIT(file_open, tomoyo_file_open),
+       LSM_HOOK_INIT(file_truncate, tomoyo_file_truncate),
+       LSM_HOOK_INIT(path_truncate, tomoyo_path_truncate),
+       LSM_HOOK_INIT(path_unlink, tomoyo_path_unlink),
+       LSM_HOOK_INIT(path_mkdir, tomoyo_path_mkdir),
+       LSM_HOOK_INIT(path_rmdir, tomoyo_path_rmdir),
+       LSM_HOOK_INIT(path_symlink, tomoyo_path_symlink),
+       LSM_HOOK_INIT(path_mknod, tomoyo_path_mknod),
+       LSM_HOOK_INIT(path_link, tomoyo_path_link),
+       LSM_HOOK_INIT(path_rename, tomoyo_path_rename),
+       LSM_HOOK_INIT(inode_getattr, tomoyo_inode_getattr),
+       LSM_HOOK_INIT(file_ioctl, tomoyo_file_ioctl),
+       LSM_HOOK_INIT(file_ioctl_compat, tomoyo_file_ioctl),
+       LSM_HOOK_INIT(path_chmod, tomoyo_path_chmod),
+       LSM_HOOK_INIT(path_chown, tomoyo_path_chown),
+       LSM_HOOK_INIT(path_chroot, tomoyo_path_chroot),
+       LSM_HOOK_INIT(sb_mount, tomoyo_sb_mount),
+       LSM_HOOK_INIT(sb_umount, tomoyo_sb_umount),
+       LSM_HOOK_INIT(sb_pivotroot, tomoyo_sb_pivotroot),
+       LSM_HOOK_INIT(socket_bind, tomoyo_socket_bind),
+       LSM_HOOK_INIT(socket_connect, tomoyo_socket_connect),
+       LSM_HOOK_INIT(socket_listen, tomoyo_socket_listen),
+       LSM_HOOK_INIT(socket_sendmsg, tomoyo_socket_sendmsg),
+};
+
+/* Lock for GC. */
+DEFINE_SRCU(tomoyo_ss);
+
+int tomoyo_enabled __ro_after_init = 1;
+
+/**
+ * tomoyo_init - Register TOMOYO Linux as a LSM module.
+ *
+ * Returns 0.
+ */
+static int __init tomoyo_init(void)
+{
+       struct tomoyo_task *s = tomoyo_task(current);
+
+       /* register ourselves with the security framework */
+       security_add_hooks(tomoyo_hooks, ARRAY_SIZE(tomoyo_hooks),
+                          &tomoyo_lsmid);
+       pr_info("TOMOYO Linux initialized\n");
+       s->domain_info = &tomoyo_kernel_domain;
+       atomic_inc(&tomoyo_kernel_domain.users);
+       s->old_domain_info = NULL;
+       tomoyo_mm_init();
+
+       return 0;
+}
+
+DEFINE_LSM(tomoyo) = {
+       .name = "tomoyo",
+       .enabled = &tomoyo_enabled,
+       .flags = LSM_FLAG_LEGACY_MAJOR,
+       .blobs = &tomoyo_blob_sizes,
+       .init = tomoyo_init,
+};
index b851ff3773829f15c5e6a10d78fb23e8e6f2db25..6799b1122c9d88c4ae8e617490eff5c6b81deb83 100644 (file)
@@ -13,6 +13,9 @@
 /* Lock for protecting policy. */
 DEFINE_MUTEX(tomoyo_policy_lock);
 
+/* Has /sbin/init started? */
+bool tomoyo_policy_loaded;
+
 /*
  * Mapping table from "enum tomoyo_mac_index" to
  * "enum tomoyo_mac_category_index".
index 4c036a9a420ab5d7487813bec7f58d977a10091d..8b40205394fe00c7e3c8d31e4b5a6a7f350bd9a3 100644 (file)
@@ -1,7 +1,7 @@
 # SPDX-License-Identifier: GPL-2.0-only
 menuconfig SOUND
        tristate "Sound card support"
-       depends on HAS_IOMEM || UML
+       depends on HAS_IOMEM || INDIRECT_IOMEM
        help
          If you have a sound card in your computer, i.e. if it can say more
          than an occasional beep, say Y.
index e90e03bb0dc09fc19119963b08d2007e2982fcac..ac347a14f282cf9c1fa1c39bf69c2959192ad491 100644 (file)
@@ -1040,7 +1040,7 @@ static void onyx_i2c_remove(struct i2c_client *client)
 }
 
 static const struct i2c_device_id onyx_i2c_id[] = {
-       { "MAC,pcm3052", 0 },
+       { "MAC,pcm3052" },
        { }
 };
 MODULE_DEVICE_TABLE(i2c,onyx_i2c_id);
index be9822ebf9f8ace734251b96d07af6b4a0b83f41..804b2ebbe28fe8565dca87529695e6cabf824f3f 100644 (file)
@@ -927,7 +927,7 @@ static void tas_i2c_remove(struct i2c_client *client)
 }
 
 static const struct i2c_device_id tas_i2c_id[] = {
-       { "MAC,tas3004", 0 },
+       { "MAC,tas3004" },
        { }
 };
 MODULE_DEVICE_TABLE(i2c,tas_i2c_id);
index b8c0d6edbdd187e0b4114af824b01568cd398b26..bdf1d78de8338aad28c5098eeb26981518f4aab8 100644 (file)
@@ -288,7 +288,7 @@ static ssize_t snd_compr_write(struct file *f, const char __user *buf,
 
        stream = &data->stream;
        guard(mutex)(&stream->device->lock);
-       /* write is allowed when stream is running or has been steup */
+       /* write is allowed when stream is running or has been setup */
        switch (stream->runtime->state) {
        case SNDRV_PCM_STATE_SETUP:
        case SNDRV_PCM_STATE_PREPARED:
index 2f790a7b1e90421ef37150955115095d2b5a4579..0ddade871b524afee3c0f58da56f738364df20a9 100644 (file)
@@ -1641,6 +1641,8 @@ static int snd_ctl_elem_add(struct snd_ctl_file *file,
        count = info->owner;
        if (count == 0)
                count = 1;
+       if (count > MAX_CONTROL_COUNT)
+               return -EINVAL;
 
        /* Arrange access permissions if needed. */
        access = info->access;
index b92aa7103589e5ab8727dc4606e076a7d2e7c401..114fb87de990e70c90e427fc299e933a37b2d73b 100644 (file)
@@ -654,13 +654,19 @@ void snd_card_free(struct snd_card *card)
 }
 EXPORT_SYMBOL(snd_card_free);
 
+/* check, if the character is in the valid ASCII range */
+static inline bool safe_ascii_char(char c)
+{
+       return isascii(c) && isalnum(c);
+}
+
 /* retrieve the last word of shortname or longname */
 static const char *retrieve_id_from_card_name(const char *name)
 {
        const char *spos = name;
 
        while (*name) {
-               if (isspace(*name) && isalnum(name[1]))
+               if (isspace(*name) && safe_ascii_char(name[1]))
                        spos = name + 1;
                name++;
        }
@@ -687,12 +693,12 @@ static void copy_valid_id_string(struct snd_card *card, const char *src,
 {
        char *id = card->id;
 
-       while (*nid && !isalnum(*nid))
+       while (*nid && !safe_ascii_char(*nid))
                nid++;
        if (isdigit(*nid))
                *id++ = isalpha(*src) ? *src : 'D';
        while (*nid && (size_t)(id - card->id) < sizeof(card->id) - 1) {
-               if (isalnum(*nid))
+               if (safe_ascii_char(*nid))
                        *id++ = *nid;
                nid++;
        }
@@ -787,7 +793,7 @@ static ssize_t id_store(struct device *dev, struct device_attribute *attr,
 
        for (idx = 0; idx < copy; idx++) {
                c = buf[idx];
-               if (!isalnum(c) && c != '_' && c != '-')
+               if (!safe_ascii_char(c) && c != '_' && c != '-')
                        return -EINVAL;
        }
        memcpy(buf1, buf, copy);
index 668604d0ec9d463419e2ee416916c1d032b7823e..05fc8911479c19d43f59a23a70e8392e64142900 100644 (file)
@@ -900,8 +900,8 @@ static void snd_mixer_oss_slot_free(struct snd_mixer_oss_slot *chn)
        struct slot *p = chn->private_data;
        if (p) {
                if (p->allocated && p->assigned) {
-                       kfree_const(p->assigned->name);
-                       kfree_const(p->assigned);
+                       kfree(p->assigned->name);
+                       kfree(p->assigned);
                }
                kfree(p);
        }
index 98269119347fed5010fe4e6a6a061855e83e33af..b56eeda5e30e778a51896cd1c082347ff33f6eda 100644 (file)
@@ -294,7 +294,7 @@ static int rate_action(struct snd_pcm_plugin *plugin,
        default:
                break;
        }
-       return 0;       /* silenty ignore other actions */
+       return 0;       /* silently ignore other actions */
 }
 
 int snd_pcm_plugin_build_rate(struct snd_pcm_substream *plug,
index 5b9076829adef4ade5c0f0e0031c5522a2a36bcb..b465fb6e1f5f0da620c21724428ea7d6432db1ed 100644 (file)
@@ -3115,7 +3115,7 @@ struct snd_pcm_sync_ptr32 {
        } c;
 } __packed;
 
-/* recalcuate the boundary within 32bit */
+/* recalculate the boundary within 32bit */
 static snd_pcm_uframes_t recalculate_boundary(struct snd_pcm_runtime *runtime)
 {
        snd_pcm_uframes_t boundary;
index b9db9aa0bfcb583a143a88347ab7d4cdf37321fa..6531a67f13b3e70ea69987d88fd0e659d0054857 100644 (file)
@@ -133,7 +133,7 @@ static struct snd_minor *autoload_device(unsigned int minor)
                /* /dev/aloadSEQ */
                snd_request_other(minor);
        }
-       mutex_lock(&sound_mutex); /* reacuire lock */
+       mutex_lock(&sound_mutex); /* reacquire lock */
        return snd_minors[minor];
 }
 #else /* !CONFIG_MODULES */
index c72b2a75477598da7e08e1d4fead83a75d69de34..7fc51f829eccac2dde0a147a4c56d51943118c92 100644 (file)
@@ -172,6 +172,9 @@ static int apply_constraint_to_size(struct snd_pcm_hw_params *params,
                        step = max(step, amdtp_syt_intervals[i]);
        }
 
+       if (step == 0)
+               return -EINVAL;
+
        t.min = roundup(s->min, step);
        t.max = rounddown(s->max, step);
        t.integer = 1;
index b53de020309f2bc1db45b88004986f628680cd54..2670792f43b41b65419cc26f235ca659f0f43de8 100644 (file)
@@ -657,6 +657,7 @@ static void azx_timecounter_init(struct hdac_stream *azx_dev,
  * snd_hdac_stream_timecounter_init - initialize time counter
  * @azx_dev: HD-audio core stream (master stream)
  * @streams: bit flags of streams to set up
+ * @start: true for PCM trigger start, false for other cases
  *
  * Initializes the time counter of streams marked by the bit flags (each
  * bit corresponds to the stream index).
@@ -664,7 +665,7 @@ static void azx_timecounter_init(struct hdac_stream *azx_dev,
  * updated accordingly, too.
  */
 void snd_hdac_stream_timecounter_init(struct hdac_stream *azx_dev,
-                                     unsigned int streams)
+                                     unsigned int streams, bool start)
 {
        struct hdac_bus *bus = azx_dev->bus;
        struct snd_pcm_runtime *runtime = azx_dev->substream->runtime;
@@ -672,6 +673,9 @@ void snd_hdac_stream_timecounter_init(struct hdac_stream *azx_dev,
        bool inited = false;
        u64 cycle_last = 0;
 
+       if (!start)
+               goto skip;
+
        list_for_each_entry(s, &bus->stream_list, list) {
                if ((streams & (1 << s->index))) {
                        azx_timecounter_init(s, inited, cycle_last);
@@ -682,6 +686,7 @@ void snd_hdac_stream_timecounter_init(struct hdac_stream *azx_dev,
                }
        }
 
+skip:
        snd_pcm_gettime(runtime, &runtime->trigger_tstamp);
        runtime->trigger_tstamp_latched = true;
 }
index f018bd77986243f48182616875c6d742e91b8c39..9f849e05ce79f8fa073893fd6f5295dd8a57b284 100644 (file)
@@ -721,6 +721,10 @@ static const struct config_entry acpi_config_table[] = {
 #if IS_ENABLED(CONFIG_SND_SST_ATOM_HIFI2_PLATFORM_ACPI) || \
     IS_ENABLED(CONFIG_SND_SOC_SOF_BAYTRAIL)
 /* BayTrail */
+       {
+               .flags = FLAG_SST_OR_SOF_BYT,
+               .acpi_hid = "LPE0F28",
+       },
        {
                .flags = FLAG_SST_OR_SOF_BYT,
                .acpi_hid = "80860F28",
index 04d6b6beabca5873c33e1f4b585bae1973938f8a..ed530e0dd4ddcc9dc3ebe107a823835b414e6150 100644 (file)
@@ -56,18 +56,21 @@ static int
 sdw_intel_scan_controller(struct sdw_intel_acpi_info *info)
 {
        struct acpi_device *adev = acpi_fetch_acpi_dev(info->handle);
-       u8 count, i;
+       struct fwnode_handle *fwnode;
+       unsigned long list;
+       unsigned int i;
+       u32 count;
+       u32 tmp;
        int ret;
 
        if (!adev)
                return -EINVAL;
 
-       /* Found controller, find links supported */
-       count = 0;
-       ret = fwnode_property_read_u8_array(acpi_fwnode_handle(adev),
-                                           "mipi-sdw-master-count", &count, 1);
+       fwnode = acpi_fwnode_handle(adev);
 
        /*
+        * Found controller, find links supported
+        *
         * In theory we could check the number of links supported in
         * hardware, but in that step we cannot assume SoundWire IP is
         * powered.
@@ -78,11 +81,19 @@ sdw_intel_scan_controller(struct sdw_intel_acpi_info *info)
         *
         * We will check the hardware capabilities in the startup() step
         */
-
+       ret = fwnode_property_read_u32(fwnode, "mipi-sdw-manager-list", &tmp);
        if (ret) {
-               dev_err(&adev->dev,
-                       "Failed to read mipi-sdw-master-count: %d\n", ret);
-               return -EINVAL;
+               ret = fwnode_property_read_u32(fwnode, "mipi-sdw-master-count", &count);
+               if (ret) {
+                       dev_err(&adev->dev,
+                               "Failed to read mipi-sdw-master-count: %d\n",
+                               ret);
+                       return ret;
+               }
+               list = GENMASK(count - 1, 0);
+       } else {
+               list = tmp;
+               count = hweight32(list);
        }
 
        /* Check count is within bounds */
@@ -101,14 +112,14 @@ sdw_intel_scan_controller(struct sdw_intel_acpi_info *info)
        info->count = count;
        info->link_mask = 0;
 
-       for (i = 0; i < count; i++) {
+       for_each_set_bit(i, &list, SDW_INTEL_MAX_LINKS) {
                if (ctrl_link_mask && !(ctrl_link_mask & BIT(i))) {
                        dev_dbg(&adev->dev,
                                "Link %d masked, will not be enabled\n", i);
                        continue;
                }
 
-               if (!is_link_enabled(acpi_fwnode_handle(adev), i)) {
+               if (!is_link_enabled(fwnode, i)) {
                        dev_dbg(&adev->dev,
                                "Link %d not selected in firmware\n", i);
                        continue;
index 29a1a7a0d050c6475b9c28fc2788151013d3baf3..46f0812683484020df914d515ba4bab73a338e24 100644 (file)
@@ -10,7 +10,7 @@
 #include <linux/init.h>
 #include <linux/bitrev.h>
 #include <linux/module.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include <sound/core.h>
 #include <sound/control.h>
 #include <sound/pcm.h>
index bcbcaa924c12781d0971b4f7cbae235ca83bedd8..16f9bbb43a5442a25bfcdeaafc674dd626564c2f 100644 (file)
@@ -364,7 +364,7 @@ static int snd_gf1_pcm_playback_copy(struct snd_pcm_substream *substream,
 
        bpos = get_bpos(pcmp, voice, pos, len);
        if (bpos < 0)
-               return pos;
+               return bpos;
        if (copy_from_iter(runtime->dma_area + bpos, len, src) != len)
                return -EFAULT;
        return playback_copy_ack(substream, bpos, len);
@@ -381,7 +381,7 @@ static int snd_gf1_pcm_playback_silence(struct snd_pcm_substream *substream,
        
        bpos = get_bpos(pcmp, voice, pos, len);
        if (bpos < 0)
-               return pos;
+               return bpos;
        snd_pcm_format_set_silence(runtime->format, runtime->dma_area + bpos,
                                   bytes_to_samples(runtime, count));
        return playback_copy_ack(substream, bpos, len);
index bb15a0248250cc42844e5fa08811ff774178937e..68f1eee9e5c938372577663f965f6a173b1f14ed 100644 (file)
@@ -198,7 +198,7 @@ config SND_HDA_SCODEC_TAS2781_I2C
        depends on SND_SOC
        select SND_SOC_TAS2781_COMLIB
        select SND_SOC_TAS2781_FMWLIB
-       select CRC32_SARWATE
+       select CRC32
        help
          Say Y or M here to include TAS2781 I2C HD-audio side codec support
          in snd-hda-intel driver, such as ALC287.
index 603e9bff3a71dc138529dc4ae8dfe1a7a16150dc..bb84740c852076a7cd589c48e890177971f53b43 100644 (file)
@@ -39,7 +39,7 @@ static void cs35l41_hda_i2c_remove(struct i2c_client *clt)
 }
 
 static const struct i2c_device_id cs35l41_hda_i2c_id[] = {
-       { "cs35l41-hda", 0 },
+       { "cs35l41-hda" },
        {}
 };
 
index 3dd1bda0c5c69ef4be01b9e40d3d08124f30792e..14763c0f31ad9ff2c1eafa646bc7d815254dd573 100644 (file)
@@ -1734,9 +1734,9 @@ EXPORT_SYMBOL_GPL(snd_hda_ctl_add);
 /**
  * snd_hda_add_nid - Assign a NID to a control element
  * @codec: HD-audio codec
- * @nid: corresponding NID (optional)
  * @kctl: the control element to assign
  * @index: index to kctl
+ * @nid: corresponding NID (optional)
  *
  * Add the given control element to an array inside the codec instance.
  * This function is used when #snd_hda_ctl_add cannot be used for 1:1
index 5d86e5a9c814a51248c8d57f5c7e740cd6ebb4d6..f3330b7e0fcfc97eb452d1429631444a6a35a18a 100644 (file)
@@ -275,8 +275,7 @@ static int azx_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
        spin_lock(&bus->reg_lock);
        /* reset SYNC bits */
        snd_hdac_stream_sync_trigger(hstr, false, sbits, sync_reg);
-       if (start)
-               snd_hdac_stream_timecounter_init(hstr, sbits);
+       snd_hdac_stream_timecounter_init(hstr, sbits, start);
        spin_unlock(&bus->reg_lock);
        return 0;
 }
index 68c883f202ca5bac763b0b07a81084067df4ec60..c2d0109866e62e5a93f915ad202ce71c0f84d6b9 100644 (file)
@@ -28,7 +28,7 @@
 #else
 #define AZX_DCAPS_I915_COMPONENT 0             /* NOP */
 #endif
-#define AZX_DCAPS_AMD_ALLOC_FIX        (1 << 14)       /* AMD allocation workaround */
+/* 14 unused */
 #define AZX_DCAPS_CTX_WORKAROUND (1 << 15)     /* X-Fi workaround */
 #define AZX_DCAPS_POSFIX_LPIB  (1 << 16)       /* Use LPIB as default */
 #define AZX_DCAPS_AMD_WORKAROUND (1 << 17)     /* AMD-specific workaround */
index 1d108ed5c6f2518a33db6e78ddaff2301319dbff..301730432375707ae7c143aac289244a9234e04a 100644 (file)
@@ -12,7 +12,7 @@
 #include <linux/init.h>
 #include <linux/slab.h>
 #include <sound/core.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include <sound/hda_chmap.h>
 #include <sound/hda_codec.h>
 #include "hda_local.h"
index 9cff87dfbecbb1fffa35a3d8819ac82c51571bb5..b34d84fedcc8ab46a925ee8893883ea5d08df530 100644 (file)
@@ -1383,7 +1383,7 @@ static int try_assign_dacs(struct hda_codec *codec, int num_outs,
                struct nid_path *path;
                hda_nid_t pin = pins[i];
 
-               if (!spec->obey_preferred_dacs) {
+               if (!spec->preferred_dacs) {
                        path = snd_hda_get_path_from_idx(codec, path_idx[i]);
                        if (path) {
                                badness += assign_out_path_ctls(codec, path);
@@ -1395,7 +1395,7 @@ static int try_assign_dacs(struct hda_codec *codec, int num_outs,
                if (dacs[i]) {
                        if (is_dac_already_used(codec, dacs[i]))
                                badness += bad->shared_primary;
-               } else if (spec->obey_preferred_dacs) {
+               } else if (spec->preferred_dacs) {
                        badness += BAD_NO_PRIMARY_DAC;
                }
 
index 08544601b4ce29865035734fa59901159dfbeff1..9612afaa61c2097d02ce376f57c576dd45ee9d01 100644 (file)
@@ -232,7 +232,6 @@ struct hda_gen_spec {
        unsigned int power_down_unused:1; /* power down unused widgets */
        unsigned int dac_min_mute:1; /* minimal = mute for DACs */
        unsigned int suppress_vmaster:1; /* don't create vmaster kctls */
-       unsigned int obey_preferred_dacs:1; /* obey preferred_dacs assignment */
 
        /* other internal flags */
        unsigned int no_analog:1; /* digital I/O only */
index 045cd555c2910fbe824fa2d8f69b41ae79c10466..b4540c5cd2a6f9cffcb02615cfcd3df44396e0e6 100644 (file)
@@ -40,7 +40,6 @@
 
 #ifdef CONFIG_X86
 /* for snoop control */
-#include <linux/dma-map-ops.h>
 #include <asm/set_memory.h>
 #include <asm/cpufeature.h>
 #endif
@@ -307,7 +306,7 @@ enum {
 
 /* quirks for ATI HDMI with snoop off */
 #define AZX_DCAPS_PRESET_ATI_HDMI_NS \
-       (AZX_DCAPS_PRESET_ATI_HDMI | AZX_DCAPS_AMD_ALLOC_FIX)
+       (AZX_DCAPS_PRESET_ATI_HDMI | AZX_DCAPS_SNOOP_OFF)
 
 /* quirks for AMD SB */
 #define AZX_DCAPS_PRESET_AMD_SB \
@@ -1707,13 +1706,6 @@ static void azx_check_snoop_available(struct azx *chip)
        if (chip->driver_caps & AZX_DCAPS_SNOOP_OFF)
                snoop = false;
 
-#ifdef CONFIG_X86
-       /* check the presence of DMA ops (i.e. IOMMU), disable snoop conditionally */
-       if ((chip->driver_caps & AZX_DCAPS_AMD_ALLOC_FIX) &&
-           !get_dma_ops(chip->card->dev))
-               snoop = false;
-#endif
-
        chip->snoop = snoop;
        if (!snoop) {
                dev_info(chip->card->dev, "Force to non-snoop mode\n");
index e851785ff058146fc8100116e4486faffafdf611..c74f6742c35955e51aefe10081bff3bd2290e05d 100644 (file)
@@ -166,18 +166,18 @@ static void cxt_init_gpio_led(struct hda_codec *codec)
 
 static void cx_fixup_headset_recog(struct hda_codec *codec)
 {
-       unsigned int mic_persent;
+       unsigned int mic_present;
 
        /* fix some headset type recognize fail issue, such as EDIFIER headset */
-       /* set micbiasd output current comparator threshold from 66% to 55%. */
+       /* set micbias output current comparator threshold from 66% to 55%. */
        snd_hda_codec_write(codec, 0x1c, 0, 0x320, 0x010);
-       /* set OFF voltage for DFET from -1.2V to -0.8V, set headset micbias registor
+       /* set OFF voltage for DFET from -1.2V to -0.8V, set headset micbias register
         * value adjustment trim from 2.2K ohms to 2.0K ohms.
         */
        snd_hda_codec_write(codec, 0x1c, 0, 0x3b0, 0xe10);
        /* fix reboot headset type recognize fail issue */
-       mic_persent = snd_hda_codec_read(codec, 0x19, 0, AC_VERB_GET_PIN_SENSE, 0x0);
-       if (mic_persent & AC_PINSENSE_PRESENCE)
+       mic_present = snd_hda_codec_read(codec, 0x19, 0, AC_VERB_GET_PIN_SENSE, 0x0);
+       if (mic_present & AC_PINSENSE_PRESENCE)
                /* enable headset mic VREF */
                snd_hda_codec_write(codec, 0x19, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24);
        else
@@ -249,9 +249,9 @@ static void cx_update_headset_mic_vref(struct hda_codec *codec, struct hda_jack_
 {
        unsigned int mic_present;
 
-       /* In cx8070 and sn6140, the node 16 can only be config to headphone or disabled,
-        * the node 19 can only be config to microphone or disabled.
-        * Check hp&mic tag to process headset pulgin&plugout.
+       /* In cx8070 and sn6140, the node 16 can only be configured to headphone or disabled,
+        * the node 19 can only be configured to microphone or disabled.
+        * Check hp&mic tag to process headset plugin & plugout.
         */
        mic_present = snd_hda_codec_read(codec, 0x19, 0, AC_VERB_GET_PIN_SENSE, 0x0);
        if (!(mic_present & AC_PINSENSE_PRESENCE)) /* mic plugout */
@@ -303,6 +303,7 @@ enum {
        CXT_FIXUP_HP_SPECTRE,
        CXT_FIXUP_HP_GATE_MIC,
        CXT_FIXUP_MUTE_LED_GPIO,
+       CXT_FIXUP_HP_ELITEONE_OUT_DIS,
        CXT_FIXUP_HP_ZBOOK_MUTE_LED,
        CXT_FIXUP_HEADSET_MIC,
        CXT_FIXUP_HP_MIC_NO_PRESENCE,
@@ -320,6 +321,19 @@ static void cxt_fixup_stereo_dmic(struct hda_codec *codec,
        spec->gen.inv_dmic_split = 1;
 }
 
+/* fix widget control pin settings */
+static void cxt_fixup_update_pinctl(struct hda_codec *codec,
+                                  const struct hda_fixup *fix, int action)
+{
+       if (action == HDA_FIXUP_ACT_PROBE) {
+               /* Unset OUT_EN for this Node pin, leaving only HP_EN.
+                * This is the value stored in the codec register after
+                * the correct initialization of the previous windows boot.
+                */
+               snd_hda_set_pin_ctl_cache(codec, 0x1d, AC_PINCTL_HP_EN);
+       }
+}
+
 static void cxt5066_increase_mic_boost(struct hda_codec *codec,
                                   const struct hda_fixup *fix, int action)
 {
@@ -816,6 +830,23 @@ static const struct hda_pintbl cxt_pincfg_sws_js201d[] = {
        {}
 };
 
+/* pincfg quirk for Tuxedo Sirius;
+ * unfortunately the (PCI) SSID conflicts with System76 Pangolin pang14,
+ * which has incompatible pin setup, so we check the codec SSID (luckily
+ * different one!) and conditionally apply the quirk here
+ */
+static void cxt_fixup_sirius_top_speaker(struct hda_codec *codec,
+                                        const struct hda_fixup *fix,
+                                        int action)
+{
+       /* ignore for incorrectly picked-up pang14 */
+       if (codec->core.subsystem_id == 0x278212b3)
+               return;
+       /* set up the top speaker pin */
+       if (action == HDA_FIXUP_ACT_PRE_PROBE)
+               snd_hda_codec_set_pincfg(codec, 0x1d, 0x82170111);
+}
+
 static const struct hda_fixup cxt_fixups[] = {
        [CXT_PINCFG_LENOVO_X200] = {
                .type = HDA_FIXUP_PINS,
@@ -954,6 +985,10 @@ static const struct hda_fixup cxt_fixups[] = {
                .type = HDA_FIXUP_FUNC,
                .v.func = cxt_fixup_mute_led_gpio,
        },
+       [CXT_FIXUP_HP_ELITEONE_OUT_DIS] = {
+               .type = HDA_FIXUP_FUNC,
+               .v.func = cxt_fixup_update_pinctl,
+       },
        [CXT_FIXUP_HP_ZBOOK_MUTE_LED] = {
                .type = HDA_FIXUP_FUNC,
                .v.func = cxt_fixup_hp_zbook_mute_led,
@@ -976,11 +1011,8 @@ static const struct hda_fixup cxt_fixups[] = {
                .v.pins = cxt_pincfg_sws_js201d,
        },
        [CXT_PINCFG_TOP_SPEAKER] = {
-               .type = HDA_FIXUP_PINS,
-               .v.pins = (const struct hda_pintbl[]) {
-                       { 0x1d, 0x82170111 },
-                       { }
-               },
+               .type = HDA_FIXUP_FUNC,
+               .v.func = cxt_fixup_sirius_top_speaker,
        },
 };
 
@@ -1047,6 +1079,7 @@ static const struct snd_pci_quirk cxt5066_fixups[] = {
        SND_PCI_QUIRK(0x103c, 0x83b2, "HP EliteBook 840 G5", CXT_FIXUP_HP_DOCK),
        SND_PCI_QUIRK(0x103c, 0x83b3, "HP EliteBook 830 G5", CXT_FIXUP_HP_DOCK),
        SND_PCI_QUIRK(0x103c, 0x83d3, "HP ProBook 640 G4", CXT_FIXUP_HP_DOCK),
+       SND_PCI_QUIRK(0x103c, 0x83e5, "HP EliteOne 1000 G2", CXT_FIXUP_HP_ELITEONE_OUT_DIS),
        SND_PCI_QUIRK(0x103c, 0x8402, "HP ProBook 645 G4", CXT_FIXUP_MUTE_LED_GPIO),
        SND_PCI_QUIRK(0x103c, 0x8427, "HP ZBook Studio G5", CXT_FIXUP_HP_ZBOOK_MUTE_LED),
        SND_PCI_QUIRK(0x103c, 0x844f, "HP ZBook Studio G5", CXT_FIXUP_HP_ZBOOK_MUTE_LED),
index 26f3c31600d7bf1491149d870de10ee0cf3f5434..614327218634c0c8fcd560cb2dee18757fa64367 100644 (file)
@@ -1403,8 +1403,9 @@ void dolphin_fixups(struct hda_codec *codec, const struct hda_fixup *fix, int ac
                kctrl = snd_hda_gen_add_kctl(&spec->gen, "Line Out Playback Volume",
                                             &cs42l42_dac_volume_mixer);
                /* Update Line Out kcontrol template */
-               kctrl->private_value = HDA_COMPOSE_AMP_VAL_OFS(DOLPHIN_HP_PIN_NID, 3, CS8409_CODEC1,
-                                      HDA_OUTPUT, CS42L42_VOL_DAC) | HDA_AMP_VAL_MIN_MUTE;
+               if (kctrl)
+                       kctrl->private_value = HDA_COMPOSE_AMP_VAL_OFS(DOLPHIN_HP_PIN_NID, 3, CS8409_CODEC1,
+                                              HDA_OUTPUT, CS42L42_VOL_DAC) | HDA_AMP_VAL_MIN_MUTE;
                cs8409_enable_ur(codec, 0);
                snd_hda_codec_set_name(codec, "CS8409/CS42L42");
                break;
index 4ca66234e561f69ed3c944ddd91e149a1eba5f94..571fa8a6c9e1204892a93ffb24acce65400ce4b2 100644 (file)
@@ -587,6 +587,7 @@ static void alc_shutup_pins(struct hda_codec *codec)
        switch (codec->core.vendor_id) {
        case 0x10ec0236:
        case 0x10ec0256:
+       case 0x10ec0257:
        case 0x19e58326:
        case 0x10ec0283:
        case 0x10ec0285:
@@ -3867,20 +3868,18 @@ static void alc_default_init(struct hda_codec *codec)
 
        hp_pin_sense = snd_hda_jack_detect(codec, hp_pin);
 
-       if (hp_pin_sense)
+       if (hp_pin_sense) {
                msleep(2);
 
-       snd_hda_codec_write(codec, hp_pin, 0,
-                           AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
-
-       if (hp_pin_sense)
-               msleep(85);
+               snd_hda_codec_write(codec, hp_pin, 0,
+                                   AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
 
-       snd_hda_codec_write(codec, hp_pin, 0,
-                           AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
+               msleep(75);
 
-       if (hp_pin_sense)
-               msleep(100);
+               snd_hda_codec_write(codec, hp_pin, 0,
+                                   AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE);
+               msleep(75);
+       }
 }
 
 static void alc_default_shutup(struct hda_codec *codec)
@@ -3896,22 +3895,20 @@ static void alc_default_shutup(struct hda_codec *codec)
 
        hp_pin_sense = snd_hda_jack_detect(codec, hp_pin);
 
-       if (hp_pin_sense)
+       if (hp_pin_sense) {
                msleep(2);
 
-       snd_hda_codec_write(codec, hp_pin, 0,
-                           AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
-
-       if (hp_pin_sense)
-               msleep(85);
-
-       if (!spec->no_shutup_pins)
                snd_hda_codec_write(codec, hp_pin, 0,
-                                   AC_VERB_SET_PIN_WIDGET_CONTROL, 0x0);
+                                   AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
 
-       if (hp_pin_sense)
-               msleep(100);
+               msleep(75);
 
+               if (!spec->no_shutup_pins)
+                       snd_hda_codec_write(codec, hp_pin, 0,
+                                           AC_VERB_SET_PIN_WIDGET_CONTROL, 0x0);
+
+               msleep(75);
+       }
        alc_auto_setup_eapd(codec, false);
        alc_shutup_pins(codec);
 }
@@ -6644,10 +6641,8 @@ static void alc289_fixup_asus_ga401(struct hda_codec *codec,
        };
        struct alc_spec *spec = codec->spec;
 
-       if (action == HDA_FIXUP_ACT_PRE_PROBE) {
+       if (action == HDA_FIXUP_ACT_PRE_PROBE)
                spec->gen.preferred_dacs = preferred_pairs;
-               spec->gen.obey_preferred_dacs = 1;
-       }
 }
 
 /* The DAC of NID 0x3 will introduce click/pop noise on headphones, so invalidate it */
@@ -7404,6 +7399,49 @@ static void alc245_fixup_hp_spectre_x360_eu0xxx(struct hda_codec *codec,
        alc245_fixup_hp_gpio_led(codec, fix, action);
 }
 
+/* some changes for Spectre x360 16, 2024 model */
+static void alc245_fixup_hp_spectre_x360_16_aa0xxx(struct hda_codec *codec,
+                                         const struct hda_fixup *fix, int action)
+{
+       /*
+        * The Pin Complex 0x14 for the treble speakers is wrongly reported as
+        * unconnected.
+        * The Pin Complex 0x17 for the bass speakers has the lowest association
+        * and sequence values so shift it up a bit to squeeze 0x14 in.
+        */
+       struct alc_spec *spec = codec->spec;
+       static const struct hda_pintbl pincfgs[] = {
+               { 0x14, 0x90170110 }, // top/treble
+               { 0x17, 0x90170111 }, // bottom/bass
+               { }
+       };
+
+       /*
+        * Force DAC 0x02 for the bass speakers 0x17.
+        */
+       static const hda_nid_t conn[] = { 0x02 };
+
+       switch (action) {
+       case HDA_FIXUP_ACT_PRE_PROBE:
+               /* needed for amp of back speakers */
+               spec->gpio_mask |= 0x01;
+               spec->gpio_dir |= 0x01;
+               snd_hda_apply_pincfgs(codec, pincfgs);
+               snd_hda_override_conn_list(codec, 0x17, ARRAY_SIZE(conn), conn);
+               break;
+       case HDA_FIXUP_ACT_INIT:
+               /* need to toggle GPIO to enable the amp of back speakers */
+               alc_update_gpio_data(codec, 0x01, true);
+               msleep(100);
+               alc_update_gpio_data(codec, 0x01, false);
+               break;
+       }
+
+       cs35l41_fixup_i2c_two(codec, fix, action);
+       alc245_fixup_hp_mute_led_coefbit(codec, fix, action);
+       alc245_fixup_hp_gpio_led(codec, fix, action);
+}
+
 /*
  * ALC287 PCM hooks
  */
@@ -7483,6 +7521,7 @@ enum {
        ALC286_FIXUP_SONY_MIC_NO_PRESENCE,
        ALC269_FIXUP_PINCFG_NO_HP_TO_LINEOUT,
        ALC269_FIXUP_DELL1_MIC_NO_PRESENCE,
+       ALC269_FIXUP_DELL1_LIMIT_INT_MIC_BOOST,
        ALC269_FIXUP_DELL2_MIC_NO_PRESENCE,
        ALC269_FIXUP_DELL3_MIC_NO_PRESENCE,
        ALC269_FIXUP_DELL4_MIC_NO_PRESENCE,
@@ -7513,10 +7552,12 @@ enum {
        ALC290_FIXUP_SUBWOOFER_HSJACK,
        ALC269_FIXUP_THINKPAD_ACPI,
        ALC269_FIXUP_DMIC_THINKPAD_ACPI,
+       ALC269VB_FIXUP_INFINIX_ZERO_BOOK_13,
        ALC269VB_FIXUP_CHUWI_COREBOOK_XPRO,
        ALC255_FIXUP_ACER_MIC_NO_PRESENCE,
        ALC255_FIXUP_ASUS_MIC_NO_PRESENCE,
        ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
+       ALC255_FIXUP_DELL1_LIMIT_INT_MIC_BOOST,
        ALC255_FIXUP_DELL2_MIC_NO_PRESENCE,
        ALC255_FIXUP_HEADSET_MODE,
        ALC255_FIXUP_HEADSET_MODE_NO_HP_MIC,
@@ -7607,6 +7648,7 @@ enum {
        ALC286_FIXUP_ACER_AIO_HEADSET_MIC,
        ALC256_FIXUP_ASUS_HEADSET_MIC,
        ALC256_FIXUP_ASUS_MIC_NO_PRESENCE,
+       ALC255_FIXUP_PREDATOR_SUBWOOFER,
        ALC299_FIXUP_PREDATOR_SPK,
        ALC256_FIXUP_MEDION_HEADSET_NO_PRESENCE,
        ALC289_FIXUP_DELL_SPK1,
@@ -7726,6 +7768,7 @@ enum {
        ALC256_FIXUP_ACER_SFG16_MICMUTE_LED,
        ALC256_FIXUP_HEADPHONE_AMP_VOL,
        ALC245_FIXUP_HP_SPECTRE_X360_EU0XXX,
+       ALC245_FIXUP_HP_SPECTRE_X360_16_AA0XXX,
        ALC285_FIXUP_ASUS_GA403U,
        ALC285_FIXUP_ASUS_GA403U_HEADSET_MIC,
        ALC285_FIXUP_ASUS_GA403U_I2C_SPEAKER2_TO_DAC1,
@@ -7956,6 +7999,16 @@ static const struct hda_fixup alc269_fixups[] = {
                .type = HDA_FIXUP_FUNC,
                .v.func = alc269_fixup_pincfg_U7x7_headset_mic,
        },
+       [ALC269VB_FIXUP_INFINIX_ZERO_BOOK_13] = {
+               .type = HDA_FIXUP_PINS,
+               .v.pins = (const struct hda_pintbl[]) {
+                       { 0x14, 0x90170151 }, /* use as internal speaker (LFE) */
+                       { 0x1b, 0x90170152 }, /* use as internal speaker (back) */
+                       { }
+               },
+               .chained = true,
+               .chain_id = ALC269_FIXUP_LIMIT_INT_MIC_BOOST
+       },
        [ALC269VB_FIXUP_CHUWI_COREBOOK_XPRO] = {
                .type = HDA_FIXUP_PINS,
                .v.pins = (const struct hda_pintbl[]) {
@@ -8074,6 +8127,12 @@ static const struct hda_fixup alc269_fixups[] = {
                .chained = true,
                .chain_id = ALC269_FIXUP_HEADSET_MODE
        },
+       [ALC269_FIXUP_DELL1_LIMIT_INT_MIC_BOOST] = {
+               .type = HDA_FIXUP_FUNC,
+               .v.func = alc269_fixup_limit_int_mic_boost,
+               .chained = true,
+               .chain_id = ALC269_FIXUP_DELL1_MIC_NO_PRESENCE
+       },
        [ALC269_FIXUP_DELL2_MIC_NO_PRESENCE] = {
                .type = HDA_FIXUP_PINS,
                .v.pins = (const struct hda_pintbl[]) {
@@ -8354,6 +8413,12 @@ static const struct hda_fixup alc269_fixups[] = {
                .chained = true,
                .chain_id = ALC255_FIXUP_HEADSET_MODE
        },
+       [ALC255_FIXUP_DELL1_LIMIT_INT_MIC_BOOST] = {
+               .type = HDA_FIXUP_FUNC,
+               .v.func = alc269_fixup_limit_int_mic_boost,
+               .chained = true,
+               .chain_id = ALC255_FIXUP_DELL1_MIC_NO_PRESENCE
+       },
        [ALC255_FIXUP_DELL2_MIC_NO_PRESENCE] = {
                .type = HDA_FIXUP_PINS,
                .v.pins = (const struct hda_pintbl[]) {
@@ -9020,6 +9085,13 @@ static const struct hda_fixup alc269_fixups[] = {
                .chained = true,
                .chain_id = ALC256_FIXUP_ASUS_HEADSET_MODE
        },
+       [ALC255_FIXUP_PREDATOR_SUBWOOFER] = {
+               .type = HDA_FIXUP_PINS,
+               .v.pins = (const struct hda_pintbl[]) {
+                       { 0x17, 0x90170151 }, /* use as internal speaker (LFE) */
+                       { 0x1b, 0x90170152 } /* use as internal speaker (back) */
+               }
+       },
        [ALC299_FIXUP_PREDATOR_SPK] = {
                .type = HDA_FIXUP_PINS,
                .v.pins = (const struct hda_pintbl[]) {
@@ -10012,6 +10084,10 @@ static const struct hda_fixup alc269_fixups[] = {
                .type = HDA_FIXUP_FUNC,
                .v.func = alc245_fixup_hp_spectre_x360_eu0xxx,
        },
+       [ALC245_FIXUP_HP_SPECTRE_X360_16_AA0XXX] = {
+               .type = HDA_FIXUP_FUNC,
+               .v.func = alc245_fixup_hp_spectre_x360_16_aa0xxx,
+       },
        [ALC285_FIXUP_ASUS_GA403U] = {
                .type = HDA_FIXUP_FUNC,
                .v.func = alc285_fixup_asus_ga403u,
@@ -10103,6 +10179,8 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
        SND_PCI_QUIRK(0x1025, 0x110e, "Acer Aspire ES1-432", ALC255_FIXUP_ACER_MIC_NO_PRESENCE),
        SND_PCI_QUIRK(0x1025, 0x1166, "Acer Veriton N4640G", ALC269_FIXUP_LIFEBOOK),
        SND_PCI_QUIRK(0x1025, 0x1167, "Acer Veriton N6640G", ALC269_FIXUP_LIFEBOOK),
+       SND_PCI_QUIRK(0x1025, 0x1177, "Acer Predator G9-593", ALC255_FIXUP_PREDATOR_SUBWOOFER),
+       SND_PCI_QUIRK(0x1025, 0x1178, "Acer Predator G9-593", ALC255_FIXUP_PREDATOR_SUBWOOFER),
        SND_PCI_QUIRK(0x1025, 0x1246, "Acer Predator Helios 500", ALC299_FIXUP_PREDATOR_SPK),
        SND_PCI_QUIRK(0x1025, 0x1247, "Acer vCopperbox", ALC269VC_FIXUP_ACER_VCOPPERBOX_PINS),
        SND_PCI_QUIRK(0x1025, 0x1248, "Acer Veriton N4660G", ALC269VC_FIXUP_ACER_MIC_NO_PRESENCE),
@@ -10199,6 +10277,8 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
        SND_PCI_QUIRK(0x1028, 0x0c1e, "Dell Precision 3540", ALC236_FIXUP_DELL_DUAL_CODECS),
        SND_PCI_QUIRK(0x1028, 0x0c28, "Dell Inspiron 16 Plus 7630", ALC295_FIXUP_DELL_INSPIRON_TOP_SPEAKERS),
        SND_PCI_QUIRK(0x1028, 0x0c4d, "Dell", ALC287_FIXUP_CS35L41_I2C_4),
+       SND_PCI_QUIRK(0x1028, 0x0c94, "Dell Polaris 3 metal", ALC287_FIXUP_TAS2781_I2C),
+       SND_PCI_QUIRK(0x1028, 0x0c96, "Dell Polaris 2in1", ALC287_FIXUP_TAS2781_I2C),
        SND_PCI_QUIRK(0x1028, 0x0cbd, "Dell Oasis 13 CS MTL-U", ALC289_FIXUP_DELL_CS35L41_SPI_2),
        SND_PCI_QUIRK(0x1028, 0x0cbe, "Dell Oasis 13 2-IN-1 MTL-U", ALC289_FIXUP_DELL_CS35L41_SPI_2),
        SND_PCI_QUIRK(0x1028, 0x0cbf, "Dell Oasis 13 Low Weight MTU-L", ALC289_FIXUP_DELL_CS35L41_SPI_2),
@@ -10349,6 +10429,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
        SND_PCI_QUIRK(0x103c, 0x8896, "HP EliteBook 855 G8 Notebook PC", ALC285_FIXUP_HP_MUTE_LED),
        SND_PCI_QUIRK(0x103c, 0x8898, "HP EliteBook 845 G8 Notebook PC", ALC285_FIXUP_HP_LIMIT_INT_MIC_BOOST),
        SND_PCI_QUIRK(0x103c, 0x88d0, "HP Pavilion 15-eh1xxx (mainboard 88D0)", ALC287_FIXUP_HP_GPIO_LED),
+       SND_PCI_QUIRK(0x103c, 0x88dd, "HP Pavilion 15z-ec200", ALC285_FIXUP_HP_MUTE_LED),
        SND_PCI_QUIRK(0x103c, 0x8902, "HP OMEN 16", ALC285_FIXUP_HP_MUTE_LED),
        SND_PCI_QUIRK(0x103c, 0x890e, "HP 255 G8 Notebook PC", ALC236_FIXUP_HP_MUTE_LED_COEFBIT2),
        SND_PCI_QUIRK(0x103c, 0x8919, "HP Pavilion Aero Laptop 13-be0xxx", ALC287_FIXUP_HP_GPIO_LED),
@@ -10448,7 +10529,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
        SND_PCI_QUIRK(0x103c, 0x8be9, "HP Envy 15", ALC287_FIXUP_CS35L41_I2C_2),
        SND_PCI_QUIRK(0x103c, 0x8bf0, "HP", ALC236_FIXUP_HP_GPIO_LED),
        SND_PCI_QUIRK(0x103c, 0x8c15, "HP Spectre x360 2-in-1 Laptop 14-eu0xxx", ALC245_FIXUP_HP_SPECTRE_X360_EU0XXX),
-       SND_PCI_QUIRK(0x103c, 0x8c16, "HP Spectre 16", ALC287_FIXUP_CS35L41_I2C_2),
+       SND_PCI_QUIRK(0x103c, 0x8c16, "HP Spectre x360 2-in-1 Laptop 16-aa0xxx", ALC245_FIXUP_HP_SPECTRE_X360_16_AA0XXX),
        SND_PCI_QUIRK(0x103c, 0x8c17, "HP Spectre 16", ALC287_FIXUP_CS35L41_I2C_2),
        SND_PCI_QUIRK(0x103c, 0x8c21, "HP Pavilion Plus Laptop 14-ey0XXX", ALC245_FIXUP_HP_X360_MUTE_LEDS),
        SND_PCI_QUIRK(0x103c, 0x8c30, "HP Victus 15-fb1xxx", ALC245_FIXUP_HP_MUTE_LED_COEFBIT),
@@ -10490,6 +10571,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
        SND_PCI_QUIRK(0x103c, 0x8ca2, "HP ZBook Power", ALC236_FIXUP_HP_GPIO_LED),
        SND_PCI_QUIRK(0x103c, 0x8ca4, "HP ZBook Fury", ALC245_FIXUP_CS35L41_SPI_2_HP_GPIO_LED),
        SND_PCI_QUIRK(0x103c, 0x8ca7, "HP ZBook Fury", ALC245_FIXUP_CS35L41_SPI_2_HP_GPIO_LED),
+       SND_PCI_QUIRK(0x103c, 0x8caf, "HP Elite mt645 G8 Mobile Thin Client", ALC236_FIXUP_HP_MUTE_LED_MICMUTE_VREF),
        SND_PCI_QUIRK(0x103c, 0x8cbd, "HP Pavilion Aero Laptop 13-bg0xxx", ALC245_FIXUP_HP_X360_MUTE_LEDS),
        SND_PCI_QUIRK(0x103c, 0x8cdd, "HP Spectre", ALC287_FIXUP_CS35L41_I2C_2),
        SND_PCI_QUIRK(0x103c, 0x8cde, "HP Spectre", ALC287_FIXUP_CS35L41_I2C_2),
@@ -10500,11 +10582,15 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
        SND_PCI_QUIRK(0x1043, 0x103f, "ASUS TX300", ALC282_FIXUP_ASUS_TX300),
        SND_PCI_QUIRK(0x1043, 0x106d, "Asus K53BE", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
        SND_PCI_QUIRK(0x1043, 0x10a1, "ASUS UX391UA", ALC294_FIXUP_ASUS_SPK),
+       SND_PCI_QUIRK(0x1043, 0x10a4, "ASUS TP3407SA", ALC287_FIXUP_TAS2781_I2C),
        SND_PCI_QUIRK(0x1043, 0x10c0, "ASUS X540SA", ALC256_FIXUP_ASUS_MIC),
        SND_PCI_QUIRK(0x1043, 0x10d0, "ASUS X540LA/X540LJ", ALC255_FIXUP_ASUS_MIC_NO_PRESENCE),
        SND_PCI_QUIRK(0x1043, 0x10d3, "ASUS K6500ZC", ALC294_FIXUP_ASUS_SPK),
+       SND_PCI_QUIRK(0x1043, 0x1154, "ASUS TP3607SH", ALC287_FIXUP_TAS2781_I2C),
        SND_PCI_QUIRK(0x1043, 0x115d, "Asus 1015E", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
        SND_PCI_QUIRK(0x1043, 0x11c0, "ASUS X556UR", ALC255_FIXUP_ASUS_MIC_NO_PRESENCE),
+       SND_PCI_QUIRK(0x1043, 0x1204, "ASUS Strix G615JHR_JMR_JPR", ALC287_FIXUP_TAS2781_I2C),
+       SND_PCI_QUIRK(0x1043, 0x1214, "ASUS Strix G615LH_LM_LP", ALC287_FIXUP_TAS2781_I2C),
        SND_PCI_QUIRK(0x1043, 0x125e, "ASUS Q524UQK", ALC255_FIXUP_ASUS_MIC_NO_PRESENCE),
        SND_PCI_QUIRK(0x1043, 0x1271, "ASUS X430UN", ALC256_FIXUP_ASUS_MIC_NO_PRESENCE),
        SND_PCI_QUIRK(0x1043, 0x1290, "ASUS X441SA", ALC233_FIXUP_EAPD_COEF_AND_MIC_NO_PRESENCE),
@@ -10582,6 +10668,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
        SND_PCI_QUIRK(0x1043, 0x1e51, "ASUS Zephyrus M15", ALC294_FIXUP_ASUS_GU502_PINS),
        SND_PCI_QUIRK(0x1043, 0x1e5e, "ASUS ROG Strix G513", ALC294_FIXUP_ASUS_G513_PINS),
        SND_PCI_QUIRK(0x1043, 0x1e8e, "ASUS Zephyrus G15", ALC289_FIXUP_ASUS_GA401),
+       SND_PCI_QUIRK(0x1043, 0x1eb3, "ASUS Ally RCLA72", ALC287_FIXUP_TAS2781_I2C),
        SND_PCI_QUIRK(0x1043, 0x1ed3, "ASUS HN7306W", ALC287_FIXUP_CS35L41_I2C_2),
        SND_PCI_QUIRK(0x1043, 0x1ee2, "ASUS UM6702RA/RC", ALC287_FIXUP_CS35L41_I2C_2),
        SND_PCI_QUIRK(0x1043, 0x1c52, "ASUS Zephyrus G15 2022", ALC289_FIXUP_ASUS_GA401),
@@ -10596,6 +10683,13 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
        SND_PCI_QUIRK(0x1043, 0x3a40, "ASUS G814JZR", ALC285_FIXUP_ASUS_SPI_REAR_SPEAKERS),
        SND_PCI_QUIRK(0x1043, 0x3a50, "ASUS G834JYR/JZR", ALC285_FIXUP_ASUS_SPI_REAR_SPEAKERS),
        SND_PCI_QUIRK(0x1043, 0x3a60, "ASUS G634JYR/JZR", ALC285_FIXUP_ASUS_SPI_REAR_SPEAKERS),
+       SND_PCI_QUIRK(0x1043, 0x3e30, "ASUS TP3607SA", ALC287_FIXUP_TAS2781_I2C),
+       SND_PCI_QUIRK(0x1043, 0x3ee0, "ASUS Strix G815_JHR_JMR_JPR", ALC287_FIXUP_TAS2781_I2C),
+       SND_PCI_QUIRK(0x1043, 0x3ef0, "ASUS Strix G635LR_LW_LX", ALC287_FIXUP_TAS2781_I2C),
+       SND_PCI_QUIRK(0x1043, 0x3f00, "ASUS Strix G815LH_LM_LP", ALC287_FIXUP_TAS2781_I2C),
+       SND_PCI_QUIRK(0x1043, 0x3f10, "ASUS Strix G835LR_LW_LX", ALC287_FIXUP_TAS2781_I2C),
+       SND_PCI_QUIRK(0x1043, 0x3f20, "ASUS Strix G615LR_LW", ALC287_FIXUP_TAS2781_I2C),
+       SND_PCI_QUIRK(0x1043, 0x3f30, "ASUS Strix G815LR_LW", ALC287_FIXUP_TAS2781_I2C),
        SND_PCI_QUIRK(0x1043, 0x831a, "ASUS P901", ALC269_FIXUP_STEREO_DMIC),
        SND_PCI_QUIRK(0x1043, 0x834a, "ASUS S101", ALC269_FIXUP_STEREO_DMIC),
        SND_PCI_QUIRK(0x1043, 0x8398, "ASUS P1005", ALC269_FIXUP_STEREO_DMIC),
@@ -10656,6 +10750,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
        SND_PCI_QUIRK(0x1558, 0x1404, "Clevo N150CU", ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE),
        SND_PCI_QUIRK(0x1558, 0x14a1, "Clevo L141MU", ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE),
        SND_PCI_QUIRK(0x1558, 0x2624, "Clevo L240TU", ALC256_FIXUP_SYSTEM76_MIC_NO_PRESENCE),
+       SND_PCI_QUIRK(0x1558, 0x28c1, "Clevo V370VND", ALC2XX_FIXUP_HEADSET_MIC),
        SND_PCI_QUIRK(0x1558, 0x4018, "Clevo NV40M[BE]", ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE),
        SND_PCI_QUIRK(0x1558, 0x4019, "Clevo NV40MZ", ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE),
        SND_PCI_QUIRK(0x1558, 0x4020, "Clevo NV40MB", ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE),
@@ -10818,11 +10913,14 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
        SND_PCI_QUIRK(0x17aa, 0x3878, "Lenovo Legion 7 Slim 16ARHA7", ALC287_FIXUP_CS35L41_I2C_2),
        SND_PCI_QUIRK(0x17aa, 0x387d, "Yoga S780-16 pro Quad AAC", ALC287_FIXUP_TAS2781_I2C),
        SND_PCI_QUIRK(0x17aa, 0x387e, "Yoga S780-16 pro Quad YC", ALC287_FIXUP_TAS2781_I2C),
+       SND_PCI_QUIRK(0x17aa, 0x387f, "Yoga S780-16 pro dual LX", ALC287_FIXUP_TAS2781_I2C),
+       SND_PCI_QUIRK(0x17aa, 0x3880, "Yoga S780-16 pro dual YC", ALC287_FIXUP_TAS2781_I2C),
        SND_PCI_QUIRK(0x17aa, 0x3881, "YB9 dual power mode2 YC", ALC287_FIXUP_TAS2781_I2C),
        SND_PCI_QUIRK(0x17aa, 0x3882, "Lenovo Yoga Pro 7 14APH8", ALC287_FIXUP_YOGA9_14IAP7_BASS_SPK_PIN),
        SND_PCI_QUIRK(0x17aa, 0x3884, "Y780 YG DUAL", ALC287_FIXUP_TAS2781_I2C),
        SND_PCI_QUIRK(0x17aa, 0x3886, "Y780 VECO DUAL", ALC287_FIXUP_TAS2781_I2C),
        SND_PCI_QUIRK(0x17aa, 0x3891, "Lenovo Yoga Pro 7 14AHP9", ALC287_FIXUP_YOGA9_14IAP7_BASS_SPK_PIN),
+       SND_PCI_QUIRK(0x17aa, 0x38a5, "Y580P AMD dual", ALC287_FIXUP_TAS2781_I2C),
        SND_PCI_QUIRK(0x17aa, 0x38a7, "Y780P AMD YG dual", ALC287_FIXUP_TAS2781_I2C),
        SND_PCI_QUIRK(0x17aa, 0x38a8, "Y780P AMD VECO dual", ALC287_FIXUP_TAS2781_I2C),
        SND_PCI_QUIRK(0x17aa, 0x38a9, "Thinkbook 16P", ALC287_FIXUP_MG_RTKC_CSAMP_CS35L41_I2C_THINKPAD),
@@ -10831,6 +10929,8 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
        SND_PCI_QUIRK(0x17aa, 0x38b5, "Legion Slim 7 16IRH8", ALC287_FIXUP_CS35L41_I2C_2),
        SND_PCI_QUIRK(0x17aa, 0x38b6, "Legion Slim 7 16APH8", ALC287_FIXUP_CS35L41_I2C_2),
        SND_PCI_QUIRK(0x17aa, 0x38b7, "Legion Slim 7 16APH8", ALC287_FIXUP_CS35L41_I2C_2),
+       SND_PCI_QUIRK(0x17aa, 0x38b8, "Yoga S780-14.5 proX AMD YC Dual", ALC287_FIXUP_TAS2781_I2C),
+       SND_PCI_QUIRK(0x17aa, 0x38b9, "Yoga S780-14.5 proX AMD LX Dual", ALC287_FIXUP_TAS2781_I2C),
        SND_PCI_QUIRK(0x17aa, 0x38ba, "Yoga S780-14.5 Air AMD quad YC", ALC287_FIXUP_TAS2781_I2C),
        SND_PCI_QUIRK(0x17aa, 0x38bb, "Yoga S780-14.5 Air AMD quad AAC", ALC287_FIXUP_TAS2781_I2C),
        SND_PCI_QUIRK(0x17aa, 0x38be, "Yoga S980-14.5 proX YC Dual", ALC287_FIXUP_TAS2781_I2C),
@@ -10841,11 +10941,22 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
        SND_PCI_QUIRK(0x17aa, 0x38cb, "Y790 YG DUAL", ALC287_FIXUP_TAS2781_I2C),
        SND_PCI_QUIRK(0x17aa, 0x38cd, "Y790 VECO DUAL", ALC287_FIXUP_TAS2781_I2C),
        SND_PCI_QUIRK(0x17aa, 0x38d2, "Lenovo Yoga 9 14IMH9", ALC287_FIXUP_YOGA9_14IMH9_BASS_SPK_PIN),
+       SND_PCI_QUIRK(0x17aa, 0x38d3, "Yoga S990-16 Pro IMH YC Dual", ALC287_FIXUP_TAS2781_I2C),
+       SND_PCI_QUIRK(0x17aa, 0x38d4, "Yoga S990-16 Pro IMH VECO Dual", ALC287_FIXUP_TAS2781_I2C),
+       SND_PCI_QUIRK(0x17aa, 0x38d5, "Yoga S990-16 Pro IMH YC Quad", ALC287_FIXUP_TAS2781_I2C),
+       SND_PCI_QUIRK(0x17aa, 0x38d6, "Yoga S990-16 Pro IMH VECO Quad", ALC287_FIXUP_TAS2781_I2C),
        SND_PCI_QUIRK(0x17aa, 0x38d7, "Lenovo Yoga 9 14IMH9", ALC287_FIXUP_YOGA9_14IMH9_BASS_SPK_PIN),
+       SND_PCI_QUIRK(0x17aa, 0x38df, "Yoga Y990 Intel YC Dual", ALC287_FIXUP_TAS2781_I2C),
+       SND_PCI_QUIRK(0x17aa, 0x38e0, "Yoga Y990 Intel VECO Dual", ALC287_FIXUP_TAS2781_I2C),
+       SND_PCI_QUIRK(0x17aa, 0x38f8, "Yoga Book 9i", ALC287_FIXUP_TAS2781_I2C),
+       SND_PCI_QUIRK(0x17aa, 0x38df, "Y990 YG DUAL", ALC287_FIXUP_TAS2781_I2C),
        SND_PCI_QUIRK(0x17aa, 0x38f9, "Thinkbook 16P Gen5", ALC287_FIXUP_CS35L41_I2C_2),
        SND_PCI_QUIRK(0x17aa, 0x38fa, "Thinkbook 16P Gen5", ALC287_FIXUP_CS35L41_I2C_2),
+       SND_PCI_QUIRK(0x17aa, 0x38fd, "ThinkBook plus Gen5 Hybrid", ALC287_FIXUP_TAS2781_I2C),
        SND_PCI_QUIRK(0x17aa, 0x3902, "Lenovo E50-80", ALC269_FIXUP_DMIC_THINKPAD_ACPI),
        SND_PCI_QUIRK(0x17aa, 0x3913, "Lenovo 145", ALC236_FIXUP_LENOVO_INV_DMIC),
+       SND_PCI_QUIRK(0x17aa, 0x391f, "Yoga S990-16 pro Quad YC Quad", ALC287_FIXUP_TAS2781_I2C),
+       SND_PCI_QUIRK(0x17aa, 0x3920, "Yoga S990-16 pro Quad VECO Quad", ALC287_FIXUP_TAS2781_I2C),
        SND_PCI_QUIRK(0x17aa, 0x3977, "IdeaPad S210", ALC283_FIXUP_INT_MIC),
        SND_PCI_QUIRK(0x17aa, 0x3978, "Lenovo B50-70", ALC269_FIXUP_DMIC_THINKPAD_ACPI),
        SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_FIXUP_PCM_44K),
@@ -10878,6 +10989,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
        SND_PCI_QUIRK(0x1854, 0x048a, "LG gram 17 (17ZD90R)", ALC298_FIXUP_SAMSUNG_AMP_V2_4_AMPS),
        SND_PCI_QUIRK(0x19e5, 0x3204, "Huawei MACH-WX9", ALC256_FIXUP_HUAWEI_MACH_WX9_PINS),
        SND_PCI_QUIRK(0x19e5, 0x320f, "Huawei WRT-WX9 ", ALC256_FIXUP_ASUS_MIC_NO_PRESENCE),
+       SND_PCI_QUIRK(0x19e5, 0x3212, "Huawei KLV-WX9 ", ALC256_FIXUP_ACER_HEADSET_MIC),
        SND_PCI_QUIRK(0x1b35, 0x1235, "CZC B20", ALC269_FIXUP_CZC_B20),
        SND_PCI_QUIRK(0x1b35, 0x1236, "CZC TMI", ALC269_FIXUP_CZC_TMI),
        SND_PCI_QUIRK(0x1b35, 0x1237, "CZC L101", ALC269_FIXUP_CZC_L101),
@@ -10896,6 +11008,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
        SND_PCI_QUIRK(0x1d05, 0x115c, "TongFang GMxTGxx", ALC269_FIXUP_NO_SHUTUP),
        SND_PCI_QUIRK(0x1d05, 0x121b, "TongFang GMxAGxx", ALC269_FIXUP_NO_SHUTUP),
        SND_PCI_QUIRK(0x1d05, 0x1387, "TongFang GMxIXxx", ALC2XX_FIXUP_HEADSET_MIC),
+       SND_PCI_QUIRK(0x1d05, 0x1409, "TongFang GMxIXxx", ALC2XX_FIXUP_HEADSET_MIC),
        SND_PCI_QUIRK(0x1d17, 0x3288, "Haier Boyue G42", ALC269VC_FIXUP_ACER_VCOPPERBOX_PINS),
        SND_PCI_QUIRK(0x1d72, 0x1602, "RedmiBook", ALC255_FIXUP_XIAOMI_HEADSET_MIC),
        SND_PCI_QUIRK(0x1d72, 0x1701, "XiaomiNotebook Pro", ALC298_FIXUP_DELL1_MIC_NO_PRESENCE),
@@ -10903,6 +11016,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
        SND_PCI_QUIRK(0x1d72, 0x1945, "Redmi G", ALC256_FIXUP_ASUS_HEADSET_MIC),
        SND_PCI_QUIRK(0x1d72, 0x1947, "RedmiBook Air", ALC255_FIXUP_XIAOMI_HEADSET_MIC),
        SND_PCI_QUIRK(0x2782, 0x0214, "VAIO VJFE-CL", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
+       SND_PCI_QUIRK(0x2782, 0x0228, "Infinix ZERO BOOK 13", ALC269VB_FIXUP_INFINIX_ZERO_BOOK_13),
        SND_PCI_QUIRK(0x2782, 0x0232, "CHUWI CoreBook XPro", ALC269VB_FIXUP_CHUWI_COREBOOK_XPRO),
        SND_PCI_QUIRK(0x2782, 0x1707, "Vaio VJFE-ADL", ALC298_FIXUP_SPK_VOLUME),
        SND_PCI_QUIRK(0x8086, 0x2074, "Intel NUC 8", ALC233_FIXUP_INTEL_NUC8_DMIC),
@@ -10990,6 +11104,7 @@ static const struct hda_model_fixup alc269_fixup_models[] = {
        {.id = ALC269_FIXUP_DELL2_MIC_NO_PRESENCE, .name = "dell-headset-dock"},
        {.id = ALC269_FIXUP_DELL3_MIC_NO_PRESENCE, .name = "dell-headset3"},
        {.id = ALC269_FIXUP_DELL4_MIC_NO_PRESENCE, .name = "dell-headset4"},
+       {.id = ALC269_FIXUP_DELL4_MIC_NO_PRESENCE_QUIET, .name = "dell-headset4-quiet"},
        {.id = ALC283_FIXUP_CHROME_BOOK, .name = "alc283-dac-wcaps"},
        {.id = ALC283_FIXUP_SENSE_COMBO_JACK, .name = "alc283-sense-combo"},
        {.id = ALC292_FIXUP_TPT440_DOCK, .name = "tpt440-dock"},
@@ -11544,16 +11659,16 @@ static const struct snd_hda_pin_quirk alc269_fallback_pin_fixup_tbl[] = {
        SND_HDA_PIN_QUIRK(0x10ec0289, 0x1028, "Dell", ALC269_FIXUP_DELL4_MIC_NO_PRESENCE,
                {0x19, 0x40000000},
                {0x1b, 0x40000000}),
-       SND_HDA_PIN_QUIRK(0x10ec0295, 0x1028, "Dell", ALC269_FIXUP_DELL4_MIC_NO_PRESENCE,
+       SND_HDA_PIN_QUIRK(0x10ec0295, 0x1028, "Dell", ALC269_FIXUP_DELL4_MIC_NO_PRESENCE_QUIET,
                {0x19, 0x40000000},
                {0x1b, 0x40000000}),
        SND_HDA_PIN_QUIRK(0x10ec0256, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
                {0x19, 0x40000000},
                {0x1a, 0x40000000}),
-       SND_HDA_PIN_QUIRK(0x10ec0236, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
+       SND_HDA_PIN_QUIRK(0x10ec0236, 0x1028, "Dell", ALC255_FIXUP_DELL1_LIMIT_INT_MIC_BOOST,
                {0x19, 0x40000000},
                {0x1a, 0x40000000}),
-       SND_HDA_PIN_QUIRK(0x10ec0274, 0x1028, "Dell", ALC274_FIXUP_DELL_AIO_LINEOUT_VERB,
+       SND_HDA_PIN_QUIRK(0x10ec0274, 0x1028, "Dell", ALC269_FIXUP_DELL1_LIMIT_INT_MIC_BOOST,
                {0x19, 0x40000000},
                {0x1a, 0x40000000}),
        SND_HDA_PIN_QUIRK(0x10ec0256, 0x1043, "ASUS", ALC2XX_FIXUP_HEADSET_MIC,
index f58f434e7110ee425594b3bc41163019e409f941..370d847517f9ab4b9ec6c773f73c82bf7aca564c 100644 (file)
@@ -7,7 +7,7 @@
 // Author: Shenghao Ding <[email protected]>
 // Current maintainer: Baojun Xu <[email protected]>
 
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include <linux/acpi.h>
 #include <linux/crc8.h>
 #include <linux/crc32.h>
@@ -951,7 +951,7 @@ static const struct dev_pm_ops tas2781_hda_pm_ops = {
 };
 
 static const struct i2c_device_id tas2781_hda_i2c_id[] = {
-       { "tas2781-hda", 0 },
+       { "tas2781-hda" },
        {}
 };
 
index 6c50c82765383e46bae5f354ac4014511b20592b..306854fb08e3d7d13805ccfba405ed6e9c2e65b9 100644 (file)
@@ -400,9 +400,6 @@ err_dai:
        return ret;
 }
 
-/* SoC card */
-static const char sdw_card_long_name[] = "AMD Soundwire SOF";
-
 static int mc_probe(struct platform_device *pdev)
 {
        struct snd_soc_acpi_mach *mach = dev_get_platdata(&pdev->dev);
@@ -463,8 +460,6 @@ static int mc_probe(struct platform_device *pdev)
        if (!card->components)
                return -ENOMEM;
 
-       card->long_name = sdw_card_long_name;
-
        /* Register the card */
        ret = devm_snd_soc_register_card(card->dev, card);
        if (ret) {
index 06349bf0b65874321e1c54afcff50417cdc9248c..438865d5e376e087f11a297fc46ae2ad586e168a 100644 (file)
@@ -325,6 +325,13 @@ static const struct dmi_system_id yc_acp_quirk_table[] = {
                        DMI_MATCH(DMI_PRODUCT_NAME, "M6500RC"),
                }
        },
+       {
+               .driver_data = &acp6x_card,
+               .matches = {
+                       DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK COMPUTER INC."),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "E1404FA"),
+               }
+       },
        {
                .driver_data = &acp6x_card,
                .matches = {
@@ -339,6 +346,13 @@ static const struct dmi_system_id yc_acp_quirk_table[] = {
                        DMI_MATCH(DMI_PRODUCT_NAME, "M7600RE"),
                }
        },
+       {
+               .driver_data = &acp6x_card,
+               .matches = {
+                       DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK COMPUTER INC."),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "M3502RA"),
+               }
+       },
        {
                .driver_data = &acp6x_card,
                .matches = {
@@ -444,6 +458,13 @@ static const struct dmi_system_id yc_acp_quirk_table[] = {
                        DMI_MATCH(DMI_BOARD_NAME, "8A3E"),
                }
        },
+       {
+               .driver_data = &acp6x_card,
+               .matches = {
+                       DMI_MATCH(DMI_BOARD_VENDOR, "HP"),
+                       DMI_MATCH(DMI_BOARD_NAME, "8A7F"),
+               }
+       },
        {
                .driver_data = &acp6x_card,
                .matches = {
index 939cd44ebc8a51d97ef7af4a4c0fb361a9da6785..06dc3c48e7e8daf764d1d466a51ef286306ddfd7 100644 (file)
@@ -302,6 +302,9 @@ static int mchp_pdmc_chmap_ctl_put(struct snd_kcontrol *kcontrol,
        if (!substream)
                return -ENODEV;
 
+       if (!substream->runtime)
+               return 0; /* just for avoiding error from alsactl restore */
+
        map = mchp_pdmc_chmap_get(substream, info);
        if (!map)
                return -EINVAL;
index 8bd6067df7f75ebfab93f115f74d550ef10ddbe9..291249e0a2a32df7dde81904dce2f6be143fc2d7 100644 (file)
@@ -21,7 +21,7 @@
 #include <sound/pcm_params.h>
 #include <sound/soc.h>
 
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #include "sigmadsp.h"
 #include "adau1701.h"
index f2932713b4de921c3ea3f349a1276160e17e15fd..4dcc984761e0a64d07ceae76c84d47736facb575 100644 (file)
@@ -19,7 +19,7 @@
 #include <linux/i2c.h>
 #include <linux/spi/spi.h>
 #include <linux/regmap.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #include "sigmadsp.h"
 #include "adau17x1.h"
index 8dc2b8aa6832d5f8a75e31f335bcba0b61b72ab5..bba59885242d0c01751b99d8652d4238b23b991f 100644 (file)
@@ -656,7 +656,7 @@ static int aw_dev_get_dsp_status(struct aw_device *aw_dev)
        if (ret)
                return ret;
        if (!(reg_val & (~AW88399_WDT_CNT_MASK)))
-               ret = -EPERM;
+               return -EPERM;
 
        return 0;
 }
index e1cebb9e4dc6416ff3e9dab0198a9041675cbadb..405dab137b3b092425ce3fcfe7dc335c2a05db52 100644 (file)
@@ -315,7 +315,7 @@ static const struct {
        { 0x3B, 24576000 },
 };
 
-unsigned int cs35l45_get_clk_freq_id(unsigned int freq)
+int cs35l45_get_clk_freq_id(unsigned int freq)
 {
        int i;
 
index e2ebcf58d7e03f4e1603e5a88d47bbb924e5dff1..7a790d2acac7ff4c029cc496f8c90eac01106834 100644 (file)
@@ -507,7 +507,7 @@ extern const struct dev_pm_ops cs35l45_pm_ops;
 extern const struct regmap_config cs35l45_i2c_regmap;
 extern const struct regmap_config cs35l45_spi_regmap;
 int cs35l45_apply_patch(struct cs35l45_private *cs35l45);
-unsigned int cs35l45_get_clk_freq_id(unsigned int freq);
+int cs35l45_get_clk_freq_id(unsigned int freq);
 int cs35l45_probe(struct cs35l45_private *cs35l45);
 void cs35l45_remove(struct cs35l45_private *cs35l45);
 
index e4827b8c2bde45c8f9ca48f41174e5a0ae7aacca..6e51954bdb1ecc793962335a6e1b0af3d09e45af 100644 (file)
@@ -747,8 +747,10 @@ int cs42l51_probe(struct device *dev, struct regmap *regmap)
 
        cs42l51->reset_gpio = devm_gpiod_get_optional(dev, "reset",
                                                      GPIOD_OUT_LOW);
-       if (IS_ERR(cs42l51->reset_gpio))
-               return PTR_ERR(cs42l51->reset_gpio);
+       if (IS_ERR(cs42l51->reset_gpio)) {
+               ret = PTR_ERR(cs42l51->reset_gpio);
+               goto error;
+       }
 
        if (cs42l51->reset_gpio) {
                dev_dbg(dev, "Release reset gpio\n");
@@ -780,6 +782,7 @@ int cs42l51_probe(struct device *dev, struct regmap *regmap)
        return 0;
 
 error:
+       gpiod_set_value_cansleep(cs42l51->reset_gpio, 1);
        regulator_bulk_disable(ARRAY_SIZE(cs42l51->supplies),
                               cs42l51->supplies);
        return ret;
index 71e0d3bffd3f5f757f708d58843f7b59522e5794..febbbe0739628ee634d97c0f44d303d9a16ec807 100644 (file)
 #define CDC_RX_RXn_RX_PATH_SEC3(rx, n) (0x042c  + rx->rxn_reg_stride * n)
 #define CDC_RX_RX0_RX_PATH_SEC4                (0x0430)
 #define CDC_RX_RX0_RX_PATH_SEC7                (0x0434)
-#define CDC_RX_RXn_RX_PATH_SEC7(rx, n) (0x0434  + rx->rxn_reg_stride * n)
+#define CDC_RX_RXn_RX_PATH_SEC7(rx, n)         \
+       (0x0434 + (rx->rxn_reg_stride * n) + ((n > 1) ? rx->rxn_reg_stride2 : 0))
 #define CDC_RX_DSM_OUT_DELAY_SEL_MASK  GENMASK(2, 0)
 #define CDC_RX_DSM_OUT_DELAY_TWO_SAMPLE        0x2
 #define CDC_RX_RX0_RX_PATH_MIX_SEC0    (0x0438)
 #define CDC_RX_RX0_RX_PATH_MIX_SEC1    (0x043C)
-#define CDC_RX_RXn_RX_PATH_DSM_CTL(rx, n)      (0x0440  + rx->rxn_reg_stride * n)
+#define CDC_RX_RXn_RX_PATH_DSM_CTL(rx, n)      \
+       (0x0440 + (rx->rxn_reg_stride * n) + ((n > 1) ? rx->rxn_reg_stride2 : 0))
 #define CDC_RX_RXn_DSM_CLK_EN_MASK     BIT(0)
 #define CDC_RX_RX0_RX_PATH_DSM_CTL     (0x0440)
 #define CDC_RX_RX0_RX_PATH_DSM_DATA1   (0x0444)
@@ -645,6 +647,7 @@ struct rx_macro {
        int rx_mclk_cnt;
        enum lpass_codec_version codec_version;
        int rxn_reg_stride;
+       int rxn_reg_stride2;
        bool is_ear_mode_on;
        bool hph_pwr_mode;
        bool hph_hd2_mode;
@@ -958,7 +961,7 @@ static const struct reg_default rx_defaults[] = {
        { CDC_RX_BCL_VBAT_PK_EST2, 0x01 },
        { CDC_RX_BCL_VBAT_PK_EST3, 0x40 },
        { CDC_RX_BCL_VBAT_RF_PROC1, 0x2A },
-       { CDC_RX_BCL_VBAT_RF_PROC1, 0x00 },
+       { CDC_RX_BCL_VBAT_RF_PROC2, 0x00 },
        { CDC_RX_BCL_VBAT_TAC1, 0x00 },
        { CDC_RX_BCL_VBAT_TAC2, 0x18 },
        { CDC_RX_BCL_VBAT_TAC3, 0x18 },
@@ -1929,9 +1932,6 @@ static int rx_macro_digital_mute(struct snd_soc_dai *dai, int mute, int stream)
                                                              CDC_RX_PATH_PGA_MUTE_MASK, 0x0);
                        }
 
-                       if (j == INTERP_AUX)
-                               dsm_reg = CDC_RX_RXn_RX_PATH_DSM_CTL(rx, 2);
-
                        int_mux_cfg0 = CDC_RX_INP_MUX_RX_INT0_CFG0 + j * 8;
                        int_mux_cfg1 = int_mux_cfg0 + 4;
                        int_mux_cfg0_val = snd_soc_component_read(component, int_mux_cfg0);
@@ -2702,9 +2702,6 @@ static int rx_macro_enable_interp_clk(struct snd_soc_component *component,
 
        main_reg = CDC_RX_RXn_RX_PATH_CTL(rx, interp_idx);
        dsm_reg = CDC_RX_RXn_RX_PATH_DSM_CTL(rx, interp_idx);
-       if (interp_idx == INTERP_AUX)
-               dsm_reg = CDC_RX_RXn_RX_PATH_DSM_CTL(rx, 2);
-
        rx_cfg2_reg = CDC_RX_RXn_RX_PATH_CFG2(rx, interp_idx);
 
        if (SND_SOC_DAPM_EVENT_ON(event)) {
@@ -3821,6 +3818,7 @@ static int rx_macro_probe(struct platform_device *pdev)
        case LPASS_CODEC_VERSION_2_0:
        case LPASS_CODEC_VERSION_2_1:
                rx->rxn_reg_stride = 0x80;
+               rx->rxn_reg_stride2 = 0xc;
                def_count = ARRAY_SIZE(rx_defaults) + ARRAY_SIZE(rx_pre_2_5_defaults);
                reg_defaults = kmalloc_array(def_count, sizeof(struct reg_default), GFP_KERNEL);
                if (!reg_defaults)
@@ -3834,6 +3832,7 @@ static int rx_macro_probe(struct platform_device *pdev)
        case LPASS_CODEC_VERSION_2_7:
        case LPASS_CODEC_VERSION_2_8:
                rx->rxn_reg_stride = 0xc0;
+               rx->rxn_reg_stride2 = 0x0;
                def_count = ARRAY_SIZE(rx_defaults) + ARRAY_SIZE(rx_2_5_defaults);
                reg_defaults = kmalloc_array(def_count, sizeof(struct reg_default), GFP_KERNEL);
                if (!reg_defaults)
index b847d7c59ec012778e3d2f44526e96b5210ec494..99986090b4a63a9759763881f3004d0e509e53cd 100644 (file)
@@ -763,6 +763,7 @@ static int max98388_dai_tdm_slot(struct snd_soc_dai *dai,
                        addr = MAX98388_R2044_PCM_TX_CTRL1 + (cnt / 8);
                        bits = cnt % 8;
                        regmap_update_bits(max98388->regmap, addr, bits, bits);
+                       slot_found++;
                        if (slot_found >= MAX_NUM_CH)
                                break;
                }
index 5330cf46b12712e4ed8f15bad858c4b0e1d532d5..3816b25a8ead79b269582c0d51cbd8ed6180af30 100644 (file)
@@ -2,7 +2,7 @@
 //
 // PCM3060 I2C driver
 //
-// Copyright (C) 2018 Kirill Marinushkin <kmarinushkin@birdec.com>
+// Copyright (C) 2018 Kirill Marinushkin <k.marinushkin@gmail.com>
 
 #include <linux/i2c.h>
 #include <linux/module.h>
@@ -55,5 +55,5 @@ static struct i2c_driver pcm3060_i2c_driver = {
 module_i2c_driver(pcm3060_i2c_driver);
 
 MODULE_DESCRIPTION("PCM3060 I2C driver");
-MODULE_AUTHOR("Kirill Marinushkin <kmarinushkin@birdec.com>");
+MODULE_AUTHOR("Kirill Marinushkin <k.marinushkin@gmail.com>");
 MODULE_LICENSE("GPL v2");
index 3b79734b832bd36926359a230c2031a824b9d66b..6095841f2f56f6baaec45366f5a53d9ce8a223c6 100644 (file)
@@ -2,7 +2,7 @@
 //
 // PCM3060 SPI driver
 //
-// Copyright (C) 2018 Kirill Marinushkin <kmarinushkin@birdec.com>
+// Copyright (C) 2018 Kirill Marinushkin <k.marinushkin@gmail.com>
 
 #include <linux/module.h>
 #include <linux/spi/spi.h>
@@ -55,5 +55,5 @@ static struct spi_driver pcm3060_spi_driver = {
 module_spi_driver(pcm3060_spi_driver);
 
 MODULE_DESCRIPTION("PCM3060 SPI driver");
-MODULE_AUTHOR("Kirill Marinushkin <kmarinushkin@birdec.com>");
+MODULE_AUTHOR("Kirill Marinushkin <k.marinushkin@gmail.com>");
 MODULE_LICENSE("GPL v2");
index 586ec8c7246ca73c207b70a09893f6f7a72920ad..8974200652e7eddf7253ed2b36cfc9d1e389647e 100644 (file)
@@ -2,7 +2,7 @@
 //
 // PCM3060 codec driver
 //
-// Copyright (C) 2018 Kirill Marinushkin <kmarinushkin@birdec.com>
+// Copyright (C) 2018 Kirill Marinushkin <k.marinushkin@gmail.com>
 
 #include <linux/module.h>
 #include <sound/pcm_params.h>
@@ -343,5 +343,5 @@ int pcm3060_probe(struct device *dev)
 EXPORT_SYMBOL(pcm3060_probe);
 
 MODULE_DESCRIPTION("PCM3060 codec driver");
-MODULE_AUTHOR("Kirill Marinushkin <kmarinushkin@birdec.com>");
+MODULE_AUTHOR("Kirill Marinushkin <k.marinushkin@gmail.com>");
 MODULE_LICENSE("GPL v2");
index 5e1185e7b03de4ca182229cc57c97d1e70bea86f..1b96835600b45bbaca1bc8d2cc3a0f545fd34fa3 100644 (file)
@@ -2,7 +2,7 @@
 /*
  * PCM3060 codec driver
  *
- * Copyright (C) 2018 Kirill Marinushkin <kmarinushkin@birdec.com>
+ * Copyright (C) 2018 Kirill Marinushkin <k.marinushkin@gmail.com>
  */
 
 #ifndef _SND_SOC_PCM3060_H
index 6641e7c1ddf444a84d2d590c59b82d975f2752d4..5d99877f883972bd081880515cc0fbea3572291a 100644 (file)
@@ -12,7 +12,7 @@
 // Author: Shenghao Ding <[email protected]>
 //
 
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include <linux/firmware.h>
 #include <linux/gpio.h>
 #include <linux/i2c.h>
index 74b628ae1964b7b9ff94179e49ad16873ea07083..bb9ca6354ae1b03b45c6b23eaeb05fa59a240412 100644 (file)
@@ -6,7 +6,7 @@
 //
 // Author: Herve Codina <[email protected]>
 
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include <linux/clk.h>
 #include <linux/firmware.h>
 #include <linux/gpio/consumer.h>
index 16f3425a3e35c0c1cadc1258e3b994ca8592e4f5..855139348edb4ce150fadf68d63fcb646616a471 100644 (file)
@@ -2419,10 +2419,20 @@ static irqreturn_t rt5640_jd_gpio_irq(int irq, void *data)
        return IRQ_HANDLED;
 }
 
-static void rt5640_cancel_work(void *data)
+static void rt5640_disable_irq_and_cancel_work(void *data)
 {
        struct rt5640_priv *rt5640 = data;
 
+       if (rt5640->jd_gpio_irq_requested) {
+               free_irq(rt5640->jd_gpio_irq, rt5640);
+               rt5640->jd_gpio_irq_requested = false;
+       }
+
+       if (rt5640->irq_requested) {
+               free_irq(rt5640->irq, rt5640);
+               rt5640->irq_requested = false;
+       }
+
        cancel_delayed_work_sync(&rt5640->jack_work);
        cancel_delayed_work_sync(&rt5640->bp_work);
 }
@@ -2463,13 +2473,7 @@ static void rt5640_disable_jack_detect(struct snd_soc_component *component)
        if (!rt5640->jack)
                return;
 
-       if (rt5640->jd_gpio_irq_requested)
-               free_irq(rt5640->jd_gpio_irq, rt5640);
-
-       if (rt5640->irq_requested)
-               free_irq(rt5640->irq, rt5640);
-
-       rt5640_cancel_work(rt5640);
+       rt5640_disable_irq_and_cancel_work(rt5640);
 
        if (rt5640->jack->status & SND_JACK_MICROPHONE) {
                rt5640_disable_micbias1_ovcd_irq(component);
@@ -2477,8 +2481,6 @@ static void rt5640_disable_jack_detect(struct snd_soc_component *component)
                snd_soc_jack_report(rt5640->jack, 0, SND_JACK_BTN_0);
        }
 
-       rt5640->jd_gpio_irq_requested = false;
-       rt5640->irq_requested = false;
        rt5640->jd_gpio = NULL;
        rt5640->jack = NULL;
 }
@@ -2798,7 +2800,8 @@ static int rt5640_suspend(struct snd_soc_component *component)
        if (rt5640->jack) {
                /* disable jack interrupts during system suspend */
                disable_irq(rt5640->irq);
-               rt5640_cancel_work(rt5640);
+               cancel_delayed_work_sync(&rt5640->jack_work);
+               cancel_delayed_work_sync(&rt5640->bp_work);
        }
 
        snd_soc_component_force_bias_level(component, SND_SOC_BIAS_OFF);
@@ -3032,7 +3035,7 @@ static int rt5640_i2c_probe(struct i2c_client *i2c)
        INIT_DELAYED_WORK(&rt5640->jack_work, rt5640_jack_work);
 
        /* Make sure work is stopped on probe-error / remove */
-       ret = devm_add_action_or_reset(&i2c->dev, rt5640_cancel_work, rt5640);
+       ret = devm_add_action_or_reset(&i2c->dev, rt5640_disable_irq_and_cancel_work, rt5640);
        if (ret)
                return ret;
 
index 87354bb1564e8d1c904222b9602481967ebd3907..d5c985ff5ac553d7e44a9c33681a6b0ce98b3cfd 100644 (file)
@@ -253,7 +253,7 @@ static int rt722_sdca_read_prop(struct sdw_slave *slave)
        }
 
        /* set the timeout values */
-       prop->clk_stop_timeout = 200;
+       prop->clk_stop_timeout = 900;
 
        /* wake-up event */
        prop->wake_capable = 1;
index cb4c491078c2c9eb369fbfb662c734218b776d7c..07c9d89ab24a24f4cf7c3fbc082deca05caae7c8 100644 (file)
@@ -9,7 +9,7 @@
 #include <linux/i2c.h>
 #include <linux/module.h>
 #include <linux/slab.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #include "sigmadsp.h"
 
index 3de0132c345d0d23f4301ef38e3c019eab50e11b..ae360c97fe1efbf4f2240d75abb2e316be9d29f4 100644 (file)
@@ -20,7 +20,7 @@
 #include <sound/soc.h>
 #include <sound/tlv.h>
 #include <sound/tas2781.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #define ERROR_PRAM_CRCCHK                      0x0000000
 #define ERROR_YRAM_CRCCHK                      0x0000001
index d0ba7cbe03a811ee8cc34cd64ead4b23f8f2729f..12d093437ba9b6d2763aaafdac4c7c43edaa8ff7 100644 (file)
@@ -31,7 +31,7 @@
 #include <sound/tlv.h>
 #include <sound/tas2563-tlv.h>
 #include <sound/tas2781-tlv.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #define X2563_CL_STT_VAL(xreg, xval) \
 {      .reg = xreg, \
index f249e93e2a4e4d76fd346782f0db4d8a1bf5d6c6..6c6e7ae07d80eeeefd0fdf713e09ec097ccda6a0 100644 (file)
@@ -27,7 +27,7 @@
 #include <sound/pcm_params.h>
 #include <sound/soc.h>
 #include <sound/tlv.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #include "tas571x.h"
 
index 187d68e8688c576c55b70654cbbff50d5c571328..d81ab9c25c29e772684f27f02ffe9f590c38ed10 100644 (file)
@@ -12,7 +12,7 @@
  * and mono/stereo Class-D speaker driver.
  */
 
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include <linux/module.h>
 #include <linux/moduleparam.h>
 #include <linux/init.h>
index 45f32d28190813d94abec31c4506bb4463da9fd2..08fb13a334a4cc957740e28b19db5f1df759a161 100644 (file)
@@ -715,12 +715,17 @@ static int wcd937x_codec_enable_aux_pa(struct snd_soc_dapm_widget *w,
        struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
        struct wcd937x_priv *wcd937x = snd_soc_component_get_drvdata(component);
        int hph_mode = wcd937x->hph_mode;
+       u8 val;
 
        switch (event) {
        case SND_SOC_DAPM_PRE_PMU:
+               val = WCD937X_DIGITAL_PDM_WD_CTL2_EN |
+                     WCD937X_DIGITAL_PDM_WD_CTL2_TIMEOUT_SEL |
+                     WCD937X_DIGITAL_PDM_WD_CTL2_HOLD_OFF;
                snd_soc_component_update_bits(component,
                                              WCD937X_DIGITAL_PDM_WD_CTL2,
-                                             BIT(0), BIT(0));
+                                             WCD937X_DIGITAL_PDM_WD_CTL2_MASK,
+                                             val);
                break;
        case SND_SOC_DAPM_POST_PMU:
                usleep_range(1000, 1010);
@@ -741,7 +746,8 @@ static int wcd937x_codec_enable_aux_pa(struct snd_soc_dapm_widget *w,
                                        hph_mode);
                snd_soc_component_update_bits(component,
                                              WCD937X_DIGITAL_PDM_WD_CTL2,
-                                             BIT(0), 0x00);
+                                             WCD937X_DIGITAL_PDM_WD_CTL2_MASK,
+                                             0x00);
                break;
        }
 
@@ -2049,6 +2055,8 @@ static const struct snd_kcontrol_new wcd937x_snd_controls[] = {
                       wcd937x_get_swr_port, wcd937x_set_swr_port),
        SOC_SINGLE_EXT("HPHR Switch", WCD937X_HPH_R, 0, 1, 0,
                       wcd937x_get_swr_port, wcd937x_set_swr_port),
+       SOC_SINGLE_EXT("LO Switch", WCD937X_LO, 0, 1, 0,
+                      wcd937x_get_swr_port, wcd937x_set_swr_port),
 
        SOC_SINGLE_EXT("ADC1 Switch", WCD937X_ADC1, 1, 1, 0,
                       wcd937x_get_swr_port, wcd937x_set_swr_port),
index 35f3d48bd7dd72ff7bd82c1125268e7dc4d51b77..4afa48dcaf743121c1248d35bd8199c146f4cdd8 100644 (file)
 #define WCD937X_DIGITAL_PDM_WD_CTL0            0x3465
 #define WCD937X_DIGITAL_PDM_WD_CTL1            0x3466
 #define WCD937X_DIGITAL_PDM_WD_CTL2            0x3467
+#define WCD937X_DIGITAL_PDM_WD_CTL2_HOLD_OFF   BIT(2)
+#define WCD937X_DIGITAL_PDM_WD_CTL2_TIMEOUT_SEL        BIT(1)
+#define WCD937X_DIGITAL_PDM_WD_CTL2_EN         BIT(0)
+#define WCD937X_DIGITAL_PDM_WD_CTL2_MASK       GENMASK(2, 0)
 #define WCD937X_DIGITAL_INTR_MODE              0x346A
 #define WCD937X_DIGITAL_INTR_MASK_0            0x346B
 #define WCD937X_DIGITAL_INTR_MASK_1            0x346C
index 651f1319204de275edb230727a794a2fe86c9d44..9fc7a8325724ff96b82c4cba34e8678b1b0c2b5a 100644 (file)
@@ -25,7 +25,7 @@
 
 #include <linux/mfd/arizona/core.h>
 #include <linux/mfd/arizona/registers.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #include "arizona.h"
 #include "wm5102.h"
index 7878c7a58ff10165a5834280255f8cfe66e043fe..d08419b108fea16fcbecea86c105f5773c3a3551 100644 (file)
@@ -25,7 +25,7 @@
 #include <linux/mfd/wm8994/pdata.h>
 #include <linux/mfd/wm8994/gpio.h>
 
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 
 #include "wm8994.h"
 
index a65f5b9935a2c130f447a912cdef1e91e2838dd8..0b247f16a163fa0e114987fcdf293b73073aaf58 100644 (file)
@@ -119,10 +119,10 @@ static irqreturn_t esai_isr(int irq, void *devid)
                dev_dbg(&pdev->dev, "isr: Transmission Initialized\n");
 
        if (esr & ESAI_ESR_RFF_MASK)
-               dev_warn(&pdev->dev, "isr: Receiving overrun\n");
+               dev_dbg(&pdev->dev, "isr: Receiving overrun\n");
 
        if (esr & ESAI_ESR_TFE_MASK)
-               dev_warn(&pdev->dev, "isr: Transmission underrun\n");
+               dev_dbg(&pdev->dev, "isr: Transmission underrun\n");
 
        if (esr & ESAI_ESR_TLS_MASK)
                dev_dbg(&pdev->dev, "isr: Just transmitted the last slot\n");
index 193be098fa5e0ff524452ec2589edb1daf62559d..0c71a73476dfa65cf3c94bf7846b34e383819423 100644 (file)
 
 #define MICFIL_OSR_DEFAULT     16
 
+#define MICFIL_NUM_RATES       7
+#define MICFIL_CLK_SRC_NUM     3
+/* clock source ids */
+#define MICFIL_AUDIO_PLL1      0
+#define MICFIL_AUDIO_PLL2      1
+#define MICFIL_CLK_EXT3                2
+
 enum quality {
        QUALITY_HIGH,
        QUALITY_MEDIUM,
@@ -45,9 +52,12 @@ struct fsl_micfil {
        struct clk *mclk;
        struct clk *pll8k_clk;
        struct clk *pll11k_clk;
+       struct clk *clk_src[MICFIL_CLK_SRC_NUM];
        struct snd_dmaengine_dai_dma_data dma_params_rx;
        struct sdma_peripheral_config sdmacfg;
        struct snd_soc_card *card;
+       struct snd_pcm_hw_constraint_list constraint_rates;
+       unsigned int constraint_rates_list[MICFIL_NUM_RATES];
        unsigned int dataline;
        char name[32];
        int irq[MICFIL_IRQ_LINES];
@@ -67,6 +77,7 @@ struct fsl_micfil_soc_data {
        bool imx;
        bool use_edma;
        bool use_verid;
+       bool volume_sx;
        u64  formats;
 };
 
@@ -76,6 +87,7 @@ static struct fsl_micfil_soc_data fsl_micfil_imx8mm = {
        .fifo_depth = 8,
        .dataline =  0xf,
        .formats = SNDRV_PCM_FMTBIT_S16_LE,
+       .volume_sx = true,
 };
 
 static struct fsl_micfil_soc_data fsl_micfil_imx8mp = {
@@ -84,6 +96,7 @@ static struct fsl_micfil_soc_data fsl_micfil_imx8mp = {
        .fifo_depth = 32,
        .dataline =  0xf,
        .formats = SNDRV_PCM_FMTBIT_S32_LE,
+       .volume_sx = false,
 };
 
 static struct fsl_micfil_soc_data fsl_micfil_imx93 = {
@@ -94,6 +107,7 @@ static struct fsl_micfil_soc_data fsl_micfil_imx93 = {
        .formats = SNDRV_PCM_FMTBIT_S32_LE,
        .use_edma = true,
        .use_verid = true,
+       .volume_sx = false,
 };
 
 static const struct of_device_id fsl_micfil_dt_ids[] = {
@@ -317,7 +331,26 @@ static int hwvad_detected(struct snd_kcontrol *kcontrol,
        return 0;
 }
 
-static const struct snd_kcontrol_new fsl_micfil_snd_controls[] = {
+static const struct snd_kcontrol_new fsl_micfil_volume_controls[] = {
+       SOC_SINGLE_TLV("CH0 Volume", REG_MICFIL_OUT_CTRL,
+                      MICFIL_OUTGAIN_CHX_SHIFT(0), 0xF, 0, gain_tlv),
+       SOC_SINGLE_TLV("CH1 Volume", REG_MICFIL_OUT_CTRL,
+                      MICFIL_OUTGAIN_CHX_SHIFT(1), 0xF, 0, gain_tlv),
+       SOC_SINGLE_TLV("CH2 Volume", REG_MICFIL_OUT_CTRL,
+                      MICFIL_OUTGAIN_CHX_SHIFT(2), 0xF, 0, gain_tlv),
+       SOC_SINGLE_TLV("CH3 Volume", REG_MICFIL_OUT_CTRL,
+                      MICFIL_OUTGAIN_CHX_SHIFT(3), 0xF, 0, gain_tlv),
+       SOC_SINGLE_TLV("CH4 Volume", REG_MICFIL_OUT_CTRL,
+                      MICFIL_OUTGAIN_CHX_SHIFT(4), 0xF, 0, gain_tlv),
+       SOC_SINGLE_TLV("CH5 Volume", REG_MICFIL_OUT_CTRL,
+                      MICFIL_OUTGAIN_CHX_SHIFT(5), 0xF, 0, gain_tlv),
+       SOC_SINGLE_TLV("CH6 Volume", REG_MICFIL_OUT_CTRL,
+                      MICFIL_OUTGAIN_CHX_SHIFT(6), 0xF, 0, gain_tlv),
+       SOC_SINGLE_TLV("CH7 Volume", REG_MICFIL_OUT_CTRL,
+                      MICFIL_OUTGAIN_CHX_SHIFT(7), 0xF, 0, gain_tlv),
+};
+
+static const struct snd_kcontrol_new fsl_micfil_volume_sx_controls[] = {
        SOC_SINGLE_SX_TLV("CH0 Volume", REG_MICFIL_OUT_CTRL,
                          MICFIL_OUTGAIN_CHX_SHIFT(0), 0x8, 0xF, gain_tlv),
        SOC_SINGLE_SX_TLV("CH1 Volume", REG_MICFIL_OUT_CTRL,
@@ -334,6 +367,9 @@ static const struct snd_kcontrol_new fsl_micfil_snd_controls[] = {
                          MICFIL_OUTGAIN_CHX_SHIFT(6), 0x8, 0xF, gain_tlv),
        SOC_SINGLE_SX_TLV("CH7 Volume", REG_MICFIL_OUT_CTRL,
                          MICFIL_OUTGAIN_CHX_SHIFT(7), 0x8, 0xF, gain_tlv),
+};
+
+static const struct snd_kcontrol_new fsl_micfil_snd_controls[] = {
        SOC_ENUM_EXT("MICFIL Quality Select",
                     fsl_micfil_quality_enum,
                     micfil_quality_get, micfil_quality_set),
@@ -449,12 +485,34 @@ static int fsl_micfil_startup(struct snd_pcm_substream *substream,
                              struct snd_soc_dai *dai)
 {
        struct fsl_micfil *micfil = snd_soc_dai_get_drvdata(dai);
+       unsigned int rates[MICFIL_NUM_RATES] = {8000, 11025, 16000, 22050, 32000, 44100, 48000};
+       int i, j, k = 0;
+       u64 clk_rate;
 
        if (!micfil) {
                dev_err(dai->dev, "micfil dai priv_data not set\n");
                return -EINVAL;
        }
 
+       micfil->constraint_rates.list = micfil->constraint_rates_list;
+       micfil->constraint_rates.count = 0;
+
+       for (j = 0; j < MICFIL_NUM_RATES; j++) {
+               for (i = 0; i < MICFIL_CLK_SRC_NUM; i++) {
+                       clk_rate = clk_get_rate(micfil->clk_src[i]);
+                       if (clk_rate != 0 && do_div(clk_rate, rates[j]) == 0) {
+                               micfil->constraint_rates_list[k++] = rates[j];
+                               micfil->constraint_rates.count++;
+                               break;
+                       }
+               }
+       }
+
+       if (micfil->constraint_rates.count > 0)
+               snd_pcm_hw_constraint_list(substream->runtime, 0,
+                                          SNDRV_PCM_HW_PARAM_RATE,
+                                          &micfil->constraint_rates);
+
        return 0;
 }
 
@@ -801,6 +859,20 @@ static int fsl_micfil_dai_probe(struct snd_soc_dai *cpu_dai)
        return 0;
 }
 
+static int fsl_micfil_component_probe(struct snd_soc_component *component)
+{
+       struct fsl_micfil *micfil = snd_soc_component_get_drvdata(component);
+
+       if (micfil->soc->volume_sx)
+               snd_soc_add_component_controls(component, fsl_micfil_volume_sx_controls,
+                                              ARRAY_SIZE(fsl_micfil_volume_sx_controls));
+       else
+               snd_soc_add_component_controls(component, fsl_micfil_volume_controls,
+                                              ARRAY_SIZE(fsl_micfil_volume_controls));
+
+       return 0;
+}
+
 static const struct snd_soc_dai_ops fsl_micfil_dai_ops = {
        .probe          = fsl_micfil_dai_probe,
        .startup        = fsl_micfil_startup,
@@ -821,6 +893,7 @@ static struct snd_soc_dai_driver fsl_micfil_dai = {
 
 static const struct snd_soc_component_driver fsl_micfil_component = {
        .name           = "fsl-micfil-dai",
+       .probe          = fsl_micfil_component_probe,
        .controls       = fsl_micfil_snd_controls,
        .num_controls   = ARRAY_SIZE(fsl_micfil_snd_controls),
        .legacy_dai_naming      = 1,
@@ -1134,6 +1207,12 @@ static int fsl_micfil_probe(struct platform_device *pdev)
        fsl_asoc_get_pll_clocks(&pdev->dev, &micfil->pll8k_clk,
                                &micfil->pll11k_clk);
 
+       micfil->clk_src[MICFIL_AUDIO_PLL1] = micfil->pll8k_clk;
+       micfil->clk_src[MICFIL_AUDIO_PLL2] = micfil->pll11k_clk;
+       micfil->clk_src[MICFIL_CLK_EXT3] = devm_clk_get(&pdev->dev, "clkext3");
+       if (IS_ERR(micfil->clk_src[MICFIL_CLK_EXT3]))
+               micfil->clk_src[MICFIL_CLK_EXT3] = NULL;
+
        /* init regmap */
        regs = devm_platform_get_and_ioremap_resource(pdev, 0, &res);
        if (IS_ERR(regs))
index ab58a446107352230588eda66206af8a4a7dbecd..634168d2bb6e5431624d9df2b8e95e2c57e0a104 100644 (file)
@@ -613,6 +613,9 @@ static int fsl_sai_hw_params(struct snd_pcm_substream *substream,
 
        val_cr4 |= FSL_SAI_CR4_FRSZ(slots);
 
+       /* Set to avoid channel swap */
+       val_cr4 |= FSL_SAI_CR4_FCONT;
+
        /* Set to output mode to avoid tri-stated data pins */
        if (tx)
                val_cr4 |= FSL_SAI_CR4_CHMOD;
@@ -699,7 +702,7 @@ static int fsl_sai_hw_params(struct snd_pcm_substream *substream,
 
        regmap_update_bits(sai->regmap, FSL_SAI_xCR4(tx, ofs),
                           FSL_SAI_CR4_SYWD_MASK | FSL_SAI_CR4_FRSZ_MASK |
-                          FSL_SAI_CR4_CHMOD_MASK,
+                          FSL_SAI_CR4_CHMOD_MASK | FSL_SAI_CR4_FCONT_MASK,
                           val_cr4);
        regmap_update_bits(sai->regmap, FSL_SAI_xCR5(tx, ofs),
                           FSL_SAI_CR5_WNW_MASK | FSL_SAI_CR5_W0W_MASK |
index dadbd16ee3945768ad4b95adf5902b62d5def483..9c4d19fe22c654f703fc66c77055885933394ff4 100644 (file)
 
 /* SAI Transmit and Receive Configuration 4 Register */
 
+#define FSL_SAI_CR4_FCONT_MASK BIT(28)
 #define FSL_SAI_CR4_FCONT      BIT(28)
 #define FSL_SAI_CR4_FCOMB_SHIFT BIT(26)
 #define FSL_SAI_CR4_FCOMB_SOFT  BIT(27)
index 98b37dd2b9013fa3ad81b7ba2610840fa5a1519c..a7215bad648457bdc1b5ef6cdf6fe0bca0fc3db5 100644 (file)
@@ -710,6 +710,7 @@ static int imx_card_probe(struct platform_device *pdev)
 
        data->plat_data = plat_data;
        data->card.dev = &pdev->dev;
+       data->card.owner = THIS_MODULE;
 
        dev_set_drvdata(&pdev->dev, &data->card);
        snd_soc_card_set_drvdata(&data->card, data);
index 9956dc63db749918e93bb05d774efb261f3f433a..25718063047559f4d34fb4b3e86c07c4c03f1b7d 100644 (file)
@@ -125,6 +125,28 @@ static const struct sst_res_info bytcr_res_info = {
        .acpi_ipc_irq_index = 0
 };
 
+/* For "LPE0F28" ACPI device found on some Android factory OS models */
+static const struct sst_res_info lpe8086_res_info = {
+       .shim_offset = 0x140000,
+       .shim_size = 0x000100,
+       .shim_phy_addr = SST_BYT_SHIM_PHY_ADDR,
+       .ssp0_offset = 0xa0000,
+       .ssp0_size = 0x1000,
+       .dma0_offset = 0x98000,
+       .dma0_size = 0x4000,
+       .dma1_offset = 0x9c000,
+       .dma1_size = 0x4000,
+       .iram_offset = 0x0c0000,
+       .iram_size = 0x14000,
+       .dram_offset = 0x100000,
+       .dram_size = 0x28000,
+       .mbox_offset = 0x144000,
+       .mbox_size = 0x1000,
+       .acpi_lpe_res_index = 1,
+       .acpi_ddr_index = 0,
+       .acpi_ipc_irq_index = 0
+};
+
 static struct sst_platform_info byt_rvp_platform_data = {
        .probe_data = &byt_fwparse_info,
        .ipc_info = &byt_ipc_info,
@@ -268,10 +290,38 @@ static int sst_acpi_probe(struct platform_device *pdev)
                mach->pdata = &chv_platform_data;
        pdata = mach->pdata;
 
-       ret = kstrtouint(id->id, 16, &dev_id);
-       if (ret < 0) {
-               dev_err(dev, "Unique device id conversion error: %d\n", ret);
-               return ret;
+       if (!strcmp(id->id, "LPE0F28")) {
+               struct resource *rsrc;
+
+               /* Use regular BYT SST PCI VID:PID */
+               dev_id = 0x80860F28;
+               byt_rvp_platform_data.res_info = &lpe8086_res_info;
+
+               /*
+                * The "LPE0F28" ACPI device has separate IO-mem resources for:
+                * DDR, SHIM, MBOX, IRAM, DRAM, CFG
+                * None of which covers the entire LPE base address range.
+                * lpe8086_res_info.acpi_lpe_res_index points to the SHIM.
+                * Patch this to cover the entire base address range as expected
+                * by sst_platform_get_resources().
+                */
+               rsrc = platform_get_resource(pdev, IORESOURCE_MEM,
+                                            pdata->res_info->acpi_lpe_res_index);
+               if (!rsrc) {
+                       dev_err(dev, "Invalid SHIM base\n");
+                       return -EIO;
+               }
+               rsrc->start -= pdata->res_info->shim_offset;
+               rsrc->end = rsrc->start + 0x200000 - 1;
+       } else {
+               ret = kstrtouint(id->id, 16, &dev_id);
+               if (ret < 0) {
+                       dev_err(dev, "Unique device id conversion error: %d\n", ret);
+                       return ret;
+               }
+
+               if (soc_intel_is_byt_cr(pdev))
+                       byt_rvp_platform_data.res_info = &bytcr_res_info;
        }
 
        dev_dbg(dev, "ACPI device id: %x\n", dev_id);
@@ -280,11 +330,6 @@ static int sst_acpi_probe(struct platform_device *pdev)
        if (ret < 0)
                return ret;
 
-       if (soc_intel_is_byt_cr(pdev)) {
-               /* override resource info */
-               byt_rvp_platform_data.res_info = &bytcr_res_info;
-       }
-
        /* update machine parameters */
        mach->mach_params.acpi_ipc_irq_index =
                pdata->res_info->acpi_ipc_irq_index;
@@ -344,6 +389,7 @@ static void sst_acpi_remove(struct platform_device *pdev)
 }
 
 static const struct acpi_device_id sst_acpi_ids[] = {
+       { "LPE0F28", (unsigned long)&snd_soc_acpi_intel_baytrail_machines},
        { "80860F28", (unsigned long)&snd_soc_acpi_intel_baytrail_machines},
        { "808622A8", (unsigned long)&snd_soc_acpi_intel_cherrytrail_machines},
        { },
index da7bac09acb4eba67e563f48593a34f633a87d95..73d4bde9b2f78839ad220c822be39bd968e6f1ac 100644 (file)
@@ -28,6 +28,7 @@
 #include "avs.h"
 #include "cldma.h"
 #include "messages.h"
+#include "pcm.h"
 
 static u32 pgctl_mask = AZX_PGCTL_LSRMD_MASK;
 module_param(pgctl_mask, uint, 0444);
@@ -247,7 +248,7 @@ static void hdac_stream_update_pos(struct hdac_stream *stream, u64 buffer_size)
 static void hdac_update_stream(struct hdac_bus *bus, struct hdac_stream *stream)
 {
        if (stream->substream) {
-               snd_pcm_period_elapsed(stream->substream);
+               avs_period_elapsed(stream->substream);
        } else if (stream->cstream) {
                u64 buffer_size = stream->cstream->runtime->buffer_size;
 
index afc0fc74cf9419f973c40314e6f302f23fcb9c1b..4af81158035681b5b8ecfd7efef041efcc719f36 100644 (file)
@@ -16,6 +16,7 @@
 #include <sound/soc-component.h>
 #include "avs.h"
 #include "path.h"
+#include "pcm.h"
 #include "topology.h"
 #include "../../codecs/hda.h"
 
@@ -30,6 +31,7 @@ struct avs_dma_data {
                struct hdac_ext_stream *host_stream;
        };
 
+       struct work_struct period_elapsed_work;
        struct snd_pcm_substream *substream;
 };
 
@@ -56,6 +58,22 @@ avs_dai_find_path_template(struct snd_soc_dai *dai, bool is_fe, int direction)
        return dw->priv;
 }
 
+static void avs_period_elapsed_work(struct work_struct *work)
+{
+       struct avs_dma_data *data = container_of(work, struct avs_dma_data, period_elapsed_work);
+
+       snd_pcm_period_elapsed(data->substream);
+}
+
+void avs_period_elapsed(struct snd_pcm_substream *substream)
+{
+       struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
+       struct snd_soc_dai *dai = snd_soc_rtd_to_cpu(rtd, 0);
+       struct avs_dma_data *data = snd_soc_dai_get_dma_data(dai, substream);
+
+       schedule_work(&data->period_elapsed_work);
+}
+
 static int avs_dai_startup(struct snd_pcm_substream *substream, struct snd_soc_dai *dai)
 {
        struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
@@ -77,6 +95,7 @@ static int avs_dai_startup(struct snd_pcm_substream *substream, struct snd_soc_d
        data->substream = substream;
        data->template = template;
        data->adev = adev;
+       INIT_WORK(&data->period_elapsed_work, avs_period_elapsed_work);
        snd_soc_dai_set_dma_data(dai, substream, data);
 
        if (rtd->dai_link->ignore_suspend)
diff --git a/sound/soc/intel/avs/pcm.h b/sound/soc/intel/avs/pcm.h
new file mode 100644 (file)
index 0000000..0f3615c
--- /dev/null
@@ -0,0 +1,16 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright(c) 2024 Intel Corporation
+ *
+ * Authors: Cezary Rojewski <[email protected]>
+ *          Amadeusz Slawinski <[email protected]>
+ */
+
+#ifndef __SOUND_SOC_INTEL_AVS_PCM_H
+#define __SOUND_SOC_INTEL_AVS_PCM_H
+
+#include <sound/pcm.h>
+
+void avs_period_elapsed(struct snd_pcm_substream *substream);
+
+#endif
index 2ed49acb4e36e79467a082df6273839d6800f0b2..54f77f57ec8e2500323931b7796ac56bfe24fa40 100644 (file)
@@ -17,6 +17,7 @@
 #include <linux/acpi.h>
 #include <linux/clk.h>
 #include <linux/device.h>
+#include <linux/device/bus.h>
 #include <linux/dmi.h>
 #include <linux/gpio/consumer.h>
 #include <linux/gpio/machine.h>
@@ -32,6 +33,8 @@
 #include "../atom/sst-atom-controls.h"
 #include "../common/soc-intel-quirks.h"
 
+#define BYT_RT5640_FALLBACK_CODEC_DEV_NAME     "i2c-rt5640"
+
 enum {
        BYT_RT5640_DMIC1_MAP,
        BYT_RT5640_DMIC2_MAP,
@@ -1129,6 +1132,21 @@ static const struct dmi_system_id byt_rt5640_quirk_table[] = {
                                        BYT_RT5640_SSP0_AIF2 |
                                        BYT_RT5640_MCLK_EN),
        },
+       {       /* Vexia Edu Atla 10 tablet */
+               .matches = {
+                       DMI_MATCH(DMI_BOARD_VENDOR, "AMI Corporation"),
+                       DMI_MATCH(DMI_BOARD_NAME, "Aptio CRB"),
+                       /* Above strings are too generic, also match on BIOS date */
+                       DMI_MATCH(DMI_BIOS_DATE, "08/25/2014"),
+               },
+               .driver_data = (void *)(BYT_RT5640_IN1_MAP |
+                                       BYT_RT5640_JD_SRC_JD2_IN4N |
+                                       BYT_RT5640_OVCD_TH_2000UA |
+                                       BYT_RT5640_OVCD_SF_0P75 |
+                                       BYT_RT5640_DIFF_MIC |
+                                       BYT_RT5640_SSP0_AIF2 |
+                                       BYT_RT5640_MCLK_EN),
+       },
        {       /* Voyo Winpad A15 */
                .matches = {
                        DMI_MATCH(DMI_BOARD_VENDOR, "AMI Corporation"),
@@ -1698,9 +1716,33 @@ static int snd_byt_rt5640_mc_probe(struct platform_device *pdev)
 
        codec_dev = acpi_get_first_physical_node(adev);
        acpi_dev_put(adev);
-       if (!codec_dev)
-               return -EPROBE_DEFER;
-       priv->codec_dev = get_device(codec_dev);
+
+       if (codec_dev) {
+               priv->codec_dev = get_device(codec_dev);
+       } else {
+               /*
+                * Special case for Android tablets where the codec i2c_client
+                * has been manually instantiated by x86_android_tablets.ko due
+                * to a broken DSDT.
+                */
+               codec_dev = bus_find_device_by_name(&i2c_bus_type, NULL,
+                                       BYT_RT5640_FALLBACK_CODEC_DEV_NAME);
+               if (!codec_dev)
+                       return -EPROBE_DEFER;
+
+               if (!i2c_verify_client(codec_dev)) {
+                       dev_err(dev, "Error '%s' is not an i2c_client\n",
+                               BYT_RT5640_FALLBACK_CODEC_DEV_NAME);
+                       put_device(codec_dev);
+               }
+
+               /* fixup codec name */
+               strscpy(byt_rt5640_codec_name, BYT_RT5640_FALLBACK_CODEC_DEV_NAME,
+                       sizeof(byt_rt5640_codec_name));
+
+               /* bus_find_device() returns a reference no need to get() */
+               priv->codec_dev = codec_dev;
+       }
 
        /*
         * swap SSP0 if bytcr is detected
index 5196d96f5c0e86e0cf9a6ffd4668def886ab1b47..35d707d3ae9c7112e2d4bdb67d6310d1196636ee 100644 (file)
@@ -800,6 +800,9 @@ static int create_ssp_dailinks(struct snd_soc_card *card,
                char *cpu_dai_name = devm_kasprintf(dev, GFP_KERNEL, "SSP%d Pin", i);
                char *codec_name = devm_kasprintf(dev, GFP_KERNEL, "i2c-%s:0%d",
                                                  ssp_info->acpi_id, j++);
+               if (!name || !cpu_dai_name || !codec_name)
+                       return -ENOMEM;
+
                int playback = ssp_info->dais[0].direction[SNDRV_PCM_STREAM_PLAYBACK];
                int capture = ssp_info->dais[0].direction[SNDRV_PCM_STREAM_CAPTURE];
 
@@ -866,6 +869,9 @@ static int create_hdmi_dailinks(struct snd_soc_card *card,
        for (i = 0; i < hdmi_num; i++) {
                char *name = devm_kasprintf(dev, GFP_KERNEL, "iDisp%d", i + 1);
                char *cpu_dai_name = devm_kasprintf(dev, GFP_KERNEL, "iDisp%d Pin", i + 1);
+               if (!name || !cpu_dai_name)
+                       return -ENOMEM;
+
                char *codec_name, *codec_dai_name;
 
                if (intel_ctx->hdmi.idisp_codec) {
@@ -877,6 +883,9 @@ static int create_hdmi_dailinks(struct snd_soc_card *card,
                        codec_dai_name = "snd-soc-dummy-dai";
                }
 
+               if (!codec_dai_name)
+                       return -ENOMEM;
+
                ret = asoc_sdw_init_simple_dai_link(dev, *dai_links, be_id, name,
                                                    1, 0, // HDMI only supports playback
                                                    cpu_dai_name, platform_component->name,
@@ -900,6 +909,9 @@ static int create_bt_dailinks(struct snd_soc_card *card,
                        SOF_BT_OFFLOAD_SSP_SHIFT;
        char *name = devm_kasprintf(dev, GFP_KERNEL, "SSP%d-BT", port);
        char *cpu_dai_name = devm_kasprintf(dev, GFP_KERNEL, "SSP%d Pin", port);
+       if (!name || !cpu_dai_name)
+               return -ENOMEM;
+
        int ret;
 
        ret = asoc_sdw_init_simple_dai_link(dev, *dai_links, be_id, name,
index c97c961187dd5e1c9a98ea64622823a182cd5e74..072b8486d0727c4c35b8ecd04018bf67ef9a0b33 100644 (file)
@@ -191,6 +191,7 @@ static const struct snd_soc_acpi_link_adr arl_cs42l43_l0[] = {
                .num_adr = ARRAY_SIZE(cs42l43_0_adr),
                .adr_d = cs42l43_0_adr,
        },
+       {}
 };
 
 static const struct snd_soc_acpi_link_adr arl_cs42l43_l2[] = {
@@ -199,6 +200,7 @@ static const struct snd_soc_acpi_link_adr arl_cs42l43_l2[] = {
                .num_adr = ARRAY_SIZE(cs42l43_2_adr),
                .adr_d = cs42l43_2_adr,
        },
+       {}
 };
 
 static const struct snd_soc_acpi_link_adr arl_cs42l43_l2_cs35l56_l3[] = {
index 3c4e0c7ca8eee8425d9ca5b13c87185499432e2a..094ed4b27cb06834004b4855891a6e3f337820ea 100644 (file)
@@ -225,6 +225,15 @@ static const struct snd_soc_acpi_adr_device rt1316_3_group1_adr[] = {
        }
 };
 
+static const struct snd_soc_acpi_adr_device rt1318_1_adr[] = {
+       {
+               .adr = 0x000133025D131801ull,
+               .num_endpoints = 1,
+               .endpoints = &single_endpoint,
+               .name_prefix = "rt1318-1"
+       }
+};
+
 static const struct snd_soc_acpi_adr_device rt1318_1_group1_adr[] = {
        {
                .adr = 0x000130025D131801ull,
@@ -243,6 +252,15 @@ static const struct snd_soc_acpi_adr_device rt1318_2_group1_adr[] = {
        }
 };
 
+static const struct snd_soc_acpi_adr_device rt713_0_adr[] = {
+       {
+               .adr = 0x000031025D071301ull,
+               .num_endpoints = 1,
+               .endpoints = &single_endpoint,
+               .name_prefix = "rt713"
+       }
+};
+
 static const struct snd_soc_acpi_adr_device rt714_0_adr[] = {
        {
                .adr = 0x000030025D071401ull,
@@ -378,6 +396,20 @@ static const struct snd_soc_acpi_link_adr lnl_sdw_rt1318_l12_rt714_l0[] = {
        {}
 };
 
+static const struct snd_soc_acpi_link_adr lnl_sdw_rt713_l0_rt1318_l1[] = {
+       {
+               .mask = BIT(0),
+               .num_adr = ARRAY_SIZE(rt713_0_adr),
+               .adr_d = rt713_0_adr,
+       },
+       {
+               .mask = BIT(1),
+               .num_adr = ARRAY_SIZE(rt1318_1_adr),
+               .adr_d = rt1318_1_adr,
+       },
+       {}
+};
+
 /* this table is used when there is no I2S codec present */
 struct snd_soc_acpi_mach snd_soc_acpi_intel_lnl_sdw_machines[] = {
        /* mockup tests need to be first */
@@ -447,6 +479,12 @@ struct snd_soc_acpi_mach snd_soc_acpi_intel_lnl_sdw_machines[] = {
                .drv_name = "sof_sdw",
                .sof_tplg_filename = "sof-lnl-rt1318-l12-rt714-l0.tplg"
        },
+       {
+               .link_mask = BIT(0) | BIT(1),
+               .links = lnl_sdw_rt713_l0_rt1318_l1,
+               .drv_name = "sof_sdw",
+               .sof_tplg_filename = "sof-lnl-rt713-l0-rt1318-l1.tplg"
+       },
        {},
 };
 EXPORT_SYMBOL_GPL(snd_soc_acpi_intel_lnl_sdw_machines);
index bc8817633b81b010421337ad5e95f7b717ee8f74..b83ac2e6337cf3095b120dbbc0f14c290619dba1 100644 (file)
@@ -198,6 +198,7 @@ static const struct snd_soc_acpi_link_adr rpl_cs42l43_l0[] = {
                .num_adr = ARRAY_SIZE(cs42l43_0_adr),
                .adr_d = cs42l43_0_adr,
        },
+       {}
 };
 
 static const struct snd_soc_acpi_link_adr rpl_sdca_3_in_1[] = {
index 7379f24d385c88922b8167db9b18329715fbde6b..7910d5d9ac4ffebc7c80f59b020e766da6c8d8b3 100644 (file)
@@ -144,6 +144,7 @@ static int loongson_card_parse_of(struct loongson_card_data *data)
                        dev_err(dev, "getting cpu dlc error (%d)\n", ret);
                        goto err;
                }
+               loongson_dai_links[i].platforms->of_node = loongson_dai_links[i].cpus->of_node;
 
                ret = snd_soc_of_get_dlc(codec, NULL, loongson_dai_links[i].codecs, 0);
                if (ret < 0) {
index 762491d6f2f2e9ee168e535509639563bd7b012d..ca7a30ebd26ab1acaa827784d0c775ff415e021b 100644 (file)
@@ -157,6 +157,7 @@ config SND_SOC_SDM845
        depends on COMMON_CLK
        select SND_SOC_QDSP6
        select SND_SOC_QCOM_COMMON
+       select SND_SOC_QCOM_SDW
        select SND_SOC_RT5663
        select SND_SOC_MAX98927
        imply SND_SOC_CROS_EC_CODEC
@@ -208,6 +209,7 @@ config SND_SOC_SC7280
        tristate "SoC Machine driver for SC7280 boards"
        depends on I2C && SOUNDWIRE
        select SND_SOC_QCOM_COMMON
+       select SND_SOC_QCOM_SDW
        select SND_SOC_LPASS_SC7280
        select SND_SOC_MAX98357A
        select SND_SOC_WCD938X_SDW
index 5a47f661e0c6f79599aba9361bfed99f1bd93f90..242bc16da36daf9d1a8d28ac85b77abdea21b4f3 100644 (file)
@@ -1242,6 +1242,8 @@ int asoc_qcom_lpass_cpu_platform_probe(struct platform_device *pdev)
        /* Allocation for i2sctl regmap fields */
        drvdata->i2sctl = devm_kzalloc(&pdev->dev, sizeof(struct lpaif_i2sctl),
                                        GFP_KERNEL);
+       if (!drvdata->i2sctl)
+               return -ENOMEM;
 
        /* Initialize bitfields for dai I2SCTL register */
        ret = lpass_cpu_init_i2sctl_bitfields(dev, drvdata->i2sctl,
index 207ac5da4dd430bf599b1468e290fba63c3760e0..230af8d7b205d418e6d278b4222278a3e6c0c595 100644 (file)
@@ -23,6 +23,7 @@
 #include "common.h"
 #include "lpass.h"
 #include "qdsp6/q6afe.h"
+#include "sdw.h"
 
 #define DEFAULT_MCLK_RATE              19200000
 #define RT5682_PLL_FREQ (48000 * 512)
@@ -316,6 +317,7 @@ static void sc7280_snd_shutdown(struct snd_pcm_substream *substream)
        struct snd_soc_card *card = rtd->card;
        struct sc7280_snd_data *data = snd_soc_card_get_drvdata(card);
        struct snd_soc_dai *cpu_dai = snd_soc_rtd_to_cpu(rtd, 0);
+       struct sdw_stream_runtime *sruntime = data->sruntime[cpu_dai->id];
 
        switch (cpu_dai->id) {
        case MI2S_PRIMARY:
@@ -333,6 +335,9 @@ static void sc7280_snd_shutdown(struct snd_pcm_substream *substream)
        default:
                break;
        }
+
+       data->sruntime[cpu_dai->id] = NULL;
+       sdw_release_stream(sruntime);
 }
 
 static int sc7280_snd_startup(struct snd_pcm_substream *substream)
@@ -347,6 +352,8 @@ static int sc7280_snd_startup(struct snd_pcm_substream *substream)
        switch (cpu_dai->id) {
        case MI2S_PRIMARY:
                ret = sc7280_rt5682_init(rtd);
+               if (ret)
+                       return ret;
                break;
        case SECONDARY_MI2S_RX:
                codec_dai_fmt |= SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_I2S;
@@ -360,7 +367,8 @@ static int sc7280_snd_startup(struct snd_pcm_substream *substream)
        default:
                break;
        }
-       return ret;
+
+       return qcom_snd_sdw_startup(substream);
 }
 
 static const struct snd_soc_ops sc7280_ops = {
index 75701546b6ea8b4344ac6ef9e9d06e7ce924e283..a479d7e5b7fbdca0719f12a899e8b9f7b851f488 100644 (file)
@@ -15,6 +15,7 @@
 #include <uapi/linux/input-event-codes.h>
 #include "common.h"
 #include "qdsp6/q6afe.h"
+#include "sdw.h"
 #include "../codecs/rt5663.h"
 
 #define DRIVER_NAME    "sdm845"
@@ -416,7 +417,7 @@ static int sdm845_snd_startup(struct snd_pcm_substream *substream)
                pr_err("%s: invalid dai id 0x%x\n", __func__, cpu_dai->id);
                break;
        }
-       return 0;
+       return qcom_snd_sdw_startup(substream);
 }
 
 static void  sdm845_snd_shutdown(struct snd_pcm_substream *substream)
@@ -425,6 +426,7 @@ static void  sdm845_snd_shutdown(struct snd_pcm_substream *substream)
        struct snd_soc_card *card = rtd->card;
        struct sdm845_snd_data *data = snd_soc_card_get_drvdata(card);
        struct snd_soc_dai *cpu_dai = snd_soc_rtd_to_cpu(rtd, 0);
+       struct sdw_stream_runtime *sruntime = data->sruntime[cpu_dai->id];
 
        switch (cpu_dai->id) {
        case PRIMARY_MI2S_RX:
@@ -463,6 +465,9 @@ static void  sdm845_snd_shutdown(struct snd_pcm_substream *substream)
                pr_err("%s: invalid dai id 0x%x\n", __func__, cpu_dai->id);
                break;
        }
+
+       data->sruntime[cpu_dai->id] = NULL;
+       sdw_release_stream(sruntime);
 }
 
 static int sdm845_snd_prepare(struct snd_pcm_substream *substream)
index 274bab28209aea0f2783f162f9048205b67524b2..19adadedc88a2aa42b0c4f73320c7fe911fa8f06 100644 (file)
@@ -174,6 +174,7 @@ static int sm8250_platform_probe(struct platform_device *pdev)
 
 static const struct of_device_id snd_sm8250_dt_match[] = {
        {.compatible = "qcom,sm8250-sndcard"},
+       {.compatible = "qcom,qrb4210-rb2-sndcard"},
        {.compatible = "qcom,qrb5165-rb5-sndcard"},
        {}
 };
index 9784718a2b6f5668ef6c89d031fa33ba253a3151..eca5ce096e5457c2b5e33097e584d1f74326ba2d 100644 (file)
@@ -1281,7 +1281,9 @@ audio_graph:
                if (!of_node_name_eq(ports, "ports") &&
                    !of_node_name_eq(ports, "port"))
                        continue;
-               priv->component_dais[i] = of_graph_get_endpoint_count(ports);
+               priv->component_dais[i] =
+                       of_graph_get_endpoint_count(of_node_name_eq(ports, "ports") ?
+                                                   ports : np);
                nr += priv->component_dais[i];
                i++;
                if (i >= RSND_MAX_COMPONENT) {
@@ -1493,7 +1495,8 @@ static int rsnd_dai_probe(struct rsnd_priv *priv)
                        if (!of_node_name_eq(ports, "ports") &&
                            !of_node_name_eq(ports, "port"))
                                continue;
-                       for_each_endpoint_of_node(ports, dai_np) {
+                       for_each_endpoint_of_node(of_node_name_eq(ports, "ports") ?
+                                                 ports : np, dai_np) {
                                __rsnd_dai_probe(priv, dai_np, dai_np, 0, dai_i);
                                if (!rsnd_is_gen1(priv) && !rsnd_is_gen2(priv)) {
                                        rdai = rsnd_rdai_get(priv, dai_i);
index 9330f1a3f7589dc467c04238830f2009a619a998..99521c784a9b16a232a558029a2f3e88bd8ebfb1 100644 (file)
@@ -1147,6 +1147,8 @@ static int dapm_widget_list_create(struct snd_soc_dapm_widget_list **list,
        if (*list == NULL)
                return -ENOMEM;
 
+       (*list)->num_widgets = size;
+
        list_for_each_entry(w, widgets, work_list)
                (*list)->widgets[i++] = w;
 
@@ -2785,10 +2787,10 @@ EXPORT_SYMBOL_GPL(snd_soc_dapm_update_dai);
 
 int snd_soc_dapm_widget_name_cmp(struct snd_soc_dapm_widget *widget, const char *s)
 {
-       struct snd_soc_component *component = snd_soc_dapm_to_component(widget->dapm);
+       struct snd_soc_component *component = widget->dapm->component;
        const char *wname = widget->name;
 
-       if (component->name_prefix)
+       if (component && component->name_prefix)
                wname += strlen(component->name_prefix) + 1; /* plus space */
 
        return strcmp(wname, s);
index af3158cdc8d54a08029487842b13284bf3a98e92..97517423d1f0bbcc750bf07171a9796d32b9bacf 100644 (file)
@@ -889,7 +889,7 @@ static int soc_tplg_dbytes_create(struct soc_tplg *tplg, size_t size)
                return ret;
 
        /* register dynamic object */
-       sbe = (struct soc_bytes_ext *)&kc.private_value;
+       sbe = (struct soc_bytes_ext *)kc.private_value;
 
        INIT_LIST_HEAD(&sbe->dobj.list);
        sbe->dobj.type = SND_SOC_DOBJ_BYTES;
@@ -923,7 +923,7 @@ static int soc_tplg_dmixer_create(struct soc_tplg *tplg, size_t size)
                return ret;
 
        /* register dynamic object */
-       sm = (struct soc_mixer_control *)&kc.private_value;
+       sm = (struct soc_mixer_control *)kc.private_value;
 
        INIT_LIST_HEAD(&sm->dobj.list);
        sm->dobj.type = SND_SOC_DOBJ_MIXER;
index 19f10dd77e4ba3bf17f54dfb368c52865a36214c..077af9e2af8d09be9927627b78a86854b31245f3 100644 (file)
@@ -206,7 +206,10 @@ int acp_dsp_pre_fw_run(struct snd_sof_dev *sdev)
                configure_pte_for_fw_loading(FW_SRAM_DATA_BIN, ACP_SRAM_PAGE_COUNT, adata);
                src_addr = ACP_SYSTEM_MEMORY_WINDOW + ACP_DEFAULT_SRAM_LENGTH +
                           (page_count * ACP_PAGE_SIZE);
-               dest_addr = ACP_SRAM_BASE_ADDRESS;
+               if (adata->pci_rev > ACP63_PCI_ID)
+                       dest_addr = ACP7X_SRAM_BASE_ADDRESS;
+               else
+                       dest_addr = ACP_SRAM_BASE_ADDRESS;
 
                ret = configure_and_run_dma(adata, src_addr, dest_addr,
                                            adata->fw_sram_data_bin_size);
index d579c3849392c1cb4b61940aeb7df58ad2d83930..de3001f5b9bb7c664e2eee9e7f6164d46379a5d1 100644 (file)
@@ -329,7 +329,9 @@ int configure_and_run_sha_dma(struct acp_dev_data *adata, void *image_addr,
                                            fw_qualifier, fw_qualifier & DSP_FW_RUN_ENABLE,
                                            ACP_REG_POLL_INTERVAL, ACP_DMA_COMPLETE_TIMEOUT_US);
        if (ret < 0) {
-               dev_err(sdev->dev, "PSP validation failed\n");
+               val = snd_sof_dsp_read(sdev, ACP_DSP_BAR, ACP_SHA_PSP_ACK);
+               dev_err(sdev->dev, "PSP validation failed: fw_qualifier = %#x, ACP_SHA_PSP_ACK = %#x\n",
+                       fw_qualifier, val);
                return ret;
        }
 
index 484c761478853f8b2aad4e6926fd1f525ef5b66f..92681ca7f24def1307f9a3b7d6e1fc009e566953 100644 (file)
@@ -346,20 +346,21 @@ static int hda_trigger(struct snd_sof_dev *sdev, struct snd_soc_dai *cpu_dai,
        case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
                snd_hdac_ext_stream_start(hext_stream);
                break;
-       case SNDRV_PCM_TRIGGER_SUSPEND:
-       case SNDRV_PCM_TRIGGER_STOP:
        case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
-               snd_hdac_ext_stream_clear(hext_stream);
-
                /*
-                * Save the LLP registers in case the stream is
-                * restarting due PAUSE_RELEASE, or START without a pcm
-                * close/open since in this case the LLP register is not reset
-                * to 0 and the delay calculation will return with invalid
-                * results.
+                * Save the LLP registers since in case of PAUSE the LLP
+                * register are not reset to 0, the delay calculation will use
+                * the saved offsets for compensating the delay calculation.
                 */
                hext_stream->pplcllpl = readl(hext_stream->pplc_addr + AZX_REG_PPLCLLPL);
                hext_stream->pplcllpu = readl(hext_stream->pplc_addr + AZX_REG_PPLCLLPU);
+               snd_hdac_ext_stream_clear(hext_stream);
+               break;
+       case SNDRV_PCM_TRIGGER_SUSPEND:
+       case SNDRV_PCM_TRIGGER_STOP:
+               hext_stream->pplcllpl = 0;
+               hext_stream->pplcllpu = 0;
+               snd_hdac_ext_stream_clear(hext_stream);
                break;
        default:
                dev_err(sdev->dev, "unknown trigger command %d\n", cmd);
@@ -512,7 +513,6 @@ static const struct hda_dai_widget_dma_ops sdw_ipc4_chain_dma_ops = {
 static int hda_ipc3_post_trigger(struct snd_sof_dev *sdev, struct snd_soc_dai *cpu_dai,
                                 struct snd_pcm_substream *substream, int cmd)
 {
-       struct hdac_ext_stream *hext_stream = hda_get_hext_stream(sdev, cpu_dai, substream);
        struct snd_soc_dapm_widget *w = snd_soc_dai_get_widget(cpu_dai, substream->stream);
 
        switch (cmd) {
@@ -527,9 +527,6 @@ static int hda_ipc3_post_trigger(struct snd_sof_dev *sdev, struct snd_soc_dai *c
                if (ret < 0)
                        return ret;
 
-               if (cmd == SNDRV_PCM_TRIGGER_STOP)
-                       return hda_link_dma_cleanup(substream, hext_stream, cpu_dai);
-
                break;
        }
        case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
index 1c823f9eea570082b06827133d7290bb1e8963ab..ac505c7ad3429570530849ba1a30b8a010ed68ff 100644 (file)
@@ -302,6 +302,7 @@ static int __maybe_unused hda_dai_trigger(struct snd_pcm_substream *substream, i
        }
 
        switch (cmd) {
+       case SNDRV_PCM_TRIGGER_STOP:
        case SNDRV_PCM_TRIGGER_SUSPEND:
                ret = hda_link_dma_cleanup(substream, hext_stream, dai);
                if (ret < 0) {
@@ -370,6 +371,13 @@ static int non_hda_dai_hw_params_data(struct snd_pcm_substream *substream,
                return -EINVAL;
        }
 
+       sdev = widget_to_sdev(w);
+       hext_stream = ops->get_hext_stream(sdev, cpu_dai, substream);
+
+       /* nothing more to do if the link is already prepared */
+       if (hext_stream && hext_stream->link_prepared)
+               return 0;
+
        /* use HDaudio stream handling */
        ret = hda_dai_hw_params_data(substream, params, cpu_dai, data, flags);
        if (ret < 0) {
@@ -377,7 +385,6 @@ static int non_hda_dai_hw_params_data(struct snd_pcm_substream *substream,
                return ret;
        }
 
-       sdev = widget_to_sdev(w);
        if (sdev->dspless_mode_selected)
                return 0;
 
@@ -482,6 +489,31 @@ int sdw_hda_dai_hw_params(struct snd_pcm_substream *substream,
        int ret;
        int i;
 
+       ops = hda_dai_get_ops(substream, cpu_dai);
+       if (!ops) {
+               dev_err(cpu_dai->dev, "DAI widget ops not set\n");
+               return -EINVAL;
+       }
+
+       sdev = widget_to_sdev(w);
+       hext_stream = ops->get_hext_stream(sdev, cpu_dai, substream);
+
+       /* nothing more to do if the link is already prepared */
+       if (hext_stream && hext_stream->link_prepared)
+               return 0;
+
+       /*
+        * reset the PCMSyCM registers to handle a prepare callback when the PCM is restarted
+        * due to xruns or after a call to snd_pcm_drain/drop()
+        */
+       ret = hdac_bus_eml_sdw_map_stream_ch(sof_to_bus(sdev), link_id, cpu_dai->id,
+                                            0, 0, substream->stream);
+       if (ret < 0) {
+               dev_err(cpu_dai->dev, "%s:  hdac_bus_eml_sdw_map_stream_ch failed %d\n",
+                       __func__, ret);
+               return ret;
+       }
+
        data.dai_index = (link_id << 8) | cpu_dai->id;
        data.dai_node_id = intel_alh_id;
        ret = non_hda_dai_hw_params_data(substream, params, cpu_dai, &data, flags);
@@ -490,10 +522,7 @@ int sdw_hda_dai_hw_params(struct snd_pcm_substream *substream,
                return ret;
        }
 
-       ops = hda_dai_get_ops(substream, cpu_dai);
-       sdev = widget_to_sdev(w);
        hext_stream = ops->get_hext_stream(sdev, cpu_dai, substream);
-
        if (!hext_stream)
                return -ENODEV;
 
index 75f6240cf3e1d3c4ded00423e7d3c3f5775c0092..9d8ebb7c6a106033df8cffa4d8a9db485c64552d 100644 (file)
@@ -294,14 +294,9 @@ int hda_cl_copy_fw(struct snd_sof_dev *sdev, struct hdac_ext_stream *hext_stream
 {
        struct sof_intel_hda_dev *hda = sdev->pdata->hw_pdata;
        const struct sof_intel_dsp_desc *chip = hda->desc;
-       struct sof_intel_hda_stream *hda_stream;
-       unsigned long time_left;
        unsigned int reg;
        int ret, status;
 
-       hda_stream = container_of(hext_stream, struct sof_intel_hda_stream,
-                                 hext_stream);
-
        dev_dbg(sdev->dev, "Code loader DMA starting\n");
 
        ret = hda_cl_trigger(sdev->dev, hext_stream, SNDRV_PCM_TRIGGER_START);
@@ -310,18 +305,6 @@ int hda_cl_copy_fw(struct snd_sof_dev *sdev, struct hdac_ext_stream *hext_stream
                return ret;
        }
 
-       if (sdev->pdata->ipc_type == SOF_IPC_TYPE_4) {
-               /* Wait for completion of transfer */
-               time_left = wait_for_completion_timeout(&hda_stream->ioc,
-                                                       msecs_to_jiffies(HDA_CL_DMA_IOC_TIMEOUT_MS));
-
-               if (!time_left) {
-                       dev_err(sdev->dev, "Code loader DMA did not complete\n");
-                       return -ETIMEDOUT;
-               }
-               dev_dbg(sdev->dev, "Code loader DMA done\n");
-       }
-
        dev_dbg(sdev->dev, "waiting for FW_ENTERED status\n");
 
        status = snd_sof_dsp_read_poll_timeout(sdev, HDA_DSP_BAR,
index cd9cb54e7b23fba58e31834e80af242e02d0b8d2..f6cb790826725cbb30b68411beaf3661e6511615 100644 (file)
@@ -10,7 +10,7 @@
 
 #include <linux/io-64-nonatomic-lo-hi.h>
 #include <linux/platform_device.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include <sound/soc.h>
 #include <sound/sof.h>
 #include "sof-priv.h"
index 87be7f16e8c2b65e421739dc48b2f19db9d00548..240fee2166d125d8711fc9df4316c72bff52587a 100644 (file)
@@ -3129,9 +3129,20 @@ static int sof_ipc4_dai_config(struct snd_sof_dev *sdev, struct snd_sof_widget *
                 * group_id during copier's ipc_prepare op.
                 */
                if (flags & SOF_DAI_CONFIG_FLAGS_HW_PARAMS) {
+                       struct sof_ipc4_alh_configuration_blob *blob;
+
+                       blob = (struct sof_ipc4_alh_configuration_blob *)ipc4_copier->copier_config;
                        ipc4_copier->dai_index = data->dai_node_id;
-                       copier_data->gtw_cfg.node_id &= ~SOF_IPC4_NODE_INDEX_MASK;
-                       copier_data->gtw_cfg.node_id |= SOF_IPC4_NODE_INDEX(data->dai_node_id);
+
+                       /*
+                        * no need to set the node_id for aggregated DAI's. These will be assigned
+                        * a group_id during widget ipc_prepare
+                        */
+                       if (blob->alh_cfg.device_count == 1) {
+                               copier_data->gtw_cfg.node_id &= ~SOF_IPC4_NODE_INDEX_MASK;
+                               copier_data->gtw_cfg.node_id |=
+                                       SOF_IPC4_NODE_INDEX(data->dai_node_id);
+                       }
                }
 
                break;
index 44608682e9f8f678dd7b827145cc97507b4dc217..f70089317b8c521efbe50d9346ea3b82da00b2c1 100644 (file)
@@ -8,7 +8,7 @@
 // Author: Keyon Jie <[email protected]>
 //
 
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include <linux/io-64-nonatomic-lo-hi.h>
 #include <linux/device.h>
 #include <sound/memalloc.h>
index 970c9bdce0b21648a3ba57fe1444748d9bfcafa4..84a9b7b76f43ca1433dc1f746121183992702192 100644 (file)
@@ -2,7 +2,7 @@
 /*
  * Line 6 Linux USB driver
  *
- * Copyright (C) 2004-2010 Markus Grabner ([email protected]graz.at)
+ * Copyright (C) 2004-2010 Markus Grabner (line6@grabner-graz.at)
  */
 
 #include <linux/slab.h>
index 20e05a5eceb4f1d14704ea2d7c8559a0a5ea5bad..90572dae134eee3f026616d98bd95dc928b30aba 100644 (file)
@@ -2,7 +2,7 @@
 /*
  * Line 6 Linux USB driver
  *
- * Copyright (C) 2004-2010 Markus Grabner ([email protected]graz.at)
+ * Copyright (C) 2004-2010 Markus Grabner (line6@grabner-graz.at)
  */
 
 #ifndef CAPTURE_H
index 9df49a880b750d639c5d23abef2cbf0a07e1f9c8..e9eb5c74d6c7ab71fbc930f57c0daeebd5d88de3 100644 (file)
@@ -2,7 +2,7 @@
 /*
  * Line 6 Linux USB driver
  *
- * Copyright (C) 2004-2010 Markus Grabner ([email protected]graz.at)
+ * Copyright (C) 2004-2010 Markus Grabner (line6@grabner-graz.at)
  */
 
 #include <linux/kernel.h>
@@ -20,7 +20,7 @@
 #include "midi.h"
 #include "playback.h"
 
-#define DRIVER_AUTHOR  "Markus Grabner <[email protected]graz.at>"
+#define DRIVER_AUTHOR  "Markus Grabner <line6@grabner-graz.at>"
 #define DRIVER_DESC    "Line 6 USB Driver"
 
 /*
index dbb1d90d36475e27fcdf10379becf33c19bc7058..5736ad4256a5eed3cf68f9d9efa8183f60aa30f4 100644 (file)
@@ -2,7 +2,7 @@
 /*
  * Line 6 Linux USB driver
  *
- * Copyright (C) 2004-2010 Markus Grabner ([email protected]graz.at)
+ * Copyright (C) 2004-2010 Markus Grabner (line6@grabner-graz.at)
  */
 
 #ifndef DRIVER_H
index 0838632c788e4a120c50a20db56ff75d69e1ed77..9b51760862809e50a61ac90a199487fe474c00c8 100644 (file)
@@ -2,7 +2,7 @@
 /*
  * Line 6 Linux USB driver
  *
- * Copyright (C) 2004-2010 Markus Grabner ([email protected]graz.at)
+ * Copyright (C) 2004-2010 Markus Grabner (line6@grabner-graz.at)
  */
 
 #include <linux/slab.h>
index 918754e79be44a0cefc6d304dfff528e52458b13..3409c742c173bb70f22274623687a499574352a7 100644 (file)
@@ -2,7 +2,7 @@
 /*
  * Line 6 Linux USB driver
  *
- * Copyright (C) 2004-2010 Markus Grabner ([email protected]graz.at)
+ * Copyright (C) 2004-2010 Markus Grabner (line6@grabner-graz.at)
  */
 
 #ifndef MIDI_H
index e7f830f7526c96ad809e5e3f4cf43ba5da94b677..57fca134b3378d0ad41898aeae4dce25025ad7de 100644 (file)
@@ -2,7 +2,7 @@
 /*
  * Line 6 Linux USB driver
  *
- * Copyright (C) 2004-2010 Markus Grabner ([email protected]graz.at)
+ * Copyright (C) 2004-2010 Markus Grabner (line6@grabner-graz.at)
  */
 
 #include <linux/slab.h>
index 542e8d836f87df27637c61cb7400b91593e05b3f..1dae5fac9dde6b1e1b02a514530a59722fc5b63d 100644 (file)
@@ -2,7 +2,7 @@
 /*
  * Line 6 Linux USB driver
  *
- * Copyright (C) 2004-2010 Markus Grabner ([email protected]graz.at)
+ * Copyright (C) 2004-2010 Markus Grabner (line6@grabner-graz.at)
  */
 
 #ifndef MIDIBUF_H
index 6a4af725aedd2c33b0a44ade0a6df8b086e44678..d4dbbc432505dbfa01df23e43b2ae2b2d55d5588 100644 (file)
@@ -2,7 +2,7 @@
 /*
  * Line 6 Linux USB driver
  *
- * Copyright (C) 2004-2010 Markus Grabner ([email protected]graz.at)
+ * Copyright (C) 2004-2010 Markus Grabner (line6@grabner-graz.at)
  */
 
 #include <linux/slab.h>
index 9c683042ff064acd39e6e1ff76ac2bb4bc1a150a..a15913bf2a7aad941b4836d77425581ec27f1734 100644 (file)
@@ -2,7 +2,7 @@
 /*
  * Line 6 Linux USB driver
  *
- * Copyright (C) 2004-2010 Markus Grabner ([email protected]graz.at)
+ * Copyright (C) 2004-2010 Markus Grabner (line6@grabner-graz.at)
  */
 
 /*
index 8233c61e23f168e3d742700351ffa1475293b6f7..9f26f66e6792566971f8f12973da7a8fb912287f 100644 (file)
@@ -2,7 +2,7 @@
 /*
  * Line 6 Linux USB driver
  *
- * Copyright (C) 2004-2010 Markus Grabner ([email protected]graz.at)
+ * Copyright (C) 2004-2010 Markus Grabner (line6@grabner-graz.at)
  */
 
 #include <linux/slab.h>
index 2ca832c83851fee7532ff7416c8602a013946ecf..2e0ec0ade0bf638df98e73e1d842e6a7f7530b5e 100644 (file)
@@ -2,7 +2,7 @@
 /*
  * Line 6 Linux USB driver
  *
- * Copyright (C) 2004-2010 Markus Grabner ([email protected]graz.at)
+ * Copyright (C) 2004-2010 Markus Grabner (line6@grabner-graz.at)
  */
 
 #ifndef PLAYBACK_H
index d173971e5f0297ed740833bcf216041a4fb94ff9..6f948c3e8f9e1d23a9d0c521f85fc75ede20609c 100644 (file)
@@ -2,7 +2,7 @@
 /*
  * Line 6 Linux USB driver
  *
- * Copyright (C) 2004-2010 Markus Grabner ([email protected]graz.at)
+ * Copyright (C) 2004-2010 Markus Grabner (line6@grabner-graz.at)
  */
 
 #include <linux/slab.h>
index ffd8c157a28139ed376b9b22626678f37ea4660e..70de08635f54cb43bd39363850126cb0a058f054 100644 (file)
@@ -507,7 +507,7 @@ static const struct line6_properties podhd_properties_table[] = {
        [LINE6_PODHD500X] = {
                .id = "PODHD500X",
                .name = "POD HD500X",
-               .capabilities   = LINE6_CAP_CONTROL
+               .capabilities   = LINE6_CAP_CONTROL | LINE6_CAP_HWMON_CTL
                                | LINE6_CAP_PCM | LINE6_CAP_HWMON,
                .altsetting = 1,
                .ep_ctrl_r = 0x81,
index e33df58740a91c834c8a25d3835fefa9837475cc..ca2c6f5de407ece21ab69a39ed603e3f10069039 100644 (file)
@@ -2,7 +2,7 @@
 /*
  * Line 6 Linux USB driver
  *
- * Copyright (C) 2004-2010 Markus Grabner ([email protected]graz.at)
+ * Copyright (C) 2004-2010 Markus Grabner (line6@grabner-graz.at)
  *                         Emil Myhrman ([email protected])
  */
 
index c2245aa93b08ff3a50cfe23691c88ce2fe40f83b..b2f6637c84b292b7ca8adf6468840f8744687948 100644 (file)
@@ -2,7 +2,7 @@
 /*
  * Line 6 Linux USB driver
  *
- * Copyright (C) 2004-2010 Markus Grabner ([email protected]graz.at)
+ * Copyright (C) 2004-2010 Markus Grabner (line6@grabner-graz.at)
  */
 
 #include <linux/slab.h>
index 2a9594f34dac6f753d715ed973f4a576eafa23dd..6456e87e2f397478aa1d767bc27f15d7b09acb86 100644 (file)
@@ -4042,6 +4042,9 @@ int snd_usb_mixer_apply_create_quirk(struct usb_mixer_interface *mixer)
                        break;
                err = dell_dock_mixer_init(mixer);
                break;
+       case USB_ID(0x0bda, 0x402e): /* Dell WD19 dock */
+               err = dell_dock_mixer_create(mixer);
+               break;
 
        case USB_ID(0x2a39, 0x3fd2): /* RME ADI-2 Pro */
        case USB_ID(0x2a39, 0x3fd3): /* RME ADI-2 DAC */
index 1150cf104985ceaa51372bc1d606d0d7c6bda51c..4cddf84db631c61afeb02a6ecd1adfa539918245 100644 (file)
@@ -5613,6 +5613,8 @@ static int scarlett2_update_filter_values(struct usb_mixer_interface *mixer)
                        info->peq_flt_total_count *
                        SCARLETT2_BIQUAD_COEFFS,
                peq_flt_values);
+       if (err < 0)
+               return err;
 
        for (i = 0, dst_idx = 0; i < info->dsp_input_count; i++) {
                src_idx = i *
index f62631b54e104e55800b10e1e96f4ec9b7c7beb1..e6278a24579559ac667e8d6554ecafd122746acc 100644 (file)
@@ -2221,6 +2221,8 @@ static const struct usb_audio_quirk_flags_table quirk_flags_table[] = {
                   QUIRK_FLAG_DISABLE_AUTOSUSPEND),
        DEVICE_FLG(0x17aa, 0x104d, /* Lenovo ThinkStation P620 Internal Speaker + Front Headset */
                   QUIRK_FLAG_DISABLE_AUTOSUSPEND),
+       DEVICE_FLG(0x1852, 0x5062, /* Luxman D-08u */
+                  QUIRK_FLAG_ITF_USB_DSD_DAC | QUIRK_FLAG_CTL_MSG_DELAY),
        DEVICE_FLG(0x1852, 0x5065, /* Luxman DA-06 */
                   QUIRK_FLAG_ITF_USB_DSD_DAC | QUIRK_FLAG_CTL_MSG_DELAY),
        DEVICE_FLG(0x1901, 0x0191, /* GE B850V3 CP2114 audio interface */
@@ -2279,6 +2281,8 @@ static const struct usb_audio_quirk_flags_table quirk_flags_table[] = {
                   QUIRK_FLAG_GENERIC_IMPLICIT_FB),
        DEVICE_FLG(0x2b53, 0x0031, /* Fiero SC-01 (firmware v1.1.0) */
                   QUIRK_FLAG_GENERIC_IMPLICIT_FB),
+       DEVICE_FLG(0x2d95, 0x8011, /* VIVO USB-C HEADSET */
+                  QUIRK_FLAG_CTL_MSG_DELAY_1M),
        DEVICE_FLG(0x2d95, 0x8021, /* VIVO USB-C-XE710 HEADSET */
                   QUIRK_FLAG_CTL_MSG_DELAY_1M),
        DEVICE_FLG(0x30be, 0x0101, /* Schiit Hel */
index d70c140813d6880e1423793a3a9bc44f9ad531bb..c1ea8844a46fc420ee703b8640580cef851ef4b7 100644 (file)
@@ -1067,6 +1067,7 @@ found_clock:
                                        UAC3_BADD_PD_ID10 : UAC3_BADD_PD_ID11;
                pd->pd_d1d0_rec = UAC3_BADD_PD_RECOVER_D1D0;
                pd->pd_d2d0_rec = UAC3_BADD_PD_RECOVER_D2D0;
+               pd->ctrl_iface = ctrl_intf;
 
        } else {
                fp->attributes = parse_uac_endpoint_attributes(chip, alts,
index 5fd7caea441936246ce9ddb7b5d7bdf04b30d14b..488f8e75134959f5263a61230dbde5192e8d4a58 100644 (file)
@@ -94,6 +94,7 @@
 #define ARM_CPU_PART_NEOVERSE_V3       0xD84
 #define ARM_CPU_PART_CORTEX_X925       0xD85
 #define ARM_CPU_PART_CORTEX_A725       0xD87
+#define ARM_CPU_PART_NEOVERSE_N3       0xD8E
 
 #define APM_CPU_PART_XGENE             0x000
 #define APM_CPU_VAR_POTENZA            0x00
 #define APPLE_CPU_PART_M2_AVALANCHE_MAX        0x039
 
 #define AMPERE_CPU_PART_AMPERE1                0xAC3
+#define AMPERE_CPU_PART_AMPERE1A       0xAC4
 
 #define MICROSOFT_CPU_PART_AZURE_COBALT_100    0xD49 /* Based on r0p0 of ARM Neoverse N2 */
 
 #define MIDR_NEOVERSE_V3 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_NEOVERSE_V3)
 #define MIDR_CORTEX_X925 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_X925)
 #define MIDR_CORTEX_A725 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A725)
+#define MIDR_NEOVERSE_N3 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_NEOVERSE_N3)
 #define MIDR_THUNDERX  MIDR_CPU_MODEL(ARM_CPU_IMP_CAVIUM, CAVIUM_CPU_PART_THUNDERX)
 #define MIDR_THUNDERX_81XX MIDR_CPU_MODEL(ARM_CPU_IMP_CAVIUM, CAVIUM_CPU_PART_THUNDERX_81XX)
 #define MIDR_THUNDERX_83XX MIDR_CPU_MODEL(ARM_CPU_IMP_CAVIUM, CAVIUM_CPU_PART_THUNDERX_83XX)
 #define MIDR_APPLE_M2_BLIZZARD_MAX MIDR_CPU_MODEL(ARM_CPU_IMP_APPLE, APPLE_CPU_PART_M2_BLIZZARD_MAX)
 #define MIDR_APPLE_M2_AVALANCHE_MAX MIDR_CPU_MODEL(ARM_CPU_IMP_APPLE, APPLE_CPU_PART_M2_AVALANCHE_MAX)
 #define MIDR_AMPERE1 MIDR_CPU_MODEL(ARM_CPU_IMP_AMPERE, AMPERE_CPU_PART_AMPERE1)
+#define MIDR_AMPERE1A MIDR_CPU_MODEL(ARM_CPU_IMP_AMPERE, AMPERE_CPU_PART_AMPERE1A)
 #define MIDR_MICROSOFT_AZURE_COBALT_100 MIDR_CPU_MODEL(ARM_CPU_IMP_MICROSOFT, MICROSOFT_CPU_PART_AZURE_COBALT_100)
 
 /* Fujitsu Erratum 010001 affects A64FX 1.0 and 1.1, (v0r0 and v1r0) */
diff --git a/tools/arch/arm64/vdso b/tools/arch/arm64/vdso
deleted file mode 120000 (symlink)
index 233c7a2..0000000
+++ /dev/null
@@ -1 +0,0 @@
-../../../arch/arm64/kernel/vdso
\ No newline at end of file
diff --git a/tools/arch/loongarch/vdso b/tools/arch/loongarch/vdso
deleted file mode 120000 (symlink)
index ebda43a..0000000
+++ /dev/null
@@ -1 +0,0 @@
-../../../arch/loongarch/vdso
\ No newline at end of file
diff --git a/tools/arch/powerpc/vdso b/tools/arch/powerpc/vdso
deleted file mode 120000 (symlink)
index 4e676d1..0000000
+++ /dev/null
@@ -1 +0,0 @@
-../../../arch/powerpc/kernel/vdso
\ No newline at end of file
diff --git a/tools/arch/s390/vdso b/tools/arch/s390/vdso
deleted file mode 120000 (symlink)
index 6cf4c1c..0000000
+++ /dev/null
@@ -1 +0,0 @@
-../../../arch/s390/kernel/vdso64
\ No newline at end of file
index 82c6a4d350e09e6d8f98f11189cc5cb8f5e58a7c..3ae84c3b8e6dba73f0f44d3e25a1948a68daea91 100644 (file)
 #define EFER_FFXSR             (1<<_EFER_FFXSR)
 #define EFER_AUTOIBRS          (1<<_EFER_AUTOIBRS)
 
+/*
+ * Architectural memory types that are common to MTRRs, PAT, VMX MSRs, etc.
+ * Most MSRs support/allow only a subset of memory types, but the values
+ * themselves are common across all relevant MSRs.
+ */
+#define X86_MEMTYPE_UC         0ull    /* Uncacheable, a.k.a. Strong Uncacheable */
+#define X86_MEMTYPE_WC         1ull    /* Write Combining */
+/* RESERVED                    2 */
+/* RESERVED                    3 */
+#define X86_MEMTYPE_WT         4ull    /* Write Through */
+#define X86_MEMTYPE_WP         5ull    /* Write Protected */
+#define X86_MEMTYPE_WB         6ull    /* Write Back */
+#define X86_MEMTYPE_UC_MINUS   7ull    /* Weak Uncacheabled (PAT only) */
+
 /* FRED MSRs */
 #define MSR_IA32_FRED_RSP0     0x1cc                   /* Level 0 stack pointer */
 #define MSR_IA32_FRED_RSP1     0x1cd                   /* Level 1 stack pointer */
 #define MSR_INTEGRITY_CAPS_ARRAY_BIST          BIT(MSR_INTEGRITY_CAPS_ARRAY_BIST_BIT)
 #define MSR_INTEGRITY_CAPS_PERIODIC_BIST_BIT   4
 #define MSR_INTEGRITY_CAPS_PERIODIC_BIST       BIT(MSR_INTEGRITY_CAPS_PERIODIC_BIST_BIT)
+#define MSR_INTEGRITY_CAPS_SBAF_BIT            8
+#define MSR_INTEGRITY_CAPS_SBAF                        BIT(MSR_INTEGRITY_CAPS_SBAF_BIT)
 #define MSR_INTEGRITY_CAPS_SAF_GEN_MASK        GENMASK_ULL(10, 9)
 
 #define MSR_LBR_NHM_FROM               0x00000680
 
 #define MSR_IA32_CR_PAT                        0x00000277
 
+#define PAT_VALUE(p0, p1, p2, p3, p4, p5, p6, p7)                      \
+       ((X86_MEMTYPE_ ## p0)      | (X86_MEMTYPE_ ## p1 << 8)  |       \
+       (X86_MEMTYPE_ ## p2 << 16) | (X86_MEMTYPE_ ## p3 << 24) |       \
+       (X86_MEMTYPE_ ## p4 << 32) | (X86_MEMTYPE_ ## p5 << 40) |       \
+       (X86_MEMTYPE_ ## p6 << 48) | (X86_MEMTYPE_ ## p7 << 56))
+
 #define MSR_IA32_DEBUGCTLMSR           0x000001d9
 #define MSR_IA32_LASTBRANCHFROMIP      0x000001db
 #define MSR_IA32_LASTBRANCHTOIP                0x000001dc
 #define MSR_IA32_VMX_VMFUNC             0x00000491
 #define MSR_IA32_VMX_PROCBASED_CTLS3   0x00000492
 
-/* VMX_BASIC bits and bitmasks */
-#define VMX_BASIC_VMCS_SIZE_SHIFT      32
-#define VMX_BASIC_TRUE_CTLS            (1ULL << 55)
-#define VMX_BASIC_64           0x0001000000000000LLU
-#define VMX_BASIC_MEM_TYPE_SHIFT       50
-#define VMX_BASIC_MEM_TYPE_MASK        0x003c000000000000LLU
-#define VMX_BASIC_MEM_TYPE_WB  6LLU
-#define VMX_BASIC_INOUT                0x0040000000000000LLU
-
 /* Resctrl MSRs: */
 /* - Intel: */
 #define MSR_IA32_L3_QOS_CFG            0xc81
 #define MSR_IA32_SMBA_BW_BASE          0xc0000280
 #define MSR_IA32_EVT_CFG_BASE          0xc0000400
 
-/* MSR_IA32_VMX_MISC bits */
-#define MSR_IA32_VMX_MISC_INTEL_PT                 (1ULL << 14)
-#define MSR_IA32_VMX_MISC_VMWRITE_SHADOW_RO_FIELDS (1ULL << 29)
-#define MSR_IA32_VMX_MISC_PREEMPTION_TIMER_SCALE   0x1F
-
 /* AMD-V MSRs */
 #define MSR_VM_CR                       0xc0010114
 #define MSR_VM_IGNNE                    0xc0010115
index bf57a824f72281218a7c145e44587f3845a50aad..a8debbf2f70280595573a479d81f17bc1176b22e 100644 (file)
@@ -439,6 +439,7 @@ struct kvm_sync_regs {
 #define KVM_X86_QUIRK_MISC_ENABLE_NO_MWAIT     (1 << 4)
 #define KVM_X86_QUIRK_FIX_HYPERCALL_INSN       (1 << 5)
 #define KVM_X86_QUIRK_MWAIT_NEVER_UD_FAULTS    (1 << 6)
+#define KVM_X86_QUIRK_SLOT_ZAP_ALL             (1 << 7)
 
 #define KVM_STATE_NESTED_FORMAT_VMX    0
 #define KVM_STATE_NESTED_FORMAT_SVM    1
index 9de35df1afc31f7e66fd014c9fce250900dd1ca5..63182a023e9df79e200a480d1994fb7d8e26297e 100644 (file)
@@ -11,6 +11,9 @@
 #ifndef __NR_getpgid
 #define __NR_getpgid 132
 #endif
+#ifndef __NR_capget
+#define __NR_capget 184
+#endif
 #ifndef __NR_gettid
 #define __NR_gettid 224
 #endif
index d0f2043d713205c6d70c5393c444deb2fb035fb4..77311e8d1b5d38cde163fe47dbddfd5d13629310 100644 (file)
@@ -11,6 +11,9 @@
 #ifndef __NR_getpgid
 #define __NR_getpgid 121
 #endif
+#ifndef __NR_capget
+#define __NR_capget 125
+#endif
 #ifndef __NR_gettid
 #define __NR_gettid 186
 #endif
index a43b37346a22d435ee722131b182efeefea8b267..ab5cdc3337dacbd231d124b6969740a8cec52a0d 100644 (file)
@@ -13,7 +13,7 @@
 #endif
 #include "../include/asm/inat.h" /* __ignore_sync_check__ */
 #include "../include/asm/insn.h" /* __ignore_sync_check__ */
-#include "../include/asm-generic/unaligned.h" /* __ignore_sync_check__ */
+#include "../include/linux/unaligned.h" /* __ignore_sync_check__ */
 
 #include <linux/errno.h>
 #include <linux/kconfig.h>
diff --git a/tools/arch/x86/vdso b/tools/arch/x86/vdso
deleted file mode 120000 (symlink)
index 7eb962f..0000000
+++ /dev/null
@@ -1 +0,0 @@
-../../../arch/x86/entry/vdso/
\ No newline at end of file
index 5938cf799dc6770a3d83a750e05018457eecfc62..1658596188bf85d8768eb2e4c48dc747fd0cad96 100644 (file)
@@ -172,7 +172,7 @@ DWARFLIBS := -ldw
 ifeq ($(findstring -static,${LDFLAGS}),-static)
   DWARFLIBS += -lelf -lz -llzma -lbz2 -lzstd
 
-  LIBDW_VERSION := $(shell $(PKG_CONFIG) --modversion libdw)
+  LIBDW_VERSION := $(shell $(PKG_CONFIG) --modversion libdw).0.0
   LIBDW_VERSION_1 := $(word 1, $(subst ., ,$(LIBDW_VERSION)))
   LIBDW_VERSION_2 := $(word 2, $(subst ., ,$(LIBDW_VERSION)))
 
@@ -181,6 +181,9 @@ ifeq ($(findstring -static,${LDFLAGS}),-static)
   ifeq ($(shell test $(LIBDW_VERSION_2) -lt 177; echo $$?),0)
     DWARFLIBS += -lebl
   endif
+
+  # Must put -ldl after -lebl for dependency
+  DWARFLIBS += -ldl
 endif
 
 $(OUTPUT)test-dwarf.bin:
diff --git a/tools/include/asm-generic/unaligned.h b/tools/include/asm-generic/unaligned.h
deleted file mode 100644 (file)
index cdd2fd0..0000000
+++ /dev/null
@@ -1,157 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-#ifndef __ASM_GENERIC_UNALIGNED_H
-#define __ASM_GENERIC_UNALIGNED_H
-
-/*
- * This is the most generic implementation of unaligned accesses
- * and should work almost anywhere.
- */
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wpacked"
-#pragma GCC diagnostic ignored "-Wattributes"
-
-#define __get_unaligned_t(type, ptr) ({                                                \
-       const struct { type x; } __packed *__pptr = (typeof(__pptr))(ptr);      \
-       __pptr->x;                                                              \
-})
-
-#define __put_unaligned_t(type, val, ptr) do {                                 \
-       struct { type x; } __packed *__pptr = (typeof(__pptr))(ptr);            \
-       __pptr->x = (val);                                                      \
-} while (0)
-
-#define get_unaligned(ptr)     __get_unaligned_t(typeof(*(ptr)), (ptr))
-#define put_unaligned(val, ptr) __put_unaligned_t(typeof(*(ptr)), (val), (ptr))
-
-static inline u16 get_unaligned_le16(const void *p)
-{
-       return le16_to_cpu(__get_unaligned_t(__le16, p));
-}
-
-static inline u32 get_unaligned_le32(const void *p)
-{
-       return le32_to_cpu(__get_unaligned_t(__le32, p));
-}
-
-static inline u64 get_unaligned_le64(const void *p)
-{
-       return le64_to_cpu(__get_unaligned_t(__le64, p));
-}
-
-static inline void put_unaligned_le16(u16 val, void *p)
-{
-       __put_unaligned_t(__le16, cpu_to_le16(val), p);
-}
-
-static inline void put_unaligned_le32(u32 val, void *p)
-{
-       __put_unaligned_t(__le32, cpu_to_le32(val), p);
-}
-
-static inline void put_unaligned_le64(u64 val, void *p)
-{
-       __put_unaligned_t(__le64, cpu_to_le64(val), p);
-}
-
-static inline u16 get_unaligned_be16(const void *p)
-{
-       return be16_to_cpu(__get_unaligned_t(__be16, p));
-}
-
-static inline u32 get_unaligned_be32(const void *p)
-{
-       return be32_to_cpu(__get_unaligned_t(__be32, p));
-}
-
-static inline u64 get_unaligned_be64(const void *p)
-{
-       return be64_to_cpu(__get_unaligned_t(__be64, p));
-}
-
-static inline void put_unaligned_be16(u16 val, void *p)
-{
-       __put_unaligned_t(__be16, cpu_to_be16(val), p);
-}
-
-static inline void put_unaligned_be32(u32 val, void *p)
-{
-       __put_unaligned_t(__be32, cpu_to_be32(val), p);
-}
-
-static inline void put_unaligned_be64(u64 val, void *p)
-{
-       __put_unaligned_t(__be64, cpu_to_be64(val), p);
-}
-
-static inline u32 __get_unaligned_be24(const u8 *p)
-{
-       return p[0] << 16 | p[1] << 8 | p[2];
-}
-
-static inline u32 get_unaligned_be24(const void *p)
-{
-       return __get_unaligned_be24(p);
-}
-
-static inline u32 __get_unaligned_le24(const u8 *p)
-{
-       return p[0] | p[1] << 8 | p[2] << 16;
-}
-
-static inline u32 get_unaligned_le24(const void *p)
-{
-       return __get_unaligned_le24(p);
-}
-
-static inline void __put_unaligned_be24(const u32 val, u8 *p)
-{
-       *p++ = (val >> 16) & 0xff;
-       *p++ = (val >> 8) & 0xff;
-       *p++ = val & 0xff;
-}
-
-static inline void put_unaligned_be24(const u32 val, void *p)
-{
-       __put_unaligned_be24(val, p);
-}
-
-static inline void __put_unaligned_le24(const u32 val, u8 *p)
-{
-       *p++ = val & 0xff;
-       *p++ = (val >> 8) & 0xff;
-       *p++ = (val >> 16) & 0xff;
-}
-
-static inline void put_unaligned_le24(const u32 val, void *p)
-{
-       __put_unaligned_le24(val, p);
-}
-
-static inline void __put_unaligned_be48(const u64 val, u8 *p)
-{
-       *p++ = (val >> 40) & 0xff;
-       *p++ = (val >> 32) & 0xff;
-       *p++ = (val >> 24) & 0xff;
-       *p++ = (val >> 16) & 0xff;
-       *p++ = (val >> 8) & 0xff;
-       *p++ = val & 0xff;
-}
-
-static inline void put_unaligned_be48(const u64 val, void *p)
-{
-       __put_unaligned_be48(val, p);
-}
-
-static inline u64 __get_unaligned_be48(const u8 *p)
-{
-       return (u64)p[0] << 40 | (u64)p[1] << 32 | (u64)p[2] << 24 |
-               p[3] << 16 | p[4] << 8 | p[5];
-}
-
-static inline u64 get_unaligned_be48(const void *p)
-{
-       return __get_unaligned_be48(p);
-}
-#pragma GCC diagnostic pop
-
-#endif /* __ASM_GENERIC_UNALIGNED_H */
index 0eb24d21aac2142cc94b4489ccd786df58a06400..60044b6088172b3f26aa3f17cdaede9786863dae 100644 (file)
 #define GENMASK_ULL(h, l) \
        (GENMASK_INPUT_CHECK(h, l) + __GENMASK_ULL(h, l))
 
+#if !defined(__ASSEMBLY__)
+/*
+ * Missing asm support
+ *
+ * __GENMASK_U128() depends on _BIT128() which would not work
+ * in the asm code, as it shifts an 'unsigned __init128' data
+ * type instead of direct representation of 128 bit constants
+ * such as long and unsigned long. The fundamental problem is
+ * that a 128 bit constant will get silently truncated by the
+ * gcc compiler.
+ */
+#define GENMASK_U128(h, l) \
+       (GENMASK_INPUT_CHECK(h, l) + __GENMASK_U128(h, l))
+#endif
+
 #endif /* __LINUX_BITS_H */
diff --git a/tools/include/linux/unaligned.h b/tools/include/linux/unaligned.h
new file mode 100644 (file)
index 0000000..395a446
--- /dev/null
@@ -0,0 +1,148 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef __LINUX_UNALIGNED_H
+#define __LINUX_UNALIGNED_H
+
+/*
+ * This is the most generic implementation of unaligned accesses
+ * and should work almost anywhere.
+ */
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wpacked"
+#pragma GCC diagnostic ignored "-Wattributes"
+#include <vdso/unaligned.h>
+
+#define get_unaligned(ptr)     __get_unaligned_t(typeof(*(ptr)), (ptr))
+#define put_unaligned(val, ptr) __put_unaligned_t(typeof(*(ptr)), (val), (ptr))
+
+static inline u16 get_unaligned_le16(const void *p)
+{
+       return le16_to_cpu(__get_unaligned_t(__le16, p));
+}
+
+static inline u32 get_unaligned_le32(const void *p)
+{
+       return le32_to_cpu(__get_unaligned_t(__le32, p));
+}
+
+static inline u64 get_unaligned_le64(const void *p)
+{
+       return le64_to_cpu(__get_unaligned_t(__le64, p));
+}
+
+static inline void put_unaligned_le16(u16 val, void *p)
+{
+       __put_unaligned_t(__le16, cpu_to_le16(val), p);
+}
+
+static inline void put_unaligned_le32(u32 val, void *p)
+{
+       __put_unaligned_t(__le32, cpu_to_le32(val), p);
+}
+
+static inline void put_unaligned_le64(u64 val, void *p)
+{
+       __put_unaligned_t(__le64, cpu_to_le64(val), p);
+}
+
+static inline u16 get_unaligned_be16(const void *p)
+{
+       return be16_to_cpu(__get_unaligned_t(__be16, p));
+}
+
+static inline u32 get_unaligned_be32(const void *p)
+{
+       return be32_to_cpu(__get_unaligned_t(__be32, p));
+}
+
+static inline u64 get_unaligned_be64(const void *p)
+{
+       return be64_to_cpu(__get_unaligned_t(__be64, p));
+}
+
+static inline void put_unaligned_be16(u16 val, void *p)
+{
+       __put_unaligned_t(__be16, cpu_to_be16(val), p);
+}
+
+static inline void put_unaligned_be32(u32 val, void *p)
+{
+       __put_unaligned_t(__be32, cpu_to_be32(val), p);
+}
+
+static inline void put_unaligned_be64(u64 val, void *p)
+{
+       __put_unaligned_t(__be64, cpu_to_be64(val), p);
+}
+
+static inline u32 __get_unaligned_be24(const u8 *p)
+{
+       return p[0] << 16 | p[1] << 8 | p[2];
+}
+
+static inline u32 get_unaligned_be24(const void *p)
+{
+       return __get_unaligned_be24(p);
+}
+
+static inline u32 __get_unaligned_le24(const u8 *p)
+{
+       return p[0] | p[1] << 8 | p[2] << 16;
+}
+
+static inline u32 get_unaligned_le24(const void *p)
+{
+       return __get_unaligned_le24(p);
+}
+
+static inline void __put_unaligned_be24(const u32 val, u8 *p)
+{
+       *p++ = (val >> 16) & 0xff;
+       *p++ = (val >> 8) & 0xff;
+       *p++ = val & 0xff;
+}
+
+static inline void put_unaligned_be24(const u32 val, void *p)
+{
+       __put_unaligned_be24(val, p);
+}
+
+static inline void __put_unaligned_le24(const u32 val, u8 *p)
+{
+       *p++ = val & 0xff;
+       *p++ = (val >> 8) & 0xff;
+       *p++ = (val >> 16) & 0xff;
+}
+
+static inline void put_unaligned_le24(const u32 val, void *p)
+{
+       __put_unaligned_le24(val, p);
+}
+
+static inline void __put_unaligned_be48(const u64 val, u8 *p)
+{
+       *p++ = (val >> 40) & 0xff;
+       *p++ = (val >> 32) & 0xff;
+       *p++ = (val >> 24) & 0xff;
+       *p++ = (val >> 16) & 0xff;
+       *p++ = (val >> 8) & 0xff;
+       *p++ = val & 0xff;
+}
+
+static inline void put_unaligned_be48(const u64 val, void *p)
+{
+       __put_unaligned_be48(val, p);
+}
+
+static inline u64 __get_unaligned_be48(const u8 *p)
+{
+       return (u64)p[0] << 40 | (u64)p[1] << 32 | (u64)p[2] << 24 |
+               p[3] << 16 | p[4] << 8 | p[5];
+}
+
+static inline u64 get_unaligned_be48(const void *p)
+{
+       return __get_unaligned_be48(p);
+}
+#pragma GCC diagnostic pop
+
+#endif /* __LINUX_UNALIGNED_H */
index 3c2a101986a314f6abdc486cfcda4c109017183f..5ee30f882736cbd1bc7b3c1e5236858db44015d7 100644 (file)
@@ -12,4 +12,7 @@
         (((~_ULL(0)) - (_ULL(1) << (l)) + 1) & \
          (~_ULL(0) >> (__BITS_PER_LONG_LONG - 1 - (h))))
 
+#define __GENMASK_U128(h, l) \
+       ((_BIT128((h)) << 1) - (_BIT128(l)))
+
 #endif /* _UAPI_LINUX_BITS_H */
index 1fb3cb2636e62e56e615a3a0a113072aadabac34..4a939c90dc2e4bce8c48212161d782acb4cb73a7 100644 (file)
@@ -1121,6 +1121,9 @@ enum bpf_attach_type {
 
 #define MAX_BPF_ATTACH_TYPE __MAX_BPF_ATTACH_TYPE
 
+/* Add BPF_LINK_TYPE(type, name) in bpf_types.h to keep bpf_link_type_strs[]
+ * in sync with the definitions below.
+ */
 enum bpf_link_type {
        BPF_LINK_TYPE_UNSPEC = 0,
        BPF_LINK_TYPE_RAW_TRACEPOINT = 1,
@@ -5519,11 +5522,12 @@ union bpf_attr {
  *             **-EOPNOTSUPP** if the hash calculation failed or **-EINVAL** if
  *             invalid arguments are passed.
  *
- * void *bpf_kptr_xchg(void *map_value, void *ptr)
+ * void *bpf_kptr_xchg(void *dst, void *ptr)
  *     Description
- *             Exchange kptr at pointer *map_value* with *ptr*, and return the
- *             old value. *ptr* can be NULL, otherwise it must be a referenced
- *             pointer which will be released when this helper is called.
+ *             Exchange kptr at pointer *dst* with *ptr*, and return the old value.
+ *             *dst* can be map value or local kptr. *ptr* can be NULL, otherwise
+ *             it must be a referenced pointer which will be released when this helper
+ *             is called.
  *     Return
  *             The old value of kptr (which can be NULL). The returned pointer
  *             if not NULL, is a reference which must be released using its
@@ -6046,11 +6050,6 @@ enum {
        BPF_F_MARK_ENFORCE              = (1ULL << 6),
 };
 
-/* BPF_FUNC_clone_redirect and BPF_FUNC_redirect flags. */
-enum {
-       BPF_F_INGRESS                   = (1ULL << 0),
-};
-
 /* BPF_FUNC_skb_set_tunnel_key and BPF_FUNC_skb_get_tunnel_key flags. */
 enum {
        BPF_F_TUNINFO_IPV6              = (1ULL << 0),
@@ -6197,10 +6196,12 @@ enum {
        BPF_F_BPRM_SECUREEXEC   = (1ULL << 0),
 };
 
-/* Flags for bpf_redirect_map helper */
+/* Flags for bpf_redirect and bpf_redirect_map helpers */
 enum {
-       BPF_F_BROADCAST         = (1ULL << 3),
-       BPF_F_EXCLUDE_INGRESS   = (1ULL << 4),
+       BPF_F_INGRESS           = (1ULL << 0), /* used for skb path */
+       BPF_F_BROADCAST         = (1ULL << 3), /* used for XDP path */
+       BPF_F_EXCLUDE_INGRESS   = (1ULL << 4), /* used for XDP path */
+#define BPF_F_REDIRECT_FLAGS (BPF_F_INGRESS | BPF_F_BROADCAST | BPF_F_EXCLUDE_INGRESS)
 };
 
 #define __bpf_md_ptr(type, name)       \
index a429381e7ca507fe7f4d86f4e7fa229cdcda078b..e16be0d37746e14b9eedcdb38be7d11f29b5113a 100644 (file)
 #define _BITUL(x)      (_UL(1) << (x))
 #define _BITULL(x)     (_ULL(1) << (x))
 
+#if !defined(__ASSEMBLY__)
+/*
+ * Missing asm support
+ *
+ * __BIT128() would not work in the asm code, as it shifts an
+ * 'unsigned __init128' data type as direct representation of
+ * 128 bit constants is not supported in the gcc compiler, as
+ * they get silently truncated.
+ *
+ * TODO: Please revisit this implementation when gcc compiler
+ * starts representing 128 bit constants directly like long
+ * and unsigned long etc. Subsequently drop the comment for
+ * GENMASK_U128() which would then start supporting asm code.
+ */
+#define _BIT128(x)     ((unsigned __int128)(1) << (x))
+#endif
+
 #define __ALIGN_KERNEL(x, a)           __ALIGN_KERNEL_MASK(x, (__typeof__(x))(a) - 1)
 #define __ALIGN_KERNEL_MASK(x, mask)   (((x) + (mask)) & ~(mask))
 
index d358add1611cd13d034b35d9a19cb3ebcc3e388c..5d32d53508d99f8631fad6e3172dc6e9ae5e7424 100644 (file)
@@ -141,7 +141,7 @@ struct in_addr {
  */
 #define IP_PMTUDISC_INTERFACE          4
 /* weaker version of IP_PMTUDISC_INTERFACE, which allows packets to get
- * fragmented if they exeed the interface mtu
+ * fragmented if they exceed the interface mtu
  */
 #define IP_PMTUDISC_OMIT               5
 
diff --git a/tools/include/vdso/unaligned.h b/tools/include/vdso/unaligned.h
new file mode 100644 (file)
index 0000000..eee3d2a
--- /dev/null
@@ -0,0 +1,15 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef __VDSO_UNALIGNED_H
+#define __VDSO_UNALIGNED_H
+
+#define __get_unaligned_t(type, ptr) ({                                                \
+       const struct { type x; } __packed *__pptr = (typeof(__pptr))(ptr);      \
+       __pptr->x;                                                              \
+})
+
+#define __put_unaligned_t(type, val, ptr) do {                                 \
+       struct { type x; } __packed *__pptr = (typeof(__pptr))(ptr);            \
+       __pptr->x = (val);                                                      \
+} while (0)
+
+#endif /* __VDSO_UNALIGNED_H */
index 4dcf7a0fd2358ed91d3cce5d75bc285b9051b2c6..d4332675babb74df8b70d7f3c74fc91d731e4dc2 100644 (file)
@@ -147,9 +147,9 @@ ifdef LIBDW_DIR
 endif
 DWARFLIBS := -ldw
 ifeq ($(findstring -static,${LDFLAGS}),-static)
-  DWARFLIBS += -lelf -ldl -lz -llzma -lbz2 -lzstd
+  DWARFLIBS += -lelf -lz -llzma -lbz2 -lzstd
 
-  LIBDW_VERSION := $(shell $(PKG_CONFIG) --modversion libdw)
+  LIBDW_VERSION := $(shell $(PKG_CONFIG) --modversion libdw).0.0
   LIBDW_VERSION_1 := $(word 1, $(subst ., ,$(LIBDW_VERSION)))
   LIBDW_VERSION_2 := $(word 2, $(subst ., ,$(LIBDW_VERSION)))
 
@@ -158,6 +158,9 @@ ifeq ($(findstring -static,${LDFLAGS}),-static)
   ifeq ($(shell test $(LIBDW_VERSION_2) -lt 177; echo $$?),0)
     DWARFLIBS += -lebl
   endif
+
+  # Must put -ldl after -lebl for dependency
+  DWARFLIBS += -ldl
 endif
 FEATURE_CHECK_CFLAGS-libdw-dwarf-unwind := $(LIBDW_CFLAGS)
 FEATURE_CHECK_LDFLAGS-libdw-dwarf-unwind := $(LIBDW_LDFLAGS) $(DWARFLIBS)
@@ -701,8 +704,8 @@ ifeq ($(BUILD_BPF_SKEL),1)
     BUILD_BPF_SKEL := 0
   else
     CLANG_VERSION := $(shell $(CLANG) --version | head -1 | sed 's/.*clang version \([[:digit:]]\+.[[:digit:]]\+.[[:digit:]]\+\).*/\1/g')
-    ifeq ($(call version-lt3,$(CLANG_VERSION),16.0.6),1)
-      $(warning Warning: Disabled BPF skeletons as at least $(CLANG) version 16.0.6 is reported to be a working setup with the current of BPF based perf features)
+    ifeq ($(call version-lt3,$(CLANG_VERSION),12.0.1),1)
+      $(warning Warning: Disabled BPF skeletons as reliable BTF generation needs at least $(CLANG) version 12.0.1)
       BUILD_BPF_SKEL := 0
     endif
   endif
index f6e8475290739a10ac93a3f2bd6f7f07b232e401..d3f11b90d0255c7e3e1f51f25d3415fa5436a2f1 100644 (file)
@@ -1399,7 +1399,7 @@ static const struct syscall_fmt syscall_fmts[] = {
          .arg = { [2] = { .scnprintf = SCA_WAITID_OPTIONS, /* options */ }, }, },
        { .name     = "waitid",     .errpid = true,
          .arg = { [3] = { .scnprintf = SCA_WAITID_OPTIONS, /* options */ }, }, },
-       { .name     = "write",      .errpid = true,
+       { .name     = "write",
          .arg = { [1] = { .scnprintf = SCA_BUF /* buf */, .from_user = true, }, }, },
 };
 
diff --git a/tools/perf/check-header_ignore_hunks/lib/list_sort.c b/tools/perf/check-header_ignore_hunks/lib/list_sort.c
new file mode 100644 (file)
index 0000000..32d98cb
--- /dev/null
@@ -0,0 +1,31 @@
+@@ -1,5 +1,6 @@
+ // SPDX-License-Identifier: GPL-2.0
+ #include <linux/kernel.h>
++#include <linux/bug.h>
+ #include <linux/compiler.h>
+ #include <linux/export.h>
+ #include <linux/string.h>
+@@ -52,6 +53,7 @@
+                       struct list_head *a, struct list_head *b)
+ {
+       struct list_head *tail = head;
++      u8 count = 0;
+       for (;;) {
+               /* if equal, take 'a' -- important for sort stability */
+@@ -77,6 +79,15 @@
+       /* Finish linking remainder of list b on to tail */
+       tail->next = b;
+       do {
++              /*
++               * If the merge is highly unbalanced (e.g. the input is
++               * already sorted), this loop may run many iterations.
++               * Continue callbacks to the client even though no
++               * element comparison is needed, so the client's cmp()
++               * routine can invoke cond_resched() periodically.
++               */
++              if (unlikely(!++count))
++                      cmp(priv, b, b);
+               b->prev = tail;
+               tail = b;
+               b = b->next;
index 714c78e5da07c163efcaf5ba5314e353552e6d16..a05c1c105c51bf1bd18a59195220894598eb7461 100755 (executable)
@@ -22,6 +22,7 @@ FILES=(
   "include/vdso/bits.h"
   "include/linux/const.h"
   "include/vdso/const.h"
+  "include/vdso/unaligned.h"
   "include/linux/hash.h"
   "include/linux/list-sort.h"
   "include/uapi/linux/hw_breakpoint.h"
@@ -136,6 +137,30 @@ beauty_check () {
   check_2 "tools/perf/trace/beauty/$file" "$file" "$@"
 }
 
+check_ignore_some_hunks () {
+  orig_file="$1"
+  tools_file="tools/$orig_file"
+  hunks_to_ignore="tools/perf/check-header_ignore_hunks/$orig_file"
+
+  if [ ! -f "$hunks_to_ignore" ]; then
+    echo "$hunks_to_ignore not found. Skipping $orig_file check."
+    FAILURES+=(
+      "$tools_file $orig_file"
+    )
+    return
+  fi
+
+  cmd="diff -u \"$tools_file\" \"$orig_file\" | grep -vf \"$hunks_to_ignore\" | wc -l | grep -qw 0"
+
+  if [ -f "$orig_file" ] && ! eval "$cmd"
+  then
+    FAILURES+=(
+      "$tools_file $orig_file"
+    )
+  fi
+}
+
+
 # Check if we have the kernel headers (tools/perf/../../include), else
 # we're probably on a detached tarball, so no point in trying to check
 # differences.
@@ -163,13 +188,12 @@ check arch/x86/lib/memcpy_64.S        '-I "^EXPORT_SYMBOL" -I "^#include <asm/ex
 check arch/x86/lib/memset_64.S        '-I "^EXPORT_SYMBOL" -I "^#include <asm/export.h>" -I"^SYM_FUNC_START\(_LOCAL\)*(memset_\(erms\|orig\))"'
 check arch/x86/include/asm/amd-ibs.h  '-I "^#include [<\"]\(asm/\)*msr-index.h"'
 check arch/arm64/include/asm/cputype.h '-I "^#include [<\"]\(asm/\)*sysreg.h"'
-check include/asm-generic/unaligned.h '-I "^#include <linux/unaligned/packed_struct.h>" -I "^#include <asm/byteorder.h>" -I "^#pragma GCC diagnostic"'
+check include/linux/unaligned.h '-I "^#include <linux/unaligned/packed_struct.h>" -I "^#include <asm/byteorder.h>" -I "^#pragma GCC diagnostic"'
 check include/uapi/asm-generic/mman.h '-I "^#include <\(uapi/\)*asm-generic/mman-common\(-tools\)*.h>"'
 check include/uapi/linux/mman.h       '-I "^#include <\(uapi/\)*asm/mman.h>"'
 check include/linux/build_bug.h       '-I "^#\(ifndef\|endif\)\( \/\/\)* static_assert$"'
 check include/linux/ctype.h          '-I "isdigit("'
 check lib/ctype.c                    '-I "^EXPORT_SYMBOL" -I "^#include <linux/export.h>" -B'
-check lib/list_sort.c                '-I "^#include <linux/bug.h>"'
 
 # diff non-symmetric files
 check_2 tools/perf/arch/x86/entry/syscalls/syscall_32.tbl arch/x86/entry/syscalls/syscall_32.tbl
@@ -187,6 +211,10 @@ done
 check_2 tools/perf/util/hashmap.h tools/lib/bpf/hashmap.h
 check_2 tools/perf/util/hashmap.c tools/lib/bpf/hashmap.c
 
+# Files with larger differences
+
+check_ignore_some_hunks lib/list_sort.c
+
 cd tools/perf || exit
 
 if [ ${#FAILURES[@]} -gt 0 ]
index b5dc10b2a73810b35f2058eeead842e1e3f9f56f..bead723e34af3f0e874e3a9e1dd3433907a275ff 100755 (executable)
 TEST_RESULT=0
 
 # skip if not supported
-BLACKFUNC=`head -n 1 /sys/kernel/debug/kprobes/blacklist 2> /dev/null | cut -f2`
-if [ -z "$BLACKFUNC" ]; then
+BLACKFUNC_LIST=`head -n 5 /sys/kernel/debug/kprobes/blacklist 2> /dev/null | cut -f2`
+if [ -z "$BLACKFUNC_LIST" ]; then
        print_overall_skipped
        exit 0
 fi
 
+# try to find vmlinux with DWARF debug info
+VMLINUX_FILE=$(perf probe -v random_probe |& grep "Using.*for symbols" | sed -r 's/^Using (.*) for symbols$/\1/')
+
 # remove all previously added probes
 clear_all_probes
 
 
 ### adding blacklisted function
-
-# functions from blacklist should be skipped by perf probe
-! $CMD_PERF probe $BLACKFUNC > $LOGS_DIR/adding_blacklisted.log 2> $LOGS_DIR/adding_blacklisted.err
-PERF_EXIT_CODE=$?
-
 REGEX_SCOPE_FAIL="Failed to find scope of probe point"
 REGEX_SKIP_MESSAGE=" is blacklisted function, skip it\."
-REGEX_NOT_FOUND_MESSAGE="Probe point \'$BLACKFUNC\' not found."
+REGEX_NOT_FOUND_MESSAGE="Probe point \'$RE_EVENT\' not found."
 REGEX_ERROR_MESSAGE="Error: Failed to add events."
 REGEX_INVALID_ARGUMENT="Failed to write event: Invalid argument"
 REGEX_SYMBOL_FAIL="Failed to find symbol at $RE_ADDRESS"
-REGEX_OUT_SECTION="$BLACKFUNC is out of \.\w+, skip it"
-../common/check_all_lines_matched.pl "$REGEX_SKIP_MESSAGE" "$REGEX_NOT_FOUND_MESSAGE" "$REGEX_ERROR_MESSAGE" "$REGEX_SCOPE_FAIL" "$REGEX_INVALID_ARGUMENT" "$REGEX_SYMBOL_FAIL" "$REGEX_OUT_SECTION" < $LOGS_DIR/adding_blacklisted.err
-CHECK_EXIT_CODE=$?
-
-print_results $PERF_EXIT_CODE $CHECK_EXIT_CODE "adding blacklisted function $BLACKFUNC"
-(( TEST_RESULT += $? ))
-
+REGEX_OUT_SECTION="$RE_EVENT is out of \.\w+, skip it"
+REGEX_MISSING_DECL_LINE="A function DIE doesn't have decl_line. Maybe broken DWARF?"
+
+BLACKFUNC=""
+SKIP_DWARF=0
+
+for BLACKFUNC in $BLACKFUNC_LIST; do
+       echo "Probing $BLACKFUNC"
+
+       # functions from blacklist should be skipped by perf probe
+       ! $CMD_PERF probe $BLACKFUNC > $LOGS_DIR/adding_blacklisted.log 2> $LOGS_DIR/adding_blacklisted.err
+       PERF_EXIT_CODE=$?
+
+       # check for bad DWARF polluting the result
+       ../common/check_all_patterns_found.pl "$REGEX_MISSING_DECL_LINE" >/dev/null < $LOGS_DIR/adding_blacklisted.err
+
+       if [ $? -eq 0 ]; then
+               SKIP_DWARF=1
+               echo "Result polluted by broken DWARF, trying another probe"
+
+               # confirm that the broken DWARF comes from assembler
+               if [ -n "$VMLINUX_FILE" ]; then
+                       readelf -wi "$VMLINUX_FILE" |
+                       awk -v probe="$BLACKFUNC" '/DW_AT_language/ { comp_lang = $0 }
+                                                  $0 ~ probe { if (comp_lang) { print comp_lang }; exit }' |
+                       grep -q "MIPS assembler"
+
+                       CHECK_EXIT_CODE=$?
+                       if [ $CHECK_EXIT_CODE -ne 0 ]; then
+                               SKIP_DWARF=0 # broken DWARF while available
+                               break
+                       fi
+               fi
+       else
+               ../common/check_all_lines_matched.pl "$REGEX_SKIP_MESSAGE" "$REGEX_NOT_FOUND_MESSAGE" "$REGEX_ERROR_MESSAGE" "$REGEX_SCOPE_FAIL" "$REGEX_INVALID_ARGUMENT" "$REGEX_SYMBOL_FAIL" "$REGEX_OUT_SECTION" < $LOGS_DIR/adding_blacklisted.err
+               CHECK_EXIT_CODE=$?
+
+               SKIP_DWARF=0
+               break
+       fi
+done
+
+if [ $SKIP_DWARF -eq 1 ]; then
+       print_testcase_skipped "adding blacklisted function $BLACKFUNC"
+else
+       print_results $PERF_EXIT_CODE $CHECK_EXIT_CODE "adding blacklisted function $BLACKFUNC"
+       (( TEST_RESULT += $? ))
+fi
 
 ### listing not-added probe
 
index 13aea8fc3d45fcf462b18fddc4a90fffcc87a631..47051871b436182f69c0995109290ceec267b99a 100644 (file)
@@ -18,8 +18,8 @@
  *  Vectors   0 ...  31 : system traps and exceptions - hardcoded events
  *  Vectors  32 ... 127 : device interrupts
  *  Vector  128         : legacy int80 syscall interface
- *  Vectors 129 ... LOCAL_TIMER_VECTOR-1
- *  Vectors LOCAL_TIMER_VECTOR ... 255 : special interrupts
+ *  Vectors 129 ... FIRST_SYSTEM_VECTOR-1 : device interrupts
+ *  Vectors FIRST_SYSTEM_VECTOR ... 255   : special interrupts
  *
  * 64-bit x86 has per CPU IDT tables, 32-bit has one shared IDT table.
  *
index 456f59addf741062cdf10c92b85cff414f5cc28e..e3f13f96a27c227c81c6ae7f50e277f8f084c3e7 100755 (executable)
@@ -13,9 +13,14 @@ printf "static const char *fs_at_flags[] = {\n"
 regex='^[[:space:]]*#[[:space:]]*define[[:space:]]+AT_([^_]+[[:alnum:]_]+)[[:space:]]+(0x[[:xdigit:]]+)[[:space:]]*.*'
 # AT_EACCESS is only meaningful to faccessat, so we will special case it there...
 # AT_STATX_SYNC_TYPE is not a bit, its a mask of AT_STATX_SYNC_AS_STAT, AT_STATX_FORCE_SYNC and AT_STATX_DONT_SYNC
+# AT_HANDLE_FID and AT_HANDLE_MNT_ID_UNIQUE are reusing values and are valid only for name_to_handle_at()
+# AT_RENAME_NOREPLACE reuses 0x1 and is valid only for renameat2()
 grep -E $regex ${linux_fcntl} | \
        grep -v AT_EACCESS | \
        grep -v AT_STATX_SYNC_TYPE | \
+       grep -v AT_HANDLE_FID | \
+       grep -v AT_HANDLE_MNT_ID_UNIQUE | \
+       grep -v AT_RENAME_NOREPLACE | \
        sed -r "s/$regex/\2 \1/g"       | \
        xargs printf "\t[ilog2(%s) + 1] = \"%s\",\n"
 printf "};\n"
index df9cdb8bbfb88428e1d2d6a2d16c7d1abe9ae9fc..d18cc47e89bd0164ec8de7702c266a406a2c4647 100644 (file)
@@ -327,6 +327,7 @@ struct ucred {
                                          * plain text and require encryption
                                          */
 
+#define MSG_SOCK_DEVMEM 0x2000000      /* Receive devmem skbs as cmsg */
 #define MSG_ZEROCOPY   0x4000000       /* Use user data in kernel path */
 #define MSG_SPLICE_PAGES 0x8000000     /* Splice the pages from the iterator in sendmsg() */
 #define MSG_FASTOPEN   0x20000000      /* Send data in TCP SYN */
index c0bcc185fa48f85244d3f3b0de01a1c979732b15..87e2dec79fea4ef21e694f3c069ec229926b6d08 100644 (file)
@@ -16,6 +16,9 @@
 
 #define F_DUPFD_QUERY  (F_LINUX_SPECIFIC_BASE + 3)
 
+/* Was the file just created? */
+#define F_CREATED_QUERY        (F_LINUX_SPECIFIC_BASE + 4)
+
 /*
  * Cancel a blocking posix lock; internal use only until we expose an
  * asynchronous lock api to userspace:
 #define DN_ATTRIB      0x00000020      /* File changed attibutes */
 #define DN_MULTISHOT   0x80000000      /* Don't remove notifier */
 
+#define AT_FDCWD               -100    /* Special value for dirfd used to
+                                          indicate openat should use the
+                                          current working directory. */
+
+
+/* Generic flags for the *at(2) family of syscalls. */
+
+/* Reserved for per-syscall flags      0xff. */
+#define AT_SYMLINK_NOFOLLOW            0x100   /* Do not follow symbolic
+                                                  links. */
+/* Reserved for per-syscall flags      0x200 */
+#define AT_SYMLINK_FOLLOW              0x400   /* Follow symbolic links. */
+#define AT_NO_AUTOMOUNT                        0x800   /* Suppress terminal automount
+                                                  traversal. */
+#define AT_EMPTY_PATH                  0x1000  /* Allow empty relative
+                                                  pathname to operate on dirfd
+                                                  directly. */
+/*
+ * These flags are currently statx(2)-specific, but they could be made generic
+ * in the future and so they should not be used for other per-syscall flags.
+ */
+#define AT_STATX_SYNC_TYPE             0x6000  /* Type of synchronisation required from statx() */
+#define AT_STATX_SYNC_AS_STAT          0x0000  /* - Do whatever stat() does */
+#define AT_STATX_FORCE_SYNC            0x2000  /* - Force the attributes to be sync'd with the server */
+#define AT_STATX_DONT_SYNC             0x4000  /* - Don't sync attributes with the server */
+
+#define AT_RECURSIVE                   0x8000  /* Apply to the entire subtree */
+
 /*
- * The constants AT_REMOVEDIR and AT_EACCESS have the same value.  AT_EACCESS is
- * meaningful only to faccessat, while AT_REMOVEDIR is meaningful only to
- * unlinkat.  The two functions do completely different things and therefore,
- * the flags can be allowed to overlap.  For example, passing AT_REMOVEDIR to
- * faccessat would be undefined behavior and thus treating it equivalent to
- * AT_EACCESS is valid undefined behavior.
+ * Per-syscall flags for the *at(2) family of syscalls.
+ *
+ * These are flags that are so syscall-specific that a user passing these flags
+ * to the wrong syscall is so "clearly wrong" that we can safely call such
+ * usage "undefined behaviour".
+ *
+ * For example, the constants AT_REMOVEDIR and AT_EACCESS have the same value.
+ * AT_EACCESS is meaningful only to faccessat, while AT_REMOVEDIR is meaningful
+ * only to unlinkat. The two functions do completely different things and
+ * therefore, the flags can be allowed to overlap. For example, passing
+ * AT_REMOVEDIR to faccessat would be undefined behavior and thus treating it
+ * equivalent to AT_EACCESS is valid undefined behavior.
+ *
+ * Note for implementers: When picking a new per-syscall AT_* flag, try to
+ * reuse already existing flags first. This leaves us with as many unused bits
+ * as possible, so we can use them for generic bits in the future if necessary.
  */
-#define AT_FDCWD               -100    /* Special value used to indicate
-                                           openat should use the current
-                                           working directory. */
-#define AT_SYMLINK_NOFOLLOW    0x100   /* Do not follow symbolic links.  */
+
+/* Flags for renameat2(2) (must match legacy RENAME_* flags). */
+#define AT_RENAME_NOREPLACE    0x0001
+#define AT_RENAME_EXCHANGE     0x0002
+#define AT_RENAME_WHITEOUT     0x0004
+
+/* Flag for faccessat(2). */
 #define AT_EACCESS             0x200   /* Test access permitted for
                                            effective IDs, not real IDs.  */
+/* Flag for unlinkat(2). */
 #define AT_REMOVEDIR           0x200   /* Remove directory instead of
                                            unlinking file.  */
-#define AT_SYMLINK_FOLLOW      0x400   /* Follow symbolic links.  */
-#define AT_NO_AUTOMOUNT                0x800   /* Suppress terminal automount traversal */
-#define AT_EMPTY_PATH          0x1000  /* Allow empty relative pathname */
-
-#define AT_STATX_SYNC_TYPE     0x6000  /* Type of synchronisation required from statx() */
-#define AT_STATX_SYNC_AS_STAT  0x0000  /* - Do whatever stat() does */
-#define AT_STATX_FORCE_SYNC    0x2000  /* - Force the attributes to be sync'd with the server */
-#define AT_STATX_DONT_SYNC     0x4000  /* - Don't sync attributes with the server */
-
-#define AT_RECURSIVE           0x8000  /* Apply to the entire subtree */
+/* Flags for name_to_handle_at(2). */
+#define AT_HANDLE_FID          0x200   /* File handle is needed to compare
+                                          object identity and may not be
+                                          usable with open_by_handle_at(2). */
+#define AT_HANDLE_MNT_ID_UNIQUE        0x001   /* Return the u64 unique mount ID. */
 
-/* Flags for name_to_handle_at(2). We reuse AT_ flag space to save bits... */
-#define AT_HANDLE_FID          AT_REMOVEDIR    /* file handle is needed to
-                                       compare object identity and may not
-                                       be usable to open_by_handle_at(2) */
 #if defined(__KERNEL__)
 #define AT_GETATTR_NOSEC       0x80000000
 #endif
index 3bac0a8ceab26ee78c37b425a76115aa21c20c06..359a14cc76a4038aeacef14b2915d5ce60d0cf44 100644 (file)
@@ -118,6 +118,7 @@ struct clone_args {
 /* SCHED_ISO: reserved but not implemented yet */
 #define SCHED_IDLE             5
 #define SCHED_DEADLINE         6
+#define SCHED_EXT              7
 
 /* Can be ORed in to make sure the process is reverted back to SCHED_NORMAL on fork */
 #define SCHED_RESET_ON_FORK     0x40000000
index 8bf7e8a0eb6f03a8026e07f1968568fb099e7c9f..4cd513215bcd8f74b56fbff8376d0b891babb22d 100644 (file)
@@ -869,7 +869,7 @@ struct snd_ump_block_info {
  *  Timer section - /dev/snd/timer
  */
 
-#define SNDRV_TIMER_VERSION            SNDRV_PROTOCOL_VERSION(2, 0, 7)
+#define SNDRV_TIMER_VERSION            SNDRV_PROTOCOL_VERSION(2, 0, 8)
 
 enum {
        SNDRV_TIMER_CLASS_NONE = -1,
@@ -894,6 +894,7 @@ enum {
 #define SNDRV_TIMER_GLOBAL_RTC         1       /* unused */
 #define SNDRV_TIMER_GLOBAL_HPET                2
 #define SNDRV_TIMER_GLOBAL_HRTIMER     3
+#define SNDRV_TIMER_GLOBAL_UDRIVEN     4
 
 /* info flags */
 #define SNDRV_TIMER_FLG_SLAVE          (1<<0)  /* cannot be controlled */
@@ -974,6 +975,18 @@ struct snd_timer_status {
 };
 #endif
 
+/*
+ * This structure describes the userspace-driven timer. Such timers are purely virtual,
+ * and can only be triggered from software (for instance, by userspace application).
+ */
+struct snd_timer_uinfo {
+       /* To pretend being a normal timer, we need to know the resolution in ns. */
+       __u64 resolution;
+       int fd;
+       unsigned int id;
+       unsigned char reserved[16];
+};
+
 #define SNDRV_TIMER_IOCTL_PVERSION     _IOR('T', 0x00, int)
 #define SNDRV_TIMER_IOCTL_NEXT_DEVICE  _IOWR('T', 0x01, struct snd_timer_id)
 #define SNDRV_TIMER_IOCTL_TREAD_OLD    _IOW('T', 0x02, int)
@@ -990,6 +1003,8 @@ struct snd_timer_status {
 #define SNDRV_TIMER_IOCTL_CONTINUE     _IO('T', 0xa2)
 #define SNDRV_TIMER_IOCTL_PAUSE                _IO('T', 0xa3)
 #define SNDRV_TIMER_IOCTL_TREAD64      _IOW('T', 0xa4, int)
+#define SNDRV_TIMER_IOCTL_CREATE       _IOWR('T', 0xa5, struct snd_timer_uinfo)
+#define SNDRV_TIMER_IOCTL_TRIGGER      _IO('T', 0xa6)
 
 #if __BITS_PER_LONG == 64
 #define SNDRV_TIMER_IOCTL_TREAD SNDRV_TIMER_IOCTL_TREAD_OLD
index ed3ff969b5465bbf1d29635aa75e7378d06456cb..2da581ff0c802df88505bd36dfd827944972affb 100644 (file)
@@ -11,6 +11,9 @@
 #ifndef MSG_BATCH
 #define MSG_BATCH                 0x40000
 #endif
+#ifndef MSG_SOCK_DEVMEM
+#define MSG_SOCK_DEVMEM                 0x2000000
+#endif
 #ifndef MSG_ZEROCOPY
 #define MSG_ZEROCOPY            0x4000000
 #endif
@@ -57,6 +60,7 @@ static size_t syscall_arg__scnprintf_msg_flags(char *bf, size_t size,
        P_MSG_FLAG(MORE);
        P_MSG_FLAG(WAITFORONE);
        P_MSG_FLAG(BATCH);
+       P_MSG_FLAG(SOCK_DEVMEM);
        P_MSG_FLAG(ZEROCOPY);
        P_MSG_FLAG(SPLICE_PAGES);
        P_MSG_FLAG(FASTOPEN);
index 7bf607d0f6d8a660a67956e07bf0dc7c8330c4b4..4cef10a83962fb1b33471783c3796f73f0d44995 100644 (file)
@@ -11,7 +11,7 @@
 #include <linux/bitops.h>
 #include <stdarg.h>
 #include <linux/kernel.h>
-#include <asm-generic/unaligned.h>
+#include <linux/unaligned.h>
 
 #include "arm-spe-pkt-decoder.h"
 
index b2f17cca014bcff47fb84e15aaacb80ffec011d9..4a62ed593e84edf8cd002751d0b27541195f967a 100644 (file)
@@ -288,6 +288,10 @@ int sys_enter_rename(struct syscall_enter_args *args)
        augmented_args->arg.size = PERF_ALIGN(oldpath_len + 1, sizeof(u64));
        len += augmented_args->arg.size;
 
+       /* Every read from userspace is limited to value size */
+       if (augmented_args->arg.size > sizeof(augmented_args->arg.value))
+               return 1; /* Failure: don't filter */
+
        struct augmented_arg *arg2 = (void *)&augmented_args->arg.value + augmented_args->arg.size;
 
        newpath_len = augmented_arg__read_str(arg2, newpath_arg, sizeof(augmented_args->arg.value));
@@ -315,6 +319,10 @@ int sys_enter_renameat2(struct syscall_enter_args *args)
        augmented_args->arg.size = PERF_ALIGN(oldpath_len + 1, sizeof(u64));
        len += augmented_args->arg.size;
 
+       /* Every read from userspace is limited to value size */
+       if (augmented_args->arg.size > sizeof(augmented_args->arg.value))
+               return 1; /* Failure: don't filter */
+
        struct augmented_arg *arg2 = (void *)&augmented_args->arg.value + augmented_args->arg.size;
 
        newpath_len = augmented_arg__read_str(arg2, newpath_arg, sizeof(augmented_args->arg.value));
@@ -423,8 +431,9 @@ static bool pid_filter__has(struct pids_filtered *pids, pid_t pid)
 static int augment_sys_enter(void *ctx, struct syscall_enter_args *args)
 {
        bool augmented, do_output = false;
-       int zero = 0, size, aug_size, index, output = 0,
+       int zero = 0, size, aug_size, index,
            value_size = sizeof(struct augmented_arg) - offsetof(struct augmented_arg, value);
+       u64 output = 0; /* has to be u64, otherwise it won't pass the verifier */
        unsigned int nr, *beauty_map;
        struct beauty_payload_enter *payload;
        void *arg, *payload_offset;
@@ -477,6 +486,8 @@ static int augment_sys_enter(void *ctx, struct syscall_enter_args *args)
                                augmented = true;
                } else if (size < 0 && size >= -6) { /* buffer */
                        index = -(size + 1);
+                       barrier_var(index); // Prevent clang (noticed with v18) from removing the &= 7 trick.
+                       index &= 7;         // Satisfy the bounds checking with the verifier in some kernels.
                        aug_size = args->args[index];
 
                        if (aug_size > TRACE_AUG_MAX_BUF)
@@ -488,10 +499,17 @@ static int augment_sys_enter(void *ctx, struct syscall_enter_args *args)
                        }
                }
 
+               /* Augmented data size is limited to sizeof(augmented_arg->unnamed union with value field) */
+               if (aug_size > value_size)
+                       aug_size = value_size;
+
                /* write data to payload */
                if (augmented) {
                        int written = offsetof(struct augmented_arg, value) + aug_size;
 
+                       if (written < 0 || written > sizeof(struct augmented_arg))
+                               return 1;
+
                        ((struct augmented_arg *)payload_offset)->size = aug_size;
                        output += written;
                        payload_offset += written;
@@ -499,7 +517,7 @@ static int augment_sys_enter(void *ctx, struct syscall_enter_args *args)
                }
        }
 
-       if (!do_output)
+       if (!do_output || (sizeof(struct syscall_enter_args) + output) > sizeof(struct beauty_payload_enter))
                return 1;
 
        return augmented__beauty_output(ctx, payload, sizeof(struct syscall_enter_args) + output);
index 7574a67651bc545a5e3358a6295457b82f7d5f95..69d9a2bcd40bfdd105c788644a4808460dcc16b7 100644 (file)
@@ -7,13 +7,9 @@
 #include "debug.h"
 #include <errno.h>
 #include <string.h>
-#include <unistd.h>
 #include <linux/capability.h>
 #include <sys/syscall.h>
-
-#ifndef SYS_capget
-#define SYS_capget 90
-#endif
+#include <unistd.h>
 
 #define MAX_LINUX_CAPABILITY_U32S _LINUX_CAPABILITY_U32S_3
 
@@ -21,9 +17,9 @@ bool perf_cap__capable(int cap, bool *used_root)
 {
        struct __user_cap_header_struct header = {
                .version = _LINUX_CAPABILITY_VERSION_3,
-               .pid = getpid(),
+               .pid = 0,
        };
-       struct __user_cap_data_struct data[MAX_LINUX_CAPABILITY_U32S];
+       struct __user_cap_data_struct data[MAX_LINUX_CAPABILITY_U32S] = {};
        __u32 cap_val;
 
        *used_root = false;
index 90f32f327b9b1f8265115939d383a9dabb6d0025..40f047baef8100a1fea538d7ad3cf94e3e2f8af2 100644 (file)
@@ -3323,7 +3323,7 @@ static int cs_etm__create_decoders(struct cs_etm_auxtrace *etm)
                 * Don't create decoders for empty queues, mainly because
                 * etmq->format is unknown for empty queues.
                 */
-               assert(empty == (etmq->format == UNSET));
+               assert(empty || etmq->format != UNSET);
                if (empty)
                        continue;
 
index 336a3a183a78c1fb04fd95b50f5ee9a0778ae05d..bd750581256934d75e4001f5e2b28e4c793ae0c0 100644 (file)
@@ -9,6 +9,7 @@
 #include <elfutils/libdw.h>
 #include <elfutils/libdwfl.h>
 #include <elfutils/version.h>
+#include <errno.h>
 
 struct strbuf;
 
index bccb988a7a443484c32a75e9514ce2351a89098b..94fb16cf9e0c0614d1372f161d1e3d69a3911372 100644 (file)
@@ -10,7 +10,7 @@
 #include <byteswap.h>
 #include <linux/kernel.h>
 #include <linux/compiler.h>
-#include <asm-generic/unaligned.h>
+#include <linux/unaligned.h>
 
 #include "intel-pt-pkt-decoder.h"
 
index 31a223eaf8e65fa374d415858c711e787540572f..ee3d43a7ba4570f0518b21e9d0b471476bb226f5 100644 (file)
@@ -19,6 +19,7 @@
 #include "util/bpf-filter.h"
 #include "util/env.h"
 #include "util/kvm-stat.h"
+#include "util/stat.h"
 #include "util/kwork.h"
 #include "util/sample.h"
 #include "util/lock-contention.h"
@@ -1355,6 +1356,7 @@ error:
 
 unsigned int scripting_max_stack = PERF_MAX_STACK_DEPTH;
 
+#ifdef HAVE_KVM_STAT_SUPPORT
 bool kvm_entry_event(struct evsel *evsel __maybe_unused)
 {
        return false;
@@ -1384,6 +1386,7 @@ void exit_event_decode_key(struct perf_kvm_stat *kvm __maybe_unused,
                           char *decode __maybe_unused)
 {
 }
+#endif // HAVE_KVM_STAT_SUPPORT
 
 int find_scripts(char **scripts_array  __maybe_unused, char **scripts_path_array  __maybe_unused,
                int num  __maybe_unused, int pathlen __maybe_unused)
index a18927d792afc504c8641ff2915b3a89b4c37031..3bbf173ad822bce9466ee1ed77641c75ab74d2a6 100644 (file)
@@ -1931,6 +1931,9 @@ int dso__load(struct dso *dso, struct map *map)
                if (next_slot) {
                        ss_pos++;
 
+                       if (dso__binary_type(dso) == DSO_BINARY_TYPE__NOT_FOUND)
+                               dso__set_binary_type(dso, symtab_type);
+
                        if (syms_ss && runtime_ss)
                                break;
                } else {
index 7c15dec6900d8aaa68d5d1dfaaaca6518ac49a74..6c45ded922b6d539d6fd4b07251aaa2c3b0aa4f2 100644 (file)
@@ -46,6 +46,11 @@ static const char *const *syscalltbl_native = syscalltbl_mips_n64;
 #include <asm/syscalls.c>
 const int syscalltbl_native_max_id = SYSCALLTBL_LOONGARCH_MAX_ID;
 static const char *const *syscalltbl_native = syscalltbl_loongarch;
+#else
+const int syscalltbl_native_max_id = 0;
+static const char *const syscalltbl_native[] = {
+       [0] = "unknown",
+};
 #endif
 
 struct syscall {
@@ -182,6 +187,11 @@ int syscalltbl__id(struct syscalltbl *tbl, const char *name)
        return audit_name_to_syscall(name, tbl->audit_machine);
 }
 
+int syscalltbl__id_at_idx(struct syscalltbl *tbl __maybe_unused, int idx)
+{
+       return idx;
+}
+
 int syscalltbl__strglobmatch_next(struct syscalltbl *tbl __maybe_unused,
                                  const char *syscall_glob __maybe_unused, int *idx __maybe_unused)
 {
index 1b6f8f6db7aa47142b3b58ff2459cffa475f5ca0..c12f5d8c4bf696464a9971e2c9733e601532757e 100644 (file)
@@ -308,8 +308,10 @@ static struct dso *machine__find_vdso(struct machine *machine,
                if (!dso) {
                        dso = dsos__find(&machine->dsos, DSO__NAME_VDSO,
                                         true);
-                       if (dso && dso_type != dso__type(dso, machine))
+                       if (dso && dso_type != dso__type(dso, machine)) {
+                               dso__put(dso);
                                dso = NULL;
+                       }
                }
                break;
        case DSO__TYPE_X32BIT:
index f538c75db1835dca7742d86650a9ff35c3843694..248ab790d143ed744e20d6e3b2cf06b75e98bbbd 100644 (file)
@@ -7,7 +7,13 @@
 #ifndef __SCX_COMMON_BPF_H
 #define __SCX_COMMON_BPF_H
 
+#ifdef LSP
+#define __bpf__
+#include "../vmlinux/vmlinux.h"
+#else
 #include "vmlinux.h"
+#endif
+
 #include <bpf/bpf_helpers.h>
 #include <bpf/bpf_tracing.h>
 #include <asm-generic/errno.h>
@@ -35,8 +41,8 @@ void scx_bpf_dispatch_vtime(struct task_struct *p, u64 dsq_id, u64 slice, u64 vt
 u32 scx_bpf_dispatch_nr_slots(void) __ksym;
 void scx_bpf_dispatch_cancel(void) __ksym;
 bool scx_bpf_consume(u64 dsq_id) __ksym;
-void scx_bpf_dispatch_from_dsq_set_slice(struct bpf_iter_scx_dsq *it__iter, u64 slice) __ksym;
-void scx_bpf_dispatch_from_dsq_set_vtime(struct bpf_iter_scx_dsq *it__iter, u64 vtime) __ksym;
+void scx_bpf_dispatch_from_dsq_set_slice(struct bpf_iter_scx_dsq *it__iter, u64 slice) __ksym __weak;
+void scx_bpf_dispatch_from_dsq_set_vtime(struct bpf_iter_scx_dsq *it__iter, u64 vtime) __ksym __weak;
 bool scx_bpf_dispatch_from_dsq(struct bpf_iter_scx_dsq *it__iter, struct task_struct *p, u64 dsq_id, u64 enq_flags) __ksym __weak;
 bool scx_bpf_dispatch_vtime_from_dsq(struct bpf_iter_scx_dsq *it__iter, struct task_struct *p, u64 dsq_id, u64 enq_flags) __ksym __weak;
 u32 scx_bpf_reenqueue_local(void) __ksym;
@@ -65,7 +71,7 @@ s32 scx_bpf_pick_any_cpu(const cpumask_t *cpus_allowed, u64 flags) __ksym;
 bool scx_bpf_task_running(const struct task_struct *p) __ksym;
 s32 scx_bpf_task_cpu(const struct task_struct *p) __ksym;
 struct rq *scx_bpf_cpu_rq(s32 cpu) __ksym;
-struct cgroup *scx_bpf_task_cgroup(struct task_struct *p) __ksym;
+struct cgroup *scx_bpf_task_cgroup(struct task_struct *p) __ksym __weak;
 
 /*
  * Use the following as @it__iter when calling
@@ -309,6 +315,15 @@ void bpf_cpumask_copy(struct bpf_cpumask *dst, const struct cpumask *src) __ksym
 u32 bpf_cpumask_any_distribute(const struct cpumask *cpumask) __ksym;
 u32 bpf_cpumask_any_and_distribute(const struct cpumask *src1,
                                   const struct cpumask *src2) __ksym;
+u32 bpf_cpumask_weight(const struct cpumask *cpumask) __ksym;
+
+/*
+ * Access a cpumask in read-only mode (typically to check bits).
+ */
+static __always_inline const struct cpumask *cast_mask(struct bpf_cpumask *mask)
+{
+       return (const struct cpumask *)mask;
+}
 
 /* rcu */
 void bpf_rcu_read_lock(void) __ksym;
index 3d2fe1208900554066a8fca618e8831710f2486d..e5afe9efd3f318ec6c6ea6769434ffbdfb272dec 100644 (file)
        __ret;                                                                  \
 })
 
+/* v6.12: 819513666966 ("sched_ext: Add cgroup support") */
+#define __COMPAT_scx_bpf_task_cgroup(p)                                                \
+       (bpf_ksym_exists(scx_bpf_task_cgroup) ?                                 \
+        scx_bpf_task_cgroup((p)) : NULL)
+
+/* v6.12: 4c30f5ce4f7a ("sched_ext: Implement scx_bpf_dispatch[_vtime]_from_dsq()") */
+#define __COMPAT_scx_bpf_dispatch_from_dsq_set_slice(it, slice)                        \
+       (bpf_ksym_exists(scx_bpf_dispatch_from_dsq_set_slice) ?                 \
+        scx_bpf_dispatch_from_dsq_set_slice((it), (slice)) : (void)0)
+#define __COMPAT_scx_bpf_dispatch_from_dsq_set_vtime(it, vtime)                        \
+       (bpf_ksym_exists(scx_bpf_dispatch_from_dsq_set_vtime) ?                 \
+        scx_bpf_dispatch_from_dsq_set_vtime((it), (vtime)) : (void)0)
+#define __COMPAT_scx_bpf_dispatch_from_dsq(it, p, dsq_id, enq_flags)           \
+       (bpf_ksym_exists(scx_bpf_dispatch_from_dsq) ?                           \
+        scx_bpf_dispatch_from_dsq((it), (p), (dsq_id), (enq_flags)) : false)
+#define __COMPAT_scx_bpf_dispatch_vtime_from_dsq(it, p, dsq_id, enq_flags)     \
+       (bpf_ksym_exists(scx_bpf_dispatch_vtime_from_dsq) ?                     \
+        scx_bpf_dispatch_vtime_from_dsq((it), (p), (dsq_id), (enq_flags)) : false)
+
 /*
  * Define sched_ext_ops. This may be expanded to define multiple variants for
  * backward compatibility. See compat.h::SCX_OPS_LOAD/ATTACH().
index 891693ee604ec78f4114a3df34a394d322d9ed50..8ce2734402e1d50c8e28a950fc91c0abfbb26350 100644 (file)
@@ -25,7 +25,11 @@ struct user_exit_info {
 
 #ifdef __bpf__
 
+#ifdef LSP
+#include "../vmlinux/vmlinux.h"
+#else
 #include "vmlinux.h"
+#endif
 #include <bpf/bpf_core_read.h>
 
 #define UEI_DEFINE(__name)                                                     \
index 3ab2b60781a0d9d366b194e50624bce869cacbb4..b722baf6da4b99d17d814dc50b02dc0d250c933d 100644 (file)
 /*
  * Maximum amount of retries to find a valid cgroup.
  */
-#define CGROUP_MAX_RETRIES 1024
+enum {
+       FALLBACK_DSQ            = 0,
+       CGROUP_MAX_RETRIES      = 1024,
+};
 
 char _license[] SEC("license") = "GPL";
 
@@ -225,7 +228,7 @@ static void cgrp_refresh_hweight(struct cgroup *cgrp, struct fcg_cgrp_ctx *cgc)
                                break;
 
                        /*
-                        * We can be oppotunistic here and not grab the
+                        * We can be opportunistic here and not grab the
                         * cgv_tree_lock and deal with the occasional races.
                         * However, hweight updates are already cached and
                         * relatively low-frequency. Let's just do the
@@ -258,8 +261,7 @@ static void cgrp_cap_budget(struct cgv_node *cgv_node, struct fcg_cgrp_ctx *cgc)
         * and thus can't be updated and repositioned. Instead, we collect the
         * vtime deltas separately and apply it asynchronously here.
         */
-       delta = cgc->cvtime_delta;
-       __sync_fetch_and_sub(&cgc->cvtime_delta, delta);
+       delta = __sync_fetch_and_sub(&cgc->cvtime_delta, cgc->cvtime_delta);
        cvtime = cgv_node->cvtime + delta;
 
        /*
@@ -378,12 +380,12 @@ void BPF_STRUCT_OPS(fcg_enqueue, struct task_struct *p, u64 enq_flags)
                        scx_bpf_dispatch(p, SCX_DSQ_LOCAL, SCX_SLICE_DFL, enq_flags);
                } else {
                        stat_inc(FCG_STAT_GLOBAL);
-                       scx_bpf_dispatch(p, SCX_DSQ_GLOBAL, SCX_SLICE_DFL, enq_flags);
+                       scx_bpf_dispatch(p, FALLBACK_DSQ, SCX_SLICE_DFL, enq_flags);
                }
                return;
        }
 
-       cgrp = scx_bpf_task_cgroup(p);
+       cgrp = __COMPAT_scx_bpf_task_cgroup(p);
        cgc = find_cgrp_ctx(cgrp);
        if (!cgc)
                goto out_release;
@@ -509,7 +511,7 @@ void BPF_STRUCT_OPS(fcg_runnable, struct task_struct *p, u64 enq_flags)
 {
        struct cgroup *cgrp;
 
-       cgrp = scx_bpf_task_cgroup(p);
+       cgrp = __COMPAT_scx_bpf_task_cgroup(p);
        update_active_weight_sums(cgrp, true);
        bpf_cgroup_release(cgrp);
 }
@@ -522,7 +524,7 @@ void BPF_STRUCT_OPS(fcg_running, struct task_struct *p)
        if (fifo_sched)
                return;
 
-       cgrp = scx_bpf_task_cgroup(p);
+       cgrp = __COMPAT_scx_bpf_task_cgroup(p);
        cgc = find_cgrp_ctx(cgrp);
        if (cgc) {
                /*
@@ -565,7 +567,7 @@ void BPF_STRUCT_OPS(fcg_stopping, struct task_struct *p, bool runnable)
        if (!taskc->bypassed_at)
                return;
 
-       cgrp = scx_bpf_task_cgroup(p);
+       cgrp = __COMPAT_scx_bpf_task_cgroup(p);
        cgc = find_cgrp_ctx(cgrp);
        if (cgc) {
                __sync_fetch_and_add(&cgc->cvtime_delta,
@@ -579,7 +581,7 @@ void BPF_STRUCT_OPS(fcg_quiescent, struct task_struct *p, u64 deq_flags)
 {
        struct cgroup *cgrp;
 
-       cgrp = scx_bpf_task_cgroup(p);
+       cgrp = __COMPAT_scx_bpf_task_cgroup(p);
        update_active_weight_sums(cgrp, false);
        bpf_cgroup_release(cgrp);
 }
@@ -781,7 +783,7 @@ void BPF_STRUCT_OPS(fcg_dispatch, s32 cpu, struct task_struct *prev)
 pick_next_cgroup:
        cpuc->cur_at = now;
 
-       if (scx_bpf_consume(SCX_DSQ_GLOBAL)) {
+       if (scx_bpf_consume(FALLBACK_DSQ)) {
                cpuc->cur_cgid = 0;
                return;
        }
@@ -838,7 +840,7 @@ int BPF_STRUCT_OPS_SLEEPABLE(fcg_cgroup_init, struct cgroup *cgrp,
        int ret;
 
        /*
-        * Technically incorrect as cgroup ID is full 64bit while dq ID is
+        * Technically incorrect as cgroup ID is full 64bit while dsq ID is
         * 63bit. Should not be a problem in practice and easy to spot in the
         * unlikely case that it breaks.
         */
@@ -926,6 +928,11 @@ void BPF_STRUCT_OPS(fcg_cgroup_move, struct task_struct *p,
        p->scx.dsq_vtime = to_cgc->tvtime_now + vtime_delta;
 }
 
+s32 BPF_STRUCT_OPS_SLEEPABLE(fcg_init)
+{
+       return scx_bpf_create_dsq(FALLBACK_DSQ, -1);
+}
+
 void BPF_STRUCT_OPS(fcg_exit, struct scx_exit_info *ei)
 {
        UEI_RECORD(uei, ei);
@@ -944,6 +951,7 @@ SCX_OPS_DEFINE(flatcg_ops,
               .cgroup_init             = (void *)fcg_cgroup_init,
               .cgroup_exit             = (void *)fcg_cgroup_exit,
               .cgroup_move             = (void *)fcg_cgroup_move,
+              .init                    = (void *)fcg_init,
               .exit                    = (void *)fcg_exit,
               .flags                   = SCX_OPS_HAS_CGROUP_WEIGHT | SCX_OPS_ENQ_EXITING,
               .name                    = "flatcg");
index 83c8f54c1e31d896f5c0e793da559db9114ef0e2..5d1f880d1149e76ee47d0b044dc075df62442875 100644 (file)
@@ -230,8 +230,8 @@ void BPF_STRUCT_OPS(qmap_enqueue, struct task_struct *p, u64 enq_flags)
                return;
        }
 
-       /* if !WAKEUP, select_cpu() wasn't called, try direct dispatch */
-       if (!(enq_flags & SCX_ENQ_WAKEUP) &&
+       /* if select_cpu() wasn't called, try direct dispatch */
+       if (!(enq_flags & SCX_ENQ_CPU_SELECTED) &&
            (cpu = pick_direct_dispatch_cpu(p, scx_bpf_task_cpu(p))) >= 0) {
                __sync_fetch_and_add(&nr_ddsp_from_enq, 1);
                scx_bpf_dispatch(p, SCX_DSQ_LOCAL_ON | cpu, slice_ns, enq_flags);
@@ -318,11 +318,11 @@ static bool dispatch_highpri(bool from_timer)
 
                if (tctx->highpri) {
                        /* exercise the set_*() and vtime interface too */
-                       scx_bpf_dispatch_from_dsq_set_slice(
+                       __COMPAT_scx_bpf_dispatch_from_dsq_set_slice(
                                BPF_FOR_EACH_ITER, slice_ns * 2);
-                       scx_bpf_dispatch_from_dsq_set_vtime(
+                       __COMPAT_scx_bpf_dispatch_from_dsq_set_vtime(
                                BPF_FOR_EACH_ITER, highpri_seq++);
-                       scx_bpf_dispatch_vtime_from_dsq(
+                       __COMPAT_scx_bpf_dispatch_vtime_from_dsq(
                                BPF_FOR_EACH_ITER, p, HIGHPRI_DSQ, 0);
                }
        }
@@ -340,9 +340,9 @@ static bool dispatch_highpri(bool from_timer)
                else
                        cpu = scx_bpf_pick_any_cpu(p->cpus_ptr, 0);
 
-               if (scx_bpf_dispatch_from_dsq(BPF_FOR_EACH_ITER, p,
-                                             SCX_DSQ_LOCAL_ON | cpu,
-                                             SCX_ENQ_PREEMPT)) {
+               if (__COMPAT_scx_bpf_dispatch_from_dsq(BPF_FOR_EACH_ITER, p,
+                                                      SCX_DSQ_LOCAL_ON | cpu,
+                                                      SCX_ENQ_PREEMPT)) {
                        if (cpu == this_cpu) {
                                dispatched = true;
                                __sync_fetch_and_add(&nr_expedited_local, 1);
index 90d5afd52dd06b7ce904562c6ebe0813ff273c6b..050725afa45d16202b8e92bf7d280d676592007e 100644 (file)
@@ -693,26 +693,22 @@ static int mock_decoder_commit(struct cxl_decoder *cxld)
        return 0;
 }
 
-static int mock_decoder_reset(struct cxl_decoder *cxld)
+static void mock_decoder_reset(struct cxl_decoder *cxld)
 {
        struct cxl_port *port = to_cxl_port(cxld->dev.parent);
        int id = cxld->id;
 
        if ((cxld->flags & CXL_DECODER_F_ENABLE) == 0)
-               return 0;
+               return;
 
        dev_dbg(&port->dev, "%s reset\n", dev_name(&cxld->dev));
-       if (port->commit_end != id) {
+       if (port->commit_end == id)
+               cxl_port_commit_reap(cxld);
+       else
                dev_dbg(&port->dev,
                        "%s: out of order reset, expected decoder%d.%d\n",
                        dev_name(&cxld->dev), port->id, port->commit_end);
-               return -EBUSY;
-       }
-
-       port->commit_end--;
        cxld->flags &= ~CXL_DECODER_F_ENABLE;
-
-       return 0;
 }
 
 static void default_mock_decoder(struct cxl_decoder *cxld)
@@ -1062,7 +1058,7 @@ static void mock_companion(struct acpi_device *adev, struct device *dev)
 #define SZ_64G (SZ_32G * 2)
 #endif
 
-static __init int cxl_rch_init(void)
+static __init int cxl_rch_topo_init(void)
 {
        int rc, i;
 
@@ -1090,30 +1086,8 @@ static __init int cxl_rch_init(void)
                        goto err_bridge;
        }
 
-       for (i = 0; i < ARRAY_SIZE(cxl_rcd); i++) {
-               int idx = NR_MEM_MULTI + NR_MEM_SINGLE + i;
-               struct platform_device *rch = cxl_rch[i];
-               struct platform_device *pdev;
-
-               pdev = platform_device_alloc("cxl_rcd", idx);
-               if (!pdev)
-                       goto err_mem;
-               pdev->dev.parent = &rch->dev;
-               set_dev_node(&pdev->dev, i % 2);
-
-               rc = platform_device_add(pdev);
-               if (rc) {
-                       platform_device_put(pdev);
-                       goto err_mem;
-               }
-               cxl_rcd[i] = pdev;
-       }
-
        return 0;
 
-err_mem:
-       for (i = ARRAY_SIZE(cxl_rcd) - 1; i >= 0; i--)
-               platform_device_unregister(cxl_rcd[i]);
 err_bridge:
        for (i = ARRAY_SIZE(cxl_rch) - 1; i >= 0; i--) {
                struct platform_device *pdev = cxl_rch[i];
@@ -1127,12 +1101,10 @@ err_bridge:
        return rc;
 }
 
-static void cxl_rch_exit(void)
+static void cxl_rch_topo_exit(void)
 {
        int i;
 
-       for (i = ARRAY_SIZE(cxl_rcd) - 1; i >= 0; i--)
-               platform_device_unregister(cxl_rcd[i]);
        for (i = ARRAY_SIZE(cxl_rch) - 1; i >= 0; i--) {
                struct platform_device *pdev = cxl_rch[i];
 
@@ -1143,7 +1115,7 @@ static void cxl_rch_exit(void)
        }
 }
 
-static __init int cxl_single_init(void)
+static __init int cxl_single_topo_init(void)
 {
        int i, rc;
 
@@ -1228,29 +1200,8 @@ static __init int cxl_single_init(void)
                cxl_swd_single[i] = pdev;
        }
 
-       for (i = 0; i < ARRAY_SIZE(cxl_mem_single); i++) {
-               struct platform_device *dport = cxl_swd_single[i];
-               struct platform_device *pdev;
-
-               pdev = platform_device_alloc("cxl_mem", NR_MEM_MULTI + i);
-               if (!pdev)
-                       goto err_mem;
-               pdev->dev.parent = &dport->dev;
-               set_dev_node(&pdev->dev, i % 2);
-
-               rc = platform_device_add(pdev);
-               if (rc) {
-                       platform_device_put(pdev);
-                       goto err_mem;
-               }
-               cxl_mem_single[i] = pdev;
-       }
-
        return 0;
 
-err_mem:
-       for (i = ARRAY_SIZE(cxl_mem_single) - 1; i >= 0; i--)
-               platform_device_unregister(cxl_mem_single[i]);
 err_dport:
        for (i = ARRAY_SIZE(cxl_swd_single) - 1; i >= 0; i--)
                platform_device_unregister(cxl_swd_single[i]);
@@ -1273,12 +1224,10 @@ err_bridge:
        return rc;
 }
 
-static void cxl_single_exit(void)
+static void cxl_single_topo_exit(void)
 {
        int i;
 
-       for (i = ARRAY_SIZE(cxl_mem_single) - 1; i >= 0; i--)
-               platform_device_unregister(cxl_mem_single[i]);
        for (i = ARRAY_SIZE(cxl_swd_single) - 1; i >= 0; i--)
                platform_device_unregister(cxl_swd_single[i]);
        for (i = ARRAY_SIZE(cxl_swu_single) - 1; i >= 0; i--)
@@ -1295,6 +1244,91 @@ static void cxl_single_exit(void)
        }
 }
 
+static void cxl_mem_exit(void)
+{
+       int i;
+
+       for (i = ARRAY_SIZE(cxl_rcd) - 1; i >= 0; i--)
+               platform_device_unregister(cxl_rcd[i]);
+       for (i = ARRAY_SIZE(cxl_mem_single) - 1; i >= 0; i--)
+               platform_device_unregister(cxl_mem_single[i]);
+       for (i = ARRAY_SIZE(cxl_mem) - 1; i >= 0; i--)
+               platform_device_unregister(cxl_mem[i]);
+}
+
+static int cxl_mem_init(void)
+{
+       int i, rc;
+
+       for (i = 0; i < ARRAY_SIZE(cxl_mem); i++) {
+               struct platform_device *dport = cxl_switch_dport[i];
+               struct platform_device *pdev;
+
+               pdev = platform_device_alloc("cxl_mem", i);
+               if (!pdev)
+                       goto err_mem;
+               pdev->dev.parent = &dport->dev;
+               set_dev_node(&pdev->dev, i % 2);
+
+               rc = platform_device_add(pdev);
+               if (rc) {
+                       platform_device_put(pdev);
+                       goto err_mem;
+               }
+               cxl_mem[i] = pdev;
+       }
+
+       for (i = 0; i < ARRAY_SIZE(cxl_mem_single); i++) {
+               struct platform_device *dport = cxl_swd_single[i];
+               struct platform_device *pdev;
+
+               pdev = platform_device_alloc("cxl_mem", NR_MEM_MULTI + i);
+               if (!pdev)
+                       goto err_single;
+               pdev->dev.parent = &dport->dev;
+               set_dev_node(&pdev->dev, i % 2);
+
+               rc = platform_device_add(pdev);
+               if (rc) {
+                       platform_device_put(pdev);
+                       goto err_single;
+               }
+               cxl_mem_single[i] = pdev;
+       }
+
+       for (i = 0; i < ARRAY_SIZE(cxl_rcd); i++) {
+               int idx = NR_MEM_MULTI + NR_MEM_SINGLE + i;
+               struct platform_device *rch = cxl_rch[i];
+               struct platform_device *pdev;
+
+               pdev = platform_device_alloc("cxl_rcd", idx);
+               if (!pdev)
+                       goto err_rcd;
+               pdev->dev.parent = &rch->dev;
+               set_dev_node(&pdev->dev, i % 2);
+
+               rc = platform_device_add(pdev);
+               if (rc) {
+                       platform_device_put(pdev);
+                       goto err_rcd;
+               }
+               cxl_rcd[i] = pdev;
+       }
+
+       return 0;
+
+err_rcd:
+       for (i = ARRAY_SIZE(cxl_rcd) - 1; i >= 0; i--)
+               platform_device_unregister(cxl_rcd[i]);
+err_single:
+       for (i = ARRAY_SIZE(cxl_mem_single) - 1; i >= 0; i--)
+               platform_device_unregister(cxl_mem_single[i]);
+err_mem:
+       for (i = ARRAY_SIZE(cxl_mem) - 1; i >= 0; i--)
+               platform_device_unregister(cxl_mem[i]);
+       return rc;
+}
+
 static __init int cxl_test_init(void)
 {
        int rc, i;
@@ -1407,29 +1441,11 @@ static __init int cxl_test_init(void)
                cxl_switch_dport[i] = pdev;
        }
 
-       for (i = 0; i < ARRAY_SIZE(cxl_mem); i++) {
-               struct platform_device *dport = cxl_switch_dport[i];
-               struct platform_device *pdev;
-
-               pdev = platform_device_alloc("cxl_mem", i);
-               if (!pdev)
-                       goto err_mem;
-               pdev->dev.parent = &dport->dev;
-               set_dev_node(&pdev->dev, i % 2);
-
-               rc = platform_device_add(pdev);
-               if (rc) {
-                       platform_device_put(pdev);
-                       goto err_mem;
-               }
-               cxl_mem[i] = pdev;
-       }
-
-       rc = cxl_single_init();
+       rc = cxl_single_topo_init();
        if (rc)
-               goto err_mem;
+               goto err_dport;
 
-       rc = cxl_rch_init();
+       rc = cxl_rch_topo_init();
        if (rc)
                goto err_single;
 
@@ -1442,19 +1458,20 @@ static __init int cxl_test_init(void)
 
        rc = platform_device_add(cxl_acpi);
        if (rc)
-               goto err_add;
+               goto err_root;
+
+       rc = cxl_mem_init();
+       if (rc)
+               goto err_root;
 
        return 0;
 
-err_add:
+err_root:
        platform_device_put(cxl_acpi);
 err_rch:
-       cxl_rch_exit();
+       cxl_rch_topo_exit();
 err_single:
-       cxl_single_exit();
-err_mem:
-       for (i = ARRAY_SIZE(cxl_mem) - 1; i >= 0; i--)
-               platform_device_unregister(cxl_mem[i]);
+       cxl_single_topo_exit();
 err_dport:
        for (i = ARRAY_SIZE(cxl_switch_dport) - 1; i >= 0; i--)
                platform_device_unregister(cxl_switch_dport[i]);
@@ -1486,11 +1503,10 @@ static __exit void cxl_test_exit(void)
 {
        int i;
 
+       cxl_mem_exit();
        platform_device_unregister(cxl_acpi);
-       cxl_rch_exit();
-       cxl_single_exit();
-       for (i = ARRAY_SIZE(cxl_mem) - 1; i >= 0; i--)
-               platform_device_unregister(cxl_mem[i]);
+       cxl_rch_topo_exit();
+       cxl_single_topo_exit();
        for (i = ARRAY_SIZE(cxl_switch_dport) - 1; i >= 0; i--)
                platform_device_unregister(cxl_switch_dport[i]);
        for (i = ARRAY_SIZE(cxl_switch_uport) - 1; i >= 0; i--)
index ccdd6a5042226b1e3020dc65e116489aa1fc6efe..71916e0e1546e8f7e1034482e68b28c4edc5a2ea 100644 (file)
@@ -9,7 +9,7 @@
 #include <linux/sizes.h>
 #include <linux/bits.h>
 #include <cxl/mailbox.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
 #include <crypto/sha2.h>
 #include <cxlmem.h>
 
@@ -1673,6 +1673,7 @@ static struct platform_driver cxl_mock_mem_driver = {
                .name = KBUILD_MODNAME,
                .dev_groups = cxl_mock_mem_groups,
                .groups = cxl_mock_mem_core_groups,
+               .probe_type = PROBE_PREFER_ASYNCHRONOUS,
        },
 };
 
index 1873ddbe16cc9339bf9bfba834b059672bd932f3..551ae6898c1d2dd7d05c446e5956f7e168ba1c9c 100644 (file)
@@ -36317,6 +36317,28 @@ static inline int check_vma_modification(struct maple_tree *mt)
        return 0;
 }
 
+/*
+ * test to check that bulk stores do not use wr_rebalance as the store
+ * type.
+ */
+static inline void check_bulk_rebalance(struct maple_tree *mt)
+{
+       MA_STATE(mas, mt, ULONG_MAX, ULONG_MAX);
+       int max = 10;
+
+       build_full_tree(mt, 0, 2);
+
+       /* erase every entry in the tree */
+       do {
+               /* set up bulk store mode */
+               mas_expected_entries(&mas, max);
+               mas_erase(&mas);
+               MT_BUG_ON(mt, mas.store_type == wr_rebalance);
+       } while (mas_prev(&mas, 0) != NULL);
+
+       mas_destroy(&mas);
+}
+
 void farmer_tests(void)
 {
        struct maple_node *node;
@@ -36328,6 +36350,10 @@ void farmer_tests(void)
        check_vma_modification(&tree);
        mtree_destroy(&tree);
 
+       mt_init(&tree);
+       check_bulk_rebalance(&tree);
+       mtree_destroy(&tree);
+
        tree.ma_root = xa_mk_value(0);
        mt_dump(&tree, mt_dump_dec);
 
@@ -36406,9 +36432,93 @@ void farmer_tests(void)
        check_nomem(&tree);
 }
 
+static unsigned long get_last_index(struct ma_state *mas)
+{
+       struct maple_node *node = mas_mn(mas);
+       enum maple_type mt = mte_node_type(mas->node);
+       unsigned long *pivots = ma_pivots(node, mt);
+       unsigned long last_index = mas_data_end(mas);
+
+       BUG_ON(last_index == 0);
+
+       return pivots[last_index - 1] + 1;
+}
+
+/*
+ * Assert that we handle spanning stores that consume the entirety of the right
+ * leaf node correctly.
+ */
+static void test_spanning_store_regression(void)
+{
+       unsigned long from = 0, to = 0;
+       DEFINE_MTREE(tree);
+       MA_STATE(mas, &tree, 0, 0);
+
+       /*
+        * Build a 3-level tree. We require a parent node below the root node
+        * and 2 leaf nodes under it, so we can span the entirety of the right
+        * hand node.
+        */
+       build_full_tree(&tree, 0, 3);
+
+       /* Descend into position at depth 2. */
+       mas_reset(&mas);
+       mas_start(&mas);
+       mas_descend(&mas);
+       mas_descend(&mas);
+
+       /*
+        * We need to establish a tree like the below.
+        *
+        * Then we can try a store in [from, to] which results in a spanned
+        * store across nodes B and C, with the maple state at the time of the
+        * write being such that only the subtree at A and below is considered.
+        *
+        * Height
+        *  0                              Root Node
+        *                                  /      \
+        *                    pivot = to   /        \ pivot = ULONG_MAX
+        *                                /          \
+        *   1                       A [-----]       ...
+        *                              /   \
+        *                pivot = from /     \ pivot = to
+        *                            /       \
+        *   2 (LEAVES)          B [-----]  [-----] C
+        *                                       ^--- Last pivot to.
+        */
+       while (true) {
+               unsigned long tmp = get_last_index(&mas);
+
+               if (mas_next_sibling(&mas)) {
+                       from = tmp;
+                       to = mas.max;
+               } else {
+                       break;
+               }
+       }
+
+       BUG_ON(from == 0 && to == 0);
+
+       /* Perform the store. */
+       mas_set_range(&mas, from, to);
+       mas_store_gfp(&mas, xa_mk_value(0xdead), GFP_KERNEL);
+
+       /* If the regression occurs, the validation will fail. */
+       mt_validate(&tree);
+
+       /* Cleanup. */
+       __mt_destroy(&tree);
+}
+
+static void regression_tests(void)
+{
+       test_spanning_store_regression();
+}
+
 void maple_tree_tests(void)
 {
 #if !defined(BENCH)
+       regression_tests();
        farmer_tests();
 #endif
        maple_tree_seed();
index b38199965f99014f3e2636fe8d705972f2c0d148..363d031a16f7e14152c904e6b68dab1f90c98392 100644 (file)
@@ -88,6 +88,7 @@ TARGETS += rlimits
 TARGETS += rseq
 TARGETS += rtc
 TARGETS += rust
+TARGETS += sched_ext
 TARGETS += seccomp
 TARGETS += sgx
 TARGETS += sigaltstack
@@ -129,10 +130,10 @@ ifeq ($(filter net/lib,$(TARGETS)),)
 endif
 endif
 
-# User can optionally provide a TARGETS skiplist.  By default we skip
-# BPF since it has cutting edge build time dependencies which require
-# more effort to install.
-SKIP_TARGETS ?= bpf
+# User can optionally provide a TARGETS skiplist. By default we skip
+# targets using BPF since it has cutting edge build time dependencies
+# which require more effort to install.
+SKIP_TARGETS ?= bpf sched_ext
 ifneq ($(SKIP_TARGETS),)
        TMP := $(filter-out $(SKIP_TARGETS), $(TARGETS))
        override TARGETS := $(TMP)
index 25be6802529083de0b7e13ba279a83a7a8bf740e..944279160fed269c479b5b5793c8008b16c0c519 100644 (file)
@@ -1,5 +1,9 @@
 # SPDX-License-Identifier: GPL-2.0
 #
+ifneq ($(shell pkg-config --exists alsa && echo 0 || echo 1),0)
+$(error Package alsa not found, please install alsa development package or \
+       add directory containing `alsa.pc` in PKG_CONFIG_PATH)
+endif
 
 CFLAGS += $(shell pkg-config --cflags alsa) $(KHDR_INCLUDES)
 LDLIBS += $(shell pkg-config --libs alsa)
index f04af11df8eb5a1cecd75a4864d45c669433df61..75016962f79563d65138ec10e669a81858106ec4 100644 (file)
@@ -157,7 +157,8 @@ TEST_GEN_PROGS_EXTENDED = \
        flow_dissector_load test_flow_dissector test_tcp_check_syncookie_user \
        test_lirc_mode2_user xdping test_cpp runqslower bench bpf_testmod.ko \
        xskxceiver xdp_redirect_multi xdp_synproxy veristat xdp_hw_metadata \
-       xdp_features bpf_test_no_cfi.ko
+       xdp_features bpf_test_no_cfi.ko bpf_test_modorder_x.ko \
+       bpf_test_modorder_y.ko
 
 TEST_GEN_FILES += liburandom_read.so urandom_read sign-file uprobe_multi
 
@@ -263,7 +264,7 @@ $(OUTPUT)/%:%.c
 ifeq ($(SRCARCH),$(filter $(SRCARCH),x86 riscv))
 LLD := lld
 else
-LLD := ld
+LLD := $(shell command -v $(LD))
 endif
 
 # Filter out -static for liburandom_read.so and its dependent targets so that static builds
@@ -303,6 +304,19 @@ $(OUTPUT)/bpf_test_no_cfi.ko: $(VMLINUX_BTF) $(RESOLVE_BTFIDS) $(wildcard bpf_te
        $(Q)$(MAKE) $(submake_extras) RESOLVE_BTFIDS=$(RESOLVE_BTFIDS) -C bpf_test_no_cfi
        $(Q)cp bpf_test_no_cfi/bpf_test_no_cfi.ko $@
 
+$(OUTPUT)/bpf_test_modorder_x.ko: $(VMLINUX_BTF) $(RESOLVE_BTFIDS) $(wildcard bpf_test_modorder_x/Makefile bpf_test_modorder_x/*.[ch])
+       $(call msg,MOD,,$@)
+       $(Q)$(RM) bpf_test_modorder_x/bpf_test_modorder_x.ko # force re-compilation
+       $(Q)$(MAKE) $(submake_extras) RESOLVE_BTFIDS=$(RESOLVE_BTFIDS) -C bpf_test_modorder_x
+       $(Q)cp bpf_test_modorder_x/bpf_test_modorder_x.ko $@
+
+$(OUTPUT)/bpf_test_modorder_y.ko: $(VMLINUX_BTF) $(RESOLVE_BTFIDS) $(wildcard bpf_test_modorder_y/Makefile bpf_test_modorder_y/*.[ch])
+       $(call msg,MOD,,$@)
+       $(Q)$(RM) bpf_test_modorder_y/bpf_test_modorder_y.ko # force re-compilation
+       $(Q)$(MAKE) $(submake_extras) RESOLVE_BTFIDS=$(RESOLVE_BTFIDS) -C bpf_test_modorder_y
+       $(Q)cp bpf_test_modorder_y/bpf_test_modorder_y.ko $@
+
+
 DEFAULT_BPFTOOL := $(HOST_SCRATCH_DIR)/sbin/bpftool
 ifneq ($(CROSS_COMPILE),)
 CROSS_BPFTOOL := $(SCRATCH_DIR)/sbin/bpftool
@@ -722,6 +736,8 @@ TRUNNER_EXTRA_SOURCES := test_progs.c               \
                         ip_check_defrag_frags.h
 TRUNNER_EXTRA_FILES := $(OUTPUT)/urandom_read $(OUTPUT)/bpf_testmod.ko \
                       $(OUTPUT)/bpf_test_no_cfi.ko                     \
+                      $(OUTPUT)/bpf_test_modorder_x.ko         \
+                      $(OUTPUT)/bpf_test_modorder_y.ko         \
                       $(OUTPUT)/liburandom_read.so                     \
                       $(OUTPUT)/xdp_synproxy                           \
                       $(OUTPUT)/sign-file                              \
@@ -856,6 +872,8 @@ EXTRA_CLEAN := $(SCRATCH_DIR) $(HOST_SCRATCH_DIR)                   \
        $(addprefix $(OUTPUT)/,*.o *.d *.skel.h *.lskel.h *.subskel.h   \
                               no_alu32 cpuv4 bpf_gcc bpf_testmod.ko    \
                               bpf_test_no_cfi.ko                       \
+                              bpf_test_modorder_x.ko                   \
+                              bpf_test_modorder_y.ko                   \
                               liburandom_read.so)                      \
        $(OUTPUT)/FEATURE-DUMP.selftests
 
diff --git a/tools/testing/selftests/bpf/bpf_test_modorder_x/Makefile b/tools/testing/selftests/bpf/bpf_test_modorder_x/Makefile
new file mode 100644 (file)
index 0000000..40b25b9
--- /dev/null
@@ -0,0 +1,19 @@
+BPF_TESTMOD_DIR := $(realpath $(dir $(abspath $(lastword $(MAKEFILE_LIST)))))
+KDIR ?= $(abspath $(BPF_TESTMOD_DIR)/../../../../..)
+
+ifeq ($(V),1)
+Q =
+else
+Q = @
+endif
+
+MODULES = bpf_test_modorder_x.ko
+
+obj-m += bpf_test_modorder_x.o
+
+all:
+       +$(Q)make -C $(KDIR) M=$(BPF_TESTMOD_DIR) modules
+
+clean:
+       +$(Q)make -C $(KDIR) M=$(BPF_TESTMOD_DIR) clean
+
diff --git a/tools/testing/selftests/bpf/bpf_test_modorder_x/bpf_test_modorder_x.c b/tools/testing/selftests/bpf/bpf_test_modorder_x/bpf_test_modorder_x.c
new file mode 100644 (file)
index 0000000..0cc747f
--- /dev/null
@@ -0,0 +1,39 @@
+// SPDX-License-Identifier: GPL-2.0
+#include <linux/bpf.h>
+#include <linux/btf.h>
+#include <linux/module.h>
+#include <linux/init.h>
+
+__bpf_kfunc_start_defs();
+
+__bpf_kfunc int bpf_test_modorder_retx(void)
+{
+       return 'x';
+}
+
+__bpf_kfunc_end_defs();
+
+BTF_KFUNCS_START(bpf_test_modorder_kfunc_x_ids)
+BTF_ID_FLAGS(func, bpf_test_modorder_retx);
+BTF_KFUNCS_END(bpf_test_modorder_kfunc_x_ids)
+
+static const struct btf_kfunc_id_set bpf_test_modorder_x_set = {
+       .owner = THIS_MODULE,
+       .set = &bpf_test_modorder_kfunc_x_ids,
+};
+
+static int __init bpf_test_modorder_x_init(void)
+{
+       return register_btf_kfunc_id_set(BPF_PROG_TYPE_SCHED_CLS,
+                                        &bpf_test_modorder_x_set);
+}
+
+static void __exit bpf_test_modorder_x_exit(void)
+{
+}
+
+module_init(bpf_test_modorder_x_init);
+module_exit(bpf_test_modorder_x_exit);
+
+MODULE_DESCRIPTION("BPF selftest ordertest module X");
+MODULE_LICENSE("GPL");
diff --git a/tools/testing/selftests/bpf/bpf_test_modorder_y/Makefile b/tools/testing/selftests/bpf/bpf_test_modorder_y/Makefile
new file mode 100644 (file)
index 0000000..52c3ab9
--- /dev/null
@@ -0,0 +1,19 @@
+BPF_TESTMOD_DIR := $(realpath $(dir $(abspath $(lastword $(MAKEFILE_LIST)))))
+KDIR ?= $(abspath $(BPF_TESTMOD_DIR)/../../../../..)
+
+ifeq ($(V),1)
+Q =
+else
+Q = @
+endif
+
+MODULES = bpf_test_modorder_y.ko
+
+obj-m += bpf_test_modorder_y.o
+
+all:
+       +$(Q)make -C $(KDIR) M=$(BPF_TESTMOD_DIR) modules
+
+clean:
+       +$(Q)make -C $(KDIR) M=$(BPF_TESTMOD_DIR) clean
+
diff --git a/tools/testing/selftests/bpf/bpf_test_modorder_y/bpf_test_modorder_y.c b/tools/testing/selftests/bpf/bpf_test_modorder_y/bpf_test_modorder_y.c
new file mode 100644 (file)
index 0000000..c627ee0
--- /dev/null
@@ -0,0 +1,39 @@
+// SPDX-License-Identifier: GPL-2.0
+#include <linux/bpf.h>
+#include <linux/btf.h>
+#include <linux/module.h>
+#include <linux/init.h>
+
+__bpf_kfunc_start_defs();
+
+__bpf_kfunc int bpf_test_modorder_rety(void)
+{
+       return 'y';
+}
+
+__bpf_kfunc_end_defs();
+
+BTF_KFUNCS_START(bpf_test_modorder_kfunc_y_ids)
+BTF_ID_FLAGS(func, bpf_test_modorder_rety);
+BTF_KFUNCS_END(bpf_test_modorder_kfunc_y_ids)
+
+static const struct btf_kfunc_id_set bpf_test_modorder_y_set = {
+       .owner = THIS_MODULE,
+       .set = &bpf_test_modorder_kfunc_y_ids,
+};
+
+static int __init bpf_test_modorder_y_init(void)
+{
+       return register_btf_kfunc_id_set(BPF_PROG_TYPE_SCHED_CLS,
+                                        &bpf_test_modorder_y_set);
+}
+
+static void __exit bpf_test_modorder_y_exit(void)
+{
+}
+
+module_init(bpf_test_modorder_y_init);
+module_exit(bpf_test_modorder_y_exit);
+
+MODULE_DESCRIPTION("BPF selftest ordertest module Y");
+MODULE_LICENSE("GPL");
diff --git a/tools/testing/selftests/bpf/map_tests/lpm_trie_map_get_next_key.c b/tools/testing/selftests/bpf/map_tests/lpm_trie_map_get_next_key.c
new file mode 100644 (file)
index 0000000..0ba0156
--- /dev/null
@@ -0,0 +1,109 @@
+// SPDX-License-Identifier: GPL-2.0
+
+#define _GNU_SOURCE
+#include <linux/bpf.h>
+#include <stdio.h>
+#include <stdbool.h>
+#include <unistd.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <string.h>
+#include <pthread.h>
+
+#include <bpf/bpf.h>
+#include <bpf/libbpf.h>
+
+#include <test_maps.h>
+
+struct test_lpm_key {
+       __u32 prefix;
+       __u32 data;
+};
+
+struct get_next_key_ctx {
+       struct test_lpm_key key;
+       bool start;
+       bool stop;
+       int map_fd;
+       int loop;
+};
+
+static void *get_next_key_fn(void *arg)
+{
+       struct get_next_key_ctx *ctx = arg;
+       struct test_lpm_key next_key;
+       int i = 0;
+
+       while (!ctx->start)
+               usleep(1);
+
+       while (!ctx->stop && i++ < ctx->loop)
+               bpf_map_get_next_key(ctx->map_fd, &ctx->key, &next_key);
+
+       return NULL;
+}
+
+static void abort_get_next_key(struct get_next_key_ctx *ctx, pthread_t *tids,
+                              unsigned int nr)
+{
+       unsigned int i;
+
+       ctx->stop = true;
+       ctx->start = true;
+       for (i = 0; i < nr; i++)
+               pthread_join(tids[i], NULL);
+}
+
+/* This test aims to prevent regression of future. As long as the kernel does
+ * not panic, it is considered as success.
+ */
+void test_lpm_trie_map_get_next_key(void)
+{
+#define MAX_NR_THREADS 8
+       LIBBPF_OPTS(bpf_map_create_opts, create_opts,
+                   .map_flags = BPF_F_NO_PREALLOC);
+       struct test_lpm_key key = {};
+       __u32 val = 0;
+       int map_fd;
+       const __u32 max_prefixlen = 8 * (sizeof(key) - sizeof(key.prefix));
+       const __u32 max_entries = max_prefixlen + 1;
+       unsigned int i, nr = MAX_NR_THREADS, loop = 65536;
+       pthread_t tids[MAX_NR_THREADS];
+       struct get_next_key_ctx ctx;
+       int err;
+
+       map_fd = bpf_map_create(BPF_MAP_TYPE_LPM_TRIE, "lpm_trie_map",
+                               sizeof(struct test_lpm_key), sizeof(__u32),
+                               max_entries, &create_opts);
+       CHECK(map_fd == -1, "bpf_map_create()", "error:%s\n",
+             strerror(errno));
+
+       for (i = 0; i <= max_prefixlen; i++) {
+               key.prefix = i;
+               err = bpf_map_update_elem(map_fd, &key, &val, BPF_ANY);
+               CHECK(err, "bpf_map_update_elem()", "error:%s\n",
+                     strerror(errno));
+       }
+
+       ctx.start = false;
+       ctx.stop = false;
+       ctx.map_fd = map_fd;
+       ctx.loop = loop;
+       memcpy(&ctx.key, &key, sizeof(key));
+
+       for (i = 0; i < nr; i++) {
+               err = pthread_create(&tids[i], NULL, get_next_key_fn, &ctx);
+               if (err) {
+                       abort_get_next_key(&ctx, tids, i);
+                       CHECK(err, "pthread_create", "error %d\n", err);
+               }
+       }
+
+       ctx.start = true;
+       for (i = 0; i < nr; i++)
+               pthread_join(tids[i], NULL);
+
+       printf("%s:PASS\n", __func__);
+
+       close(map_fd);
+}
index 52e6f757047528aae5c3e778f3e387c777edc2ad..f0a3a9c18e9ef5641a8fb59387ebad2068bdc35f 100644 (file)
@@ -226,7 +226,7 @@ static void test_task_common_nocheck(struct bpf_iter_attach_opts *opts,
        ASSERT_OK(pthread_create(&thread_id, NULL, &do_nothing_wait, NULL),
                  "pthread_create");
 
-       skel->bss->tid = getpid();
+       skel->bss->tid = gettid();
 
        do_dummy_read_opts(skel->progs.dump_task, opts);
 
@@ -249,25 +249,42 @@ static void test_task_common(struct bpf_iter_attach_opts *opts, int num_unknown,
        ASSERT_EQ(num_known_tid, num_known, "check_num_known_tid");
 }
 
-static void test_task_tid(void)
+static void *run_test_task_tid(void *arg)
 {
        LIBBPF_OPTS(bpf_iter_attach_opts, opts);
        union bpf_iter_link_info linfo;
        int num_unknown_tid, num_known_tid;
 
+       ASSERT_NEQ(getpid(), gettid(), "check_new_thread_id");
+
        memset(&linfo, 0, sizeof(linfo));
-       linfo.task.tid = getpid();
+       linfo.task.tid = gettid();
        opts.link_info = &linfo;
        opts.link_info_len = sizeof(linfo);
        test_task_common(&opts, 0, 1);
 
        linfo.task.tid = 0;
        linfo.task.pid = getpid();
-       test_task_common(&opts, 1, 1);
+       /* This includes the parent thread, this thread,
+        * and the do_nothing_wait thread
+        */
+       test_task_common(&opts, 2, 1);
 
        test_task_common_nocheck(NULL, &num_unknown_tid, &num_known_tid);
-       ASSERT_GT(num_unknown_tid, 1, "check_num_unknown_tid");
+       ASSERT_GT(num_unknown_tid, 2, "check_num_unknown_tid");
        ASSERT_EQ(num_known_tid, 1, "check_num_known_tid");
+
+       return NULL;
+}
+
+static void test_task_tid(void)
+{
+       pthread_t thread_id;
+
+       /* Create a new thread so pid and tid aren't the same */
+       ASSERT_OK(pthread_create(&thread_id, NULL, &run_test_task_tid, NULL),
+                 "pthread_create");
+       ASSERT_FALSE(pthread_join(thread_id, NULL), "pthread_join");
 }
 
 static void test_task_pid(void)
index 9250a1e9f9afc88da5f4af9142a39c80dce527d6..3f9ffdf7134315c178ea0c5a7e9a1ccf4d0f8d8c 100644 (file)
@@ -35,7 +35,7 @@ static int send_datagram(void)
        if (!ASSERT_OK_FD(sock, "create socket"))
                return sock;
 
-       if (!ASSERT_OK(connect(sock, &addr, sizeof(addr)), "connect")) {
+       if (!ASSERT_OK(connect(sock, (struct sockaddr *)&addr, sizeof(addr)), "connect")) {
                close(sock);
                return -1;
        }
index 2570bd4b0cb228d3cdb9aae05a22cb4cb5534758..e58a04654238c9b4d1d366f9f0537675910cc153 100644 (file)
@@ -23,6 +23,7 @@ static const char * const cpumask_success_testcases[] = {
        "test_global_mask_array_l2_rcu",
        "test_global_mask_nested_rcu",
        "test_global_mask_nested_deep_rcu",
+       "test_global_mask_nested_deep_array_rcu",
        "test_cpumask_weight",
 };
 
index f3932941bbaafc6b559e6af099cfdfc2bb19d131..d50cbd8040d45fdb51cef51d087f3c8813926a1e 100644 (file)
@@ -67,8 +67,9 @@ again:
 
                ASSERT_EQ(info.perf_event.kprobe.cookie, PERF_EVENT_COOKIE, "kprobe_cookie");
 
+               ASSERT_EQ(info.perf_event.kprobe.name_len, strlen(KPROBE_FUNC) + 1,
+                                 "name_len");
                if (!info.perf_event.kprobe.func_name) {
-                       ASSERT_EQ(info.perf_event.kprobe.name_len, 0, "name_len");
                        info.perf_event.kprobe.func_name = ptr_to_u64(&buf);
                        info.perf_event.kprobe.name_len = sizeof(buf);
                        goto again;
@@ -79,8 +80,9 @@ again:
                ASSERT_EQ(err, 0, "cmp_kprobe_func_name");
                break;
        case BPF_PERF_EVENT_TRACEPOINT:
+               ASSERT_EQ(info.perf_event.tracepoint.name_len, strlen(TP_NAME) + 1,
+                                 "name_len");
                if (!info.perf_event.tracepoint.tp_name) {
-                       ASSERT_EQ(info.perf_event.tracepoint.name_len, 0, "name_len");
                        info.perf_event.tracepoint.tp_name = ptr_to_u64(&buf);
                        info.perf_event.tracepoint.name_len = sizeof(buf);
                        goto again;
@@ -96,8 +98,9 @@ again:
        case BPF_PERF_EVENT_URETPROBE:
                ASSERT_EQ(info.perf_event.uprobe.offset, offset, "uprobe_offset");
 
+               ASSERT_EQ(info.perf_event.uprobe.name_len, strlen(UPROBE_FILE) + 1,
+                                 "name_len");
                if (!info.perf_event.uprobe.file_name) {
-                       ASSERT_EQ(info.perf_event.uprobe.name_len, 0, "name_len");
                        info.perf_event.uprobe.file_name = ptr_to_u64(&buf);
                        info.perf_event.uprobe.name_len = sizeof(buf);
                        goto again;
@@ -417,6 +420,15 @@ verify_umulti_link_info(int fd, bool retprobe, __u64 *offsets,
        if (!ASSERT_NEQ(err, -1, "readlink"))
                return -1;
 
+       memset(&info, 0, sizeof(info));
+       err = bpf_link_get_info_by_fd(fd, &info, &len);
+       if (!ASSERT_OK(err, "bpf_link_get_info_by_fd"))
+               return -1;
+
+       ASSERT_EQ(info.uprobe_multi.count, 3, "info.uprobe_multi.count");
+       ASSERT_EQ(info.uprobe_multi.path_size, strlen(path) + 1,
+                 "info.uprobe_multi.path_size");
+
        for (bit = 0; bit < 8; bit++) {
                memset(&info, 0, sizeof(info));
                info.uprobe_multi.path = ptr_to_u64(path_buf);
diff --git a/tools/testing/selftests/bpf/prog_tests/kfunc_module_order.c b/tools/testing/selftests/bpf/prog_tests/kfunc_module_order.c
new file mode 100644 (file)
index 0000000..48c0560
--- /dev/null
@@ -0,0 +1,55 @@
+// SPDX-License-Identifier: GPL-2.0
+#include <test_progs.h>
+#include <testing_helpers.h>
+
+#include "kfunc_module_order.skel.h"
+
+static int test_run_prog(const struct bpf_program *prog,
+                        struct bpf_test_run_opts *opts)
+{
+       int err;
+
+       err = bpf_prog_test_run_opts(bpf_program__fd(prog), opts);
+       if (!ASSERT_OK(err, "bpf_prog_test_run_opts"))
+               return err;
+
+       if (!ASSERT_EQ((int)opts->retval, 0, bpf_program__name(prog)))
+               return -EINVAL;
+
+       return 0;
+}
+
+void test_kfunc_module_order(void)
+{
+       struct kfunc_module_order *skel;
+       char pkt_data[64] = {};
+       int err = 0;
+
+       DECLARE_LIBBPF_OPTS(bpf_test_run_opts, test_opts, .data_in = pkt_data,
+                           .data_size_in = sizeof(pkt_data));
+
+       err = load_module("bpf_test_modorder_x.ko",
+                         env_verbosity > VERBOSE_NONE);
+       if (!ASSERT_OK(err, "load bpf_test_modorder_x.ko"))
+               return;
+
+       err = load_module("bpf_test_modorder_y.ko",
+                         env_verbosity > VERBOSE_NONE);
+       if (!ASSERT_OK(err, "load bpf_test_modorder_y.ko"))
+               goto exit_modx;
+
+       skel = kfunc_module_order__open_and_load();
+       if (!ASSERT_OK_PTR(skel, "kfunc_module_order__open_and_load()")) {
+               err = -EINVAL;
+               goto exit_mods;
+       }
+
+       test_run_prog(skel->progs.call_kfunc_xy, &test_opts);
+       test_run_prog(skel->progs.call_kfunc_yx, &test_opts);
+
+       kfunc_module_order__destroy(skel);
+exit_mods:
+       unload_module("bpf_test_modorder_y", env_verbosity > VERBOSE_NONE);
+exit_modx:
+       unload_module("bpf_test_modorder_x", env_verbosity > VERBOSE_NONE);
+}
index 4297a2a4cb11b1edb83ad8f1649d932de2c4d024..2f52fa2641baf53c2335f7375d367e86c3164b5c 100644 (file)
@@ -26,10 +26,43 @@ static const struct nf_link_test nf_hook_link_tests[] = {
 
        { .pf = NFPROTO_INET, .priority = 1, .name = "invalid-inet-not-supported", },
 
-       { .pf = NFPROTO_IPV4, .priority = -10000, .expect_success = true, .name = "attach ipv4", },
-       { .pf = NFPROTO_IPV6, .priority =  10001, .expect_success = true, .name = "attach ipv6", },
+       {
+               .pf = NFPROTO_IPV4,
+               .hooknum = NF_INET_POST_ROUTING,
+               .priority = -10000,
+               .flags = 0,
+               .expect_success = true,
+               .name = "attach ipv4",
+       },
+       {
+               .pf = NFPROTO_IPV6,
+               .hooknum = NF_INET_FORWARD,
+               .priority =  10001,
+               .flags = BPF_F_NETFILTER_IP_DEFRAG,
+               .expect_success = true,
+               .name = "attach ipv6",
+       },
 };
 
+static void verify_netfilter_link_info(struct bpf_link *link, const struct nf_link_test nf_expected)
+{
+       struct bpf_link_info info;
+       __u32 len = sizeof(info);
+       int err, fd;
+
+       memset(&info, 0, len);
+
+       fd = bpf_link__fd(link);
+       err = bpf_link_get_info_by_fd(fd, &info, &len);
+       ASSERT_OK(err, "get_link_info");
+
+       ASSERT_EQ(info.type, BPF_LINK_TYPE_NETFILTER, "info link type");
+       ASSERT_EQ(info.netfilter.pf, nf_expected.pf, "info nf protocol family");
+       ASSERT_EQ(info.netfilter.hooknum, nf_expected.hooknum, "info nf hooknum");
+       ASSERT_EQ(info.netfilter.priority, nf_expected.priority, "info nf priority");
+       ASSERT_EQ(info.netfilter.flags, nf_expected.flags, "info nf flags");
+}
+
 void test_netfilter_link_attach(void)
 {
        struct test_netfilter_link_attach *skel;
@@ -64,6 +97,8 @@ void test_netfilter_link_attach(void)
                        if (!ASSERT_OK_PTR(link, "program attach successful"))
                                continue;
 
+                       verify_netfilter_link_info(link, nf_hook_link_tests[i]);
+
                        link2 = bpf_program__attach_netfilter(prog, &opts);
                        ASSERT_ERR_PTR(link2, "attach program with same pf/hook/priority");
 
@@ -73,6 +108,9 @@ void test_netfilter_link_attach(void)
                        link2 = bpf_program__attach_netfilter(prog, &opts);
                        if (!ASSERT_OK_PTR(link2, "program reattach successful"))
                                continue;
+
+                       verify_netfilter_link_info(link2, nf_hook_link_tests[i]);
+
                        if (!ASSERT_OK(bpf_link__destroy(link2), "link destroy"))
                                break;
                } else {
index e26b5150fc43403a834a0564229472b3257acf45..75f7a2ce334b11f2e9ad119dff67f6e2d112f57e 100644 (file)
@@ -44,6 +44,7 @@
 #include "verifier_ld_ind.skel.h"
 #include "verifier_ldsx.skel.h"
 #include "verifier_leak_ptr.skel.h"
+#include "verifier_linked_scalars.skel.h"
 #include "verifier_loops1.skel.h"
 #include "verifier_lwt.skel.h"
 #include "verifier_map_in_map.skel.h"
@@ -53,6 +54,7 @@
 #include "verifier_masking.skel.h"
 #include "verifier_meta_access.skel.h"
 #include "verifier_movsx.skel.h"
+#include "verifier_mtu.skel.h"
 #include "verifier_netfilter_ctx.skel.h"
 #include "verifier_netfilter_retcode.skel.h"
 #include "verifier_bpf_fastcall.skel.h"
@@ -170,6 +172,7 @@ void test_verifier_jit_convergence(void)      { RUN(verifier_jit_convergence); }
 void test_verifier_ld_ind(void)               { RUN(verifier_ld_ind); }
 void test_verifier_ldsx(void)                  { RUN(verifier_ldsx); }
 void test_verifier_leak_ptr(void)             { RUN(verifier_leak_ptr); }
+void test_verifier_linked_scalars(void)       { RUN(verifier_linked_scalars); }
 void test_verifier_loops1(void)               { RUN(verifier_loops1); }
 void test_verifier_lwt(void)                  { RUN(verifier_lwt); }
 void test_verifier_map_in_map(void)           { RUN(verifier_map_in_map); }
@@ -221,6 +224,24 @@ void test_verifier_xdp_direct_packet_access(void) { RUN(verifier_xdp_direct_pack
 void test_verifier_bits_iter(void) { RUN(verifier_bits_iter); }
 void test_verifier_lsm(void)                  { RUN(verifier_lsm); }
 
+void test_verifier_mtu(void)
+{
+       __u64 caps = 0;
+       int ret;
+
+       /* In case CAP_BPF and CAP_PERFMON is not set */
+       ret = cap_enable_effective(1ULL << CAP_BPF | 1ULL << CAP_NET_ADMIN, &caps);
+       if (!ASSERT_OK(ret, "set_cap_bpf_cap_net_admin"))
+               return;
+       ret = cap_disable_effective(1ULL << CAP_SYS_ADMIN | 1ULL << CAP_PERFMON, NULL);
+       if (!ASSERT_OK(ret, "disable_cap_sys_admin"))
+               goto restore_cap;
+       RUN(verifier_mtu);
+restore_cap:
+       if (caps)
+               cap_enable_effective(caps, NULL);
+}
+
 static int init_test_val_map(struct bpf_object *obj, char *map_name)
 {
        struct test_val value = {
index ce6812558287a415d2b1ee42058ccb84ff490a1d..27ffed17d4be33fab8776baa1dd1a6055e7194bf 100644 (file)
@@ -1,6 +1,9 @@
 // SPDX-License-Identifier: GPL-2.0
+#include <arpa/inet.h>
 #include <uapi/linux/bpf.h>
 #include <linux/if_link.h>
+#include <network_helpers.h>
+#include <net/if.h>
 #include <test_progs.h>
 
 #include "test_xdp_devmap_helpers.skel.h"
 #include "test_xdp_with_devmap_helpers.skel.h"
 
 #define IFINDEX_LO 1
+#define TEST_NS "devmap_attach_ns"
 
 static void test_xdp_with_devmap_helpers(void)
 {
-       struct test_xdp_with_devmap_helpers *skel;
+       struct test_xdp_with_devmap_helpers *skel = NULL;
        struct bpf_prog_info info = {};
        struct bpf_devmap_val val = {
                .ifindex = IFINDEX_LO,
        };
        __u32 len = sizeof(info);
-       int err, dm_fd, map_fd;
+       int err, dm_fd, dm_fd_redir, map_fd;
+       struct nstoken *nstoken = NULL;
+       char data[10] = {};
        __u32 idx = 0;
 
+       SYS(out_close, "ip netns add %s", TEST_NS);
+       nstoken = open_netns(TEST_NS);
+       if (!ASSERT_OK_PTR(nstoken, "open_netns"))
+               goto out_close;
+       SYS(out_close, "ip link set dev lo up");
 
        skel = test_xdp_with_devmap_helpers__open_and_load();
        if (!ASSERT_OK_PTR(skel, "test_xdp_with_devmap_helpers__open_and_load"))
-               return;
+               goto out_close;
 
-       dm_fd = bpf_program__fd(skel->progs.xdp_redir_prog);
-       err = bpf_xdp_attach(IFINDEX_LO, dm_fd, XDP_FLAGS_SKB_MODE, NULL);
+       dm_fd_redir = bpf_program__fd(skel->progs.xdp_redir_prog);
+       err = bpf_xdp_attach(IFINDEX_LO, dm_fd_redir, XDP_FLAGS_SKB_MODE, NULL);
        if (!ASSERT_OK(err, "Generic attach of program with 8-byte devmap"))
                goto out_close;
 
-       err = bpf_xdp_detach(IFINDEX_LO, XDP_FLAGS_SKB_MODE, NULL);
-       ASSERT_OK(err, "XDP program detach");
-
        dm_fd = bpf_program__fd(skel->progs.xdp_dummy_dm);
        map_fd = bpf_map__fd(skel->maps.dm_ports);
        err = bpf_prog_get_info_by_fd(dm_fd, &info, &len);
@@ -47,6 +55,22 @@ static void test_xdp_with_devmap_helpers(void)
        ASSERT_OK(err, "Read devmap entry");
        ASSERT_EQ(info.id, val.bpf_prog.id, "Match program id to devmap entry prog_id");
 
+       /* send a packet to trigger any potential bugs in there */
+       DECLARE_LIBBPF_OPTS(bpf_test_run_opts, opts,
+                           .data_in = &data,
+                           .data_size_in = 10,
+                           .flags = BPF_F_TEST_XDP_LIVE_FRAMES,
+                           .repeat = 1,
+               );
+       err = bpf_prog_test_run_opts(dm_fd_redir, &opts);
+       ASSERT_OK(err, "XDP test run");
+
+       /* wait for the packets to be flushed */
+       kern_sync_rcu();
+
+       err = bpf_xdp_detach(IFINDEX_LO, XDP_FLAGS_SKB_MODE, NULL);
+       ASSERT_OK(err, "XDP program detach");
+
        /* can not attach BPF_XDP_DEVMAP program to a device */
        err = bpf_xdp_attach(IFINDEX_LO, dm_fd, XDP_FLAGS_SKB_MODE, NULL);
        if (!ASSERT_NEQ(err, 0, "Attach of BPF_XDP_DEVMAP program"))
@@ -67,6 +91,8 @@ static void test_xdp_with_devmap_helpers(void)
        ASSERT_NEQ(err, 0, "Add BPF_XDP program with frags to devmap entry");
 
 out_close:
+       close_netns(nstoken);
+       SYS_NOFAIL("ip netns del %s", TEST_NS);
        test_xdp_with_devmap_helpers__destroy(skel);
 }
 
@@ -124,6 +150,86 @@ out_close:
        test_xdp_with_devmap_frags_helpers__destroy(skel);
 }
 
+static void test_xdp_with_devmap_helpers_veth(void)
+{
+       struct test_xdp_with_devmap_helpers *skel = NULL;
+       struct bpf_prog_info info = {};
+       struct bpf_devmap_val val = {};
+       struct nstoken *nstoken = NULL;
+       __u32 len = sizeof(info);
+       int err, dm_fd, dm_fd_redir, map_fd, ifindex_dst;
+       char data[10] = {};
+       __u32 idx = 0;
+
+       SYS(out_close, "ip netns add %s", TEST_NS);
+       nstoken = open_netns(TEST_NS);
+       if (!ASSERT_OK_PTR(nstoken, "open_netns"))
+               goto out_close;
+
+       SYS(out_close, "ip link add veth_src type veth peer name veth_dst");
+       SYS(out_close, "ip link set dev veth_src up");
+       SYS(out_close, "ip link set dev veth_dst up");
+
+       val.ifindex = if_nametoindex("veth_src");
+       ifindex_dst = if_nametoindex("veth_dst");
+       if (!ASSERT_NEQ(val.ifindex, 0, "val.ifindex") ||
+           !ASSERT_NEQ(ifindex_dst, 0, "ifindex_dst"))
+               goto out_close;
+
+       skel = test_xdp_with_devmap_helpers__open_and_load();
+       if (!ASSERT_OK_PTR(skel, "test_xdp_with_devmap_helpers__open_and_load"))
+               goto out_close;
+
+       dm_fd_redir = bpf_program__fd(skel->progs.xdp_redir_prog);
+       err = bpf_xdp_attach(val.ifindex, dm_fd_redir, XDP_FLAGS_DRV_MODE, NULL);
+       if (!ASSERT_OK(err, "Attach of program with 8-byte devmap"))
+               goto out_close;
+
+       dm_fd = bpf_program__fd(skel->progs.xdp_dummy_dm);
+       map_fd = bpf_map__fd(skel->maps.dm_ports);
+       err = bpf_prog_get_info_by_fd(dm_fd, &info, &len);
+       if (!ASSERT_OK(err, "bpf_prog_get_info_by_fd"))
+               goto out_close;
+
+       val.bpf_prog.fd = dm_fd;
+       err = bpf_map_update_elem(map_fd, &idx, &val, 0);
+       ASSERT_OK(err, "Add program to devmap entry");
+
+       err = bpf_map_lookup_elem(map_fd, &idx, &val);
+       ASSERT_OK(err, "Read devmap entry");
+       ASSERT_EQ(info.id, val.bpf_prog.id, "Match program id to devmap entry prog_id");
+
+       /* attach dummy to other side to enable reception */
+       dm_fd = bpf_program__fd(skel->progs.xdp_dummy_prog);
+       err = bpf_xdp_attach(ifindex_dst, dm_fd, XDP_FLAGS_DRV_MODE, NULL);
+       if (!ASSERT_OK(err, "Attach of dummy XDP"))
+               goto out_close;
+
+       /* send a packet to trigger any potential bugs in there */
+       DECLARE_LIBBPF_OPTS(bpf_test_run_opts, opts,
+                           .data_in = &data,
+                           .data_size_in = 10,
+                           .flags = BPF_F_TEST_XDP_LIVE_FRAMES,
+                           .repeat = 1,
+               );
+       err = bpf_prog_test_run_opts(dm_fd_redir, &opts);
+       ASSERT_OK(err, "XDP test run");
+
+       /* wait for the packets to be flushed */
+       kern_sync_rcu();
+
+       err = bpf_xdp_detach(val.ifindex, XDP_FLAGS_DRV_MODE, NULL);
+       ASSERT_OK(err, "XDP program detach");
+
+       err = bpf_xdp_detach(ifindex_dst, XDP_FLAGS_DRV_MODE, NULL);
+       ASSERT_OK(err, "XDP program detach");
+
+out_close:
+       close_netns(nstoken);
+       SYS_NOFAIL("ip netns del %s", TEST_NS);
+       test_xdp_with_devmap_helpers__destroy(skel);
+}
+
 void serial_test_xdp_devmap_attach(void)
 {
        if (test__start_subtest("DEVMAP with programs in entries"))
@@ -134,4 +240,7 @@ void serial_test_xdp_devmap_attach(void)
 
        if (test__start_subtest("Verifier check of DEVMAP programs"))
                test_neg_xdp_devmap_helpers();
+
+       if (test__start_subtest("DEVMAP with programs in entries on veth"))
+               test_xdp_with_devmap_helpers_veth();
 }
index b979e91f55f07906736f12746b9c1e58d84b29c6..4ece7873ba609d3e86e7aeb2f6337ab561e59f68 100644 (file)
@@ -7,6 +7,11 @@
 #include "errno.h"
 #include <stdbool.h>
 
+/* Should use BTF_FIELDS_MAX, but it is not always available in vmlinux.h,
+ * so use the hard-coded number as a workaround.
+ */
+#define CPUMASK_KPTR_FIELDS_MAX 11
+
 int err;
 
 #define private(name) SEC(".bss." #name) __attribute__((aligned(8)))
index a988d2823b5285a3c6b40b636135b74529ce013f..b40b52548ffb0ef6a6391e78cb20feff23bc70d3 100644 (file)
 
 char _license[] SEC("license") = "GPL";
 
+struct kptr_nested_array_2 {
+       struct bpf_cpumask __kptr * mask;
+};
+
+struct kptr_nested_array_1 {
+       /* Make btf_parse_fields() in map_create() return -E2BIG */
+       struct kptr_nested_array_2 d_2[CPUMASK_KPTR_FIELDS_MAX + 1];
+};
+
+struct kptr_nested_array {
+       struct kptr_nested_array_1 d_1;
+};
+
+private(MASK_NESTED) static struct kptr_nested_array global_mask_nested_arr;
+
 /* Prototype for all of the program trace events below:
  *
  * TRACE_EVENT(task_newtask,
@@ -187,3 +202,23 @@ int BPF_PROG(test_global_mask_rcu_no_null_check, struct task_struct *task, u64 c
 
        return 0;
 }
+
+SEC("tp_btf/task_newtask")
+__failure __msg("has no valid kptr")
+int BPF_PROG(test_invalid_nested_array, struct task_struct *task, u64 clone_flags)
+{
+       struct bpf_cpumask *local, *prev;
+
+       local = create_cpumask();
+       if (!local)
+               return 0;
+
+       prev = bpf_kptr_xchg(&global_mask_nested_arr.d_1.d_2[CPUMASK_KPTR_FIELDS_MAX].mask, local);
+       if (prev) {
+               bpf_cpumask_release(prev);
+               err = 3;
+               return 0;
+       }
+
+       return 0;
+}
index fd8106831c32c356a5a494b09f374a55221e1133..80ee469b0b6028634308f05df383471bc6bcec70 100644 (file)
@@ -31,11 +31,59 @@ struct kptr_nested_deep {
        struct kptr_nested_pair ptr_pairs[3];
 };
 
+struct kptr_nested_deep_array_1_2 {
+       int dummy;
+       struct bpf_cpumask __kptr * mask[CPUMASK_KPTR_FIELDS_MAX];
+};
+
+struct kptr_nested_deep_array_1_1 {
+       int dummy;
+       struct kptr_nested_deep_array_1_2 d_2;
+};
+
+struct kptr_nested_deep_array_1 {
+       long dummy;
+       struct kptr_nested_deep_array_1_1 d_1;
+};
+
+struct kptr_nested_deep_array_2_2 {
+       long dummy[2];
+       struct bpf_cpumask __kptr * mask;
+};
+
+struct kptr_nested_deep_array_2_1 {
+       int dummy;
+       struct kptr_nested_deep_array_2_2 d_2[CPUMASK_KPTR_FIELDS_MAX];
+};
+
+struct kptr_nested_deep_array_2 {
+       long dummy;
+       struct kptr_nested_deep_array_2_1 d_1;
+};
+
+struct kptr_nested_deep_array_3_2 {
+       long dummy[2];
+       struct bpf_cpumask __kptr * mask;
+};
+
+struct kptr_nested_deep_array_3_1 {
+       int dummy;
+       struct kptr_nested_deep_array_3_2 d_2;
+};
+
+struct kptr_nested_deep_array_3 {
+       long dummy;
+       struct kptr_nested_deep_array_3_1 d_1[CPUMASK_KPTR_FIELDS_MAX];
+};
+
 private(MASK) static struct bpf_cpumask __kptr * global_mask_array[2];
 private(MASK) static struct bpf_cpumask __kptr * global_mask_array_l2[2][1];
 private(MASK) static struct bpf_cpumask __kptr * global_mask_array_one[1];
 private(MASK) static struct kptr_nested global_mask_nested[2];
 private(MASK_DEEP) static struct kptr_nested_deep global_mask_nested_deep;
+private(MASK_1) static struct kptr_nested_deep_array_1 global_mask_nested_deep_array_1;
+private(MASK_2) static struct kptr_nested_deep_array_2 global_mask_nested_deep_array_2;
+private(MASK_3) static struct kptr_nested_deep_array_3 global_mask_nested_deep_array_3;
 
 static bool is_test_task(void)
 {
@@ -543,12 +591,21 @@ static int _global_mask_array_rcu(struct bpf_cpumask **mask0,
                goto err_exit;
        }
 
-       /* [<mask 0>, NULL] */
-       if (!*mask0 || *mask1) {
+       /* [<mask 0>, *] */
+       if (!*mask0) {
                err = 2;
                goto err_exit;
        }
 
+       if (!mask1)
+               goto err_exit;
+
+       /* [*, NULL] */
+       if (*mask1) {
+               err = 3;
+               goto err_exit;
+       }
+
        local = create_cpumask();
        if (!local) {
                err = 9;
@@ -631,6 +688,23 @@ int BPF_PROG(test_global_mask_nested_deep_rcu, struct task_struct *task, u64 clo
        return 0;
 }
 
+SEC("tp_btf/task_newtask")
+int BPF_PROG(test_global_mask_nested_deep_array_rcu, struct task_struct *task, u64 clone_flags)
+{
+       int i;
+
+       for (i = 0; i < CPUMASK_KPTR_FIELDS_MAX; i++)
+               _global_mask_array_rcu(&global_mask_nested_deep_array_1.d_1.d_2.mask[i], NULL);
+
+       for (i = 0; i < CPUMASK_KPTR_FIELDS_MAX; i++)
+               _global_mask_array_rcu(&global_mask_nested_deep_array_2.d_1.d_2[i].mask, NULL);
+
+       for (i = 0; i < CPUMASK_KPTR_FIELDS_MAX; i++)
+               _global_mask_array_rcu(&global_mask_nested_deep_array_3.d_1[i].d_2.mask, NULL);
+
+       return 0;
+}
+
 SEC("tp_btf/task_newtask")
 int BPF_PROG(test_cpumask_weight, struct task_struct *task, u64 clone_flags)
 {
diff --git a/tools/testing/selftests/bpf/progs/kfunc_module_order.c b/tools/testing/selftests/bpf/progs/kfunc_module_order.c
new file mode 100644 (file)
index 0000000..76003d0
--- /dev/null
@@ -0,0 +1,30 @@
+// SPDX-License-Identifier: GPL-2.0
+#include <linux/bpf.h>
+#include <bpf/bpf_helpers.h>
+
+extern int bpf_test_modorder_retx(void) __ksym;
+extern int bpf_test_modorder_rety(void) __ksym;
+
+SEC("classifier")
+int call_kfunc_xy(struct __sk_buff *skb)
+{
+       int ret1, ret2;
+
+       ret1 = bpf_test_modorder_retx();
+       ret2 = bpf_test_modorder_rety();
+
+       return ret1 == 'x' && ret2 == 'y' ? 0 : -1;
+}
+
+SEC("classifier")
+int call_kfunc_yx(struct __sk_buff *skb)
+{
+       int ret1, ret2;
+
+       ret1 = bpf_test_modorder_rety();
+       ret2 = bpf_test_modorder_retx();
+
+       return ret1 == 'y' && ret2 == 'x' ? 0 : -1;
+}
+
+char _license[] SEC("license") = "GPL";
index f8b1b7e68d2edc44b297173b9a9b19f0808e91c1..34024de6337ea8a47ecda10635d2d325dd465c06 100644 (file)
@@ -22,7 +22,7 @@
                __builtin_memcpy(b, __tmp, sizeof(a));  \
        } while (0)
 
-/* asm-generic/unaligned.h */
+/* linux/unaligned.h */
 #define __get_unaligned_t(type, ptr) ({                                                \
        const struct { type x; } __packed * __pptr = (typeof(__pptr))(ptr);     \
        __pptr->x;                                                              \
index 4139a14f9996723780e866842490ee6cc905b823..92b65a485d4a9725f01e99671c7399656f04f4f4 100644 (file)
@@ -12,7 +12,7 @@ struct {
 SEC("xdp")
 int xdp_redir_prog(struct xdp_md *ctx)
 {
-       return bpf_redirect_map(&dm_ports, 1, 0);
+       return bpf_redirect_map(&dm_ports, 0, 0);
 }
 
 /* invalid program on DEVMAP entry;
index f4da4d508ddb9d9474fb8e7036e663613d4db645..156cc278e2fc9ce791003d4c7fb6412c5b080f03 100644 (file)
@@ -15,6 +15,8 @@ int bpf_iter_bits_new(struct bpf_iter_bits *it, const u64 *unsafe_ptr__ign,
 int *bpf_iter_bits_next(struct bpf_iter_bits *it) __ksym __weak;
 void bpf_iter_bits_destroy(struct bpf_iter_bits *it) __ksym __weak;
 
+u64 bits_array[511] = {};
+
 SEC("iter.s/cgroup")
 __description("bits iter without destroy")
 __failure __msg("Unreleased reference")
@@ -110,16 +112,16 @@ int bit_index(void)
 }
 
 SEC("syscall")
-__description("bits nomem")
+__description("bits too big")
 __success __retval(0)
-int bits_nomem(void)
+int bits_too_big(void)
 {
        u64 data[4];
        int nr = 0;
        int *bit;
 
        __builtin_memset(&data, 0xff, sizeof(data));
-       bpf_for_each(bits, bit, &data[0], 513) /* Be greater than 512 */
+       bpf_for_each(bits, bit, &data[0], 512) /* Be greater than 511 */
                nr++;
        return nr;
 }
@@ -151,3 +153,56 @@ int zero_words(void)
                nr++;
        return nr;
 }
+
+SEC("syscall")
+__description("huge words")
+__success __retval(0)
+int huge_words(void)
+{
+       u64 data[8] = {0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1};
+       int nr = 0;
+       int *bit;
+
+       bpf_for_each(bits, bit, &data[0], 67108865)
+               nr++;
+       return nr;
+}
+
+SEC("syscall")
+__description("max words")
+__success __retval(4)
+int max_words(void)
+{
+       volatile int nr = 0;
+       int *bit;
+
+       bits_array[0] = (1ULL << 63) | 1U;
+       bits_array[510] = (1ULL << 33) | (1ULL << 32);
+
+       bpf_for_each(bits, bit, bits_array, 511) {
+               if (nr == 0 && *bit != 0)
+                       break;
+               if (nr == 2 && *bit != 32672)
+                       break;
+               nr++;
+       }
+       return nr;
+}
+
+SEC("syscall")
+__description("bad words")
+__success __retval(0)
+int bad_words(void)
+{
+       void *bad_addr = (void *)(3UL << 30);
+       int nr = 0;
+       int *bit;
+
+       bpf_for_each(bits, bit, bad_addr, 1)
+               nr++;
+
+       bpf_for_each(bits, bit, bad_addr, 4)
+               nr++;
+
+       return nr;
+}
index 9da97d2efcd9e3ba936982a4e9be677f8ee93007..5094c288cfd7bc889199fcb8234088bda3437ac5 100644 (file)
@@ -790,61 +790,6 @@ __naked static void cumulative_stack_depth_subprog(void)
        :: __imm(bpf_get_smp_processor_id) : __clobber_all);
 }
 
-SEC("raw_tp")
-__arch_x86_64
-__log_level(4)
-__msg("stack depth 512")
-__xlated("0: r1 = 42")
-__xlated("1: *(u64 *)(r10 -512) = r1")
-__xlated("2: w0 = ")
-__xlated("3: r0 = &(void __percpu *)(r0)")
-__xlated("4: r0 = *(u32 *)(r0 +0)")
-__xlated("5: exit")
-__success
-__naked int bpf_fastcall_max_stack_ok(void)
-{
-       asm volatile(
-       "r1 = 42;"
-       "*(u64 *)(r10 - %[max_bpf_stack]) = r1;"
-       "*(u64 *)(r10 - %[max_bpf_stack_8]) = r1;"
-       "call %[bpf_get_smp_processor_id];"
-       "r1 = *(u64 *)(r10 - %[max_bpf_stack_8]);"
-       "exit;"
-       :
-       : __imm_const(max_bpf_stack, MAX_BPF_STACK),
-         __imm_const(max_bpf_stack_8, MAX_BPF_STACK + 8),
-         __imm(bpf_get_smp_processor_id)
-       : __clobber_all
-       );
-}
-
-SEC("raw_tp")
-__arch_x86_64
-__log_level(4)
-__msg("stack depth 520")
-__failure
-__naked int bpf_fastcall_max_stack_fail(void)
-{
-       asm volatile(
-       "r1 = 42;"
-       "*(u64 *)(r10 - %[max_bpf_stack]) = r1;"
-       "*(u64 *)(r10 - %[max_bpf_stack_8]) = r1;"
-       "call %[bpf_get_smp_processor_id];"
-       "r1 = *(u64 *)(r10 - %[max_bpf_stack_8]);"
-       /* call to prandom blocks bpf_fastcall rewrite */
-       "*(u64 *)(r10 - %[max_bpf_stack_8]) = r1;"
-       "call %[bpf_get_prandom_u32];"
-       "r1 = *(u64 *)(r10 - %[max_bpf_stack_8]);"
-       "exit;"
-       :
-       : __imm_const(max_bpf_stack, MAX_BPF_STACK),
-         __imm_const(max_bpf_stack_8, MAX_BPF_STACK + 8),
-         __imm(bpf_get_smp_processor_id),
-         __imm(bpf_get_prandom_u32)
-       : __clobber_all
-       );
-}
-
 SEC("cgroup/getsockname_unix")
 __xlated("0: r2 = 1")
 /* bpf_cast_to_kern_ctx is replaced by a single assignment */
index 2e533d7eec2f12233d15039c41c27e16008902e5..e118dbb768bfca0d196af492ed5ce4ed66b9f9d8 100644 (file)
@@ -1,8 +1,9 @@
 // SPDX-License-Identifier: GPL-2.0
 /* Copyright (c) 2024 Isovalent */
 
-#include <linux/bpf.h>
+#include "vmlinux.h"
 #include <bpf/bpf_helpers.h>
+#include <bpf/bpf_tracing.h>
 #include "bpf_misc.h"
 
 const volatile long foo = 42;
@@ -66,4 +67,32 @@ int tcx6(struct __sk_buff *skb)
        return TCX_PASS;
 }
 
+static inline void write_fixed(volatile void *p, __u32 val)
+{
+       *(volatile __u32 *)p = val;
+}
+
+static inline void write_dyn(void *p, void *val, int len)
+{
+       bpf_copy_from_user(p, len, val);
+}
+
+SEC("tc/ingress")
+__description("rodata/mark: write with unknown reg rejected")
+__failure __msg("write into map forbidden")
+int tcx7(struct __sk_buff *skb)
+{
+       write_fixed((void *)&foo, skb->mark);
+       return TCX_PASS;
+}
+
+SEC("lsm.s/bprm_committed_creds")
+__description("rodata/mark: write with unknown reg rejected")
+__failure __msg("write into map forbidden")
+int BPF_PROG(bprm, struct linux_binprm *bprm)
+{
+       write_dyn((void *)&foo, &bart, bpf_get_prandom_u32() & 3);
+       return 0;
+}
+
 char LICENSE[] SEC("license") = "GPL";
diff --git a/tools/testing/selftests/bpf/progs/verifier_linked_scalars.c b/tools/testing/selftests/bpf/progs/verifier_linked_scalars.c
new file mode 100644 (file)
index 0000000..8f755d2
--- /dev/null
@@ -0,0 +1,34 @@
+// SPDX-License-Identifier: GPL-2.0
+
+#include <linux/bpf.h>
+#include <bpf/bpf_helpers.h>
+#include "bpf_misc.h"
+
+SEC("socket")
+__description("scalars: find linked scalars")
+__failure
+__msg("math between fp pointer and 2147483647 is not allowed")
+__naked void scalars(void)
+{
+       asm volatile ("                         \
+       r0 = 0;                                 \
+       r1 = 0x80000001 ll;                     \
+       r1 /= 1;                                \
+       r2 = r1;                                \
+       r4 = r1;                                \
+       w2 += 0x7FFFFFFF;                       \
+       w4 += 0;                                \
+       if r2 == 0 goto l1;                     \
+       exit;                                   \
+l1:                                            \
+       r4 >>= 63;                              \
+       r3 = 1;                                 \
+       r3 -= r4;                               \
+       r3 *= 0x7FFFFFFF;                       \
+       r3 += r10;                              \
+       *(u8*)(r3 - 1) = r0;                    \
+       exit;                                   \
+"      ::: __clobber_all);
+}
+
+char _license[] SEC("license") = "GPL";
index 028ec855587bea6c0313f5b35698a6d6dfda3534..994bbc346d25d7d37c678bdbf2290ff297ec7af1 100644 (file)
@@ -287,6 +287,46 @@ l0_%=:                                                     \
        : __clobber_all);
 }
 
+SEC("socket")
+__description("MOV64SX, S8, unsigned range_check")
+__success __retval(0)
+__naked void mov64sx_s8_range_check(void)
+{
+       asm volatile ("                                 \
+       call %[bpf_get_prandom_u32];                    \
+       r0 &= 0x1;                                      \
+       r0 += 0xfe;                                     \
+       r0 = (s8)r0;                                    \
+       if r0 < 0xfffffffffffffffe goto label_%=;       \
+       r0 = 0;                                         \
+       exit;                                           \
+label_%=:                                              \
+       exit;                                           \
+"      :
+       : __imm(bpf_get_prandom_u32)
+       : __clobber_all);
+}
+
+SEC("socket")
+__description("MOV32SX, S8, unsigned range_check")
+__success __retval(0)
+__naked void mov32sx_s8_range_check(void)
+{
+       asm volatile ("                                 \
+       call %[bpf_get_prandom_u32];                    \
+       w0 &= 0x1;                                      \
+       w0 += 0xfe;                                     \
+       w0 = (s8)w0;                                    \
+       if w0 < 0xfffffffe goto label_%=;               \
+       r0 = 0;                                         \
+       exit;                                           \
+label_%=:                                              \
+       exit;                                           \
+       "      :
+       : __imm(bpf_get_prandom_u32)
+       : __clobber_all);
+}
+
 #else
 
 SEC("socket")
diff --git a/tools/testing/selftests/bpf/progs/verifier_mtu.c b/tools/testing/selftests/bpf/progs/verifier_mtu.c
new file mode 100644 (file)
index 0000000..70c7600
--- /dev/null
@@ -0,0 +1,18 @@
+// SPDX-License-Identifier: GPL-2.0
+
+#include "vmlinux.h"
+#include <bpf/bpf_helpers.h>
+#include "bpf_misc.h"
+
+SEC("tc/ingress")
+__description("uninit/mtu: write rejected")
+__failure __msg("invalid indirect read from stack")
+int tc_uninit_mtu(struct __sk_buff *ctx)
+{
+       __u32 mtu;
+
+       bpf_check_mtu(ctx, 0, &mtu, 0, 0);
+       return TCX_PASS;
+}
+
+char LICENSE[] SEC("license") = "GPL";
index 2ecf77b623e04c959d8d73a24ac2e37630535371..7c5e5e6d10ebc2387a69ba01a3d34a35ca7a824f 100644 (file)
@@ -760,4 +760,71 @@ __naked void two_old_ids_one_cur_id(void)
        : __clobber_all);
 }
 
+SEC("socket")
+/* Note the flag, see verifier.c:opt_subreg_zext_lo32_rnd_hi32() */
+__flag(BPF_F_TEST_RND_HI32)
+__success
+/* This test was added because of a bug in verifier.c:sync_linked_regs(),
+ * upon range propagation it destroyed subreg_def marks for registers.
+ * The subreg_def mark is used to decide whether zero extension instructions
+ * are needed when register is read. When BPF_F_TEST_RND_HI32 is set it
+ * also causes generation of statements to randomize upper halves of
+ * read registers.
+ *
+ * The test is written in a way to return an upper half of a register
+ * that is affected by range propagation and must have it's subreg_def
+ * preserved. This gives a return value of 0 and leads to undefined
+ * return value if subreg_def mark is not preserved.
+ */
+__retval(0)
+/* Check that verifier believes r1/r0 are zero at exit */
+__log_level(2)
+__msg("4: (77) r1 >>= 32                     ; R1_w=0")
+__msg("5: (bf) r0 = r1                       ; R0_w=0 R1_w=0")
+__msg("6: (95) exit")
+__msg("from 3 to 4")
+__msg("4: (77) r1 >>= 32                     ; R1_w=0")
+__msg("5: (bf) r0 = r1                       ; R0_w=0 R1_w=0")
+__msg("6: (95) exit")
+/* Verify that statements to randomize upper half of r1 had not been
+ * generated.
+ */
+__xlated("call unknown")
+__xlated("r0 &= 2147483647")
+__xlated("w1 = w0")
+/* This is how disasm.c prints BPF_ZEXT_REG at the moment, x86 and arm
+ * are the only CI archs that do not need zero extension for subregs.
+ */
+#if !defined(__TARGET_ARCH_x86) && !defined(__TARGET_ARCH_arm64)
+__xlated("w1 = w1")
+#endif
+__xlated("if w0 < 0xa goto pc+0")
+__xlated("r1 >>= 32")
+__xlated("r0 = r1")
+__xlated("exit")
+__naked void linked_regs_and_subreg_def(void)
+{
+       asm volatile (
+       "call %[bpf_ktime_get_ns];"
+       /* make sure r0 is in 32-bit range, otherwise w1 = w0 won't
+        * assign same IDs to registers.
+        */
+       "r0 &= 0x7fffffff;"
+       /* link w1 and w0 via ID */
+       "w1 = w0;"
+       /* 'if' statement propagates range info from w0 to w1,
+        * but should not affect w1->subreg_def property.
+        */
+       "if w0 < 10 goto +0;"
+       /* r1 is read here, on archs that require subreg zero
+        * extension this would cause zext patch generation.
+        */
+       "r1 >>= 32;"
+       "r0 = r1;"
+       "exit;"
+       :
+       : __imm(bpf_ktime_get_ns)
+       : __clobber_all);
+}
+
 char _license[] SEC("license") = "GPL";
index 5a14498d352f3ef9760f536f0b46ff05aef0b1f1..f40e57251e9419a9ea6a8639e2befce8d68747ee 100644 (file)
@@ -2,6 +2,7 @@
 /* Converted from tools/testing/selftests/bpf/verifier/search_pruning.c */
 
 #include <linux/bpf.h>
+#include <../../../include/linux/filter.h>
 #include <bpf/bpf_helpers.h>
 #include "bpf_misc.h"
 
@@ -336,4 +337,26 @@ l0_%=:     r1 = 42;                                        \
        : __clobber_all);
 }
 
+/* Without checkpoint forcibly inserted at the back-edge a loop this
+ * test would take a very long time to verify.
+ */
+SEC("kprobe")
+__failure __log_level(4)
+__msg("BPF program is too large.")
+__naked void short_loop1(void)
+{
+       asm volatile (
+       "   r7 = *(u16 *)(r1 +0);"
+       "1: r7 += 0x1ab064b9;"
+       "   .8byte %[jset];" /* same as 'if r7 & 0x702000 goto 1b;' */
+       "   r7 &= 0x1ee60e;"
+       "   r7 += r1;"
+       "   if r7 s> 0x37d2 goto +0;"
+       "   r0 = 0;"
+       "   exit;"
+       :
+       : __imm_insn(jset, BPF_JMP_IMM(BPF_JSET, BPF_REG_7, 0x702000, -2))
+       : __clobber_all);
+}
+
 char _license[] SEC("license") = "GPL";
index d3c3c3a24150f99abd13ecb7d7b11d8f7351560d..5e9f16683be5460b1a295fb9754df761cbd090ea 100644 (file)
@@ -367,7 +367,7 @@ int delete_module(const char *name, int flags)
        return syscall(__NR_delete_module, name, flags);
 }
 
-int unload_bpf_testmod(bool verbose)
+int unload_module(const char *name, bool verbose)
 {
        int ret, cnt = 0;
 
@@ -375,11 +375,11 @@ int unload_bpf_testmod(bool verbose)
                fprintf(stdout, "Failed to trigger kernel-side RCU sync!\n");
 
        for (;;) {
-               ret = delete_module("bpf_testmod", 0);
+               ret = delete_module(name, 0);
                if (!ret || errno != EAGAIN)
                        break;
                if (++cnt > 10000) {
-                       fprintf(stdout, "Unload of bpf_testmod timed out\n");
+                       fprintf(stdout, "Unload of %s timed out\n", name);
                        break;
                }
                usleep(100);
@@ -388,41 +388,51 @@ int unload_bpf_testmod(bool verbose)
        if (ret) {
                if (errno == ENOENT) {
                        if (verbose)
-                               fprintf(stdout, "bpf_testmod.ko is already unloaded.\n");
+                               fprintf(stdout, "%s.ko is already unloaded.\n", name);
                        return -1;
                }
-               fprintf(stdout, "Failed to unload bpf_testmod.ko from kernel: %d\n", -errno);
+               fprintf(stdout, "Failed to unload %s.ko from kernel: %d\n", name, -errno);
                return -1;
        }
        if (verbose)
-               fprintf(stdout, "Successfully unloaded bpf_testmod.ko.\n");
+               fprintf(stdout, "Successfully unloaded %s.ko.\n", name);
        return 0;
 }
 
-int load_bpf_testmod(bool verbose)
+int load_module(const char *path, bool verbose)
 {
        int fd;
 
        if (verbose)
-               fprintf(stdout, "Loading bpf_testmod.ko...\n");
+               fprintf(stdout, "Loading %s...\n", path);
 
-       fd = open("bpf_testmod.ko", O_RDONLY);
+       fd = open(path, O_RDONLY);
        if (fd < 0) {
-               fprintf(stdout, "Can't find bpf_testmod.ko kernel module: %d\n", -errno);
+               fprintf(stdout, "Can't find %s kernel module: %d\n", path, -errno);
                return -ENOENT;
        }
        if (finit_module(fd, "", 0)) {
-               fprintf(stdout, "Failed to load bpf_testmod.ko into the kernel: %d\n", -errno);
+               fprintf(stdout, "Failed to load %s into the kernel: %d\n", path, -errno);
                close(fd);
                return -EINVAL;
        }
        close(fd);
 
        if (verbose)
-               fprintf(stdout, "Successfully loaded bpf_testmod.ko.\n");
+               fprintf(stdout, "Successfully loaded %s.\n", path);
        return 0;
 }
 
+int unload_bpf_testmod(bool verbose)
+{
+       return unload_module("bpf_testmod", verbose);
+}
+
+int load_bpf_testmod(bool verbose)
+{
+       return load_module("bpf_testmod.ko", verbose);
+}
+
 /*
  * Trigger synchronize_rcu() in kernel.
  */
index d55f6ab124338ccab33bc120ca7e3baa18264aea..46d7f7089f636b0d2476859fd0fa5e1c4b305419 100644 (file)
@@ -38,6 +38,8 @@ int unload_bpf_testmod(bool verbose);
 int kern_sync_rcu(void);
 int finit_module(int fd, const char *param_values, int flags);
 int delete_module(const char *name, int flags);
+int load_module(const char *path, bool verbose);
+int unload_module(const char *name, bool verbose);
 
 static inline __u64 get_time_ns(void)
 {
index 1a385061618d849aeeb08ff39da331618c13db89..e661ffdcaadff187b2100306bde2df91c16ea8aa 100644 (file)
@@ -15,3 +15,4 @@ test_usdt*
 test_verif_scale*
 test_xdp_noinline*
 xdp_synproxy*
+verifier_search_pruning*
index dfec31fb9b30d14f327c54e1e3312657414211f8..8d275f03e977f508c40b5bcff9b53bf267dd8962 100644 (file)
@@ -152,7 +152,10 @@ void suspend(void)
        if (err < 0)
                ksft_exit_fail_msg("timerfd_settime() failed\n");
 
-       if (write(power_state_fd, "mem", strlen("mem")) != strlen("mem"))
+       system("(echo mem > /sys/power/state) 2> /dev/null");
+
+       timerfd_gettime(timerfd, &spec);
+       if (spec.it_value.tv_sec != 0 || spec.it_value.tv_nsec != 0)
                ksft_exit_fail_msg("Failed to enter Suspend state\n");
 
        close(timerfd);
index 31b56d6256550b62aca41495f6d716d17cd5f54a..3c196fa86c992324b69087b91378ae20c7fc8895 100644 (file)
@@ -27,8 +27,6 @@
 #include "../kselftest_harness.h"
 #include "clone3_selftests.h"
 
-#define MAX_PID_NS_LEVEL 32
-
 static void child_exit(int ret)
 {
        fflush(stdout);
index 6e6712ce5817d6e9af5bfc369ef2c8e2a68b491a..7999361992aa84e67b3f5cbe66fb2d8136a4a438 100644 (file)
@@ -1 +1,2 @@
 close_range_test
+unshare_test
index d94a74b8a054874f862fa27a1e527f3dbde84d34..d7a2bb91c807968927e1412ee3814f14e87018a3 100755 (executable)
@@ -45,7 +45,7 @@ def find_pci_controller_dirs():
 
 
 def find_usb_controller_dirs():
-    usb_controller_sysfs_dir = "usb[\d]+"
+    usb_controller_sysfs_dir = r"usb[\d]+"
 
     dir_regex = re.compile(usb_controller_sysfs_dir)
     for d in os.scandir(sysfs_usb_devices):
@@ -91,7 +91,7 @@ def get_acpi_uid(sysfs_dev_dir):
 
 
 def get_usb_version(sysfs_dev_dir):
-    re_usb_version = re.compile("PRODUCT=.*/(\d)/.*")
+    re_usb_version = re.compile(r"PRODUCT=.*/(\d)/.*")
     with open(os.path.join(sysfs_dev_dir, "uevent")) as f:
         return int(re_usb_version.search(f.read()).group(1))
 
index 90c238ba6a4b41991a3fab4b34ad198df5324d15..a0dc5d4bf73353dcde864e5677170e6fe193050c 100644 (file)
@@ -9,7 +9,8 @@ execveat.ephemeral
 execveat.denatured
 non-regular
 null-argv
-/load_address_*
+/load_address.*
+!load_address.c
 /recursion-depth
 xxxxxxxx*
 pipe
diff --git a/tools/testing/selftests/ftrace/test.d/ftrace/fgraph-profiler.tc b/tools/testing/selftests/ftrace/test.d/ftrace/fgraph-profiler.tc
new file mode 100644 (file)
index 0000000..ffff864
--- /dev/null
@@ -0,0 +1,31 @@
+#!/bin/sh
+# SPDX-License-Identifier: GPL-2.0
+# description: ftrace - function profiler with function graph tracing
+# requires: function_profile_enabled set_ftrace_filter function_graph:tracer
+
+# The function graph tracer can now be run along side of the function
+# profiler. But there was a bug that caused the combination of the two
+# to crash. It also required the function graph tracer to be started
+# first.
+#
+# This test triggers that bug
+#
+# We need both function_graph and profiling to run this test
+
+fail() { # mesg
+    echo $1
+    exit_fail
+}
+
+echo "Enabling function graph tracer:"
+echo function_graph > current_tracer
+echo "enable profiler"
+
+# Older kernels do not allow function_profile to be enabled with
+# function graph tracer. If the below fails, mark it as unsupported
+echo 1 > function_profile_enabled || exit_unsupported
+
+# Let it run for a bit to make sure nothing explodes
+sleep 1
+
+exit 0
index 72be55ac4bdfe538ba0038664fc72c51dc50ecd1..662209f5fabcfc30ac5330d6c678986195cf6392 100644 (file)
@@ -17,6 +17,9 @@ TEST_PROGS += hid-tablet.sh
 TEST_PROGS += hid-usb_crash.sh
 TEST_PROGS += hid-wacom.sh
 
+TEST_FILES := run-hid-tools-tests.sh
+TEST_FILES += tests
+
 CXX ?= $(CROSS_COMPILE)g++
 
 HOSTPKG_CONFIG := pkg-config
index e7008f614ad7935f6fab4a8658a1afbea0c443b2..6a3b8503264e1555604f7ebbabe77a4f3b00dd54 100755 (executable)
@@ -44,6 +44,11 @@ if [ $UID != 0 ] && [ $EVALUATE_ONLY == 0 ]; then
     exit $ksft_skip
 fi
 
+if ! command -v cpupower &> /dev/null; then
+       echo $msg cpupower could not be found, please install it >&2
+       exit $ksft_skip
+fi
+
 max_cpus=$(($(nproc)-1))
 
 function run_test () {
@@ -87,9 +92,9 @@ mkt_freq=${_mkt_freq}0
 
 # Get the ranges from cpupower
 _min_freq=$(cpupower frequency-info -l | tail -1 | awk ' { print $1 } ')
-min_freq=$(($_min_freq / 1000))
+min_freq=$((_min_freq / 1000))
 _max_freq=$(cpupower frequency-info -l | tail -1 | awk ' { print $2 } ')
-max_freq=$(($_max_freq / 1000))
+max_freq=$((_max_freq / 1000))
 
 
 [ $EVALUATE_ONLY -eq 0 ] && for freq in `seq $max_freq -100 $min_freq`
index 960cf6a7719858586d2483c9a64839096ccd8015..156fbfae940feac649f933dc6e048a2e2926542a 100644 (file)
@@ -248,6 +248,9 @@ CFLAGS += -Wall -Wstrict-prototypes -Wuninitialized -O2 -g -std=gnu99 \
 ifeq ($(ARCH),s390)
        CFLAGS += -march=z10
 endif
+ifeq ($(ARCH),x86)
+       CFLAGS += -march=x86-64-v2
+endif
 ifeq ($(ARCH),arm64)
 tools_dir := $(top_srcdir)/tools
 arm64_tools_dir := $(tools_dir)/arch/arm64/tools/
index 2a3fe7914b728ac0377985773e3c3261a6c8b1ab..b87e53580bfcdaad60ea66eca2b222b1e3cfa88c 100644 (file)
@@ -68,6 +68,8 @@ struct test_feature_reg {
        }
 
 static const struct reg_ftr_bits ftr_id_aa64dfr0_el1[] = {
+       S_REG_FTR_BITS(FTR_LOWER_SAFE, ID_AA64DFR0_EL1, DoubleLock, 0),
+       REG_FTR_BITS(FTR_LOWER_SAFE, ID_AA64DFR0_EL1, WRPs, 0),
        S_REG_FTR_BITS(FTR_LOWER_SAFE, ID_AA64DFR0_EL1, PMUVer, 0),
        REG_FTR_BITS(FTR_LOWER_SAFE, ID_AA64DFR0_EL1, DebugVer, ID_AA64DFR0_EL1_DebugVer_IMP),
        REG_FTR_END,
@@ -134,6 +136,13 @@ static const struct reg_ftr_bits ftr_id_aa64pfr0_el1[] = {
        REG_FTR_END,
 };
 
+static const struct reg_ftr_bits ftr_id_aa64pfr1_el1[] = {
+       REG_FTR_BITS(FTR_LOWER_SAFE, ID_AA64PFR1_EL1, CSV2_frac, 0),
+       REG_FTR_BITS(FTR_LOWER_SAFE, ID_AA64PFR1_EL1, SSBS, ID_AA64PFR1_EL1_SSBS_NI),
+       REG_FTR_BITS(FTR_LOWER_SAFE, ID_AA64PFR1_EL1, BT, 0),
+       REG_FTR_END,
+};
+
 static const struct reg_ftr_bits ftr_id_aa64mmfr0_el1[] = {
        REG_FTR_BITS(FTR_LOWER_SAFE, ID_AA64MMFR0_EL1, ECV, 0),
        REG_FTR_BITS(FTR_LOWER_SAFE, ID_AA64MMFR0_EL1, EXS, 0),
@@ -200,6 +209,7 @@ static struct test_feature_reg test_regs[] = {
        TEST_REG(SYS_ID_AA64ISAR1_EL1, ftr_id_aa64isar1_el1),
        TEST_REG(SYS_ID_AA64ISAR2_EL1, ftr_id_aa64isar2_el1),
        TEST_REG(SYS_ID_AA64PFR0_EL1, ftr_id_aa64pfr0_el1),
+       TEST_REG(SYS_ID_AA64PFR1_EL1, ftr_id_aa64pfr1_el1),
        TEST_REG(SYS_ID_AA64MMFR0_EL1, ftr_id_aa64mmfr0_el1),
        TEST_REG(SYS_ID_AA64MMFR1_EL1, ftr_id_aa64mmfr1_el1),
        TEST_REG(SYS_ID_AA64MMFR2_EL1, ftr_id_aa64mmfr2_el1),
@@ -569,9 +579,9 @@ int main(void)
        test_cnt = ARRAY_SIZE(ftr_id_aa64dfr0_el1) + ARRAY_SIZE(ftr_id_dfr0_el1) +
                   ARRAY_SIZE(ftr_id_aa64isar0_el1) + ARRAY_SIZE(ftr_id_aa64isar1_el1) +
                   ARRAY_SIZE(ftr_id_aa64isar2_el1) + ARRAY_SIZE(ftr_id_aa64pfr0_el1) +
-                  ARRAY_SIZE(ftr_id_aa64mmfr0_el1) + ARRAY_SIZE(ftr_id_aa64mmfr1_el1) +
-                  ARRAY_SIZE(ftr_id_aa64mmfr2_el1) + ARRAY_SIZE(ftr_id_aa64zfr0_el1) -
-                  ARRAY_SIZE(test_regs) + 2;
+                  ARRAY_SIZE(ftr_id_aa64pfr1_el1) + ARRAY_SIZE(ftr_id_aa64mmfr0_el1) +
+                  ARRAY_SIZE(ftr_id_aa64mmfr1_el1) + ARRAY_SIZE(ftr_id_aa64mmfr2_el1) +
+                  ARRAY_SIZE(ftr_id_aa64zfr0_el1) - ARRAY_SIZE(test_regs) + 2;
 
        ksft_set_plan(test_cnt);
 
index e3343f0df9e1f294c5ef71ae6ce6cc4012508df4..c81a84990eabfc3fe7ffa9fe2f75c1d45207a0bb 100644 (file)
@@ -169,12 +169,14 @@ int main(int argc, char *argv[])
                case 'i':
                        p.nr_iterations = atoi_positive("Number of iterations", optarg);
                        break;
+#ifdef __x86_64__
                case 'q':
                        p.disable_slot_zap_quirk = true;
 
                        TEST_REQUIRE(kvm_check_cap(KVM_CAP_DISABLE_QUIRKS2) &
                                     KVM_X86_QUIRK_SLOT_ZAP_ALL);
                        break;
+#endif
                case 'h':
                default:
                        help(argv[0]);
index 893366982f77bb02ddbf19aaa35abc6af7f1275b..989ffe0d047f19e1ed12b20608d551e952f3f460 100644 (file)
@@ -113,7 +113,9 @@ static_assert(ATOMIC_BOOL_LOCK_FREE == 2, "atomic bool is not lockless");
 static sem_t vcpu_ready;
 
 static bool map_unmap_verify;
+#ifdef __x86_64__
 static bool disable_slot_zap_quirk;
+#endif
 
 static bool verbose;
 #define pr_info_v(...)                         \
@@ -579,8 +581,10 @@ static bool test_memslot_move_prepare(struct vm_data *data,
        uint32_t guest_page_size = data->vm->page_size;
        uint64_t movesrcgpa, movetestgpa;
 
+#ifdef __x86_64__
        if (disable_slot_zap_quirk)
                vm_enable_cap(data->vm, KVM_CAP_DISABLE_QUIRKS2, KVM_X86_QUIRK_SLOT_ZAP_ALL);
+#endif
 
        movesrcgpa = vm_slot2gpa(data, data->nslots - 1);
 
@@ -971,11 +975,13 @@ static bool parse_args(int argc, char *argv[],
                case 'd':
                        map_unmap_verify = true;
                        break;
+#ifdef __x86_64__
                case 'q':
                        disable_slot_zap_quirk = true;
                        TEST_REQUIRE(kvm_check_cap(KVM_CAP_DISABLE_QUIRKS2) &
                                     KVM_X86_QUIRK_SLOT_ZAP_ALL);
                        break;
+#endif
                case 's':
                        targs->nslots = atoi_paranoid(optarg);
                        if (targs->nslots <= 1 && targs->nslots != -1) {
index 8c579ce714e9a7ce3982123b089856c3b5963d43..fec03b11b0592ca18bc8f8fbe858f0c090e6f733 100644 (file)
@@ -60,7 +60,7 @@ static bool is_cpuid_mangled(const struct kvm_cpuid_entry2 *entrie)
 {
        int i;
 
-       for (i = 0; i < sizeof(mangled_cpuids); i++) {
+       for (i = 0; i < ARRAY_SIZE(mangled_cpuids); i++) {
                if (mangled_cpuids[i].function == entrie->function &&
                    mangled_cpuids[i].index == entrie->index)
                        return true;
index d2cfc9b494a0ee9c2eab5f90923f6edb88655eb3..141bf63cbe05ecf8bef3bc88ee313d44863e39df 100644 (file)
@@ -1657,7 +1657,7 @@ TEST_F(hmm2, double_map)
 
        buffer->fd = -1;
        buffer->size = size;
-       buffer->mirror = malloc(npages);
+       buffer->mirror = malloc(size);
        ASSERT_NE(buffer->mirror, NULL);
 
        /* Reserve a range of addresses. */
index 56d4480e8d3cbfc4c20af9c48026e2c34f0fa39e..8a4d34cce36b2aff12392b2356f597a2668f9d1d 100644 (file)
@@ -1091,7 +1091,7 @@ static void usage(void)
        fprintf(stderr, "\n\t\"file,all\" mem_type requires kernel built with\n");
        fprintf(stderr, "\tCONFIG_READ_ONLY_THP_FOR_FS=y\n");
        fprintf(stderr, "\n\tif [dir] is a (sub)directory of a tmpfs mount, tmpfs must be\n");
-       fprintf(stderr, "\tmounted with huge=madvise option for khugepaged tests to work\n");
+       fprintf(stderr, "\tmounted with huge=advise option for khugepaged tests to work\n");
        fprintf(stderr, "\n\tSupported Options:\n");
        fprintf(stderr, "\t\t-h: This help message.\n");
        fprintf(stderr, "\t\t-s: mTHP size, expressed as page order.\n");
index b3d21eed203dc2cc7ddefc9165de45d85d561334..a2e71b1636e7ca41aa53602ab9f49be6a3f89205 100644 (file)
@@ -241,6 +241,8 @@ static void *fork_event_consumer(void *data)
        fork_event_args *args = data;
        struct uffd_msg msg = { 0 };
 
+       ready_for_fork = true;
+
        /* Read until a full msg received */
        while (uffd_read_msg(args->parent_uffd, &msg));
 
@@ -308,8 +310,11 @@ static int pagemap_test_fork(int uffd, bool with_event, bool test_pin)
 
        /* Prepare a thread to resolve EVENT_FORK */
        if (with_event) {
+               ready_for_fork = false;
                if (pthread_create(&thread, NULL, fork_event_consumer, &args))
                        err("pthread_create()");
+               while (!ready_for_fork)
+                       ; /* Wait for the poll_thread to start executing before forking */
        }
 
        child = fork();
index c6a8c732b802176dea234feb34ec13d6a73d6fc8..68801e1a9ec2d163ac37b5557bbe208d6f9b0a7f 100644 (file)
@@ -1414,6 +1414,13 @@ TEST_F(mount_setattr_idmapped, idmap_mount_tree_invalid)
        ASSERT_EQ(expected_uid_gid(-EBADF, "/tmp/B/b", 0, 0, 0), 0);
        ASSERT_EQ(expected_uid_gid(-EBADF, "/tmp/B/BB/b", 0, 0, 0), 0);
 
+       ASSERT_EQ(mount("testing", "/mnt/A", "ramfs", MS_NOATIME | MS_NODEV,
+                       "size=100000,mode=700"), 0);
+
+       ASSERT_EQ(mkdir("/mnt/A/AA", 0777), 0);
+
+       ASSERT_EQ(mount("/tmp", "/mnt/A/AA", NULL, MS_BIND | MS_REC, NULL), 0);
+
        open_tree_fd = sys_open_tree(-EBADF, "/mnt/A",
                                     AT_RECURSIVE |
                                     AT_EMPTY_PATH |
@@ -1433,6 +1440,8 @@ TEST_F(mount_setattr_idmapped, idmap_mount_tree_invalid)
        ASSERT_EQ(expected_uid_gid(-EBADF, "/tmp/B/BB/b", 0, 0, 0), 0);
        ASSERT_EQ(expected_uid_gid(open_tree_fd, "B/b", 0, 0, 0), 0);
        ASSERT_EQ(expected_uid_gid(open_tree_fd, "B/BB/b", 0, 0, 0), 0);
+
+       (void)umount2("/mnt/A", MNT_DETACH);
 }
 
 TEST_F(mount_setattr, mount_attr_nosymfollow)
index 1c04c780db66747abdf45a0a1c07db3fba3f5b0e..217d8b7a736502f4b3002ba0ebd816db88dc3964 100644 (file)
@@ -16,6 +16,7 @@ ipsec
 ipv6_flowlabel
 ipv6_flowlabel_mgr
 log.txt
+msg_oob
 msg_zerocopy
 ncdevmem
 nettest
index 96c97064f2d33c381db573ba6527fae4126f4a61..becc7c3fc809f07d3bfc071b0180bef1f6aec2c7 100755 (executable)
@@ -8,6 +8,7 @@
 ALL_TESTS="
        gre_flat
        gre_mtu_change
+       gre_flat_remote_change
 "
 
 NUM_NETIFS=6
@@ -44,6 +45,19 @@ gre_mtu_change()
        test_mtu_change
 }
 
+gre_flat_remote_change()
+{
+       flat_remote_change
+
+       test_traffic_ip4ip6 "GRE flat IPv4-in-IPv6 (new remote)"
+       test_traffic_ip6ip6 "GRE flat IPv6-in-IPv6 (new remote)"
+
+       flat_remote_restore
+
+       test_traffic_ip4ip6 "GRE flat IPv4-in-IPv6 (old remote)"
+       test_traffic_ip6ip6 "GRE flat IPv6-in-IPv6 (old remote)"
+}
+
 cleanup()
 {
        pre_cleanup
index ff9fb0db9bd1285482e71854627c9e6bdaee4c50..e5335116a2fdde14f42595ed22ea961c7c078809 100755 (executable)
@@ -8,6 +8,7 @@
 ALL_TESTS="
        gre_flat
        gre_mtu_change
+       gre_flat_remote_change
 "
 
 NUM_NETIFS=6
@@ -44,6 +45,19 @@ gre_mtu_change()
        test_mtu_change
 }
 
+gre_flat_remote_change()
+{
+       flat_remote_change
+
+       test_traffic_ip4ip6 "GRE flat IPv4-in-IPv6 with key (new remote)"
+       test_traffic_ip6ip6 "GRE flat IPv6-in-IPv6 with key (new remote)"
+
+       flat_remote_restore
+
+       test_traffic_ip4ip6 "GRE flat IPv4-in-IPv6 with key (old remote)"
+       test_traffic_ip6ip6 "GRE flat IPv6-in-IPv6 with key (old remote)"
+}
+
 cleanup()
 {
        pre_cleanup
index 12c1387852421fa8aafb6c5d3283045ffe3d33ab..7e0cbfdefab0e15378f2d375154eb20deb8b177d 100755 (executable)
@@ -8,6 +8,7 @@
 ALL_TESTS="
        gre_flat
        gre_mtu_change
+       gre_flat_remote_change
 "
 
 NUM_NETIFS=6
@@ -44,6 +45,19 @@ gre_mtu_change()
        test_mtu_change gre
 }
 
+gre_flat_remote_change()
+{
+       flat_remote_change
+
+       test_traffic_ip4ip6 "GRE flat IPv4-in-IPv6 with ikey/okey (new remote)"
+       test_traffic_ip6ip6 "GRE flat IPv6-in-IPv6 with ikey/okey (new remote)"
+
+       flat_remote_restore
+
+       test_traffic_ip4ip6 "GRE flat IPv4-in-IPv6 with ikey/okey (old remote)"
+       test_traffic_ip6ip6 "GRE flat IPv6-in-IPv6 with ikey/okey (old remote)"
+}
+
 cleanup()
 {
        pre_cleanup
index 83b55c30a5c359b2df4e73e35ce2613201338ba0..e0844495f3d1cf435d3b0736b5bf8ab58c6595c0 100755 (executable)
@@ -8,6 +8,7 @@
 ALL_TESTS="
        gre_hier
        gre_mtu_change
+       gre_hier_remote_change
 "
 
 NUM_NETIFS=6
@@ -44,6 +45,19 @@ gre_mtu_change()
        test_mtu_change gre
 }
 
+gre_hier_remote_change()
+{
+       hier_remote_change
+
+       test_traffic_ip4ip6 "GRE hierarchical IPv4-in-IPv6 (new remote)"
+       test_traffic_ip6ip6 "GRE hierarchical IPv6-in-IPv6 (new remote)"
+
+       hier_remote_restore
+
+       test_traffic_ip4ip6 "GRE hierarchical IPv4-in-IPv6 (old remote)"
+       test_traffic_ip6ip6 "GRE hierarchical IPv6-in-IPv6 (old remote)"
+}
+
 cleanup()
 {
        pre_cleanup
index 256607916d92f43084530d8d143e7c781a4b887d..741bc9c928eb2c15d54a65770c1e2b95d8b11a4e 100755 (executable)
@@ -8,6 +8,7 @@
 ALL_TESTS="
        gre_hier
        gre_mtu_change
+       gre_hier_remote_change
 "
 
 NUM_NETIFS=6
@@ -44,6 +45,19 @@ gre_mtu_change()
        test_mtu_change gre
 }
 
+gre_hier_remote_change()
+{
+       hier_remote_change
+
+       test_traffic_ip4ip6 "GRE hierarchical IPv4-in-IPv6 with key (new remote)"
+       test_traffic_ip6ip6 "GRE hierarchical IPv6-in-IPv6 with key (new remote)"
+
+       hier_remote_restore
+
+       test_traffic_ip4ip6 "GRE hierarchical IPv4-in-IPv6 with key (old remote)"
+       test_traffic_ip6ip6 "GRE hierarchical IPv6-in-IPv6 with key (old remote)"
+}
+
 cleanup()
 {
        pre_cleanup
index ad1bcd6334a80b46f2f69e979ca393fb7dfde31a..ad9eab4b1367bce04270472d20e52c2cc2a68b8f 100755 (executable)
@@ -8,6 +8,7 @@
 ALL_TESTS="
        gre_hier
        gre_mtu_change
+       gre_hier_remote_change
 "
 
 NUM_NETIFS=6
@@ -44,6 +45,19 @@ gre_mtu_change()
        test_mtu_change gre
 }
 
+gre_hier_remote_change()
+{
+       hier_remote_change
+
+       test_traffic_ip4ip6 "GRE hierarchical IPv4-in-IPv6 with ikey/okey (new remote)"
+       test_traffic_ip6ip6 "GRE hierarchical IPv6-in-IPv6 with ikey/okey (new remote)"
+
+       hier_remote_restore
+
+       test_traffic_ip4ip6 "GRE hierarchical IPv4-in-IPv6 with ikey/okey (old remote)"
+       test_traffic_ip6ip6 "GRE hierarchical IPv6-in-IPv6 with ikey/okey (old remote)"
+}
+
 cleanup()
 {
        pre_cleanup
index 24f4ab328bd2de7267eca7c66e25f86324e612c4..2d91281dc5b7765e70cc9ea1e094ff1283bb465b 100644 (file)
@@ -436,3 +436,83 @@ test_mtu_change()
        check_err $?
        log_test "ping GRE IPv6, packet size 1800 after MTU change"
 }
+
+topo_flat_remote_change()
+{
+       local old1=$1; shift
+       local new1=$1; shift
+       local old2=$1; shift
+       local new2=$1; shift
+
+       ip link set dev g1a type ip6gre local $new1 remote $new2
+        __addr_add_del g1a add "$new1/128"
+        __addr_add_del g1a del "$old1/128"
+       ip -6 route add $new2/128 via 2001:db8:10::2
+       ip -6 route del $old2/128
+
+       ip link set dev g2a type ip6gre local $new2 remote $new1
+        __addr_add_del g2a add "$new2/128"
+        __addr_add_del g2a del "$old2/128"
+       ip -6 route add vrf v$ol2 $new1/128 via 2001:db8:10::1
+       ip -6 route del vrf v$ol2 $old1/128
+}
+
+flat_remote_change()
+{
+       local old1=2001:db8:3::1
+       local new1=2001:db8:3::10
+       local old2=2001:db8:3::2
+       local new2=2001:db8:3::20
+
+       topo_flat_remote_change $old1 $new1 $old2 $new2
+}
+
+flat_remote_restore()
+{
+       local old1=2001:db8:3::10
+       local new1=2001:db8:3::1
+       local old2=2001:db8:3::20
+       local new2=2001:db8:3::2
+
+       topo_flat_remote_change $old1 $new1 $old2 $new2
+}
+
+topo_hier_remote_change()
+{
+       local old1=$1; shift
+       local new1=$1; shift
+       local old2=$1; shift
+       local new2=$1; shift
+
+        __addr_add_del dummy1 del "$old1/64"
+        __addr_add_del dummy1 add "$new1/64"
+       ip link set dev g1a type ip6gre local $new1 remote $new2
+       ip -6 route add vrf v$ul1 $new2/128 via 2001:db8:10::2
+       ip -6 route del vrf v$ul1 $old2/128
+
+        __addr_add_del dummy2 del "$old2/64"
+        __addr_add_del dummy2 add "$new2/64"
+       ip link set dev g2a type ip6gre local $new2 remote $new1
+       ip -6 route add vrf v$ul2 $new1/128 via 2001:db8:10::1
+       ip -6 route del vrf v$ul2 $old1/128
+}
+
+hier_remote_change()
+{
+       local old1=2001:db8:3::1
+       local new1=2001:db8:3::10
+       local old2=2001:db8:3::2
+       local new2=2001:db8:3::20
+
+       topo_hier_remote_change $old1 $new1 $old2 $new2
+}
+
+hier_remote_restore()
+{
+       local old1=2001:db8:3::10
+       local new1=2001:db8:3::1
+       local old2=2001:db8:3::20
+       local new2=2001:db8:3::2
+
+       topo_hier_remote_change $old1 $new1 $old2 $new2
+}
index 9e677aa64a06a6fadf17d8817a6abe6f5b1cea32..694ece9ba3a74274103063c2a04580db78797419 100755 (executable)
@@ -202,7 +202,7 @@ one_bridge_two_pvids()
        ip link set $swp2 master br0
 
        bridge vlan add dev $swp1 vid 1 pvid untagged
-       bridge vlan add dev $swp1 vid 2 pvid untagged
+       bridge vlan add dev $swp2 vid 2 pvid untagged
 
        run_test "Switch ports in VLAN-aware bridge with different PVIDs"
 
index f571a8b3139bc3470671f61afc7d277cf866b90d..1a8cbe9acc48e79efe4aefef945a3903a9a689f6 100644 (file)
@@ -1,5 +1,6 @@
 # SPDX-License-Identifier: GPL-2.0
 
+import errno
 import json
 import os
 import random
index 57325d57e4c6e3653019db2de09620d692143683..b48b4e56826a9cfdb3501242b707ae2ebe29b220 100755 (executable)
@@ -259,6 +259,15 @@ check_mptcp_disabled()
        mptcp_lib_ns_init disabled_ns
 
        print_larger_title "New MPTCP socket can be blocked via sysctl"
+
+       # mainly to cover more code
+       if ! ip netns exec ${disabled_ns} sysctl net.mptcp >/dev/null; then
+               mptcp_lib_pr_fail "not able to list net.mptcp sysctl knobs"
+               mptcp_lib_result_fail "not able to list net.mptcp sysctl knobs"
+               ret=${KSFT_FAIL}
+               return 1
+       fi
+
        # net.mptcp.enabled should be enabled by default
        if [ "$(ip netns exec ${disabled_ns} sysctl net.mptcp.enabled | awk '{ print $3 }')" -ne 1 ]; then
                mptcp_lib_pr_fail "net.mptcp.enabled sysctl is not 1 by default"
index e8d0a01b4144264615d92b953a69ebd934ce468e..c07e2bd3a315aac9c422fed85c3196ec46e060f7 100755 (executable)
@@ -23,6 +23,7 @@ tmpfile=""
 cout=""
 err=""
 capout=""
+cappid=""
 ns1=""
 ns2=""
 iptables="iptables"
@@ -887,40 +888,62 @@ check_cestab()
        fi
 }
 
-do_transfer()
+cond_start_capture()
 {
-       local listener_ns="$1"
-       local connector_ns="$2"
-       local cl_proto="$3"
-       local srv_proto="$4"
-       local connect_addr="$5"
-
-       local port=$((10000 + MPTCP_LIB_TEST_COUNTER - 1))
-       local cappid
-       local FAILING_LINKS=${FAILING_LINKS:-""}
-       local fastclose=${fastclose:-""}
-       local speed=${speed:-"fast"}
+       local ns="$1"
 
-       :> "$cout"
-       :> "$sout"
        :> "$capout"
 
        if $capture; then
-               local capuser
-               if [ -z $SUDO_USER ] ; then
+               local capuser capfile
+               if [ -z $SUDO_USER ]; then
                        capuser=""
                else
                        capuser="-Z $SUDO_USER"
                fi
 
-               capfile=$(printf "mp_join-%02u-%s.pcap" "$MPTCP_LIB_TEST_COUNTER" "${listener_ns}")
+               capfile=$(printf "mp_join-%02u-%s.pcap" "$MPTCP_LIB_TEST_COUNTER" "$ns")
 
                echo "Capturing traffic for test $MPTCP_LIB_TEST_COUNTER into $capfile"
-               ip netns exec ${listener_ns} tcpdump -i any -s 65535 -B 32768 $capuser -w $capfile > "$capout" 2>&1 &
+               ip netns exec "$ns" tcpdump -i any -s 65535 -B 32768 $capuser -w "$capfile" > "$capout" 2>&1 &
                cappid=$!
 
                sleep 1
        fi
+}
+
+cond_stop_capture()
+{
+       if $capture; then
+               sleep 1
+               kill $cappid
+               cat "$capout"
+       fi
+}
+
+get_port()
+{
+       echo "$((10000 + MPTCP_LIB_TEST_COUNTER - 1))"
+}
+
+do_transfer()
+{
+       local listener_ns="$1"
+       local connector_ns="$2"
+       local cl_proto="$3"
+       local srv_proto="$4"
+       local connect_addr="$5"
+       local port
+
+       local FAILING_LINKS=${FAILING_LINKS:-""}
+       local fastclose=${fastclose:-""}
+       local speed=${speed:-"fast"}
+       port=$(get_port)
+
+       :> "$cout"
+       :> "$sout"
+
+       cond_start_capture ${listener_ns}
 
        NSTAT_HISTORY=/tmp/${listener_ns}.nstat ip netns exec ${listener_ns} \
                nstat -n
@@ -1007,10 +1030,7 @@ do_transfer()
        wait $spid
        local rets=$?
 
-       if $capture; then
-           sleep 1
-           kill $cappid
-       fi
+       cond_stop_capture
 
        NSTAT_HISTORY=/tmp/${listener_ns}.nstat ip netns exec ${listener_ns} \
                nstat | grep Tcp > /tmp/${listener_ns}.out
@@ -1026,7 +1046,6 @@ do_transfer()
                ip netns exec ${connector_ns} ss -Menita 1>&2 -o "dport = :$port"
                cat /tmp/${connector_ns}.out
 
-               cat "$capout"
                return 1
        fi
 
@@ -1043,13 +1062,7 @@ do_transfer()
        fi
        rets=$?
 
-       if [ $retc -eq 0 ] && [ $rets -eq 0 ];then
-               cat "$capout"
-               return 0
-       fi
-
-       cat "$capout"
-       return 1
+       [ $retc -eq 0 ] && [ $rets -eq 0 ]
 }
 
 make_file()
@@ -2873,6 +2886,32 @@ verify_listener_events()
        fail_test
 }
 
+chk_mpc_endp_attempt()
+{
+       local retl=$1
+       local attempts=$2
+
+       print_check "Connect"
+
+       if [ ${retl} = 124 ]; then
+               fail_test "timeout on connect"
+       elif [ ${retl} = 0 ]; then
+               fail_test "unexpected successful connect"
+       else
+               print_ok
+
+               print_check "Attempts"
+               count=$(mptcp_lib_get_counter ${ns1} "MPTcpExtMPCapableEndpAttempt")
+               if [ -z "$count" ]; then
+                       print_skip
+               elif [ "$count" != "$attempts" ]; then
+                       fail_test "got ${count} MPC attempt[s] on port-based endpoint, expected ${attempts}"
+               else
+                       print_ok
+               fi
+       fi
+}
+
 add_addr_ports_tests()
 {
        # signal address with port
@@ -2963,6 +3002,22 @@ add_addr_ports_tests()
                chk_join_nr 2 2 2
                chk_add_nr 2 2 2
        fi
+
+       if reset "port-based signal endpoint must not accept mpc"; then
+               local port retl count
+               port=$(get_port)
+
+               cond_start_capture ${ns1}
+               pm_nl_add_endpoint ${ns1} 10.0.2.1 flags signal port ${port}
+               mptcp_lib_wait_local_port_listen ${ns1} ${port}
+
+               timeout 1 ip netns exec ${ns2} \
+                       ./mptcp_connect -t ${timeout_poll} -p $port -s MPTCP 10.0.2.1 >/dev/null 2>&1
+               retl=$?
+               cond_stop_capture
+
+               chk_mpc_endp_attempt ${retl} 1
+       fi
 }
 
 syncookies_tests()
index e6c9e777feadc6e234506ca9f5ae2b5801b20b33..542f7886a0bc2ac016f41d8b70357a8e0c1d271b 100644 (file)
@@ -31,6 +31,7 @@ TEST_PROGS += nft_tproxy_tcp.sh
 TEST_PROGS += nft_tproxy_udp.sh
 TEST_PROGS += nft_zones_many.sh
 TEST_PROGS += rpath.sh
+TEST_PROGS += vxlan_mtu_frag.sh
 TEST_PROGS += xt_string.sh
 
 TEST_PROGS_EXTENDED = nft_concat_range_perf.sh
index c5fe7b34eaf19a39777a161ccb58400d446ab585..43d8b500d391a255722a4f8ede32e3f427fab982 100644 (file)
@@ -7,6 +7,7 @@ CONFIG_BRIDGE_EBT_REDIRECT=m
 CONFIG_BRIDGE_EBT_T_FILTER=m
 CONFIG_BRIDGE_NETFILTER=m
 CONFIG_BRIDGE_NF_EBTABLES=m
+CONFIG_BRIDGE_VLAN_FILTERING=y
 CONFIG_CGROUP_BPF=y
 CONFIG_DUMMY=m
 CONFIG_INET_ESP=m
@@ -84,6 +85,7 @@ CONFIG_NFT_SYNPROXY=m
 CONFIG_NFT_TPROXY=m
 CONFIG_VETH=m
 CONFIG_VLAN_8021Q=m
+CONFIG_VXLAN=m
 CONFIG_XFRM_USER=m
 CONFIG_XFRM_STATISTICS=y
 CONFIG_NET_PKTGEN=m
index bd9317bf5adafb4fc5d55a5bcba2b041e39cc50c..254ff03297f06c16296201191cb2815ce47e0907 100644 (file)
@@ -98,7 +98,7 @@ static int conntrack_data_insert(struct mnl_socket *sock, struct nlmsghdr *nlh,
        char buf[MNL_SOCKET_BUFFER_SIZE];
        struct nlmsghdr *rplnlh;
        unsigned int portid;
-       int err, ret;
+       int ret;
 
        portid = mnl_socket_get_portid(sock);
 
@@ -207,6 +207,7 @@ static int conntrack_data_generate_v6(struct mnl_socket *sock,
 static int count_entries(const struct nlmsghdr *nlh, void *data)
 {
        reply_counter++;
+       return MNL_CB_OK;
 }
 
 static int conntracK_count_zone(struct mnl_socket *sock, uint16_t zone)
@@ -216,7 +217,7 @@ static int conntracK_count_zone(struct mnl_socket *sock, uint16_t zone)
        struct nfgenmsg *nfh;
        struct nlattr *nest;
        unsigned int portid;
-       int err, ret;
+       int ret;
 
        portid = mnl_socket_get_portid(sock);
 
@@ -263,7 +264,7 @@ static int conntrack_flush_zone(struct mnl_socket *sock, uint16_t zone)
        struct nfgenmsg *nfh;
        struct nlattr *nest;
        unsigned int portid;
-       int err, ret;
+       int ret;
 
        portid = mnl_socket_get_portid(sock);
 
index 073e8e62d350b28f8b2664468f439a18b4a6951e..e95ecb37c2b145712e0e1f20267d0789f9ccb5c0 100755 (executable)
@@ -32,6 +32,7 @@ source lib.sh
 
 IP0=172.30.30.1
 IP1=172.30.30.2
+DUMMYNET=10.9.9
 PFXL=30
 ret=0
 
@@ -54,6 +55,7 @@ setup_ns ns0 ns1
 ip netns exec "$ns0" sysctl -q -w net.ipv4.conf.default.rp_filter=0
 ip netns exec "$ns0" sysctl -q -w net.ipv4.conf.all.rp_filter=0
 ip netns exec "$ns0" sysctl -q -w net.ipv4.conf.all.rp_filter=0
+ip netns exec "$ns0" sysctl -q -w net.ipv4.conf.all.forwarding=1
 
 if ! ip link add veth0 netns "$ns0" type veth peer name veth0 netns "$ns1" > /dev/null 2>&1; then
        echo "SKIP: Could not add veth device"
@@ -65,13 +67,18 @@ if ! ip -net "$ns0" li add tvrf type vrf table 9876; then
        exit $ksft_skip
 fi
 
+ip -net "$ns0" link add dummy0 type dummy
+
 ip -net "$ns0" li set veth0 master tvrf
+ip -net "$ns0" li set dummy0 master tvrf
 ip -net "$ns0" li set tvrf up
 ip -net "$ns0" li set veth0 up
+ip -net "$ns0" li set dummy0 up
 ip -net "$ns1" li set veth0 up
 
 ip -net "$ns0" addr add $IP0/$PFXL dev veth0
 ip -net "$ns1" addr add $IP1/$PFXL dev veth0
+ip -net "$ns0" addr add $DUMMYNET.1/$PFXL dev dummy0
 
 listener_ready()
 {
@@ -212,9 +219,35 @@ EOF
        fi
 }
 
+test_fib()
+{
+ip netns exec "$ns0" nft -f - <<EOF
+flush ruleset
+table ip t {
+       counter fibcount { }
+
+       chain prerouting {
+               type filter hook prerouting priority 0;
+               meta iifname veth0 ip daddr $DUMMYNET.2 fib daddr oif dummy0 counter name fibcount notrack
+       }
+}
+EOF
+       ip -net "$ns1" route add 10.9.9.0/24 via "$IP0" dev veth0
+       ip netns exec "$ns1" ping -q -w 1 -c 1 "$DUMMYNET".2 > /dev/null
+
+       if ip netns exec "$ns0" nft list counter t fibcount | grep -q "packets 1"; then
+               echo "PASS: fib lookup returned exepected output interface"
+       else
+               echo "FAIL: fib lookup did not return exepected output interface"
+               ret=1
+               return
+       fi
+}
+
 test_ct_zone_in
 test_masquerade_vrf "default"
 test_masquerade_vrf "pfifo"
 test_masquerade_veth
+test_fib
 
 exit $ret
index 902f8114bc80fc2727cc2c6778d22ef066013227..87f2b4c725aa027a0296967f82414fcfcbbc5e98 100755 (executable)
@@ -48,12 +48,31 @@ logread_pid=$!
 trap 'kill $logread_pid; rm -f $logfile $rulefile' EXIT
 exec 3<"$logfile"
 
+lsplit='s/^\(.*\) entries=\([^ ]*\) \(.*\)$/pfx="\1"\nval="\2"\nsfx="\3"/'
+summarize_logs() {
+       sum=0
+       while read line; do
+               eval $(sed "$lsplit" <<< "$line")
+               [[ $sum -gt 0 ]] && {
+                       [[ "$pfx $sfx" == "$tpfx $tsfx" ]] && {
+                               let "sum += val"
+                               continue
+                       }
+                       echo "$tpfx entries=$sum $tsfx"
+               }
+               tpfx="$pfx"
+               tsfx="$sfx"
+               sum=$val
+       done
+       echo "$tpfx entries=$sum $tsfx"
+}
+
 do_test() { # (cmd, log)
        echo -n "testing for cmd: $1 ... "
        cat <&3 >/dev/null
        $1 >/dev/null || exit 1
        sleep 0.1
-       res=$(diff -a -u <(echo "$2") - <&3)
+       res=$(diff -a -u <(echo "$2") <(summarize_logs <&3))
        [ $? -eq 0 ] && { echo "OK"; return; }
        echo "FAIL"
        grep -v '^\(---\|+++\|@@\)' <<< "$res"
@@ -152,31 +171,17 @@ do_test 'nft reset rules t1 c2' \
 'table=t1 family=2 entries=3 op=nft_reset_rule'
 
 do_test 'nft reset rules table t1' \
-'table=t1 family=2 entries=3 op=nft_reset_rule
-table=t1 family=2 entries=3 op=nft_reset_rule
-table=t1 family=2 entries=3 op=nft_reset_rule'
+'table=t1 family=2 entries=9 op=nft_reset_rule'
 
 do_test 'nft reset rules t2 c3' \
-'table=t2 family=2 entries=189 op=nft_reset_rule
-table=t2 family=2 entries=188 op=nft_reset_rule
-table=t2 family=2 entries=126 op=nft_reset_rule'
+'table=t2 family=2 entries=503 op=nft_reset_rule'
 
 do_test 'nft reset rules t2' \
-'table=t2 family=2 entries=3 op=nft_reset_rule
-table=t2 family=2 entries=3 op=nft_reset_rule
-table=t2 family=2 entries=186 op=nft_reset_rule
-table=t2 family=2 entries=188 op=nft_reset_rule
-table=t2 family=2 entries=129 op=nft_reset_rule'
+'table=t2 family=2 entries=509 op=nft_reset_rule'
 
 do_test 'nft reset rules' \
-'table=t1 family=2 entries=3 op=nft_reset_rule
-table=t1 family=2 entries=3 op=nft_reset_rule
-table=t1 family=2 entries=3 op=nft_reset_rule
-table=t2 family=2 entries=3 op=nft_reset_rule
-table=t2 family=2 entries=3 op=nft_reset_rule
-table=t2 family=2 entries=180 op=nft_reset_rule
-table=t2 family=2 entries=188 op=nft_reset_rule
-table=t2 family=2 entries=135 op=nft_reset_rule'
+'table=t1 family=2 entries=9 op=nft_reset_rule
+table=t2 family=2 entries=509 op=nft_reset_rule'
 
 # resetting sets and elements
 
@@ -200,13 +205,11 @@ do_test 'nft reset counters t1' \
 'table=t1 family=2 entries=1 op=nft_reset_obj'
 
 do_test 'nft reset counters t2' \
-'table=t2 family=2 entries=342 op=nft_reset_obj
-table=t2 family=2 entries=158 op=nft_reset_obj'
+'table=t2 family=2 entries=500 op=nft_reset_obj'
 
 do_test 'nft reset counters' \
 'table=t1 family=2 entries=1 op=nft_reset_obj
-table=t2 family=2 entries=341 op=nft_reset_obj
-table=t2 family=2 entries=159 op=nft_reset_obj'
+table=t2 family=2 entries=500 op=nft_reset_obj'
 
 # resetting quotas
 
@@ -217,13 +220,11 @@ do_test 'nft reset quotas t1' \
 'table=t1 family=2 entries=1 op=nft_reset_obj'
 
 do_test 'nft reset quotas t2' \
-'table=t2 family=2 entries=315 op=nft_reset_obj
-table=t2 family=2 entries=185 op=nft_reset_obj'
+'table=t2 family=2 entries=500 op=nft_reset_obj'
 
 do_test 'nft reset quotas' \
 'table=t1 family=2 entries=1 op=nft_reset_obj
-table=t2 family=2 entries=314 op=nft_reset_obj
-table=t2 family=2 entries=186 op=nft_reset_obj'
+table=t2 family=2 entries=500 op=nft_reset_obj'
 
 # deleting rules
 
index b3995550856a7f59c6a1e29f7915f5468b8d923d..a4ee5496f2a17cedf1ee71214397012c7906650f 100755 (executable)
@@ -71,6 +71,8 @@ omtu=9000
 lmtu=1500
 rmtu=2000
 
+filesize=$((2 * 1024 * 1024))
+
 usage(){
        echo "nft_flowtable.sh [OPTIONS]"
        echo
@@ -81,12 +83,13 @@ usage(){
        exit 1
 }
 
-while getopts "o:l:r:" o
+while getopts "o:l:r:s:" o
 do
        case $o in
                o) omtu=$OPTARG;;
                l) lmtu=$OPTARG;;
                r) rmtu=$OPTARG;;
+               s) filesize=$OPTARG;;
                *) usage;;
        esac
 done
@@ -217,18 +220,10 @@ ns2out=$(mktemp)
 
 make_file()
 {
-       name=$1
-
-       SIZE=$((RANDOM % (1024 * 128)))
-       SIZE=$((SIZE + (1024 * 8)))
-       TSIZE=$((SIZE * 1024))
-
-       dd if=/dev/urandom of="$name" bs=1024 count=$SIZE 2> /dev/null
+       name="$1"
+       sz="$2"
 
-       SIZE=$((RANDOM % 1024))
-       SIZE=$((SIZE + 128))
-       TSIZE=$((TSIZE + SIZE))
-       dd if=/dev/urandom conf=notrunc of="$name" bs=1 count=$SIZE 2> /dev/null
+       head -c "$sz" < /dev/urandom > "$name"
 }
 
 check_counters()
@@ -246,18 +241,18 @@ check_counters()
        local fs
        fs=$(du -sb "$nsin")
        local max_orig=${fs%%/*}
-       local max_repl=$((max_orig/4))
+       local max_repl=$((max_orig))
 
        # flowtable fastpath should bypass normal routing one, i.e. the counters in forward hook
        # should always be lower than the size of the transmitted file (max_orig).
        if [ "$orig_cnt" -gt "$max_orig" ];then
-               echo "FAIL: $what: original counter $orig_cnt exceeds expected value $max_orig" 1>&2
+               echo "FAIL: $what: original counter $orig_cnt exceeds expected value $max_orig, reply counter $repl_cnt" 1>&2
                ret=1
                ok=0
        fi
 
        if [ "$repl_cnt" -gt $max_repl ];then
-               echo "FAIL: $what: reply counter $repl_cnt exceeds expected value $max_repl" 1>&2
+               echo "FAIL: $what: reply counter $repl_cnt exceeds expected value $max_repl, original counter $orig_cnt" 1>&2
                ret=1
                ok=0
        fi
@@ -455,7 +450,7 @@ test_tcp_forwarding_nat()
        return $lret
 }
 
-make_file "$nsin"
+make_file "$nsin" "$filesize"
 
 # First test:
 # No PMTU discovery, nsr1 is expected to fragment packets from ns1 to ns2 as needed.
@@ -664,8 +659,16 @@ if [ "$1" = "" ]; then
        l=$(((RANDOM%mtu) + low))
        r=$(((RANDOM%mtu) + low))
 
-       echo "re-run with random mtus: -o $o -l $l -r $r"
-       $0 -o "$o" -l "$l" -r "$r"
+       MINSIZE=$((2 *  1000 * 1000))
+       MAXSIZE=$((64 * 1000 * 1000))
+
+       filesize=$(((RANDOM * RANDOM) % MAXSIZE))
+       if [ "$filesize" -lt "$MINSIZE" ]; then
+               filesize=$((filesize+MINSIZE))
+       fi
+
+       echo "re-run with random mtus and file size: -o $o -l $l -r $r -s $filesize"
+       $0 -o "$o" -l "$l" -r "$r" -s "$filesize"
 fi
 
 exit $ret
diff --git a/tools/testing/selftests/net/netfilter/vxlan_mtu_frag.sh b/tools/testing/selftests/net/netfilter/vxlan_mtu_frag.sh
new file mode 100755 (executable)
index 0000000..912cb95
--- /dev/null
@@ -0,0 +1,121 @@
+#!/bin/bash
+# SPDX-License-Identifier: GPL-2.0
+
+source lib.sh
+
+if ! modprobe -q -n br_netfilter 2>&1; then
+        echo "SKIP: Test needs br_netfilter kernel module"
+        exit $ksft_skip
+fi
+
+cleanup()
+{
+        cleanup_all_ns
+}
+
+trap cleanup EXIT
+
+setup_ns host vtep router
+
+create_topology()
+{
+    ip link add host-eth0 netns "$host" type veth peer name vtep-host netns "$vtep"
+    ip link add vtep-router netns "$vtep" type veth peer name router-vtep netns "$router"
+}
+
+setup_host()
+{
+    # bring ports up
+    ip -n "$host" addr add 10.0.0.1/24 dev host-eth0
+    ip -n "$host" link set host-eth0 up
+
+    # Add VLAN 10,20
+    for vid in 10 20; do
+        ip -n "$host" link add link host-eth0 name host-eth0.$vid type vlan id $vid
+        ip -n "$host" addr add 10.0.$vid.1/24 dev host-eth0.$vid
+        ip -n "$host" link set host-eth0.$vid up
+    done
+}
+
+setup_vtep()
+{
+    # create bridge on vtep
+    ip -n "$vtep" link add name br0 type bridge
+    ip -n "$vtep" link set br0 type bridge vlan_filtering 1
+
+    # VLAN 10 is untagged PVID
+    ip -n "$vtep" link set dev vtep-host master br0
+    bridge -n "$vtep" vlan add dev vtep-host vid 10 pvid untagged
+
+    # VLAN 20 as other VID
+    ip -n "$vtep" link set dev vtep-host master br0
+    bridge -n "$vtep" vlan add dev vtep-host vid 20
+
+    # single-vxlan device on vtep
+    ip -n "$vtep" address add dev vtep-router 60.0.0.1/24
+    ip -n "$vtep" link add dev vxd type vxlan external \
+        vnifilter local 60.0.0.1 remote 60.0.0.2 dstport 4789 ttl 64
+    ip -n "$vtep" link set vxd master br0
+
+    # Add VLAN-VNI 1-1 mappings
+    bridge -n "$vtep" link set dev vxd vlan_tunnel on
+    for vid in 10 20; do
+        bridge -n "$vtep" vlan add dev vxd vid $vid
+        bridge -n "$vtep" vlan add dev vxd vid $vid tunnel_info id $vid
+        bridge -n "$vtep" vni add dev vxd vni $vid
+    done
+
+    # bring ports up
+    ip -n "$vtep" link set vxd up
+    ip -n "$vtep" link set vtep-router up
+    ip -n "$vtep" link set vtep-host up
+    ip -n "$vtep" link set dev br0 up
+}
+
+setup_router()
+{
+    # bring ports up
+    ip -n "$router" link set router-vtep up
+}
+
+setup()
+{
+    modprobe -q br_netfilter
+    create_topology
+    setup_host
+    setup_vtep
+    setup_router
+}
+
+test_large_mtu_untagged_traffic()
+{
+    ip -n "$vtep" link set vxd mtu 1000
+    ip -n "$host" neigh add 10.0.0.2 lladdr ca:fe:ba:be:00:01 dev host-eth0
+    ip netns exec "$host" \
+        ping -q 10.0.0.2 -I host-eth0 -c 1 -W 0.5 -s2000 > /dev/null 2>&1
+    return 0
+}
+
+test_large_mtu_tagged_traffic()
+{
+    for vid in 10 20; do
+        ip -n "$vtep" link set vxd mtu 1000
+        ip -n "$host" neigh add 10.0.$vid.2 lladdr ca:fe:ba:be:00:01 dev host-eth0.$vid
+        ip netns exec "$host" \
+            ping -q 10.0.$vid.2 -I host-eth0.$vid -c 1 -W 0.5 -s2000 > /dev/null 2>&1
+    done
+    return 0
+}
+
+do_test()
+{
+    # Frames will be dropped so ping will not succeed
+    # If it doesn't panic, it passes
+    test_large_mtu_tagged_traffic
+    test_large_mtu_untagged_traffic
+}
+
+setup && \
+echo "Test for VxLAN fragmentation with large MTU in br_netfilter:" && \
+do_test && echo "PASS!"
+exit $?
diff --git a/tools/testing/selftests/net/rds/.gitignore b/tools/testing/selftests/net/rds/.gitignore
new file mode 100644 (file)
index 0000000..1c6f04e
--- /dev/null
@@ -0,0 +1 @@
+include.sh
index da9714bc7aad325d08c1fca9518cf193ef17c7c0..1803c39dbacb14d567cf6967778c7e3adffdc1f6 100644 (file)
@@ -4,9 +4,10 @@ all:
        @echo mk_build_dir="$(shell pwd)" > include.sh
 
 TEST_PROGS := run.sh \
-       include.sh \
        test.py
 
-EXTRA_CLEAN := /tmp/rds_logs
+TEST_FILES := include.sh
+
+EXTRA_CLEAN := /tmp/rds_logs include.sh
 
 include ../../lib.mk
old mode 100644 (file)
new mode 100755 (executable)
index e6bb109..4a7178d
@@ -14,8 +14,11 @@ import sys
 import atexit
 from pwd import getpwuid
 from os import stat
-from lib.py import ip
 
+# Allow utils module to be imported from different directory
+this_dir = os.path.dirname(os.path.realpath(__file__))
+sys.path.append(os.path.join(this_dir, "../"))
+from lib.py.utils import ip
 
 libc = ctypes.cdll.LoadLibrary('libc.so.6')
 setns = libc.setns
index 59cb26cf3f7384925a0d14ee0cecd75d660d6b83..1ef24119def0acfb051be1d0cb304bf2b29ff98d 100644 (file)
@@ -19,3 +19,7 @@ $(YNL_OUTPUTS): CFLAGS += \
 $(OUTPUT)/libynl.a:
        $(Q)$(MAKE) -C $(top_srcdir)/tools/net/ynl GENS="$(YNL_GENS)" libynl.a
        $(Q)cp $(top_srcdir)/tools/net/ynl/libynl.a $(OUTPUT)/libynl.a
+
+EXTRA_CLEAN += \
+       $(top_srcdir)/tools/net/ynl/lib/__pycache__ \
+       $(top_srcdir)/tools/net/ynl/lib/*.[ado]
index 96e812bdf8a45c7ad7cc0f8d1e8b2b26d6570722..5b9772cdf2651bb924e1c68d50eea83d9c1a3e96 100644 (file)
@@ -60,12 +60,6 @@ unsigned int rseq_size = -1U;
 /* Flags used during rseq registration.  */
 unsigned int rseq_flags;
 
-/*
- * rseq feature size supported by the kernel. 0 if the registration was
- * unsuccessful.
- */
-unsigned int rseq_feature_size = -1U;
-
 static int rseq_ownership;
 static int rseq_reg_success;   /* At least one rseq registration has succeded. */
 
@@ -111,6 +105,43 @@ int rseq_available(void)
        }
 }
 
+/* The rseq areas need to be at least 32 bytes. */
+static
+unsigned int get_rseq_min_alloc_size(void)
+{
+       unsigned int alloc_size = rseq_size;
+
+       if (alloc_size < ORIG_RSEQ_ALLOC_SIZE)
+               alloc_size = ORIG_RSEQ_ALLOC_SIZE;
+       return alloc_size;
+}
+
+/*
+ * Return the feature size supported by the kernel.
+ *
+ * Depending on the value returned by getauxval(AT_RSEQ_FEATURE_SIZE):
+ *
+ * 0:   Return ORIG_RSEQ_FEATURE_SIZE (20)
+ * > 0: Return the value from getauxval(AT_RSEQ_FEATURE_SIZE).
+ *
+ * It should never return a value below ORIG_RSEQ_FEATURE_SIZE.
+ */
+static
+unsigned int get_rseq_kernel_feature_size(void)
+{
+       unsigned long auxv_rseq_feature_size, auxv_rseq_align;
+
+       auxv_rseq_align = getauxval(AT_RSEQ_ALIGN);
+       assert(!auxv_rseq_align || auxv_rseq_align <= RSEQ_THREAD_AREA_ALLOC_SIZE);
+
+       auxv_rseq_feature_size = getauxval(AT_RSEQ_FEATURE_SIZE);
+       assert(!auxv_rseq_feature_size || auxv_rseq_feature_size <= RSEQ_THREAD_AREA_ALLOC_SIZE);
+       if (auxv_rseq_feature_size)
+               return auxv_rseq_feature_size;
+       else
+               return ORIG_RSEQ_FEATURE_SIZE;
+}
+
 int rseq_register_current_thread(void)
 {
        int rc;
@@ -119,7 +150,7 @@ int rseq_register_current_thread(void)
                /* Treat libc's ownership as a successful registration. */
                return 0;
        }
-       rc = sys_rseq(&__rseq_abi, rseq_size, 0, RSEQ_SIG);
+       rc = sys_rseq(&__rseq_abi, get_rseq_min_alloc_size(), 0, RSEQ_SIG);
        if (rc) {
                if (RSEQ_READ_ONCE(rseq_reg_success)) {
                        /* Incoherent success/failure within process. */
@@ -140,28 +171,12 @@ int rseq_unregister_current_thread(void)
                /* Treat libc's ownership as a successful unregistration. */
                return 0;
        }
-       rc = sys_rseq(&__rseq_abi, rseq_size, RSEQ_ABI_FLAG_UNREGISTER, RSEQ_SIG);
+       rc = sys_rseq(&__rseq_abi, get_rseq_min_alloc_size(), RSEQ_ABI_FLAG_UNREGISTER, RSEQ_SIG);
        if (rc)
                return -1;
        return 0;
 }
 
-static
-unsigned int get_rseq_feature_size(void)
-{
-       unsigned long auxv_rseq_feature_size, auxv_rseq_align;
-
-       auxv_rseq_align = getauxval(AT_RSEQ_ALIGN);
-       assert(!auxv_rseq_align || auxv_rseq_align <= RSEQ_THREAD_AREA_ALLOC_SIZE);
-
-       auxv_rseq_feature_size = getauxval(AT_RSEQ_FEATURE_SIZE);
-       assert(!auxv_rseq_feature_size || auxv_rseq_feature_size <= RSEQ_THREAD_AREA_ALLOC_SIZE);
-       if (auxv_rseq_feature_size)
-               return auxv_rseq_feature_size;
-       else
-               return ORIG_RSEQ_FEATURE_SIZE;
-}
-
 static __attribute__((constructor))
 void rseq_init(void)
 {
@@ -178,28 +193,54 @@ void rseq_init(void)
        }
        if (libc_rseq_size_p && libc_rseq_offset_p && libc_rseq_flags_p &&
                        *libc_rseq_size_p != 0) {
+               unsigned int libc_rseq_size;
+
                /* rseq registration owned by glibc */
                rseq_offset = *libc_rseq_offset_p;
-               rseq_size = *libc_rseq_size_p;
+               libc_rseq_size = *libc_rseq_size_p;
                rseq_flags = *libc_rseq_flags_p;
-               rseq_feature_size = get_rseq_feature_size();
-               if (rseq_feature_size > rseq_size)
-                       rseq_feature_size = rseq_size;
+
+               /*
+                * Previous versions of glibc expose the value
+                * 32 even though the kernel only supported 20
+                * bytes initially. Therefore treat 32 as a
+                * special-case. glibc 2.40 exposes a 20 bytes
+                * __rseq_size without using getauxval(3) to
+                * query the supported size, while still allocating a 32
+                * bytes area. Also treat 20 as a special-case.
+                *
+                * Special-cases are handled by using the following
+                * value as active feature set size:
+                *
+                *   rseq_size = min(32, get_rseq_kernel_feature_size())
+                */
+               switch (libc_rseq_size) {
+               case ORIG_RSEQ_FEATURE_SIZE:
+                       fallthrough;
+               case ORIG_RSEQ_ALLOC_SIZE:
+               {
+                       unsigned int rseq_kernel_feature_size = get_rseq_kernel_feature_size();
+
+                       if (rseq_kernel_feature_size < ORIG_RSEQ_ALLOC_SIZE)
+                               rseq_size = rseq_kernel_feature_size;
+                       else
+                               rseq_size = ORIG_RSEQ_ALLOC_SIZE;
+                       break;
+               }
+               default:
+                       /* Otherwise just use the __rseq_size from libc as rseq_size. */
+                       rseq_size = libc_rseq_size;
+                       break;
+               }
                return;
        }
        rseq_ownership = 1;
        if (!rseq_available()) {
                rseq_size = 0;
-               rseq_feature_size = 0;
                return;
        }
        rseq_offset = (void *)&__rseq_abi - rseq_thread_pointer();
        rseq_flags = 0;
-       rseq_feature_size = get_rseq_feature_size();
-       if (rseq_feature_size == ORIG_RSEQ_FEATURE_SIZE)
-               rseq_size = ORIG_RSEQ_ALLOC_SIZE;
-       else
-               rseq_size = RSEQ_THREAD_AREA_ALLOC_SIZE;
 }
 
 static __attribute__((destructor))
@@ -209,7 +250,6 @@ void rseq_exit(void)
                return;
        rseq_offset = 0;
        rseq_size = -1U;
-       rseq_feature_size = -1U;
        rseq_ownership = 0;
 }
 
index d7364ea4d201d206709af51c49d8c7b8e4936c81..4e217b620e0c7a9743b0db06dfd22e3cbdc72d08 100644 (file)
@@ -68,12 +68,6 @@ extern unsigned int rseq_size;
 /* Flags used during rseq registration. */
 extern unsigned int rseq_flags;
 
-/*
- * rseq feature size supported by the kernel. 0 if the registration was
- * unsuccessful.
- */
-extern unsigned int rseq_feature_size;
-
 enum rseq_mo {
        RSEQ_MO_RELAXED = 0,
        RSEQ_MO_CONSUME = 1,    /* Unused */
@@ -193,7 +187,7 @@ static inline uint32_t rseq_current_cpu(void)
 
 static inline bool rseq_node_id_available(void)
 {
-       return (int) rseq_feature_size >= rseq_offsetofend(struct rseq_abi, node_id);
+       return (int) rseq_size >= rseq_offsetofend(struct rseq_abi, node_id);
 }
 
 /*
@@ -207,7 +201,7 @@ static inline uint32_t rseq_current_node_id(void)
 
 static inline bool rseq_mm_cid_available(void)
 {
-       return (int) rseq_feature_size >= rseq_offsetofend(struct rseq_abi, mm_cid);
+       return (int) rseq_size >= rseq_offsetofend(struct rseq_abi, mm_cid);
 }
 
 static inline uint32_t rseq_current_mm_cid(void)
index 9647b14b47c59e5d0ac603de9b7fb9b18072db29..38a8e67de77d6f7ce196f78051f0170badc8054e 100644 (file)
@@ -412,6 +412,8 @@ TEST_F_TIMEOUT(rtc, alarm_wkalm_set_minute, 65) {
 
 int main(int argc, char **argv)
 {
+       int ret = -1;
+
        switch (argc) {
        case 2:
                rtc_file = argv[1];
@@ -423,5 +425,12 @@ int main(int argc, char **argv)
                return 1;
        }
 
-       return test_harness_run(argc, argv);
+       /* Run the test if rtc_file is accessible */
+       if (access(rtc_file, R_OK) == 0)
+               ret = test_harness_run(argc, argv);
+       else
+               ksft_exit_skip("[SKIP]: Cannot access rtc file %s - Exiting\n",
+                                               rtc_file);
+
+       return ret;
 }
index 0754a2c110a1a9d167fb152f8985388ad6b85dd9..0117622246007fda57f7fcec8ff71b4c6a351f95 100644 (file)
@@ -3,23 +3,12 @@
 include ../../../build/Build.include
 include ../../../scripts/Makefile.arch
 include ../../../scripts/Makefile.include
-include ../lib.mk
 
-ifneq ($(LLVM),)
-ifneq ($(filter %/,$(LLVM)),)
-LLVM_PREFIX := $(LLVM)
-else ifneq ($(filter -%,$(LLVM)),)
-LLVM_SUFFIX := $(LLVM)
-endif
-
-CC := $(LLVM_PREFIX)clang$(LLVM_SUFFIX) $(CLANG_FLAGS) -fintegrated-as
-else
-CC := gcc
-endif # LLVM
+TEST_GEN_PROGS := runner
 
-ifneq ($(CROSS_COMPILE),)
-$(error CROSS_COMPILE not supported for scx selftests)
-endif # CROSS_COMPILE
+# override lib.mk's default rules
+OVERRIDE_TARGETS := 1
+include ../lib.mk
 
 CURDIR := $(abspath .)
 REPOROOT := $(abspath ../../../..)
@@ -34,18 +23,23 @@ GENHDR := $(GENDIR)/autoconf.h
 SCXTOOLSDIR := $(TOOLSDIR)/sched_ext
 SCXTOOLSINCDIR := $(TOOLSDIR)/sched_ext/include
 
-OUTPUT_DIR := $(CURDIR)/build
+OUTPUT_DIR := $(OUTPUT)/build
 OBJ_DIR := $(OUTPUT_DIR)/obj
 INCLUDE_DIR := $(OUTPUT_DIR)/include
 BPFOBJ_DIR := $(OBJ_DIR)/libbpf
 SCXOBJ_DIR := $(OBJ_DIR)/sched_ext
 BPFOBJ := $(BPFOBJ_DIR)/libbpf.a
 LIBBPF_OUTPUT := $(OBJ_DIR)/libbpf/libbpf.a
-DEFAULT_BPFTOOL := $(OUTPUT_DIR)/sbin/bpftool
-HOST_BUILD_DIR := $(OBJ_DIR)
-HOST_OUTPUT_DIR := $(OUTPUT_DIR)
 
-VMLINUX_BTF_PATHS ?= ../../../../vmlinux                                       \
+DEFAULT_BPFTOOL := $(OUTPUT_DIR)/host/sbin/bpftool
+HOST_OBJ_DIR := $(OBJ_DIR)/host/bpftool
+HOST_LIBBPF_OUTPUT := $(OBJ_DIR)/host/libbpf/
+HOST_LIBBPF_DESTDIR := $(OUTPUT_DIR)/host/
+HOST_DESTDIR := $(OUTPUT_DIR)/host/
+
+VMLINUX_BTF_PATHS ?= $(if $(O),$(O)/vmlinux)                                   \
+                    $(if $(KBUILD_OUTPUT),$(KBUILD_OUTPUT)/vmlinux)            \
+                    ../../../../vmlinux                                        \
                     /sys/kernel/btf/vmlinux                                    \
                     /boot/vmlinux-$(shell uname -r)
 VMLINUX_BTF ?= $(abspath $(firstword $(wildcard $(VMLINUX_BTF_PATHS))))
@@ -80,17 +74,23 @@ IS_LITTLE_ENDIAN = $(shell $(CC) -dM -E - </dev/null |                              \
 # Use '-idirafter': Don't interfere with include mechanics except where the
 # build would have failed anyways.
 define get_sys_includes
-$(shell $(1) -v -E - </dev/null 2>&1 \
+$(shell $(1) $(2) -v -E - </dev/null 2>&1 \
        | sed -n '/<...> search starts here:/,/End of search list./{ s| \(/.*\)|-idirafter \1|p }') \
-$(shell $(1) -dM -E - </dev/null | grep '__riscv_xlen ' | awk '{printf("-D__riscv_xlen=%d -D__BITS_PER_LONG=%d", $$3, $$3)}')
+$(shell $(1) $(2) -dM -E - </dev/null | grep '__riscv_xlen ' | awk '{printf("-D__riscv_xlen=%d -D__BITS_PER_LONG=%d", $$3, $$3)}')
 endef
 
+ifneq ($(CROSS_COMPILE),)
+CLANG_TARGET_ARCH = --target=$(notdir $(CROSS_COMPILE:%-=%))
+endif
+
+CLANG_SYS_INCLUDES = $(call get_sys_includes,$(CLANG),$(CLANG_TARGET_ARCH))
+
 BPF_CFLAGS = -g -D__TARGET_ARCH_$(SRCARCH)                                     \
             $(if $(IS_LITTLE_ENDIAN),-mlittle-endian,-mbig-endian)             \
             -I$(CURDIR)/include -I$(CURDIR)/include/bpf-compat                 \
             -I$(INCLUDE_DIR) -I$(APIDIR) -I$(SCXTOOLSINCDIR)                   \
             -I$(REPOROOT)/include                                              \
-            $(call get_sys_includes,$(CLANG))                                  \
+            $(CLANG_SYS_INCLUDES)                                              \
             -Wall -Wno-compare-distinct-pointer-types                          \
             -Wno-incompatible-function-pointer-types                           \
             -O2 -mcpu=v3
@@ -98,7 +98,7 @@ BPF_CFLAGS = -g -D__TARGET_ARCH_$(SRCARCH)                                    \
 # sort removes libbpf duplicates when not cross-building
 MAKE_DIRS := $(sort $(OBJ_DIR)/libbpf $(OBJ_DIR)/libbpf                                \
               $(OBJ_DIR)/bpftool $(OBJ_DIR)/resolve_btfids                     \
-              $(INCLUDE_DIR) $(SCXOBJ_DIR))
+              $(HOST_OBJ_DIR) $(INCLUDE_DIR) $(SCXOBJ_DIR))
 
 $(MAKE_DIRS):
        $(call msg,MKDIR,,$@)
@@ -108,18 +108,19 @@ $(BPFOBJ): $(wildcard $(BPFDIR)/*.[ch] $(BPFDIR)/Makefile)                        \
           $(APIDIR)/linux/bpf.h                                                \
           | $(OBJ_DIR)/libbpf
        $(Q)$(MAKE) $(submake_extras) -C $(BPFDIR) OUTPUT=$(OBJ_DIR)/libbpf/    \
+                   ARCH=$(ARCH) CC="$(CC)" CROSS_COMPILE=$(CROSS_COMPILE)      \
                    EXTRA_CFLAGS='-g -O0 -fPIC'                                 \
                    DESTDIR=$(OUTPUT_DIR) prefix= all install_headers
 
 $(DEFAULT_BPFTOOL): $(wildcard $(BPFTOOLDIR)/*.[ch] $(BPFTOOLDIR)/Makefile)    \
-                   $(LIBBPF_OUTPUT) | $(OBJ_DIR)/bpftool
+                   $(LIBBPF_OUTPUT) | $(HOST_OBJ_DIR)
        $(Q)$(MAKE) $(submake_extras)  -C $(BPFTOOLDIR)                         \
                    ARCH= CROSS_COMPILE= CC=$(HOSTCC) LD=$(HOSTLD)              \
                    EXTRA_CFLAGS='-g -O0'                                       \
-                   OUTPUT=$(OBJ_DIR)/bpftool/                                  \
-                   LIBBPF_OUTPUT=$(OBJ_DIR)/libbpf/                            \
-                   LIBBPF_DESTDIR=$(OUTPUT_DIR)/                               \
-                   prefix= DESTDIR=$(OUTPUT_DIR)/ install-bin
+                   OUTPUT=$(HOST_OBJ_DIR)/                                     \
+                   LIBBPF_OUTPUT=$(HOST_LIBBPF_OUTPUT)                         \
+                   LIBBPF_DESTDIR=$(HOST_LIBBPF_DESTDIR)                       \
+                   prefix= DESTDIR=$(HOST_DESTDIR) install-bin
 
 $(INCLUDE_DIR)/vmlinux.h: $(VMLINUX_BTF) $(BPFTOOL) | $(INCLUDE_DIR)
 ifeq ($(VMLINUX_H),)
@@ -150,9 +151,7 @@ $(INCLUDE_DIR)/%.bpf.skel.h: $(SCXOBJ_DIR)/%.bpf.o $(INCLUDE_DIR)/vmlinux.h $(BP
 
 override define CLEAN
        rm -rf $(OUTPUT_DIR)
-       rm -f *.o *.bpf.o *.bpf.skel.h *.bpf.subskel.h
        rm -f $(TEST_GEN_PROGS)
-       rm -f runner
 endef
 
 # Every testcase takes all of the BPF progs are dependencies by default. This
@@ -185,7 +184,7 @@ auto-test-targets :=                        \
 
 testcase-targets := $(addsuffix .o,$(addprefix $(SCXOBJ_DIR)/,$(auto-test-targets)))
 
-$(SCXOBJ_DIR)/runner.o: runner.c | $(SCXOBJ_DIR)
+$(SCXOBJ_DIR)/runner.o: runner.c | $(SCXOBJ_DIR) $(BPFOBJ)
        $(CC) $(CFLAGS) -c $< -o $@
 
 # Create all of the test targets object files, whose testcase objects will be
@@ -196,21 +195,15 @@ $(SCXOBJ_DIR)/runner.o: runner.c | $(SCXOBJ_DIR)
 # function doesn't support using implicit rules otherwise.
 $(testcase-targets): $(SCXOBJ_DIR)/%.o: %.c $(SCXOBJ_DIR)/runner.o $(all_test_bpfprogs) | $(SCXOBJ_DIR)
        $(eval test=$(patsubst %.o,%.c,$(notdir $@)))
-       $(CC) $(CFLAGS) -c $< -o $@ $(SCXOBJ_DIR)/runner.o
+       $(CC) $(CFLAGS) -c $< -o $@
 
 $(SCXOBJ_DIR)/util.o: util.c | $(SCXOBJ_DIR)
        $(CC) $(CFLAGS) -c $< -o $@
 
-runner: $(SCXOBJ_DIR)/runner.o $(SCXOBJ_DIR)/util.o $(BPFOBJ) $(testcase-targets)
+$(OUTPUT)/runner: $(SCXOBJ_DIR)/runner.o $(SCXOBJ_DIR)/util.o $(BPFOBJ) $(testcase-targets)
        @echo "$(testcase-targets)"
        $(CC) $(CFLAGS) -o $@ $^ $(LDFLAGS)
 
-TEST_GEN_PROGS := runner
-
-all: runner
-
-.PHONY: all clean help
-
 .DEFAULT_GOAL := all
 
 .DELETE_ON_ERROR:
index 23f79ed343f02e56b88775fc1f49ea440feafc9a..2cfc4ffd60e28fb282f7ee68aab6585cf480609d 100644 (file)
@@ -51,8 +51,8 @@ s32 BPF_STRUCT_OPS_SLEEPABLE(create_dsq_init)
 
 SEC(".struct_ops.link")
 struct sched_ext_ops create_dsq_ops = {
-       .init_task              = create_dsq_init_task,
-       .exit_task              = create_dsq_exit_task,
-       .init                   = create_dsq_init,
+       .init_task              = (void *) create_dsq_init_task,
+       .exit_task              = (void *) create_dsq_exit_task,
+       .init                   = (void *) create_dsq_init,
        .name                   = "create_dsq",
 };
index e97ad41d354ad857976b24acb1d47ab5b94a6033..37d9bf6fb7458d3ddbfd3de74b3d9f1775574664 100644 (file)
@@ -35,8 +35,8 @@ void BPF_STRUCT_OPS(ddsp_bogus_dsq_fail_exit, struct scx_exit_info *ei)
 
 SEC(".struct_ops.link")
 struct sched_ext_ops ddsp_bogus_dsq_fail_ops = {
-       .select_cpu             = ddsp_bogus_dsq_fail_select_cpu,
-       .exit                   = ddsp_bogus_dsq_fail_exit,
+       .select_cpu             = (void *) ddsp_bogus_dsq_fail_select_cpu,
+       .exit                   = (void *) ddsp_bogus_dsq_fail_exit,
        .name                   = "ddsp_bogus_dsq_fail",
        .timeout_ms             = 1000U,
 };
index dde7e7dafbfbc02fc680c5a1257c6620ab63aa2d..dffc97d9cdf141beffdeecce79f9e8751b0a3a52 100644 (file)
@@ -32,8 +32,8 @@ void BPF_STRUCT_OPS(ddsp_vtimelocal_fail_exit, struct scx_exit_info *ei)
 
 SEC(".struct_ops.link")
 struct sched_ext_ops ddsp_vtimelocal_fail_ops = {
-       .select_cpu             = ddsp_vtimelocal_fail_select_cpu,
-       .exit                   = ddsp_vtimelocal_fail_exit,
+       .select_cpu             = (void *) ddsp_vtimelocal_fail_select_cpu,
+       .exit                   = (void *) ddsp_vtimelocal_fail_exit,
        .name                   = "ddsp_vtimelocal_fail",
        .timeout_ms             = 1000U,
 };
index efb4672decb41c82f6141f3d45f4ec5b4f56511a..6a7db1502c29e1d8a1bca1f224c10c25540e5732 100644 (file)
@@ -56,10 +56,10 @@ void BPF_STRUCT_OPS(dsp_local_on_exit, struct scx_exit_info *ei)
 
 SEC(".struct_ops.link")
 struct sched_ext_ops dsp_local_on_ops = {
-       .select_cpu             = dsp_local_on_select_cpu,
-       .enqueue                = dsp_local_on_enqueue,
-       .dispatch               = dsp_local_on_dispatch,
-       .exit                   = dsp_local_on_exit,
+       .select_cpu             = (void *) dsp_local_on_select_cpu,
+       .enqueue                = (void *) dsp_local_on_enqueue,
+       .dispatch               = (void *) dsp_local_on_dispatch,
+       .exit                   = (void *) dsp_local_on_exit,
        .name                   = "dsp_local_on",
        .timeout_ms             = 1000U,
 };
index b0b99531d5d5d4612e340cd46f67dfb5fcf927a9..e1bd13e48889f107b2fbae271b16f6976285212a 100644 (file)
 
 char _license[] SEC("license") = "GPL";
 
+u32 exit_kind;
+
+void BPF_STRUCT_OPS_SLEEPABLE(enq_last_no_enq_fails_exit, struct scx_exit_info *info)
+{
+       exit_kind = info->kind;
+}
+
 SEC(".struct_ops.link")
 struct sched_ext_ops enq_last_no_enq_fails_ops = {
        .name                   = "enq_last_no_enq_fails",
        /* Need to define ops.enqueue() with SCX_OPS_ENQ_LAST */
        .flags                  = SCX_OPS_ENQ_LAST,
+       .exit                   = (void *) enq_last_no_enq_fails_exit,
        .timeout_ms             = 1000U,
 };
index 2a3eda5e2c0b475f7fc185025f45e9146b3d6282..73e679953e27ae15d7341450b6137273db849179 100644 (file)
@@ -31,8 +31,12 @@ static enum scx_test_status run(void *ctx)
        struct bpf_link *link;
 
        link = bpf_map__attach_struct_ops(skel->maps.enq_last_no_enq_fails_ops);
-       if (link) {
-               SCX_ERR("Incorrectly succeeded in to attaching scheduler");
+       if (!link) {
+               SCX_ERR("Incorrectly failed at attaching scheduler");
+               return SCX_TEST_FAIL;
+       }
+       if (!skel->bss->exit_kind) {
+               SCX_ERR("Incorrectly stayed loaded");
                return SCX_TEST_FAIL;
        }
 
@@ -50,7 +54,7 @@ static void cleanup(void *ctx)
 
 struct scx_test enq_last_no_enq_fails = {
        .name = "enq_last_no_enq_fails",
-       .description = "Verify we fail to load a scheduler if we specify "
+       .description = "Verify we eject a scheduler if we specify "
                       "the SCX_OPS_ENQ_LAST flag without defining "
                       "ops.enqueue()",
        .setup = setup,
index b3dfc1033cd6a6ae7f527395ec5419ca3c3f04c7..1efb50d61040ad3832d5cea89c11200593691069 100644 (file)
@@ -36,8 +36,8 @@ void BPF_STRUCT_OPS(enq_select_cpu_fails_enqueue, struct task_struct *p,
 
 SEC(".struct_ops.link")
 struct sched_ext_ops enq_select_cpu_fails_ops = {
-       .select_cpu             = enq_select_cpu_fails_select_cpu,
-       .enqueue                = enq_select_cpu_fails_enqueue,
+       .select_cpu             = (void *) enq_select_cpu_fails_select_cpu,
+       .enqueue                = (void *) enq_select_cpu_fails_enqueue,
        .name                   = "enq_select_cpu_fails",
        .timeout_ms             = 1000U,
 };
index ae12ddaac921b054a68a2805df670f8e03c888ca..d75d4faf07f6d5690801695288306c358e3a5e84 100644 (file)
@@ -15,6 +15,8 @@ UEI_DEFINE(uei);
 
 #define EXIT_CLEANLY() scx_bpf_exit(exit_point, "%d", exit_point)
 
+#define DSQ_ID 0
+
 s32 BPF_STRUCT_OPS(exit_select_cpu, struct task_struct *p,
                   s32 prev_cpu, u64 wake_flags)
 {
@@ -31,7 +33,7 @@ void BPF_STRUCT_OPS(exit_enqueue, struct task_struct *p, u64 enq_flags)
        if (exit_point == EXIT_ENQUEUE)
                EXIT_CLEANLY();
 
-       scx_bpf_dispatch(p, SCX_DSQ_GLOBAL, SCX_SLICE_DFL, enq_flags);
+       scx_bpf_dispatch(p, DSQ_ID, SCX_SLICE_DFL, enq_flags);
 }
 
 void BPF_STRUCT_OPS(exit_dispatch, s32 cpu, struct task_struct *p)
@@ -39,7 +41,7 @@ void BPF_STRUCT_OPS(exit_dispatch, s32 cpu, struct task_struct *p)
        if (exit_point == EXIT_DISPATCH)
                EXIT_CLEANLY();
 
-       scx_bpf_consume(SCX_DSQ_GLOBAL);
+       scx_bpf_consume(DSQ_ID);
 }
 
 void BPF_STRUCT_OPS(exit_enable, struct task_struct *p)
@@ -67,18 +69,18 @@ s32 BPF_STRUCT_OPS_SLEEPABLE(exit_init)
        if (exit_point == EXIT_INIT)
                EXIT_CLEANLY();
 
-       return 0;
+       return scx_bpf_create_dsq(DSQ_ID, -1);
 }
 
 SEC(".struct_ops.link")
 struct sched_ext_ops exit_ops = {
-       .select_cpu             = exit_select_cpu,
-       .enqueue                = exit_enqueue,
-       .dispatch               = exit_dispatch,
-       .init_task              = exit_init_task,
-       .enable                 = exit_enable,
-       .exit                   = exit_exit,
-       .init                   = exit_init,
+       .select_cpu             = (void *) exit_select_cpu,
+       .enqueue                = (void *) exit_enqueue,
+       .dispatch               = (void *) exit_dispatch,
+       .init_task              = (void *) exit_init_task,
+       .enable                 = (void *) exit_enable,
+       .exit                   = (void *) exit_exit,
+       .init                   = (void *) exit_init,
        .name                   = "exit",
        .timeout_ms             = 1000U,
 };
index 8f2601db39f370b8f8e52f984c41181e809081a3..6c9f25c9bf53e58534ea20cc2c8a202636f532cd 100644 (file)
@@ -46,16 +46,16 @@ void BPF_STRUCT_OPS_SLEEPABLE(hotplug_cpu_offline, s32 cpu)
 
 SEC(".struct_ops.link")
 struct sched_ext_ops hotplug_cb_ops = {
-       .cpu_online             = hotplug_cpu_online,
-       .cpu_offline            = hotplug_cpu_offline,
-       .exit                   = hotplug_exit,
+       .cpu_online             = (void *) hotplug_cpu_online,
+       .cpu_offline            = (void *) hotplug_cpu_offline,
+       .exit                   = (void *) hotplug_exit,
        .name                   = "hotplug_cbs",
        .timeout_ms             = 1000U,
 };
 
 SEC(".struct_ops.link")
 struct sched_ext_ops hotplug_nocb_ops = {
-       .exit                   = hotplug_exit,
+       .exit                   = (void *) hotplug_exit,
        .name                   = "hotplug_nocbs",
        .timeout_ms             = 1000U,
 };
index 47ea89a626c3754bd5fe4d02a0d54b219e224335..5eb9edb1837dc7f6a940195dda055acf317c97d6 100644 (file)
@@ -45,9 +45,9 @@ void BPF_STRUCT_OPS(cnt_disable, struct task_struct *p)
 
 SEC(".struct_ops.link")
 struct sched_ext_ops init_enable_count_ops = {
-       .init_task      = cnt_init_task,
-       .exit_task      = cnt_exit_task,
-       .enable         = cnt_enable,
-       .disable        = cnt_disable,
+       .init_task      = (void *) cnt_init_task,
+       .exit_task      = (void *) cnt_exit_task,
+       .enable         = (void *) cnt_enable,
+       .disable        = (void *) cnt_disable,
        .name           = "init_enable_count",
 };
index 00bfa9cb95d382dd6063a18c230dee1b7212d7db..4d4cd8d966dba646f2718f8ab126726b7c3ad375 100644 (file)
@@ -131,34 +131,34 @@ void BPF_STRUCT_OPS(maximal_exit, struct scx_exit_info *info)
 
 SEC(".struct_ops.link")
 struct sched_ext_ops maximal_ops = {
-       .select_cpu             = maximal_select_cpu,
-       .enqueue                = maximal_enqueue,
-       .dequeue                = maximal_dequeue,
-       .dispatch               = maximal_dispatch,
-       .runnable               = maximal_runnable,
-       .running                = maximal_running,
-       .stopping               = maximal_stopping,
-       .quiescent              = maximal_quiescent,
-       .yield                  = maximal_yield,
-       .core_sched_before      = maximal_core_sched_before,
-       .set_weight             = maximal_set_weight,
-       .set_cpumask            = maximal_set_cpumask,
-       .update_idle            = maximal_update_idle,
-       .cpu_acquire            = maximal_cpu_acquire,
-       .cpu_release            = maximal_cpu_release,
-       .cpu_online             = maximal_cpu_online,
-       .cpu_offline            = maximal_cpu_offline,
-       .init_task              = maximal_init_task,
-       .enable                 = maximal_enable,
-       .exit_task              = maximal_exit_task,
-       .disable                = maximal_disable,
-       .cgroup_init            = maximal_cgroup_init,
-       .cgroup_exit            = maximal_cgroup_exit,
-       .cgroup_prep_move       = maximal_cgroup_prep_move,
-       .cgroup_move            = maximal_cgroup_move,
-       .cgroup_cancel_move     = maximal_cgroup_cancel_move,
-       .cgroup_set_weight      = maximal_cgroup_set_weight,
-       .init                   = maximal_init,
-       .exit                   = maximal_exit,
+       .select_cpu             = (void *) maximal_select_cpu,
+       .enqueue                = (void *) maximal_enqueue,
+       .dequeue                = (void *) maximal_dequeue,
+       .dispatch               = (void *) maximal_dispatch,
+       .runnable               = (void *) maximal_runnable,
+       .running                = (void *) maximal_running,
+       .stopping               = (void *) maximal_stopping,
+       .quiescent              = (void *) maximal_quiescent,
+       .yield                  = (void *) maximal_yield,
+       .core_sched_before      = (void *) maximal_core_sched_before,
+       .set_weight             = (void *) maximal_set_weight,
+       .set_cpumask            = (void *) maximal_set_cpumask,
+       .update_idle            = (void *) maximal_update_idle,
+       .cpu_acquire            = (void *) maximal_cpu_acquire,
+       .cpu_release            = (void *) maximal_cpu_release,
+       .cpu_online             = (void *) maximal_cpu_online,
+       .cpu_offline            = (void *) maximal_cpu_offline,
+       .init_task              = (void *) maximal_init_task,
+       .enable                 = (void *) maximal_enable,
+       .exit_task              = (void *) maximal_exit_task,
+       .disable                = (void *) maximal_disable,
+       .cgroup_init            = (void *) maximal_cgroup_init,
+       .cgroup_exit            = (void *) maximal_cgroup_exit,
+       .cgroup_prep_move       = (void *) maximal_cgroup_prep_move,
+       .cgroup_move            = (void *) maximal_cgroup_move,
+       .cgroup_cancel_move     = (void *) maximal_cgroup_cancel_move,
+       .cgroup_set_weight      = (void *) maximal_cgroup_set_weight,
+       .init                   = (void *) maximal_init,
+       .exit                   = (void *) maximal_exit,
        .name                   = "maximal",
 };
index 27d0f386acfb1de6980bc9d49578b722e7d69996..cf4ae870cd4e56b0ddcf2cb868da71dfafcad00d 100644 (file)
@@ -29,8 +29,8 @@ bool BPF_STRUCT_OPS(maybe_null_success_yield, struct task_struct *from,
 
 SEC(".struct_ops.link")
 struct sched_ext_ops maybe_null_success = {
-       .dispatch               = maybe_null_success_dispatch,
-       .yield                  = maybe_null_success_yield,
-       .enable                 = maybe_null_running,
+       .dispatch               = (void *) maybe_null_success_dispatch,
+       .yield                  = (void *) maybe_null_success_yield,
+       .enable                 = (void *) maybe_null_running,
        .name                   = "minimal",
 };
index c0641050271d32dc4b88628122880663080c5736..ec724d7b33d18dc692e882ef0dbb322479ea92f3 100644 (file)
@@ -19,7 +19,7 @@ void BPF_STRUCT_OPS(maybe_null_fail_dispatch, s32 cpu, struct task_struct *p)
 
 SEC(".struct_ops.link")
 struct sched_ext_ops maybe_null_fail = {
-       .dispatch               = maybe_null_fail_dispatch,
-       .enable                 = maybe_null_running,
+       .dispatch               = (void *) maybe_null_fail_dispatch,
+       .enable                 = (void *) maybe_null_running,
        .name                   = "maybe_null_fail_dispatch",
 };
index 3c1740028e3b9a2ec6547a134688662937f65637..e6552cace020e5757b5c74d260fb4c5f36b61b74 100644 (file)
@@ -22,7 +22,7 @@ bool BPF_STRUCT_OPS(maybe_null_fail_yield, struct task_struct *from,
 
 SEC(".struct_ops.link")
 struct sched_ext_ops maybe_null_fail = {
-       .yield                  = maybe_null_fail_yield,
-       .enable                 = maybe_null_running,
+       .yield                  = (void *) maybe_null_fail_yield,
+       .enable                 = (void *) maybe_null_running,
        .name                   = "maybe_null_fail_yield",
 };
index 6a4d7c48e3f224e452e6de4b417bc91e39131ae1..00c267626a68fe558aa478b203175e027c9d9b18 100644 (file)
@@ -28,6 +28,6 @@ void BPF_STRUCT_OPS(prog_run_exit, struct scx_exit_info *ei)
 
 SEC(".struct_ops.link")
 struct sched_ext_ops prog_run_ops = {
-       .exit                   = prog_run_exit,
+       .exit                   = (void *) prog_run_exit,
        .name                   = "prog_run",
 };
index 2ed2991afafe387526a206b5fb26967d9828ffcc..f171ac47097060be0ff3a72ef13385cc00502126 100644 (file)
@@ -35,6 +35,6 @@ void BPF_STRUCT_OPS(select_cpu_dfl_enqueue, struct task_struct *p,
 
 SEC(".struct_ops.link")
 struct sched_ext_ops select_cpu_dfl_ops = {
-       .enqueue                = select_cpu_dfl_enqueue,
+       .enqueue                = (void *) select_cpu_dfl_enqueue,
        .name                   = "select_cpu_dfl",
 };
index 4bb5abb2d36900270c5be0f64072031812cabd95..9efdbb7da92887d0eec403e130783bd7b106e88e 100644 (file)
@@ -82,8 +82,8 @@ s32 BPF_STRUCT_OPS(select_cpu_dfl_nodispatch_init_task,
 
 SEC(".struct_ops.link")
 struct sched_ext_ops select_cpu_dfl_nodispatch_ops = {
-       .select_cpu             = select_cpu_dfl_nodispatch_select_cpu,
-       .enqueue                = select_cpu_dfl_nodispatch_enqueue,
-       .init_task              = select_cpu_dfl_nodispatch_init_task,
+       .select_cpu             = (void *) select_cpu_dfl_nodispatch_select_cpu,
+       .enqueue                = (void *) select_cpu_dfl_nodispatch_enqueue,
+       .init_task              = (void *) select_cpu_dfl_nodispatch_init_task,
        .name                   = "select_cpu_dfl_nodispatch",
 };
index f0b96a4a04b2c74ecd498ea4c2deeec464381a8d..59bfc4f36167a704c8980304dc09fc7a51ff1456 100644 (file)
@@ -35,7 +35,7 @@ dispatch:
 
 SEC(".struct_ops.link")
 struct sched_ext_ops select_cpu_dispatch_ops = {
-       .select_cpu             = select_cpu_dispatch_select_cpu,
+       .select_cpu             = (void *) select_cpu_dispatch_select_cpu,
        .name                   = "select_cpu_dispatch",
        .timeout_ms             = 1000U,
 };
index 7b42ddce0f56c19a01c0cb414a9d786284ebbc13..3bbd5fcdfb18e0aa64a3a68b79d6db4573218d03 100644 (file)
@@ -30,8 +30,8 @@ void BPF_STRUCT_OPS(select_cpu_dispatch_bad_dsq_exit, struct scx_exit_info *ei)
 
 SEC(".struct_ops.link")
 struct sched_ext_ops select_cpu_dispatch_bad_dsq_ops = {
-       .select_cpu             = select_cpu_dispatch_bad_dsq_select_cpu,
-       .exit                   = select_cpu_dispatch_bad_dsq_exit,
+       .select_cpu             = (void *) select_cpu_dispatch_bad_dsq_select_cpu,
+       .exit                   = (void *) select_cpu_dispatch_bad_dsq_exit,
        .name                   = "select_cpu_dispatch_bad_dsq",
        .timeout_ms             = 1000U,
 };
index 653e3dc0b4dc8c7f0cbb7b68553c8540dc2565d7..0fda57fe0ecfaecc5a5cfaebe2589f563f7ad579 100644 (file)
@@ -31,8 +31,8 @@ void BPF_STRUCT_OPS(select_cpu_dispatch_dbl_dsp_exit, struct scx_exit_info *ei)
 
 SEC(".struct_ops.link")
 struct sched_ext_ops select_cpu_dispatch_dbl_dsp_ops = {
-       .select_cpu             = select_cpu_dispatch_dbl_dsp_select_cpu,
-       .exit                   = select_cpu_dispatch_dbl_dsp_exit,
+       .select_cpu             = (void *) select_cpu_dispatch_dbl_dsp_select_cpu,
+       .exit                   = (void *) select_cpu_dispatch_dbl_dsp_exit,
        .name                   = "select_cpu_dispatch_dbl_dsp",
        .timeout_ms             = 1000U,
 };
index 7f3ebf4fc2ead27a39726c14132fb132691d36c1..e6c67bcf5e6e35f82e47ce139476a375f509c2cb 100644 (file)
@@ -81,12 +81,12 @@ s32 BPF_STRUCT_OPS_SLEEPABLE(select_cpu_vtime_init)
 
 SEC(".struct_ops.link")
 struct sched_ext_ops select_cpu_vtime_ops = {
-       .select_cpu             = select_cpu_vtime_select_cpu,
-       .dispatch               = select_cpu_vtime_dispatch,
-       .running                = select_cpu_vtime_running,
-       .stopping               = select_cpu_vtime_stopping,
-       .enable                 = select_cpu_vtime_enable,
-       .init                   = select_cpu_vtime_init,
+       .select_cpu             = (void *) select_cpu_vtime_select_cpu,
+       .dispatch               = (void *) select_cpu_vtime_dispatch,
+       .running                = (void *) select_cpu_vtime_running,
+       .stopping               = (void *) select_cpu_vtime_stopping,
+       .enable                 = (void *) select_cpu_vtime_enable,
+       .init                   = (void *) select_cpu_vtime_init,
        .name                   = "select_cpu_vtime",
        .timeout_ms             = 1000U,
 };
index 16bd49492efa2ea6a7b73796d6d665f04fa14579..ddb1cebc844eeba2b82f49c5a8dce34044385078 100644 (file)
 static void __fatal_error(const char *test, const char *name, const char *what)
 {
        char buf[64];
+       char *ret_str = NULL;
 
-       strerror_r(errno, buf, sizeof(buf));
+       ret_str = strerror_r(errno, buf, sizeof(buf));
 
-       if (name && strlen(name))
-               ksft_exit_fail_msg("%s %s %s %s\n", test, name, what, buf);
+       if (name && strlen(name) && ret_str)
+               ksft_exit_fail_msg("%s %s %s %s\n", test, name, what, ret_str);
+       else if (ret_str)
+               ksft_exit_fail_msg("%s %s %s\n", test, what, ret_str);
        else
-               ksft_exit_fail_msg("%s %s %s\n", test, what, buf);
+               ksft_exit_fail_msg("%s %s\n", test, what);
+
 }
 
 #define fatal_error(name, what)        __fatal_error(__func__, name, what)
index af9cedbf5357fdae2ce4909e30bde36ecccedc07..1cf14a8da43803249f72fe1b09689c8834806986 100644 (file)
@@ -9,10 +9,8 @@ ifeq ($(ARCH),$(filter $(ARCH),x86 x86_64))
 TEST_GEN_PROGS += vdso_standalone_test_x86
 endif
 TEST_GEN_PROGS += vdso_test_correctness
-ifeq ($(ARCH)$(CONFIG_X86_32),$(filter $(ARCH)$(CONFIG_X86_32),x86 x86_64 loongarch arm64 powerpc s390))
 TEST_GEN_PROGS += vdso_test_getrandom
 TEST_GEN_PROGS += vdso_test_chacha
-endif
 
 CFLAGS := -std=gnu99 -O2
 
@@ -37,9 +35,9 @@ $(OUTPUT)/vdso_test_getrandom: CFLAGS += -isystem $(top_srcdir)/tools/include \
                                          $(KHDR_INCLUDES) \
                                          -isystem $(top_srcdir)/include/uapi
 
-$(OUTPUT)/vdso_test_chacha: $(top_srcdir)/tools/arch/$(SRCARCH)/vdso/vgetrandom-chacha.S
+$(OUTPUT)/vdso_test_chacha: vgetrandom-chacha.S
 $(OUTPUT)/vdso_test_chacha: CFLAGS += -idirafter $(top_srcdir)/tools/include \
                                       -idirafter $(top_srcdir)/tools/include/generated \
                                       -idirafter $(top_srcdir)/arch/$(SRCARCH)/include \
                                       -idirafter $(top_srcdir)/include \
-                                      -D__ASSEMBLY__ -Wa,--noexecstack
+                                      -Wa,--noexecstack
index b1ea532c59961e4afac4aee717710c872a76fb11..8757f738b0b1a76a48c83c5e5df79925a30c1bc7 100644 (file)
@@ -3,6 +3,7 @@
  * Copyright (C) 2022-2024 Jason A. Donenfeld <[email protected]>. All Rights Reserved.
  */
 
+#include <linux/compiler.h>
 #include <tools/le_byteshift.h>
 #include <sys/random.h>
 #include <sys/auxv.h>
@@ -73,10 +74,10 @@ static void reference_chacha20_blocks(uint8_t *dst_bytes, const uint32_t *key, u
        counter[1] = s[13];
 }
 
-typedef uint8_t u8;
-typedef uint32_t u32;
-typedef uint64_t u64;
-#include <vdso/getrandom.h>
+void __weak __arch_chacha20_blocks_nostack(uint8_t *dst_bytes, const uint32_t *key, uint32_t *counter, size_t nblocks)
+{
+       ksft_exit_skip("Not implemented on architecture\n");
+}
 
 int main(int argc, char *argv[])
 {
@@ -90,10 +91,8 @@ int main(int argc, char *argv[])
        ksft_set_plan(1);
 
        for (unsigned int trial = 0; trial < TRIALS; ++trial) {
-               if (getrandom(key, sizeof(key), 0) != sizeof(key)) {
-                       printf("getrandom() failed!\n");
-                       return KSFT_SKIP;
-               }
+               if (getrandom(key, sizeof(key), 0) != sizeof(key))
+                       ksft_exit_skip("getrandom() failed unexpectedly\n");
                memset(counter1, 0, sizeof(counter1));
                reference_chacha20_blocks(output1, key, counter1, BLOCKS);
                for (unsigned int split = 0; split < BLOCKS; ++split) {
@@ -102,8 +101,10 @@ int main(int argc, char *argv[])
                        if (split)
                                __arch_chacha20_blocks_nostack(output2, key, counter2, split);
                        __arch_chacha20_blocks_nostack(output2 + split * BLOCK_SIZE, key, counter2, BLOCKS - split);
-                       if (memcmp(output1, output2, sizeof(output1)) || memcmp(counter1, counter2, sizeof(counter1)))
-                               return KSFT_FAIL;
+                       if (memcmp(output1, output2, sizeof(output1)))
+                               ksft_exit_fail_msg("Main loop outputs do not match on trial %u, split %u\n", trial, split);
+                       if (memcmp(counter1, counter2, sizeof(counter1)))
+                               ksft_exit_fail_msg("Main loop counters do not match on trial %u, split %u\n", trial, split);
                }
        }
        memset(counter1, 0, sizeof(counter1));
@@ -113,14 +114,19 @@ int main(int argc, char *argv[])
 
        reference_chacha20_blocks(output1, key, counter1, BLOCKS);
        __arch_chacha20_blocks_nostack(output2, key, counter2, BLOCKS);
-       if (memcmp(output1, output2, sizeof(output1)) || memcmp(counter1, counter2, sizeof(counter1)))
-               return KSFT_FAIL;
+       if (memcmp(output1, output2, sizeof(output1)))
+               ksft_exit_fail_msg("Block limit outputs do not match after first round\n");
+       if (memcmp(counter1, counter2, sizeof(counter1)))
+               ksft_exit_fail_msg("Block limit counters do not match after first round\n");
 
        reference_chacha20_blocks(output1, key, counter1, BLOCKS);
        __arch_chacha20_blocks_nostack(output2, key, counter2, BLOCKS);
-       if (memcmp(output1, output2, sizeof(output1)) || memcmp(counter1, counter2, sizeof(counter1)))
-               return KSFT_FAIL;
+       if (memcmp(output1, output2, sizeof(output1)))
+               ksft_exit_fail_msg("Block limit outputs do not match after second round\n");
+       if (memcmp(counter1, counter2, sizeof(counter1)))
+               ksft_exit_fail_msg("Block limit counters do not match after second round\n");
 
        ksft_test_result_pass("chacha: PASS\n");
-       return KSFT_PASS;
+       ksft_exit_pass();
+       return 0;
 }
index 72a1d9b43a84445f3f45e599201cac30ee021a7a..95057f7567db22226d9cb09a667a56e387a33a46 100644 (file)
@@ -11,6 +11,7 @@
 #include <string.h>
 #include <time.h>
 #include <unistd.h>
+#include <sched.h>
 #include <signal.h>
 #include <sys/auxv.h>
 #include <sys/mman.h>
@@ -40,6 +41,9 @@
        } while (0)
 #endif
 
+#define ksft_assert(condition) \
+       do { if (!(condition)) ksft_exit_fail_msg("Assertion failed: %s\n", #condition); } while (0)
+
 static struct {
        pthread_mutex_t lock;
        void **states;
@@ -59,10 +63,12 @@ static void *vgetrandom_get_state(void)
                size_t page_size = getpagesize();
                size_t new_cap;
                size_t alloc_size, num = sysconf(_SC_NPROCESSORS_ONLN); /* Just a decent heuristic. */
+               size_t state_size_aligned, cache_line_size = sysconf(_SC_LEVEL1_DCACHE_LINESIZE) ?: 1;
                void *new_block, *new_states;
 
-               alloc_size = (num * vgrnd.params.size_of_opaque_state + page_size - 1) & (~(page_size - 1));
-               num = (page_size / vgrnd.params.size_of_opaque_state) * (alloc_size / page_size);
+               state_size_aligned = (vgrnd.params.size_of_opaque_state + cache_line_size - 1) & (~(cache_line_size - 1));
+               alloc_size = (num * state_size_aligned + page_size - 1) & (~(page_size - 1));
+               num = (page_size / state_size_aligned) * (alloc_size / page_size);
                new_block = mmap(0, alloc_size, vgrnd.params.mmap_prot, vgrnd.params.mmap_flags, -1, 0);
                if (new_block == MAP_FAILED)
                        goto out;
@@ -78,7 +84,7 @@ static void *vgetrandom_get_state(void)
                        if (((uintptr_t)new_block & (page_size - 1)) + vgrnd.params.size_of_opaque_state > page_size)
                                new_block = (void *)(((uintptr_t)new_block + page_size - 1) & (~(page_size - 1)));
                        vgrnd.states[i] = new_block;
-                       new_block += vgrnd.params.size_of_opaque_state;
+                       new_block += state_size_aligned;
                }
                vgrnd.len = num;
                goto success;
@@ -109,26 +115,19 @@ static void vgetrandom_init(void)
        const char *version = versions[VDSO_VERSION];
        const char *name = names[VDSO_NAMES][6];
        unsigned long sysinfo_ehdr = getauxval(AT_SYSINFO_EHDR);
-       size_t ret;
+       ssize_t ret;
 
-       if (!sysinfo_ehdr) {
-               printf("AT_SYSINFO_EHDR is not present!\n");
-               exit(KSFT_SKIP);
-       }
+       if (!sysinfo_ehdr)
+               ksft_exit_skip("AT_SYSINFO_EHDR is not present\n");
        vdso_init_from_sysinfo_ehdr(sysinfo_ehdr);
        vgrnd.fn = (__typeof__(vgrnd.fn))vdso_sym(version, name);
-       if (!vgrnd.fn) {
-               printf("%s is missing!\n", name);
-               exit(KSFT_FAIL);
-       }
+       if (!vgrnd.fn)
+               ksft_exit_skip("%s@%s symbol is missing from vDSO\n", name, version);
        ret = VDSO_CALL(vgrnd.fn, 5, NULL, 0, 0, &vgrnd.params, ~0UL);
-       if (ret == -ENOSYS) {
-               printf("unsupported architecture\n");
-               exit(KSFT_SKIP);
-       } else if (ret) {
-               printf("failed to fetch vgetrandom params!\n");
-               exit(KSFT_FAIL);
-       }
+       if (ret == -ENOSYS)
+               ksft_exit_skip("CPU does not have runtime support\n");
+       else if (ret)
+               ksft_exit_fail_msg("Failed to fetch vgetrandom params: %zd\n", ret);
 }
 
 static ssize_t vgetrandom(void *buf, size_t len, unsigned long flags)
@@ -137,10 +136,7 @@ static ssize_t vgetrandom(void *buf, size_t len, unsigned long flags)
 
        if (!state) {
                state = vgetrandom_get_state();
-               if (!state) {
-                       printf("vgetrandom_get_state failed!\n");
-                       exit(KSFT_FAIL);
-               }
+               ksft_assert(state);
        }
        return VDSO_CALL(vgrnd.fn, 5, buf, len, flags, state, vgrnd.params.size_of_opaque_state);
 }
@@ -152,7 +148,7 @@ static void *test_vdso_getrandom(void *ctx)
        for (size_t i = 0; i < TRIALS; ++i) {
                unsigned int val;
                ssize_t ret = vgetrandom(&val, sizeof(val), 0);
-               assert(ret == sizeof(val));
+               ksft_assert(ret == sizeof(val));
        }
        return NULL;
 }
@@ -162,7 +158,7 @@ static void *test_libc_getrandom(void *ctx)
        for (size_t i = 0; i < TRIALS; ++i) {
                unsigned int val;
                ssize_t ret = getrandom(&val, sizeof(val), 0);
-               assert(ret == sizeof(val));
+               ksft_assert(ret == sizeof(val));
        }
        return NULL;
 }
@@ -172,7 +168,7 @@ static void *test_syscall_getrandom(void *ctx)
        for (size_t i = 0; i < TRIALS; ++i) {
                unsigned int val;
                ssize_t ret = syscall(__NR_getrandom, &val, sizeof(val), 0);
-               assert(ret == sizeof(val));
+               ksft_assert(ret == sizeof(val));
        }
        return NULL;
 }
@@ -207,7 +203,7 @@ static void bench_multi(void)
 
        clock_gettime(CLOCK_MONOTONIC, &start);
        for (size_t i = 0; i < THREADS; ++i)
-               assert(pthread_create(&threads[i], NULL, test_vdso_getrandom, NULL) == 0);
+               ksft_assert(pthread_create(&threads[i], NULL, test_vdso_getrandom, NULL) == 0);
        for (size_t i = 0; i < THREADS; ++i)
                pthread_join(threads[i], NULL);
        clock_gettime(CLOCK_MONOTONIC, &end);
@@ -216,7 +212,7 @@ static void bench_multi(void)
 
        clock_gettime(CLOCK_MONOTONIC, &start);
        for (size_t i = 0; i < THREADS; ++i)
-               assert(pthread_create(&threads[i], NULL, test_libc_getrandom, NULL) == 0);
+               ksft_assert(pthread_create(&threads[i], NULL, test_libc_getrandom, NULL) == 0);
        for (size_t i = 0; i < THREADS; ++i)
                pthread_join(threads[i], NULL);
        clock_gettime(CLOCK_MONOTONIC, &end);
@@ -225,7 +221,7 @@ static void bench_multi(void)
 
        clock_gettime(CLOCK_MONOTONIC, &start);
        for (size_t i = 0; i < THREADS; ++i)
-               assert(pthread_create(&threads[i], NULL, test_syscall_getrandom, NULL) == 0);
+               ksft_assert(pthread_create(&threads[i], NULL, test_syscall_getrandom, NULL) == 0);
        for (size_t i = 0; i < THREADS; ++i)
                pthread_join(threads[i], NULL);
        clock_gettime(CLOCK_MONOTONIC, &end);
@@ -250,48 +246,46 @@ static void kselftest(void)
 
        for (size_t i = 0; i < 1000; ++i) {
                ssize_t ret = vgetrandom(weird_size, sizeof(weird_size), 0);
-               if (ret != sizeof(weird_size))
-                       exit(KSFT_FAIL);
+               ksft_assert(ret == sizeof(weird_size));
        }
 
        ksft_test_result_pass("getrandom: PASS\n");
 
        unshare(CLONE_NEWUSER);
-       assert(unshare(CLONE_NEWTIME) == 0);
+       ksft_assert(unshare(CLONE_NEWTIME) == 0);
        child = fork();
-       assert(child >= 0);
+       ksft_assert(child >= 0);
        if (!child) {
                vgetrandom_init();
                child = getpid();
-               assert(ptrace(PTRACE_TRACEME, 0, NULL, NULL) == 0);
-               assert(kill(child, SIGSTOP) == 0);
-               assert(vgetrandom(weird_size, sizeof(weird_size), 0) == sizeof(weird_size));
+               ksft_assert(ptrace(PTRACE_TRACEME, 0, NULL, NULL) == 0);
+               ksft_assert(kill(child, SIGSTOP) == 0);
+               ksft_assert(vgetrandom(weird_size, sizeof(weird_size), 0) == sizeof(weird_size));
                _exit(0);
        }
        for (;;) {
                struct ptrace_syscall_info info = { 0 };
                int status, ret;
-               assert(waitpid(child, &status, 0) >= 0);
+               ksft_assert(waitpid(child, &status, 0) >= 0);
                if (WIFEXITED(status)) {
-                       if (WEXITSTATUS(status) != 0)
-                               exit(KSFT_FAIL);
+                       ksft_assert(WEXITSTATUS(status) == 0);
                        break;
                }
-               assert(WIFSTOPPED(status));
+               ksft_assert(WIFSTOPPED(status));
                if (WSTOPSIG(status) == SIGSTOP)
-                       assert(ptrace(PTRACE_SETOPTIONS, child, 0, PTRACE_O_TRACESYSGOOD) == 0);
+                       ksft_assert(ptrace(PTRACE_SETOPTIONS, child, 0, PTRACE_O_TRACESYSGOOD) == 0);
                else if (WSTOPSIG(status) == (SIGTRAP | 0x80)) {
-                       assert(ptrace(PTRACE_GET_SYSCALL_INFO, child, sizeof(info), &info) > 0);
+                       ksft_assert(ptrace(PTRACE_GET_SYSCALL_INFO, child, sizeof(info), &info) > 0);
                        if (info.op == PTRACE_SYSCALL_INFO_ENTRY && info.entry.nr == __NR_getrandom &&
                            info.entry.args[0] == (uintptr_t)weird_size && info.entry.args[1] == sizeof(weird_size))
-                               exit(KSFT_FAIL);
+                               ksft_exit_fail_msg("vgetrandom passed buffer to syscall getrandom unexpectedly\n");
                }
-               assert(ptrace(PTRACE_SYSCALL, child, 0, 0) == 0);
+               ksft_assert(ptrace(PTRACE_SYSCALL, child, 0, 0) == 0);
        }
 
        ksft_test_result_pass("getrandom timens: PASS\n");
 
-       exit(KSFT_PASS);
+       ksft_exit_pass();
 }
 
 static void usage(const char *argv0)
diff --git a/tools/testing/selftests/vDSO/vgetrandom-chacha.S b/tools/testing/selftests/vDSO/vgetrandom-chacha.S
new file mode 100644 (file)
index 0000000..d6e09af
--- /dev/null
@@ -0,0 +1,18 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (C) 2024 Jason A. Donenfeld <[email protected]>. All Rights Reserved.
+ */
+
+#define __ASSEMBLY__
+
+#if defined(__aarch64__)
+#include "../../../../arch/arm64/kernel/vdso/vgetrandom-chacha.S"
+#elif defined(__loongarch__)
+#include "../../../../arch/loongarch/vdso/vgetrandom-chacha.S"
+#elif defined(__powerpc__) || defined(__powerpc64__)
+#include "../../../../arch/powerpc/kernel/vdso/vgetrandom-chacha.S"
+#elif defined(__s390x__)
+#include "../../../../arch/s390/kernel/vdso64/vgetrandom-chacha.S"
+#elif defined(__x86_64__)
+#include "../../../../arch/x86/entry/vdso/vgetrandom-chacha.S"
+#endif
index bc71cbca0dde704b80619f4f64f864a82c6269cf..a1f506ba557864bdae7316d12a79de2d852ab2a0 100644 (file)
@@ -334,7 +334,13 @@ int main(int argc, char *argv[])
 
        printf("Watchdog Ticking Away!\n");
 
+       /*
+        * Register the signals
+        */
        signal(SIGINT, term);
+       signal(SIGTERM, term);
+       signal(SIGKILL, term);
+       signal(SIGQUIT, term);
 
        while (1) {
                keep_alive();
index c53f220eb6cc039ac884ca063dc16d85cf57d9ca..b33b47342d4182457ad26391b6844cdacd284250 100644 (file)
@@ -1522,6 +1522,45 @@ static bool test_copy_vma(void)
        return true;
 }
 
+static bool test_expand_only_mode(void)
+{
+       unsigned long flags = VM_READ | VM_WRITE | VM_MAYREAD | VM_MAYWRITE;
+       struct mm_struct mm = {};
+       VMA_ITERATOR(vmi, &mm, 0);
+       struct vm_area_struct *vma_prev, *vma;
+       VMG_STATE(vmg, &mm, &vmi, 0x5000, 0x9000, flags, 5);
+
+       /*
+        * Place a VMA prior to the one we're expanding so we assert that we do
+        * not erroneously try to traverse to the previous VMA even though we
+        * have, through the use of VMG_FLAG_JUST_EXPAND, indicated we do not
+        * need to do so.
+        */
+       alloc_and_link_vma(&mm, 0, 0x2000, 0, flags);
+
+       /*
+        * We will be positioned at the prev VMA, but looking to expand to
+        * 0x9000.
+        */
+       vma_iter_set(&vmi, 0x3000);
+       vma_prev = alloc_and_link_vma(&mm, 0x3000, 0x5000, 3, flags);
+       vmg.prev = vma_prev;
+       vmg.merge_flags = VMG_FLAG_JUST_EXPAND;
+
+       vma = vma_merge_new_range(&vmg);
+       ASSERT_NE(vma, NULL);
+       ASSERT_EQ(vma, vma_prev);
+       ASSERT_EQ(vmg.state, VMA_MERGE_SUCCESS);
+       ASSERT_EQ(vma->vm_start, 0x3000);
+       ASSERT_EQ(vma->vm_end, 0x9000);
+       ASSERT_EQ(vma->vm_pgoff, 3);
+       ASSERT_TRUE(vma_write_started(vma));
+       ASSERT_EQ(vma_iter_addr(&vmi), 0x3000);
+
+       cleanup_mm(&mm, &vmi);
+       return true;
+}
+
 int main(void)
 {
        int num_tests = 0, num_fail = 0;
@@ -1553,6 +1592,7 @@ int main(void)
        TEST(vmi_prealloc_fail);
        TEST(merge_extend);
        TEST(copy_vma);
+       TEST(expand_only_mode);
 
 #undef TEST
 
index 3ff0b8970896f72e591a5dd40041443c267428d2..cc1d6b615475f0817a5d0cc9aa0537c99467c2b3 100644 (file)
@@ -38,7 +38,7 @@ BINDIR                := /usr/bin
 .PHONY: install
 install: doc_install
        @$(MKDIR) -p $(DESTDIR)$(BINDIR)
-       $(call QUIET_INSTALL,rtla)$(INSTALL) rtla -m 755 $(DESTDIR)$(BINDIR)
+       $(call QUIET_INSTALL,rtla)$(INSTALL) $(RTLA) -m 755 $(DESTDIR)$(BINDIR)
        @$(STRIP) $(DESTDIR)$(BINDIR)/rtla
        @test ! -f $(DESTDIR)$(BINDIR)/osnoise || $(RM) $(DESTDIR)$(BINDIR)/osnoise
        @$(LN) rtla $(DESTDIR)$(BINDIR)/osnoise
index 2f756628613dd82d86a22e1e17752c7e3f36c941..30e3853076a0daa7e3c7c0a7f420f37f03605e89 100644 (file)
@@ -442,7 +442,7 @@ struct osnoise_top_params *osnoise_top_parse_args(int argc, char **argv)
                case 'd':
                        params->duration = parse_seconds_duration(optarg);
                        if (!params->duration)
-                               osnoise_top_usage(params, "Invalid -D duration\n");
+                               osnoise_top_usage(params, "Invalid -d duration\n");
                        break;
                case 'e':
                        tevent = trace_event_alloc(optarg);
index 8c16419fe22aa7b7791fb144932ca4f79be97583..210b0f533534abf2834945d2960dcc0a04ae817c 100644 (file)
@@ -459,7 +459,7 @@ static void timerlat_top_usage(char *usage)
                "         -c/--cpus cpus: run the tracer only on the given cpus",
                "         -H/--house-keeping cpus: run rtla control threads only on the given cpus",
                "         -C/--cgroup[=cgroup_name]: set cgroup, if no cgroup_name is passed, the rtla's cgroup will be inherited",
-               "         -d/--duration time[m|h|d]: duration of the session in seconds",
+               "         -d/--duration time[s|m|h|d]: duration of the session",
                "         -D/--debug: print debug info",
                "            --dump-tasks: prints the task running on all CPUs if stop conditions are met (depends on !--no-aa)",
                "         -t/--trace[file]: save the stopped trace to [file|timerlat_trace.txt]",
@@ -613,7 +613,7 @@ static struct timerlat_top_params
                case 'd':
                        params->duration = parse_seconds_duration(optarg);
                        if (!params->duration)
-                               timerlat_top_usage("Invalid -D duration\n");
+                               timerlat_top_usage("Invalid -d duration\n");
                        break;
                case 'e':
                        tevent = trace_event_alloc(optarg);
index b29101986b5a62591993e8aeb9301790322926f0..6b78d4a81e95b29cd5f06045dbfe02e6a57777f0 100644 (file)
@@ -68,6 +68,7 @@ static int detach_port(char *port)
        }
 
        if (!found) {
+               ret = -1;
                err("Invalid port %s > maxports %d",
                        port, vhci_driver->nports);
                goto call_driver_close;
index 05cbb2548d999bd5acdb329381cdfaa21409dd90..6ca7a1045bbb75dfbd9195b348c3d03a83578a86 100644 (file)
@@ -3035,24 +3035,12 @@ kvm_pfn_t gfn_to_pfn_memslot_atomic(const struct kvm_memory_slot *slot, gfn_t gf
 }
 EXPORT_SYMBOL_GPL(gfn_to_pfn_memslot_atomic);
 
-kvm_pfn_t kvm_vcpu_gfn_to_pfn_atomic(struct kvm_vcpu *vcpu, gfn_t gfn)
-{
-       return gfn_to_pfn_memslot_atomic(kvm_vcpu_gfn_to_memslot(vcpu, gfn), gfn);
-}
-EXPORT_SYMBOL_GPL(kvm_vcpu_gfn_to_pfn_atomic);
-
 kvm_pfn_t gfn_to_pfn(struct kvm *kvm, gfn_t gfn)
 {
        return gfn_to_pfn_memslot(gfn_to_memslot(kvm, gfn), gfn);
 }
 EXPORT_SYMBOL_GPL(gfn_to_pfn);
 
-kvm_pfn_t kvm_vcpu_gfn_to_pfn(struct kvm_vcpu *vcpu, gfn_t gfn)
-{
-       return gfn_to_pfn_memslot(kvm_vcpu_gfn_to_memslot(vcpu, gfn), gfn);
-}
-EXPORT_SYMBOL_GPL(kvm_vcpu_gfn_to_pfn);
-
 int gfn_to_page_many_atomic(struct kvm_memory_slot *slot, gfn_t gfn,
                            struct page **pages, int nr_pages)
 {
@@ -6387,7 +6375,7 @@ static void kvm_sched_out(struct preempt_notifier *pn,
 
        WRITE_ONCE(vcpu->scheduled_out, true);
 
-       if (current->on_rq && vcpu->wants_to_run) {
+       if (task_is_runnable(current) && vcpu->wants_to_run) {
                WRITE_ONCE(vcpu->preempted, true);
                WRITE_ONCE(vcpu->ready, true);
        }
This page took 4.855709 seconds and 4 git commands to generate.