summaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
Diffstat (limited to 'include')
-rw-r--r--include/acpi/acpi_bus.h43
-rw-r--r--include/acpi/actbl2.h7
-rw-r--r--include/acpi/cppc_acpi.h32
-rw-r--r--include/acpi/ghes.h4
-rw-r--r--include/acpi/processor.h6
-rw-r--r--include/asm-generic/Kbuild1
-rw-r--r--include/asm-generic/mshyperv.h4
-rw-r--r--include/asm-generic/pgtable-nop4d.h1
-rw-r--r--include/asm-generic/pgtable-nopmd.h1
-rw-r--r--include/asm-generic/pgtable-nopud.h1
-rw-r--r--include/asm-generic/preempt.h10
-rw-r--r--include/asm-generic/tlb.h66
-rw-r--r--include/asm-generic/vdso/vsyscall.h35
-rw-r--r--include/asm-generic/vmlinux.lds.h33
-rw-r--r--include/crypto/aes-ccm.h22
-rw-r--r--include/crypto/aes-gcm.h22
-rw-r--r--include/crypto/aes-xts.h13
-rw-r--r--include/crypto/aes.h31
-rw-r--r--include/crypto/blake2b.h9
-rw-r--r--include/crypto/blake2s.h9
-rw-r--r--include/crypto/chacha.h6
-rw-r--r--include/crypto/internal/poly1305.h4
-rw-r--r--include/crypto/md5.h19
-rw-r--r--include/crypto/poly1305.h4
-rw-r--r--include/crypto/sha1.h19
-rw-r--r--include/crypto/sha2.h73
-rw-r--r--include/crypto/sm3.h10
-rw-r--r--include/cxl/event.h6
-rw-r--r--include/drm/bridge/analogix_dp.h1
-rw-r--r--include/drm/bridge/dw_hdmi_qp.h4
-rw-r--r--include/drm/clients/drm_fbdev_helper.h (renamed from include/drm/drm_fb_helper.h)4
-rw-r--r--include/drm/display/drm_dp.h1
-rw-r--r--include/drm/display/drm_dp_helper.h6
-rw-r--r--include/drm/display/drm_hdmi_helper.h15
-rw-r--r--include/drm/display/drm_hdmi_state_helper.h11
-rw-r--r--include/drm/display/drm_scdc.h21
-rw-r--r--include/drm/display/drm_scdc_helper.h105
-rw-r--r--include/drm/drm_atomic.h89
-rw-r--r--include/drm/drm_atomic_state_helper.h6
-rw-r--r--include/drm/drm_bridge.h103
-rw-r--r--include/drm/drm_client.h14
-rw-r--r--include/drm/drm_client_event.h3
-rw-r--r--include/drm/drm_colorop.h127
-rw-r--r--include/drm/drm_connector.h216
-rw-r--r--include/drm/drm_crtc.h12
-rw-r--r--include/drm/drm_device.h1
-rw-r--r--include/drm/drm_edid.h2
-rw-r--r--include/drm/drm_exec.h15
-rw-r--r--include/drm/drm_gem.h14
-rw-r--r--include/drm/drm_gem_atomic_helper.h13
-rw-r--r--include/drm/drm_gpusvm.h77
-rw-r--r--include/drm/drm_mipi_dbi.h2
-rw-r--r--include/drm/drm_mode_config.h4
-rw-r--r--include/drm/drm_modeset_helper_vtables.h53
-rw-r--r--include/drm/drm_of.h15
-rw-r--r--include/drm/drm_pagemap.h7
-rw-r--r--include/drm/drm_panel.h99
-rw-r--r--include/drm/drm_panel_quirks.h (renamed from include/drm/drm_utils.h)10
-rw-r--r--include/drm/drm_panic.h117
-rw-r--r--include/drm/drm_panic_helper.h41
-rw-r--r--include/drm/drm_plane.h69
-rw-r--r--include/drm/drm_print.h3
-rw-r--r--include/drm/drm_ras.h34
-rw-r--r--include/drm/drm_simple_kms_helper.h7
-rw-r--r--include/drm/drm_sysfs.h4
-rw-r--r--include/drm/drm_timeout.h17
-rw-r--r--include/drm/gpu_scheduler.h10
-rw-r--r--include/drm/intel/display_parent_interface.h24
-rw-r--r--include/drm/intel/gtt_view_types.h79
-rw-r--r--include/drm/intel/pciids.h1
-rw-r--r--include/drm/ttm/ttm_resource.h2
-rw-r--r--include/dt-bindings/arm/qcom,ids.h3
-rw-r--r--include/dt-bindings/arm/ux500_pm_domains.h17
-rw-r--r--include/dt-bindings/clock/agilex-clock.h1
-rw-r--r--include/dt-bindings/clock/qcom,eliza-cambistmclkcc.h32
-rw-r--r--include/dt-bindings/clock/qcom,eliza-camcc.h151
-rw-r--r--include/dt-bindings/clock/qcom,eliza-gpucc.h51
-rw-r--r--include/dt-bindings/clock/qcom,eliza-videocc.h37
-rw-r--r--include/dt-bindings/clock/qcom,hawi-camcc.h165
-rw-r--r--include/dt-bindings/clock/qcom,hawi-gpucc.h47
-rw-r--r--include/dt-bindings/clock/qcom,nord-camcc.h167
-rw-r--r--include/dt-bindings/clock/qcom,nord-nwgcc.h3
-rw-r--r--include/dt-bindings/clock/renesas,r8a774a3-cpg-mssr.h59
-rw-r--r--include/dt-bindings/clock/renesas,r8a78000-cpg.h2
-rw-r--r--include/dt-bindings/clock/starfive,jhb100-crg.h554
-rw-r--r--include/dt-bindings/interconnect/qcom,ipq9650.h28
-rw-r--r--include/dt-bindings/interconnect/qcom,kuno.h89
-rw-r--r--include/dt-bindings/media/video-interface-devices.h13
-rw-r--r--include/dt-bindings/pinctrl/mediatek,mt6735-pinfunc.h1148
-rw-r--r--include/dt-bindings/power/qcom,rpmhpd.h1
-rw-r--r--include/dt-bindings/power/renesas,r8a774a3-sysc.h30
-rw-r--r--include/dt-bindings/reset/mediatek,mt8167-wdt.h21
-rw-r--r--include/dt-bindings/reset/starfive,jhb100-crg.h189
-rw-r--r--include/dt-bindings/sound/cs35l45.h27
-rw-r--r--include/dt-bindings/sound/qcom,q6dsp-lpass-ports.h52
-rw-r--r--include/hyperv/hvgdk_mini.h10
-rw-r--r--include/hyperv/hvhdk_mini.h155
-rw-r--r--include/keys/request_key_auth-type.h2
-rw-r--r--include/keys/trusted-type.h11
-rw-r--r--include/keys/trusted_tpm.h14
-rw-r--r--include/kunit/test.h5
-rw-r--r--include/kvm/arm_arch_timer.h15
-rw-r--r--include/kvm/arm_psci.h2
-rw-r--r--include/kvm/arm_vgic.h213
-rw-r--r--include/linux/acpi.h37
-rw-r--r--include/linux/aer.h9
-rw-r--r--include/linux/amd-iommu.h13
-rw-r--r--include/linux/apple-gmux.h2
-rw-r--r--include/linux/arm-rmi-cmds.h581
-rw-r--r--include/linux/arm-rsi-cmds.h239
-rw-r--r--include/linux/arm-smccc-bus.h48
-rw-r--r--include/linux/arm-smccc-rmi.h516
-rw-r--r--include/linux/arm-smccc-rsi.h193
-rw-r--r--include/linux/arm_mpam.h2
-rw-r--r--include/linux/audit.h16
-rw-r--r--include/linux/binfmts.h3
-rw-r--r--include/linux/bio-integrity.h3
-rw-r--r--include/linux/bio.h11
-rw-r--r--include/linux/bitfield-fix-width.h241
-rw-r--r--include/linux/bitfield.h49
-rw-r--r--include/linux/bitmap.h14
-rw-r--r--include/linux/blk-mq.h3
-rw-r--r--include/linux/blkdev.h19
-rw-r--r--include/linux/bnge/hsi.h136
-rw-r--r--include/linux/bpf-cgroup-defs.h1
-rw-r--r--include/linux/bpf-cgroup.h64
-rw-r--r--include/linux/bpf.h274
-rw-r--r--include/linux/bpf_compiler_types.h21
-rw-r--r--include/linux/bpf_crypto.h24
-rw-r--r--include/linux/bpf_local_storage.h13
-rw-r--r--include/linux/bpf_lsm.h11
-rw-r--r--include/linux/bpf_verifier.h603
-rw-r--r--include/linux/bsg-lib.h3
-rw-r--r--include/linux/btf.h66
-rw-r--r--include/linux/buffer_head.h94
-rw-r--r--include/linux/cacheinfo.h12
-rw-r--r--include/linux/can/core.h3
-rw-r--r--include/linux/can/skb.h4
-rw-r--r--include/linux/capability.h8
-rw-r--r--include/linux/ccp.h58
-rw-r--r--include/linux/cgroup-defs.h8
-rw-r--r--include/linux/cgroup.h3
-rw-r--r--include/linux/cleanup.h7
-rw-r--r--include/linux/cmpxchg-emu.h4
-rw-r--r--include/linux/cnum.h3
-rw-r--r--include/linux/compaction.h11
-rw-r--r--include/linux/compat.h1
-rw-r--r--include/linux/compiler.h22
-rw-r--r--include/linux/configfs.h73
-rw-r--r--include/linux/console.h17
-rw-r--r--include/linux/console_struct.h8
-rw-r--r--include/linux/coredump.h41
-rw-r--r--include/linux/coresight.h4
-rw-r--r--include/linux/cpufreq.h3
-rw-r--r--include/linux/cpuhotplug.h6
-rw-r--r--include/linux/cpumask.h42
-rw-r--r--include/linux/cred.h17
-rw-r--r--include/linux/damon.h90
-rw-r--r--include/linux/dax.h12
-rw-r--r--include/linux/dcache.h38
-rw-r--r--include/linux/device-id/apr.h21
-rw-r--r--include/linux/device-id/arm_smccc.h19
-rw-r--r--include/linux/device-id/scmi.h17
-rw-r--r--include/linux/device.h14
-rw-r--r--include/linux/device/bus.h1
-rw-r--r--include/linux/device/devres.h102
-rw-r--r--include/linux/dibs.h6
-rw-r--r--include/linux/dma-fence.h8
-rw-r--r--include/linux/dma-map-ops.h4
-rw-r--r--include/linux/dma-mapping.h4
-rw-r--r--include/linux/dmaengine.h9
-rw-r--r--include/linux/efi.h37
-rw-r--r--include/linux/entry-common.h9
-rw-r--r--include/linux/ethtool.h12
-rw-r--r--include/linux/fdtable.h16
-rw-r--r--include/linux/file.h130
-rw-r--r--include/linux/fileattr.h2
-rw-r--r--include/linux/filter.h83
-rw-r--r--include/linux/firewire.h153
-rw-r--r--include/linux/firmware/cirrus/cs_dsp.h2
-rw-r--r--include/linux/firmware/intel/stratix10-smc.h44
-rw-r--r--include/linux/firmware/qcom/qcom_scm.h29
-rw-r--r--include/linux/firmware/xlnx-zynqmp-ufs.h8
-rw-r--r--include/linux/firmware/xlnx-zynqmp.h5
-rw-r--r--include/linux/firmware_attributes.h12
-rw-r--r--include/linux/font.h4
-rw-r--r--include/linux/fortify-string.h2
-rw-r--r--include/linux/fs.h132
-rw-r--r--include/linux/fs_context.h4
-rw-r--r--include/linux/fscache-cache.h2
-rw-r--r--include/linux/fscache.h60
-rw-r--r--include/linux/fsl/mc.h2
-rw-r--r--include/linux/fsnotify_backend.h1
-rw-r--r--include/linux/fsverity.h10
-rw-r--r--include/linux/ftrace.h1
-rw-r--r--include/linux/futex.h19
-rw-r--r--include/linux/futex_types.h2
-rw-r--r--include/linux/generic_pt/common.h6
-rw-r--r--include/linux/generic_pt/iommu.h12
-rw-r--r--include/linux/gfp.h6
-rw-r--r--include/linux/gfp_types.h6
-rw-r--r--include/linux/gpio/driver.h9
-rw-r--r--include/linux/gpio/legacy.h10
-rw-r--r--include/linux/gpio/regmap.h2
-rw-r--r--include/linux/gpu_buddy.h101
-rw-r--r--include/linux/greybus/bundle.h12
-rw-r--r--include/linux/hardirq.h2
-rw-r--r--include/linux/hdmi.h12
-rw-r--r--include/linux/hiddev.h2
-rw-r--r--include/linux/hisi_acc_qm.h6
-rw-r--r--include/linux/host1x.h51
-rw-r--r--include/linux/hrtimer.h10
-rw-r--r--include/linux/hrtimer_rearm.h2
-rw-r--r--include/linux/hugetlb.h8
-rw-r--r--include/linux/hyperv.h8
-rw-r--r--include/linux/i2c.h23
-rw-r--r--include/linux/idr.h5
-rw-r--r--include/linux/ieee80211-eht.h18
-rw-r--r--include/linux/ieee80211-mesh.h4
-rw-r--r--include/linux/ieee80211-nan.h28
-rw-r--r--include/linux/ieee80211-uhr.h101
-rw-r--r--include/linux/ieee80211.h42
-rw-r--r--include/linux/if_vlan.h37
-rw-r--r--include/linux/igmp.h3
-rw-r--r--include/linux/iio/adc/qcom-adc5-gen3-common.h2
-rw-r--r--include/linux/iio/backend.h6
-rw-r--r--include/linux/iio/iio-gts-helper.h11
-rw-r--r--include/linux/iio/iio-opaque.h2
-rw-r--r--include/linux/iio/iio.h25
-rw-r--r--include/linux/input/samsung-keypad.h39
-rw-r--r--include/linux/interrupt.h8
-rw-r--r--include/linux/interrupt_rc.h13
-rw-r--r--include/linux/io_uring.h32
-rw-r--r--include/linux/io_uring/cmd.h34
-rw-r--r--include/linux/io_uring_types.h9
-rw-r--r--include/linux/iomap.h38
-rw-r--r--include/linux/iommu-dma.h2
-rw-r--r--include/linux/iommu.h8
-rw-r--r--include/linux/iommufd.h2
-rw-r--r--include/linux/irq-entry-common.h40
-rw-r--r--include/linux/irq_work.h2
-rw-r--r--include/linux/irqchip/arm-gic-v5.h256
-rw-r--r--include/linux/irqchip/arm-vgic-info.h5
-rw-r--r--include/linux/irqchip/riscv-imsic.h3
-rw-r--r--include/linux/kernel-page-flags.h1
-rw-r--r--include/linux/kernel.h20
-rw-r--r--include/linux/kernel_stat.h18
-rw-r--r--include/linux/kernfs.h2
-rw-r--r--include/linux/key-type.h1
-rw-r--r--include/linux/key.h7
-rw-r--r--include/linux/kmod.h12
-rw-r--r--include/linux/kvm_host.h146
-rw-r--r--include/linux/landlock.h29
-rw-r--r--include/linux/libata.h4
-rw-r--r--include/linux/list.h6
-rw-r--r--include/linux/livepatch.h4
-rw-r--r--include/linux/llc.h5
-rw-r--r--include/linux/lsm_audit.h7
-rw-r--r--include/linux/lsm_hook_defs.h50
-rw-r--r--include/linux/lsm_hooks.h1
-rw-r--r--include/linux/mailbox/riscv-rpmi-message.h11
-rw-r--r--include/linux/maple_tree.h8
-rw-r--r--include/linux/mdio-mux.h2
-rw-r--r--include/linux/memcontrol.h443
-rw-r--r--include/linux/mempool.h7
-rw-r--r--include/linux/mfd/88pm886.h7
-rw-r--r--include/linux/mfd/rohm-bd73800.h306
-rw-r--r--include/linux/mfd/rohm-generic.h1
-rw-r--r--include/linux/mhi.h2
-rw-r--r--include/linux/mhi_ep.h16
-rw-r--r--include/linux/micrel_phy.h5
-rw-r--r--include/linux/mlx5/cq.h10
-rw-r--r--include/linux/mlx5/data_direct.h47
-rw-r--r--include/linux/mlx5/device.h231
-rw-r--r--include/linux/mlx5/driver.h8
-rw-r--r--include/linux/mlx5/eswitch.h3
-rw-r--r--include/linux/mlx5/mlx5_ifc.h194
-rw-r--r--include/linux/mlx5/mlx5_ifc_macros.h185
-rw-r--r--include/linux/mm.h106
-rw-r--r--include/linux/mm_inline.h115
-rw-r--r--include/linux/mm_types.h27
-rw-r--r--include/linux/mmap_lock.h96
-rw-r--r--include/linux/mmc/host.h6
-rw-r--r--include/linux/mmc/sdio_ids.h2
-rw-r--r--include/linux/mmzone.h176
-rw-r--r--include/linux/mnt_idmapping.h24
-rw-r--r--include/linux/mod_devicetable.h2
-rw-r--r--include/linux/module.h15
-rw-r--r--include/linux/module_symbol.h7
-rw-r--r--include/linux/mount.h6
-rw-r--r--include/linux/mtd/bbm.h2
-rw-r--r--include/linux/mtd/lpc32xx_mlc.h17
-rw-r--r--include/linux/mtd/lpc32xx_slc.h17
-rw-r--r--include/linux/mtd/nand-qpic-common.h18
-rw-r--r--include/linux/mtd/nand.h2
-rw-r--r--include/linux/mtd/rawnand.h2
-rw-r--r--include/linux/mtd/sh_flctl.h4
-rw-r--r--include/linux/mtd/spi-nor.h10
-rw-r--r--include/linux/mtd/spinand.h3
-rw-r--r--include/linux/namei.h19
-rw-r--r--include/linux/net.h34
-rw-r--r--include/linux/netdevice.h76
-rw-r--r--include/linux/netfilter_arp/arp_tables.h19
-rw-r--r--include/linux/netfilter_netdev.h2
-rw-r--r--include/linux/netfs.h119
-rw-r--r--include/linux/netpoll.h5
-rw-r--r--include/linux/nfs_fs.h6
-rw-r--r--include/linux/notifier.h7
-rw-r--r--include/linux/ns/ns_common_types.h9
-rw-r--r--include/linux/nsproxy.h1
-rw-r--r--include/linux/nvme.h4
-rw-r--r--include/linux/of.h6
-rw-r--r--include/linux/once_lite.h8
-rw-r--r--include/linux/overflow.h2
-rw-r--r--include/linux/page-flags.h64
-rw-r--r--include/linux/page_counter.h3
-rw-r--r--include/linux/pagemap.h67
-rw-r--r--include/linux/panic.h3
-rw-r--r--include/linux/pci-epf.h3
-rw-r--r--include/linux/pci.h3
-rw-r--r--include/linux/pci_ids.h3
-rw-r--r--include/linux/pcs/pcs-xpcs-rk.h11
-rw-r--r--include/linux/perf/riscv_pmu.h2
-rw-r--r--include/linux/perf_event.h47
-rw-r--r--include/linux/perf_regs.h36
-rw-r--r--include/linux/pgtable.h24
-rw-r--r--include/linux/phy.h40
-rw-r--r--include/linux/phy/phy.h13
-rw-r--r--include/linux/phy_link_topology.h43
-rw-r--r--include/linux/phy_port.h5
-rw-r--r--include/linux/phylink.h2
-rw-r--r--include/linux/pid.h64
-rw-r--r--include/linux/pid_types.h8
-rw-r--r--include/linux/pidfs.h5
-rw-r--r--include/linux/pinctrl/consumer.h5
-rw-r--r--include/linux/pinctrl/pinconf-generic.h5
-rw-r--r--include/linux/platform_data/cros_ec_commands.h72
-rw-r--r--include/linux/platform_data/dmtimer-omap.h2
-rw-r--r--include/linux/platform_data/microchip-ksz.h2
-rw-r--r--include/linux/platform_data/x86/int3472.h2
-rw-r--r--include/linux/pm.h93
-rw-r--r--include/linux/pm_domain.h9
-rw-r--r--include/linux/pm_qos.h9
-rw-r--r--include/linux/pm_runtime.h409
-rw-r--r--include/linux/posix-timers.h39
-rw-r--r--include/linux/posix_acl.h24
-rw-r--r--include/linux/power_supply.h16
-rw-r--r--include/linux/pps_gen_kernel.h4
-rw-r--r--include/linux/preempt.h20
-rw-r--r--include/linux/property.h5
-rw-r--r--include/linux/psp-sev.h86
-rw-r--r--include/linux/pwrseq/consumer.h7
-rw-r--r--include/linux/pwrseq/provider.h8
-rw-r--r--include/linux/quotaops.h6
-rw-r--r--include/linux/rbtree_augmented.h180
-rw-r--r--include/linux/rcupdate.h10
-rw-r--r--include/linux/rcuref.h2
-rw-r--r--include/linux/rcutree.h2
-rw-r--r--include/linux/regulator/driver.h2
-rw-r--r--include/linux/regulator/lp872x.h86
-rw-r--r--include/linux/regulator/pca9450.h4
-rw-r--r--include/linux/remoteproc.h3
-rw-r--r--include/linux/resctrl.h19
-rw-r--r--include/linux/resctrl_types.h2
-rw-r--r--include/linux/rhashtable-types.h74
-rw-r--r--include/linux/rhashtable.h39
-rw-r--r--include/linux/ring_buffer.h26
-rw-r--r--include/linux/rolling_buffer.h6
-rw-r--r--include/linux/rtnetlink.h7
-rw-r--r--include/linux/sched.h73
-rw-r--r--include/linux/sched/cputime.h6
-rw-r--r--include/linux/sched/ext.h40
-rw-r--r--include/linux/sched/signal.h60
-rw-r--r--include/linux/sched/stat.h2
-rw-r--r--include/linux/sched/task.h1
-rw-r--r--include/linux/sched/topology.h4
-rw-r--r--include/linux/sched/user.h8
-rw-r--r--include/linux/scmi_protocol.h20
-rw-r--r--include/linux/seccomp.h3
-rw-r--r--include/linux/security.h132
-rw-r--r--include/linux/seq_buf.h141
-rw-r--r--include/linux/serial_8250.h8
-rw-r--r--include/linux/serial_core.h2
-rw-r--r--include/linux/set_memory.h120
-rw-r--r--include/linux/shmem_fs.h12
-rw-r--r--include/linux/siphash.h8
-rw-r--r--include/linux/skbuff.h62
-rw-r--r--include/linux/skbuff_ref.h66
-rw-r--r--include/linux/slimbus.h2
-rw-r--r--include/linux/soc/marvell/octeontx2/asm.h6
-rw-r--r--include/linux/soc/qcom/apr.h4
-rw-r--r--include/linux/soc/qcom/geni-se.h23
-rw-r--r--include/linux/soc/qcom/llcc-qcom.h6
-rw-r--r--include/linux/soc/qcom/tc9563.h19
-rw-r--r--include/linux/soc/qcom/ubwc.h3
-rw-r--r--include/linux/soc/ti/k3-ringacc.h31
-rw-r--r--include/linux/socket.h9
-rw-r--r--include/linux/spi/spi.h9
-rw-r--r--include/linux/spinlock_types_raw.h4
-rw-r--r--include/linux/splice.h4
-rw-r--r--include/linux/spmi.h17
-rw-r--r--include/linux/srcu.h83
-rw-r--r--include/linux/srcutiny.h18
-rw-r--r--include/linux/srcutree.h19
-rw-r--r--include/linux/stmmac.h2
-rw-r--r--include/linux/string.h13
-rw-r--r--include/linux/suspend.h1
-rw-r--r--include/linux/swap.h59
-rw-r--r--include/linux/swapops.h9
-rw-r--r--include/linux/swiotlb.h2
-rw-r--r--include/linux/syscalls.h1
-rw-r--r--include/linux/tcp.h10
-rw-r--r--include/linux/thermal.h19
-rw-r--r--include/linux/thunderbolt.h50
-rw-r--r--include/linux/tnum.h2
-rw-r--r--include/linux/trace_remote_event.h2
-rw-r--r--include/linux/trace_seq.h5
-rw-r--r--include/linux/tty.h2
-rw-r--r--include/linux/tty_driver.h6
-rw-r--r--include/linux/tty_port.h22
-rw-r--r--include/linux/ucs2_string.h11
-rw-r--r--include/linux/uidgid.h12
-rw-r--r--include/linux/ulpi/driver.h4
-rw-r--r--include/linux/unicode.h1
-rw-r--r--include/linux/usb.h13
-rw-r--r--include/linux/usb/rndis_host.h5
-rw-r--r--include/linux/usb/serial.h9
-rw-r--r--include/linux/usb/typec_altmode.h4
-rw-r--r--include/linux/user_namespace.h11
-rw-r--r--include/linux/vdso_time.h8
-rw-r--r--include/linux/vfio.h5
-rw-r--r--include/linux/vfio_pci_core.h41
-rw-r--r--include/linux/vga_switcheroo.h29
-rw-r--r--include/linux/vgaarb.h8
-rw-r--r--include/linux/virtio_net.h60
-rw-r--r--include/linux/vmalloc.h4
-rw-r--r--include/linux/vmemmap-optimization.h115
-rw-r--r--include/linux/wait.h2
-rw-r--r--include/linux/wait_bit.h26
-rw-r--r--include/linux/wwan.h9
-rw-r--r--include/linux/xattr.h20
-rw-r--r--include/linux/zsmalloc.h4
-rw-r--r--include/linux/zswap.h8
-rw-r--r--include/math-emu/op-common.h23
-rw-r--r--include/math-emu/soft-fp.h8
-rw-r--r--include/media/ipu-bridge.h53
-rw-r--r--include/media/ipu6-pci-table.h6
-rw-r--r--include/media/rc-map.h2
-rw-r--r--include/media/v4l2-common.h75
-rw-r--r--include/media/v4l2-ctrls.h6
-rw-r--r--include/media/v4l2-dv-timings.h14
-rw-r--r--include/media/v4l2-hevc.h41
-rw-r--r--include/media/v4l2-subdev.h34
-rw-r--r--include/net/addrconf.h3
-rw-r--r--include/net/af_rxrpc.h5
-rw-r--r--include/net/af_vsock.h1
-rw-r--r--include/net/amt.h4
-rw-r--r--include/net/arp.h26
-rw-r--r--include/net/bluetooth/bluetooth.h4
-rw-r--r--include/net/bluetooth/coredump.h2
-rw-r--r--include/net/bluetooth/hci.h1
-rw-r--r--include/net/bluetooth/hci_core.h74
-rw-r--r--include/net/bluetooth/hci_h4.h60
-rw-r--r--include/net/bluetooth/hci_mon.h2
-rw-r--r--include/net/bluetooth/hci_sync.h1
-rw-r--r--include/net/bluetooth/l2cap.h103
-rw-r--r--include/net/bluetooth/mgmt.h14
-rw-r--r--include/net/bluetooth/rfcomm.h1
-rw-r--r--include/net/bond_3ad.h7
-rw-r--r--include/net/bond_alb.h14
-rw-r--r--include/net/can.h2
-rw-r--r--include/net/cfg80211.h170
-rw-r--r--include/net/cfg802154.h10
-rw-r--r--include/net/codel.h5
-rw-r--r--include/net/codel_impl.h16
-rw-r--r--include/net/dropreason-core.h38
-rw-r--r--include/net/dsa.h2
-rw-r--r--include/net/dst.h3
-rw-r--r--include/net/gso.h15
-rw-r--r--include/net/gue.h19
-rw-r--r--include/net/ieee80211_radiotap.h113
-rw-r--r--include/net/inet_connection_sock.h1
-rw-r--r--include/net/inet_sock.h2
-rw-r--r--include/net/ip.h24
-rw-r--r--include/net/ip6_route.h19
-rw-r--r--include/net/ip6_tunnel.h1
-rw-r--r--include/net/ip_fib.h4
-rw-r--r--include/net/ip_tunnels.h17
-rw-r--r--include/net/ip_vs.h50
-rw-r--r--include/net/llc.h108
-rw-r--r--include/net/llc_c_ac.h180
-rw-r--r--include/net/llc_c_ev.h217
-rw-r--r--include/net/llc_c_st.h46
-rw-r--r--include/net/llc_conn.h114
-rw-r--r--include/net/llc_if.h63
-rw-r--r--include/net/llc_pdu.h379
-rw-r--r--include/net/llc_s_ac.h35
-rw-r--r--include/net/llc_s_ev.h61
-rw-r--r--include/net/llc_s_st.h32
-rw-r--r--include/net/llc_sap.h26
-rw-r--r--include/net/mac80211.h111
-rw-r--r--include/net/mana/gdma.h118
-rw-r--r--include/net/mana/hw_channel.h8
-rw-r--r--include/net/mana/mana.h20
-rw-r--r--include/net/mptcp.h9
-rw-r--r--include/net/ndisc.h39
-rw-r--r--include/net/neighbour.h46
-rw-r--r--include/net/net_namespace.h5
-rw-r--r--include/net/netdev_lock.h20
-rw-r--r--include/net/netdev_queues.h56
-rw-r--r--include/net/netfilter/nf_conntrack.h5
-rw-r--r--include/net/netfilter/nf_conntrack_seqadj.h1
-rw-r--r--include/net/netfilter/nf_flow_table.h3
-rw-r--r--include/net/netfilter/nf_queue.h3
-rw-r--r--include/net/netmem.h88
-rw-r--r--include/net/netns/netfilter.h2
-rw-r--r--include/net/nfc/hci.h2
-rw-r--r--include/net/nfc/nfc.h3
-rw-r--r--include/net/page_pool/helpers.h30
-rw-r--r--include/net/page_pool/memory_provider.h10
-rw-r--r--include/net/page_pool/types.h6
-rw-r--r--include/net/phy/realtek_phy.h7
-rw-r--r--include/net/pkt_cls.h2
-rw-r--r--include/net/psp/functions.h5
-rw-r--r--include/net/psp/types.h4
-rw-r--r--include/net/route.h13
-rw-r--r--include/net/sch_generic.h11
-rw-r--r--include/net/scm.h10
-rw-r--r--include/net/sctp/sm.h1
-rw-r--r--include/net/seg6_hmac.h3
-rw-r--r--include/net/sock.h12
-rw-r--r--include/net/strparser.h19
-rw-r--r--include/net/tcp.h299
-rw-r--r--include/net/udp.h2
-rw-r--r--include/net/vxlan.h12
-rw-r--r--include/net/xdp.h5
-rw-r--r--include/net/xsk_buff_pool.h3
-rw-r--r--include/rdma/ib_umem.h2
-rw-r--r--include/rdma/ib_verbs.h4
-rw-r--r--include/rdma/uverbs_ioctl.h2
-rw-r--r--include/rdma/uverbs_types.h2
-rw-r--r--include/scsi/scsi_cmnd.h3
-rw-r--r--include/scsi/scsi_common.h16
-rw-r--r--include/scsi/scsi_dbg.h6
-rw-r--r--include/scsi/scsi_device.h26
-rw-r--r--include/scsi/scsi_host.h9
-rw-r--r--include/scsi/scsi_proto.h71
-rw-r--r--include/scsi/scsi_sense.h950
-rw-r--r--include/soc/fsl/qe/qe.h6
-rw-r--r--include/soc/imx/cpu.h2
-rw-r--r--include/soc/tegra/fuse.h1
-rw-r--r--include/sound/aw88399.h8
-rw-r--r--include/sound/compress_driver.h2
-rw-r--r--include/sound/control.h4
-rw-r--r--include/sound/core.h14
-rw-r--r--include/sound/cs35l56.h1
-rw-r--r--include/sound/emu10k1.h4
-rw-r--r--include/sound/emux_legacy.h2
-rw-r--r--include/sound/hda_codec.h6
-rw-r--r--include/sound/hdaudio.h12
-rw-r--r--include/sound/jack.h2
-rw-r--r--include/sound/omap-hdmi-audio.h1
-rw-r--r--include/sound/pcm.h2
-rw-r--r--include/sound/pcm_oss.h1
-rw-r--r--include/sound/rawmidi.h1
-rw-r--r--include/sound/sdca.h23
-rw-r--r--include/sound/sdca_class.h70
-rw-r--r--include/sound/simple_card_utils.h2
-rw-r--r--include/sound/soc-component.h82
-rw-r--r--include/sound/soc-dai.h189
-rw-r--r--include/sound/soc.h38
-rw-r--r--include/sound/soc_sdw_utils.h22
-rw-r--r--include/sound/sof/ipc4/header.h24
-rw-r--r--include/sound/tas2781-dsp.h13
-rw-r--r--include/sound/tas2781.h31
-rw-r--r--include/trace/define_remote_events.h19
-rw-r--r--include/trace/events/bridge.h7
-rw-r--r--include/trace/events/cachefiles.h100
-rw-r--r--include/trace/events/dma.h2
-rw-r--r--include/trace/events/fib.h13
-rw-r--r--include/trace/events/fib6.h8
-rw-r--r--include/trace/events/fscache.h10
-rw-r--r--include/trace/events/huge_memory.h18
-rw-r--r--include/trace/events/kvm.h14
-rw-r--r--include/trace/events/landlock.h603
-rw-r--r--include/trace/events/mmflags.h45
-rw-r--r--include/trace/events/module.h3
-rw-r--r--include/trace/events/netfs.h175
-rw-r--r--include/trace/events/pagemap.h2
-rw-r--r--include/trace/events/rxrpc.h4
-rw-r--r--include/trace/events/scmi.h8
-rw-r--r--include/trace/events/scsi.h4
-rw-r--r--include/trace/events/timer.h2
-rw-r--r--include/trace/events/vmscan.h14
-rw-r--r--include/trace/events/workqueue.h146
-rw-r--r--include/uapi/asm-generic/socket.h4
-rw-r--r--include/uapi/drm/amdgpu_drm.h43
-rw-r--r--include/uapi/drm/drm_fourcc.h24
-rw-r--r--include/uapi/drm/drm_mode.h12
-rw-r--r--include/uapi/drm/drm_ras.h18
-rw-r--r--include/uapi/drm/ivpu_accel.h17
-rw-r--r--include/uapi/drm/nova_drm.h146
-rw-r--r--include/uapi/drm/panfrost_drm.h29
-rw-r--r--include/uapi/drm/tegra_drm.h4
-rw-r--r--include/uapi/drm/xe_drm.h22
-rw-r--r--include/uapi/linux/alloc_tag.h1
-rw-r--r--include/uapi/linux/android/binder.h1
-rw-r--r--include/uapi/linux/atm.h2
-rw-r--r--include/uapi/linux/audit.h1
-rw-r--r--include/uapi/linux/bpf.h126
-rw-r--r--include/uapi/linux/btf.h83
-rw-r--r--include/uapi/linux/btrfs_tree.h25
-rw-r--r--include/uapi/linux/close_range.h31
-rw-r--r--include/uapi/linux/coredump.h149
-rw-r--r--include/uapi/linux/dccp.h41
-rw-r--r--include/uapi/linux/dpll.h3
-rw-r--r--include/uapi/linux/ethtool.h2
-rw-r--r--include/uapi/linux/ethtool_netlink_generated.h22
-rw-r--r--include/uapi/linux/firewire-cdev.h4
-rw-r--r--include/uapi/linux/fs.h2
-rw-r--r--include/uapi/linux/gpio.h2
-rw-r--r--include/uapi/linux/handshake.h5
-rw-r--r--include/uapi/linux/if_addr.h1
-rw-r--r--include/uapi/linux/if_link.h1
-rw-r--r--include/uapi/linux/iio/types.h1
-rw-r--r--include/uapi/linux/input-event-codes.h6
-rw-r--r--include/uapi/linux/io_uring.h15
-rw-r--r--include/uapi/linux/iommufd.h12
-rw-r--r--include/uapi/linux/it6625.h25
-rw-r--r--include/uapi/linux/keyctl.h1
-rw-r--r--include/uapi/linux/kvm.h16
-rw-r--r--include/uapi/linux/landlock.h139
-rw-r--r--include/uapi/linux/media.h7
-rw-r--r--include/uapi/linux/media/arm/mali-c55-config.h2
-rw-r--r--include/uapi/linux/media/st/dcmipp_config.h16
-rw-r--r--include/uapi/linux/mii.h2
-rw-r--r--include/uapi/linux/mount.h1
-rw-r--r--include/uapi/linux/netdev.h2
-rw-r--r--include/uapi/linux/netfilter/nfnetlink_conntrack.h1
-rw-r--r--include/uapi/linux/netlink.h14
-rw-r--r--include/uapi/linux/nl80211.h115
-rw-r--r--include/uapi/linux/nsfs.h1
-rw-r--r--include/uapi/linux/perf_event.h49
-rw-r--r--include/uapi/linux/psp-sev.h26
-rw-r--r--include/uapi/linux/random.h2
-rw-r--r--include/uapi/linux/sched.h2
-rw-r--r--include/uapi/linux/seccomp.h2
-rw-r--r--include/uapi/linux/tee.h40
-rw-r--r--include/uapi/linux/thermal.h8
-rw-r--r--include/uapi/linux/v4l2-controls.h21
-rw-r--r--include/uapi/rdma/bnxt_re-abi.h2
-rw-r--r--include/uapi/rdma/ionic-abi.h11
-rw-r--r--include/uapi/rdma/mana-abi.h12
-rw-r--r--include/uapi/sound/asound.h3
-rw-r--r--include/ufs/ufs.h1
-rw-r--r--include/ufs/ufshcd.h8
-rw-r--r--include/vdso/getrandom.h2
-rw-r--r--include/vdso/math64.h33
-rw-r--r--include/vdso/vsyscall.h7
-rw-r--r--include/video/mmp_disp.h6
-rw-r--r--include/xen/interface/hvm/hvm_vcpu.h116
-rw-r--r--include/xen/interface/platform.h4
-rw-r--r--include/xen/interface/xen.h2
-rw-r--r--include/xen/xenbus.h2
664 files changed, 18998 insertions, 6017 deletions
diff --git a/include/acpi/acpi_bus.h b/include/acpi/acpi_bus.h
index a10a591c18b2..a755b15af9db 100644
--- a/include/acpi/acpi_bus.h
+++ b/include/acpi/acpi_bus.h
@@ -9,6 +9,8 @@
#ifndef __ACPI_BUS_H__
#define __ACPI_BUS_H__
+#ifdef CONFIG_ACPI
+
#include <linux/completion.h>
#include <linux/container_of.h>
#include <linux/device.h>
@@ -58,7 +60,6 @@ bool acpi_dock_match(acpi_handle handle);
bool acpi_check_dsm(acpi_handle handle, const guid_t *guid, u64 rev, u64 funcs);
union acpi_object *acpi_evaluate_dsm(acpi_handle handle, const guid_t *guid,
u64 rev, u64 func, union acpi_object *argv4);
-#ifdef CONFIG_ACPI
bool
acpi_get_physical_device_location(acpi_handle handle, struct acpi_pld_info **pld);
@@ -77,7 +78,6 @@ acpi_evaluate_dsm_typed(acpi_handle handle, const guid_t *guid, u64 rev,
return obj;
}
-#endif
#define ACPI_INIT_DSM_ARGV4(cnt, eles) \
{ \
@@ -90,8 +90,6 @@ bool acpi_dev_found(const char *hid);
bool acpi_dev_present(const char *hid, const char *uid, s64 hrv);
bool acpi_reduced_hardware(void);
-#ifdef CONFIG_ACPI
-
struct proc_dir_entry;
#define ACPI_BUS_FILE_ROOT "acpi"
@@ -435,9 +433,9 @@ struct acpi_device_software_nodes {
/* Device */
struct acpi_device {
+ acpi_handle handle; /* no handle for fixed hardware */
u32 pld_crc;
int device_type;
- acpi_handle handle; /* no handle for fixed hardware */
struct fwnode_handle fwnode;
struct list_head wakeup_list;
struct list_head del_list;
@@ -613,7 +611,6 @@ int acpi_bus_get_status(struct acpi_device *device);
int acpi_bus_set_power(acpi_handle handle, int state);
const char *acpi_power_state_string(int state);
int acpi_device_set_power(struct acpi_device *device, int state);
-int acpi_bus_init_power(struct acpi_device *device);
int acpi_device_fix_up_power(struct acpi_device *device);
void acpi_device_fix_up_power_extended(struct acpi_device *adev);
void acpi_device_fix_up_power_children(struct acpi_device *adev);
@@ -665,7 +662,7 @@ struct acpi_bus_type {
int register_acpi_bus_type(struct acpi_bus_type *);
int unregister_acpi_bus_type(struct acpi_bus_type *);
int acpi_bind_one(struct device *dev, struct acpi_device *adev);
-int acpi_unbind_one(struct device *dev);
+void acpi_unbind_one(struct device *dev);
enum acpi_bridge_type {
ACPI_BRIDGE_TYPE_PCIE = 1,
@@ -830,7 +827,15 @@ static inline bool acpi_str_uid_match(struct acpi_device *adev, const char *uid2
{
const char *uid1 = acpi_device_uid(adev);
- return uid1 && uid2 && !strcmp(uid1, uid2);
+ if (!uid1 || !uid2)
+ return false;
+
+ if (*uid1 == '\\' && uid1[1])
+ uid1++;
+ if (*uid2 == '\\' && uid2[1])
+ uid2++;
+
+ return !strcmp(uid1, uid2);
}
static inline bool acpi_int_uid_match(struct acpi_device *adev, u64 uid2)
@@ -857,6 +862,10 @@ static inline bool acpi_int_uid_match(struct acpi_device *adev, u64 uid2)
*
* Matches UID in @adev with given @uid2.
*
+ * If both the UID in @adev and @uid2 are strings, they are compared
+ * after optionally skipping a leading backslash ('\') if the given
+ * string contains additional characters.
+ *
* Returns: %true if matches, %false otherwise.
*/
#define acpi_dev_uid_match(adev, uid2) \
@@ -942,8 +951,21 @@ int acpi_wait_for_acpi_ipmi(void);
int acpi_scan_add_dep(acpi_handle handle, struct acpi_handle_list *dep_devices);
u32 arch_acpi_add_auto_dep(acpi_handle handle);
+
#else /* CONFIG_ACPI */
+static inline struct acpi_device *
+acpi_find_child_device(struct acpi_device *parent, u64 address,
+ bool check_children)
+{
+ return NULL;
+}
+
+static inline bool acpi_has_method(acpi_handle handle, char *name)
+{
+ return false;
+}
+
static inline struct device *acpi_bus_get_primary_device(struct acpi_device *adev)
{
return NULL;
@@ -959,6 +981,11 @@ static inline const char *acpi_device_hid(struct acpi_device *device)
return "";
}
+static inline char *acpi_device_uid(struct acpi_device *device)
+{
+ return NULL;
+}
+
static inline bool
acpi_get_physical_device_location(acpi_handle handle, struct acpi_pld_info **pld)
{
diff --git a/include/acpi/actbl2.h b/include/acpi/actbl2.h
index baef525367b5..76e4a5bc79b4 100644
--- a/include/acpi/actbl2.h
+++ b/include/acpi/actbl2.h
@@ -919,6 +919,13 @@ struct acpi_iovt_iommu {
u32 device_entry_offset;
};
+/* Masks for Flags field above */
+#define ACPI_IOVT_IOMMU_PCI_DEVICE (1<<0)
+#define ACPI_IOVT_IOMMU_PXM_VALID (1<<1)
+#define ACPI_IOVT_IOMMU_MAGAGE_BY_SEGMENT (1<<2)
+#define ACPI_IOVT_IOMMU_HW_CAP_SUPPORT (1<<3)
+#define ACPI_IOVT_IOMMU_MSI_INT_BYPASS (1<<4)
+
struct acpi_iovt_device_entry {
u8 type;
u8 length;
diff --git a/include/acpi/cppc_acpi.h b/include/acpi/cppc_acpi.h
index 94a6277edab2..5bcdb0e553b9 100644
--- a/include/acpi/cppc_acpi.h
+++ b/include/acpi/cppc_acpi.h
@@ -72,11 +72,16 @@ struct cpc_register_resource {
struct {
struct cpc_reg reg;
bool use_rmw_lock;
+ bool read_unsupported;
+ bool write_unsupported;
};
u64 int_value;
} cpc_entry;
};
+struct cpc_sysmem_node;
+struct cpc_non_mmio_node;
+
/* Container to hold the CPC details for each CPU */
struct cpc_desc {
int num_entries;
@@ -84,10 +89,12 @@ struct cpc_desc {
int cpu_id;
int write_cmd_status;
int write_cmd_id;
- /* Lock used for RMW operations in cpc_write() */
+ /* Serialize partial SystemMemory writes within this descriptor. */
raw_spinlock_t rmw_lock;
struct cpc_register_resource cpc_regs[MAX_CPC_REG_ENT];
struct acpi_psd_package domain_info;
+ struct cpc_sysmem_node *sysmem_nodes;
+ struct cpc_non_mmio_node *non_mmio_nodes;
struct kobject kobj;
};
@@ -141,6 +148,8 @@ struct cppc_perf_ctrls {
u32 desired_perf;
u32 energy_perf;
bool auto_sel;
+ /* Allow an explicit zero minimum; otherwise zero omits the update. */
+ bool min_perf_valid;
};
struct cppc_perf_fb_ctrs {
@@ -188,11 +197,14 @@ extern int cppc_set_epp(int cpu, u64 epp_val);
extern int cppc_get_auto_act_window(int cpu, u64 *auto_act_window);
extern int cppc_set_auto_act_window(int cpu, u64 auto_act_window);
extern int cppc_get_auto_sel(int cpu, bool *enable);
+bool cppc_auto_sel_is_immutable(int cpu);
extern int cppc_set_auto_sel(int cpu, bool enable);
extern int cppc_get_perf_limited(int cpu, u64 *perf_limited);
extern int cppc_set_perf_limited(int cpu, u64 bits_to_clear);
extern int amd_get_highest_perf(unsigned int cpu, u32 *highest_perf);
-extern int amd_get_boost_ratio_numerator(unsigned int cpu, u64 *numerator);
+extern int amd_get_effective_highest_perf(unsigned int cpu);
+extern int amd_get_max_frequency(unsigned int cpu);
+extern int amd_get_boost_ratio(unsigned int cpu, u64 *numerator, u64 *denominator);
extern int amd_detect_prefcore(bool *detected);
#else /* !CONFIG_ACPI_CPPC_LIB */
static inline int cppc_get_desired_perf(int cpunum, u64 *desired_perf)
@@ -289,6 +301,12 @@ static inline int cppc_get_auto_sel(int cpu, bool *enable)
{
return -EOPNOTSUPP;
}
+
+static inline bool cppc_auto_sel_is_immutable(int cpu)
+{
+ return false;
+}
+
static inline int cppc_set_auto_sel(int cpu, bool enable)
{
return -EOPNOTSUPP;
@@ -305,7 +323,15 @@ static inline int amd_get_highest_perf(unsigned int cpu, u32 *highest_perf)
{
return -ENODEV;
}
-static inline int amd_get_boost_ratio_numerator(unsigned int cpu, u64 *numerator)
+static inline int amd_get_effective_highest_perf(unsigned int cpu)
+{
+ return -EOPNOTSUPP;
+}
+static inline int amd_get_max_frequency(unsigned int cpu)
+{
+ return 0;
+}
+static inline int amd_get_boost_ratio(unsigned int cpu, u64 *numerator, u64 *denominator)
{
return -EOPNOTSUPP;
}
diff --git a/include/acpi/ghes.h b/include/acpi/ghes.h
index 8d7e5caef3f1..7acf209061ea 100644
--- a/include/acpi/ghes.h
+++ b/include/acpi/ghes.h
@@ -85,6 +85,10 @@ int devm_ghes_register_vendor_record_notifier(struct device *dev,
struct list_head *ghes_get_devices(void);
void ghes_estatus_pool_region_free(unsigned long addr, u32 size);
+
+struct cxl_cper_sec_prot_err;
+void cxl_cper_post_prot_err(struct cxl_cper_sec_prot_err *prot_err,
+ int severity, u32 len);
#else
static inline struct list_head *ghes_get_devices(void) { return NULL; }
diff --git a/include/acpi/processor.h b/include/acpi/processor.h
index 554be224ce76..b5447af4d40b 100644
--- a/include/acpi/processor.h
+++ b/include/acpi/processor.h
@@ -427,10 +427,8 @@ int acpi_processor_ffh_lpi_enter(struct acpi_lpi_state *lpi);
#endif /* CONFIG_ACPI_PROCESSOR_IDLE */
/* in processor_thermal.c */
-int acpi_processor_thermal_init(struct acpi_processor *pr,
- struct acpi_device *device);
-void acpi_processor_thermal_exit(struct acpi_processor *pr,
- struct acpi_device *device);
+int acpi_processor_thermal_init(struct acpi_processor *pr);
+void acpi_processor_thermal_exit(struct acpi_processor *pr);
extern const struct thermal_cooling_device_ops processor_cooling_ops;
#ifdef CONFIG_CPU_FREQ
void acpi_thermal_cpufreq_init(struct cpufreq_policy *policy);
diff --git a/include/asm-generic/Kbuild b/include/asm-generic/Kbuild
index 2bc00c67dc54..b7a388bef6ea 100644
--- a/include/asm-generic/Kbuild
+++ b/include/asm-generic/Kbuild
@@ -63,6 +63,7 @@ mandatory-y += trace_clock.h
mandatory-y += uaccess.h
mandatory-y += unwind_user.h
mandatory-y += vdso/clocksource.h
+mandatory-y += vdso/vsyscall.h
mandatory-y += vermagic.h
mandatory-y += vga.h
mandatory-y += video.h
diff --git a/include/asm-generic/mshyperv.h b/include/asm-generic/mshyperv.h
index bf601d67cecb..34d4c332449c 100644
--- a/include/asm-generic/mshyperv.h
+++ b/include/asm-generic/mshyperv.h
@@ -73,6 +73,10 @@ extern enum hv_partition_type hv_curr_partition_type;
extern void * __percpu *hyperv_pcpu_input_arg;
extern void * __percpu *hyperv_pcpu_output_arg;
+int hv_pci_register_dev_id(int pci_domain_nr, u32 logical_dev_id_prefix);
+void hv_pci_unregister_dev_id(int pci_domain_nr);
+int hv_pci_lookup_dev_id(int pci_domain_nr, u32 *prefix);
+
u64 hv_do_hypercall(u64 control, void *inputaddr, void *outputaddr);
u64 hv_do_fast_hypercall8(u16 control, u64 input8);
u64 hv_do_fast_hypercall16(u16 control, u64 input1, u64 input2);
diff --git a/include/asm-generic/pgtable-nop4d.h b/include/asm-generic/pgtable-nop4d.h
index 89c21f84cffb..1cf739ee38aa 100644
--- a/include/asm-generic/pgtable-nop4d.h
+++ b/include/asm-generic/pgtable-nop4d.h
@@ -22,7 +22,6 @@ static inline int pgd_none(pgd_t pgd) { return 0; }
static inline int pgd_bad(pgd_t pgd) { return 0; }
static inline int pgd_present(pgd_t pgd) { return 1; }
static inline void pgd_clear(pgd_t *pgd) { }
-#define p4d_ERROR(p4d) (pgd_ERROR((p4d).pgd))
#define pgd_populate(mm, pgd, p4d) do { } while (0)
#define pgd_populate_safe(mm, pgd, p4d) do { } while (0)
diff --git a/include/asm-generic/pgtable-nopmd.h b/include/asm-generic/pgtable-nopmd.h
index 36b6490ed180..ff4235cf84d7 100644
--- a/include/asm-generic/pgtable-nopmd.h
+++ b/include/asm-generic/pgtable-nopmd.h
@@ -33,7 +33,6 @@ static inline int pud_present(pud_t pud) { return 1; }
static inline int pud_user(pud_t pud) { return 0; }
static inline int pud_leaf(pud_t pud) { return 0; }
static inline void pud_clear(pud_t *pud) { }
-#define pmd_ERROR(pmd) (pud_ERROR((pmd).pud))
#define pud_populate(mm, pmd, pte) do { } while (0)
diff --git a/include/asm-generic/pgtable-nopud.h b/include/asm-generic/pgtable-nopud.h
index 356cbfbaab24..eedee8e3ad68 100644
--- a/include/asm-generic/pgtable-nopud.h
+++ b/include/asm-generic/pgtable-nopud.h
@@ -29,7 +29,6 @@ static inline int p4d_none(p4d_t p4d) { return 0; }
static inline int p4d_bad(p4d_t p4d) { return 0; }
static inline int p4d_present(p4d_t p4d) { return 1; }
static inline void p4d_clear(p4d_t *p4d) { }
-#define pud_ERROR(pud) (p4d_ERROR((pud).p4d))
#define p4d_populate(mm, p4d, pud) do { } while (0)
#define p4d_populate_safe(mm, p4d, pud) do { } while (0)
diff --git a/include/asm-generic/preempt.h b/include/asm-generic/preempt.h
index c8683c046615..1adddeab8545 100644
--- a/include/asm-generic/preempt.h
+++ b/include/asm-generic/preempt.h
@@ -96,19 +96,9 @@ static __always_inline bool should_resched(int preempt_offset)
extern asmlinkage void preempt_schedule(void);
extern asmlinkage void preempt_schedule_notrace(void);
-#if defined(CONFIG_PREEMPT_DYNAMIC) && defined(CONFIG_HAVE_PREEMPT_DYNAMIC_KEY)
-
-void dynamic_preempt_schedule(void);
-void dynamic_preempt_schedule_notrace(void);
-#define __preempt_schedule() dynamic_preempt_schedule()
-#define __preempt_schedule_notrace() dynamic_preempt_schedule_notrace()
-
-#else /* !CONFIG_PREEMPT_DYNAMIC || !CONFIG_HAVE_PREEMPT_DYNAMIC_KEY*/
-
#define __preempt_schedule() preempt_schedule()
#define __preempt_schedule_notrace() preempt_schedule_notrace()
-#endif /* CONFIG_PREEMPT_DYNAMIC && CONFIG_HAVE_PREEMPT_DYNAMIC_KEY*/
#endif /* CONFIG_PREEMPTION */
#endif /* __ASM_PREEMPT_H */
diff --git a/include/asm-generic/tlb.h b/include/asm-generic/tlb.h
index bdcc2778ac64..9d827076db19 100644
--- a/include/asm-generic/tlb.h
+++ b/include/asm-generic/tlb.h
@@ -67,11 +67,8 @@
* - tlb_remove_table()
*
* tlb_remove_table() is the basic primitive to free page-table directories
- * (__p*_free_tlb()). In it's most primitive form it is an alias for
- * tlb_remove_page() below, for when page directories are pages and have no
- * additional constraints.
- *
- * See also MMU_GATHER_TABLE_FREE and MMU_GATHER_RCU_TABLE_FREE.
+ * (__p*_free_tlb()). Page directories are freed after an RCU grace
+ * period - see the comment in mm/mmu_gather.c.
*
* - tlb_remove_page() / tlb_remove_page_size()
* - __tlb_remove_folio_pages() / __tlb_remove_page_size()
@@ -151,24 +148,15 @@
* This might be useful if your architecture has size specific TLB
* invalidation instructions.
*
- * MMU_GATHER_TABLE_FREE
- *
- * This provides tlb_remove_table(), to be used instead of tlb_remove_page()
- * for page directores (__p*_free_tlb()).
- *
- * Useful if your architecture has non-page page directories.
+ * Page directories (__p*_free_tlb()) are always freed via tlb_remove_table(),
+ * after an RCU grace period (see mm/mmu_gather.c).
*
- * When used, an architecture is expected to provide __tlb_remove_table() or
- * use the generic __tlb_remove_table(), which does the actual freeing of these
- * pages.
+ * This serialises against software page-table walkers, including architectures
+ * which do not use IPIs for remote TLB invalidates.
*
- * MMU_GATHER_RCU_TABLE_FREE
- *
- * Like MMU_GATHER_TABLE_FREE, and adds semi-RCU semantics to the free (see
- * comment below).
- *
- * Useful if your architecture doesn't use IPIs for remote TLB invalidates
- * and therefore doesn't naturally serialize with software page-table walkers.
+ * An architecture is expected to provide __tlb_remove_table() (see
+ * HAVE_ARCH_TLB_REMOVE_TABLE) or use the generic __tlb_remove_table(), which
+ * does the actual freeing of these pages.
*
* MMU_GATHER_NO_FLUSH_CACHE
*
@@ -200,12 +188,8 @@
* various ptep_get_and_clear() functions.
*/
-#ifdef CONFIG_MMU_GATHER_TABLE_FREE
-
struct mmu_table_batch {
-#ifdef CONFIG_MMU_GATHER_RCU_TABLE_FREE
struct rcu_head rcu;
-#endif
unsigned int nr;
void *tables[];
};
@@ -224,23 +208,6 @@ static inline void __tlb_remove_table(void *table)
extern void tlb_remove_table(struct mmu_gather *tlb, void *table);
-#else /* !CONFIG_MMU_GATHER_TABLE_FREE */
-
-static inline void tlb_remove_page(struct mmu_gather *tlb, struct page *page);
-/*
- * Without MMU_GATHER_TABLE_FREE the architecture is assumed to have page based
- * page directories and we can use the normal page batching to free them.
- */
-static inline void tlb_remove_table(struct mmu_gather *tlb, void *table)
-{
- struct ptdesc *ptdesc = (struct ptdesc *)table;
-
- pagetable_dtor(ptdesc);
- tlb_remove_page(tlb, ptdesc_page(ptdesc));
-}
-#endif /* CONFIG_MMU_GATHER_TABLE_FREE */
-
-#ifdef CONFIG_MMU_GATHER_RCU_TABLE_FREE
/*
* This allows an architecture that does not use the linux page-tables for
* hardware to skip the TLBI when freeing page tables.
@@ -253,19 +220,6 @@ void tlb_remove_table_sync_one(void);
void tlb_remove_table_sync_rcu(void);
-#else
-
-#ifdef tlb_needs_table_invalidate
-#error tlb_needs_table_invalidate() requires MMU_GATHER_RCU_TABLE_FREE
-#endif
-
-static inline void tlb_remove_table_sync_one(void) { }
-
-static inline void tlb_remove_table_sync_rcu(void) { }
-
-#endif /* CONFIG_MMU_GATHER_RCU_TABLE_FREE */
-
-
#ifndef CONFIG_MMU_GATHER_NO_GATHER
/*
* If we can't allocate a page to make a big batch of page pointers
@@ -325,9 +279,7 @@ static inline void tlb_flush_rmaps(struct mmu_gather *tlb, struct vm_area_struct
struct mmu_gather {
struct mm_struct *mm;
-#ifdef CONFIG_MMU_GATHER_TABLE_FREE
struct mmu_table_batch *batch;
-#endif
unsigned long start;
unsigned long end;
diff --git a/include/asm-generic/vdso/vsyscall.h b/include/asm-generic/vdso/vsyscall.h
index a6b03cfba0e2..e69de29bb2d1 100644
--- a/include/asm-generic/vdso/vsyscall.h
+++ b/include/asm-generic/vdso/vsyscall.h
@@ -1,35 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-#ifndef __ASM_GENERIC_VSYSCALL_H
-#define __ASM_GENERIC_VSYSCALL_H
-
-#ifndef __ASSEMBLER__
-
-#ifndef __arch_get_vdso_u_time_data
-static __always_inline const struct vdso_time_data *__arch_get_vdso_u_time_data(void)
-{
- return &vdso_u_time_data;
-}
-#endif
-
-#ifndef __arch_get_vdso_u_rng_data
-static __always_inline const struct vdso_rng_data *__arch_get_vdso_u_rng_data(void)
-{
- return &vdso_u_rng_data;
-}
-#endif
-
-#ifndef __arch_update_vdso_clock
-static __always_inline void __arch_update_vdso_clock(struct vdso_clock *vc)
-{
-}
-#endif /* __arch_update_vdso_clock */
-
-#ifndef __arch_sync_vdso_time_data
-static __always_inline void __arch_sync_vdso_time_data(struct vdso_time_data *vdata)
-{
-}
-#endif /* __arch_sync_vdso_time_data */
-
-#endif /* !__ASSEMBLER__ */
-
-#endif /* __ASM_GENERIC_VSYSCALL_H */
diff --git a/include/asm-generic/vmlinux.lds.h b/include/asm-generic/vmlinux.lds.h
index b2988aa12f66..3eb732942d69 100644
--- a/include/asm-generic/vmlinux.lds.h
+++ b/include/asm-generic/vmlinux.lds.h
@@ -675,12 +675,43 @@
/*
* .BTF
*/
+#ifdef CONFIG_DEBUG_INFO_BTF_INLINE
+#define BTF_INLINE \
+ . = ALIGN(PAGE_SIZE); \
+ .BTF.inline : AT(ADDR(.BTF.inline) - LOAD_OFFSET) { \
+ BOUNDED_SECTION_BY(.BTF.inline, _BTF_inline) \
+ }
+#else
+#define BTF_INLINE
+#endif
+
+#ifdef CONFIG_DEBUG_INFO_BTF_INLINE_MODULE
+/* __MODULE_NAME_LEN + SHA-256 digest + u32 BTF size */
+#ifdef CONFIG_64BIT
+#define BTF_LINK_SIZE (64 - 8 + 32 + 4)
+#else
+#define BTF_LINK_SIZE (64 - 4 + 32 + 4)
+#endif
+#define BTF_INLINE_LINK \
+ . = ALIGN(PAGE_SIZE); \
+ .BTF.inline.link : AT(ADDR(.BTF.inline.link) - LOAD_OFFSET) { \
+ __start_BTF_inline_link = .; \
+ BYTE(0) \
+ . += BTF_LINK_SIZE - 1; \
+ __stop_BTF_inline_link = .; \
+ }
+#else
+#define BTF_INLINE_LINK
+#endif
+
#ifdef CONFIG_DEBUG_INFO_BTF
#define BTF \
. = ALIGN(PAGE_SIZE); \
.BTF : AT(ADDR(.BTF) - LOAD_OFFSET) { \
BOUNDED_SECTION_BY(.BTF, _BTF) \
} \
+ BTF_INLINE \
+ BTF_INLINE_LINK \
. = ALIGN(PAGE_SIZE); \
.BTF_ids : AT(ADDR(.BTF_ids) - LOAD_OFFSET) { \
*(.BTF_ids) \
@@ -855,7 +886,7 @@
KLP_SYMID
#define MODINFO \
- .modinfo : { *(.modinfo) . = ALIGN(8); }
+ .modinfo (INFO) : { KEEP(*(.modinfo)) }
#ifdef CONFIG_GENERIC_BUG
#define BUG_TABLE \
diff --git a/include/crypto/aes-ccm.h b/include/crypto/aes-ccm.h
index 8b00859ac4d6..c52982dd91d2 100644
--- a/include/crypto/aes-ccm.h
+++ b/include/crypto/aes-ccm.h
@@ -19,6 +19,15 @@ struct aes_ccm_key {
};
/**
+ * aes_ccm_zeroize_key() - Zeroize an aes_ccm_key structure
+ * @key: The aes_ccm_key to zeroize
+ */
+static inline void aes_ccm_zeroize_key(struct aes_ccm_key *key)
+{
+ memzero_explicit(key, sizeof(*key));
+}
+
+/**
* struct aes_ccm_ctx - Context for incrementally en/decrypting a message
*/
struct aes_ccm_ctx {
@@ -51,6 +60,15 @@ struct aes_ccm_ctx {
};
/**
+ * aes_ccm_zeroize_ctx() - Zeroize an aes_ccm_ctx structure
+ * @ctx: The aes_ccm_ctx to zeroize
+ */
+static inline void aes_ccm_zeroize_ctx(struct aes_ccm_ctx *ctx)
+{
+ memzero_explicit(ctx, sizeof(*ctx));
+}
+
+/**
* aes_ccm_preparekey() - Prepare a key for AES-CCM encryption and decryption
* @key: (output) The key structure to initialize
* @in_key: The raw AES-CCM key
@@ -58,8 +76,8 @@ struct aes_ccm_ctx {
* @authtag_len: Length of the authentication tag in bytes:
* 4, 6, 8, 10, 12, 14, or 16. 16 is recommended.
*
- * Users should use memzero_explicit() to zeroize the key struct at the end of
- * its lifetime. (But if this function fails, zeroization is unnecessary.)
+ * Users should use aes_ccm_zeroize_key() to zeroize the key struct at the end
+ * of its lifetime. (But if this function fails, zeroization is unnecessary.)
*
* Context: Any context.
* Return:
diff --git a/include/crypto/aes-gcm.h b/include/crypto/aes-gcm.h
index 2aee62f01989..a81b00fd8e27 100644
--- a/include/crypto/aes-gcm.h
+++ b/include/crypto/aes-gcm.h
@@ -22,6 +22,15 @@ struct aes_gcm_key {
};
/**
+ * aes_gcm_zeroize_key() - Zeroize an aes_gcm_key structure
+ * @key: The aes_gcm_key to zeroize
+ */
+static inline void aes_gcm_zeroize_key(struct aes_gcm_key *key)
+{
+ memzero_explicit(key, sizeof(*key));
+}
+
+/**
* struct aes_gcm_ctx - Context for incrementally en/decrypting a message
*/
struct aes_gcm_ctx {
@@ -59,6 +68,15 @@ struct aes_gcm_ctx {
};
/**
+ * aes_gcm_zeroize_ctx() - Zeroize an aes_gcm_ctx structure
+ * @ctx: The aes_gcm_ctx to zeroize
+ */
+static inline void aes_gcm_zeroize_ctx(struct aes_gcm_ctx *ctx)
+{
+ memzero_explicit(ctx, sizeof(*ctx));
+}
+
+/**
* aes_gcm_preparekey() - Prepare a key for AES-GCM encryption and decryption
* @key: (output) The key structure to initialize
* @in_key: The raw AES-GCM key
@@ -66,8 +84,8 @@ struct aes_gcm_ctx {
* @authtag_len: Length of the authentication tag in bytes:
* 4, 8, 12, 13, 14, 15, or 16. 16 is recommended.
*
- * Users should use memzero_explicit() to zeroize the key struct at the end of
- * its lifetime. (But if this function fails, zeroization is unnecessary.)
+ * Users should use aes_gcm_zeroize_key() to zeroize the key struct at the end
+ * of its lifetime. (But if this function fails, zeroization is unnecessary.)
*
* Context: Any context.
* Return:
diff --git a/include/crypto/aes-xts.h b/include/crypto/aes-xts.h
index b9e828265e58..3a52e1cf40b5 100644
--- a/include/crypto/aes-xts.h
+++ b/include/crypto/aes-xts.h
@@ -23,6 +23,15 @@ struct aes_xts_key {
};
/**
+ * aes_xts_zeroize_key() - Zeroize an aes_xts_key structure
+ * @key: The aes_xts_key to zeroize
+ */
+static inline void aes_xts_zeroize_key(struct aes_xts_key *key)
+{
+ memzero_explicit(key, sizeof(*key));
+}
+
+/**
* aes_xts_preparekey() - Prepare a key for AES-XTS encryption and decryption
* @key: (output) The key structure to initialize
* @in_key: The raw AES-XTS key
@@ -30,8 +39,8 @@ struct aes_xts_key {
* @flags: Optional flag XTS_FORBID_WEAK_KEYS to forbid keys whose two halves
* are the same.
*
- * Users should use memzero_explicit() to zeroize the key struct at the end of
- * its lifetime. (But if this function fails, zeroization is unnecessary.)
+ * Users should use aes_xts_zeroize_key() to zeroize the key struct at the end
+ * of its lifetime. (But if this function fails, zeroization is unnecessary.)
*
* Context: Any context.
* Return:
diff --git a/include/crypto/aes.h b/include/crypto/aes.h
index 3279cfa54608..fa5c3d363ac9 100644
--- a/include/crypto/aes.h
+++ b/include/crypto/aes.h
@@ -102,6 +102,15 @@ struct aes_enckey {
};
/**
+ * aes_zeroize_enckey() - Zeroize an aes_enckey structure
+ * @key: The aes_enckey to zeroize
+ */
+static inline void aes_zeroize_enckey(struct aes_enckey *key)
+{
+ memzero_explicit(key, sizeof(*key));
+}
+
+/**
* struct aes_key - An AES key prepared for encryption and decryption
* @aes_enckey: Common fields and the key prepared for encryption
* @inv_k: This generally contains the round keys for the AES Equivalent
@@ -115,6 +124,15 @@ struct aes_key {
union aes_invkey_arch inv_k;
};
+/**
+ * aes_zeroize_key() - Zeroize an aes_key structure
+ * @key: The aes_key to zeroize
+ */
+static inline void aes_zeroize_key(struct aes_key *key)
+{
+ memzero_explicit(key, sizeof(*key));
+}
+
/*
* Please ensure that the first two fields are 16-byte aligned
* relative to the start of the structure, i.e., don't move them!
@@ -159,6 +177,19 @@ static inline int aes_check_keylen(size_t keylen)
int aes_expandkey(struct crypto_aes_ctx *ctx, const u8 *in_key,
unsigned int key_len);
+/**
+ * aes_zeroize_ctx - Clear a crypto_aes_ctx structure
+ * @ctx: The location of the context that should be zeroized
+ *
+ * Explicitly fills the crypto_aes_ctx with zeroes. This should be done
+ * once the context is not required anymore to avoid that its contents
+ * are leaked on the stack or heap (if not using kfree_sensitive()).
+ */
+static inline void aes_zeroize_ctx(struct crypto_aes_ctx *ctx)
+{
+ memzero_explicit(ctx, sizeof(*ctx));
+}
+
/*
* The following functions are temporarily exported for use by the AES mode
* implementations in arch/$(SRCARCH)/crypto/. These exports will go away when
diff --git a/include/crypto/blake2b.h b/include/crypto/blake2b.h
index 3bc37fd103a7..eda1604bce78 100644
--- a/include/crypto/blake2b.h
+++ b/include/crypto/blake2b.h
@@ -37,6 +37,15 @@ struct blake2b_ctx {
unsigned int outlen;
};
+/**
+ * blake2b_zeroize_ctx() - Zeroize a blake2b_ctx structure
+ * @ctx: The blake2b_ctx to zeroize
+ */
+static inline void blake2b_zeroize_ctx(struct blake2b_ctx *ctx)
+{
+ memzero_explicit(ctx, sizeof(*ctx));
+}
+
enum blake2b_iv {
BLAKE2B_IV0 = 0x6A09E667F3BCC908ULL,
BLAKE2B_IV1 = 0xBB67AE8584CAA73BULL,
diff --git a/include/crypto/blake2s.h b/include/crypto/blake2s.h
index 648cb7824358..bb4e6870ed19 100644
--- a/include/crypto/blake2s.h
+++ b/include/crypto/blake2s.h
@@ -41,6 +41,15 @@ struct blake2s_ctx {
unsigned int outlen;
};
+/**
+ * blake2s_zeroize_ctx() - Zeroize a blake2s_ctx structure
+ * @ctx: The blake2s_ctx to zeroize
+ */
+static inline void blake2s_zeroize_ctx(struct blake2s_ctx *ctx)
+{
+ memzero_explicit(ctx, sizeof(*ctx));
+}
+
enum blake2s_iv {
BLAKE2S_IV0 = 0x6A09E667UL,
BLAKE2S_IV1 = 0xBB67AE85UL,
diff --git a/include/crypto/chacha.h b/include/crypto/chacha.h
index 1cc301a48469..bacf253781d5 100644
--- a/include/crypto/chacha.h
+++ b/include/crypto/chacha.h
@@ -86,10 +86,10 @@ static inline void chacha_init(struct chacha_state *state,
}
void chacha_crypt(struct chacha_state *state, u8 *dst, const u8 *src,
- unsigned int bytes, int nrounds);
+ size_t bytes, int nrounds);
-static inline void chacha20_crypt(struct chacha_state *state,
- u8 *dst, const u8 *src, unsigned int bytes)
+static inline void chacha20_crypt(struct chacha_state *state, u8 *dst,
+ const u8 *src, size_t bytes)
{
chacha_crypt(state, dst, src, bytes, 20);
}
diff --git a/include/crypto/internal/poly1305.h b/include/crypto/internal/poly1305.h
index a72fff409ab8..6b0dec05cd36 100644
--- a/include/crypto/internal/poly1305.h
+++ b/include/crypto/internal/poly1305.h
@@ -26,7 +26,7 @@ static inline void poly1305_core_init(struct poly1305_state *state)
void poly1305_core_blocks(struct poly1305_state *state,
const struct poly1305_core_key *key, const void *src,
- unsigned int nblocks, u32 hibit);
+ size_t nblocks, u32 hibit);
void poly1305_core_emit(const struct poly1305_state *state, const u32 nonce[4],
void *dst);
@@ -39,7 +39,7 @@ poly1305_block_init_generic(struct poly1305_block_state *desc,
}
static inline void poly1305_blocks_generic(struct poly1305_block_state *state,
- const u8 *src, unsigned int len,
+ const u8 *src, size_t len,
u32 padbit)
{
poly1305_core_blocks(&state->h, &state->core_r, src,
diff --git a/include/crypto/md5.h b/include/crypto/md5.h
index c47aedfe67ec..1ed89c15b662 100644
--- a/include/crypto/md5.h
+++ b/include/crypto/md5.h
@@ -4,6 +4,7 @@
#include <crypto/hash.h>
#include <linux/types.h>
+#include <linux/string.h>
#define MD5_DIGEST_SIZE 16
#define MD5_HMAC_BLOCK_SIZE 64
@@ -99,6 +100,15 @@ struct hmac_md5_key {
};
/**
+ * hmac_md5_zeroize_key() - Zeroize an hmac_md5_key structure
+ * @key: The hmac_md5_key to zeroize
+ */
+static inline void hmac_md5_zeroize_key(struct hmac_md5_key *key)
+{
+ memzero_explicit(key, sizeof(*key));
+}
+
+/**
* struct hmac_md5_ctx - Context for computing HMAC-MD5 of a message
* @hash_ctx: private
* @ostate: private
@@ -109,6 +119,15 @@ struct hmac_md5_ctx {
};
/**
+ * hmac_md5_zeroize_ctx() - Zeroize an hmac_md5_ctx structure
+ * @ctx: The hmac_md5_ctx context to zeroize
+ */
+static inline void hmac_md5_zeroize_ctx(struct hmac_md5_ctx *ctx)
+{
+ memzero_explicit(ctx, sizeof(*ctx));
+}
+
+/**
* hmac_md5_preparekey() - Prepare a key for HMAC-MD5
* @key: (output) the key structure to initialize
* @raw_key: the raw HMAC-MD5 key
diff --git a/include/crypto/poly1305.h b/include/crypto/poly1305.h
index 190beb427c6d..ccdb0ea3e25d 100644
--- a/include/crypto/poly1305.h
+++ b/include/crypto/poly1305.h
@@ -60,8 +60,8 @@ struct poly1305_desc_ctx {
void poly1305_init(struct poly1305_desc_ctx *desc,
const u8 key[at_least POLY1305_KEY_SIZE]);
-void poly1305_update(struct poly1305_desc_ctx *desc,
- const u8 *src, unsigned int nbytes);
+void poly1305_update(struct poly1305_desc_ctx *desc, const u8 *src,
+ size_t nbytes);
void poly1305_final(struct poly1305_desc_ctx *desc, u8 *digest);
#endif
diff --git a/include/crypto/sha1.h b/include/crypto/sha1.h
index 4d973e016cd6..bc0046bffeae 100644
--- a/include/crypto/sha1.h
+++ b/include/crypto/sha1.h
@@ -7,6 +7,7 @@
#define _CRYPTO_SHA1_H
#include <linux/types.h>
+#include <linux/string.h>
#define SHA1_DIGEST_SIZE 20
#define SHA1_BLOCK_SIZE 64
@@ -97,6 +98,15 @@ struct hmac_sha1_key {
};
/**
+ * hmac_sha1_zeroize_key() - Zeroize an hmac_sha1_key structure
+ * @key: The hmac_sha1_key to zeroize
+ */
+static inline void hmac_sha1_zeroize_key(struct hmac_sha1_key *key)
+{
+ memzero_explicit(key, sizeof(*key));
+}
+
+/**
* struct hmac_sha1_ctx - Context for computing HMAC-SHA1 of a message
* @sha_ctx: private
* @ostate: private
@@ -107,6 +117,15 @@ struct hmac_sha1_ctx {
};
/**
+ * hmac_sha1_zeroize_ctx() - Zeroize an hmac_sha1_ctx structure
+ * @ctx: The hmac_sha1_ctx context to zeroize
+ */
+static inline void hmac_sha1_zeroize_ctx(struct hmac_sha1_ctx *ctx)
+{
+ memzero_explicit(ctx, sizeof(*ctx));
+}
+
+/**
* hmac_sha1_preparekey() - Prepare a key for HMAC-SHA1
* @key: (output) the key structure to initialize
* @raw_key: the raw HMAC-SHA1 key
diff --git a/include/crypto/sha2.h b/include/crypto/sha2.h
index 7bb8fe169daf..22fbc37ae840 100644
--- a/include/crypto/sha2.h
+++ b/include/crypto/sha2.h
@@ -7,6 +7,7 @@
#define _CRYPTO_SHA2_H
#include <linux/types.h>
+#include <linux/string.h>
#define SHA224_DIGEST_SIZE 28
#define SHA224_BLOCK_SIZE 64
@@ -211,6 +212,15 @@ struct hmac_sha224_key {
};
/**
+ * hmac_sha224_zeroize_key() - Zeroize an hmac_sha224_key structure
+ * @key: The hmac_sha224_key to zeroize
+ */
+static inline void hmac_sha224_zeroize_key(struct hmac_sha224_key *key)
+{
+ memzero_explicit(key, sizeof(*key));
+}
+
+/**
* struct hmac_sha224_ctx - Context for computing HMAC-SHA224 of a message
* @ctx: private
*/
@@ -219,6 +229,15 @@ struct hmac_sha224_ctx {
};
/**
+ * hmac_sha224_zeroize_ctx() - Zeroize an hmac_sha224_ctx structure
+ * @ctx: The hmac_sha224_ctx context to zeroize
+ */
+static inline void hmac_sha224_zeroize_ctx(struct hmac_sha224_ctx *ctx)
+{
+ memzero_explicit(ctx, sizeof(*ctx));
+}
+
+/**
* hmac_sha224_preparekey() - Prepare a key for HMAC-SHA224
* @key: (output) the key structure to initialize
* @raw_key: the raw HMAC-SHA224 key
@@ -415,6 +434,15 @@ struct hmac_sha256_key {
};
/**
+ * hmac_sha256_zeroize_key() - Zeroize an hmac_sha256_key structure
+ * @key: The hmac_sha256_key to zeroize
+ */
+static inline void hmac_sha256_zeroize_key(struct hmac_sha256_key *key)
+{
+ memzero_explicit(key, sizeof(*key));
+}
+
+/**
* struct hmac_sha256_ctx - Context for computing HMAC-SHA256 of a message
* @ctx: private
*/
@@ -423,6 +451,15 @@ struct hmac_sha256_ctx {
};
/**
+ * hmac_sha256_zeroize_ctx() - Zeroize an hmac_sha256_ctx structure
+ * @ctx: The hmac_sha256_ctx context to zeroize
+ */
+static inline void hmac_sha256_zeroize_ctx(struct hmac_sha256_ctx *ctx)
+{
+ memzero_explicit(ctx, sizeof(*ctx));
+}
+
+/**
* hmac_sha256_preparekey() - Prepare a key for HMAC-SHA256
* @key: (output) the key structure to initialize
* @raw_key: the raw HMAC-SHA256 key
@@ -624,6 +661,15 @@ struct hmac_sha384_key {
};
/**
+ * hmac_sha384_zeroize_key() - Zeroize an hmac_sha384_key structure
+ * @key: The hmac_sha384_key to zeroize
+ */
+static inline void hmac_sha384_zeroize_key(struct hmac_sha384_key *key)
+{
+ memzero_explicit(key, sizeof(*key));
+}
+
+/**
* struct hmac_sha384_ctx - Context for computing HMAC-SHA384 of a message
* @ctx: private
*/
@@ -632,6 +678,15 @@ struct hmac_sha384_ctx {
};
/**
+ * hmac_sha384_zeroize_ctx() - Zeroize an hmac_sha384_ctx structure
+ * @ctx: The hmac_sha384_ctx context to zeroize
+ */
+static inline void hmac_sha384_zeroize_ctx(struct hmac_sha384_ctx *ctx)
+{
+ memzero_explicit(ctx, sizeof(*ctx));
+}
+
+/**
* hmac_sha384_preparekey() - Prepare a key for HMAC-SHA384
* @key: (output) the key structure to initialize
* @raw_key: the raw HMAC-SHA384 key
@@ -799,6 +854,15 @@ struct hmac_sha512_key {
};
/**
+ * hmac_sha512_zeroize_key() - Zeroize an hmac_sha512_key structure
+ * @key: The hmac_sha512_key to zeroize
+ */
+static inline void hmac_sha512_zeroize_key(struct hmac_sha512_key *key)
+{
+ memzero_explicit(key, sizeof(*key));
+}
+
+/**
* struct hmac_sha512_ctx - Context for computing HMAC-SHA512 of a message
* @ctx: private
*/
@@ -807,6 +871,15 @@ struct hmac_sha512_ctx {
};
/**
+ * hmac_sha512_zeroize_ctx() - Zeroize an hmac_sha512_ctx structure
+ * @ctx: The hmac_sha512_ctx context to zeroize
+ */
+static inline void hmac_sha512_zeroize_ctx(struct hmac_sha512_ctx *ctx)
+{
+ memzero_explicit(ctx, sizeof(*ctx));
+}
+
+/**
* hmac_sha512_preparekey() - Prepare a key for HMAC-SHA512
* @key: (output) the key structure to initialize
* @raw_key: the raw HMAC-SHA512 key
diff --git a/include/crypto/sm3.h b/include/crypto/sm3.h
index 371e8a661705..d044ca80213b 100644
--- a/include/crypto/sm3.h
+++ b/include/crypto/sm3.h
@@ -11,6 +11,7 @@
#define _CRYPTO_SM3_H
#include <linux/types.h>
+#include <linux/string.h>
#define SM3_DIGEST_SIZE 32
#define SM3_BLOCK_SIZE 64
@@ -42,6 +43,15 @@ struct sm3_ctx {
};
/**
+ * sm3_zeroize_ctx() - Zeroize an sm3_ctx structure
+ * @ctx: The sm3_ctx to zeroize
+ */
+static inline void sm3_zeroize_ctx(struct sm3_ctx *ctx)
+{
+ memzero_explicit(ctx, sizeof(*ctx));
+}
+
+/**
* sm3_init() - Initialize an SM3 context for a new message
* @ctx: the context to initialize
*
diff --git a/include/cxl/event.h b/include/cxl/event.h
index b5673384d930..a9f5c2381cc9 100644
--- a/include/cxl/event.h
+++ b/include/cxl/event.h
@@ -312,13 +312,13 @@ static inline int cxl_cper_prot_err_kfifo_get(struct cxl_cper_prot_err_work_data
#endif
#ifdef CONFIG_ACPI_APEI_PCIEAER
-int cxl_cper_sec_prot_err_valid(struct cxl_cper_sec_prot_err *prot_err);
+int cxl_cper_sec_prot_err_valid(struct cxl_cper_sec_prot_err *prot_err, u32 len);
int cxl_cper_setup_prot_err_work_data(struct cxl_cper_prot_err_work_data *wd,
struct cxl_cper_sec_prot_err *prot_err,
int severity);
#else
static inline int
-cxl_cper_sec_prot_err_valid(struct cxl_cper_sec_prot_err *prot_err)
+cxl_cper_sec_prot_err_valid(struct cxl_cper_sec_prot_err *prot_err, u32 len)
{
return -EOPNOTSUPP;
}
@@ -331,6 +331,4 @@ cxl_cper_setup_prot_err_work_data(struct cxl_cper_prot_err_work_data *wd,
}
#endif
-void cxl_cper_handle_prot_err(struct cxl_cper_prot_err_work_data *wd);
-
#endif /* _LINUX_CXL_EVENT_H */
diff --git a/include/drm/bridge/analogix_dp.h b/include/drm/bridge/analogix_dp.h
index 0e0b87abee59..6033137b651e 100644
--- a/include/drm/bridge/analogix_dp.h
+++ b/include/drm/bridge/analogix_dp.h
@@ -35,7 +35,6 @@ static inline bool analogix_dp_is_rockchip(enum analogix_dp_devtype type)
struct analogix_dp_plat_data {
enum analogix_dp_devtype dev_type;
- struct drm_panel *panel;
struct drm_bridge *next_bridge;
struct drm_encoder *encoder;
struct drm_connector *connector;
diff --git a/include/drm/bridge/dw_hdmi_qp.h b/include/drm/bridge/dw_hdmi_qp.h
index 6ea9c561cfef..ad33f9cafdeb 100644
--- a/include/drm/bridge/dw_hdmi_qp.h
+++ b/include/drm/bridge/dw_hdmi_qp.h
@@ -16,7 +16,8 @@ struct dw_hdmi_qp_phy_ops {
int (*init)(struct dw_hdmi_qp *hdmi, void *data);
void (*disable)(struct dw_hdmi_qp *hdmi, void *data);
enum drm_connector_status (*read_hpd)(struct dw_hdmi_qp *hdmi, void *data);
- void (*setup_hpd)(struct dw_hdmi_qp *hdmi, void *data);
+ void (*enable_hpd)(struct dw_hdmi_qp *hdmi, void *data);
+ void (*disable_hpd)(struct dw_hdmi_qp *hdmi, void *data);
};
struct dw_hdmi_qp_plat_data {
@@ -34,6 +35,7 @@ struct dw_hdmi_qp_plat_data {
struct dw_hdmi_qp *dw_hdmi_qp_bind(struct platform_device *pdev,
struct drm_encoder *encoder,
const struct dw_hdmi_qp_plat_data *plat_data);
+void dw_hdmi_qp_hpd_notify(struct dw_hdmi_qp *hdmi);
void dw_hdmi_qp_suspend(struct device *dev, struct dw_hdmi_qp *hdmi);
void dw_hdmi_qp_resume(struct device *dev, struct dw_hdmi_qp *hdmi);
#endif /* __DW_HDMI_QP__ */
diff --git a/include/drm/drm_fb_helper.h b/include/drm/clients/drm_fbdev_helper.h
index 0c5e5ed7b5e7..7575aaf34c62 100644
--- a/include/drm/drm_fb_helper.h
+++ b/include/drm/clients/drm_fbdev_helper.h
@@ -27,8 +27,8 @@
* Dave Airlie <airlied@linux.ie>
* Jesse Barnes <jesse.barnes@intel.com>
*/
-#ifndef DRM_FB_HELPER_H
-#define DRM_FB_HELPER_H
+#ifndef DRM_FBDEV_HELPER_H
+#define DRM_FBDEV_HELPER_H
struct drm_clip_rect;
struct drm_fb_helper;
diff --git a/include/drm/display/drm_dp.h b/include/drm/display/drm_dp.h
index 8b0ca36083dd..e63c7f075f54 100644
--- a/include/drm/display/drm_dp.h
+++ b/include/drm/display/drm_dp.h
@@ -1035,6 +1035,7 @@
# define DP_EDP_14a 0x04 /* eDP 1.4a */
# define DP_EDP_14b 0x05 /* eDP 1.4b */
# define DP_EDP_15 0x06 /* eDP 1.5 */
+# define DP_EDP_20 0x07 /* eDP 2.0 */
#define DP_EDP_GENERAL_CAP_1 0x701
# define DP_EDP_TCON_BACKLIGHT_ADJUSTMENT_CAP (1 << 0)
diff --git a/include/drm/display/drm_dp_helper.h b/include/drm/display/drm_dp_helper.h
index ab16c1be3900..5b05a7fbe174 100644
--- a/include/drm/display/drm_dp_helper.h
+++ b/include/drm/display/drm_dp_helper.h
@@ -139,6 +139,12 @@ bool drm_dp_as_sdp_supported(struct drm_dp_aux *aux, const u8 dpcd[DP_RECEIVER_C
int drm_dp_psr_setup_time(const u8 psr_cap[EDP_PSR_RECEIVER_CAP_SIZE]);
+static inline bool
+drm_dp_lane_count_is_valid(int lane_count)
+{
+ return lane_count == 1 || lane_count == 2 || lane_count == 4;
+}
+
static inline int
drm_dp_max_link_rate(const u8 dpcd[DP_RECEIVER_CAP_SIZE])
{
diff --git a/include/drm/display/drm_hdmi_helper.h b/include/drm/display/drm_hdmi_helper.h
index 9c31ed90516b..2cdd6e3bc090 100644
--- a/include/drm/display/drm_hdmi_helper.h
+++ b/include/drm/display/drm_hdmi_helper.h
@@ -8,6 +8,7 @@
struct drm_connector;
struct drm_connector_state;
struct drm_display_mode;
+struct drm_modeset_acquire_ctx;
enum drm_output_color_format;
void
@@ -35,4 +36,18 @@ drm_hdmi_acr_get_n_cts(unsigned long long tmds_char_rate,
unsigned int *out_n,
unsigned int *out_cts);
+bool
+drm_hdmi_mode_needs_scrambling(const struct drm_display_mode *mode,
+ unsigned int bpc, enum drm_output_color_format fmt);
+
+int
+drm_connector_hdmi_enable_scrambling(struct drm_connector *connector,
+ const struct drm_connector_state *conn_state);
+int
+drm_connector_hdmi_disable_scrambling(struct drm_connector *connector);
+
+int
+drm_connector_hdmi_sync_scdc(struct drm_connector *connector, bool plugged,
+ struct drm_modeset_acquire_ctx *ctx);
+
#endif
diff --git a/include/drm/display/drm_hdmi_state_helper.h b/include/drm/display/drm_hdmi_state_helper.h
index 13375bd0f4ae..965342f6bbc9 100644
--- a/include/drm/display/drm_hdmi_state_helper.h
+++ b/include/drm/display/drm_hdmi_state_helper.h
@@ -3,10 +3,12 @@
#ifndef DRM_HDMI_STATE_HELPER_H_
#define DRM_HDMI_STATE_HELPER_H_
+struct dentry;
struct drm_atomic_commit;
struct drm_connector;
struct drm_connector_state;
struct drm_display_mode;
+struct drm_modeset_acquire_ctx;
struct hdmi_audio_infoframe;
enum drm_connector_status;
@@ -22,12 +24,17 @@ int drm_atomic_helper_connector_hdmi_update_audio_infoframe(struct drm_connector
int drm_atomic_helper_connector_hdmi_clear_audio_infoframe(struct drm_connector *connector);
int drm_atomic_helper_connector_hdmi_update_infoframes(struct drm_connector *connector,
struct drm_atomic_commit *state);
-void drm_atomic_helper_connector_hdmi_hotplug(struct drm_connector *connector,
- enum drm_connector_status status);
+int drm_atomic_helper_connector_hdmi_hotplug(struct drm_connector *connector,
+ struct drm_modeset_acquire_ctx *ctx,
+ enum drm_connector_status status);
void drm_atomic_helper_connector_hdmi_force(struct drm_connector *connector);
+int drm_atomic_helper_connector_hdmi_force_ctx(struct drm_connector *connector,
+ struct drm_modeset_acquire_ctx *ctx);
enum drm_mode_status
drm_hdmi_connector_mode_valid(struct drm_connector *connector,
const struct drm_display_mode *mode);
+void drm_hdmi_connector_debugfs_init(struct drm_connector *connector,
+ struct dentry *root);
#endif // DRM_HDMI_STATE_HELPER_H_
diff --git a/include/drm/display/drm_scdc.h b/include/drm/display/drm_scdc.h
index 3d58f37e8ed8..7f0b05b2f280 100644
--- a/include/drm/display/drm_scdc.h
+++ b/include/drm/display/drm_scdc.h
@@ -29,6 +29,8 @@
#define SCDC_SOURCE_VERSION 0x02
#define SCDC_UPDATE_0 0x10
+#define SCDC_RSED_UPDATE (1 << 6)
+#define SCDC_FLT_UPDATE (1 << 5)
#define SCDC_READ_REQUEST_TEST (1 << 2)
#define SCDC_CED_UPDATE (1 << 1)
#define SCDC_STATUS_UPDATE (1 << 0)
@@ -46,14 +48,25 @@
#define SCDC_CONFIG_0 0x30
#define SCDC_READ_REQUEST_ENABLE (1 << 0)
+#define SCDC_CONFIG_1 0x31
+#define SCDC_FRL_RATE 0x0f
+#define SCDC_FFE_LEVELS 0xf0
+
#define SCDC_STATUS_FLAGS_0 0x40
+#define SCDC_DSC_FAIL (1 << 7)
+#define SCDC_FLT_READY (1 << 6)
+#define SCDC_LN3_LOCK (1 << 4)
#define SCDC_CH2_LOCK (1 << 3)
#define SCDC_CH1_LOCK (1 << 2)
#define SCDC_CH0_LOCK (1 << 1)
-#define SCDC_CH_LOCK_MASK (SCDC_CH2_LOCK | SCDC_CH1_LOCK | SCDC_CH0_LOCK)
+#define SCDC_CH_LOCK_MASK (SCDC_LN3_LOCK | SCDC_CH2_LOCK | SCDC_CH1_LOCK | \
+ SCDC_CH0_LOCK)
#define SCDC_CLOCK_DETECT (1 << 0)
#define SCDC_STATUS_FLAGS_1 0x41
+#define SCDC_LN_EVEN_TRAIN_PTRN 0x0f
+#define SCDC_LN_ODD_TRAIN_PTRN 0xf0
+#define SCDC_STATUS_FLAGS_2 0x42
#define SCDC_ERR_DET_0_L 0x50
#define SCDC_ERR_DET_0_H 0x51
@@ -65,6 +78,12 @@
#define SCDC_ERR_DET_CHECKSUM 0x56
+#define SCDC_ERR_DET_3_L 0x57
+#define SCDC_ERR_DET_3_H 0x58
+
+#define SCDC_ERR_DET_RS_L 0x59
+#define SCDC_ERR_DET_RS_H 0x5a
+
#define SCDC_TEST_CONFIG_0 0xc0
#define SCDC_TEST_READ_REQUEST (1 << 7)
#define SCDC_TEST_READ_REQUEST_DELAY(x) ((x) & 0x7f)
diff --git a/include/drm/display/drm_scdc_helper.h b/include/drm/display/drm_scdc_helper.h
index 34600476a1b9..6a8be1f16ce0 100644
--- a/include/drm/display/drm_scdc_helper.h
+++ b/include/drm/display/drm_scdc_helper.h
@@ -24,17 +24,108 @@
#ifndef DRM_SCDC_HELPER_H
#define DRM_SCDC_HELPER_H
+#include <linux/errno.h>
#include <linux/types.h>
#include <drm/display/drm_scdc.h>
struct drm_connector;
struct i2c_adapter;
+struct dentry;
-ssize_t drm_scdc_read(struct i2c_adapter *adapter, u8 offset, void *buffer,
- size_t size);
-ssize_t drm_scdc_write(struct i2c_adapter *adapter, u8 offset,
- const void *buffer, size_t size);
+struct drm_scdc_status_flags {
+ /* Status Register 0 */
+ bool clock_detected;
+ bool ch0_locked;
+ bool ch1_locked;
+ bool ch2_locked;
+ bool ln3_locked;
+ bool flt_ready;
+ bool dsc_fail;
+
+ /* Status Register 1 */
+ u8 ln0_training_pattern : 4;
+ u8 ln1_training_pattern : 4;
+
+ /* Status Register 2 */
+ u8 ln2_training_pattern : 4;
+ u8 ln3_training_pattern : 4;
+};
+
+enum drm_scdc_frl_rate {
+ SCDC_FRL_RATE_OFF = 0,
+ SCDC_FRL_RATE_3X3 = 1,
+ SCDC_FRL_RATE_6X3 = 2,
+ SCDC_FRL_RATE_6X4 = 3,
+ SCDC_FRL_RATE_8X4 = 4,
+ SCDC_FRL_RATE_10X4 = 5,
+ SCDC_FRL_RATE_12X4 = 6,
+ SCDC_FRL_RATE_RESV_7 = 7,
+ SCDC_FRL_RATE_RESV_8 = 8,
+ SCDC_FRL_RATE_RESV_9 = 9,
+ SCDC_FRL_RATE_RESV_10 = 10,
+ SCDC_FRL_RATE_RESV_11 = 11,
+ SCDC_FRL_RATE_RESV_12 = 12,
+ SCDC_FRL_RATE_RESV_13 = 13,
+ SCDC_FRL_RATE_RESV_14 = 14,
+ SCDC_FRL_RATE_RESV_15 = 15
+};
+
+/**
+ * drm_scdc_num_frl_lanes - get number of lanes for a given FRL rate
+ * @rate: one of &enum drm_scdc_frl_rate
+ *
+ * For a given @rate, return the number of lanes it uses.
+ *
+ * Returns: %-EINVAL if @rate is not a valid FRL rate, or the number of lanes
+ * for a given &enum drm_scdc_frl_rate on success (including %0 for "off")
+ */
+static inline __pure int drm_scdc_num_frl_lanes(enum drm_scdc_frl_rate rate)
+{
+ switch (rate) {
+ case SCDC_FRL_RATE_OFF:
+ return 0;
+ case SCDC_FRL_RATE_3X3:
+ case SCDC_FRL_RATE_6X3:
+ return 3;
+ case SCDC_FRL_RATE_6X4:
+ case SCDC_FRL_RATE_8X4:
+ case SCDC_FRL_RATE_10X4:
+ case SCDC_FRL_RATE_12X4:
+ return 4;
+ default:
+ return -EINVAL;
+ }
+}
+
+struct drm_scdc_state {
+ /** @stf: contents of the status flag registers */
+ struct drm_scdc_status_flags stf;
+ /** @scramling_enabled: true if TMDS scrambling is on */
+ bool scrambling_enabled;
+ /** @scrambling_detected: true if the sink actually detected scrambling */
+ bool scrambling_detected;
+ /**
+ * @tmds_bclk_x40: true if TMDS bit period is 1/40th of the TMDS
+ * clock period, false if it's 1/10th of the clock period.
+ */
+ bool tmds_bclk_x40;
+ /** @rate: FRL rate set by the source */
+ enum drm_scdc_frl_rate rate : 4;
+ /** @ffe_levels: The FFE levels for @rate set by the source */
+ u8 ffe_levels : 4;
+ /** @error_count: character error counts for each channel/link */
+ u16 error_count[4];
+ /** @rs_corrections: number of Reed-Solomon Corrections */
+ u16 rs_corrections;
+ /** @scdc: raw SCDC data buffer */
+ u8 scdc[256];
+};
+
+int drm_scdc_read(struct i2c_adapter *adapter, u8 offset, void *buffer,
+ size_t size);
+int drm_scdc_write(struct i2c_adapter *adapter, u8 offset, const void *buffer,
+ size_t size);
/**
* drm_scdc_readb - read a single byte from SCDC
@@ -77,4 +168,10 @@ bool drm_scdc_get_scrambling_status(struct drm_connector *connector);
bool drm_scdc_set_scrambling(struct drm_connector *connector, bool enable);
bool drm_scdc_set_high_tmds_clock_ratio(struct drm_connector *connector, bool set);
+int drm_scdc_set_source_version(struct drm_connector *connector, u8 ver);
+
+int drm_scdc_read_state(struct drm_connector *connector,
+ struct drm_scdc_state *state);
+void drm_scdc_debugfs_init(struct drm_connector *connector, struct dentry *root);
+
#endif
diff --git a/include/drm/drm_atomic.h b/include/drm/drm_atomic.h
index 88087910ab1a..3ae35b09c0cf 100644
--- a/include/drm/drm_atomic.h
+++ b/include/drm/drm_atomic.h
@@ -159,7 +159,23 @@ struct drm_crtc_commit {
struct __drm_colorops_state {
struct drm_colorop *ptr;
- struct drm_colorop_state *state, *old_state, *new_state;
+
+ /**
+ * @state_to_destroy:
+ *
+ * Used to track the @drm_colorop_state we will need to free
+ * when tearing down the associated &drm_atomic_commit in
+ * $drm_mode_config_funcs.atomic_state_clear or
+ * drm_atomic_commit_default_clear().
+ *
+ * Before a commit, and the call to
+ * drm_atomic_helper_swap_state() in particular, it points to
+ * the same state than @new_state. After a commit, it points to
+ * the same state than @old_state.
+ */
+ struct drm_colorop_state *state_to_destroy;
+
+ struct drm_colorop_state *old_state, *new_state;
};
struct __drm_planes_state {
@@ -951,9 +967,11 @@ void drm_state_dump(struct drm_device *dev, struct drm_printer *p);
(__i)++) \
for_each_if ((__state)->connectors[__i].ptr && \
((connector) = (__state)->connectors[__i].ptr, \
- (void)(connector) /* Only to avoid unused-but-set-variable warning */, \
- (old_connector_state) = (__state)->connectors[__i].old_state, \
- (new_connector_state) = (__state)->connectors[__i].new_state, 1))
+ (void)(connector) /* Only to avoid unused-but-set-variable warning */, \
+ (old_connector_state) = (__state)->connectors[__i].old_state, \
+ (void)(old_connector_state) /* Only to avoid unused-but-set-variable warning */, \
+ (new_connector_state) = (__state)->connectors[__i].new_state, \
+ (void)(new_connector_state) /* Only to avoid unused-but-set-variable warning */, 1))
/**
* for_each_old_connector_in_state - iterate over all connectors in an atomic update
@@ -973,8 +991,9 @@ void drm_state_dump(struct drm_device *dev, struct drm_printer *p);
(__i)++) \
for_each_if ((__state)->connectors[__i].ptr && \
((connector) = (__state)->connectors[__i].ptr, \
- (void)(connector) /* Only to avoid unused-but-set-variable warning */, \
- (old_connector_state) = (__state)->connectors[__i].old_state, 1))
+ (void)(connector) /* Only to avoid unused-but-set-variable warning */, \
+ (old_connector_state) = (__state)->connectors[__i].old_state, \
+ (void)(old_connector_state) /* Only to avoid unused-but-set-variable warning */, 1))
/**
* for_each_new_connector_in_state - iterate over all connectors in an atomic update
@@ -994,9 +1013,9 @@ void drm_state_dump(struct drm_device *dev, struct drm_printer *p);
(__i)++) \
for_each_if ((__state)->connectors[__i].ptr && \
((connector) = (__state)->connectors[__i].ptr, \
- (void)(connector) /* Only to avoid unused-but-set-variable warning */, \
- (new_connector_state) = (__state)->connectors[__i].new_state, \
- (void)(new_connector_state) /* Only to avoid unused-but-set-variable warning */, 1))
+ (void)(connector) /* Only to avoid unused-but-set-variable warning */, \
+ (new_connector_state) = (__state)->connectors[__i].new_state, \
+ (void)(new_connector_state) /* Only to avoid unused-but-set-variable warning */, 1))
/**
* for_each_oldnew_crtc_in_state - iterate over all CRTCs in an atomic update
@@ -1017,10 +1036,10 @@ void drm_state_dump(struct drm_device *dev, struct drm_printer *p);
for_each_if ((__state)->crtcs[__i].ptr && \
((crtc) = (__state)->crtcs[__i].ptr, \
(void)(crtc) /* Only to avoid unused-but-set-variable warning */, \
- (old_crtc_state) = (__state)->crtcs[__i].old_state, \
- (void)(old_crtc_state) /* Only to avoid unused-but-set-variable warning */, \
- (new_crtc_state) = (__state)->crtcs[__i].new_state, \
- (void)(new_crtc_state) /* Only to avoid unused-but-set-variable warning */, 1))
+ (old_crtc_state) = (__state)->crtcs[__i].old_state, \
+ (void)(old_crtc_state) /* Only to avoid unused-but-set-variable warning */, \
+ (new_crtc_state) = (__state)->crtcs[__i].new_state, \
+ (void)(new_crtc_state) /* Only to avoid unused-but-set-variable warning */, 1))
/**
* for_each_old_crtc_in_state - iterate over all CRTCs in an atomic update
@@ -1040,7 +1059,8 @@ void drm_state_dump(struct drm_device *dev, struct drm_printer *p);
for_each_if ((__state)->crtcs[__i].ptr && \
((crtc) = (__state)->crtcs[__i].ptr, \
(void)(crtc) /* Only to avoid unused-but-set-variable warning */, \
- (old_crtc_state) = (__state)->crtcs[__i].old_state, 1))
+ (old_crtc_state) = (__state)->crtcs[__i].old_state, \
+ (void)(old_crtc_state) /* Only to avoid unused-but-set-variable warning */, 1))
/**
* for_each_new_crtc_in_state - iterate over all CRTCs in an atomic update
@@ -1126,8 +1146,10 @@ void drm_state_dump(struct drm_device *dev, struct drm_printer *p);
for_each_if ((__state)->planes[__i].ptr && \
((plane) = (__state)->planes[__i].ptr, \
(void)(plane) /* Only to avoid unused-but-set-variable warning */, \
- (old_plane_state) = (__state)->planes[__i].old_state,\
- (new_plane_state) = (__state)->planes[__i].new_state, 1))
+ (old_plane_state) = (__state)->planes[__i].old_state, \
+ (void)(old_plane_state) /* Only to avoid unused-but-set-variable warning */, \
+ (new_plane_state) = (__state)->planes[__i].new_state, \
+ (void)(new_plane_state) /* Only to avoid unused-but-set-variable warning */, 1))
/**
* for_each_oldnew_plane_in_state_reverse - iterate over all planes in an atomic
@@ -1148,8 +1170,11 @@ void drm_state_dump(struct drm_device *dev, struct drm_printer *p);
(__i)--) \
for_each_if ((__state)->planes[__i].ptr && \
((plane) = (__state)->planes[__i].ptr, \
- (old_plane_state) = (__state)->planes[__i].old_state,\
- (new_plane_state) = (__state)->planes[__i].new_state, 1))
+ (void)(plane) /* Only to avoid unused-but-set-variable warning */, \
+ (old_plane_state) = (__state)->planes[__i].old_state, \
+ (void)(old_plane_state) /* Only to avoid unused-but-set-variable warning */, \
+ (new_plane_state) = (__state)->planes[__i].new_state, \
+ (void)(new_plane_state) /* Only to avoid unused-but-set-variable warning */, 1))
/**
* for_each_new_plane_in_state_reverse - other than only tracking new state,
@@ -1165,7 +1190,9 @@ void drm_state_dump(struct drm_device *dev, struct drm_printer *p);
(__i)--) \
for_each_if ((__state)->planes[__i].ptr && \
((plane) = (__state)->planes[__i].ptr, \
- (new_plane_state) = (__state)->planes[__i].new_state, 1))
+ (void)(plane) /* Only to avoid unused-but-set-variable warning */, \
+ (new_plane_state) = (__state)->planes[__i].new_state, \
+ (void)(new_plane_state) /* Only to avoid unused-but-set-variable warning */, 1))
/**
* for_each_old_plane_in_state - iterate over all planes in an atomic update
@@ -1184,7 +1211,10 @@ void drm_state_dump(struct drm_device *dev, struct drm_printer *p);
(__i)++) \
for_each_if ((__state)->planes[__i].ptr && \
((plane) = (__state)->planes[__i].ptr, \
- (old_plane_state) = (__state)->planes[__i].old_state, 1))
+ (void)(plane) /* Only to avoid unused-but-set-variable warning */, \
+ (old_plane_state) = (__state)->planes[__i].old_state, \
+ (void)(old_plane_state) /* Only to avoid unused-but-set-variable warning */, 1))
+
/**
* for_each_new_plane_in_state - iterate over all planes in an atomic update
* @__state: &struct drm_atomic_commit pointer
@@ -1222,8 +1252,11 @@ void drm_state_dump(struct drm_device *dev, struct drm_printer *p);
for ((__i) = 0; \
(__i) < (__state)->num_private_objs && \
((obj) = (__state)->private_objs[__i].ptr, \
+ (void)(obj) /* Only to avoid unused-but-set-variable warning */, \
(old_obj_state) = (__state)->private_objs[__i].old_state, \
- (new_obj_state) = (__state)->private_objs[__i].new_state, 1); \
+ (void)(old_obj_state) /* Only to avoid unused-but-set-variable warning */, \
+ (new_obj_state) = (__state)->private_objs[__i].new_state, \
+ (void)(new_obj_state) /* Only to avoid unused-but-set-variable warning */, 1); \
(__i)++)
/**
@@ -1241,7 +1274,9 @@ void drm_state_dump(struct drm_device *dev, struct drm_printer *p);
for ((__i) = 0; \
(__i) < (__state)->num_private_objs && \
((obj) = (__state)->private_objs[__i].ptr, \
- (old_obj_state) = (__state)->private_objs[__i].old_state, 1); \
+ (void)(obj) /* Only to avoid unused-but-set-variable warning */, \
+ (old_obj_state) = (__state)->private_objs[__i].old_state, \
+ (void)(old_obj_state) /* Only to avoid unused-but-set-variable warning */, 1); \
(__i)++)
/**
@@ -1260,7 +1295,8 @@ void drm_state_dump(struct drm_device *dev, struct drm_printer *p);
(__i) < (__state)->num_private_objs && \
((obj) = (__state)->private_objs[__i].ptr, \
(void)(obj) /* Only to avoid unused-but-set-variable warning */, \
- (new_obj_state) = (__state)->private_objs[__i].new_state, 1); \
+ (new_obj_state) = (__state)->private_objs[__i].new_state, \
+ (void)(new_obj_state) /* Only to avoid unused-but-set-variable warning */, 1); \
(__i)++)
/**
@@ -1361,11 +1397,8 @@ struct drm_bridge_state {
struct drm_bus_cfg output_bus_cfg;
};
-static inline struct drm_bridge_state *
-drm_priv_to_bridge_state(struct drm_private_state *priv)
-{
- return container_of(priv, struct drm_bridge_state, base);
-}
+#define drm_priv_to_bridge_state(priv) \
+ container_of_const(priv, struct drm_bridge_state, base)
struct drm_bridge_state *
drm_atomic_get_bridge_state(struct drm_atomic_commit *state,
diff --git a/include/drm/drm_atomic_state_helper.h b/include/drm/drm_atomic_state_helper.h
index 34a599c3d86d..4706eeab52c1 100644
--- a/include/drm/drm_atomic_state_helper.h
+++ b/include/drm/drm_atomic_state_helper.h
@@ -42,9 +42,6 @@ struct drm_device;
void __drm_atomic_helper_crtc_state_init(struct drm_crtc_state *state,
struct drm_crtc *crtc);
-void __drm_atomic_helper_crtc_reset(struct drm_crtc *crtc,
- struct drm_crtc_state *state);
-void drm_atomic_helper_crtc_reset(struct drm_crtc *crtc);
struct drm_crtc_state *
drm_atomic_helper_crtc_create_state(struct drm_crtc *crtc);
void __drm_atomic_helper_crtc_duplicate_state(struct drm_crtc *crtc,
@@ -59,9 +56,6 @@ void __drm_atomic_helper_plane_state_init(struct drm_plane_state *state,
struct drm_plane *plane);
struct drm_plane_state *
drm_atomic_helper_plane_create_state(struct drm_plane *plane);
-void __drm_atomic_helper_plane_reset(struct drm_plane *plane,
- struct drm_plane_state *state);
-void drm_atomic_helper_plane_reset(struct drm_plane *plane);
void __drm_atomic_helper_plane_duplicate_state(struct drm_plane *plane,
struct drm_plane_state *state);
struct drm_plane_state *
diff --git a/include/drm/drm_bridge.h b/include/drm/drm_bridge.h
index 58fff047f43b..1981d24a700d 100644
--- a/include/drm/drm_bridge.h
+++ b/include/drm/drm_bridge.h
@@ -562,6 +562,41 @@ struct drm_bridge_funcs {
unsigned long long tmds_rate);
/**
+ * @hdmi_scrambler_enable:
+ *
+ * Enable source-side scrambling and the high TMDS clock ratio for the
+ * mode currently being applied.
+ *
+ * This only programs the source side. Sink-side SCDC configuration is
+ * handled by the HDMI connector helpers.
+ *
+ * Mandatory for bridges that set the DRM_BRIDGE_OP_HDMI flag in their
+ * &drm_bridge->ops and advertise HDMI_VERSION_2_0 or later via
+ * &drm_bridge->supported_hdmi_ver; unused otherwise.
+ *
+ * Returns:
+ * 0 on success, a negative error code otherwise.
+ */
+ int (*hdmi_scrambler_enable)(struct drm_bridge *bridge);
+
+ /**
+ * @hdmi_scrambler_disable:
+ *
+ * Disable source-side scrambling and the high TMDS clock ratio.
+ *
+ * This only programs the source side. Sink-side SCDC configuration is
+ * handled by the HDMI connector helpers.
+ *
+ * Mandatory for bridges that set the DRM_BRIDGE_OP_HDMI flag in their
+ * &drm_bridge->ops and advertise HDMI_VERSION_2_0 or later via
+ * &drm_bridge->supported_hdmi_ver; unused otherwise.
+ *
+ * Returns:
+ * 0 on success, a negative error code otherwise.
+ */
+ int (*hdmi_scrambler_disable)(struct drm_bridge *bridge);
+
+ /**
* @hdmi_clear_avi_infoframe:
*
* This callback clears the infoframes in the hardware during commit.
@@ -1082,6 +1117,12 @@ struct drm_bridge {
const char *product;
/**
+ * @supported_hdmi_ver: HDMI version the bridge is conformant with.
+ * This is only relevant if @DRM_BRIDGE_OP_HDMI is set.
+ */
+ enum hdmi_version supported_hdmi_ver;
+
+ /**
* @supported_formats: Bitmask of @drm_output_color_format listing
* supported output formats. This is only relevant if
* @DRM_BRIDGE_OP_HDMI is set.
@@ -1089,6 +1130,14 @@ struct drm_bridge {
unsigned int supported_formats;
/**
+ * @max_tmds_char_rate: Maximum TMDS character rate, in Hz, the HDMI
+ * bridge supports. A value of 0 means the core should use the default
+ * limit implied by @supported_hdmi_ver. This is only relevant if
+ * @DRM_BRIDGE_OP_HDMI is set.
+ */
+ unsigned long long max_tmds_char_rate;
+
+ /**
* @max_bpc: Maximum bits per char the HDMI bridge supports. Allowed
* values are 8, 10 and 12. This is only relevant if
* @DRM_BRIDGE_OP_HDMI is set.
@@ -1473,60 +1522,6 @@ void drm_bridge_hpd_disable(struct drm_bridge *bridge);
void drm_bridge_hpd_notify(struct drm_bridge *bridge,
enum drm_connector_status status);
-#ifdef CONFIG_DRM_PANEL_BRIDGE
-bool drm_bridge_is_panel(const struct drm_bridge *bridge);
-struct drm_bridge *drm_panel_bridge_add(struct drm_panel *panel);
-struct drm_bridge *drm_panel_bridge_add_typed(struct drm_panel *panel,
- u32 connector_type);
-void drm_panel_bridge_remove(struct drm_bridge *bridge);
-int drm_panel_bridge_set_orientation(struct drm_connector *connector,
- struct drm_bridge *bridge);
-struct drm_bridge *devm_drm_panel_bridge_add(struct device *dev,
- struct drm_panel *panel);
-struct drm_bridge *devm_drm_panel_bridge_add_typed(struct device *dev,
- struct drm_panel *panel,
- u32 connector_type);
-struct drm_bridge *drmm_panel_bridge_add(struct drm_device *drm,
- struct drm_panel *panel);
-struct drm_connector *drm_panel_bridge_connector(struct drm_bridge *bridge);
-#else
-static inline bool drm_bridge_is_panel(const struct drm_bridge *bridge)
-{
- return false;
-}
-
-static inline int drm_panel_bridge_set_orientation(struct drm_connector *connector,
- struct drm_bridge *bridge)
-{
- return -EINVAL;
-}
-#endif
-
-#if defined(CONFIG_OF) && defined(CONFIG_DRM_PANEL_BRIDGE)
-struct drm_bridge *devm_drm_of_get_bridge(struct device *dev, struct device_node *node,
- u32 port, u32 endpoint);
-struct drm_bridge *drmm_of_get_bridge(struct drm_device *drm, struct device_node *node,
- u32 port, u32 endpoint);
-#else
-static inline struct drm_bridge *devm_drm_of_get_bridge(struct device *dev,
- struct device_node *node,
- u32 port,
- u32 endpoint)
-{
- return ERR_PTR(-ENODEV);
-}
-
-static inline struct drm_bridge *drmm_of_get_bridge(struct drm_device *drm,
- struct device_node *node,
- u32 port,
- u32 endpoint)
-{
- return ERR_PTR(-ENODEV);
-}
-#endif
-
-void devm_drm_put_bridge(struct device *dev, struct drm_bridge *bridge);
-
void drm_bridge_debugfs_params(struct dentry *root);
void drm_bridge_debugfs_encoder_params(struct dentry *root, struct drm_encoder *encoder);
diff --git a/include/drm/drm_client.h b/include/drm/drm_client.h
index 49a21f3dcb36..10a0cae3e48f 100644
--- a/include/drm/drm_client.h
+++ b/include/drm/drm_client.h
@@ -67,6 +67,20 @@ struct drm_client_funcs {
int (*restore)(struct drm_client_dev *client, bool force);
/**
+ * @acquire_outputs:
+ *
+ * Called by vga-switcheroo. Informs the client that the outputs will
+ * be switched to its device. When @acquire_outputs runs, the outputs
+ * have not been switched yet. The client should only prepare the software
+ * state. After the switch happened, the client might get a hotplug
+ * event to update the hardware state.
+ *
+ * This callback exists for remapping framebuffers to virtual terminals
+ * in fbcon.
+ */
+ void (*acquire_outputs)(struct drm_client_dev *client);
+
+ /**
* @hotplug:
*
* Called on drm_kms_helper_hotplug_event().
diff --git a/include/drm/drm_client_event.h b/include/drm/drm_client_event.h
index 79369c755bc9..c93f404bae1d 100644
--- a/include/drm/drm_client_event.h
+++ b/include/drm/drm_client_event.h
@@ -11,6 +11,7 @@ struct drm_device;
void drm_client_dev_unregister(struct drm_device *dev);
void drm_client_dev_hotplug(struct drm_device *dev);
void drm_client_dev_restore(struct drm_device *dev, bool force);
+void drm_client_dev_acquire_outputs(struct drm_device *dev);
void drm_client_dev_suspend(struct drm_device *dev);
void drm_client_dev_resume(struct drm_device *dev);
#else
@@ -20,6 +21,8 @@ static inline void drm_client_dev_hotplug(struct drm_device *dev)
{ }
static inline void drm_client_dev_restore(struct drm_device *dev, bool force)
{ }
+static inline void drm_client_dev_acquire_outputs(struct drm_device *dev)
+{ }
static inline void drm_client_dev_suspend(struct drm_device *dev)
{ }
static inline void drm_client_dev_resume(struct drm_device *dev)
diff --git a/include/drm/drm_colorop.h b/include/drm/drm_colorop.h
index 224fae40ed2b..26ef67c835e2 100644
--- a/include/drm/drm_colorop.h
+++ b/include/drm/drm_colorop.h
@@ -135,6 +135,114 @@ enum drm_colorop_curve_1d_type {
};
/**
+ * enum drm_colorop_fixed_matrix_type - type of Fixed Matrix
+ *
+ * Describes a Fixed Matrix operation to be applied by the DRM_COLOROP_FIXED_MATRIX
+ */
+enum drm_colorop_fixed_matrix_type {
+ /**
+ * @DRM_COLOROP_FM_YCBCR601_FULL_RGB:
+ *
+ * enum string "YCbCr 601 Full to RGB"
+ *
+ * Converts full-range YCbCr into full-range RGB using the BT.601
+ * coefficients. Y is normalized to [0, 1] and Cb, Cr are centered
+ * at 0 (the nominal 0.5 offset removed) before the matrix::
+ *
+ * | R | | 1.0 0.000000 1.402000 | | Y |
+ * | G | = | 1.0 -0.344136 -0.714136 | x | Cb |
+ * | B | | 1.0 1.772000 0.000000 | | Cr |
+ */
+ DRM_COLOROP_FM_YCBCR601_FULL_RGB,
+
+ /**
+ * @DRM_COLOROP_FM_YCBCR601_LIMITED_RGB:
+ *
+ * enum string "YCbCr 601 Limited to RGB"
+ *
+ * Converts limited- (narrow-) range YCbCr into full-range RGB using
+ * the BT.601 coefficients. Before the matrix Y is offset by 16/255
+ * and Cb, Cr are centered at 0, following the studio-range
+ * convention of ITU-R BT.601::
+ *
+ * | R | | 1.164384 0.000000 1.596027 | | Y - 16/255 |
+ * | G | = | 1.164384 -0.391762 -0.812968 | x | Cb |
+ * | B | | 1.164384 2.017232 0.000000 | | Cr |
+ */
+ DRM_COLOROP_FM_YCBCR601_LIMITED_RGB,
+
+ /**
+ * @DRM_COLOROP_FM_YCBCR709_FULL_RGB:
+ *
+ * enum string "YCbCr 709 Full to RGB"
+ *
+ * Converts full-range YCbCr into full-range RGB using the BT.709
+ * coefficients. Y is normalized to [0, 1] and Cb, Cr are centered
+ * at 0 (the nominal 0.5 offset removed) before the matrix::
+ *
+ * | R | | 1.0 0.000000 1.574800 | | Y |
+ * | G | = | 1.0 -0.187324 -0.468124 | x | Cb |
+ * | B | | 1.0 1.855600 0.000000 | | Cr |
+ */
+ DRM_COLOROP_FM_YCBCR709_FULL_RGB,
+
+ /**
+ * @DRM_COLOROP_FM_YCBCR709_LIMITED_RGB:
+ *
+ * enum string "YCbCr 709 Limited to RGB"
+ *
+ * Converts limited- (narrow-) range YCbCr into full-range RGB using
+ * the BT.709 coefficients. Before the matrix Y is offset by 16/255
+ * and Cb, Cr are centered at 0, following the studio-range
+ * convention of ITU-R BT.709::
+ *
+ * | R | | 1.164384 0.000000 1.792741 | | Y - 16/255 |
+ * | G | = | 1.164384 -0.213249 -0.532909 | x | Cb |
+ * | B | | 1.164384 2.112402 0.000000 | | Cr |
+ */
+ DRM_COLOROP_FM_YCBCR709_LIMITED_RGB,
+
+ /**
+ * @DRM_COLOROP_FM_YCBCR2020_NC_FULL_RGB:
+ *
+ * enum string "YCbCr 2020 NC Full to RGB"
+ *
+ * Converts full-range YCbCr into full-range RGB using the BT.2020
+ * non-constant luminance coefficients. Y is normalized to [0, 1]
+ * and Cb, Cr are centered at 0 (the nominal 0.5 offset removed)
+ * before the matrix::
+ *
+ * | R | | 1.0 0.000000 1.474600 | | Y |
+ * | G | = | 1.0 -0.164553 -0.571353 | x | Cb |
+ * | B | | 1.0 1.881400 0.000000 | | Cr |
+ */
+ DRM_COLOROP_FM_YCBCR2020_NC_FULL_RGB,
+
+ /**
+ * @DRM_COLOROP_FM_YCBCR2020_NC_LIMITED_RGB:
+ *
+ * enum string "YCbCr 2020 NC Limited to RGB"
+ *
+ * Converts limited- (narrow-) range YCbCr into full-range RGB using
+ * the BT.2020 non-constant luminance coefficients. Before the matrix
+ * Y is offset by 16/255 and Cb, Cr are centered at 0, following the
+ * studio-range convention of ITU-R BT.2020::
+ *
+ * | R | | 1.164384 0.000000 1.678674 | | Y - 16/255 |
+ * | G | = | 1.164384 -0.187326 -0.650424 | x | Cb |
+ * | B | | 1.164384 2.141772 0.000000 | | Cr |
+ */
+ DRM_COLOROP_FM_YCBCR2020_NC_LIMITED_RGB,
+
+ /**
+ * @DRM_COLOROP_FM_COUNT:
+ *
+ * enum value denoting the size of the enum
+ */
+ DRM_COLOROP_FM_COUNT
+};
+
+/**
* struct drm_colorop_state - mutable colorop state
*/
struct drm_colorop_state {
@@ -197,6 +305,13 @@ struct drm_colorop_state {
*/
enum drm_colorop_lut3d_interpolation_type lut3d_interpolation;
+ /**
+ * @fixed_matrix_type:
+ *
+ * Type of Fixed Matrix operation.
+ */
+ enum drm_colorop_fixed_matrix_type fixed_matrix_type;
+
/** @state: backpointer to global drm_atomic_commit */
struct drm_atomic_commit *state;
};
@@ -367,6 +482,13 @@ struct drm_colorop {
struct drm_property *data_property;
/**
+ * @fixed_matrix_type_property:
+ *
+ * Sub-type for DRM_COLOROP_FIXED_MATRIX type.
+ */
+ struct drm_property *fixed_matrix_type_property;
+
+ /**
* @next_property:
*
* Read-only property to next colorop in the pipeline
@@ -422,6 +544,10 @@ int drm_plane_colorop_3dlut_init(struct drm_device *dev, struct drm_colorop *col
uint32_t lut_size,
enum drm_colorop_lut3d_interpolation_type interpolation,
uint32_t flags);
+int drm_plane_colorop_fixed_matrix_init(struct drm_device *dev, struct drm_colorop *colorop,
+ struct drm_plane *plane,
+ const struct drm_colorop_funcs *funcs,
+ u64 supported_fm, uint32_t flags);
struct drm_colorop_state *
drm_atomic_helper_colorop_create_state(struct drm_colorop *colorop);
@@ -480,6 +606,7 @@ drm_get_colorop_lut1d_interpolation_name(enum drm_colorop_lut1d_interpolation_ty
const char *
drm_get_colorop_lut3d_interpolation_name(enum drm_colorop_lut3d_interpolation_type type);
+const char *drm_get_colorop_fixed_matrix_type_name(enum drm_colorop_fixed_matrix_type type);
void drm_colorop_set_next_property(struct drm_colorop *colorop, struct drm_colorop *next);
diff --git a/include/drm/drm_connector.h b/include/drm/drm_connector.h
index a0cf0268de48..2ee7c59329aa 100644
--- a/include/drm/drm_connector.h
+++ b/include/drm/drm_connector.h
@@ -28,6 +28,7 @@
#include <linux/ctype.h>
#include <linux/hdmi.h>
#include <linux/notifier.h>
+#include <linux/workqueue.h>
#include <drm/drm_mode_object.h>
#include <drm/drm_util.h>
#include <drm/drm_property.h>
@@ -255,6 +256,44 @@ struct drm_scdc {
};
/**
+ * struct drm_hdmi_vrr_cap - Information about VRR capabilities of a HDMI sink
+ *
+ * Describes the VRR support provided by HDMI 2.1 sink. The information is
+ * fetched fom additional HFVSDB blocks defined for HDMI 2.1.
+ */
+struct drm_hdmi_vrr_cap {
+ /** @fva: flag for Fast VActive (Quick Frame Transport) support */
+ bool fva;
+
+ /** @mcnmvrr: flag for Negative M VRR support */
+ bool cnmvrr;
+
+ /** @mcinema_vrr: flag for Cinema VRR support */
+ bool cinema_vrr;
+
+ /** @mdelta: flag for limited frame-to-frame compensation support */
+ bool mdelta;
+
+ /**
+ * @vrr_min : minimum supported variable refresh rate in Hz.
+ * Valid values only inide 1 - 48 range
+ */
+ u16 vrr_min;
+
+ /**
+ * @vrr_max : maximum supported variable refresh rate in Hz (optional).
+ * Valid values are either 0 (max based on video mode) or >= 100
+ */
+ u16 vrr_max;
+
+ /**
+ * @supported: flag for vrr support based on checking for VRRmin and
+ * VRRmax values having correct values.
+ */
+ bool supported;
+};
+
+/**
* struct drm_hdmi_dsc_cap - DSC capabilities of HDMI sink
*
* Describes the DSC support provided by HDMI 2.1 sink.
@@ -330,6 +369,15 @@ struct drm_hdmi_info {
/** @max_lanes: supported by sink */
u8 max_lanes;
+ /** @fapa_start_location: flag for the FAPA in blanking support */
+ bool fapa_start_location;
+
+ /** @allm: flag for Auto Low Latency Mode support by sink */
+ bool allm;
+
+ /** @vrr_cap: VRR capabilities of the sink */
+ struct drm_hdmi_vrr_cap vrr_cap;
+
/** @dsc_cap: DSC capabilities of the sink */
struct drm_hdmi_dsc_cap dsc_cap;
};
@@ -765,7 +813,7 @@ enum drm_bus_flags {
* struct drm_amd_vsdb_info - AMD-specific VSDB information
*
* This structure holds information parsed from the AMD Vendor-Specific Data
- * Block (VSDB) version 3.
+ * Block (VSDB) versions 1 to 3.
*/
struct drm_amd_vsdb_info {
/**
@@ -774,6 +822,26 @@ struct drm_amd_vsdb_info {
u8 version;
/**
+ * @freesync_supported: FreeSync (variable refresh rate) supported by panel
+ */
+ bool freesync_supported;
+
+ /**
+ * @min_frame_rate: FreeSync minimum refresh rate in Hz
+ */
+ u16 min_frame_rate;
+
+ /**
+ * @max_frame_rate: FreeSync maximum refresh rate in Hz
+ */
+ u16 max_frame_rate;
+
+ /**
+ * @freesync_vcp_code: MCCS VCP code for FreeSync
+ */
+ u8 freesync_vcp_code;
+
+ /**
* @replay_mode: Panel Replay supported
*/
bool replay_mode;
@@ -1131,6 +1199,17 @@ struct drm_connector_hdmi_state {
* @tmds_char_rate: TMDS Character Rate, in Hz.
*/
unsigned long long tmds_char_rate;
+
+ /**
+ * @scrambler_needed: Whether HDMI 2.0 SCDC scrambling is required
+ * for the negotiated mode/bpc/format.
+ *
+ * Computed by drm_atomic_helper_connector_hdmi_check() according to
+ * the HDMI 2.0 specification: scrambling is mandatory above a 340 MHz
+ * TMDS character rate. Optional scrambling at lower rates is
+ * deliberately not requested by the helper.
+ */
+ bool scrambler_needed;
};
/**
@@ -1403,9 +1482,51 @@ struct drm_connector_infoframe_funcs {
/**
* struct drm_connector_hdmi_funcs - drm_hdmi_connector control functions
+ * and controller capabilities
*/
struct drm_connector_hdmi_funcs {
/**
+ * @vendor: HDMI Controller Vendor name.
+ */
+ const char *vendor;
+
+ /**
+ * @product: HDMI Controller Product name
+ */
+ const char *product;
+
+ /**
+ * @supported_hdmi_ver:
+ *
+ * Maximum HDMI specification version supported by the controller side
+ * of this connector. This describes the controller capability only;
+ * the effective link capabilities may be further restricted by the
+ * sink, bridge, or mode validation.
+ */
+ enum hdmi_version supported_hdmi_ver;
+
+ /**
+ * @supported_tmds_char_rate:
+ *
+ * Maximum TMDS character rate supported by the controller, in Hz.
+ * A value of 0 means the core should use the default limit implied by
+ * @supported_hdmi_ver.
+ */
+ unsigned long long supported_tmds_char_rate;
+
+ /**
+ * @supported_formats:
+ *
+ * Bitmask of @drm_output_color_format listing supported output formats.
+ */
+ unsigned long supported_formats;
+
+ /**
+ * @max_bpc: Maximum bits per char the HDMI connector supports.
+ */
+ unsigned int max_bpc;
+
+ /**
* @tmds_char_rate_valid:
*
* This callback is invoked at atomic_check time to figure out
@@ -1440,6 +1561,36 @@ struct drm_connector_hdmi_funcs {
const struct drm_edid *(*read_edid)(struct drm_connector *connector);
/**
+ * @scrambler_enable:
+ *
+ * The callback is invoked via @drm_connector_hdmi_enable_scrambling
+ * during commit to setup SCDC scrambling and high TMDS clock ratio on
+ * the source side.
+ *
+ * The @scrambler_enable callback is mandatory if HDMI 2.0 is to be
+ * supported.
+ *
+ * Returns:
+ * 0 on success, a negative error code otherwise
+ */
+ int (*scrambler_enable)(struct drm_connector *connector);
+
+ /**
+ * @scrambler_disable:
+ *
+ * The callback is invoked via @drm_connector_hdmi_disable_scrambling
+ * during commit to tear down SCDC scrambling and high TMDS clock ratio
+ * on the source side.
+ *
+ * The @scrambler_disable callback is mandatory if HDMI 2.0 is to be
+ * supported.
+ *
+ * Returns:
+ * 0 on success, a negative error code otherwise
+ */
+ int (*scrambler_disable)(struct drm_connector *connector);
+
+ /**
* @avi:
*
* Set of callbacks for handling the AVI InfoFrame. These callbacks are
@@ -1561,6 +1712,12 @@ struct drm_connector_funcs {
* the sysfs interfaces or on the kernel cmdline. In that case the
* @detect callback isn't called.
*
+ * New drivers should implement
+ * &drm_connector_helper_funcs.force_ctx instead, which gets passed
+ * the modeset acquire context and thus allows taking additional
+ * locks. It takes precedence over this callback when both are
+ * implemented.
+ *
* FIXME:
*
* Note that this hook is only called by the probe helper. It's not in
@@ -2052,7 +2209,38 @@ struct drm_connector_hdmi {
unsigned long supported_formats;
/**
- * @funcs: HDMI connector Control Functions
+ * @max_tmds_char_rate: Maximum TMDS character rate, in Hz,
+ * supported by the controller.
+ *
+ * This is inferred from &drm_connector_hdmi_funcs.supported_hdmi_ver,
+ * by default. However, controllers may support a lower rate than that
+ * specification version would imply. If that is the case, drivers are
+ * expected to set &drm_connector_hdmi_funcs.supported_tmds_char_rate
+ * to a non-zero value indicating the actual limit.
+ */
+ unsigned long long max_tmds_char_rate;
+
+ /**
+ * @scrambler_enabled: Tracks whether HDMI 2.0 scrambler is currently enabled.
+ */
+ bool scrambler_enabled;
+
+ /**
+ * @scdc_work: Work item currently used to monitor sink-side scrambling
+ * status and retry setup if the sink resets it.
+ */
+ struct delayed_work scdc_work;
+
+ /**
+ * @scdc_work_initialized: Tracks whether @scdc_work has been set up via
+ * INIT_DELAYED_WORK(). The work item is initialized lazily on the first
+ * scrambling enable, so this guards the teardown paths against touching
+ * an uninitialized work item.
+ */
+ bool scdc_work_initialized;
+
+ /**
+ * @funcs: HDMI connector Control Functions and controller capabilities
*/
const struct drm_connector_hdmi_funcs *funcs;
@@ -2551,6 +2739,12 @@ int drmm_connector_init(struct drm_device *dev,
struct i2c_adapter *ddc);
int drmm_connector_hdmi_init(struct drm_device *dev,
struct drm_connector *connector,
+ const struct drm_connector_funcs *funcs,
+ const struct drm_connector_hdmi_funcs *hdmi_funcs,
+ int connector_type,
+ struct i2c_adapter *ddc);
+int drmm_connector_hdmi_ini2(struct drm_device *dev,
+ struct drm_connector *connector,
const char *vendor, const char *product,
const struct drm_connector_funcs *funcs,
const struct drm_connector_hdmi_funcs *hdmi_funcs,
@@ -2636,6 +2830,24 @@ drm_connector_is_unregistered(struct drm_connector *connector)
DRM_CONNECTOR_UNREGISTERED;
}
+/**
+ * drm_connector_hdmi_scrambler_supported - does connector support HDMI
+ * scrambling?
+ * @connector: DRM connector
+ *
+ * Checks whether or not @connector driver supports HDMI scrambling, based on
+ * the HDMI version advertised by the controller.
+ *
+ * Returns:
+ * True if the connector supports scrambling, false otherwise.
+ */
+static inline bool
+drm_connector_hdmi_scrambler_supported(const struct drm_connector *connector)
+{
+ return connector->hdmi.funcs &&
+ connector->hdmi.funcs->supported_hdmi_ver >= HDMI_VERSION_2_0;
+}
+
void drm_connector_oob_hotplug_event(struct fwnode_handle *connector_fwnode,
enum drm_connector_status status);
enum drm_connector_color_format
diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h
index 152349f973e3..be5dca538d87 100644
--- a/include/drm/drm_crtc.h
+++ b/include/drm/drm_crtc.h
@@ -424,18 +424,6 @@ struct drm_crtc_state {
*/
struct drm_crtc_funcs {
/**
- * @reset:
- *
- * Reset CRTC hardware and software state to off. This function isn't
- * called by the core directly, only through drm_mode_config_reset().
- * It's not a helper hook only for historical reasons.
- *
- * Atomic drivers can use drm_atomic_helper_crtc_reset() to reset
- * atomic state using this hook.
- */
- void (*reset)(struct drm_crtc *crtc);
-
- /**
* @cursor_set:
*
* Update the cursor image. The cursor position is relative to the CRTC
diff --git a/include/drm/drm_device.h b/include/drm/drm_device.h
index 768a8dae83c5..75f030d027ee 100644
--- a/include/drm/drm_device.h
+++ b/include/drm/drm_device.h
@@ -37,6 +37,7 @@ struct pci_controller;
#define DRM_WEDGE_RECOVERY_REBIND BIT(1) /* unbind + bind driver */
#define DRM_WEDGE_RECOVERY_BUS_RESET BIT(2) /* unbind + reset bus device + bind */
#define DRM_WEDGE_RECOVERY_VENDOR BIT(3) /* vendor specific recovery method */
+#define DRM_WEDGE_RECOVERY_COLD_RESET BIT(4) /* remove device + slot power cycle + rescan */
/**
* struct drm_wedge_task_info - information about the guilty task of a wedge dev
diff --git a/include/drm/drm_edid.h b/include/drm/drm_edid.h
index 04f7a7f1f108..a2617aa34edf 100644
--- a/include/drm/drm_edid.h
+++ b/include/drm/drm_edid.h
@@ -490,5 +490,7 @@ u32 drm_edid_get_panel_id(const struct drm_edid *drm_edid);
bool drm_edid_match(const struct drm_edid *drm_edid,
const struct drm_edid_ident *ident);
bool drm_edid_has_quirk(struct drm_connector *connector, enum drm_edid_quirk quirk);
+int drm_edid_detect_panel_size(const struct drm_edid *drm_edid,
+ unsigned int *width, unsigned int *height);
#endif /* __DRM_EDID_H__ */
diff --git a/include/drm/drm_exec.h b/include/drm/drm_exec.h
index cc2937185a9f..c92d69a2c793 100644
--- a/include/drm/drm_exec.h
+++ b/include/drm/drm_exec.h
@@ -73,13 +73,15 @@ drm_exec_obj(struct drm_exec *exec, unsigned long index)
/* Helper for drm_exec_for_each_locked_object(). Internal use only. */
#define __drm_exec_for_each_locked_object(exec, obj, __index) \
- for (unsigned long __index = 0; ((obj) = drm_exec_obj(exec, __index)); ++__index)
+ for (unsigned long __index = 0; ((obj) = drm_exec_obj(exec, __index)); \
+ ++__index)
/**
* drm_exec_for_each_locked_object - iterate over all the locked objects
* @exec: drm_exec object
* @obj: the current GEM object
*
- * Iterate over all the locked GEM objects inside the drm_exec object.
+ * Iterate over all the explicitly locked GEM objects inside the drm_exec
+ * container, except for the contended and implicit prelocked one.
*/
#define drm_exec_for_each_locked_object(exec, obj) \
__drm_exec_for_each_locked_object(exec, obj, __UNIQUE_ID(drm_exec))
@@ -94,12 +96,13 @@ drm_exec_obj(struct drm_exec *exec, unsigned long index)
* @exec: drm_exec object
* @obj: the current GEM object
*
- * Iterate over all the locked GEM objects inside the drm_exec object in
- * reverse locking order. Note that the internal index may wrap around,
- * but that will be caught by drm_exec_obj(), returning a NULL object.
+ * Iterate over all the explicitly locked GEM objects inside the drm_exec
+ * container in reverse locking order. Note that the internal index may wrap
+ * around, but that will be caught by drm_exec_obj(), returning a NULL object.
*/
#define drm_exec_for_each_locked_object_reverse(exec, obj) \
- __drm_exec_for_each_locked_object_reverse(exec, obj, __UNIQUE_ID(drm_exec))
+ __drm_exec_for_each_locked_object_reverse(exec, obj, \
+ __UNIQUE_ID(drm_exec))
/**
* drm_exec_until_all_locked - loop until all GEM objects are locked
diff --git a/include/drm/drm_gem.h b/include/drm/drm_gem.h
index 885244e375d3..ed329408acbe 100644
--- a/include/drm/drm_gem.h
+++ b/include/drm/drm_gem.h
@@ -228,6 +228,17 @@ struct drm_gem_object_funcs {
size_t (*rss)(struct drm_gem_object *obj);
/**
+ * @handle_free:
+ *
+ * This callback is called when the GEM handle count goes down to 0.
+ * It is currently used by AMDGPU driver to release their exported BO
+ * handles.
+ *
+ * This callback is optional.
+ */
+ void (*handle_free)(struct drm_gem_object *obj);
+
+ /**
* @vm_ops:
*
* Virtual memory operations used with mmap.
@@ -616,8 +627,7 @@ drm_gem_lru_scan(struct drm_device *dev,
struct drm_gem_lru *lru,
unsigned int nr_to_scan,
unsigned long *remaining,
- bool (*shrink)(struct drm_gem_object *obj, struct ww_acquire_ctx *ticket),
- struct ww_acquire_ctx *ticket);
+ bool (*shrink)(struct drm_gem_object *obj));
int drm_gem_evict_locked(struct drm_gem_object *obj);
diff --git a/include/drm/drm_gem_atomic_helper.h b/include/drm/drm_gem_atomic_helper.h
index 3e01c619a25e..d41877f77b77 100644
--- a/include/drm/drm_gem_atomic_helper.h
+++ b/include/drm/drm_gem_atomic_helper.h
@@ -91,10 +91,10 @@ to_drm_shadow_plane_state(struct drm_plane_state *state)
void __drm_gem_duplicate_shadow_plane_state(struct drm_plane *plane,
struct drm_shadow_plane_state *new_shadow_plane_state);
void __drm_gem_destroy_shadow_plane_state(struct drm_shadow_plane_state *shadow_plane_state);
-void __drm_gem_reset_shadow_plane(struct drm_plane *plane,
- struct drm_shadow_plane_state *shadow_plane_state);
-void drm_gem_reset_shadow_plane(struct drm_plane *plane);
+void __drm_gem_shadow_plane_state_init(struct drm_plane *plane,
+ struct drm_shadow_plane_state *shadow_plane_state);
+struct drm_plane_state *drm_gem_create_shadow_plane_state(struct drm_plane *plane);
struct drm_plane_state *drm_gem_duplicate_shadow_plane_state(struct drm_plane *plane);
void drm_gem_destroy_shadow_plane_state(struct drm_plane *plane,
struct drm_plane_state *plane_state);
@@ -107,7 +107,7 @@ void drm_gem_destroy_shadow_plane_state(struct drm_plane *plane,
* macro initializes struct drm_plane_funcs to use the rsp helper functions.
*/
#define DRM_GEM_SHADOW_PLANE_FUNCS \
- .reset = drm_gem_reset_shadow_plane, \
+ .atomic_create_state = drm_gem_create_shadow_plane_state, \
.atomic_duplicate_state = drm_gem_duplicate_shadow_plane_state, \
.atomic_destroy_state = drm_gem_destroy_shadow_plane_state
@@ -130,7 +130,8 @@ int drm_gem_simple_kms_begin_shadow_fb_access(struct drm_simple_display_pipe *pi
struct drm_plane_state *plane_state);
void drm_gem_simple_kms_end_shadow_fb_access(struct drm_simple_display_pipe *pipe,
struct drm_plane_state *plane_state);
-void drm_gem_simple_kms_reset_shadow_plane(struct drm_simple_display_pipe *pipe);
+struct drm_plane_state *
+drm_gem_simple_kms_create_shadow_plane_state(struct drm_simple_display_pipe *pipe);
struct drm_plane_state *
drm_gem_simple_kms_duplicate_shadow_plane_state(struct drm_simple_display_pipe *pipe);
void drm_gem_simple_kms_destroy_shadow_plane_state(struct drm_simple_display_pipe *pipe,
@@ -147,7 +148,7 @@ void drm_gem_simple_kms_destroy_shadow_plane_state(struct drm_simple_display_pip
#define DRM_GEM_SIMPLE_DISPLAY_PIPE_SHADOW_PLANE_FUNCS \
.begin_fb_access = drm_gem_simple_kms_begin_shadow_fb_access, \
.end_fb_access = drm_gem_simple_kms_end_shadow_fb_access, \
- .reset_plane = drm_gem_simple_kms_reset_shadow_plane, \
+ .create_plane_state = drm_gem_simple_kms_create_shadow_plane_state, \
.duplicate_plane_state = drm_gem_simple_kms_duplicate_shadow_plane_state, \
.destroy_plane_state = drm_gem_simple_kms_destroy_shadow_plane_state
diff --git a/include/drm/drm_gpusvm.h b/include/drm/drm_gpusvm.h
index b7d987bf76aa..4d31c6bba745 100644
--- a/include/drm/drm_gpusvm.h
+++ b/include/drm/drm_gpusvm.h
@@ -10,6 +10,7 @@
#include <linux/kref.h>
#include <linux/interval_tree.h>
#include <linux/mmu_notifier.h>
+#include <drm/drm_pagemap.h>
struct dev_pagemap_ops;
struct drm_device;
@@ -18,7 +19,6 @@ struct drm_gpusvm_notifier;
struct drm_gpusvm_ops;
struct drm_gpusvm_range;
struct drm_pagemap;
-struct drm_pagemap_addr;
/**
* struct drm_gpusvm_ops - Operations structure for GPU SVM
@@ -112,6 +112,7 @@ struct drm_gpusvm_notifier {
* @unmapped: Flag indicating if the pages has been unmapped
* @has_devmem_pages: Flag indicating if the pages has devmem pages
* @has_dma_mapping: Flag indicating if the pages has a DMA mapping
+ * @inline_dma_mapping: Flag indicating if the pages have an inline DMA mapping
* @__flags: Flags for pages in u16 form (used for READ_ONCE)
*/
struct drm_gpusvm_pages_flags {
@@ -121,6 +122,7 @@ struct drm_gpusvm_pages_flags {
u16 unmapped : 1;
u16 has_devmem_pages : 1;
u16 has_dma_mapping : 1;
+ u16 inline_dma_mapping : 1;
};
u16 __flags;
};
@@ -130,17 +132,27 @@ struct drm_gpusvm_pages_flags {
* struct drm_gpusvm_pages - Structure representing a GPU SVM mapped pages
*
* @drm: The DRM device that owns the dma mappings
- * @dma_addr: Device address array
+ * @dma_addr: Device address array, valid while @flags.inline_dma_mapping is
+ * not set
+ * @inline_addr: Device address inline address, valid while
+ * @flags.inline_dma_mapping is set
* @dpagemap: The struct drm_pagemap of the device pages we're dma-mapping.
* Note this is assuming only one drm_pagemap per range is allowed.
* @state: DMA IOVA state for mapping.
* @state_offset: DMA IOVA offset for mapping.
* @notifier_seq: Notifier sequence number of the range's pages
* @flags: Flags for the range; see &struct drm_gpusvm_pages_flags
+ *
+ * @dma_addr and @inline_addr share storage, discriminated by
+ * @flags.inline_dma_mapping. Driver should use drm_gpusvm_pages_first_dma()
+ * to access the correct DMA address.
*/
struct drm_gpusvm_pages {
struct drm_device *drm;
- struct drm_pagemap_addr *dma_addr;
+ union {
+ struct drm_pagemap_addr *dma_addr;
+ struct drm_pagemap_addr inline_addr;
+ };
struct drm_pagemap *dpagemap;
struct dma_iova_state state;
unsigned long state_offset;
@@ -254,6 +266,19 @@ struct drm_gpusvm {
* @allow_mixed: Allow mixed mappings in get pages. Mixing between system and
* single dpagemap is supported, mixing between multiple dpagemap
* is unsupported.
+ * @no_dma_map: Only fault the CPU pages for the range; skip the device DMA
+ * mapping step. Used by drivers that consume the faulted pages
+ * without needing a DMA mapping. In this mode @drm on the
+ * drm_gpusvm_pages is not required, no mapping state is recorded
+ * and drm_gpusvm_pages_valid() therefore never reports these
+ * pages as valid; the caller revalidates the snapshot itself, see
+ * drm_gpusvm_get_pages(). @devmem_only is rejected and no page
+ * type check is performed, so @allow_mixed has no effect.
+ * @devmem_fn: Optional callback invoked under the notifier lock, once per
+ * contiguous run of pages backed by the same &drm_pagemap_devmem.
+ * Must not sleep and must be idempotent, as a non-contiguous
+ * allocation is reported more than once. Fires even with
+ * @no_dma_map. May be NULL.
*
* Context that is DRM GPUSVM is operating in (i.e. user arguments).
*/
@@ -261,11 +286,13 @@ struct drm_gpusvm_ctx {
void *device_private_page_owner;
unsigned long check_pages_threshold;
unsigned long timeslice_ms;
+ void (*devmem_fn)(struct drm_pagemap_devmem *devmem);
unsigned int in_notifier :1;
unsigned int read_only :1;
unsigned int devmem_possible :1;
unsigned int devmem_only :1;
unsigned int allow_mixed :1;
+ unsigned int no_dma_map :1;
};
int drm_gpusvm_init(struct drm_gpusvm *gpusvm,
@@ -324,6 +351,7 @@ void drm_gpusvm_range_set_unmapped(struct drm_gpusvm_range *range,
int drm_gpusvm_get_pages(struct drm_gpusvm *gpusvm,
struct drm_gpusvm_pages *svm_pages,
+ unsigned int num_pages,
struct mm_struct *mm,
struct mmu_interval_notifier *notifier,
unsigned long pages_start, unsigned long pages_end,
@@ -356,6 +384,49 @@ static inline void drm_gpusvm_init_pages(struct drm_gpusvm_pages *svm_pages,
}
/**
+ * drm_gpusvm_pages_first_dma() - Resolve the device address array
+ * @svm_pages: Pointer to the drm_gpusvm_pages.
+ * @contiguous: Where to store whether one entry spans the whole range, or NULL
+ *
+ * drm_gpusvm_pages use unions to optimize the storage of DMA addresses,
+ * this function abstracts the access to the first device address. The driver
+ * should use this helper instead of reading dma_addr directly to prevent
+ * array out of bounds access.
+ *
+ * @contiguous comes from the same read of the flags as the array itself, so a
+ * caller cannot see the two disagree and walk past that single entry into the
+ * fields behind it. When it is set the length comes from the range rather than
+ * from the order. The order still states what one PTE may cover: the range
+ * length for a huge page, PAGE_SIZE for an IOVA mapped range of single pages.
+ *
+ * Only get_pages() and the free path switch between the two union members.
+ * Both hold the notifier lock for read, so taking that lock does not stop
+ * them; callers need the driver lock that does, which every reader of the
+ * addresses holds anyway. The notifier never touches the union, so the
+ * pointer returned here stays good and can then be used under the notifier
+ * lock.
+ *
+ * Return: Pointer to the first device address, NULL if none is populated.
+ */
+static inline const struct drm_pagemap_addr *
+drm_gpusvm_pages_first_dma(const struct drm_gpusvm_pages *svm_pages,
+ bool *contiguous)
+{
+ struct drm_gpusvm_pages_flags flags = {
+ /* READ_ONCE pairs with the WRITE_ONCE of the flag writers */
+ .__flags = READ_ONCE(svm_pages->flags.__flags),
+ };
+
+ if (contiguous)
+ *contiguous = flags.inline_dma_mapping;
+
+ if (flags.inline_dma_mapping)
+ return &svm_pages->inline_addr;
+
+ return READ_ONCE(svm_pages->dma_addr);
+}
+
+/**
* enum drm_gpusvm_scan_result - Scan result from the drm_gpusvm_scan_mm() function.
* @DRM_GPUSVM_SCAN_UNPOPULATED: At least one page was not present or inaccessible.
* @DRM_GPUSVM_SCAN_EQUAL: All pages belong to the struct dev_pagemap indicated as
diff --git a/include/drm/drm_mipi_dbi.h b/include/drm/drm_mipi_dbi.h
index 78ab23d844ce..d93e25fdc2e1 100644
--- a/include/drm/drm_mipi_dbi.h
+++ b/include/drm/drm_mipi_dbi.h
@@ -234,7 +234,7 @@ void drm_mipi_dbi_plane_helper_atomic_update(struct drm_plane *plane,
*/
#define DRM_MIPI_DBI_CRTC_FUNCS \
- .reset = drm_atomic_helper_crtc_reset, \
+ .atomic_create_state = drm_atomic_helper_crtc_create_state, \
.set_config = drm_atomic_helper_set_config, \
.page_flip = drm_atomic_helper_page_flip, \
.atomic_duplicate_state = drm_atomic_helper_crtc_duplicate_state, \
diff --git a/include/drm/drm_mode_config.h b/include/drm/drm_mode_config.h
index d8f5b7e9673e..084517beb924 100644
--- a/include/drm/drm_mode_config.h
+++ b/include/drm/drm_mode_config.h
@@ -495,8 +495,8 @@ struct drm_mode_config {
*
* Raw spinlock used to protect critical sections of code that access
* the display hardware or modeset software state, which the panic
- * printing code must be protected against. See drm_panic_trylock(),
- * drm_panic_lock() and drm_panic_unlock().
+ * printing code must be protected against. See the documentation on
+ * DRM panic handling for more information.
*/
struct raw_spinlock panic_lock;
diff --git a/include/drm/drm_modeset_helper_vtables.h b/include/drm/drm_modeset_helper_vtables.h
index ca6268945c28..60b30cc26940 100644
--- a/include/drm/drm_modeset_helper_vtables.h
+++ b/include/drm/drm_modeset_helper_vtables.h
@@ -282,6 +282,20 @@ struct drm_crtc_helper_funcs {
void (*disable)(struct drm_crtc *crtc);
/**
+ * @hw_reset:
+ *
+ * Optional hook for CRTC hardware reset.
+ *
+ * Unlike @drm_crtc_funcs.reset, which both resets hardware and
+ * creates new software state, this hook only resets the
+ * hardware to a known good state without touching the software
+ * state at all.
+ *
+ * This hook is called by drm_mode_config_reset().
+ */
+ void (*hw_reset)(struct drm_crtc *crtc);
+
+ /**
* @atomic_check:
*
* Drivers should check plane-update related CRTC constraints in this
@@ -922,6 +936,34 @@ struct drm_connector_helper_funcs {
bool force);
/**
+ * @force_ctx:
+ *
+ * This function is called to update internal encoder state when the
+ * connector is forced to a certain state by userspace, either through
+ * the sysfs interfaces or on the kernel cmdline. In that case the
+ * @detect_ctx callback isn't called.
+ *
+ * This is the atomic version of &drm_connector_funcs.force. When
+ * both are implemented, this one takes precedence and
+ * &drm_connector_funcs.force is not called.
+ *
+ * To avoid races against concurrent connector state updates, the
+ * helper libraries always call this with ctx set to a valid context,
+ * and &drm_mode_config.connection_mutex will always be locked with
+ * the ctx parameter set to this ctx. This allows taking additional
+ * locks as required.
+ *
+ * RETURNS:
+ *
+ * Zero on success, or a negative error code otherwise. This includes
+ * -EDEADLK when a lock acquisition needs to be restarted, in which
+ * case the helpers take care of backing off and calling this function
+ * again.
+ */
+ int (*force_ctx)(struct drm_connector *connector,
+ struct drm_modeset_acquire_ctx *ctx);
+
+ /**
* @mode_valid:
*
* Callback to validate a mode for a connector, irrespective of the
@@ -1442,17 +1484,20 @@ struct drm_plane_helper_funcs {
/**
* @get_scanout_buffer:
*
- * Get the current scanout buffer, to display a message with drm_panic.
+ * Get the current scanout buffer to display a message with drm_panic.
* The driver should do the minimum changes to provide a buffer,
* that can be used to display the panic screen. Currently only linear
* buffers are supported. Non-linear buffer support is on the TODO list.
* The device &dev.mode_config.panic_lock is taken before calling this
* function, so you can safely access the &plane.state
* It is called from a panic callback, and must follow its restrictions.
- * Please look the documentation at drm_panic_trylock() for an in-depth
+ * Please look the documentation on DRM panic handling for an in-depth
* discussions of what's safe and what is not allowed.
+ *
* It's a best effort mode, so it's expected that in some complex cases
- * the panic screen won't be displayed.
+ * the panic screen won't be displayed. Drivers must not make any
+ * assumptions about the actual state of the hardware.
+ *
* The returned &drm_scanout_buffer.map must be valid if no error code is
* returned.
*
@@ -1472,7 +1517,7 @@ struct drm_plane_helper_funcs {
* It is only called if get_scanout_buffer() returned successfully, and
* the &dev.mode_config.panic_lock is held during the entire sequence.
* It is called from a panic callback, and must follow its restrictions.
- * Please look the documentation at drm_panic_trylock() for an in-depth
+ * Please look the documentation on DRM panic handling for an in-depth
* discussions of what's safe and what is not allowed.
*/
void (*panic_flush)(struct drm_plane *plane);
diff --git a/include/drm/drm_of.h b/include/drm/drm_of.h
index ebebed14c611..002ba1b18eb1 100644
--- a/include/drm/drm_of.h
+++ b/include/drm/drm_of.h
@@ -7,6 +7,7 @@
#if IS_ENABLED(CONFIG_OF) && IS_ENABLED(CONFIG_DRM_PANEL_BRIDGE)
#include <linux/of.h>
#include <drm/drm_bridge.h>
+#include <drm/drm_panel.h>
#endif
struct component_master_ops;
@@ -14,8 +15,6 @@ struct component_match;
struct device;
struct drm_device;
struct drm_encoder;
-struct drm_panel;
-struct drm_bridge;
struct device_node;
struct mipi_dsi_device_info;
struct mipi_dsi_host;
@@ -51,10 +50,6 @@ int drm_of_encoder_active_endpoint(struct device_node *node,
struct of_endpoint *endpoint);
int drm_of_get_panel_orientation(const struct device_node *np,
enum drm_panel_orientation *orientation);
-int drm_of_find_panel_or_bridge(const struct device_node *np,
- int port, int endpoint,
- struct drm_panel **panel,
- struct drm_bridge **bridge);
int drm_of_lvds_get_dual_link_pixel_order(const struct device_node *port1,
const struct device_node *port2);
int drm_of_lvds_get_dual_link_pixel_order_sink(struct device_node *port1,
@@ -112,14 +107,6 @@ static inline int drm_of_get_panel_orientation(const struct device_node *np,
return -EINVAL;
}
-static inline int drm_of_find_panel_or_bridge(const struct device_node *np,
- int port, int endpoint,
- struct drm_panel **panel,
- struct drm_bridge **bridge)
-{
- return -EINVAL;
-}
-
static inline int
drm_of_lvds_get_dual_link_pixel_order(const struct device_node *port1,
const struct device_node *port2)
diff --git a/include/drm/drm_pagemap.h b/include/drm/drm_pagemap.h
index ebbd3b0ddf36..d12a509d6baf 100644
--- a/include/drm/drm_pagemap.h
+++ b/include/drm/drm_pagemap.h
@@ -258,6 +258,8 @@ struct drm_pagemap *drm_pagemap_create(struct drm_device *drm,
struct drm_pagemap *drm_pagemap_page_to_dpagemap(struct page *page);
+struct drm_pagemap_devmem *drm_pagemap_page_to_devmem(struct page *page);
+
void drm_pagemap_put(struct drm_pagemap *dpagemap);
#else
@@ -267,6 +269,11 @@ static inline struct drm_pagemap *drm_pagemap_page_to_dpagemap(struct page *page
return NULL;
}
+static inline struct drm_pagemap_devmem *drm_pagemap_page_to_devmem(struct page *page)
+{
+ return NULL;
+}
+
static inline void drm_pagemap_put(struct drm_pagemap *dpagemap)
{
}
diff --git a/include/drm/drm_panel.h b/include/drm/drm_panel.h
index b87323443f49..58113ea7d63a 100644
--- a/include/drm/drm_panel.h
+++ b/include/drm/drm_panel.h
@@ -30,10 +30,14 @@
#include <linux/mutex.h>
#include <linux/kref.h>
+#include <drm/drm_bridge.h>
+
struct backlight_device;
struct dentry;
struct device_node;
+struct drm_bridge;
struct drm_connector;
+struct drm_device;
struct drm_panel_follower;
struct drm_panel;
struct display_timing;
@@ -229,6 +233,22 @@ struct drm_panel {
const struct drm_panel_funcs *funcs;
/**
+ * @bridge:
+ *
+ * Bridge to access the panel features through the drm_bridge API.
+ */
+ struct drm_bridge bridge;
+
+ /**
+ * @connector:
+ *
+ * Connector instantiated by the bridge (only for legacy code not
+ * yet using the drm_bridge_connector and
+ * DRM_BRIDGE_ATTACH_NO_CONNECTOR).
+ */
+ struct drm_connector connector;
+
+ /**
* @connector_type:
*
* Type of the panel as a DRM_MODE_CONNECTOR_* value. This is used to
@@ -281,17 +301,6 @@ struct drm_panel {
* If true then the panel has been enabled.
*/
bool enabled;
-
- /**
- * @container: Pointer to the private driver struct embedding this
- * @struct drm_panel.
- */
- void *container;
-
- /**
- * @refcount: reference count of users referencing this panel.
- */
- struct kref refcount;
};
void *__devm_drm_panel_alloc(struct device *dev, size_t size, size_t offset,
@@ -335,16 +344,28 @@ void drm_panel_disable(struct drm_panel *panel);
int drm_panel_get_modes(struct drm_panel *panel, struct drm_connector *connector);
-#if defined(CONFIG_OF) && defined(CONFIG_DRM_PANEL)
+#if defined(CONFIG_OF) && IS_ENABLED(CONFIG_DRM_PANEL)
struct drm_panel *of_drm_find_panel(const struct device_node *np);
+int drm_of_find_panel_or_bridge(const struct device_node *np,
+ int port, int endpoint,
+ struct drm_panel **panel,
+ struct drm_bridge **bridge);
#else
static inline struct drm_panel *of_drm_find_panel(const struct device_node *np)
{
return ERR_PTR(-ENODEV);
}
+
+static inline int drm_of_find_panel_or_bridge(const struct device_node *np,
+ int port, int endpoint,
+ struct drm_panel **panel,
+ struct drm_bridge **bridge)
+{
+ return -EINVAL;
+}
#endif
-#if defined(CONFIG_DRM_PANEL)
+#if IS_ENABLED(CONFIG_DRM_PANEL)
bool drm_is_panel_follower(struct device *dev);
int drm_panel_add_follower(struct device *follower_dev,
struct drm_panel_follower *follower);
@@ -381,4 +402,56 @@ static inline int drm_panel_of_backlight(struct drm_panel *panel)
}
#endif
+#ifdef CONFIG_DRM_PANEL_BRIDGE
+bool drm_bridge_is_panel(const struct drm_bridge *bridge);
+struct drm_bridge *drm_panel_bridge_add(struct drm_panel *panel);
+struct drm_bridge *drm_panel_bridge_add_typed(struct drm_panel *panel,
+ u32 connector_type);
+void drm_panel_bridge_remove(struct drm_bridge *bridge);
+int drm_panel_bridge_set_orientation(struct drm_connector *connector,
+ struct drm_bridge *bridge);
+struct drm_bridge *devm_drm_panel_bridge_add(struct device *dev,
+ struct drm_panel *panel);
+struct drm_bridge *devm_drm_panel_bridge_add_typed(struct device *dev,
+ struct drm_panel *panel,
+ u32 connector_type);
+struct drm_bridge *drmm_panel_bridge_add(struct drm_device *drm,
+ struct drm_panel *panel);
+struct drm_connector *drm_panel_bridge_connector(struct drm_bridge *bridge);
+#else
+static inline bool drm_bridge_is_panel(const struct drm_bridge *bridge)
+{
+ return false;
+}
+
+static inline int drm_panel_bridge_set_orientation(struct drm_connector *connector,
+ struct drm_bridge *bridge)
+{
+ return -EINVAL;
+}
+#endif
+
+#if defined(CONFIG_OF) && defined(CONFIG_DRM_PANEL_BRIDGE)
+struct drm_bridge *devm_drm_of_get_bridge(struct device *dev, struct device_node *node,
+ u32 port, u32 endpoint);
+struct drm_bridge *drmm_of_get_bridge(struct drm_device *drm, struct device_node *node,
+ u32 port, u32 endpoint);
+#else
+static inline struct drm_bridge *devm_drm_of_get_bridge(struct device *dev,
+ struct device_node *node,
+ u32 port,
+ u32 endpoint)
+{
+ return ERR_PTR(-ENODEV);
+}
+
+static inline struct drm_bridge *drmm_of_get_bridge(struct drm_device *drm,
+ struct device_node *node,
+ u32 port,
+ u32 endpoint)
+{
+ return ERR_PTR(-ENODEV);
+}
+#endif
+
#endif
diff --git a/include/drm/drm_utils.h b/include/drm/drm_panel_quirks.h
index 7e077484c5bb..60711a49d403 100644
--- a/include/drm/drm_utils.h
+++ b/include/drm/drm_panel_quirks.h
@@ -1,14 +1,12 @@
/* SPDX-License-Identifier: MIT */
/*
- * Function prototypes for misc. drm utility functions.
- * Specifically this file is for function prototypes for functions which
- * may also be used outside of drm code (e.g. in fbdev drivers).
+ * Function prototypes for panel-related quirks.
*
* Copyright (C) 2017 Hans de Goede <hdegoede@redhat.com>
*/
-#ifndef __DRM_UTILS_H__
-#define __DRM_UTILS_H__
+#ifndef __DRM_PANEL_QUIRKS_H__
+#define __DRM_PANEL_QUIRKS_H__
#include <linux/types.h>
@@ -25,6 +23,4 @@ struct drm_panel_backlight_quirk {
const struct drm_panel_backlight_quirk *
drm_get_panel_backlight_quirk(const struct drm_edid *edid);
-signed long drm_timeout_abs_to_jiffies(int64_t timeout_nsec);
-
#endif
diff --git a/include/drm/drm_panic.h b/include/drm/drm_panic.h
index ac0e46b73436..3e628cbaffca 100644
--- a/include/drm/drm_panic.h
+++ b/include/drm/drm_panic.h
@@ -8,13 +8,19 @@
#ifndef __DRM_PANIC_H__
#define __DRM_PANIC_H__
-#include <linux/module.h>
#include <linux/types.h>
#include <linux/iosys-map.h>
-#include <drm/drm_device.h>
#include <drm/drm_fourcc.h>
+struct page;
+
+enum drm_panic_type {
+ DRM_PANIC_TYPE_KMSG,
+ DRM_PANIC_TYPE_USER,
+ DRM_PANIC_TYPE_QR,
+};
+
/**
* struct drm_scanout_buffer - DRM scanout buffer
*
@@ -77,113 +83,6 @@ struct drm_scanout_buffer {
* set_pixel()
*/
void *private;
-
};
-#ifdef CONFIG_DRM_PANIC
-
-/**
- * drm_panic_trylock - try to enter the panic printing critical section
- * @dev: struct drm_device
- * @flags: unsigned long irq flags you need to pass to the unlock() counterpart
- *
- * This function must be called by any panic printing code. The panic printing
- * attempt must be aborted if the trylock fails.
- *
- * Panic printing code can make the following assumptions while holding the
- * panic lock:
- *
- * - Anything protected by drm_panic_lock() and drm_panic_unlock() pairs is safe
- * to access.
- *
- * - Furthermore the panic printing code only registers in drm_dev_unregister()
- * and gets removed in drm_dev_unregister(). This allows the panic code to
- * safely access any state which is invariant in between these two function
- * calls, like the list of planes &drm_mode_config.plane_list or most of the
- * struct drm_plane structure.
- *
- * Specifically thanks to the protection around plane updates in
- * drm_atomic_helper_swap_state() the following additional guarantees hold:
- *
- * - It is safe to deference the drm_plane.state pointer.
- *
- * - Anything in struct drm_plane_state or the driver's subclass thereof which
- * stays invariant after the atomic check code has finished is safe to access.
- * Specifically this includes the reference counted pointers to framebuffer
- * and buffer objects.
- *
- * - Anything set up by &drm_plane_helper_funcs.fb_prepare and cleaned up
- * &drm_plane_helper_funcs.fb_cleanup is safe to access, as long as it stays
- * invariant between these two calls. This also means that for drivers using
- * dynamic buffer management the framebuffer is pinned, and therefer all
- * relevant datastructures can be accessed without taking any further locks
- * (which would be impossible in panic context anyway).
- *
- * - Importantly, software and hardware state set up by
- * &drm_plane_helper_funcs.begin_fb_access and
- * &drm_plane_helper_funcs.end_fb_access is not safe to access.
- *
- * Drivers must not make any assumptions about the actual state of the hardware,
- * unless they explicitly protected these hardware access with drm_panic_lock()
- * and drm_panic_unlock().
- *
- * Return:
- * %0 when failing to acquire the raw spinlock, nonzero on success.
- */
-#define drm_panic_trylock(dev, flags) \
- raw_spin_trylock_irqsave(&(dev)->mode_config.panic_lock, flags)
-
-/**
- * drm_panic_lock - protect panic printing relevant state
- * @dev: struct drm_device
- * @flags: unsigned long irq flags you need to pass to the unlock() counterpart
- *
- * This function must be called to protect software and hardware state that the
- * panic printing code must be able to rely on. The protected sections must be
- * as small as possible. It uses the irqsave/irqrestore variant, and can be
- * called from irq handler. Examples include:
- *
- * - Access to peek/poke or other similar registers, if that is the way the
- * driver prints the pixels into the scanout buffer at panic time.
- *
- * - Updates to pointers like &drm_plane.state, allowing the panic handler to
- * safely deference these. This is done in drm_atomic_helper_swap_state().
- *
- * - An state that isn't invariant and that the driver must be able to access
- * during panic printing.
- */
-
-#define drm_panic_lock(dev, flags) \
- raw_spin_lock_irqsave(&(dev)->mode_config.panic_lock, flags)
-
-/**
- * drm_panic_unlock - end of the panic printing critical section
- * @dev: struct drm_device
- * @flags: irq flags that were returned when acquiring the lock
- *
- * Unlocks the raw spinlock acquired by either drm_panic_lock() or
- * drm_panic_trylock().
- */
-#define drm_panic_unlock(dev, flags) \
- raw_spin_unlock_irqrestore(&(dev)->mode_config.panic_lock, flags)
-
-#else
-
-static inline bool drm_panic_trylock(struct drm_device *dev, unsigned long flags)
-{
- return true;
-}
-
-static inline void drm_panic_lock(struct drm_device *dev, unsigned long flags) {}
-static inline void drm_panic_unlock(struct drm_device *dev, unsigned long flags) {}
-
-#endif
-
-#if defined(CONFIG_DRM_PANIC_SCREEN_QR_CODE)
-size_t drm_panic_qr_max_data_size(u8 version, size_t url_len);
-
-u8 drm_panic_qr_generate(const char *url, u8 *data, size_t data_len, size_t data_size,
- u8 *tmp, size_t tmp_size);
-#endif
-
#endif /* __DRM_PANIC_H__ */
diff --git a/include/drm/drm_panic_helper.h b/include/drm/drm_panic_helper.h
new file mode 100644
index 000000000000..fbfe51161aef
--- /dev/null
+++ b/include/drm/drm_panic_helper.h
@@ -0,0 +1,41 @@
+/* SPDX-License-Identifier: GPL-2.0 or MIT */
+
+#ifndef __DRM_DRM_PANIC_HELPER_H_
+#define __DRM_DRM_PANIC_HELPER_H_
+
+#include <linux/types.h>
+
+enum drm_panic_type;
+
+struct drm_plane;
+struct drm_scanout_buffer;
+
+/* drm_panic_helper.c */
+int drm_plane_helper_display_panic_screen(struct drm_plane *plane,
+ const char *description,
+ enum drm_panic_type panic_type,
+ u32 fg_color, u32 bg_color,
+ unsigned int qr_version);
+#if IS_ENABLED(CONFIG_KUNIT)
+int drm_panic_helper_draw_screen_user(struct drm_scanout_buffer *sb, u32 fg_color, u32 bg_color);
+int drm_panic_helper_draw_screen_kmsg(struct drm_scanout_buffer *sb, u32 fg_color, u32 bg_color);
+int drm_panic_helper_draw_screen_qr_code(struct drm_scanout_buffer *sb,
+ u32 fg_color, u32 bg_color, unsigned int qr_version);
+void drm_panic_helper_set_description(const char *description);
+void drm_panic_helper_clear_description(void);
+#endif
+
+/* drm_panic_helper_qr.rs */
+size_t drm_panic_helper_qr_max_data_size(u8 version, size_t url_len);
+u8 drm_panic_helper_qr_generate(const char *url, u8 *data, size_t data_len, size_t data_size,
+ u8 *tmp, size_t tmp_size);
+
+#if IS_ENABLED(CONFIG_DRM_PANIC)
+#define DRM_PANIC_PLANE_FUNCS \
+ .display_panic_screen = drm_plane_helper_display_panic_screen
+#else
+#define DRM_PANIC_PLANE_FUNCS \
+ .display_panic_screen = NULL
+#endif
+
+#endif
diff --git a/include/drm/drm_plane.h b/include/drm/drm_plane.h
index 2c5a5a70a71b..410d7b02b77a 100644
--- a/include/drm/drm_plane.h
+++ b/include/drm/drm_plane.h
@@ -32,6 +32,8 @@
#include <drm/drm_modeset_lock.h>
#include <drm/drm_util.h>
+enum drm_panic_type;
+
struct drm_crtc;
struct drm_plane_size_hint;
struct drm_printer;
@@ -360,18 +362,6 @@ struct drm_plane_funcs {
void (*destroy)(struct drm_plane *plane);
/**
- * @reset:
- *
- * Reset plane hardware and software state to off. This function isn't
- * called by the core directly, only through drm_mode_config_reset().
- * It's not a helper hook only for historical reasons.
- *
- * Atomic drivers can use drm_atomic_helper_plane_reset() to reset
- * atomic state using this hook.
- */
- void (*reset)(struct drm_plane *plane);
-
- /**
* @set_property:
*
* This is the legacy entry point to update a property attached to the
@@ -590,6 +580,61 @@ struct drm_plane_funcs {
bool (*format_mod_supported_async)(struct drm_plane *plane,
u32 format, u64 modifier);
+ /**
+ * @display_panic_screen:
+ *
+ * DRM panic handling invokes this callback on panics.
+ *
+ * It is a panic handler, so it can't take locks, allocate memory, run tasks/irq,
+ * or attempt to sleep. It's a best effort, and it may not be able to display
+ * the message in all situations (like if the panic occurs in the middle of a
+ * modesetting).
+ *
+ * Panic-printing code must acquire the panic lock before interacting with the
+ * scanout buffer. Such helpers can make the following assumptions while holding
+ * the panic lock:
+ *
+ * - Anything protected by drm_panic_lock() and drm_panic_unlock() pairs is safe
+ * to access.
+ *
+ * - Furthermore the panic printing code only registers in drm_dev_unregister()
+ * and gets removed in drm_dev_unregister(). This allows the panic code to
+ * safely access any state which is invariant in between these two function
+ * calls, like the list of planes &drm_mode_config.plane_list or most of the
+ * struct drm_plane structure.
+ *
+ * Specifically thanks to the protection around plane updates in
+ * drm_atomic_helper_swap_state() the following additional guarantees hold:
+ *
+ * - It is safe to deference the drm_plane.state pointer.
+ *
+ * - Anything in struct drm_plane_state or the driver's subclass thereof which
+ * stays invariant after the atomic check code has finished is safe to access.
+ * Specifically this includes the reference counted pointers to framebuffer
+ * and buffer objects.
+ *
+ * - Anything set up by &drm_plane_helper_funcs.fb_prepare and cleaned up
+ * &drm_plane_helper_funcs.fb_cleanup is safe to access, as long as it stays
+ * invariant between these two calls. This also means that for drivers using
+ * dynamic buffer management the framebuffer is pinned, and therefer all
+ * relevant datastructures can be accessed without taking any further locks
+ * (which would be impossible in panic context anyway).
+ *
+ * - Importantly, software and hardware state set up by
+ * &drm_plane_helper_funcs.begin_fb_access and
+ * &drm_plane_helper_funcs.end_fb_access is not safe to access.
+ *
+ * It will display only one static frame, so performance optimizations are
+ * low priority as the machine is already in an unusable state.
+ *
+ * This callback is optional. Planes without will not be considered
+ * for panic output.
+ */
+ int (*display_panic_screen)(struct drm_plane *plane,
+ const char *description,
+ enum drm_panic_type panic_type,
+ u32 fg_color, u32 bg_color,
+ unsigned int qr_version);
};
/**
diff --git a/include/drm/drm_print.h b/include/drm/drm_print.h
index 2adc5ac688e1..0805903c093b 100644
--- a/include/drm/drm_print.h
+++ b/include/drm/drm_print.h
@@ -644,6 +644,9 @@ static inline struct device *__drm_to_dev(const struct drm_device *drm)
#define drm_err_ratelimited(drm, fmt, ...) \
__drm_printk((drm), err, _ratelimited, "*ERROR* " fmt, ##__VA_ARGS__)
+#define drm_warn_ratelimited(drm, fmt, ...) \
+ __drm_printk((drm), warn, _ratelimited, fmt, ##__VA_ARGS__)
+
#define drm_dbg_core(drm, fmt, ...) \
drm_dev_dbg(__drm_to_dev(drm), DRM_UT_CORE, fmt, ##__VA_ARGS__)
diff --git a/include/drm/drm_ras.h b/include/drm/drm_ras.h
index 0beede3ddc4e..1765a3130b09 100644
--- a/include/drm/drm_ras.h
+++ b/include/drm/drm_ras.h
@@ -71,6 +71,35 @@ struct drm_ras_node {
*/
int (*clear_error_counter)(struct drm_ras_node *node, u32 error_id);
+ /**
+ * @query_error_threshold:
+ *
+ * This callback is used by drm-ras to query error threshold of a
+ * specific counter.
+ *
+ * Driver should expect query_error_threshold() to be called with
+ * error_id from `error_counter_range.first` to
+ * `error_counter_range.last`.
+ *
+ * Returns: 0 on success, negative error code on failure.
+ */
+ int (*query_error_threshold)(struct drm_ras_node *node, u32 error_id, const char **name,
+ u32 *threshold);
+
+ /**
+ * @set_error_threshold:
+ *
+ * This callback is used by drm-ras to set error threshold of a specific
+ * counter.
+ *
+ * Driver should expect set_error_threshold() to be called with error_id
+ * from `error_counter_range.first` to `error_counter_range.last`.
+ * Driver is responsible for error threshold bounds checking.
+ *
+ * Returns: 0 on success, negative error code on failure.
+ */
+ int (*set_error_threshold)(struct drm_ras_node *node, u32 error_id, u32 threshold);
+
/** @priv: Driver private data */
void *priv;
};
@@ -80,9 +109,14 @@ struct drm_device;
#if IS_ENABLED(CONFIG_DRM_RAS)
int drm_ras_node_register(struct drm_ras_node *node);
void drm_ras_node_unregister(struct drm_ras_node *node);
+int drm_ras_nl_error_event(struct drm_ras_node *node, u32 error_id, const char *error_name,
+ u32 value);
#else
static inline int drm_ras_node_register(struct drm_ras_node *node) { return 0; }
static inline void drm_ras_node_unregister(struct drm_ras_node *node) { }
+static inline int drm_ras_nl_error_event(struct drm_ras_node *node, u32 error_id,
+ const char *error_name, u32 value)
+{ return 0; }
#endif
#endif
diff --git a/include/drm/drm_simple_kms_helper.h b/include/drm/drm_simple_kms_helper.h
index cb672ce0e856..2b31c25c57a9 100644
--- a/include/drm/drm_simple_kms_helper.h
+++ b/include/drm/drm_simple_kms_helper.h
@@ -39,11 +39,10 @@ struct drm_simple_display_pipe_funcs {
struct drm_plane_state *plane_state);
int (*enable_vblank)(struct drm_simple_display_pipe *pipe);
void (*disable_vblank)(struct drm_simple_display_pipe *pipe);
- void (*reset_crtc)(struct drm_simple_display_pipe *pipe);
struct drm_crtc_state * (*duplicate_crtc_state)(struct drm_simple_display_pipe *pipe);
void (*destroy_crtc_state)(struct drm_simple_display_pipe *pipe,
struct drm_crtc_state *crtc_state);
- void (*reset_plane)(struct drm_simple_display_pipe *pipe);
+ struct drm_plane_state * (*create_plane_state)(struct drm_simple_display_pipe *pipe);
struct drm_plane_state * (*duplicate_plane_state)(struct drm_simple_display_pipe *pipe);
void (*destroy_plane_state)(struct drm_simple_display_pipe *pipe,
struct drm_plane_state *plane_state);
@@ -68,10 +67,6 @@ int drm_simple_display_pipe_init(struct drm_device *dev,
const uint64_t *format_modifiers,
struct drm_connector *connector);
-int drm_simple_encoder_init(struct drm_device *dev,
- struct drm_encoder *encoder,
- int encoder_type);
-
void *__drmm_simple_encoder_alloc(struct drm_device *dev, size_t size,
size_t offset, int encoder_type);
diff --git a/include/drm/drm_sysfs.h b/include/drm/drm_sysfs.h
index 96a5d858404b..7695873a9456 100644
--- a/include/drm/drm_sysfs.h
+++ b/include/drm/drm_sysfs.h
@@ -3,13 +3,9 @@
#define _DRM_SYSFS_H_
struct drm_device;
-struct device;
struct drm_connector;
struct drm_property;
-int drm_class_device_register(struct device *dev);
-void drm_class_device_unregister(struct device *dev);
-
void drm_sysfs_hotplug_event(struct drm_device *dev);
void drm_sysfs_connector_hotplug_event(struct drm_connector *connector);
void drm_sysfs_connector_property_event(struct drm_connector *connector,
diff --git a/include/drm/drm_timeout.h b/include/drm/drm_timeout.h
new file mode 100644
index 000000000000..6ee222a3e97c
--- /dev/null
+++ b/include/drm/drm_timeout.h
@@ -0,0 +1,17 @@
+/* SPDX-License-Identifier: MIT */
+/*
+ * Function prototypes for timeout conversion helpers for wait ioctls.
+ *
+ * Copyright 2017 Red Hat
+ * Copyright 2016 Advanced Micro Devices, Inc.
+ */
+
+#ifndef __DRM_TIMEOUT_H__
+#define __DRM_TIMEOUT_H__
+
+#include <linux/types.h>
+
+signed long drm_timeout_abs_to_jiffies(s64 timeout_nsec);
+unsigned long drm_timeout_rel_to_jiffies(u64 timeout_nsec);
+
+#endif
diff --git a/include/drm/gpu_scheduler.h b/include/drm/gpu_scheduler.h
index 7a64cc11de08..3b0978fa8cf0 100644
--- a/include/drm/gpu_scheduler.h
+++ b/include/drm/gpu_scheduler.h
@@ -100,8 +100,8 @@ struct drm_sched_entity {
* @lock:
*
* Lock protecting the run-queue (@rq) to which this entity belongs,
- * @priority, the list of schedulers (@sched_list, @num_sched_list) and
- * the @rr_ts field.
+ * @priority, @last_scheduled and the list of schedulers (@sched_list,
+ * @num_sched_list), @rr_ts and @stopped.
*/
spinlock_t lock;
@@ -215,11 +215,9 @@ struct drm_sched_entity {
/**
* @last_scheduled:
*
- * Points to the finished fence of the last scheduled job. Only written
- * by drm_sched_entity_pop_job(). Can be accessed locklessly from
- * drm_sched_job_arm() if the queue is empty.
+ * Points to the finished fence of the last scheduled job.
*/
- struct dma_fence __rcu *last_scheduled;
+ struct dma_fence *last_scheduled;
/**
* @last_user: last group leader pushing a job into the entity.
diff --git a/include/drm/intel/display_parent_interface.h b/include/drm/intel/display_parent_interface.h
index de395df9ca30..464fb588cb60 100644
--- a/include/drm/intel/display_parent_interface.h
+++ b/include/drm/intel/display_parent_interface.h
@@ -16,11 +16,11 @@ struct drm_mode_fb_cmd2;
struct drm_plane_state;
struct drm_scanout_buffer;
struct fb_info;
-struct i915_gtt_view;
struct i915_vma;
struct intel_dpt;
struct intel_dsb_buffer;
struct intel_frontbuffer;
+struct intel_gtt_view;
struct intel_hdcp_gsc_context;
struct intel_initial_plane_config;
struct intel_panic;
@@ -31,7 +31,7 @@ struct seq_file;
struct vm_area_struct;
struct intel_fb_pin_params {
- const struct i915_gtt_view *view;
+ const struct intel_gtt_view *view;
unsigned int alignment;
unsigned int phys_alignment;
unsigned int vtd_guard;
@@ -101,9 +101,9 @@ struct intel_display_fb_pin_interface {
struct i915_vma *ggtt_vma);
struct i915_vma *(*reuse_vma)(struct i915_vma *old_ggtt_vma,
struct drm_gem_object *old_obj,
- const struct i915_gtt_view *old_view,
+ const struct intel_gtt_view *old_view,
struct drm_gem_object *new_obj,
- const struct i915_gtt_view *new_view,
+ const struct intel_gtt_view *new_view,
u32 *out_offset);
void (*get_map)(struct i915_vma *vma, struct iosys_map *map);
};
@@ -179,7 +179,7 @@ struct intel_display_pc8_interface {
};
struct intel_display_pcode_interface {
- int (*read)(struct drm_device *drm, u32 mbox, u32 *val, u32 *val1);
+ int (*read)(struct drm_device *drm, u32 mbox, u32 *val0, u32 *val1);
int (*write)(struct drm_device *drm, u32 mbox, u32 val, int timeout_ms);
int (*request)(struct drm_device *drm, u32 mbox, u32 request,
u32 reply_mask, u32 reply, int timeout_base_ms);
@@ -196,6 +196,7 @@ struct intel_display_rpm_interface {
void (*put_unchecked)(const struct drm_device *drm);
bool (*suspended)(const struct drm_device *drm);
+ bool (*pme_enabled)(const struct drm_device *drm); /* Optional */
void (*assert_held)(const struct drm_device *drm);
void (*assert_block)(const struct drm_device *drm);
void (*assert_unblock)(const struct drm_device *drm);
@@ -230,6 +231,10 @@ struct intel_display_vlv_iosf_interface {
int (*write)(struct drm_device *drm, enum vlv_iosf_sb_unit unit, u32 addr, u32 val);
};
+struct intel_display_wa_interface {
+ bool (*wa_16023588340)(struct drm_device *drm);
+};
+
/**
* struct intel_display_parent_interface - services parent driver provides to display
*
@@ -291,6 +296,12 @@ struct intel_display_parent_interface {
/** @vlv_iosf: VLV IOSF sideband. Optional. */
const struct intel_display_vlv_iosf_interface *vlv_iosf;
+ /**
+ * @wa: Display workarounds query. Use only for workarounds that require
+ * information only available to the parent driver. Optional.
+ */
+ const struct intel_display_wa_interface *wa;
+
/* Generic independent functions */
struct {
/** @fence_priority_display: Set display priority. Optional. */
@@ -302,6 +313,9 @@ struct intel_display_parent_interface {
/** @has_fenced_regions: Support legacy fencing? Optional. */
bool (*has_fenced_regions)(struct drm_device *drm);
+ /** @transient_data_flush: Transient data flush. Optional. */
+ void (*transient_data_flush)(struct drm_device *drm);
+
/** @vgpu_active: Is vGPU active? Optional. */
bool (*vgpu_active)(struct drm_device *drm);
};
diff --git a/include/drm/intel/gtt_view_types.h b/include/drm/intel/gtt_view_types.h
new file mode 100644
index 000000000000..128392d98f3a
--- /dev/null
+++ b/include/drm/intel/gtt_view_types.h
@@ -0,0 +1,79 @@
+/* SPDX-License-Identifier: MIT */
+/* Copyright © 2025 Intel Corporation */
+
+#ifndef __DRM_INTEL_GTT_VIEW_TYPES_H__
+#define __DRM_INTEL_GTT_VIEW_TYPES_H__
+
+#include <linux/types.h>
+
+struct intel_remapped_plane_info {
+ /* in gtt pages */
+ u32 offset:31;
+ u32 linear:1;
+ union {
+ /* in gtt pages for !linear */
+ struct {
+ u16 width;
+ u16 height;
+ u16 src_stride;
+ u16 dst_stride;
+ };
+
+ /* in gtt pages for linear */
+ u32 size;
+ };
+} __packed;
+
+struct intel_rotation_info {
+ struct intel_remapped_plane_info plane[2];
+} __packed;
+
+struct intel_partial_info {
+ u64 offset;
+ unsigned int size;
+} __packed;
+
+struct intel_remapped_info {
+ struct intel_remapped_plane_info plane[4];
+ /* in gtt pages */
+ u32 plane_alignment;
+} __packed;
+
+enum intel_gtt_view_type {
+ INTEL_GTT_VIEW_NORMAL = 0,
+ INTEL_GTT_VIEW_ROTATED = sizeof(struct intel_rotation_info),
+ INTEL_GTT_VIEW_PARTIAL = sizeof(struct intel_partial_info),
+ INTEL_GTT_VIEW_REMAPPED = sizeof(struct intel_remapped_info),
+};
+
+struct intel_gtt_view {
+ enum intel_gtt_view_type type;
+ union {
+ /* Members need to contain no holes/padding */
+ struct intel_partial_info partial;
+ struct intel_rotation_info rotated;
+ struct intel_remapped_info remapped;
+ };
+};
+
+static inline bool intel_gtt_view_is_normal(const struct intel_gtt_view *view)
+{
+ return view->type == INTEL_GTT_VIEW_NORMAL;
+}
+
+static inline bool intel_gtt_view_is_remapped(const struct intel_gtt_view *view)
+{
+ return view->type == INTEL_GTT_VIEW_REMAPPED;
+}
+
+static inline bool intel_gtt_view_is_rotated(const struct intel_gtt_view *view)
+{
+ return view->type == INTEL_GTT_VIEW_ROTATED;
+}
+
+static inline bool intel_gtt_view_is_partial(const struct intel_gtt_view *view)
+{
+ return view->type == INTEL_GTT_VIEW_PARTIAL;
+}
+
+#endif /* __DRM_INTEL_GTT_VIEW_TYPES_H__ */
diff --git a/include/drm/intel/pciids.h b/include/drm/intel/pciids.h
index dff389b56eb3..32c88a690ad8 100644
--- a/include/drm/intel/pciids.h
+++ b/include/drm/intel/pciids.h
@@ -880,6 +880,7 @@
MACRO__(0xB08F, ## __VA_ARGS__), \
MACRO__(0xB090, ## __VA_ARGS__), \
MACRO__(0xB0A0, ## __VA_ARGS__), \
+ MACRO__(0xB0A1, ## __VA_ARGS__), \
MACRO__(0xB0B0, ## __VA_ARGS__)
/* WCL */
diff --git a/include/drm/ttm/ttm_resource.h b/include/drm/ttm/ttm_resource.h
index 3f2812743a7e..714c533622c2 100644
--- a/include/drm/ttm/ttm_resource.h
+++ b/include/drm/ttm/ttm_resource.h
@@ -35,7 +35,7 @@
#include <drm/ttm/ttm_kmap_iter.h>
#define TTM_MAX_BO_PRIORITY 4U
-#define TTM_NUM_MEM_TYPES 9
+#define TTM_NUM_MEM_TYPES 10
struct dentry;
struct dmem_cgroup_device;
diff --git a/include/dt-bindings/arm/qcom,ids.h b/include/dt-bindings/arm/qcom,ids.h
index 2cf433f61d5e..135297027580 100644
--- a/include/dt-bindings/arm/qcom,ids.h
+++ b/include/dt-bindings/arm/qcom,ids.h
@@ -209,6 +209,7 @@
#define QCOM_ID_IPQ8172 397
#define QCOM_ID_IPQ8173 398
#define QCOM_ID_IPQ8174 399
+#define QCOM_ID_SM7250 400
#define QCOM_ID_IPQ6018 402
#define QCOM_ID_IPQ6028 403
#define QCOM_ID_SDM429W 416
@@ -300,8 +301,10 @@
#define QCOM_ID_QCS9075 676
#define QCOM_ID_QCS615 680
#define QCOM_ID_SA8797P 690
+#define QCOM_ID_SM8975 707
#define QCOM_ID_CQ7790M 731
#define QCOM_ID_CQ7790S 732
+#define QCOM_ID_SM8950 735
#define QCOM_ID_CQ2390M 756
#define QCOM_ID_CQ2390S 758
#define QCOM_ID_IQ2390S 759
diff --git a/include/dt-bindings/arm/ux500_pm_domains.h b/include/dt-bindings/arm/ux500_pm_domains.h
index 9bd764f0c9e6..f7a9fc101fb2 100644
--- a/include/dt-bindings/arm/ux500_pm_domains.h
+++ b/include/dt-bindings/arm/ux500_pm_domains.h
@@ -8,8 +8,21 @@
#define _DT_BINDINGS_ARM_UX500_PM_DOMAINS_H
#define DOMAIN_VAPE 0
+#define DOMAIN_VARM 1
+#define DOMAIN_VMODEM 2
+#define DOMAIN_VPLL 3
+#define DOMAIN_VSMPS1 4
+#define DOMAIN_VSMPS2 5
+#define DOMAIN_VSMPS3 6
+#define DOMAIN_VRF1 7
+#define DOMAIN_SVA_MMDSP 8
+#define DOMAIN_SVA_PIPE 9
+#define DOMAIN_SIA_MMDSP 10
+#define DOMAIN_SIA_PIPE 11
+#define DOMAIN_SGA 12
+#define DOMAIN_B2R2_MCDE 13
+#define DOMAIN_ESRAM_12 14
+#define DOMAIN_ESRAM_34 15
-/* Number of PM domains. */
-#define NR_DOMAINS (DOMAIN_VAPE + 1)
#endif
diff --git a/include/dt-bindings/clock/agilex-clock.h b/include/dt-bindings/clock/agilex-clock.h
index 06feca07e08e..6206a45e007c 100644
--- a/include/dt-bindings/clock/agilex-clock.h
+++ b/include/dt-bindings/clock/agilex-clock.h
@@ -44,6 +44,7 @@
/* Gate clocks */
#define AGILEX_MPU_CLK 30
+/* Legacy ABI ID; do not use in new DTs, use AGILEX_MPU_CCU_CLK */
#define AGILEX_MPU_L2RAM_CLK 31
#define AGILEX_MPU_PERIPH_CLK 32
#define AGILEX_L4_MAIN_CLK 33
diff --git a/include/dt-bindings/clock/qcom,eliza-cambistmclkcc.h b/include/dt-bindings/clock/qcom,eliza-cambistmclkcc.h
new file mode 100644
index 000000000000..7b8b285f18d2
--- /dev/null
+++ b/include/dt-bindings/clock/qcom,eliza-cambistmclkcc.h
@@ -0,0 +1,32 @@
+/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */
+/*
+ * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
+ */
+
+#ifndef _DT_BINDINGS_CLK_QCOM_CAM_BIST_MCLK_CC_ELIZA_H
+#define _DT_BINDINGS_CLK_QCOM_CAM_BIST_MCLK_CC_ELIZA_H
+
+/* CAM_BIST_MCLK_CC clocks */
+#define CAM_BIST_MCLK_CC_MCLK0_CLK 0
+#define CAM_BIST_MCLK_CC_MCLK0_CLK_SRC 1
+#define CAM_BIST_MCLK_CC_MCLK1_CLK 2
+#define CAM_BIST_MCLK_CC_MCLK1_CLK_SRC 3
+#define CAM_BIST_MCLK_CC_MCLK2_CLK 4
+#define CAM_BIST_MCLK_CC_MCLK2_CLK_SRC 5
+#define CAM_BIST_MCLK_CC_MCLK3_CLK 6
+#define CAM_BIST_MCLK_CC_MCLK3_CLK_SRC 7
+#define CAM_BIST_MCLK_CC_MCLK4_CLK 8
+#define CAM_BIST_MCLK_CC_MCLK4_CLK_SRC 9
+#define CAM_BIST_MCLK_CC_MCLK5_CLK 10
+#define CAM_BIST_MCLK_CC_MCLK5_CLK_SRC 11
+#define CAM_BIST_MCLK_CC_MCLK6_CLK 12
+#define CAM_BIST_MCLK_CC_MCLK6_CLK_SRC 13
+#define CAM_BIST_MCLK_CC_MCLK7_CLK 14
+#define CAM_BIST_MCLK_CC_MCLK7_CLK_SRC 15
+#define CAM_BIST_MCLK_CC_PLL0 16
+#define CAM_BIST_MCLK_CC_PLL_TEST_CLK 17
+#define CAM_BIST_MCLK_CC_PLL_TEST_DIV_CLK_SRC 18
+#define CAM_BIST_MCLK_CC_SLEEP_CLK 19
+#define CAM_BIST_MCLK_CC_SLEEP_CLK_SRC 20
+
+#endif
diff --git a/include/dt-bindings/clock/qcom,eliza-camcc.h b/include/dt-bindings/clock/qcom,eliza-camcc.h
new file mode 100644
index 000000000000..d85ef9777d08
--- /dev/null
+++ b/include/dt-bindings/clock/qcom,eliza-camcc.h
@@ -0,0 +1,151 @@
+/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */
+/*
+ * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
+ */
+
+#ifndef _DT_BINDINGS_CLK_QCOM_CAM_CC_ELIZA_H
+#define _DT_BINDINGS_CLK_QCOM_CAM_CC_ELIZA_H
+
+/* CAM_CC clocks */
+#define CAM_CC_CAM_TOP_AHB_CLK 0
+#define CAM_CC_CAM_TOP_FAST_AHB_CLK 1
+#define CAM_CC_CAMNOC_DCD_XO_CLK 2
+#define CAM_CC_CAMNOC_NRT_AXI_CLK 3
+#define CAM_CC_CAMNOC_NRT_CRE_CLK 4
+#define CAM_CC_CAMNOC_NRT_IPE_NPS_CLK 5
+#define CAM_CC_CAMNOC_NRT_OFE_ANCHOR_CLK 6
+#define CAM_CC_CAMNOC_NRT_OFE_HDR_CLK 7
+#define CAM_CC_CAMNOC_NRT_OFE_MAIN_CLK 8
+#define CAM_CC_CAMNOC_RT_AXI_CLK 9
+#define CAM_CC_CAMNOC_RT_AXI_CLK_SRC 10
+#define CAM_CC_CAMNOC_RT_IFE_LITE_CLK 11
+#define CAM_CC_CAMNOC_RT_TFE_0_BAYER_CLK 12
+#define CAM_CC_CAMNOC_RT_TFE_0_MAIN_CLK 13
+#define CAM_CC_CAMNOC_RT_TFE_1_BAYER_CLK 14
+#define CAM_CC_CAMNOC_RT_TFE_1_MAIN_CLK 15
+#define CAM_CC_CAMNOC_RT_TFE_2_BAYER_CLK 16
+#define CAM_CC_CAMNOC_RT_TFE_2_MAIN_CLK 17
+#define CAM_CC_CAMNOC_XO_CLK 18
+#define CAM_CC_CCI_0_CLK 19
+#define CAM_CC_CCI_0_CLK_SRC 20
+#define CAM_CC_CCI_1_CLK 21
+#define CAM_CC_CCI_1_CLK_SRC 22
+#define CAM_CC_CCI_2_CLK 23
+#define CAM_CC_CCI_2_CLK_SRC 24
+#define CAM_CC_CORE_AHB_CLK 25
+#define CAM_CC_CPHY_RX_CLK_SRC 26
+#define CAM_CC_CRE_AHB_CLK 27
+#define CAM_CC_CRE_CLK 28
+#define CAM_CC_CRE_CLK_SRC 29
+#define CAM_CC_CSI0PHYTIMER_CLK 30
+#define CAM_CC_CSI0PHYTIMER_CLK_SRC 31
+#define CAM_CC_CSI1PHYTIMER_CLK 32
+#define CAM_CC_CSI1PHYTIMER_CLK_SRC 33
+#define CAM_CC_CSI2PHYTIMER_CLK 34
+#define CAM_CC_CSI2PHYTIMER_CLK_SRC 35
+#define CAM_CC_CSI3PHYTIMER_CLK 36
+#define CAM_CC_CSI3PHYTIMER_CLK_SRC 37
+#define CAM_CC_CSI4PHYTIMER_CLK 38
+#define CAM_CC_CSI4PHYTIMER_CLK_SRC 39
+#define CAM_CC_CSI5PHYTIMER_CLK 40
+#define CAM_CC_CSI5PHYTIMER_CLK_SRC 41
+#define CAM_CC_CSID_CLK 42
+#define CAM_CC_CSID_CLK_SRC 43
+#define CAM_CC_CSID_CSIPHY_RX_CLK 44
+#define CAM_CC_CSIPHY0_CLK 45
+#define CAM_CC_CSIPHY1_CLK 46
+#define CAM_CC_CSIPHY2_CLK 47
+#define CAM_CC_CSIPHY3_CLK 48
+#define CAM_CC_CSIPHY4_CLK 49
+#define CAM_CC_CSIPHY5_CLK 50
+#define CAM_CC_DRV_AHB_CLK 51
+#define CAM_CC_DRV_XO_CLK 52
+#define CAM_CC_FAST_AHB_CLK_SRC 53
+#define CAM_CC_GDSC_CLK 54
+#define CAM_CC_ICP_0_AHB_CLK 55
+#define CAM_CC_ICP_0_CLK 56
+#define CAM_CC_ICP_0_CLK_SRC 57
+#define CAM_CC_ICP_1_AHB_CLK 58
+#define CAM_CC_ICP_1_CLK 59
+#define CAM_CC_ICP_1_CLK_SRC 60
+#define CAM_CC_IFE_LITE_AHB_CLK 61
+#define CAM_CC_IFE_LITE_CLK 62
+#define CAM_CC_IFE_LITE_CLK_SRC 63
+#define CAM_CC_IFE_LITE_CPHY_RX_CLK 64
+#define CAM_CC_IFE_LITE_CSID_CLK 65
+#define CAM_CC_IFE_LITE_CSID_CLK_SRC 66
+#define CAM_CC_IPE_NPS_AHB_CLK 67
+#define CAM_CC_IPE_NPS_CLK 68
+#define CAM_CC_IPE_NPS_CLK_SRC 69
+#define CAM_CC_IPE_NPS_FAST_AHB_CLK 70
+#define CAM_CC_IPE_PPS_CLK 71
+#define CAM_CC_IPE_PPS_FAST_AHB_CLK 72
+#define CAM_CC_JPEG_0_CLK 73
+#define CAM_CC_JPEG_1_CLK 74
+#define CAM_CC_JPEG_CLK_SRC 75
+#define CAM_CC_OFE_AHB_CLK 76
+#define CAM_CC_OFE_ANCHOR_CLK 77
+#define CAM_CC_OFE_ANCHOR_FAST_AHB_CLK 78
+#define CAM_CC_OFE_CLK_SRC 79
+#define CAM_CC_OFE_HDR_CLK 80
+#define CAM_CC_OFE_HDR_FAST_AHB_CLK 81
+#define CAM_CC_OFE_MAIN_CLK 82
+#define CAM_CC_OFE_MAIN_FAST_AHB_CLK 83
+#define CAM_CC_PLL0 84
+#define CAM_CC_PLL0_OUT_EVEN 85
+#define CAM_CC_PLL0_OUT_ODD 86
+#define CAM_CC_PLL1 87
+#define CAM_CC_PLL1_OUT_EVEN 88
+#define CAM_CC_PLL2 89
+#define CAM_CC_PLL2_OUT_EVEN 90
+#define CAM_CC_PLL3 91
+#define CAM_CC_PLL3_OUT_EVEN 92
+#define CAM_CC_PLL4 93
+#define CAM_CC_PLL4_OUT_EVEN 94
+#define CAM_CC_PLL5 95
+#define CAM_CC_PLL5_OUT_EVEN 96
+#define CAM_CC_PLL6 97
+#define CAM_CC_PLL6_OUT_EVEN 98
+#define CAM_CC_PLL6_OUT_ODD 99
+#define CAM_CC_QDSS_DEBUG_CLK 100
+#define CAM_CC_QDSS_DEBUG_CLK_SRC 101
+#define CAM_CC_QDSS_DEBUG_XO_CLK 102
+#define CAM_CC_SLEEP_CLK 103
+#define CAM_CC_SLEEP_CLK_SRC 104
+#define CAM_CC_SLOW_AHB_CLK_SRC 105
+#define CAM_CC_TFE_0_BAYER_CLK 106
+#define CAM_CC_TFE_0_BAYER_FAST_AHB_CLK 107
+#define CAM_CC_TFE_0_CLK_SRC 108
+#define CAM_CC_TFE_0_MAIN_CLK 109
+#define CAM_CC_TFE_0_MAIN_FAST_AHB_CLK 110
+#define CAM_CC_TFE_1_BAYER_CLK 111
+#define CAM_CC_TFE_1_BAYER_FAST_AHB_CLK 112
+#define CAM_CC_TFE_1_CLK_SRC 113
+#define CAM_CC_TFE_1_MAIN_CLK 114
+#define CAM_CC_TFE_1_MAIN_FAST_AHB_CLK 115
+#define CAM_CC_TFE_2_BAYER_CLK 116
+#define CAM_CC_TFE_2_BAYER_FAST_AHB_CLK 117
+#define CAM_CC_TFE_2_CLK_SRC 118
+#define CAM_CC_TFE_2_MAIN_CLK 119
+#define CAM_CC_TFE_2_MAIN_FAST_AHB_CLK 120
+#define CAM_CC_XO_CLK_SRC 121
+
+/* CAM_CC power domains */
+#define CAM_CC_IPE_0_GDSC 0
+#define CAM_CC_OFE_GDSC 1
+#define CAM_CC_TFE_0_GDSC 2
+#define CAM_CC_TFE_1_GDSC 3
+#define CAM_CC_TFE_2_GDSC 4
+#define CAM_CC_TITAN_TOP_GDSC 5
+
+/* CAM_CC resets */
+#define CAM_CC_DRV_BCR 0
+#define CAM_CC_ICP_BCR 1
+#define CAM_CC_IPE_0_BCR 2
+#define CAM_CC_OFE_BCR 3
+#define CAM_CC_QDSS_DEBUG_BCR 4
+#define CAM_CC_TFE_0_BCR 5
+#define CAM_CC_TFE_1_BCR 6
+#define CAM_CC_TFE_2_BCR 7
+
+#endif
diff --git a/include/dt-bindings/clock/qcom,eliza-gpucc.h b/include/dt-bindings/clock/qcom,eliza-gpucc.h
new file mode 100644
index 000000000000..c3d9b7827325
--- /dev/null
+++ b/include/dt-bindings/clock/qcom,eliza-gpucc.h
@@ -0,0 +1,51 @@
+/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */
+/*
+ * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
+ */
+
+#ifndef _DT_BINDINGS_CLK_QCOM_GPU_CC_ELIZA_H
+#define _DT_BINDINGS_CLK_QCOM_GPU_CC_ELIZA_H
+
+/* GPU_CC clocks */
+#define GPU_CC_AHB_CLK 0
+#define GPU_CC_CRC_AHB_CLK 1
+#define GPU_CC_CX_ACCU_SHIFT_CLK 2
+#define GPU_CC_CX_FF_CLK 3
+#define GPU_CC_CX_GMU_CLK 4
+#define GPU_CC_CXO_AON_CLK 5
+#define GPU_CC_CXO_CLK 6
+#define GPU_CC_DEMET_CLK 7
+#define GPU_CC_DEMET_DIV_CLK_SRC 8
+#define GPU_CC_FF_CLK_SRC 9
+#define GPU_CC_FREQ_MEASURE_CLK 10
+#define GPU_CC_GMU_CLK_SRC 11
+#define GPU_CC_HLOS1_VOTE_GPU_SMMU_CLK 12
+#define GPU_CC_HUB_AON_CLK 13
+#define GPU_CC_HUB_CLK_SRC 14
+#define GPU_CC_HUB_CX_INT_CLK 15
+#define GPU_CC_MEMNOC_GFX_CLK 16
+#define GPU_CC_MND1X_0_GFX3D_CLK 17
+#define GPU_CC_MND1X_1_GFX3D_CLK 18
+#define GPU_CC_PLL0 19
+#define GPU_CC_PLL1 20
+#define GPU_CC_SLEEP_CLK 21
+#define GPU_CC_XO_CLK_SRC 22
+#define GPU_CC_XO_DIV_CLK_SRC 23
+
+/* GPU_CC power domains */
+#define GPU_CC_CX_GDSC 0
+#define GPU_CC_GX_GDSC 1
+
+/* GPU_CC resets */
+#define GPU_CC_ACD_BCR 0
+#define GPU_CC_CB_BCR 1
+#define GPU_CC_CX_BCR 2
+#define GPU_CC_FAST_HUB_BCR 3
+#define GPU_CC_FF_BCR 4
+#define GPU_CC_GFX3D_AON_BCR 5
+#define GPU_CC_GMU_BCR 6
+#define GPU_CC_GX_BCR 7
+#define GPU_CC_RBCPR_BCR 8
+#define GPU_CC_XO_BCR 9
+
+#endif
diff --git a/include/dt-bindings/clock/qcom,eliza-videocc.h b/include/dt-bindings/clock/qcom,eliza-videocc.h
new file mode 100644
index 000000000000..1e922250a7fa
--- /dev/null
+++ b/include/dt-bindings/clock/qcom,eliza-videocc.h
@@ -0,0 +1,37 @@
+/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */
+/*
+ * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
+ */
+
+#ifndef _DT_BINDINGS_CLK_QCOM_VIDEO_CC_ELIZA_H
+#define _DT_BINDINGS_CLK_QCOM_VIDEO_CC_ELIZA_H
+
+/* VIDEO_CC clocks */
+#define VIDEO_CC_AHB_CLK 0
+#define VIDEO_CC_AHB_CLK_SRC 1
+#define VIDEO_CC_MVS0_CLK 2
+#define VIDEO_CC_MVS0_CLK_SRC 3
+#define VIDEO_CC_MVS0_DIV_CLK_SRC 4
+#define VIDEO_CC_MVS0_SHIFT_CLK 5
+#define VIDEO_CC_MVS0C_CLK 6
+#define VIDEO_CC_MVS0C_DIV2_DIV_CLK_SRC 7
+#define VIDEO_CC_MVS0C_SHIFT_CLK 8
+#define VIDEO_CC_PLL0 9
+#define VIDEO_CC_SLEEP_CLK 10
+#define VIDEO_CC_SLEEP_CLK_SRC 11
+#define VIDEO_CC_XO_CLK 12
+#define VIDEO_CC_XO_CLK_SRC 13
+
+/* VIDEO_CC power domains */
+#define VIDEO_CC_MVS0_GDSC 0
+#define VIDEO_CC_MVS0C_GDSC 1
+
+/* VIDEO_CC resets */
+#define VIDEO_CC_INTERFACE_BCR 0
+#define VIDEO_CC_MVS0_CLK_ARES 1
+#define VIDEO_CC_MVS0_BCR 2
+#define VIDEO_CC_MVS0C_CLK_ARES 3
+#define VIDEO_CC_MVS0C_BCR 4
+#define VIDEO_CC_XO_CLK_ARES 5
+
+#endif
diff --git a/include/dt-bindings/clock/qcom,hawi-camcc.h b/include/dt-bindings/clock/qcom,hawi-camcc.h
new file mode 100644
index 000000000000..6ef731738e6e
--- /dev/null
+++ b/include/dt-bindings/clock/qcom,hawi-camcc.h
@@ -0,0 +1,165 @@
+/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */
+/*
+ * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
+ */
+
+#ifndef _DT_BINDINGS_CLK_QCOM_CAM_CC_HAWI_H
+#define _DT_BINDINGS_CLK_QCOM_CAM_CC_HAWI_H
+
+/* CAM_CC clocks */
+#define CAM_CC_CAM_TOP_AHB_CLK 0
+#define CAM_CC_CAM_TOP_FAST_AHB_CLK 1
+#define CAM_CC_CAMNOC_DCD_XO_CLK 2
+#define CAM_CC_CAMNOC_NRT_AXI_CLK 3
+#define CAM_CC_CAMNOC_NRT_CRE_CLK 4
+#define CAM_CC_CAMNOC_NRT_IPE_NPS_CLK 5
+#define CAM_CC_CAMNOC_NRT_IPE_SCALERS_CLK 6
+#define CAM_CC_CAMNOC_NRT_OFE_MAIN_CLK 7
+#define CAM_CC_CAMNOC_NRT_SQPF_CLK 8
+#define CAM_CC_CAMNOC_RT_AXI_CLK 9
+#define CAM_CC_CAMNOC_RT_AXI_CLK_SRC 10
+#define CAM_CC_CAMNOC_RT_IFE_LITE_CLK 11
+#define CAM_CC_CAMNOC_RT_TFE_0_MAIN_CLK 12
+#define CAM_CC_CAMNOC_RT_TFE_1_MAIN_CLK 13
+#define CAM_CC_CAMNOC_RT_TFE_2_MAIN_CLK 14
+#define CAM_CC_CCI_0_CLK 15
+#define CAM_CC_CCI_0_CLK_SRC 16
+#define CAM_CC_CCI_1_CLK 17
+#define CAM_CC_CCI_1_CLK_SRC 18
+#define CAM_CC_CCI_2_CLK 19
+#define CAM_CC_CCI_2_CLK_SRC 20
+#define CAM_CC_CORE_AHB_CLK 21
+#define CAM_CC_CPHY_RX_CLK_SRC 22
+#define CAM_CC_CRE_AHB_CLK 23
+#define CAM_CC_CRE_CLK 24
+#define CAM_CC_CRE_CLK_SRC 25
+#define CAM_CC_CSI0PHYTIMER_CLK 26
+#define CAM_CC_CSI0PHYTIMER_CLK_SRC 27
+#define CAM_CC_CSI1PHYTIMER_CLK 28
+#define CAM_CC_CSI1PHYTIMER_CLK_SRC 29
+#define CAM_CC_CSI2PHYTIMER_CLK 30
+#define CAM_CC_CSI2PHYTIMER_CLK_SRC 31
+#define CAM_CC_CSI3PHYTIMER_CLK 32
+#define CAM_CC_CSI3PHYTIMER_CLK_SRC 33
+#define CAM_CC_CSI4PHYTIMER_CLK 34
+#define CAM_CC_CSI4PHYTIMER_CLK_SRC 35
+#define CAM_CC_CSI5PHYTIMER_CLK 36
+#define CAM_CC_CSI5PHYTIMER_CLK_SRC 37
+#define CAM_CC_CSID_CLK 38
+#define CAM_CC_CSID_CLK_SRC 39
+#define CAM_CC_CSID_CSIPHY_RX_CLK 40
+#define CAM_CC_CSIPHY0_CLK 41
+#define CAM_CC_CSIPHY1_CLK 42
+#define CAM_CC_CSIPHY2_CLK 43
+#define CAM_CC_CSIPHY3_CLK 44
+#define CAM_CC_CSIPHY4_CLK 45
+#define CAM_CC_CSIPHY5_CLK 46
+#define CAM_CC_CX_GDSC_CLK 47
+#define CAM_CC_DRV_AHB_CLK 48
+#define CAM_CC_DRV_XO_CLK 49
+#define CAM_CC_FAST_AHB_CLK_SRC 50
+#define CAM_CC_GDSC_CLK 51
+#define CAM_CC_ICP_0_AHB_CLK 52
+#define CAM_CC_ICP_0_CLK 53
+#define CAM_CC_ICP_0_CLK_SRC 54
+#define CAM_CC_ICP_1_AHB_CLK 55
+#define CAM_CC_ICP_1_CLK 56
+#define CAM_CC_ICP_1_CLK_SRC 57
+#define CAM_CC_IFE_LITE_AHB_CLK 58
+#define CAM_CC_IFE_LITE_CLK 59
+#define CAM_CC_IFE_LITE_CLK_SRC 60
+#define CAM_CC_IFE_LITE_CPHY_RX_CLK 61
+#define CAM_CC_IFE_LITE_CSID_CLK 62
+#define CAM_CC_IFE_LITE_CSID_CLK_SRC 63
+#define CAM_CC_IPE_NPS_AHB_CLK 64
+#define CAM_CC_IPE_NPS_CLK 65
+#define CAM_CC_IPE_NPS_CLK_SRC 66
+#define CAM_CC_IPE_NPS_FAST_AHB_CLK 67
+#define CAM_CC_IPE_PPS_CLK 68
+#define CAM_CC_IPE_PPS_FAST_AHB_CLK 69
+#define CAM_CC_IPE_SCALERS_CLK 70
+#define CAM_CC_IPE_SCALERS_FAST_AHB_CLK 71
+#define CAM_CC_JPEG_CLK 72
+#define CAM_CC_JPEG_CLK_SRC 73
+#define CAM_CC_MMSS_AHB_CLK 74
+#define CAM_CC_OFE_AHB_CLK 75
+#define CAM_CC_OFE_ANCHOR_CLK 76
+#define CAM_CC_OFE_ANCHOR_FAST_AHB_CLK 77
+#define CAM_CC_OFE_CLK_SRC 78
+#define CAM_CC_OFE_HDR_CLK 79
+#define CAM_CC_OFE_HDR_FAST_AHB_CLK 80
+#define CAM_CC_OFE_MAIN_CLK 81
+#define CAM_CC_OFE_MAIN_FAST_AHB_CLK 82
+#define CAM_CC_OFE_MP_CLK 83
+#define CAM_CC_OFE_MP_FAST_AHB_CLK 84
+#define CAM_CC_PLL0 85
+#define CAM_CC_PLL0_OUT_EVEN 86
+#define CAM_CC_PLL0_OUT_ODD 87
+#define CAM_CC_PLL1 88
+#define CAM_CC_PLL1_OUT_EVEN 89
+#define CAM_CC_PLL2 90
+#define CAM_CC_PLL2_OUT_EVEN 91
+#define CAM_CC_PLL3 92
+#define CAM_CC_PLL3_OUT_EVEN 93
+#define CAM_CC_PLL4 94
+#define CAM_CC_PLL4_OUT_EVEN 95
+#define CAM_CC_PLL5 96
+#define CAM_CC_PLL5_OUT_EVEN 97
+#define CAM_CC_PLL6 98
+#define CAM_CC_PLL6_OUT_EVEN 99
+#define CAM_CC_PLL6_OUT_ODD 100
+#define CAM_CC_PLL7 101
+#define CAM_CC_PLL8 102
+#define CAM_CC_PLL8_OUT_EVEN 103
+#define CAM_CC_QDSS_DEBUG_CLK 104
+#define CAM_CC_QDSS_DEBUG_CLK_SRC 105
+#define CAM_CC_QDSS_DEBUG_XO_CLK 106
+#define CAM_CC_SLEEP_CLK 107
+#define CAM_CC_SLOW_AHB_CLK_SRC 108
+#define CAM_CC_SQPF_AHB_CLK 109
+#define CAM_CC_SQPF_CLK 110
+#define CAM_CC_SQPF_CLK_SRC 111
+#define CAM_CC_SQPF_FAST_AHB_CLK 112
+#define CAM_CC_TFE_0_BAYER_CLK 113
+#define CAM_CC_TFE_0_BAYER_FAST_AHB_CLK 114
+#define CAM_CC_TFE_0_CLK_SRC 115
+#define CAM_CC_TFE_0_MAIN_CLK 116
+#define CAM_CC_TFE_0_MAIN_FAST_AHB_CLK 117
+#define CAM_CC_TFE_1_BAYER_CLK 118
+#define CAM_CC_TFE_1_BAYER_FAST_AHB_CLK 119
+#define CAM_CC_TFE_1_CLK_SRC 120
+#define CAM_CC_TFE_1_MAIN_CLK 121
+#define CAM_CC_TFE_1_MAIN_FAST_AHB_CLK 122
+#define CAM_CC_TFE_2_BAYER_CLK 123
+#define CAM_CC_TFE_2_BAYER_FAST_AHB_CLK 124
+#define CAM_CC_TFE_2_CLK_SRC 125
+#define CAM_CC_TFE_2_MAIN_CLK 126
+#define CAM_CC_TFE_2_MAIN_FAST_AHB_CLK 127
+#define CAM_CC_TITAN_CAMNOC_XO_CLK 128
+#define CAM_CC_TITAN_MNOC_HF_CLK 129
+#define CAM_CC_TITAN_MNOC_SF_CLK 130
+#define CAM_CC_TRACENOC_TPDM_1_CMB_CLK 131
+#define CAM_CC_XO_CLK_SRC 132
+
+/* CAM_CC power domains */
+#define CAM_CC_IPE_0_GDSC 0
+#define CAM_CC_OFE_GDSC 1
+#define CAM_CC_SQPF_GDSC 2
+#define CAM_CC_TFE_0_GDSC 3
+#define CAM_CC_TFE_1_GDSC 4
+#define CAM_CC_TFE_2_GDSC 5
+#define CAM_CC_TITAN_TOP_CX_GDSC 6
+#define CAM_CC_TITAN_TOP_GDSC 7
+
+/* CAM_CC resets */
+#define CAM_CC_DRV_BCR 0
+#define CAM_CC_ICP_BCR 1
+#define CAM_CC_IPE_0_BCR 2
+#define CAM_CC_OFE_BCR 3
+#define CAM_CC_QDSS_DEBUG_BCR 4
+#define CAM_CC_SQPF_BCR 5
+#define CAM_CC_TFE_0_BCR 6
+#define CAM_CC_TFE_1_BCR 7
+#define CAM_CC_TFE_2_BCR 8
+
+#endif
diff --git a/include/dt-bindings/clock/qcom,hawi-gpucc.h b/include/dt-bindings/clock/qcom,hawi-gpucc.h
new file mode 100644
index 000000000000..181534771b10
--- /dev/null
+++ b/include/dt-bindings/clock/qcom,hawi-gpucc.h
@@ -0,0 +1,47 @@
+/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */
+/*
+ * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
+ */
+
+#ifndef _DT_BINDINGS_CLK_QCOM_GPU_CC_HAWI_H
+#define _DT_BINDINGS_CLK_QCOM_GPU_CC_HAWI_H
+
+/* GPU_CC clocks */
+#define GPU_CC_AHB_CLK 0
+#define GPU_CC_CB_CLK 1
+#define GPU_CC_CX_ACCU_SHIFT_CLK 2
+#define GPU_CC_CX_GMU_CLK 3
+#define GPU_CC_CXO_AON_CLK 4
+#define GPU_CC_CXO_CLK 5
+#define GPU_CC_DEMET_CLK 6
+#define GPU_CC_DPM_CLK 7
+#define GPU_CC_FREQ_MEASURE_CLK 8
+#define GPU_CC_GMU_CLK_SRC 9
+#define GPU_CC_GPU_SMMU_VOTE_CLK 10
+#define GPU_CC_GX_ACCU_SHIFT_CLK 11
+#define GPU_CC_HUB_AON_CLK 12
+#define GPU_CC_HUB_CLK_SRC 13
+#define GPU_CC_HUB_CX_INT_CLK 14
+#define GPU_CC_HUB_DIV_CLK_SRC 15
+#define GPU_CC_MEMNOC_GFX_CLK 16
+#define GPU_CC_MXG_AHB_CLK 17
+#define GPU_CC_MXG_XO_CLK 18
+#define GPU_CC_PLL0 19
+#define GPU_CC_RSCC_HUB_AON_CLK 20
+#define GPU_CC_RSCC_XO_AON_CLK 21
+#define GPU_CC_SLEEP_CLK 22
+
+/* GPU_CC power domains */
+#define GPU_CC_CX_GDSC 0
+#define GPU_CC_MXG_GDSC 1
+
+/* GPU_CC resets */
+#define GPU_CC_CB_BCR 0
+#define GPU_CC_CX_BCR 1
+#define GPU_CC_FAST_HUB_BCR 2
+#define GPU_CC_GMU_BCR 3
+#define GPU_CC_GX_BCR 4
+#define GPU_CC_MXG_BCR 5
+#define GPU_CC_XO_BCR 6
+
+#endif
diff --git a/include/dt-bindings/clock/qcom,nord-camcc.h b/include/dt-bindings/clock/qcom,nord-camcc.h
new file mode 100644
index 000000000000..655fef2084a5
--- /dev/null
+++ b/include/dt-bindings/clock/qcom,nord-camcc.h
@@ -0,0 +1,167 @@
+/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */
+/*
+ * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
+ */
+
+#ifndef _DT_BINDINGS_CLK_QCOM_CAM_CC_NORD_H
+#define _DT_BINDINGS_CLK_QCOM_CAM_CC_NORD_H
+
+/* CAM_CC clocks */
+#define CAM_CC_CAMNOC_DCD_XO_CLK 0
+#define CAM_CC_CAMNOC_NRT_AXI_CLK 1
+#define CAM_CC_CAMNOC_RT_AXI_CLK 2
+#define CAM_CC_CAMNOC_RT_AXI_CLK_SRC 3
+#define CAM_CC_CAMNOC_XO_CLK 4
+#define CAM_CC_CCI_0_CLK 5
+#define CAM_CC_CCI_0_CLK_SRC 6
+#define CAM_CC_CCI_1_CLK 7
+#define CAM_CC_CCI_1_CLK_SRC 8
+#define CAM_CC_CCI_2_CLK 9
+#define CAM_CC_CCI_2_CLK_SRC 10
+#define CAM_CC_CCI_3_CLK 11
+#define CAM_CC_CCI_3_CLK_SRC 12
+#define CAM_CC_CCI_4_CLK 13
+#define CAM_CC_CCI_4_CLK_SRC 14
+#define CAM_CC_CCU_FAST_AHB_CLK 15
+#define CAM_CC_CORE_AHB_CLK 16
+#define CAM_CC_CPHY_RX_CLK_SRC 17
+#define CAM_CC_CSI0PHYTIMER_CLK 18
+#define CAM_CC_CSI0PHYTIMER_CLK_SRC 19
+#define CAM_CC_CSI1PHYTIMER_CLK 20
+#define CAM_CC_CSI1PHYTIMER_CLK_SRC 21
+#define CAM_CC_CSI2PHYTIMER_CLK 22
+#define CAM_CC_CSI2PHYTIMER_CLK_SRC 23
+#define CAM_CC_CSI3PHYTIMER_CLK 24
+#define CAM_CC_CSI3PHYTIMER_CLK_SRC 25
+#define CAM_CC_CSI4PHYTIMER_CLK 26
+#define CAM_CC_CSI4PHYTIMER_CLK_SRC 27
+#define CAM_CC_CSID_CLK 28
+#define CAM_CC_CSID_CLK_SRC 29
+#define CAM_CC_CSID_CSIPHY_RX_CLK 30
+#define CAM_CC_CSIPHY0_CLK 31
+#define CAM_CC_CSIPHY1_CLK 32
+#define CAM_CC_CSIPHY2_CLK 33
+#define CAM_CC_CSIPHY3_CLK 34
+#define CAM_CC_CSIPHY4_CLK 35
+#define CAM_CC_FAST_AHB_CLK_SRC 36
+#define CAM_CC_GDSC_CLK 37
+#define CAM_CC_ICP_0_AHB_CLK 38
+#define CAM_CC_ICP_0_CLK 39
+#define CAM_CC_ICP_0_CLK_SRC 40
+#define CAM_CC_ICP_1_AHB_CLK 41
+#define CAM_CC_ICP_1_CLK 42
+#define CAM_CC_ICP_1_CLK_SRC 43
+#define CAM_CC_IFE_0_MAIN_CLK 44
+#define CAM_CC_IFE_0_MAIN_CLK_SRC 45
+#define CAM_CC_IFE_0_MAIN_FAST_AHB_CLK 46
+#define CAM_CC_IFE_0_PCP_CLK 47
+#define CAM_CC_IFE_0_PCP_FAST_AHB_CLK 48
+#define CAM_CC_IFE_0_SCALAR_CLK 49
+#define CAM_CC_IFE_0_SCALAR_FAST_AHB_CLK 50
+#define CAM_CC_IFE_0_TMC_CLK 51
+#define CAM_CC_IFE_0_TMC_FAST_AHB_CLK 52
+#define CAM_CC_IFE_1_MAIN_CLK 53
+#define CAM_CC_IFE_1_MAIN_CLK_SRC 54
+#define CAM_CC_IFE_1_MAIN_FAST_AHB_CLK 55
+#define CAM_CC_IFE_1_PCP_CLK 56
+#define CAM_CC_IFE_1_PCP_FAST_AHB_CLK 57
+#define CAM_CC_IFE_1_SCALAR_CLK 58
+#define CAM_CC_IFE_1_SCALAR_FAST_AHB_CLK 59
+#define CAM_CC_IFE_1_TMC_CLK 60
+#define CAM_CC_IFE_1_TMC_FAST_AHB_CLK 61
+#define CAM_CC_IFE_2_MAIN_CLK 62
+#define CAM_CC_IFE_2_MAIN_CLK_SRC 63
+#define CAM_CC_IFE_2_MAIN_FAST_AHB_CLK 64
+#define CAM_CC_IFE_2_PCP_CLK 65
+#define CAM_CC_IFE_2_PCP_FAST_AHB_CLK 66
+#define CAM_CC_IFE_2_SCALAR_CLK 67
+#define CAM_CC_IFE_2_SCALAR_FAST_AHB_CLK 68
+#define CAM_CC_IFE_2_TMC_CLK 69
+#define CAM_CC_IFE_2_TMC_FAST_AHB_CLK 70
+#define CAM_CC_IFE_LITE_AHB_CLK 71
+#define CAM_CC_IFE_LITE_CLK 72
+#define CAM_CC_IFE_LITE_CLK_SRC 73
+#define CAM_CC_IFE_LITE_CPHY_RX_CLK 74
+#define CAM_CC_IFE_LITE_CSID_CLK 75
+#define CAM_CC_IFE_LITE_CSID_CLK_SRC 76
+#define CAM_CC_IPE_0_AHB_CLK 77
+#define CAM_CC_IPE_0_CLK 78
+#define CAM_CC_IPE_0_CLK_SRC 79
+#define CAM_CC_IPE_0_FAST_AHB_CLK 80
+#define CAM_CC_IPE_1_AHB_CLK 81
+#define CAM_CC_IPE_1_CLK 82
+#define CAM_CC_IPE_1_CLK_SRC 83
+#define CAM_CC_IPE_1_FAST_AHB_CLK 84
+#define CAM_CC_PLL0 85
+#define CAM_CC_PLL0_OUT_EVEN 86
+#define CAM_CC_PLL0_OUT_ODD 87
+#define CAM_CC_PLL2 88
+#define CAM_CC_PLL2_OUT_EVEN 89
+#define CAM_CC_PLL3 90
+#define CAM_CC_PLL3_OUT_EVEN 91
+#define CAM_CC_PLL4 92
+#define CAM_CC_PLL4_OUT_EVEN 93
+#define CAM_CC_PLL5 94
+#define CAM_CC_PLL5_OUT_EVEN 95
+#define CAM_CC_PLL6 96
+#define CAM_CC_PLL6_OUT_EVEN 97
+#define CAM_CC_QDSS_DEBUG_CLK 98
+#define CAM_CC_QDSS_DEBUG_CLK_SRC 99
+#define CAM_CC_QDSS_DEBUG_XO_CLK 100
+#define CAM_CC_QUP_AHBM_CLK 101
+#define CAM_CC_QUP_AHBM_CLK_SRC 102
+#define CAM_CC_QUP_CORE_2X_CLK 103
+#define CAM_CC_QUP_CORE_2X_CLK_SRC 104
+#define CAM_CC_QUP_CORE_2X_DIV_CLK_SRC 105
+#define CAM_CC_QUP_CORE_CLK 106
+#define CAM_CC_QUP_SE_CLK 107
+#define CAM_CC_QUP_SE_CLK_SRC 108
+#define CAM_CC_QUP_SLEEP_CLK 109
+#define CAM_CC_SFE_LITE_0_CLK 110
+#define CAM_CC_SFE_LITE_0_FAST_AHB_CLK 111
+#define CAM_CC_SFE_LITE_1_CLK 112
+#define CAM_CC_SFE_LITE_1_FAST_AHB_CLK 113
+#define CAM_CC_SFE_LITE_2_CLK 114
+#define CAM_CC_SFE_LITE_2_FAST_AHB_CLK 115
+#define CAM_CC_SLEEP_CLK 116
+#define CAM_CC_SLEEP_CLK_SRC 117
+#define CAM_CC_SLOW_AHB_CLK_SRC 118
+#define CAM_CC_SM_OBS_CLK 119
+#define CAM_CC_TOP_AHB_CLK 120
+#define CAM_CC_TOP_FAST_AHB_CLK 121
+#define CAM_CC_TOP_IFE_0_CLK 122
+#define CAM_CC_TOP_IFE_1_CLK 123
+#define CAM_CC_TOP_IFE_2_CLK 124
+#define CAM_CC_TOP_IFE_LITE_CLK 125
+#define CAM_CC_TOP_IPE_0_CLK 126
+#define CAM_CC_TOP_IPE_1_CLK 127
+#define CAM_CC_TOP_QUP_AHBM_CLK 128
+#define CAM_CC_TOP_SFE_LITE_0_CLK 129
+#define CAM_CC_TOP_SFE_LITE_1_CLK 130
+#define CAM_CC_TOP_SFE_LITE_2_CLK 131
+#define CAM_CC_TPG_CSIPHY_RX_CLK 132
+#define CAM_CC_XO_CLK_SRC 133
+
+/* CAM_CC power domains */
+#define CAM_CC_IFE_0_GDSC 0
+#define CAM_CC_IFE_1_GDSC 1
+#define CAM_CC_IFE_2_GDSC 2
+#define CAM_CC_IPE_0_GDSC 3
+#define CAM_CC_IPE_1_GDSC 4
+#define CAM_CC_TITAN_TOP_GDSC 5
+
+/* CAM_CC resets */
+#define CAM_CC_CCU_BCR 0
+#define CAM_CC_ICP_0_BCR 1
+#define CAM_CC_ICP_1_BCR 2
+#define CAM_CC_IFE_0_BCR 3
+#define CAM_CC_IFE_1_BCR 4
+#define CAM_CC_IFE_2_BCR 5
+#define CAM_CC_IPE_0_BCR 6
+#define CAM_CC_IPE_1_BCR 7
+#define CAM_CC_QDSS_DEBUG_BCR 8
+#define CAM_CC_SFE_LITE_0_BCR 9
+#define CAM_CC_SFE_LITE_1_BCR 10
+#define CAM_CC_SFE_LITE_2_BCR 11
+
+#endif
diff --git a/include/dt-bindings/clock/qcom,nord-nwgcc.h b/include/dt-bindings/clock/qcom,nord-nwgcc.h
index b6253dd2aa85..8beaa129aa81 100644
--- a/include/dt-bindings/clock/qcom,nord-nwgcc.h
+++ b/include/dt-bindings/clock/qcom,nord-nwgcc.h
@@ -65,5 +65,8 @@
#define NW_GCC_GPU_2_BCR 6
#define NW_GCC_GPU_BCR 7
#define NW_GCC_VIDEO_BCR 8
+#define NW_GCC_VIDEO_AXI0_CLK_ARES 9
+#define NW_GCC_VIDEO_AXI0C_CLK_ARES 10
+#define NW_GCC_VIDEO_AXI1_CLK_ARES 11
#endif
diff --git a/include/dt-bindings/clock/renesas,r8a774a3-cpg-mssr.h b/include/dt-bindings/clock/renesas,r8a774a3-cpg-mssr.h
new file mode 100644
index 000000000000..09121a30e066
--- /dev/null
+++ b/include/dt-bindings/clock/renesas,r8a774a3-cpg-mssr.h
@@ -0,0 +1,59 @@
+/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */
+/*
+ * Copyright (C) 2026 Renesas Electronics Corp.
+ */
+#ifndef __DT_BINDINGS_CLOCK_RENESAS_R8A774A3_CPG_MSSR_H__
+#define __DT_BINDINGS_CLOCK_RENESAS_R8A774A3_CPG_MSSR_H__
+
+#include <dt-bindings/clock/renesas-cpg-mssr.h>
+
+/* r8a774a3 CPG Core Clocks */
+#define R8A774A3_CLK_Z 0
+#define R8A774A3_CLK_Z2 1
+#define R8A774A3_CLK_ZG 2
+#define R8A774A3_CLK_ZTR 3
+#define R8A774A3_CLK_ZTRD2 4
+#define R8A774A3_CLK_ZT 5
+#define R8A774A3_CLK_ZX 6
+#define R8A774A3_CLK_S0D1 7
+#define R8A774A3_CLK_S0D2 8
+#define R8A774A3_CLK_S0D3 9
+#define R8A774A3_CLK_S0D4 10
+#define R8A774A3_CLK_S0D6 11
+#define R8A774A3_CLK_S0D8 12
+#define R8A774A3_CLK_S0D12 13
+#define R8A774A3_CLK_S1D2 14
+#define R8A774A3_CLK_S1D4 15
+#define R8A774A3_CLK_S2D1 16
+#define R8A774A3_CLK_S2D2 17
+#define R8A774A3_CLK_S2D4 18
+#define R8A774A3_CLK_S3D1 19
+#define R8A774A3_CLK_S3D2 20
+#define R8A774A3_CLK_S3D4 21
+#define R8A774A3_CLK_LB 22
+#define R8A774A3_CLK_CL 23
+#define R8A774A3_CLK_ZB3 24
+#define R8A774A3_CLK_ZB3D2 25
+#define R8A774A3_CLK_ZB3D4 26
+#define R8A774A3_CLK_CR 27
+#define R8A774A3_CLK_CRD2 28
+#define R8A774A3_CLK_SD0H 29
+#define R8A774A3_CLK_SD0 30
+#define R8A774A3_CLK_SD1H 31
+#define R8A774A3_CLK_SD1 32
+#define R8A774A3_CLK_SD2H 33
+#define R8A774A3_CLK_SD2 34
+#define R8A774A3_CLK_SD3H 35
+#define R8A774A3_CLK_SD3 36
+#define R8A774A3_CLK_RPC 37
+#define R8A774A3_CLK_RPCD2 38
+#define R8A774A3_CLK_MSO 39
+#define R8A774A3_CLK_CANFD 40
+#define R8A774A3_CLK_HDMI 41
+#define R8A774A3_CLK_CSI0 42
+#define R8A774A3_CLK_CP 43
+#define R8A774A3_CLK_CPEX 44
+#define R8A774A3_CLK_R 45
+#define R8A774A3_CLK_OSC 46
+
+#endif /* __DT_BINDINGS_CLOCK_RENESAS_R8A774A3_CPG_MSSR_H__ */
diff --git a/include/dt-bindings/clock/renesas,r8a78000-cpg.h b/include/dt-bindings/clock/renesas,r8a78000-cpg.h
index 7fd09a3fb353..14b3885f2d99 100644
--- a/include/dt-bindings/clock/renesas,r8a78000-cpg.h
+++ b/include/dt-bindings/clock/renesas,r8a78000-cpg.h
@@ -10,5 +10,7 @@
#define R8A78000_CPG_SGASYNCD4_PERW_BUS 0
#define R8A78000_CPG_SGASYNCD8_PERW_BUS 1
#define R8A78000_CPG_SGASYNCD16_PERW_BUS 2
+#define R8A78000_CPG_MSO_SCP_MAIN 3
+#define R8A78000_CPG_MSOCK_PERW_BUS 4
#endif /* __DT_BINDINGS_CLOCK_RENESAS_R8A78000_CPG_H__ */
diff --git a/include/dt-bindings/clock/starfive,jhb100-crg.h b/include/dt-bindings/clock/starfive,jhb100-crg.h
new file mode 100644
index 000000000000..4270bfa532e8
--- /dev/null
+++ b/include/dt-bindings/clock/starfive,jhb100-crg.h
@@ -0,0 +1,554 @@
+/* SPDX-License-Identifier: GPL-2.0 OR MIT */
+/*
+ * Copyright (C) 2024 StarFive Technology Co., Ltd.
+ * Author: Changhuang Liang <changhuang.liang@starfivetech.com>
+ *
+ */
+
+#ifndef __DT_BINDINGS_CLOCK_STARFIVE_JHB100_H__
+#define __DT_BINDINGS_CLOCK_STARFIVE_JHB100_H__
+
+/* SYS0PLL clocks */
+#define JHB100_SYS0PLL_PLL2_OUT 0
+#define JHB100_SYS0PLL_PLL3_OUT 1
+#define JHB100_SYS0PLL_PLL4_OUT 2
+#define JHB100_SYS0PLL_PLL5_OUT 3
+
+/* PER0PLL clocks */
+#define JHB100_PER0PLL_PLL6_OUT 0
+
+/* PER1PLL clocks */
+#define JHB100_PER1PLL_PLL7_OUT 0
+
+/* SYS0CRG clocks */
+#define JHB100_SYS0CLK_BMCPCIERP_NCNOC_MAIN 17
+#define JHB100_SYS0CLK_BMCPCIERP_NCNOC_CFG 18
+
+#define JHB100_SYS0CLK_PCIE_REF_CML 20
+#define JHB100_SYS0CLK_BMCPCIERP_NCNOC_DATA_INIT 21
+#define JHB100_SYS0CLK_BMCPCIERP_NCNOC_CFG_INIT 22
+#define JHB100_SYS0CLK_BMCPCIERP_NCNOC_TARG 23
+
+#define JHB100_SYS0CLK_BMCPCIERP_PCU 26
+#define JHB100_SYS0CLK_HOSTSS0_NCNOC_CFG 27
+#define JHB100_SYS0CLK_HOSTSS0_NCNOC_DATA 28
+#define JHB100_SYS0CLK_HOSTSS0_PHY_SCAN_400 29
+#define JHB100_SYS0CLK_GPIO_ESPI0_EXT 30
+
+#define JHB100_SYS0CLK_BMCUSB_NCNOC_INIT 34
+#define JHB100_SYS0CLK_BMCUSB_NCNOC_TARG 35
+#define JHB100_SYS0CLK_BMCUSB_SCANCLK 36
+#define JHB100_SYS0CLK_BMCUSB_480M_SCANCLK 37
+
+#define JHB100_SYS0CLK_VCE_NCNOC_INIT 50
+#define JHB100_SYS0CLK_VCE_NCNOC_TARG 51
+#define JHB100_SYS0CLK_BMCPER2_NCNOC_INIT 52
+#define JHB100_SYS0CLK_BMCPER2_NCNOC_TARG 53
+#define JHB100_SYS0CLK_BMCPER2_CFG_400 54
+#define JHB100_SYS0CLK_BMCPER2_CFG_125 55
+
+#define JHB100_SYS0CLK_HOSTSS1_NCNOC_DATA 58
+#define JHB100_SYS0CLK_HOSTSS1_PHY_SCAN_400 59
+#define JHB100_SYS0CLK_HOSTSS1_PHY_SCAN_400_ICG_BUF 60
+#define JHB100_SYS0CLK_NPU_NCNOC_INIT 61
+#define JHB100_SYS0CLK_VOUT_NCNOC_INIT 62
+#define JHB100_SYS0CLK_VOUT_AUX 63
+
+#define JHB100_SYS0CLK_BMCPER3_NCNOC_INIT 65
+#define JHB100_SYS0CLK_HOSTUSB_NCNOC_INIT 66
+#define JHB100_SYS0CLK_HOSTUSBCMN_CFG_480 67
+#define JHB100_SYS0CLK_BMCPER1_NCNOC_INIT 68
+#define JHB100_SYS0CLK_BMCPER1_CFG_800 69
+#define JHB100_SYS0CLK_BMCPER0_NCNOC_INIT 70
+#define JHB100_SYS0CLK_BMCPER0_CFG_400 71
+#define JHB100_SYS0CLK_BMCPER0_CFG_800 72
+#define JHB100_SYS0CLK_GPU0_NCNOC_INIT 73
+#define JHB100_SYS0CLK_GPU1_NCNOC_INIT 74
+
+/* SYS1CRG clocks */
+#define JHB100_SYS1CLK_APB_MAIN_SYS1 0
+#define JHB100_SYS1CLK_APB_SENSOR_ICG_BUF 1
+
+#define JHB100_SYS1CLK_GPIO_ESPI1_EXT 5
+
+#define JHB100_SYS1CLK_HOSTSS1_NCNOC_CFG 7
+#define JHB100_SYS1CLK_HOSTSS1_PHY_SCAN_1000_ICG_BUF 8
+#define JHB100_SYS1CLK_NPU_NCNOC_CFG 9
+#define JHB100_SYS1CLK_NPU_CORE_DIV 10
+#define JHB100_SYS1CLK_DOM_NPU_CORE_CLK 11
+#define JHB100_SYS1CLK_DOM_NPU_BUS_CLK 12
+#define JHB100_SYS1CLK_DOM_NPU_INIT_CLK 13
+#define JHB100_SYS1CLK_DOM_NPU_OSC_CLK 14
+#define JHB100_SYS1CLK_VOUT_NCNOC_TARG 15
+#define JHB100_SYS1CLK_VOUT_PIX0 16
+#define JHB100_SYS1CLK_VOUT_PIX1 17
+#define JHB100_SYS1CLK_BMCPER3_NCNOC_TARG 18
+#define JHB100_SYS1CLK_BMCPER3_CFG_125 19
+
+/* SYS2CRG clocks */
+#define JHB100_SYS2CLK_JTAGM0_HCLK 3
+#define JHB100_SYS2CLK_JTAGM1_HCLK 4
+#define JHB100_SYS2CLK_JTAGM0_ATPG 5
+#define JHB100_SYS2CLK_JTAGM1_ATPG 6
+#define JHB100_SYS2CLK_JTAGM0_ATPG_TCLOCK 7
+#define JHB100_SYS2CLK_JTAGM1_ATPG_TCLOCK 8
+#define JHB100_SYS2CLK_JTAG0_MST_WRAP_HCLK 9
+#define JHB100_SYS2CLK_JTAG0_MST_WRAP_CLK_JTAG 10
+#define JHB100_SYS2CLK_JTAG0_MST_WRAP_APB_PCLK 11
+#define JHB100_SYS2CLK_JTAG0_MST_WRAP_ATPG_TCLOCK 12
+#define JHB100_SYS2CLK_JTAG1_MST_WRAP_HCLK 13
+#define JHB100_SYS2CLK_JTAG1_MST_WRAP_CLK_JTAG 14
+#define JHB100_SYS2CLK_JTAG1_MST_WRAP_APB_PCLK 15
+#define JHB100_SYS2CLK_JTAG1_MST_WRAP_ATPG_TCLOCK 16
+#define JHB100_SYS2CLK_HOSTUSB_NCNOC_TARG 17
+#define JHB100_SYS2CLK_HOSTUSBCMN_CFG_500 18
+#define JHB100_SYS2CLK_BMCPER1_NCNOC_TARG 19
+#define JHB100_SYS2CLK_BMCPER1_CFG_250 20
+#define JHB100_SYS2CLK_BMCPER1_CFG_143_DFT 21
+#define JHB100_SYS2CLK_BMCPER1_CFG_143 22
+#define JHB100_SYS2CLK_BMCPER0_NCNOC_TARG 23
+#define JHB100_SYS2CLK_GPU0_NCNOC_TARG 24
+#define JHB100_SYS2CLK_GPU0_BUS_CLK 25
+#define JHB100_SYS2CLK_GPU0_APB_CLK 26
+#define JHB100_SYS2CLK_GPU0_OSC_CLK 27
+#define JHB100_SYS2CLK_GPU1_NCNOC_TARG 28
+#define JHB100_SYS2CLK_GPU1_BUS_CLK 29
+#define JHB100_SYS2CLK_GPU1_APB_CLK 30
+#define JHB100_SYS2CLK_GPU1_OSC_CLK 31
+#define JHB100_SYS2CLK_MAIN_ICG_EN_JTAG0 32
+#define JHB100_SYS2CLK_MAIN_ICG_EN_JTAG1 33
+
+/* PER0CRG clocks */
+#define JHB100_PER0CLK_CDR_I3C0 0
+#define JHB100_PER0CLK_CDR_I3C1 1
+#define JHB100_PER0CLK_CDR_I3C2 2
+#define JHB100_PER0CLK_CDR_I3C3 3
+#define JHB100_PER0CLK_CDR_I3C4 4
+#define JHB100_PER0CLK_CDR_I3C5 5
+#define JHB100_PER0CLK_CDR_I3C6 6
+#define JHB100_PER0CLK_CDR_I3C7 7
+#define JHB100_PER0CLK_CDR_I3C8 8
+#define JHB100_PER0CLK_CDR_I3C9 9
+#define JHB100_PER0CLK_CDR_I3C10 10
+#define JHB100_PER0CLK_CDR_I3C11 11
+#define JHB100_PER0CLK_CDR_I3C12 12
+#define JHB100_PER0CLK_CDR_I3C13 13
+#define JHB100_PER0CLK_CDR_I3C14 14
+#define JHB100_PER0CLK_CDR_I3C15 15
+#define JHB100_PER0CLK_200 16
+#define JHB100_PER0CLK_600_DIV6 17
+#define JHB100_PER0CLK_600_DIV6_DIV5 18
+#define JHB100_PER0CLK_TIMER0_DUALTIMER0 19
+#define JHB100_PER0CLK_TIMER1_DUALTIMER0 20
+#define JHB100_PER0CLK_TIMER0_DUALTIMER1 21
+#define JHB100_PER0CLK_TIMER1_DUALTIMER1 22
+#define JHB100_PER0CLK_TIMER0_DUALTIMER2 23
+#define JHB100_PER0CLK_TIMER1_DUALTIMER2 24
+#define JHB100_PER0CLK_1200_PH0_LVDS0 25
+#define JHB100_PER0CLK_1200_PH0_LVDS1 26
+#define JHB100_PER0CLK_1200_CORE0 27
+#define JHB100_PER0CLK_1200_CORE1 28
+#define JHB100_PER0CLK_1200_SHIFT90_LVDS0 29
+#define JHB100_PER0CLK_1200_SHIFT90_LVDS1 30
+#define JHB100_PER0CLK_1200_DIV5_CORE0 31
+#define JHB100_PER0CLK_1200_DIV5_CORE1 32
+#define JHB100_PER0CLK_PH0_LTPI0 33
+
+#define JHB100_PER0CLK_PH0_LTPI1 35
+
+#define JHB100_PER0CLK_PH90_LTPI0 37
+
+#define JHB100_PER0CLK_PH90_LTPI1 39
+
+#define JHB100_PER0CLK_240_CORE_LTPI0 41
+
+#define JHB100_PER0CLK_240_CORE_LTPI1 43
+
+#define JHB100_PER0CLK_AXI_DMA_I2C_INIT 45
+#define JHB100_PER0CLK_AXI_DMA_I3C_INIT 46
+#define JHB100_PER0CLK_AXI_DMA_UART_INIT 47
+#define JHB100_PER0CLK_CORE_DMAC0 48
+#define JHB100_PER0CLK_CORE_DMAC1 49
+#define JHB100_PER0CLK_CORE_DMAC2 50
+
+#define JHB100_PER0CLK_HDR_TX_I3C0 78
+#define JHB100_PER0CLK_HDR_TX_I3C1 79
+#define JHB100_PER0CLK_HDR_TX_I3C2 80
+#define JHB100_PER0CLK_HDR_TX_I3C3 81
+#define JHB100_PER0CLK_HDR_TX_I3C4 82
+#define JHB100_PER0CLK_HDR_TX_I3C5 83
+#define JHB100_PER0CLK_HDR_TX_I3C6 84
+#define JHB100_PER0CLK_HDR_TX_I3C7 85
+#define JHB100_PER0CLK_HDR_TX_I3C8 86
+#define JHB100_PER0CLK_HDR_TX_I3C9 87
+#define JHB100_PER0CLK_HDR_TX_I3C10 88
+#define JHB100_PER0CLK_HDR_TX_I3C11 89
+#define JHB100_PER0CLK_HDR_TX_I3C12 90
+#define JHB100_PER0CLK_HDR_TX_I3C13 91
+#define JHB100_PER0CLK_HDR_TX_I3C14 92
+#define JHB100_PER0CLK_HDR_TX_I3C15 93
+#define JHB100_PER0CLK_CORE_I2C0 94
+#define JHB100_PER0CLK_CORE_I2C1 95
+#define JHB100_PER0CLK_CORE_I2C2 96
+#define JHB100_PER0CLK_CORE_I2C3 97
+#define JHB100_PER0CLK_CORE_I2C4 98
+#define JHB100_PER0CLK_CORE_I2C5 99
+#define JHB100_PER0CLK_CORE_I2C6 100
+#define JHB100_PER0CLK_CORE_I2C7 101
+#define JHB100_PER0CLK_CORE_I2C8 102
+#define JHB100_PER0CLK_CORE_I2C9 103
+#define JHB100_PER0CLK_CORE_I2C10 104
+#define JHB100_PER0CLK_CORE_I2C11 105
+#define JHB100_PER0CLK_CORE_I2C12 106
+#define JHB100_PER0CLK_CORE_I2C13 107
+#define JHB100_PER0CLK_CORE_I2C14 108
+#define JHB100_PER0CLK_CORE_I2C15 109
+
+#define JHB100_PER0CLK_WDOGCLK_WDT0 126
+#define JHB100_PER0CLK_WDOGCLK_WDT1 127
+#define JHB100_PER0CLK_WDOGCLK_WDT2 128
+#define JHB100_PER0CLK_WDOGCLK_WDT3 129
+#define JHB100_PER0CLK_WDOGCLK_WDT_EXTERNAL 130
+#define JHB100_PER0CLK_SCLK_UART4 131
+#define JHB100_PER0CLK_SCLK_UART5 132
+#define JHB100_PER0CLK_SCLK_UART6 133
+#define JHB100_PER0CLK_SCLK_UART7 134
+#define JHB100_PER0CLK_SCLK_UART8 135
+#define JHB100_PER0CLK_SCLK_UART9 136
+#define JHB100_PER0CLK_SCLK_UART10 137
+#define JHB100_PER0CLK_SCLK_UART11 138
+#define JHB100_PER0CLK_SCLK_UART12 139
+#define JHB100_PER0CLK_SCLK_UART13 140
+#define JHB100_PER0CLK_SCLK_UART14 141
+
+#define JHB100_PER0CLK_PCLK_DMA_UART_CFG 148
+#define JHB100_PER0CLK_PCLK_DMA_I2C_CFG 149
+#define JHB100_PER0CLK_PCLK_DMA_I3C_CFG 150
+#define JHB100_PER0CLK_PCLK_DUALTIMER0 151
+#define JHB100_PER0CLK_PCLK_DUALTIMER1 152
+#define JHB100_PER0CLK_PCLK_DUALTIMER2 153
+
+#define JHB100_PER0CLK_HCLK_TRNG 156
+#define JHB100_PER0CLK_APB_I2C0 157
+#define JHB100_PER0CLK_APB_I2C1 158
+#define JHB100_PER0CLK_APB_I2C2 159
+#define JHB100_PER0CLK_APB_I2C3 160
+#define JHB100_PER0CLK_APB_I2C4 161
+#define JHB100_PER0CLK_APB_I2C5 162
+#define JHB100_PER0CLK_APB_I2C6 163
+#define JHB100_PER0CLK_APB_I2C7 164
+#define JHB100_PER0CLK_APB_I2C8 165
+#define JHB100_PER0CLK_APB_I2C9 166
+#define JHB100_PER0CLK_APB_I2C10 167
+#define JHB100_PER0CLK_APB_I2C11 168
+#define JHB100_PER0CLK_APB_I2C12 169
+#define JHB100_PER0CLK_APB_I2C13 170
+#define JHB100_PER0CLK_APB_I2C14 171
+#define JHB100_PER0CLK_APB_I2C15 172
+#define JHB100_PER0CLK_APB_I2CF0 173
+#define JHB100_PER0CLK_APB_I2CF1 174
+#define JHB100_PER0CLK_APB_I2CF2 175
+#define JHB100_PER0CLK_APB_I2CF3 176
+#define JHB100_PER0CLK_APB_I2CF4 177
+#define JHB100_PER0CLK_APB_I2CF5 178
+#define JHB100_PER0CLK_APB_I2CF6 179
+#define JHB100_PER0CLK_APB_I2CF7 180
+#define JHB100_PER0CLK_APB_I2CF8 181
+#define JHB100_PER0CLK_APB_I2CF9 182
+#define JHB100_PER0CLK_APB_I2CF10 183
+#define JHB100_PER0CLK_APB_I2CF11 184
+#define JHB100_PER0CLK_APB_I2CF12 185
+#define JHB100_PER0CLK_APB_I2CF13 186
+#define JHB100_PER0CLK_APB_I2CF14 187
+#define JHB100_PER0CLK_APB_I2CF15 188
+#define JHB100_PER0CLK_APB_I3C0 189
+#define JHB100_PER0CLK_APB_I3C1 190
+#define JHB100_PER0CLK_APB_I3C2 191
+#define JHB100_PER0CLK_APB_I3C3 192
+#define JHB100_PER0CLK_APB_I3C4 193
+#define JHB100_PER0CLK_APB_I3C5 194
+#define JHB100_PER0CLK_APB_I3C6 195
+#define JHB100_PER0CLK_APB_I3C7 196
+#define JHB100_PER0CLK_APB_I3C8 197
+#define JHB100_PER0CLK_APB_I3C9 198
+#define JHB100_PER0CLK_APB_I3C10 199
+#define JHB100_PER0CLK_APB_I3C11 200
+#define JHB100_PER0CLK_APB_I3C12 201
+#define JHB100_PER0CLK_APB_I3C13 202
+#define JHB100_PER0CLK_APB_I3C14 203
+#define JHB100_PER0CLK_APB_I3C15 204
+#define JHB100_PER0CLK_APB_UART0 205
+#define JHB100_PER0CLK_APB_UART1 206
+#define JHB100_PER0CLK_APB_UART2 207
+#define JHB100_PER0CLK_APB_UART3 208
+#define JHB100_PER0CLK_APB_UART4 209
+#define JHB100_PER0CLK_APB_UART5 210
+#define JHB100_PER0CLK_APB_UART6 211
+#define JHB100_PER0CLK_APB_UART7 212
+#define JHB100_PER0CLK_APB_UART8 213
+#define JHB100_PER0CLK_APB_UART9 214
+#define JHB100_PER0CLK_APB_UART10 215
+#define JHB100_PER0CLK_APB_UART11 216
+#define JHB100_PER0CLK_APB_UART12 217
+#define JHB100_PER0CLK_APB_UART13 218
+#define JHB100_PER0CLK_APB_UART14 219
+#define JHB100_PER0CLK_DMA_I3C0 220
+#define JHB100_PER0CLK_DMA_I3C1 221
+#define JHB100_PER0CLK_DMA_I3C2 222
+#define JHB100_PER0CLK_DMA_I3C3 223
+#define JHB100_PER0CLK_DMA_I3C4 224
+#define JHB100_PER0CLK_DMA_I3C5 225
+#define JHB100_PER0CLK_DMA_I3C6 226
+#define JHB100_PER0CLK_DMA_I3C7 227
+#define JHB100_PER0CLK_DMA_I3C8 228
+#define JHB100_PER0CLK_DMA_I3C9 229
+#define JHB100_PER0CLK_DMA_I3C10 230
+#define JHB100_PER0CLK_DMA_I3C11 231
+#define JHB100_PER0CLK_DMA_I3C12 232
+#define JHB100_PER0CLK_DMA_I3C13 233
+#define JHB100_PER0CLK_DMA_I3C14 234
+#define JHB100_PER0CLK_DMA_I3C15 235
+#define JHB100_PER0CLK_CORE_I3C0 236
+#define JHB100_PER0CLK_CORE_I3C1 237
+#define JHB100_PER0CLK_CORE_I3C2 238
+#define JHB100_PER0CLK_CORE_I3C3 239
+#define JHB100_PER0CLK_CORE_I3C4 240
+#define JHB100_PER0CLK_CORE_I3C5 241
+#define JHB100_PER0CLK_CORE_I3C6 242
+#define JHB100_PER0CLK_CORE_I3C7 243
+#define JHB100_PER0CLK_CORE_I3C8 244
+#define JHB100_PER0CLK_CORE_I3C9 245
+#define JHB100_PER0CLK_CORE_I3C10 246
+#define JHB100_PER0CLK_CORE_I3C11 247
+#define JHB100_PER0CLK_CORE_I3C12 248
+#define JHB100_PER0CLK_CORE_I3C13 249
+#define JHB100_PER0CLK_CORE_I3C14 250
+#define JHB100_PER0CLK_CORE_I3C15 251
+#define JHB100_PER0CLK_DMAC_AXI_PERIPH0_HS_CLK_I2C 252
+#define JHB100_PER0CLK_MAIN_ICG_EN_I3C0 253
+#define JHB100_PER0CLK_MAIN_ICG_EN_I3C1 254
+#define JHB100_PER0CLK_MAIN_ICG_EN_I3C2 255
+#define JHB100_PER0CLK_MAIN_ICG_EN_I3C3 256
+#define JHB100_PER0CLK_MAIN_ICG_EN_I3C4 257
+#define JHB100_PER0CLK_MAIN_ICG_EN_I3C5 258
+#define JHB100_PER0CLK_MAIN_ICG_EN_I3C6 259
+#define JHB100_PER0CLK_MAIN_ICG_EN_I3C7 260
+#define JHB100_PER0CLK_MAIN_ICG_EN_I3C8 261
+#define JHB100_PER0CLK_MAIN_ICG_EN_I3C9 262
+#define JHB100_PER0CLK_MAIN_ICG_EN_I3C10 263
+#define JHB100_PER0CLK_MAIN_ICG_EN_I3C11 264
+#define JHB100_PER0CLK_MAIN_ICG_EN_I3C12 265
+#define JHB100_PER0CLK_MAIN_ICG_EN_I3C13 266
+#define JHB100_PER0CLK_MAIN_ICG_EN_I3C14 267
+#define JHB100_PER0CLK_MAIN_ICG_EN_I3C15 268
+#define JHB100_PER0CLK_MAIN_ICG_EN_DUALTIMER0 269
+#define JHB100_PER0CLK_MAIN_ICG_EN_DUALTIMER1 270
+#define JHB100_PER0CLK_MAIN_ICG_EN_DUALTIMER2 271
+#define JHB100_PER0CLK_MAIN_ICG_EN_LTPI0 272
+#define JHB100_PER0CLK_MAIN_ICG_EN_LTPI1 273
+#define JHB100_PER0CLK_MAIN_ICG_EN_DMAC_I2C 274
+#define JHB100_PER0CLK_MAIN_ICG_EN_DMAC_I3C 275
+#define JHB100_PER0CLK_MAIN_ICG_EN_DMAC_UART 276
+#define JHB100_PER0CLK_MAIN_ICG_EN_SOL4 277
+#define JHB100_PER0CLK_MAIN_ICG_EN_SOL5 278
+#define JHB100_PER0CLK_MAIN_ICG_EN_SOL6 279
+#define JHB100_PER0CLK_MAIN_ICG_EN_SOL7 280
+#define JHB100_PER0CLK_MAIN_ICG_EN_SOL8 281
+#define JHB100_PER0CLK_MAIN_ICG_EN_SOL9 282
+#define JHB100_PER0CLK_MAIN_ICG_EN_SOL10 283
+#define JHB100_PER0CLK_MAIN_ICG_EN_SOL11 284
+#define JHB100_PER0CLK_MAIN_ICG_EN_SOL12 285
+#define JHB100_PER0CLK_MAIN_ICG_EN_SOL13 286
+#define JHB100_PER0CLK_MAIN_ICG_EN_SOL14 287
+
+#define JHB100_PER0CLK_MAIN_ICG_EN_I2C0 304
+#define JHB100_PER0CLK_MAIN_ICG_EN_I2C1 305
+#define JHB100_PER0CLK_MAIN_ICG_EN_I2C2 306
+#define JHB100_PER0CLK_MAIN_ICG_EN_I2C3 307
+#define JHB100_PER0CLK_MAIN_ICG_EN_I2C4 308
+#define JHB100_PER0CLK_MAIN_ICG_EN_I2C5 309
+#define JHB100_PER0CLK_MAIN_ICG_EN_I2C6 310
+#define JHB100_PER0CLK_MAIN_ICG_EN_I2C7 311
+#define JHB100_PER0CLK_MAIN_ICG_EN_I2C8 312
+#define JHB100_PER0CLK_MAIN_ICG_EN_I2C9 313
+#define JHB100_PER0CLK_MAIN_ICG_EN_I2C10 314
+#define JHB100_PER0CLK_MAIN_ICG_EN_I2C11 315
+#define JHB100_PER0CLK_MAIN_ICG_EN_I2C12 316
+#define JHB100_PER0CLK_MAIN_ICG_EN_I2C13 317
+#define JHB100_PER0CLK_MAIN_ICG_EN_I2C14 318
+#define JHB100_PER0CLK_MAIN_ICG_EN_I2C15 319
+#define JHB100_PER0CLK_MAIN_ICG_EN_WDT0 320
+#define JHB100_PER0CLK_MAIN_ICG_EN_WDT1 321
+#define JHB100_PER0CLK_MAIN_ICG_EN_WDT2 322
+#define JHB100_PER0CLK_MAIN_ICG_EN_WDT3 323
+#define JHB100_PER0CLK_MAIN_ICG_EN_WDT_EXTERNAL 324
+#define JHB100_PER0CLK_MAIN_ICG_EN_UART4 325
+#define JHB100_PER0CLK_MAIN_ICG_EN_UART5 326
+#define JHB100_PER0CLK_MAIN_ICG_EN_UART6 327
+#define JHB100_PER0CLK_MAIN_ICG_EN_UART7 328
+#define JHB100_PER0CLK_MAIN_ICG_EN_UART8 329
+#define JHB100_PER0CLK_MAIN_ICG_EN_UART9 330
+#define JHB100_PER0CLK_MAIN_ICG_EN_UART10 331
+#define JHB100_PER0CLK_MAIN_ICG_EN_UART11 332
+#define JHB100_PER0CLK_MAIN_ICG_EN_UART12 333
+#define JHB100_PER0CLK_MAIN_ICG_EN_UART13 334
+#define JHB100_PER0CLK_MAIN_ICG_EN_UART14 335
+#define JHB100_PER0CLK_MAIN_ICG_EN_LDO0 336
+#define JHB100_PER0CLK_MAIN_ICG_EN_LDO1 337
+#define JHB100_PER0CLK_MAIN_ICG_EN_SENSORS_PERIPH0 338
+#define JHB100_PER0CLK_MAIN_ICG_EN_SENSORS_DMAC 339
+#define JHB100_PER0CLK_MAIN_ICG_EN_TRNG 340
+
+/* PER1CRG clocks */
+#define JHB100_PER1CLK_100 0
+#define JHB100_PER1CLK_1 1
+#define JHB100_PER1CLK_200_DIVN0 2
+#define JHB100_PER1CLK_200_DIVN1 3
+#define JHB100_PER1CLK_200_DIVN2 4
+#define JHB100_PER1CLK_200_DIVN3 5
+#define JHB100_PER1CLK_200_CCLK_DIV 6
+
+#define JHB100_PER1CLK_SGPIO0_PCLK 15
+#define JHB100_PER1CLK_SGPIO0_DCLK 16
+#define JHB100_PER1CLK_SGPIO1_PCLK 17
+#define JHB100_PER1CLK_SGPIO1_DCLK 18
+
+#define JHB100_PER1CLK_EMMC0_BCLK 22
+
+#define JHB100_PER1CLK_EMMC0_CCLK 25
+
+#define JHB100_PER1CLK_DMAC1_1CH_CORE 29
+
+#define JHB100_PER1CLK_DMAC1_1CH_ACLK 31
+
+#define JHB100_PER1CLK_DMAC2_1CH_CORE 33
+
+#define JHB100_PER1CLK_DMAC2_1CH_ACLK 35
+
+#define JHB100_PER1CLK_DMAC3_1CH_CORE 37
+
+#define JHB100_PER1CLK_DMAC3_1CH_ACLK 39
+
+#define JHB100_PER1CLK_DMAC0_2CH_CORE 41
+
+#define JHB100_PER1CLK_DMAC0_2CH_ACLK 43
+
+#define JHB100_PER1CLK_UFS_REF 45
+#define JHB100_PER1CLK_UFS_300 46
+#define JHB100_PER1CLK_UFS_150 47
+#define JHB100_PER1CLK_UFS_400 48
+#define JHB100_PER1CLK_UFS_75 49
+#define JHB100_PER1CLK_UFS_37_5 50
+#define JHB100_PER1CLK_UFS_7_5 51
+#define JHB100_PER1CLK_UFS_1_875 52
+#define JHB100_PER1CLK_UFS_7_143 53
+#define JHB100_PER1CLK_UFS_3_5715 54
+
+#define JHB100_PER1CLK_MAIN_ICG_EN_SFC0 63
+#define JHB100_PER1CLK_MAIN_ICG_EN_SFC1 64
+#define JHB100_PER1CLK_MAIN_ICG_EN_SFC2 65
+#define JHB100_PER1CLK_MAIN_ICG_EN_SPI0 66
+#define JHB100_PER1CLK_MAIN_ICG_EN_SGPIO0 67
+#define JHB100_PER1CLK_MAIN_ICG_EN_SGPIO1 68
+#define JHB100_PER1CLK_MAIN_ICG_EN_SENSORS_PERIPH1 69
+#define JHB100_PER1CLK_MAIN_ICG_EN_EMMC0 70
+#define JHB100_PER1CLK_MAIN_ICG_EN_DMAC_SFC0 71
+#define JHB100_PER1CLK_MAIN_ICG_EN_DMAC_SFC1 72
+#define JHB100_PER1CLK_MAIN_ICG_EN_DMAC_SFC2 73
+#define JHB100_PER1CLK_MAIN_ICG_EN_DMAC_SPI0 74
+#define JHB100_PER1CLK_MAIN_ICG_EN_RAS 75
+#define JHB100_PER1CLK_MAIN_ICG_EN_UFS 76
+
+/* PER2CRG clocks */
+#define JHB100_PER2CLK_300 0
+#define JHB100_PER2CLK_100 1
+#define JHB100_PER2CLK_50 2
+#define JHB100_PER2CLK_GMAC2_RMII_50 3
+#define JHB100_PER2CLK_CAN0_CORE_DIV 4
+#define JHB100_PER2CLK_CAN1_CORE_DIV 5
+#define JHB100_PER2CLK_CAN0_TIMER 6
+#define JHB100_PER2CLK_CAN1_TIMER 7
+
+#define JHB100_PER2CLK_RTC_CORE_DIV 11
+#define JHB100_PER2CLK_GMAC2_RMII_MUX_DLY 12
+#define JHB100_PER2CLK_GMAC2_RMII_DIV 13
+
+#define JHB100_PER2CLK_GMAC2_RGMII_125_MUX 15
+#define JHB100_PER2CLK_GMAC2_RGMII_DIV 16
+#define JHB100_PER2CLK_GMAC2_TX_MUX 17
+#define JHB100_PER2CLK_GMAC2_TX_180_BUF 18
+#define JHB100_PER2CLK_GMAC2_RX_MUX_DLY 19
+#define JHB100_PER2CLK_GMAC2_RX_180_BUF 20
+#define JHB100_PER2CLK_GMAC2_TXCK_MUX_DLY 21
+#define JHB100_PER2CLK_GMAC3_TX_125_MUX 22
+#define JHB100_PER2CLK_GMAC3_RX_125_MUX 23
+#define JHB100_PER2CLK_GMAC3_TX_DIV 24
+#define JHB100_PER2CLK_GMAC3_RX_DIV 25
+#define JHB100_PER2CLK_SENSORS_PERIPH2 26
+
+#define JHB100_PER2CLK_FAN_TACH_PCLK 33
+
+#define JHB100_PER2CLK_ETHER0_RMIIANDRGMII_TX_I 44
+#define JHB100_PER2CLK_ETHER0_RMIIANDRGMII_RX_I 45
+#define JHB100_PER2CLK_ETHER0_RMIIANDRGMII_TX_180_I 46
+#define JHB100_PER2CLK_ETHER0_RMIIANDRGMII_RX_180_I 47
+#define JHB100_PER2CLK_ETHER0_RMIIANDRGMII_PTP_REF_I 48
+#define JHB100_PER2CLK_ETHER0_RMIIANDRGMII_RMII_I 49
+#define JHB100_PER2CLK_ETHER0_RMIIANDRGMII_CSR_I 50
+#define JHB100_PER2CLK_ETHER0_RMIIANDRGMII_ACLK_I 51
+#define JHB100_PER2CLK_RMIIANDRGMII_IOMUX_GMAC2_TXCK 52
+#define JHB100_PER2CLK_ETHER1_SGMII_TX_I 53
+#define JHB100_PER2CLK_ETHER1_SGMII_RX_I 54
+#define JHB100_PER2CLK_ETHER1_SGMII_TX_125_I 55
+#define JHB100_PER2CLK_ETHER1_SGMII_RX_125_I 56
+#define JHB100_PER2CLK_ETHER1_SGMII_PTP_REF_I 57
+#define JHB100_PER2CLK_ETHER1_SGMII_CSR_I 58
+#define JHB100_PER2CLK_ETHER1_SGMII_ACLK_I 59
+#define JHB100_PER2CLK_ETHER1_SGMII_PHY_PCLK_I 60
+#define JHB100_PER2CLK_ETHER1_SGMII_REF_25_I 61
+#define JHB100_PER2CLK_MAIN_ICG_EN_CAN0 62
+#define JHB100_PER2CLK_MAIN_ICG_EN_CAN1 63
+
+#define JHB100_PER2CLK_MAIN_ICG_EN_DMAC_8CH 65
+#define JHB100_PER2CLK_MAIN_ICG_EN_RTC_SCAN 66
+#define JHB100_PER2CLK_MAIN_ICG_EN_ADC0 67
+#define JHB100_PER2CLK_MAIN_ICG_EN_ADC1 68
+#define JHB100_PER2CLK_MAIN_ICG_EN_GMAC2 69
+#define JHB100_PER2CLK_MAIN_ICG_EN_GMAC3 70
+
+/* PER3CRG clocks */
+#define JHB100_PER3CLK_300 0
+#define JHB100_PER3CLK_200 1
+#define JHB100_PER3CLK_GMAC1_PTP_REF 2
+#define JHB100_PER3CLK_GMAC1_TX_125_MUX 3
+#define JHB100_PER3CLK_GMAC1_TX 4
+#define JHB100_PER3CLK_GMAC1_RX_125_MUX 5
+#define JHB100_PER3CLK_GMAC1_RX 6
+#define JHB100_PER3CLK_GMAC0_PTP_REF 7
+#define JHB100_PER3CLK_GMAC0_RMII_PLL 8
+#define JHB100_PER3CLK_GMAC0_RMII_MUX 9
+#define JHB100_PER3CLK_GMAC0_RMII_MUX_DIV2 10
+
+#define JHB100_PER3CLK_ETHER0_RMII_CLK_TX_I 17
+#define JHB100_PER3CLK_ETHER0_RMII_CLK_RX_I 18
+#define JHB100_PER3CLK_ETHER0_RMII_CLK_PTP_REF_I 19
+#define JHB100_PER3CLK_ETHER0_RMII_CLK_RMII_I 20
+#define JHB100_PER3CLK_ETHER0_RMII_CLK_CSR_I 21
+#define JHB100_PER3CLK_ETHER0_RMII_ACLK_I 22
+#define JHB100_PER3CLK_GMAC0_RMII_RCLKO 23
+#define JHB100_PER3CLK_ETHER0_SGMII_CLK_TX_I 24
+#define JHB100_PER3CLK_ETHER0_SGMII_CLK_RX_I 25
+#define JHB100_PER3CLK_ETHER0_SGMII_CLK_TX_125_I 26
+#define JHB100_PER3CLK_ETHER0_SGMII_CLK_RX_125_I 27
+#define JHB100_PER3CLK_ETHER0_SGMII_CLK_PTP_REF_I 28
+#define JHB100_PER3CLK_ETHER0_SGMII_CLK_REF_25_I 29
+#define JHB100_PER3CLK_ETHER0_SGMII_CLK_CSR_I 30
+#define JHB100_PER3CLK_ETHER0_SGMII_ACLK_I 31
+#define JHB100_PER3CLK_ETHER0_SGMII_PHY_PCLK_I 32
+#define JHB100_PER3CLK_MAIN_ICG_EN_SENSORS_PERIPH3 33
+#define JHB100_PER3CLK_MAIN_ICG_EN_PECI0 34
+#define JHB100_PER3CLK_MAIN_ICG_EN_PECI1 35
+#define JHB100_PER3CLK_MAIN_ICG_EN_GMAC0 36
+#define JHB100_PER3CLK_MAIN_ICG_EN_GMAC1 37
+
+#endif /* __DT_BINDINGS_CLOCK_STARFIVE_JHB100_H__ */
diff --git a/include/dt-bindings/interconnect/qcom,ipq9650.h b/include/dt-bindings/interconnect/qcom,ipq9650.h
new file mode 100644
index 000000000000..023a3878cc08
--- /dev/null
+++ b/include/dt-bindings/interconnect/qcom,ipq9650.h
@@ -0,0 +1,28 @@
+/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */
+#ifndef INTERCONNECT_QCOM_IPQ9650_H
+#define INTERCONNECT_QCOM_IPQ9650_H
+
+#define MASTER_ANOC_PCIE0 0
+#define SLAVE_ANOC_PCIE0 1
+#define MASTER_CNOC_PCIE0 2
+#define SLAVE_CNOC_PCIE0 3
+#define MASTER_ANOC_PCIE1 4
+#define SLAVE_ANOC_PCIE1 5
+#define MASTER_CNOC_PCIE1 6
+#define SLAVE_CNOC_PCIE1 7
+#define MASTER_ANOC_PCIE2 8
+#define SLAVE_ANOC_PCIE2 9
+#define MASTER_CNOC_PCIE2 10
+#define SLAVE_CNOC_PCIE2 11
+#define MASTER_ANOC_PCIE3 12
+#define SLAVE_ANOC_PCIE3 13
+#define MASTER_CNOC_PCIE3 14
+#define SLAVE_CNOC_PCIE3 15
+#define MASTER_ANOC_PCIE4 16
+#define SLAVE_ANOC_PCIE4 17
+#define MASTER_CNOC_PCIE4 18
+#define SLAVE_CNOC_PCIE4 19
+#define MASTER_SNOC_USB 20
+#define SLAVE_SNOC_USB 21
+
+#endif /* INTERCONNECT_QCOM_IPQ9650_H */
diff --git a/include/dt-bindings/interconnect/qcom,kuno.h b/include/dt-bindings/interconnect/qcom,kuno.h
new file mode 100644
index 000000000000..eacbae38f85d
--- /dev/null
+++ b/include/dt-bindings/interconnect/qcom,kuno.h
@@ -0,0 +1,89 @@
+/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */
+/*
+ * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
+ */
+
+#ifndef __DT_BINDINGS_INTERCONNECT_QCOM_KUNO_H
+#define __DT_BINDINGS_INTERCONNECT_QCOM_KUNO_H
+
+#define MASTER_SYS_TCU 0
+#define MASTER_LLCC 1
+#define MASTER_AUDIO 2
+#define MASTER_CPUCP 3
+#define MASTER_PCIE_RSCC 4
+#define MASTER_QDSS_BAM 5
+#define MASTER_QPIC 6
+#define MASTER_QUP_0 7
+#define MASTER_ANOC_SNOC 8
+#define MASTER_CNOC_DC_NOC 9
+#define MASTER_CNOC_SNOC 10
+#define MASTER_MSS_PROC 11
+#define MASTER_GEM_NOC_CFG 12
+#define MASTER_GEM_NOC_CNOC 13
+#define MASTER_GEM_NOC_PCIE_SNOC 14
+#define MASTER_ANOC_PCIE_GEM_NOC 15
+#define MASTER_SNOC_SF_MEM_NOC 16
+#define MASTER_QUP_CORE_0 17
+#define MASTER_CRYPTO 18
+#define MASTER_IPA 19
+#define MASTER_MSS_NAV 20
+#define MASTER_TME 21
+#define MASTER_APPSS_PROC 22
+#define MASTER_EMAC 23
+#define MASTER_IPA_PCIE 24
+#define MASTER_PCIE_0 25
+#define MASTER_QDSS_DAP 26
+#define MASTER_QDSS_ETR 27
+#define MASTER_QDSS_ETR_1 28
+#define MASTER_SDCC_4 29
+#define MASTER_USB3_0 30
+#define SLAVE_EBI1 31
+#define SLAVE_AHB2PHY 32
+#define SLAVE_AOSS 33
+#define SLAVE_APPSS 34
+#define SLAVE_AUDIO 35
+#define SLAVE_CLK_CTL 36
+#define SLAVE_RBCPR_CX_CFG 37
+#define SLAVE_RBCPR_MXA_CFG 38
+#define SLAVE_RBCPR_MXC_CFG 39
+#define SLAVE_CRYPTO_0_CFG 40
+#define SLAVE_EMAC_CFG 41
+#define SLAVE_IMEM_CFG 42
+#define SLAVE_IPA_CFG 43
+#define SLAVE_IPC_ROUTER_CFG 44
+#define SLAVE_LAGG_CFG 45
+#define SLAVE_MCCC_MASTER 46
+#define SLAVE_CNOC_MSS 47
+#define SLAVE_PCIE_0_CFG 48
+#define SLAVE_PCIE_RSC_CFG 49
+#define SLAVE_PDM 50
+#define SLAVE_PMU_WRAPPER_CFG 51
+#define SLAVE_PRNG 52
+#define SLAVE_QDSS_CFG 53
+#define SLAVE_QPIC 54
+#define SLAVE_QUP_0 55
+#define SLAVE_SDCC_4 56
+#define SLAVE_SPMI_VGI_COEX 57
+#define SLAVE_TCSR 58
+#define SLAVE_TLMM 59
+#define SLAVE_TME_CFG 60
+#define SLAVE_USB3 61
+#define SLAVE_VSENSE_CTRL_CFG 62
+#define SLAVE_A1NOC_CFG 63
+#define SLAVE_DDRSS_CFG 64
+#define SLAVE_LLCC 65
+#define SLAVE_GEM_NOC_CNOC 66
+#define SLAVE_SNOC_MEM_NOC_SF 67
+#define SLAVE_MEM_NOC_PCIE_SNOC 68
+#define SLAVE_ANOC_PCIE_GEM_NOC 69
+#define SLAVE_SNOC_CNOC 70
+#define SLAVE_ANOC_THROTTLE_CFG 71
+#define SLAVE_QUP_CORE_0 72
+#define SLAVE_BOOT_IMEM 73
+#define SLAVE_IMEM 74
+#define SLAVE_SERVICE_GEM_NOC 75
+#define SLAVE_PCIE_0 76
+#define SLAVE_QDSS_STM 77
+#define SLAVE_TCU 78
+
+#endif
diff --git a/include/dt-bindings/media/video-interface-devices.h b/include/dt-bindings/media/video-interface-devices.h
new file mode 100644
index 000000000000..d2340b457292
--- /dev/null
+++ b/include/dt-bindings/media/video-interface-devices.h
@@ -0,0 +1,13 @@
+/* SPDX-License-Identifier: (GPL-2.0-only OR MIT) */
+/*
+ * Copyright (C) 2026 Kieran Bingham <kieran.bingham@ideasonboard.com>
+ */
+
+#ifndef __DT_BINDINGS_MEDIA_VIDEO_INTERFACE_DEVICES_H__
+#define __DT_BINDINGS_MEDIA_VIDEO_INTERFACE_DEVICES_H__
+
+#define MEDIA_ORIENTATION_FRONT 0
+#define MEDIA_ORIENTATION_BACK 1
+#define MEDIA_ORIENTATION_EXTERNAL 2
+
+#endif /* __DT_BINDINGS_MEDIA_VIDEO_INTERFACE_DEVICES_H__ */
diff --git a/include/dt-bindings/pinctrl/mediatek,mt6735-pinfunc.h b/include/dt-bindings/pinctrl/mediatek,mt6735-pinfunc.h
new file mode 100644
index 000000000000..bc7c9fc4548d
--- /dev/null
+++ b/include/dt-bindings/pinctrl/mediatek,mt6735-pinfunc.h
@@ -0,0 +1,1148 @@
+/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */
+/*
+ * Copyright (C) 2022 Yassine Oudjana <y.oudjana@protonmail.com>
+ */
+
+#ifndef _DT_BINDINGS_PINCTRL_MEDIATEK_MT6735_PINFUNC_H
+#define _DT_BINDINGS_PINCTRL_MEDIATEK_MT6735_PINFUNC_H
+
+#include "mt65xx.h"
+
+#define PINMUX_GPIO0__FUNC_GPIO0 (MTK_PIN_NO(0) | 0)
+#define PINMUX_GPIO0__FUNC_IDDIG (MTK_PIN_NO(0) | 1)
+#define PINMUX_GPIO0__FUNC_DPI_D4 (MTK_PIN_NO(0) | 2)
+#define PINMUX_GPIO0__FUNC_CLKM4 (MTK_PIN_NO(0) | 3)
+#define PINMUX_GPIO0__FUNC_EXT_FRAME_SYNC (MTK_PIN_NO(0) | 4)
+#define PINMUX_GPIO0__FUNC_PWM3 (MTK_PIN_NO(0) | 5)
+#define PINMUX_GPIO0__FUNC_KCOL2 (MTK_PIN_NO(0) | 6)
+#define PINMUX_GPIO0__FUNC_C2K_ARM_EINT0 (MTK_PIN_NO(0) | 7)
+
+#define PINMUX_GPIO1__FUNC_GPIO1 (MTK_PIN_NO(1) | 0)
+#define PINMUX_GPIO1__FUNC_PWM2 (MTK_PIN_NO(1) | 1)
+#define PINMUX_GPIO1__FUNC_DPI_D5 (MTK_PIN_NO(1) | 2)
+#define PINMUX_GPIO1__FUNC_MD_EINT0 (MTK_PIN_NO(1) | 3)
+#define PINMUX_GPIO1__FUNC_TDD_TDO (MTK_PIN_NO(1) | 4)
+#define PINMUX_GPIO1__FUNC_CONN_MCU_TDO (MTK_PIN_NO(1) | 5)
+#define PINMUX_GPIO1__FUNC_PTA_RXD (MTK_PIN_NO(1) | 6)
+#define PINMUX_GPIO1__FUNC_C2K_ARM_EINT1 (MTK_PIN_NO(1) | 7)
+
+#define PINMUX_GPIO2__FUNC_GPIO2 (MTK_PIN_NO(2) | 0)
+#define PINMUX_GPIO2__FUNC_CLKM0 (MTK_PIN_NO(2) | 1)
+#define PINMUX_GPIO2__FUNC_DPI_D6 (MTK_PIN_NO(2) | 2)
+#define PINMUX_GPIO2__FUNC_MD_EINT0 (MTK_PIN_NO(2) | 3)
+#define PINMUX_GPIO2__FUNC_USB_DRVVBUS (MTK_PIN_NO(2) | 4)
+#define PINMUX_GPIO2__FUNC_CONN_MCU_DBGACK_N (MTK_PIN_NO(2) | 5)
+#define PINMUX_GPIO2__FUNC_PTA_TXD (MTK_PIN_NO(2) | 6)
+#define PINMUX_GPIO2__FUNC_C2K_ARM_EINT2 (MTK_PIN_NO(2) | 7)
+
+#define PINMUX_GPIO3__FUNC_GPIO3 (MTK_PIN_NO(3) | 0)
+#define PINMUX_GPIO3__FUNC_CLKM1 (MTK_PIN_NO(3) | 1)
+#define PINMUX_GPIO3__FUNC_DPI_D7 (MTK_PIN_NO(3) | 2)
+#define PINMUX_GPIO3__FUNC_SPI_MIB (MTK_PIN_NO(3) | 3)
+#define PINMUX_GPIO3__FUNC_MD_EINT0 (MTK_PIN_NO(3) | 4)
+#define PINMUX_GPIO3__FUNC_CONN_MCU_DBGI_N (MTK_PIN_NO(3) | 5)
+#define PINMUX_GPIO3__FUNC_CONN_MCU_AICE_TMSC (MTK_PIN_NO(3) | 6)
+#define PINMUX_GPIO3__FUNC_C2K_ARM_EINT3 (MTK_PIN_NO(3) | 7)
+
+#define PINMUX_GPIO4__FUNC_GPIO4 (MTK_PIN_NO(4) | 0)
+#define PINMUX_GPIO4__FUNC_CLKM2 (MTK_PIN_NO(4) | 1)
+#define PINMUX_GPIO4__FUNC_DPI_D8 (MTK_PIN_NO(4) | 2)
+#define PINMUX_GPIO4__FUNC_SPI_MOB (MTK_PIN_NO(4) | 3)
+#define PINMUX_GPIO4__FUNC_TDD_TCK (MTK_PIN_NO(4) | 4)
+#define PINMUX_GPIO4__FUNC_CONN_MCU_TCK_0 (MTK_PIN_NO(4) | 5)
+#define PINMUX_GPIO4__FUNC_CONN_MCU_AICE_TCKC (MTK_PIN_NO(4) | 6)
+#define PINMUX_GPIO4__FUNC_C2K_DM_EINT0 (MTK_PIN_NO(4) | 7)
+
+#define PINMUX_GPIO5__FUNC_GPIO5 (MTK_PIN_NO(5) | 0)
+#define PINMUX_GPIO5__FUNC_UCTS2 (MTK_PIN_NO(5) | 1)
+#define PINMUX_GPIO5__FUNC_DPI_D9 (MTK_PIN_NO(5) | 2)
+#define PINMUX_GPIO5__FUNC_SPI_CSB (MTK_PIN_NO(5) | 3)
+#define PINMUX_GPIO5__FUNC_TDD_TDI (MTK_PIN_NO(5) | 4)
+#define PINMUX_GPIO5__FUNC_CONN_MCU_TDI (MTK_PIN_NO(5) | 5)
+#define PINMUX_GPIO5__FUNC_I2S1_DO (MTK_PIN_NO(5) | 6)
+#define PINMUX_GPIO5__FUNC_MD_URXD (MTK_PIN_NO(5) | 7)
+
+#define PINMUX_GPIO6__FUNC_GPIO6 (MTK_PIN_NO(6) | 0)
+#define PINMUX_GPIO6__FUNC_URTS2 (MTK_PIN_NO(6) | 1)
+#define PINMUX_GPIO6__FUNC_DPI_D10 (MTK_PIN_NO(6) | 2)
+#define PINMUX_GPIO6__FUNC_SPI_CKB (MTK_PIN_NO(6) | 3)
+#define PINMUX_GPIO6__FUNC_TDD_TRSTN (MTK_PIN_NO(6) | 4)
+#define PINMUX_GPIO6__FUNC_CONN_MCU_TRST_B (MTK_PIN_NO(6) | 5)
+#define PINMUX_GPIO6__FUNC_I2S1_LRCK (MTK_PIN_NO(6) | 6)
+#define PINMUX_GPIO6__FUNC_MD_UTXD (MTK_PIN_NO(6) | 7)
+
+#define PINMUX_GPIO7__FUNC_GPIO7 (MTK_PIN_NO(7) | 0)
+#define PINMUX_GPIO7__FUNC_UCTS3 (MTK_PIN_NO(7) | 1)
+#define PINMUX_GPIO7__FUNC_DPI_D11 (MTK_PIN_NO(7) | 2)
+#define PINMUX_GPIO7__FUNC_SDA1 (MTK_PIN_NO(7) | 3)
+#define PINMUX_GPIO7__FUNC_TDD_TMS (MTK_PIN_NO(7) | 4)
+#define PINMUX_GPIO7__FUNC_CONN_MCU_TMS (MTK_PIN_NO(7) | 5)
+#define PINMUX_GPIO7__FUNC_I2S1_BCK (MTK_PIN_NO(7) | 6)
+#define PINMUX_GPIO7__FUNC_TDD_TXD (MTK_PIN_NO(7) | 7)
+
+#define PINMUX_GPIO8__FUNC_GPIO8 (MTK_PIN_NO(8) | 0)
+#define PINMUX_GPIO8__FUNC_URTS3 (MTK_PIN_NO(8) | 1)
+#define PINMUX_GPIO8__FUNC_C2K_UIM0_HOT_PLUG_IN (MTK_PIN_NO(8) | 2)
+#define PINMUX_GPIO8__FUNC_SCL1 (MTK_PIN_NO(8) | 3)
+#define PINMUX_GPIO8__FUNC_PCM1_DO1 (MTK_PIN_NO(8) | 4)
+#define PINMUX_GPIO8__FUNC_MD_EINT1 (MTK_PIN_NO(8) | 5)
+#define PINMUX_GPIO8__FUNC_KCOL4 (MTK_PIN_NO(8) | 6)
+#define PINMUX_GPIO8__FUNC_UTXD0 (MTK_PIN_NO(8) | 7)
+
+#define PINMUX_GPIO9__FUNC_GPIO9 (MTK_PIN_NO(9) | 0)
+#define PINMUX_GPIO9__FUNC_C2K_UIM1_HOT_PLUG_IN (MTK_PIN_NO(9) | 1)
+#define PINMUX_GPIO9__FUNC_PCM1_DO0 (MTK_PIN_NO(9) | 2)
+#define PINMUX_GPIO9__FUNC_I2S3_MCK (MTK_PIN_NO(9) | 3)
+#define PINMUX_GPIO9__FUNC_MD_EINT2 (MTK_PIN_NO(9) | 4)
+#define PINMUX_GPIO9__FUNC_CLKM2 (MTK_PIN_NO(9) | 5)
+#define PINMUX_GPIO9__FUNC_I2S1_MCK (MTK_PIN_NO(9) | 6)
+#define PINMUX_GPIO9__FUNC_DBG_MON_A29 (MTK_PIN_NO(9) | 7)
+
+#define PINMUX_GPIO10__FUNC_GPIO10 (MTK_PIN_NO(10) | 0)
+#define PINMUX_GPIO10__FUNC_PWM1 (MTK_PIN_NO(10) | 1)
+#define PINMUX_GPIO10__FUNC_CLKM1 (MTK_PIN_NO(10) | 2)
+#define PINMUX_GPIO10__FUNC_KROW2 (MTK_PIN_NO(10) | 3)
+#define PINMUX_GPIO10__FUNC_MD_EINT0 (MTK_PIN_NO(10) | 4)
+#define PINMUX_GPIO10__FUNC_I2S1_MCK (MTK_PIN_NO(10) | 5)
+#define PINMUX_GPIO10__FUNC_SDA3 (MTK_PIN_NO(10) | 6)
+#define PINMUX_GPIO10__FUNC_DBG_MON_A30 (MTK_PIN_NO(10) | 7)
+
+#define PINMUX_GPIO11__FUNC_GPIO11 (MTK_PIN_NO(11) | 0)
+#define PINMUX_GPIO11__FUNC_MD_EINT1 (MTK_PIN_NO(11) | 1)
+#define PINMUX_GPIO11__FUNC_IRTX_OUT (MTK_PIN_NO(11) | 2)
+#define PINMUX_GPIO11__FUNC_C2K_UIM0_HOT_PLUG_IN (MTK_PIN_NO(11) | 3)
+#define PINMUX_GPIO11__FUNC_CLKM0 (MTK_PIN_NO(11) | 4)
+#define PINMUX_GPIO11__FUNC_I2S2_MCK (MTK_PIN_NO(11) | 5)
+#define PINMUX_GPIO11__FUNC_SCL3 (MTK_PIN_NO(11) | 6)
+#define PINMUX_GPIO11__FUNC_URXD0 (MTK_PIN_NO(11) | 7)
+
+#define PINMUX_GPIO12__FUNC_GPIO12 (MTK_PIN_NO(12) | 0)
+#define PINMUX_GPIO12__FUNC_I2S0_MCK (MTK_PIN_NO(12) | 1)
+#define PINMUX_GPIO12__FUNC_C2K_UIM1_HOT_PLUG_IN (MTK_PIN_NO(12) | 2)
+#define PINMUX_GPIO12__FUNC_KCOL2 (MTK_PIN_NO(12) | 3)
+#define PINMUX_GPIO12__FUNC_MD_EINT2 (MTK_PIN_NO(12) | 4)
+#define PINMUX_GPIO12__FUNC_IRTX_OUT (MTK_PIN_NO(12) | 5)
+#define PINMUX_GPIO12__FUNC_SRCLKENAI2 (MTK_PIN_NO(12) | 6)
+#define PINMUX_GPIO12__FUNC_PCM1_DO1 (MTK_PIN_NO(12) | 7)
+
+#define PINMUX_GPIO13__FUNC_GPIO13 (MTK_PIN_NO(13) | 0)
+#define PINMUX_GPIO13__FUNC_WB_CTRL0 (MTK_PIN_NO(13) | 1)
+#define PINMUX_GPIO13__FUNC_C2K_ARM_EINT0 (MTK_PIN_NO(13) | 3)
+#define PINMUX_GPIO13__FUNC_DBG_MON_A0 (MTK_PIN_NO(13) | 7)
+
+#define PINMUX_GPIO14__FUNC_GPIO14 (MTK_PIN_NO(14) | 0)
+#define PINMUX_GPIO14__FUNC_WB_CTRL1 (MTK_PIN_NO(14) | 1)
+#define PINMUX_GPIO14__FUNC_C2K_ARM_EINT1 (MTK_PIN_NO(14) | 3)
+#define PINMUX_GPIO14__FUNC_DBG_MON_A1 (MTK_PIN_NO(14) | 7)
+
+#define PINMUX_GPIO15__FUNC_GPIO15 (MTK_PIN_NO(15) | 0)
+#define PINMUX_GPIO15__FUNC_WB_CTRL2 (MTK_PIN_NO(15) | 1)
+#define PINMUX_GPIO15__FUNC_C2K_ARM_EINT2 (MTK_PIN_NO(15) | 3)
+#define PINMUX_GPIO15__FUNC_DBG_MON_A2 (MTK_PIN_NO(15) | 7)
+
+#define PINMUX_GPIO16__FUNC_GPIO16 (MTK_PIN_NO(16) | 0)
+#define PINMUX_GPIO16__FUNC_WB_CTRL3 (MTK_PIN_NO(16) | 1)
+#define PINMUX_GPIO16__FUNC_C2K_ARM_EINT3 (MTK_PIN_NO(16) | 3)
+#define PINMUX_GPIO16__FUNC_DBG_MON_A3 (MTK_PIN_NO(16) | 7)
+
+#define PINMUX_GPIO17__FUNC_GPIO17 (MTK_PIN_NO(17) | 0)
+#define PINMUX_GPIO17__FUNC_WB_CTRL4 (MTK_PIN_NO(17) | 1)
+#define PINMUX_GPIO17__FUNC_C2K_DM_EINT0 (MTK_PIN_NO(17) | 3)
+#define PINMUX_GPIO17__FUNC_WATCHDOG (MTK_PIN_NO(17) | 4)
+#define PINMUX_GPIO17__FUNC_DBG_MON_A4 (MTK_PIN_NO(17) | 7)
+
+#define PINMUX_GPIO18__FUNC_GPIO18 (MTK_PIN_NO(18) | 0)
+#define PINMUX_GPIO18__FUNC_WB_CTRL5 (MTK_PIN_NO(18) | 1)
+#define PINMUX_GPIO18__FUNC_C2K_DM_EINT1 (MTK_PIN_NO(18) | 3)
+#define PINMUX_GPIO18__FUNC_DBG_MON_A5 (MTK_PIN_NO(18) | 7)
+
+#define PINMUX_GPIO19__FUNC_GPIO19 (MTK_PIN_NO(19) | 0)
+#define PINMUX_GPIO19__FUNC_ANT_SEL0 (MTK_PIN_NO(19) | 1)
+#define PINMUX_GPIO19__FUNC_IRTX_OUT (MTK_PIN_NO(19) | 2)
+#define PINMUX_GPIO19__FUNC_IRDA_TX (MTK_PIN_NO(19) | 3)
+#define PINMUX_GPIO19__FUNC_C2K_UART0_TXD (MTK_PIN_NO(19) | 4)
+#define PINMUX_GPIO19__FUNC_GPS_FRAME_SYNC (MTK_PIN_NO(19) | 5)
+#define PINMUX_GPIO19__FUNC_LTE_UTXD (MTK_PIN_NO(19) | 6)
+#define PINMUX_GPIO19__FUNC_DBG_MON_A6 (MTK_PIN_NO(19) | 7)
+
+#define PINMUX_GPIO20__FUNC_GPIO20 (MTK_PIN_NO(20) | 0)
+#define PINMUX_GPIO20__FUNC_ANT_SEL1 (MTK_PIN_NO(20) | 1)
+#define PINMUX_GPIO20__FUNC_C2K_UIM1_HOT_PLUG_IN (MTK_PIN_NO(20) | 2)
+#define PINMUX_GPIO20__FUNC_IRDA_RX (MTK_PIN_NO(20) | 3)
+#define PINMUX_GPIO20__FUNC_C2K_UART0_RXD (MTK_PIN_NO(20) | 4)
+#define PINMUX_GPIO20__FUNC_MD_EINT2 (MTK_PIN_NO(20) | 5)
+#define PINMUX_GPIO20__FUNC_LTE_URXD (MTK_PIN_NO(20) | 6)
+#define PINMUX_GPIO20__FUNC_DBG_MON_A7 (MTK_PIN_NO(20) | 7)
+
+#define PINMUX_GPIO21__FUNC_GPIO21 (MTK_PIN_NO(21) | 0)
+#define PINMUX_GPIO21__FUNC_ANT_SEL2 (MTK_PIN_NO(21) | 1)
+#define PINMUX_GPIO21__FUNC_PWM2 (MTK_PIN_NO(21) | 2)
+#define PINMUX_GPIO21__FUNC_IRDA_PDN (MTK_PIN_NO(21) | 3)
+#define PINMUX_GPIO21__FUNC_CORESONIC_SWCK (MTK_PIN_NO(21) | 4)
+#define PINMUX_GPIO21__FUNC_MD_EINT1 (MTK_PIN_NO(21) | 5)
+#define PINMUX_GPIO21__FUNC_C2K_UIM0_HOT_PLUG_IN (MTK_PIN_NO(21) | 6)
+#define PINMUX_GPIO21__FUNC_DBG_MON_A8 (MTK_PIN_NO(21) | 7)
+
+#define PINMUX_GPIO22__FUNC_GPIO22 (MTK_PIN_NO(22) | 0)
+#define PINMUX_GPIO22__FUNC_RDN0 (MTK_PIN_NO(22) | 1)
+
+#define PINMUX_GPIO23__FUNC_GPIO23 (MTK_PIN_NO(23) | 0)
+#define PINMUX_GPIO23__FUNC_RDP0 (MTK_PIN_NO(23) | 1)
+
+#define PINMUX_GPIO24__FUNC_GPIO24 (MTK_PIN_NO(24) | 0)
+#define PINMUX_GPIO24__FUNC_RDN1 (MTK_PIN_NO(24) | 1)
+
+#define PINMUX_GPIO25__FUNC_GPIO25 (MTK_PIN_NO(25) | 0)
+#define PINMUX_GPIO25__FUNC_RDP1 (MTK_PIN_NO(25) | 1)
+
+#define PINMUX_GPIO26__FUNC_GPIO26 (MTK_PIN_NO(26) | 0)
+#define PINMUX_GPIO26__FUNC_RCN (MTK_PIN_NO(26) | 1)
+
+#define PINMUX_GPIO27__FUNC_GPIO27 (MTK_PIN_NO(27) | 0)
+#define PINMUX_GPIO27__FUNC_RCP (MTK_PIN_NO(27) | 1)
+
+#define PINMUX_GPIO28__FUNC_GPIO28 (MTK_PIN_NO(28) | 0)
+#define PINMUX_GPIO28__FUNC_RDN2 (MTK_PIN_NO(28) | 1)
+
+#define PINMUX_GPIO29__FUNC_GPIO29 (MTK_PIN_NO(29) | 0)
+#define PINMUX_GPIO29__FUNC_RDP2 (MTK_PIN_NO(29) | 1)
+
+#define PINMUX_GPIO30__FUNC_GPIO30 (MTK_PIN_NO(30) | 0)
+#define PINMUX_GPIO30__FUNC_RDN3 (MTK_PIN_NO(30) | 1)
+
+#define PINMUX_GPIO31__FUNC_GPIO31 (MTK_PIN_NO(31) | 0)
+#define PINMUX_GPIO31__FUNC_RDP3 (MTK_PIN_NO(31) | 1)
+
+#define PINMUX_GPIO32__FUNC_GPIO32 (MTK_PIN_NO(32) | 0)
+#define PINMUX_GPIO32__FUNC_RDN0_A (MTK_PIN_NO(32) | 1)
+#define PINMUX_GPIO32__FUNC_CMHSYNC (MTK_PIN_NO(32) | 2)
+#define PINMUX_GPIO32__FUNC_CMCSD0 (MTK_PIN_NO(32) | 3)
+
+#define PINMUX_GPIO33__FUNC_GPIO33 (MTK_PIN_NO(33) | 0)
+#define PINMUX_GPIO33__FUNC_RDP0_A (MTK_PIN_NO(33) | 1)
+#define PINMUX_GPIO33__FUNC_CMVSYNC (MTK_PIN_NO(33) | 2)
+#define PINMUX_GPIO33__FUNC_CMCSD1 (MTK_PIN_NO(33) | 3)
+
+#define PINMUX_GPIO34__FUNC_GPIO34 (MTK_PIN_NO(34) | 0)
+#define PINMUX_GPIO34__FUNC_RDN1_A (MTK_PIN_NO(34) | 1)
+#define PINMUX_GPIO34__FUNC_CMDAT9 (MTK_PIN_NO(34) | 2)
+#define PINMUX_GPIO34__FUNC_CMCSD2 (MTK_PIN_NO(34) | 3)
+
+#define PINMUX_GPIO35__FUNC_GPIO35 (MTK_PIN_NO(35) | 0)
+#define PINMUX_GPIO35__FUNC_RDP1_A (MTK_PIN_NO(35) | 1)
+#define PINMUX_GPIO35__FUNC_CMDAT8 (MTK_PIN_NO(35) | 2)
+#define PINMUX_GPIO35__FUNC_CMCSD3 (MTK_PIN_NO(35) | 3)
+
+#define PINMUX_GPIO36__FUNC_GPIO36 (MTK_PIN_NO(36) | 0)
+#define PINMUX_GPIO36__FUNC_RCN_A (MTK_PIN_NO(36) | 1)
+#define PINMUX_GPIO36__FUNC_CMDAT7 (MTK_PIN_NO(36) | 2)
+
+#define PINMUX_GPIO37__FUNC_GPIO37 (MTK_PIN_NO(37) | 0)
+#define PINMUX_GPIO37__FUNC_RCP_A (MTK_PIN_NO(37) | 1)
+#define PINMUX_GPIO37__FUNC_CMDAT6 (MTK_PIN_NO(37) | 2)
+
+#define PINMUX_GPIO38__FUNC_GPIO38 (MTK_PIN_NO(38) | 0)
+#define PINMUX_GPIO38__FUNC_RDN2_A (MTK_PIN_NO(38) | 1)
+#define PINMUX_GPIO38__FUNC_CMDAT5 (MTK_PIN_NO(38) | 2)
+
+#define PINMUX_GPIO39__FUNC_GPIO39 (MTK_PIN_NO(39) | 0)
+#define PINMUX_GPIO39__FUNC_RDP2_A (MTK_PIN_NO(39) | 1)
+#define PINMUX_GPIO39__FUNC_CMDAT4 (MTK_PIN_NO(39) | 2)
+
+#define PINMUX_GPIO40__FUNC_GPIO40 (MTK_PIN_NO(40) | 0)
+#define PINMUX_GPIO40__FUNC_RDN3_A (MTK_PIN_NO(40) | 1)
+#define PINMUX_GPIO40__FUNC_CMDAT3 (MTK_PIN_NO(40) | 2)
+
+#define PINMUX_GPIO41__FUNC_GPIO41 (MTK_PIN_NO(41) | 0)
+#define PINMUX_GPIO41__FUNC_RDP3_A (MTK_PIN_NO(41) | 1)
+#define PINMUX_GPIO41__FUNC_CMDAT2 (MTK_PIN_NO(41) | 2)
+
+#define PINMUX_GPIO42__FUNC_GPIO42 (MTK_PIN_NO(42) | 0)
+#define PINMUX_GPIO42__FUNC_CMDAT0 (MTK_PIN_NO(42) | 1)
+#define PINMUX_GPIO42__FUNC_CMCSD0 (MTK_PIN_NO(42) | 2)
+#define PINMUX_GPIO42__FUNC_CMMCLK1 (MTK_PIN_NO(42) | 3)
+#define PINMUX_GPIO42__FUNC_ANT_SEL5 (MTK_PIN_NO(42) | 5)
+#define PINMUX_GPIO42__FUNC_CLKM5 (MTK_PIN_NO(42) | 6)
+#define PINMUX_GPIO42__FUNC_DBG_MON_A9 (MTK_PIN_NO(42) | 7)
+
+#define PINMUX_GPIO43__FUNC_GPIO43 (MTK_PIN_NO(43) | 0)
+#define PINMUX_GPIO43__FUNC_CMDAT1 (MTK_PIN_NO(43) | 1)
+#define PINMUX_GPIO43__FUNC_CMCSD1 (MTK_PIN_NO(43) | 2)
+#define PINMUX_GPIO43__FUNC_CMFLASH (MTK_PIN_NO(43) | 3)
+#define PINMUX_GPIO43__FUNC_MD_EINT0 (MTK_PIN_NO(43) | 4)
+#define PINMUX_GPIO43__FUNC_CMMCLK1 (MTK_PIN_NO(43) | 5)
+#define PINMUX_GPIO43__FUNC_CLKM4 (MTK_PIN_NO(43) | 6)
+#define PINMUX_GPIO43__FUNC_DBG_MON_A10 (MTK_PIN_NO(43) | 7)
+
+#define PINMUX_GPIO44__FUNC_GPIO44 (MTK_PIN_NO(44) | 0)
+#define PINMUX_GPIO44__FUNC_CMPCLK (MTK_PIN_NO(44) | 1)
+#define PINMUX_GPIO44__FUNC_CMCSK (MTK_PIN_NO(44) | 2)
+#define PINMUX_GPIO44__FUNC_CMCSD2 (MTK_PIN_NO(44) | 3)
+#define PINMUX_GPIO44__FUNC_KCOL3 (MTK_PIN_NO(44) | 4)
+#define PINMUX_GPIO44__FUNC_SRCLKENAI2 (MTK_PIN_NO(44) | 5)
+#define PINMUX_GPIO44__FUNC_PWM0 (MTK_PIN_NO(44) | 6)
+#define PINMUX_GPIO44__FUNC_DBG_MON_A11 (MTK_PIN_NO(44) | 7)
+
+#define PINMUX_GPIO45__FUNC_GPIO45 (MTK_PIN_NO(45) | 0)
+#define PINMUX_GPIO45__FUNC_CMMCLK0 (MTK_PIN_NO(45) | 1)
+#define PINMUX_GPIO45__FUNC_DBG_MON_A12 (MTK_PIN_NO(45) | 7)
+
+#define PINMUX_GPIO46__FUNC_GPIO46 (MTK_PIN_NO(46) | 0)
+#define PINMUX_GPIO46__FUNC_CMMCLK1 (MTK_PIN_NO(46) | 1)
+#define PINMUX_GPIO46__FUNC_IDDIG (MTK_PIN_NO(46) | 2)
+#define PINMUX_GPIO46__FUNC_LTE_MD32_JTAG_TRST (MTK_PIN_NO(46) | 3)
+#define PINMUX_GPIO46__FUNC_TDD_TRSTN (MTK_PIN_NO(46) | 4)
+#define PINMUX_GPIO46__FUNC_DM_JTINTP (MTK_PIN_NO(46) | 5)
+#define PINMUX_GPIO46__FUNC_KCOL6 (MTK_PIN_NO(46) | 6)
+#define PINMUX_GPIO46__FUNC_DBG_MON_A13 (MTK_PIN_NO(46) | 7)
+
+#define PINMUX_GPIO47__FUNC_GPIO47 (MTK_PIN_NO(47) | 0)
+#define PINMUX_GPIO47__FUNC_SDA0 (MTK_PIN_NO(47) | 1)
+
+#define PINMUX_GPIO48__FUNC_GPIO48 (MTK_PIN_NO(48) | 0)
+#define PINMUX_GPIO48__FUNC_SCL0 (MTK_PIN_NO(48) | 1)
+
+#define PINMUX_GPIO49__FUNC_GPIO49 (MTK_PIN_NO(49) | 0)
+#define PINMUX_GPIO49__FUNC_SDA1 (MTK_PIN_NO(49) | 1)
+
+#define PINMUX_GPIO50__FUNC_GPIO50 (MTK_PIN_NO(50) | 0)
+#define PINMUX_GPIO50__FUNC_SCL1 (MTK_PIN_NO(50) | 1)
+
+#define PINMUX_GPIO51__FUNC_GPIO51 (MTK_PIN_NO(51) | 0)
+#define PINMUX_GPIO51__FUNC_SDA2 (MTK_PIN_NO(51) | 1)
+
+#define PINMUX_GPIO52__FUNC_GPIO52 (MTK_PIN_NO(52) | 0)
+#define PINMUX_GPIO52__FUNC_SCL2 (MTK_PIN_NO(52) | 1)
+
+#define PINMUX_GPIO53__FUNC_GPIO53 (MTK_PIN_NO(53) | 0)
+#define PINMUX_GPIO53__FUNC_SDA3 (MTK_PIN_NO(53) | 1)
+#define PINMUX_GPIO53__FUNC_IDDIG (MTK_PIN_NO(53) | 3)
+#define PINMUX_GPIO53__FUNC_MD_EINT2 (MTK_PIN_NO(53) | 5)
+#define PINMUX_GPIO53__FUNC_C2K_UIM1_HOT_PLUG_IN (MTK_PIN_NO(53) | 6)
+
+#define PINMUX_GPIO54__FUNC_GPIO54 (MTK_PIN_NO(54) | 0)
+#define PINMUX_GPIO54__FUNC_SCL3 (MTK_PIN_NO(54) | 1)
+#define PINMUX_GPIO54__FUNC_IDDIG (MTK_PIN_NO(54) | 3)
+#define PINMUX_GPIO54__FUNC_MD_EINT1 (MTK_PIN_NO(54) | 5)
+#define PINMUX_GPIO54__FUNC_C2K_UIM0_HOT_PLUG_IN (MTK_PIN_NO(54) | 6)
+
+#define PINMUX_GPIO55__FUNC_GPIO55 (MTK_PIN_NO(55) | 0)
+#define PINMUX_GPIO55__FUNC_SRCLKENAI0 (MTK_PIN_NO(55) | 1)
+#define PINMUX_GPIO55__FUNC_PWM2 (MTK_PIN_NO(55) | 2)
+#define PINMUX_GPIO55__FUNC_CLKM5 (MTK_PIN_NO(55) | 3)
+#define PINMUX_GPIO55__FUNC_CORESONIC_SWD (MTK_PIN_NO(55) | 4)
+#define PINMUX_GPIO55__FUNC_ANT_SEL6 (MTK_PIN_NO(55) | 5)
+#define PINMUX_GPIO55__FUNC_KROW5 (MTK_PIN_NO(55) | 6)
+#define PINMUX_GPIO55__FUNC_DISP_PWM (MTK_PIN_NO(55) | 7)
+
+#define PINMUX_GPIO56__FUNC_GPIO56 (MTK_PIN_NO(56) | 0)
+#define PINMUX_GPIO56__FUNC_SRCLKENA1 (MTK_PIN_NO(56) | 1)
+
+#define PINMUX_GPIO57__FUNC_GPIO57 (MTK_PIN_NO(57) | 0)
+#define PINMUX_GPIO57__FUNC_URXD2 (MTK_PIN_NO(57) | 1)
+#define PINMUX_GPIO57__FUNC_DPI_HSYNC0 (MTK_PIN_NO(57) | 2)
+#define PINMUX_GPIO57__FUNC_UTXD2 (MTK_PIN_NO(57) | 3)
+#define PINMUX_GPIO57__FUNC_MD_URXD (MTK_PIN_NO(57) | 4)
+#define PINMUX_GPIO57__FUNC_SRCLKENAI1 (MTK_PIN_NO(57) | 5)
+#define PINMUX_GPIO57__FUNC_KROW4 (MTK_PIN_NO(57) | 6)
+#define PINMUX_GPIO57__FUNC_DBG_MON_A14 (MTK_PIN_NO(57) | 7)
+
+#define PINMUX_GPIO58__FUNC_GPIO58 (MTK_PIN_NO(58) | 0)
+#define PINMUX_GPIO58__FUNC_UTXD2 (MTK_PIN_NO(58) | 1)
+#define PINMUX_GPIO58__FUNC_DPI_VSYNC0 (MTK_PIN_NO(58) | 2)
+#define PINMUX_GPIO58__FUNC_URXD2 (MTK_PIN_NO(58) | 3)
+#define PINMUX_GPIO58__FUNC_MD_UTXD (MTK_PIN_NO(58) | 4)
+#define PINMUX_GPIO58__FUNC_TDD_TXD (MTK_PIN_NO(58) | 5)
+#define PINMUX_GPIO58__FUNC_KROW5 (MTK_PIN_NO(58) | 6)
+#define PINMUX_GPIO58__FUNC_DBG_MON_A15 (MTK_PIN_NO(58) | 7)
+
+#define PINMUX_GPIO59__FUNC_GPIO59 (MTK_PIN_NO(59) | 0)
+#define PINMUX_GPIO59__FUNC_URXD3 (MTK_PIN_NO(59) | 1)
+#define PINMUX_GPIO59__FUNC_DPI_CK0 (MTK_PIN_NO(59) | 2)
+#define PINMUX_GPIO59__FUNC_UTXD3 (MTK_PIN_NO(59) | 3)
+#define PINMUX_GPIO59__FUNC_UCTS2 (MTK_PIN_NO(59) | 4)
+#define PINMUX_GPIO59__FUNC_PWM3 (MTK_PIN_NO(59) | 5)
+#define PINMUX_GPIO59__FUNC_KROW6 (MTK_PIN_NO(59) | 6)
+#define PINMUX_GPIO59__FUNC_DBG_MON_A16 (MTK_PIN_NO(59) | 7)
+
+#define PINMUX_GPIO60__FUNC_GPIO60 (MTK_PIN_NO(60) | 0)
+#define PINMUX_GPIO60__FUNC_UTXD3 (MTK_PIN_NO(60) | 1)
+#define PINMUX_GPIO60__FUNC_DPI_DE0 (MTK_PIN_NO(60) | 2)
+#define PINMUX_GPIO60__FUNC_URXD3 (MTK_PIN_NO(60) | 3)
+#define PINMUX_GPIO60__FUNC_URTS2 (MTK_PIN_NO(60) | 4)
+#define PINMUX_GPIO60__FUNC_PWM4 (MTK_PIN_NO(60) | 5)
+#define PINMUX_GPIO60__FUNC_KROW7 (MTK_PIN_NO(60) | 6)
+#define PINMUX_GPIO60__FUNC_DBG_MON_A17 (MTK_PIN_NO(60) | 7)
+
+#define PINMUX_GPIO61__FUNC_GPIO61 (MTK_PIN_NO(61) | 0)
+#define PINMUX_GPIO61__FUNC_PCM1_CLK (MTK_PIN_NO(61) | 1)
+#define PINMUX_GPIO61__FUNC_DPI_D0 (MTK_PIN_NO(61) | 2)
+#define PINMUX_GPIO61__FUNC_I2S0_BCK (MTK_PIN_NO(61) | 3)
+#define PINMUX_GPIO61__FUNC_KROW4 (MTK_PIN_NO(61) | 4)
+#define PINMUX_GPIO61__FUNC_ANT_SEL3 (MTK_PIN_NO(61) | 5)
+#define PINMUX_GPIO61__FUNC_IRTX_OUT (MTK_PIN_NO(61) | 6)
+#define PINMUX_GPIO61__FUNC_DBG_MON_A18 (MTK_PIN_NO(61) | 7)
+
+#define PINMUX_GPIO62__FUNC_GPIO62 (MTK_PIN_NO(62) | 0)
+#define PINMUX_GPIO62__FUNC_PCM1_SYNC (MTK_PIN_NO(62) | 1)
+#define PINMUX_GPIO62__FUNC_DPI_D1 (MTK_PIN_NO(62) | 2)
+#define PINMUX_GPIO62__FUNC_I2S0_LRCK (MTK_PIN_NO(62) | 3)
+#define PINMUX_GPIO62__FUNC_KCOL7 (MTK_PIN_NO(62) | 4)
+#define PINMUX_GPIO62__FUNC_CLKM3 (MTK_PIN_NO(62) | 5)
+#define PINMUX_GPIO62__FUNC_CMFLASH (MTK_PIN_NO(62) | 6)
+#define PINMUX_GPIO62__FUNC_DBG_MON_A19 (MTK_PIN_NO(62) | 7)
+
+#define PINMUX_GPIO63__FUNC_GPIO63 (MTK_PIN_NO(63) | 0)
+#define PINMUX_GPIO63__FUNC_PCM1_DI (MTK_PIN_NO(63) | 1)
+#define PINMUX_GPIO63__FUNC_DPI_D2 (MTK_PIN_NO(63) | 2)
+#define PINMUX_GPIO63__FUNC_I2S0_DI (MTK_PIN_NO(63) | 3)
+#define PINMUX_GPIO63__FUNC_PCM1_DO0 (MTK_PIN_NO(63) | 4)
+#define PINMUX_GPIO63__FUNC_CLKM5 (MTK_PIN_NO(63) | 5)
+#define PINMUX_GPIO63__FUNC_KROW3 (MTK_PIN_NO(63) | 6)
+#define PINMUX_GPIO63__FUNC_DBG_MON_A20 (MTK_PIN_NO(63) | 7)
+
+#define PINMUX_GPIO64__FUNC_GPIO64 (MTK_PIN_NO(64) | 0)
+#define PINMUX_GPIO64__FUNC_PCM1_DO0 (MTK_PIN_NO(64) | 1)
+#define PINMUX_GPIO64__FUNC_DPI_D3 (MTK_PIN_NO(64) | 2)
+#define PINMUX_GPIO64__FUNC_I2S0_MCK (MTK_PIN_NO(64) | 3)
+#define PINMUX_GPIO64__FUNC_PCM1_DI (MTK_PIN_NO(64) | 4)
+#define PINMUX_GPIO64__FUNC_SRCLKENAI2 (MTK_PIN_NO(64) | 5)
+#define PINMUX_GPIO64__FUNC_KCOL5 (MTK_PIN_NO(64) | 6)
+#define PINMUX_GPIO64__FUNC_DBG_MON_A21 (MTK_PIN_NO(64) | 7)
+
+#define PINMUX_GPIO65__FUNC_GPIO65 (MTK_PIN_NO(65) | 0)
+#define PINMUX_GPIO65__FUNC_SPI_CSA (MTK_PIN_NO(65) | 1)
+#define PINMUX_GPIO65__FUNC_EXT_FRAME_SYNC (MTK_PIN_NO(65) | 2)
+#define PINMUX_GPIO65__FUNC_I2S3_MCK (MTK_PIN_NO(65) | 3)
+#define PINMUX_GPIO65__FUNC_KROW2 (MTK_PIN_NO(65) | 4)
+#define PINMUX_GPIO65__FUNC_GPS_FRAME_SYNC (MTK_PIN_NO(65) | 5)
+#define PINMUX_GPIO65__FUNC_PTA_RXD (MTK_PIN_NO(65) | 6)
+#define PINMUX_GPIO65__FUNC_DBG_MON_A22 (MTK_PIN_NO(65) | 7)
+
+#define PINMUX_GPIO66__FUNC_GPIO66 (MTK_PIN_NO(66) | 0)
+#define PINMUX_GPIO66__FUNC_SPI_CKA (MTK_PIN_NO(66) | 1)
+#define PINMUX_GPIO66__FUNC_USB_DRVVBUS (MTK_PIN_NO(66) | 2)
+#define PINMUX_GPIO66__FUNC_I2S3_BCK (MTK_PIN_NO(66) | 3)
+#define PINMUX_GPIO66__FUNC_KCOL2 (MTK_PIN_NO(66) | 4)
+#define PINMUX_GPIO66__FUNC_PTA_TXD (MTK_PIN_NO(66) | 6)
+#define PINMUX_GPIO66__FUNC_DBG_MON_A23 (MTK_PIN_NO(66) | 7)
+
+#define PINMUX_GPIO67__FUNC_GPIO67 (MTK_PIN_NO(67) | 0)
+#define PINMUX_GPIO67__FUNC_SPI_MIA (MTK_PIN_NO(67) | 1)
+#define PINMUX_GPIO67__FUNC_SPI_MOA (MTK_PIN_NO(67) | 2)
+#define PINMUX_GPIO67__FUNC_I2S3_DO (MTK_PIN_NO(67) | 3)
+#define PINMUX_GPIO67__FUNC_PTA_RXD (MTK_PIN_NO(67) | 4)
+#define PINMUX_GPIO67__FUNC_IDDIG (MTK_PIN_NO(67) | 5)
+#define PINMUX_GPIO67__FUNC_UCTS1 (MTK_PIN_NO(67) | 6)
+#define PINMUX_GPIO67__FUNC_DBG_MON_A24 (MTK_PIN_NO(67) | 7)
+
+#define PINMUX_GPIO68__FUNC_GPIO68 (MTK_PIN_NO(68) | 0)
+#define PINMUX_GPIO68__FUNC_SPI_MOA (MTK_PIN_NO(68) | 1)
+#define PINMUX_GPIO68__FUNC_SPI_MIA (MTK_PIN_NO(68) | 2)
+#define PINMUX_GPIO68__FUNC_I2S3_LRCK (MTK_PIN_NO(68) | 3)
+#define PINMUX_GPIO68__FUNC_PTA_TXD (MTK_PIN_NO(68) | 4)
+#define PINMUX_GPIO68__FUNC_ANT_SEL4 (MTK_PIN_NO(68) | 5)
+#define PINMUX_GPIO68__FUNC_URTS1 (MTK_PIN_NO(68) | 6)
+#define PINMUX_GPIO68__FUNC_DBG_MON_A25 (MTK_PIN_NO(68) | 7)
+
+#define PINMUX_GPIO69__FUNC_GPIO69 (MTK_PIN_NO(69) | 0)
+#define PINMUX_GPIO69__FUNC_DISP_PWM (MTK_PIN_NO(69) | 1)
+#define PINMUX_GPIO69__FUNC_PWM1 (MTK_PIN_NO(69) | 2)
+#define PINMUX_GPIO69__FUNC_LTE_MD32_JTAG_TRST (MTK_PIN_NO(69) | 3)
+#define PINMUX_GPIO69__FUNC_TDD_TRSTN (MTK_PIN_NO(69) | 4)
+#define PINMUX_GPIO69__FUNC_ANT_SEL7 (MTK_PIN_NO(69) | 5)
+#define PINMUX_GPIO69__FUNC_DM_JTINTP (MTK_PIN_NO(69) | 6)
+
+#define PINMUX_GPIO70__FUNC_GPIO70 (MTK_PIN_NO(70) | 0)
+#define PINMUX_GPIO70__FUNC_JTMS (MTK_PIN_NO(70) | 1)
+#define PINMUX_GPIO70__FUNC_CONN_MCU_TMS (MTK_PIN_NO(70) | 2)
+#define PINMUX_GPIO70__FUNC_LTE_MD32_JTAG_TMS (MTK_PIN_NO(70) | 3)
+#define PINMUX_GPIO70__FUNC_TDD_TMS (MTK_PIN_NO(70) | 4)
+#define PINMUX_GPIO70__FUNC_CORESONIC_SWD (MTK_PIN_NO(70) | 5)
+#define PINMUX_GPIO70__FUNC_DM_OTMS (MTK_PIN_NO(70) | 6)
+#define PINMUX_GPIO70__FUNC_DFD_TMS (MTK_PIN_NO(70) | 7)
+
+#define PINMUX_GPIO71__FUNC_GPIO71 (MTK_PIN_NO(71) | 0)
+#define PINMUX_GPIO71__FUNC_JTCK (MTK_PIN_NO(71) | 1)
+#define PINMUX_GPIO71__FUNC_CONN_MCU_TCK_1 (MTK_PIN_NO(71) | 2)
+#define PINMUX_GPIO71__FUNC_LTE_MD32_JTAG_TCK (MTK_PIN_NO(71) | 3)
+#define PINMUX_GPIO71__FUNC_TDD_TCK (MTK_PIN_NO(71) | 4)
+#define PINMUX_GPIO71__FUNC_CORESONIC_SWCK (MTK_PIN_NO(71) | 5)
+#define PINMUX_GPIO71__FUNC_DM_OTCK (MTK_PIN_NO(71) | 6)
+#define PINMUX_GPIO71__FUNC_DFD_TCK_XI (MTK_PIN_NO(71) | 7)
+
+#define PINMUX_GPIO72__FUNC_GPIO72 (MTK_PIN_NO(72) | 0)
+#define PINMUX_GPIO72__FUNC_JTDI (MTK_PIN_NO(72) | 1)
+#define PINMUX_GPIO72__FUNC_CONN_MCU_TDI (MTK_PIN_NO(72) | 2)
+#define PINMUX_GPIO72__FUNC_LTE_MD32_JTAG_TDI (MTK_PIN_NO(72) | 3)
+#define PINMUX_GPIO72__FUNC_TDD_TDI (MTK_PIN_NO(72) | 4)
+#define PINMUX_GPIO72__FUNC_DM_OTDI (MTK_PIN_NO(72) | 6)
+#define PINMUX_GPIO72__FUNC_DFD_TDI (MTK_PIN_NO(72) | 7)
+
+#define PINMUX_GPIO73__FUNC_GPIO73 (MTK_PIN_NO(73) | 0)
+#define PINMUX_GPIO73__FUNC_JTDO (MTK_PIN_NO(73) | 1)
+#define PINMUX_GPIO73__FUNC_CONN_MCU_TDO (MTK_PIN_NO(73) | 2)
+#define PINMUX_GPIO73__FUNC_LTE_MD32_JTAG_TDO (MTK_PIN_NO(73) | 3)
+#define PINMUX_GPIO73__FUNC_TDD_TDO (MTK_PIN_NO(73) | 4)
+#define PINMUX_GPIO73__FUNC_DM_OTDO (MTK_PIN_NO(73) | 6)
+#define PINMUX_GPIO73__FUNC_DFD_TDO (MTK_PIN_NO(73) | 7)
+
+#define PINMUX_GPIO74__FUNC_GPIO74 (MTK_PIN_NO(74) | 0)
+#define PINMUX_GPIO74__FUNC_URXD0 (MTK_PIN_NO(74) | 1)
+#define PINMUX_GPIO74__FUNC_UTXD0 (MTK_PIN_NO(74) | 2)
+#define PINMUX_GPIO74__FUNC_MD_URXD (MTK_PIN_NO(74) | 3)
+#define PINMUX_GPIO74__FUNC_SDA3 (MTK_PIN_NO(74) | 4)
+#define PINMUX_GPIO74__FUNC_C2K_UART0_RXD (MTK_PIN_NO(74) | 5)
+#define PINMUX_GPIO74__FUNC_LTE_URXD (MTK_PIN_NO(74) | 6)
+#define PINMUX_GPIO74__FUNC_AUXIF_ST (MTK_PIN_NO(74) | 7)
+
+#define PINMUX_GPIO75__FUNC_GPIO75 (MTK_PIN_NO(75) | 0)
+#define PINMUX_GPIO75__FUNC_UTXD0 (MTK_PIN_NO(75) | 1)
+#define PINMUX_GPIO75__FUNC_URXD0 (MTK_PIN_NO(75) | 2)
+#define PINMUX_GPIO75__FUNC_MD_UTXD (MTK_PIN_NO(75) | 3)
+#define PINMUX_GPIO75__FUNC_TDD_TXD (MTK_PIN_NO(75) | 4)
+#define PINMUX_GPIO75__FUNC_C2K_UART0_TXD (MTK_PIN_NO(75) | 5)
+#define PINMUX_GPIO75__FUNC_LTE_UTXD (MTK_PIN_NO(75) | 6)
+
+#define PINMUX_GPIO76__FUNC_GPIO76 (MTK_PIN_NO(76) | 0)
+#define PINMUX_GPIO76__FUNC_URXD1 (MTK_PIN_NO(76) | 1)
+#define PINMUX_GPIO76__FUNC_UTXD1 (MTK_PIN_NO(76) | 2)
+#define PINMUX_GPIO76__FUNC_MD_URXD (MTK_PIN_NO(76) | 3)
+#define PINMUX_GPIO76__FUNC_SCL3 (MTK_PIN_NO(76) | 4)
+#define PINMUX_GPIO76__FUNC_LTE_URXD (MTK_PIN_NO(76) | 5)
+#define PINMUX_GPIO76__FUNC_C2K_UART0_RXD (MTK_PIN_NO(76) | 6)
+#define PINMUX_GPIO76__FUNC_AUXIF_CLK (MTK_PIN_NO(76) | 7)
+
+#define PINMUX_GPIO77__FUNC_GPIO77 (MTK_PIN_NO(77) | 0)
+#define PINMUX_GPIO77__FUNC_UTXD1 (MTK_PIN_NO(77) | 1)
+#define PINMUX_GPIO77__FUNC_URXD1 (MTK_PIN_NO(77) | 2)
+#define PINMUX_GPIO77__FUNC_MD_UTXD (MTK_PIN_NO(77) | 3)
+#define PINMUX_GPIO77__FUNC_TDD_TXD (MTK_PIN_NO(77) | 4)
+#define PINMUX_GPIO77__FUNC_LTE_UTXD (MTK_PIN_NO(77) | 5)
+#define PINMUX_GPIO77__FUNC_C2K_UART0_TXD (MTK_PIN_NO(77) | 6)
+
+#define PINMUX_GPIO78__FUNC_GPIO78 (MTK_PIN_NO(78) | 0)
+#define PINMUX_GPIO78__FUNC_I2S0_DI (MTK_PIN_NO(78) | 1)
+#define PINMUX_GPIO78__FUNC_PCM1_DI (MTK_PIN_NO(78) | 2)
+#define PINMUX_GPIO78__FUNC_I2S3_DO (MTK_PIN_NO(78) | 3)
+#define PINMUX_GPIO78__FUNC_I2S1_DO (MTK_PIN_NO(78) | 4)
+#define PINMUX_GPIO78__FUNC_PWM0 (MTK_PIN_NO(78) | 5)
+#define PINMUX_GPIO78__FUNC_I2S2_DI (MTK_PIN_NO(78) | 6)
+#define PINMUX_GPIO78__FUNC_DBG_MON_A26 (MTK_PIN_NO(78) | 7)
+
+#define PINMUX_GPIO79__FUNC_GPIO79 (MTK_PIN_NO(79) | 0)
+#define PINMUX_GPIO79__FUNC_I2S0_LRCK (MTK_PIN_NO(79) | 1)
+#define PINMUX_GPIO79__FUNC_PCM1_SYNC (MTK_PIN_NO(79) | 2)
+#define PINMUX_GPIO79__FUNC_I2S3_LRCK (MTK_PIN_NO(79) | 3)
+#define PINMUX_GPIO79__FUNC_I2S1_LRCK (MTK_PIN_NO(79) | 4)
+#define PINMUX_GPIO79__FUNC_PWM3 (MTK_PIN_NO(79) | 5)
+#define PINMUX_GPIO79__FUNC_I2S2_LRCK (MTK_PIN_NO(79) | 6)
+#define PINMUX_GPIO79__FUNC_DBG_MON_A27 (MTK_PIN_NO(79) | 7)
+
+#define PINMUX_GPIO80__FUNC_GPIO80 (MTK_PIN_NO(80) | 0)
+#define PINMUX_GPIO80__FUNC_I2S0_BCK (MTK_PIN_NO(80) | 1)
+#define PINMUX_GPIO80__FUNC_PCM1_CLK (MTK_PIN_NO(80) | 2)
+#define PINMUX_GPIO80__FUNC_I2S3_BCK (MTK_PIN_NO(80) | 3)
+#define PINMUX_GPIO80__FUNC_I2S1_BCK (MTK_PIN_NO(80) | 4)
+#define PINMUX_GPIO80__FUNC_PWM4 (MTK_PIN_NO(80) | 5)
+#define PINMUX_GPIO80__FUNC_I2S2_BCK (MTK_PIN_NO(80) | 6)
+#define PINMUX_GPIO80__FUNC_DBG_MON_A28 (MTK_PIN_NO(80) | 7)
+
+#define PINMUX_GPIO81__FUNC_GPIO81 (MTK_PIN_NO(81) | 0)
+#define PINMUX_GPIO81__FUNC_KROW0 (MTK_PIN_NO(81) | 1)
+#define PINMUX_GPIO81__FUNC_CONN_MCU_DBGI_N (MTK_PIN_NO(81) | 3)
+#define PINMUX_GPIO81__FUNC_CORESONIC_SWCK (MTK_PIN_NO(81) | 4)
+#define PINMUX_GPIO81__FUNC_C2K_TCK (MTK_PIN_NO(81) | 5)
+#define PINMUX_GPIO81__FUNC_C2K_DM_EINT1 (MTK_PIN_NO(81) | 7)
+
+#define PINMUX_GPIO82__FUNC_GPIO82 (MTK_PIN_NO(82) | 0)
+#define PINMUX_GPIO82__FUNC_KROW1 (MTK_PIN_NO(82) | 1)
+#define PINMUX_GPIO82__FUNC_CONN_MCU_TRST_B (MTK_PIN_NO(82) | 3)
+#define PINMUX_GPIO82__FUNC_CORESONIC_SWD (MTK_PIN_NO(82) | 4)
+#define PINMUX_GPIO82__FUNC_C2K_NTRST (MTK_PIN_NO(82) | 5)
+#define PINMUX_GPIO82__FUNC_USB_DRVVBUS (MTK_PIN_NO(82) | 6)
+#define PINMUX_GPIO82__FUNC_C2K_DM_EINT2 (MTK_PIN_NO(82) | 7)
+
+#define PINMUX_GPIO83__FUNC_GPIO83 (MTK_PIN_NO(83) | 0)
+#define PINMUX_GPIO83__FUNC_KROW2 (MTK_PIN_NO(83) | 1)
+#define PINMUX_GPIO83__FUNC_USB_DRVVBUS (MTK_PIN_NO(83) | 2)
+#define PINMUX_GPIO83__FUNC_C2K_TDI (MTK_PIN_NO(83) | 5)
+#define PINMUX_GPIO83__FUNC_C2K_DM_EINT3 (MTK_PIN_NO(83) | 7)
+
+#define PINMUX_GPIO84__FUNC_GPIO84 (MTK_PIN_NO(84) | 0)
+#define PINMUX_GPIO84__FUNC_KCOL0 (MTK_PIN_NO(84) | 1)
+#define PINMUX_GPIO84__FUNC_URTS0 (MTK_PIN_NO(84) | 2)
+#define PINMUX_GPIO84__FUNC_CONN_MCU_DBGACK_N (MTK_PIN_NO(84) | 3)
+#define PINMUX_GPIO84__FUNC_SCL2 (MTK_PIN_NO(84) | 4)
+#define PINMUX_GPIO84__FUNC_C2K_TDO (MTK_PIN_NO(84) | 5)
+#define PINMUX_GPIO84__FUNC_AUXIF_CLK (MTK_PIN_NO(84) | 6)
+
+#define PINMUX_GPIO85__FUNC_GPIO85 (MTK_PIN_NO(85) | 0)
+#define PINMUX_GPIO85__FUNC_KCOL1 (MTK_PIN_NO(85) | 1)
+#define PINMUX_GPIO85__FUNC_UCTS0 (MTK_PIN_NO(85) | 2)
+#define PINMUX_GPIO85__FUNC_UCTS1 (MTK_PIN_NO(85) | 3)
+#define PINMUX_GPIO85__FUNC_SDA2 (MTK_PIN_NO(85) | 4)
+#define PINMUX_GPIO85__FUNC_C2K_TMS (MTK_PIN_NO(85) | 5)
+#define PINMUX_GPIO85__FUNC_AUXIF_ST (MTK_PIN_NO(85) | 6)
+#define PINMUX_GPIO85__FUNC_DBG_MON_A31 (MTK_PIN_NO(85) | 7)
+
+#define PINMUX_GPIO86__FUNC_GPIO86 (MTK_PIN_NO(86) | 0)
+#define PINMUX_GPIO86__FUNC_KCOL2 (MTK_PIN_NO(86) | 1)
+#define PINMUX_GPIO86__FUNC_URTS1 (MTK_PIN_NO(86) | 3)
+#define PINMUX_GPIO86__FUNC_C2K_RTCK (MTK_PIN_NO(86) | 5)
+#define PINMUX_GPIO86__FUNC_DBG_MON_A32 (MTK_PIN_NO(86) | 7)
+
+#define PINMUX_GPIO87__FUNC_GPIO87 (MTK_PIN_NO(87) | 0)
+#define PINMUX_GPIO87__FUNC_BPI_BUS5 (MTK_PIN_NO(87) | 1)
+#define PINMUX_GPIO87__FUNC_LTE_C2K_BPI_BUS5 (MTK_PIN_NO(87) | 2)
+#define PINMUX_GPIO87__FUNC_C2K_BPI_BUS5 (MTK_PIN_NO(87) | 5)
+#define PINMUX_GPIO87__FUNC_DBG_MON_B0 (MTK_PIN_NO(87) | 7)
+
+#define PINMUX_GPIO88__FUNC_GPIO88 (MTK_PIN_NO(88) | 0)
+#define PINMUX_GPIO88__FUNC_BPI_BUS6 (MTK_PIN_NO(88) | 1)
+#define PINMUX_GPIO88__FUNC_LTE_C2K_BPI_BUS6 (MTK_PIN_NO(88) | 2)
+#define PINMUX_GPIO88__FUNC_C2K_BPI_BUS6 (MTK_PIN_NO(88) | 5)
+#define PINMUX_GPIO88__FUNC_DBG_MON_B1 (MTK_PIN_NO(88) | 7)
+
+#define PINMUX_GPIO89__FUNC_GPIO89 (MTK_PIN_NO(89) | 0)
+#define PINMUX_GPIO89__FUNC_BPI_BUS7 (MTK_PIN_NO(89) | 1)
+#define PINMUX_GPIO89__FUNC_LTE_C2K_BPI_BUS7 (MTK_PIN_NO(89) | 2)
+#define PINMUX_GPIO89__FUNC_CLKM0 (MTK_PIN_NO(89) | 3)
+#define PINMUX_GPIO89__FUNC_C2K_BPI_BUS7 (MTK_PIN_NO(89) | 5)
+#define PINMUX_GPIO89__FUNC_DBG_MON_B2 (MTK_PIN_NO(89) | 7)
+
+#define PINMUX_GPIO90__FUNC_GPIO90 (MTK_PIN_NO(90) | 0)
+#define PINMUX_GPIO90__FUNC_BPI_BUS8 (MTK_PIN_NO(90) | 1)
+#define PINMUX_GPIO90__FUNC_LTE_C2K_BPI_BUS8 (MTK_PIN_NO(90) | 2)
+#define PINMUX_GPIO90__FUNC_CLKM1 (MTK_PIN_NO(90) | 3)
+#define PINMUX_GPIO90__FUNC_C2K_BPI_BUS8 (MTK_PIN_NO(90) | 5)
+#define PINMUX_GPIO90__FUNC_DBG_MON_B3 (MTK_PIN_NO(90) | 7)
+
+#define PINMUX_GPIO91__FUNC_GPIO91 (MTK_PIN_NO(91) | 0)
+#define PINMUX_GPIO91__FUNC_BPI_BUS9 (MTK_PIN_NO(91) | 1)
+#define PINMUX_GPIO91__FUNC_LTE_C2K_BPI_BUS9 (MTK_PIN_NO(91) | 2)
+#define PINMUX_GPIO91__FUNC_CLKM2 (MTK_PIN_NO(91) | 3)
+#define PINMUX_GPIO91__FUNC_C2K_BPI_BUS9 (MTK_PIN_NO(91) | 5)
+#define PINMUX_GPIO91__FUNC_DBG_MON_B4 (MTK_PIN_NO(91) | 7)
+
+#define PINMUX_GPIO92__FUNC_GPIO92 (MTK_PIN_NO(92) | 0)
+#define PINMUX_GPIO92__FUNC_BPI_BUS10 (MTK_PIN_NO(92) | 1)
+#define PINMUX_GPIO92__FUNC_LTE_C2K_BPI_BUS10 (MTK_PIN_NO(92) | 2)
+#define PINMUX_GPIO92__FUNC_CLKM3 (MTK_PIN_NO(92) | 3)
+#define PINMUX_GPIO92__FUNC_C2K_BPI_BUS10 (MTK_PIN_NO(92) | 5)
+#define PINMUX_GPIO92__FUNC_DBG_MON_B5 (MTK_PIN_NO(92) | 7)
+
+#define PINMUX_GPIO93__FUNC_GPIO93 (MTK_PIN_NO(93) | 0)
+#define PINMUX_GPIO93__FUNC_BPI_BUS11 (MTK_PIN_NO(93) | 1)
+#define PINMUX_GPIO93__FUNC_LTE_C2K_BPI_BUS11 (MTK_PIN_NO(93) | 2)
+#define PINMUX_GPIO93__FUNC_C2K_BPI_BUS11 (MTK_PIN_NO(93) | 5)
+#define PINMUX_GPIO93__FUNC_DBG_MON_B6 (MTK_PIN_NO(93) | 7)
+
+#define PINMUX_GPIO94__FUNC_GPIO94 (MTK_PIN_NO(94) | 0)
+#define PINMUX_GPIO94__FUNC_BPI_BUS12 (MTK_PIN_NO(94) | 1)
+#define PINMUX_GPIO94__FUNC_LTE_C2K_BPI_BUS12 (MTK_PIN_NO(94) | 2)
+#define PINMUX_GPIO94__FUNC_C2K_BPI_BUS12 (MTK_PIN_NO(94) | 5)
+#define PINMUX_GPIO94__FUNC_DBG_MON_B7 (MTK_PIN_NO(94) | 7)
+
+#define PINMUX_GPIO95__FUNC_GPIO95 (MTK_PIN_NO(95) | 0)
+#define PINMUX_GPIO95__FUNC_BPI_BUS13 (MTK_PIN_NO(95) | 1)
+#define PINMUX_GPIO95__FUNC_LTE_C2K_BPI_BUS13 (MTK_PIN_NO(95) | 2)
+#define PINMUX_GPIO95__FUNC_C2K_BPI_BUS13 (MTK_PIN_NO(95) | 5)
+#define PINMUX_GPIO95__FUNC_DBG_MON_B8 (MTK_PIN_NO(95) | 7)
+
+#define PINMUX_GPIO96__FUNC_GPIO96 (MTK_PIN_NO(96) | 0)
+#define PINMUX_GPIO96__FUNC_BPI_BUS14 (MTK_PIN_NO(96) | 1)
+#define PINMUX_GPIO96__FUNC_LTE_C2K_BPI_BUS14 (MTK_PIN_NO(96) | 2)
+#define PINMUX_GPIO96__FUNC_C2K_BPI_BUS14 (MTK_PIN_NO(96) | 5)
+#define PINMUX_GPIO96__FUNC_DBG_MON_B9 (MTK_PIN_NO(96) | 7)
+
+#define PINMUX_GPIO97__FUNC_GPIO97 (MTK_PIN_NO(97) | 0)
+#define PINMUX_GPIO97__FUNC_BPI_BUS15 (MTK_PIN_NO(97) | 1)
+#define PINMUX_GPIO97__FUNC_LTE_C2K_BPI_BUS15 (MTK_PIN_NO(97) | 2)
+#define PINMUX_GPIO97__FUNC_C2K_BPI_BUS15 (MTK_PIN_NO(97) | 5)
+#define PINMUX_GPIO97__FUNC_DBG_MON_B10 (MTK_PIN_NO(97) | 7)
+
+#define PINMUX_GPIO98__FUNC_GPIO98 (MTK_PIN_NO(98) | 0)
+#define PINMUX_GPIO98__FUNC_BPI_BUS16 (MTK_PIN_NO(98) | 1)
+#define PINMUX_GPIO98__FUNC_LTE_C2K_BPI_BUS16 (MTK_PIN_NO(98) | 2)
+#define PINMUX_GPIO98__FUNC_C2K_BPI_BUS16 (MTK_PIN_NO(98) | 5)
+#define PINMUX_GPIO98__FUNC_DBG_MON_B11 (MTK_PIN_NO(98) | 7)
+
+#define PINMUX_GPIO99__FUNC_GPIO99 (MTK_PIN_NO(99) | 0)
+#define PINMUX_GPIO99__FUNC_BPI_BUS17 (MTK_PIN_NO(99) | 1)
+#define PINMUX_GPIO99__FUNC_LTE_C2K_BPI_BUS17 (MTK_PIN_NO(99) | 2)
+#define PINMUX_GPIO99__FUNC_C2K_BPI_BUS17 (MTK_PIN_NO(99) | 5)
+#define PINMUX_GPIO99__FUNC_DBG_MON_B12 (MTK_PIN_NO(99) | 7)
+
+#define PINMUX_GPIO100__FUNC_GPIO100 (MTK_PIN_NO(100) | 0)
+#define PINMUX_GPIO100__FUNC_BPI_BUS18 (MTK_PIN_NO(100) | 1)
+#define PINMUX_GPIO100__FUNC_LTE_C2K_BPI_BUS18 (MTK_PIN_NO(100) | 2)
+#define PINMUX_GPIO100__FUNC_C2K_BPI_BUS18 (MTK_PIN_NO(100) | 5)
+#define PINMUX_GPIO100__FUNC_DBG_MON_B13 (MTK_PIN_NO(100) | 7)
+
+#define PINMUX_GPIO101__FUNC_GPIO101 (MTK_PIN_NO(101) | 0)
+#define PINMUX_GPIO101__FUNC_BPI_BUS19 (MTK_PIN_NO(101) | 1)
+#define PINMUX_GPIO101__FUNC_LTE_C2K_BPI_BUS19 (MTK_PIN_NO(101) | 2)
+#define PINMUX_GPIO101__FUNC_C2K_BPI_BUS19 (MTK_PIN_NO(101) | 5)
+#define PINMUX_GPIO101__FUNC_DBG_MON_B14 (MTK_PIN_NO(101) | 7)
+
+#define PINMUX_GPIO102__FUNC_GPIO102 (MTK_PIN_NO(102) | 0)
+#define PINMUX_GPIO102__FUNC_BPI_BUS20 (MTK_PIN_NO(102) | 1)
+#define PINMUX_GPIO102__FUNC_LTE_C2K_BPI_BUS20 (MTK_PIN_NO(102) | 2)
+#define PINMUX_GPIO102__FUNC_C2K_BPI_BUS20 (MTK_PIN_NO(102) | 5)
+#define PINMUX_GPIO102__FUNC_DBG_MON_B15 (MTK_PIN_NO(102) | 7)
+
+#define PINMUX_GPIO103__FUNC_GPIO103 (MTK_PIN_NO(103) | 0)
+#define PINMUX_GPIO103__FUNC_C2K_TXBPI (MTK_PIN_NO(103) | 1)
+#define PINMUX_GPIO103__FUNC_DBG_MON_B16 (MTK_PIN_NO(103) | 7)
+
+#define PINMUX_GPIO104__FUNC_GPIO104 (MTK_PIN_NO(104) | 0)
+#define PINMUX_GPIO104__FUNC_RFIC1_BSI_EN (MTK_PIN_NO(104) | 1)
+#define PINMUX_GPIO104__FUNC_C2K_RX_BSI_EN (MTK_PIN_NO(104) | 5)
+#define PINMUX_GPIO104__FUNC_DBG_MON_B17 (MTK_PIN_NO(104) | 7)
+
+#define PINMUX_GPIO105__FUNC_GPIO105 (MTK_PIN_NO(105) | 0)
+#define PINMUX_GPIO105__FUNC_RFIC1_BSI_CK (MTK_PIN_NO(105) | 1)
+#define PINMUX_GPIO105__FUNC_C2K_RX_BSI_CLK (MTK_PIN_NO(105) | 5)
+#define PINMUX_GPIO105__FUNC_DBG_MON_B18 (MTK_PIN_NO(105) | 7)
+
+#define PINMUX_GPIO106__FUNC_GPIO106 (MTK_PIN_NO(106) | 0)
+#define PINMUX_GPIO106__FUNC_RFIC1_BSI_D0 (MTK_PIN_NO(106) | 1)
+#define PINMUX_GPIO106__FUNC_C2K_RX_BSI_DATA (MTK_PIN_NO(106) | 5)
+#define PINMUX_GPIO106__FUNC_DBG_MON_B19 (MTK_PIN_NO(106) | 7)
+
+#define PINMUX_GPIO107__FUNC_GPIO107 (MTK_PIN_NO(107) | 0)
+#define PINMUX_GPIO107__FUNC_RFIC1_BSI_D1 (MTK_PIN_NO(107) | 1)
+#define PINMUX_GPIO107__FUNC_C2K_TX_BSI_EN (MTK_PIN_NO(107) | 5)
+#define PINMUX_GPIO107__FUNC_DBG_MON_B20 (MTK_PIN_NO(107) | 7)
+
+#define PINMUX_GPIO108__FUNC_GPIO108 (MTK_PIN_NO(108) | 0)
+#define PINMUX_GPIO108__FUNC_RFIC1_BSI_D2 (MTK_PIN_NO(108) | 1)
+#define PINMUX_GPIO108__FUNC_C2K_TX_BSI_CLK (MTK_PIN_NO(108) | 5)
+#define PINMUX_GPIO108__FUNC_DBG_MON_B21 (MTK_PIN_NO(108) | 7)
+
+#define PINMUX_GPIO109__FUNC_GPIO109 (MTK_PIN_NO(109) | 0)
+#define PINMUX_GPIO109__FUNC_C2K_TX_BSI_DATA (MTK_PIN_NO(109) | 5)
+#define PINMUX_GPIO109__FUNC_DBG_MON_B22 (MTK_PIN_NO(109) | 7)
+
+#define PINMUX_GPIO110__FUNC_GPIO110 (MTK_PIN_NO(110) | 0)
+#define PINMUX_GPIO110__FUNC_RFIC0_BSI_EN (MTK_PIN_NO(110) | 1)
+#define PINMUX_GPIO110__FUNC_SPM_BSI_EN (MTK_PIN_NO(110) | 4)
+#define PINMUX_GPIO110__FUNC_DBG_MON_B23 (MTK_PIN_NO(110) | 7)
+
+#define PINMUX_GPIO111__FUNC_GPIO111 (MTK_PIN_NO(111) | 0)
+#define PINMUX_GPIO111__FUNC_RFIC0_BSI_CK (MTK_PIN_NO(111) | 1)
+#define PINMUX_GPIO111__FUNC_SPM_BSI_CLK (MTK_PIN_NO(111) | 4)
+#define PINMUX_GPIO111__FUNC_DBG_MON_B24 (MTK_PIN_NO(111) | 7)
+
+#define PINMUX_GPIO112__FUNC_GPIO112 (MTK_PIN_NO(112) | 0)
+#define PINMUX_GPIO112__FUNC_RFIC0_BSI_D2 (MTK_PIN_NO(112) | 1)
+#define PINMUX_GPIO112__FUNC_SPM_BSI_D2 (MTK_PIN_NO(112) | 4)
+#define PINMUX_GPIO112__FUNC_DBG_MON_B25 (MTK_PIN_NO(112) | 7)
+
+#define PINMUX_GPIO113__FUNC_GPIO113 (MTK_PIN_NO(113) | 0)
+#define PINMUX_GPIO113__FUNC_RFIC0_BSI_D1 (MTK_PIN_NO(113) | 1)
+#define PINMUX_GPIO113__FUNC_SPM_BSI_D1 (MTK_PIN_NO(113) | 4)
+#define PINMUX_GPIO113__FUNC_DBG_MON_B26 (MTK_PIN_NO(113) | 7)
+
+#define PINMUX_GPIO114__FUNC_GPIO114 (MTK_PIN_NO(114) | 0)
+#define PINMUX_GPIO114__FUNC_RFIC0_BSI_D0 (MTK_PIN_NO(114) | 1)
+#define PINMUX_GPIO114__FUNC_SPM_BSI_D0 (MTK_PIN_NO(114) | 4)
+#define PINMUX_GPIO114__FUNC_DBG_MON_B27 (MTK_PIN_NO(114) | 7)
+
+#define PINMUX_GPIO115__FUNC_GPIO115 (MTK_PIN_NO(115) | 0)
+#define PINMUX_GPIO115__FUNC_AUXIN0 (MTK_PIN_NO(115) | 1)
+
+#define PINMUX_GPIO116__FUNC_GPIO116 (MTK_PIN_NO(116) | 0)
+#define PINMUX_GPIO116__FUNC_AUXIN1 (MTK_PIN_NO(116) | 1)
+
+#define PINMUX_GPIO117__FUNC_GPIO117 (MTK_PIN_NO(117) | 0)
+#define PINMUX_GPIO117__FUNC_AUXIN2 (MTK_PIN_NO(117) | 1)
+
+#define PINMUX_GPIO118__FUNC_GPIO118 (MTK_PIN_NO(118) | 0)
+#define PINMUX_GPIO118__FUNC_TXBPI (MTK_PIN_NO(118) | 1)
+
+#define PINMUX_GPIO119__FUNC_GPIO119 (MTK_PIN_NO(119) | 0)
+#define PINMUX_GPIO119__FUNC_BPI_BUS0 (MTK_PIN_NO(119) | 1)
+#define PINMUX_GPIO119__FUNC_DBG_MON_B28 (MTK_PIN_NO(119) | 7)
+
+#define PINMUX_GPIO120__FUNC_GPIO120 (MTK_PIN_NO(120) | 0)
+#define PINMUX_GPIO120__FUNC_BPI_BUS1 (MTK_PIN_NO(120) | 1)
+#define PINMUX_GPIO120__FUNC_DBG_MON_B29 (MTK_PIN_NO(120) | 7)
+
+#define PINMUX_GPIO121__FUNC_GPIO121 (MTK_PIN_NO(121) | 0)
+#define PINMUX_GPIO121__FUNC_BPI_BUS2 (MTK_PIN_NO(121) | 1)
+#define PINMUX_GPIO121__FUNC_DBG_MON_B30 (MTK_PIN_NO(121) | 7)
+
+#define PINMUX_GPIO122__FUNC_GPIO122 (MTK_PIN_NO(122) | 0)
+#define PINMUX_GPIO122__FUNC_BPI_BUS3 (MTK_PIN_NO(122) | 1)
+#define PINMUX_GPIO122__FUNC_DBG_MON_B31 (MTK_PIN_NO(122) | 7)
+
+#define PINMUX_GPIO123__FUNC_GPIO123 (MTK_PIN_NO(123) | 0)
+#define PINMUX_GPIO123__FUNC_BPI_BUS4 (MTK_PIN_NO(123) | 1)
+#define PINMUX_GPIO123__FUNC_DBG_MON_B32 (MTK_PIN_NO(123) | 7)
+
+#define PINMUX_GPIO124__FUNC_GPIO124 (MTK_PIN_NO(124) | 0)
+#define PINMUX_GPIO124__FUNC_BPI_BUS21 (MTK_PIN_NO(124) | 1)
+#define PINMUX_GPIO124__FUNC_DPI_HSYNC1 (MTK_PIN_NO(124) | 5)
+#define PINMUX_GPIO124__FUNC_KCOL2 (MTK_PIN_NO(124) | 6)
+#define PINMUX_GPIO124__FUNC_TDD_TXD (MTK_PIN_NO(124) | 7)
+
+#define PINMUX_GPIO125__FUNC_GPIO125 (MTK_PIN_NO(125) | 0)
+#define PINMUX_GPIO125__FUNC_BPI_BUS22 (MTK_PIN_NO(125) | 1)
+#define PINMUX_GPIO125__FUNC_DPI_VSYNC1 (MTK_PIN_NO(125) | 5)
+#define PINMUX_GPIO125__FUNC_KROW2 (MTK_PIN_NO(125) | 6)
+#define PINMUX_GPIO125__FUNC_MD_URXD (MTK_PIN_NO(125) | 7)
+
+#define PINMUX_GPIO126__FUNC_GPIO126 (MTK_PIN_NO(126) | 0)
+#define PINMUX_GPIO126__FUNC_BPI_BUS23 (MTK_PIN_NO(126) | 1)
+#define PINMUX_GPIO126__FUNC_DPI_CK1 (MTK_PIN_NO(126) | 5)
+#define PINMUX_GPIO126__FUNC_I2S2_MCK (MTK_PIN_NO(126) | 6)
+#define PINMUX_GPIO126__FUNC_MD_UTXD (MTK_PIN_NO(126) | 7)
+
+#define PINMUX_GPIO127__FUNC_GPIO127 (MTK_PIN_NO(127) | 0)
+#define PINMUX_GPIO127__FUNC_BPI_BUS24 (MTK_PIN_NO(127) | 1)
+#define PINMUX_GPIO127__FUNC_CONN_MCU_DBGI_N (MTK_PIN_NO(127) | 3)
+#define PINMUX_GPIO127__FUNC_EXT_FRAME_SYNC (MTK_PIN_NO(127) | 4)
+#define PINMUX_GPIO127__FUNC_DPI_DE1 (MTK_PIN_NO(127) | 5)
+#define PINMUX_GPIO127__FUNC_SRCLKENAI1 (MTK_PIN_NO(127) | 6)
+#define PINMUX_GPIO127__FUNC_URXD0 (MTK_PIN_NO(127) | 7)
+
+#define PINMUX_GPIO128__FUNC_GPIO128 (MTK_PIN_NO(128) | 0)
+#define PINMUX_GPIO128__FUNC_BPI_BUS25 (MTK_PIN_NO(128) | 1)
+#define PINMUX_GPIO128__FUNC_GPS_FRAME_SYNC (MTK_PIN_NO(128) | 3)
+#define PINMUX_GPIO128__FUNC_I2S2_DI (MTK_PIN_NO(128) | 5)
+#define PINMUX_GPIO128__FUNC_PTA_RXD (MTK_PIN_NO(128) | 6)
+#define PINMUX_GPIO128__FUNC_UTXD0 (MTK_PIN_NO(128) | 7)
+
+#define PINMUX_GPIO129__FUNC_GPIO129 (MTK_PIN_NO(129) | 0)
+#define PINMUX_GPIO129__FUNC_BPI_BUS26 (MTK_PIN_NO(129) | 1)
+#define PINMUX_GPIO129__FUNC_DISP_PWM (MTK_PIN_NO(129) | 2)
+#define PINMUX_GPIO129__FUNC_I2S2_LRCK (MTK_PIN_NO(129) | 5)
+#define PINMUX_GPIO129__FUNC_PTA_TXD (MTK_PIN_NO(129) | 6)
+#define PINMUX_GPIO129__FUNC_LTE_URXD (MTK_PIN_NO(129) | 7)
+
+#define PINMUX_GPIO130__FUNC_GPIO130 (MTK_PIN_NO(130) | 0)
+#define PINMUX_GPIO130__FUNC_BPI_BUS27 (MTK_PIN_NO(130) | 1)
+#define PINMUX_GPIO130__FUNC_I2S2_BCK (MTK_PIN_NO(130) | 5)
+#define PINMUX_GPIO130__FUNC_IRTX_OUT (MTK_PIN_NO(130) | 6)
+#define PINMUX_GPIO130__FUNC_LTE_UTXD (MTK_PIN_NO(130) | 7)
+
+#define PINMUX_GPIO131__FUNC_GPIO131 (MTK_PIN_NO(131) | 0)
+#define PINMUX_GPIO131__FUNC_LTE_PAVM0 (MTK_PIN_NO(131) | 1)
+
+#define PINMUX_GPIO132__FUNC_GPIO132 (MTK_PIN_NO(132) | 0)
+#define PINMUX_GPIO132__FUNC_LTE_PAVM1 (MTK_PIN_NO(132) | 1)
+
+#define PINMUX_GPIO133__FUNC_GPIO133 (MTK_PIN_NO(133) | 0)
+#define PINMUX_GPIO133__FUNC_MIPI1_SCLK (MTK_PIN_NO(133) | 1)
+
+#define PINMUX_GPIO134__FUNC_GPIO134 (MTK_PIN_NO(134) | 0)
+#define PINMUX_GPIO134__FUNC_MIPI1_SDATA (MTK_PIN_NO(134) | 1)
+
+#define PINMUX_GPIO135__FUNC_GPIO135 (MTK_PIN_NO(135) | 0)
+#define PINMUX_GPIO135__FUNC_MIPI0_SCLK (MTK_PIN_NO(135) | 1)
+
+#define PINMUX_GPIO136__FUNC_GPIO136 (MTK_PIN_NO(136) | 0)
+#define PINMUX_GPIO136__FUNC_MIPI0_SDATA (MTK_PIN_NO(136) | 1)
+
+#define PINMUX_GPIO137__FUNC_GPIO137 (MTK_PIN_NO(137) | 0)
+#define PINMUX_GPIO137__FUNC_RTC32K_CK (MTK_PIN_NO(137) | 1)
+
+#define PINMUX_GPIO138__FUNC_GPIO138 (MTK_PIN_NO(138) | 0)
+#define PINMUX_GPIO138__FUNC_PWRAP_SPIDO (MTK_PIN_NO(138) | 1)
+#define PINMUX_GPIO138__FUNC_PWRAP_SPIDI (MTK_PIN_NO(138) | 2)
+
+#define PINMUX_GPIO139__FUNC_GPIO139 (MTK_PIN_NO(139) | 0)
+#define PINMUX_GPIO139__FUNC_PWRAP_SPIDI (MTK_PIN_NO(139) | 1)
+#define PINMUX_GPIO139__FUNC_PWRAP_SPIDO (MTK_PIN_NO(139) | 2)
+
+#define PINMUX_GPIO140__FUNC_GPIO140 (MTK_PIN_NO(140) | 0)
+#define PINMUX_GPIO140__FUNC_LTE_MD32_JTAG_TRST (MTK_PIN_NO(140) | 3)
+#define PINMUX_GPIO140__FUNC_TDD_TRSTN (MTK_PIN_NO(140) | 4)
+#define PINMUX_GPIO140__FUNC_DM_JTINTP (MTK_PIN_NO(140) | 5)
+
+#define PINMUX_GPIO141__FUNC_GPIO141 (MTK_PIN_NO(141) | 0)
+#define PINMUX_GPIO141__FUNC_PWRAP_SPICK_I (MTK_PIN_NO(141) | 1)
+
+#define PINMUX_GPIO142__FUNC_GPIO142 (MTK_PIN_NO(142) | 0)
+#define PINMUX_GPIO142__FUNC_PWRAP_SPICS_B_I (MTK_PIN_NO(142) | 1)
+
+#define PINMUX_GPIO143__FUNC_GPIO143 (MTK_PIN_NO(143) | 0)
+#define PINMUX_GPIO143__FUNC_AUD_CLK_MOSI (MTK_PIN_NO(143) | 1)
+
+#define PINMUX_GPIO144__FUNC_GPIO144 (MTK_PIN_NO(144) | 0)
+#define PINMUX_GPIO144__FUNC_AUD_DAT_MISO (MTK_PIN_NO(144) | 1)
+#define PINMUX_GPIO144__FUNC_AUD_DAT_MOSI (MTK_PIN_NO(144) | 3)
+
+#define PINMUX_GPIO145__FUNC_GPIO145 (MTK_PIN_NO(145) | 0)
+#define PINMUX_GPIO145__FUNC_AUD_DAT_MOSI (MTK_PIN_NO(145) | 1)
+#define PINMUX_GPIO145__FUNC_AUD_DAT_MISO (MTK_PIN_NO(145) | 3)
+
+#define PINMUX_GPIO146__FUNC_GPIO146 (MTK_PIN_NO(146) | 0)
+#define PINMUX_GPIO146__FUNC_LCM_RST (MTK_PIN_NO(146) | 1)
+
+#define PINMUX_GPIO147__FUNC_GPIO147 (MTK_PIN_NO(147) | 0)
+#define PINMUX_GPIO147__FUNC_DSI_TE (MTK_PIN_NO(147) | 1)
+
+#define PINMUX_GPIO148__FUNC_GPIO148 (MTK_PIN_NO(148) | 0)
+#define PINMUX_GPIO148__FUNC_SRCLKENA (MTK_PIN_NO(148) | 1)
+
+#define PINMUX_GPIO149__FUNC_GPIO149 (MTK_PIN_NO(149) | 0)
+#define PINMUX_GPIO149__FUNC_WATCHDOG (MTK_PIN_NO(149) | 1)
+
+#define PINMUX_GPIO150__FUNC_GPIO150 (MTK_PIN_NO(150) | 0)
+#define PINMUX_GPIO150__FUNC_TDP0 (MTK_PIN_NO(150) | 1)
+
+#define PINMUX_GPIO151__FUNC_GPIO151 (MTK_PIN_NO(151) | 0)
+#define PINMUX_GPIO151__FUNC_TDN0 (MTK_PIN_NO(151) | 1)
+
+#define PINMUX_GPIO152__FUNC_GPIO152 (MTK_PIN_NO(152) | 0)
+#define PINMUX_GPIO152__FUNC_TDP1 (MTK_PIN_NO(152) | 1)
+
+#define PINMUX_GPIO153__FUNC_GPIO153 (MTK_PIN_NO(153) | 0)
+#define PINMUX_GPIO153__FUNC_TDN1 (MTK_PIN_NO(153) | 1)
+
+#define PINMUX_GPIO154__FUNC_GPIO154 (MTK_PIN_NO(154) | 0)
+#define PINMUX_GPIO154__FUNC_TCP (MTK_PIN_NO(154) | 1)
+
+#define PINMUX_GPIO155__FUNC_GPIO155 (MTK_PIN_NO(155) | 0)
+#define PINMUX_GPIO155__FUNC_TCN (MTK_PIN_NO(155) | 1)
+
+#define PINMUX_GPIO156__FUNC_GPIO156 (MTK_PIN_NO(156) | 0)
+#define PINMUX_GPIO156__FUNC_TDP2 (MTK_PIN_NO(156) | 1)
+
+#define PINMUX_GPIO157__FUNC_GPIO157 (MTK_PIN_NO(157) | 0)
+#define PINMUX_GPIO157__FUNC_TDN2 (MTK_PIN_NO(157) | 1)
+
+#define PINMUX_GPIO158__FUNC_GPIO158 (MTK_PIN_NO(158) | 0)
+#define PINMUX_GPIO158__FUNC_TDP3 (MTK_PIN_NO(158) | 1)
+
+#define PINMUX_GPIO159__FUNC_GPIO159 (MTK_PIN_NO(159) | 0)
+#define PINMUX_GPIO159__FUNC_TDN3 (MTK_PIN_NO(159) | 1)
+
+#define PINMUX_GPIO160__FUNC_GPIO160 (MTK_PIN_NO(160) | 0)
+#define PINMUX_GPIO160__FUNC_MD_SIM2_SCLK (MTK_PIN_NO(160) | 1)
+#define PINMUX_GPIO160__FUNC_MD_SIM1_SCLK (MTK_PIN_NO(160) | 2)
+#define PINMUX_GPIO160__FUNC_UIM0_CLK (MTK_PIN_NO(160) | 3)
+#define PINMUX_GPIO160__FUNC_UIM1_CLK (MTK_PIN_NO(160) | 4)
+
+#define PINMUX_GPIO161__FUNC_GPIO161 (MTK_PIN_NO(161) | 0)
+#define PINMUX_GPIO161__FUNC_MD_SIM2_SRST (MTK_PIN_NO(161) | 1)
+#define PINMUX_GPIO161__FUNC_MD_SIM1_SRST (MTK_PIN_NO(161) | 2)
+#define PINMUX_GPIO161__FUNC_UIM0_RST (MTK_PIN_NO(161) | 3)
+#define PINMUX_GPIO161__FUNC_UIM1_RST (MTK_PIN_NO(161) | 4)
+
+#define PINMUX_GPIO162__FUNC_GPIO162 (MTK_PIN_NO(162) | 0)
+#define PINMUX_GPIO162__FUNC_MD_SIM2_SDAT (MTK_PIN_NO(162) | 1)
+#define PINMUX_GPIO162__FUNC_MD_SIM1_SDAT (MTK_PIN_NO(162) | 2)
+#define PINMUX_GPIO162__FUNC_UIM0_IO (MTK_PIN_NO(162) | 3)
+#define PINMUX_GPIO162__FUNC_UIM1_IO (MTK_PIN_NO(162) | 4)
+
+#define PINMUX_GPIO163__FUNC_GPIO163 (MTK_PIN_NO(163) | 0)
+#define PINMUX_GPIO163__FUNC_MD_SIM1_SCLK (MTK_PIN_NO(163) | 1)
+#define PINMUX_GPIO163__FUNC_MD_SIM2_SCLK (MTK_PIN_NO(163) | 2)
+#define PINMUX_GPIO163__FUNC_UIM1_CLK (MTK_PIN_NO(163) | 3)
+#define PINMUX_GPIO163__FUNC_UIM0_CLK (MTK_PIN_NO(163) | 4)
+
+#define PINMUX_GPIO164__FUNC_GPIO164 (MTK_PIN_NO(164) | 0)
+#define PINMUX_GPIO164__FUNC_MD_SIM1_SRST (MTK_PIN_NO(164) | 1)
+#define PINMUX_GPIO164__FUNC_MD_SIM2_SRST (MTK_PIN_NO(164) | 2)
+#define PINMUX_GPIO164__FUNC_UIM1_RST (MTK_PIN_NO(164) | 3)
+#define PINMUX_GPIO164__FUNC_UIM0_RST (MTK_PIN_NO(164) | 4)
+
+#define PINMUX_GPIO165__FUNC_GPIO165 (MTK_PIN_NO(165) | 0)
+#define PINMUX_GPIO165__FUNC_MD_SIM1_SDAT (MTK_PIN_NO(165) | 1)
+#define PINMUX_GPIO165__FUNC_MD_SIM2_SDAT (MTK_PIN_NO(165) | 2)
+#define PINMUX_GPIO165__FUNC_UIM1_IO (MTK_PIN_NO(165) | 3)
+#define PINMUX_GPIO165__FUNC_UIM0_IO (MTK_PIN_NO(165) | 4)
+
+#define PINMUX_GPIO166__FUNC_GPIO166 (MTK_PIN_NO(166) | 0)
+#define PINMUX_GPIO166__FUNC_MSDC1_CMD (MTK_PIN_NO(166) | 1)
+#define PINMUX_GPIO166__FUNC_LTE_MD32_JTAG_TMS (MTK_PIN_NO(166) | 2)
+#define PINMUX_GPIO166__FUNC_C2K_TMS (MTK_PIN_NO(166) | 3)
+#define PINMUX_GPIO166__FUNC_TDD_TMS (MTK_PIN_NO(166) | 4)
+#define PINMUX_GPIO166__FUNC_CONN_DSP_JMS (MTK_PIN_NO(166) | 5)
+#define PINMUX_GPIO166__FUNC_JTMS (MTK_PIN_NO(166) | 6)
+#define PINMUX_GPIO166__FUNC_CONN_MCU_AICE_TMSC (MTK_PIN_NO(166) | 7)
+
+#define PINMUX_GPIO167__FUNC_GPIO167 (MTK_PIN_NO(167) | 0)
+#define PINMUX_GPIO167__FUNC_MSDC1_CLK (MTK_PIN_NO(167) | 1)
+#define PINMUX_GPIO167__FUNC_LTE_MD32_JTAG_TCK (MTK_PIN_NO(167) | 2)
+#define PINMUX_GPIO167__FUNC_C2K_TCK (MTK_PIN_NO(167) | 3)
+#define PINMUX_GPIO167__FUNC_TDD_TCK (MTK_PIN_NO(167) | 4)
+#define PINMUX_GPIO167__FUNC_CONN_DSP_JCK (MTK_PIN_NO(167) | 5)
+#define PINMUX_GPIO167__FUNC_JTCK (MTK_PIN_NO(167) | 6)
+#define PINMUX_GPIO167__FUNC_CONN_MCU_AICE_TCKC (MTK_PIN_NO(167) | 7)
+
+#define PINMUX_GPIO168__FUNC_GPIO168 (MTK_PIN_NO(168) | 0)
+#define PINMUX_GPIO168__FUNC_MSDC1_DAT0 (MTK_PIN_NO(168) | 1)
+#define PINMUX_GPIO168__FUNC_LTE_MD32_JTAG_TDI (MTK_PIN_NO(168) | 2)
+#define PINMUX_GPIO168__FUNC_C2K_TDI (MTK_PIN_NO(168) | 3)
+#define PINMUX_GPIO168__FUNC_TDD_TDI (MTK_PIN_NO(168) | 4)
+#define PINMUX_GPIO168__FUNC_CONN_DSP_JDI (MTK_PIN_NO(168) | 5)
+#define PINMUX_GPIO168__FUNC_JTDI (MTK_PIN_NO(168) | 6)
+
+#define PINMUX_GPIO169__FUNC_GPIO169 (MTK_PIN_NO(169) | 0)
+#define PINMUX_GPIO169__FUNC_MSDC1_DAT1 (MTK_PIN_NO(169) | 1)
+#define PINMUX_GPIO169__FUNC_LTE_MD32_JTAG_TDO (MTK_PIN_NO(169) | 2)
+#define PINMUX_GPIO169__FUNC_C2K_TDO (MTK_PIN_NO(169) | 3)
+#define PINMUX_GPIO169__FUNC_TDD_TDO (MTK_PIN_NO(169) | 4)
+#define PINMUX_GPIO169__FUNC_CONN_DSP_JDO (MTK_PIN_NO(169) | 5)
+#define PINMUX_GPIO169__FUNC_JTDO (MTK_PIN_NO(169) | 6)
+
+#define PINMUX_GPIO170__FUNC_GPIO170 (MTK_PIN_NO(170) | 0)
+#define PINMUX_GPIO170__FUNC_MSDC1_DAT2 (MTK_PIN_NO(170) | 1)
+#define PINMUX_GPIO170__FUNC_LTE_MD32_JTAG_TRST (MTK_PIN_NO(170) | 2)
+#define PINMUX_GPIO170__FUNC_C2K_NTRST (MTK_PIN_NO(170) | 3)
+#define PINMUX_GPIO170__FUNC_TDD_TRSTN (MTK_PIN_NO(170) | 4)
+#define PINMUX_GPIO170__FUNC_CONN_DSP_JINTP (MTK_PIN_NO(170) | 5)
+#define PINMUX_GPIO170__FUNC_DM_JTINTP (MTK_PIN_NO(170) | 6)
+
+#define PINMUX_GPIO171__FUNC_GPIO171 (MTK_PIN_NO(171) | 0)
+#define PINMUX_GPIO171__FUNC_MSDC1_DAT3 (MTK_PIN_NO(171) | 1)
+#define PINMUX_GPIO171__FUNC_C2K_RTCK (MTK_PIN_NO(171) | 3)
+
+#define PINMUX_GPIO172__FUNC_GPIO172 (MTK_PIN_NO(172) | 0)
+#define PINMUX_GPIO172__FUNC_MSDC0_CMD (MTK_PIN_NO(172) | 1)
+
+#define PINMUX_GPIO173__FUNC_GPIO173 (MTK_PIN_NO(173) | 0)
+#define PINMUX_GPIO173__FUNC_MSDC0_DSL (MTK_PIN_NO(173) | 1)
+
+#define PINMUX_GPIO174__FUNC_GPIO174 (MTK_PIN_NO(174) | 0)
+#define PINMUX_GPIO174__FUNC_MSDC0_CLK (MTK_PIN_NO(174) | 1)
+
+#define PINMUX_GPIO175__FUNC_GPIO175 (MTK_PIN_NO(175) | 0)
+#define PINMUX_GPIO175__FUNC_MSDC0_DAT0 (MTK_PIN_NO(175) | 1)
+
+#define PINMUX_GPIO176__FUNC_GPIO176 (MTK_PIN_NO(176) | 0)
+#define PINMUX_GPIO176__FUNC_MSDC0_DAT1 (MTK_PIN_NO(176) | 1)
+
+#define PINMUX_GPIO177__FUNC_GPIO177 (MTK_PIN_NO(177) | 0)
+#define PINMUX_GPIO177__FUNC_MSDC0_DAT2 (MTK_PIN_NO(177) | 1)
+
+#define PINMUX_GPIO178__FUNC_GPIO178 (MTK_PIN_NO(178) | 0)
+#define PINMUX_GPIO178__FUNC_MSDC0_DAT3 (MTK_PIN_NO(178) | 1)
+
+#define PINMUX_GPIO179__FUNC_GPIO179 (MTK_PIN_NO(179) | 0)
+#define PINMUX_GPIO179__FUNC_MSDC0_DAT4 (MTK_PIN_NO(179) | 1)
+
+#define PINMUX_GPIO180__FUNC_GPIO180 (MTK_PIN_NO(180) | 0)
+#define PINMUX_GPIO180__FUNC_MSDC0_DAT5 (MTK_PIN_NO(180) | 1)
+
+#define PINMUX_GPIO181__FUNC_GPIO181 (MTK_PIN_NO(181) | 0)
+#define PINMUX_GPIO181__FUNC_MSDC0_DAT6 (MTK_PIN_NO(181) | 1)
+
+#define PINMUX_GPIO182__FUNC_GPIO182 (MTK_PIN_NO(182) | 0)
+#define PINMUX_GPIO182__FUNC_MSDC0_DAT7 (MTK_PIN_NO(182) | 1)
+
+#define PINMUX_GPIO183__FUNC_GPIO183 (MTK_PIN_NO(183) | 0)
+#define PINMUX_GPIO183__FUNC_MSDC0_RSTB (MTK_PIN_NO(183) | 1)
+
+#define PINMUX_GPIO184__FUNC_GPIO184 (MTK_PIN_NO(184) | 0)
+#define PINMUX_GPIO184__FUNC_F2W_DATA (MTK_PIN_NO(184) | 1)
+#define PINMUX_GPIO184__FUNC_MRG_CLK (MTK_PIN_NO(184) | 2)
+#define PINMUX_GPIO184__FUNC_C2K_DM_EINT2 (MTK_PIN_NO(184) | 3)
+#define PINMUX_GPIO184__FUNC_PCM0_CLK (MTK_PIN_NO(184) | 4)
+
+#define PINMUX_GPIO185__FUNC_GPIO185 (MTK_PIN_NO(185) | 0)
+#define PINMUX_GPIO185__FUNC_F2W_CK (MTK_PIN_NO(185) | 1)
+#define PINMUX_GPIO185__FUNC_MRG_DI (MTK_PIN_NO(185) | 2)
+#define PINMUX_GPIO185__FUNC_C2K_DM_EINT3 (MTK_PIN_NO(185) | 3)
+#define PINMUX_GPIO185__FUNC_PCM0_DI (MTK_PIN_NO(185) | 4)
+
+#define PINMUX_GPIO186__FUNC_GPIO186 (MTK_PIN_NO(186) | 0)
+#define PINMUX_GPIO186__FUNC_WB_RSTB (MTK_PIN_NO(186) | 1)
+#define PINMUX_GPIO186__FUNC_URXD3 (MTK_PIN_NO(186) | 4)
+#define PINMUX_GPIO186__FUNC_UTXD3 (MTK_PIN_NO(186) | 5)
+
+#define PINMUX_GPIO187__FUNC_GPIO187 (MTK_PIN_NO(187) | 0)
+#define PINMUX_GPIO187__FUNC_WB_SCLK (MTK_PIN_NO(187) | 1)
+#define PINMUX_GPIO187__FUNC_MRG_DO (MTK_PIN_NO(187) | 2)
+#define PINMUX_GPIO187__FUNC_PCM0_DO (MTK_PIN_NO(187) | 4)
+
+#define PINMUX_GPIO188__FUNC_GPIO188 (MTK_PIN_NO(188) | 0)
+#define PINMUX_GPIO188__FUNC_WB_SDATA (MTK_PIN_NO(188) | 1)
+#define PINMUX_GPIO188__FUNC_MRG_SYNC (MTK_PIN_NO(188) | 2)
+#define PINMUX_GPIO188__FUNC_PCM0_SYNC (MTK_PIN_NO(188) | 4)
+
+#define PINMUX_GPIO189__FUNC_GPIO189 (MTK_PIN_NO(189) | 0)
+#define PINMUX_GPIO189__FUNC_WB_SEN (MTK_PIN_NO(189) | 1)
+#define PINMUX_GPIO189__FUNC_UTXD3 (MTK_PIN_NO(189) | 4)
+#define PINMUX_GPIO189__FUNC_URXD3 (MTK_PIN_NO(189) | 5)
+
+#define PINMUX_GPIO190__FUNC_GPIO190 (MTK_PIN_NO(190) | 0)
+#define PINMUX_GPIO190__FUNC_GPS_RXQN (MTK_PIN_NO(190) | 1)
+
+#define PINMUX_GPIO191__FUNC_GPIO191 (MTK_PIN_NO(191) | 0)
+#define PINMUX_GPIO191__FUNC_GPS_RXQP (MTK_PIN_NO(191) | 1)
+
+#define PINMUX_GPIO192__FUNC_GPIO192 (MTK_PIN_NO(192) | 0)
+#define PINMUX_GPIO192__FUNC_GPS_RXIN (MTK_PIN_NO(192) | 1)
+
+#define PINMUX_GPIO193__FUNC_GPIO193 (MTK_PIN_NO(193) | 0)
+#define PINMUX_GPIO193__FUNC_GPS_RXIP (MTK_PIN_NO(193) | 1)
+
+#define PINMUX_GPIO194__FUNC_GPIO194 (MTK_PIN_NO(194) | 0)
+#define PINMUX_GPIO194__FUNC_WB_RXQN (MTK_PIN_NO(194) | 1)
+
+#define PINMUX_GPIO195__FUNC_GPIO195 (MTK_PIN_NO(195) | 0)
+#define PINMUX_GPIO195__FUNC_WB_RXQP (MTK_PIN_NO(195) | 1)
+
+#define PINMUX_GPIO196__FUNC_GPIO196 (MTK_PIN_NO(196) | 0)
+#define PINMUX_GPIO196__FUNC_WB_RXIN (MTK_PIN_NO(196) | 1)
+
+#define PINMUX_GPIO197__FUNC_GPIO197 (MTK_PIN_NO(197) | 0)
+#define PINMUX_GPIO197__FUNC_WB_RXIP (MTK_PIN_NO(197) | 1)
+
+#define PINMUX_GPIO198__FUNC_GPIO198 (MTK_PIN_NO(198) | 0)
+#define PINMUX_GPIO198__FUNC_MSDC2_CMD (MTK_PIN_NO(198) | 1)
+#define PINMUX_GPIO198__FUNC_SDA1 (MTK_PIN_NO(198) | 2)
+#define PINMUX_GPIO198__FUNC_C2K_UART0_RXD (MTK_PIN_NO(198) | 3)
+#define PINMUX_GPIO198__FUNC_C2K_TMS (MTK_PIN_NO(198) | 4)
+#define PINMUX_GPIO198__FUNC_ANT_SEL6 (MTK_PIN_NO(198) | 5)
+#define PINMUX_GPIO198__FUNC_DM_OTMS (MTK_PIN_NO(198) | 7)
+
+#define PINMUX_GPIO199__FUNC_GPIO199 (MTK_PIN_NO(199) | 0)
+#define PINMUX_GPIO199__FUNC_MSDC2_CLK (MTK_PIN_NO(199) | 1)
+#define PINMUX_GPIO199__FUNC_SCL1 (MTK_PIN_NO(199) | 2)
+#define PINMUX_GPIO199__FUNC_C2K_UART0_TXD (MTK_PIN_NO(199) | 3)
+#define PINMUX_GPIO199__FUNC_C2K_TCK (MTK_PIN_NO(199) | 4)
+#define PINMUX_GPIO199__FUNC_ANT_SEL7 (MTK_PIN_NO(199) | 5)
+#define PINMUX_GPIO199__FUNC_TDD_TXD (MTK_PIN_NO(199) | 6)
+#define PINMUX_GPIO199__FUNC_DM_OTCK (MTK_PIN_NO(199) | 7)
+
+#define PINMUX_GPIO200__FUNC_GPIO200 (MTK_PIN_NO(200) | 0)
+#define PINMUX_GPIO200__FUNC_MSDC2_DAT0 (MTK_PIN_NO(200) | 1)
+#define PINMUX_GPIO200__FUNC_ANT_SEL6 (MTK_PIN_NO(200) | 2)
+#define PINMUX_GPIO200__FUNC_GPS_FRAME_SYNC (MTK_PIN_NO(200) | 3)
+#define PINMUX_GPIO200__FUNC_C2K_TDI (MTK_PIN_NO(200) | 4)
+#define PINMUX_GPIO200__FUNC_UTXD0 (MTK_PIN_NO(200) | 5)
+#define PINMUX_GPIO200__FUNC_DM_OTDI (MTK_PIN_NO(200) | 7)
+
+#define PINMUX_GPIO201__FUNC_GPIO201 (MTK_PIN_NO(201) | 0)
+#define PINMUX_GPIO201__FUNC_MSDC2_DAT1 (MTK_PIN_NO(201) | 1)
+#define PINMUX_GPIO201__FUNC_ANT_SEL3 (MTK_PIN_NO(201) | 2)
+#define PINMUX_GPIO201__FUNC_PWM0 (MTK_PIN_NO(201) | 3)
+#define PINMUX_GPIO201__FUNC_C2K_TDO (MTK_PIN_NO(201) | 4)
+#define PINMUX_GPIO201__FUNC_URXD0 (MTK_PIN_NO(201) | 5)
+#define PINMUX_GPIO201__FUNC_DM_OTDO (MTK_PIN_NO(201) | 7)
+
+#define PINMUX_GPIO202__FUNC_GPIO202 (MTK_PIN_NO(202) | 0)
+#define PINMUX_GPIO202__FUNC_MSDC2_DAT2 (MTK_PIN_NO(202) | 1)
+#define PINMUX_GPIO202__FUNC_ANT_SEL4 (MTK_PIN_NO(202) | 2)
+#define PINMUX_GPIO202__FUNC_SDA2 (MTK_PIN_NO(202) | 3)
+#define PINMUX_GPIO202__FUNC_C2K_NTRST (MTK_PIN_NO(202) | 4)
+#define PINMUX_GPIO202__FUNC_UTXD1 (MTK_PIN_NO(202) | 5)
+#define PINMUX_GPIO202__FUNC_KCOL3 (MTK_PIN_NO(202) | 6)
+#define PINMUX_GPIO202__FUNC_DM_JTINTP (MTK_PIN_NO(202) | 7)
+
+#define PINMUX_GPIO203__FUNC_GPIO203 (MTK_PIN_NO(203) | 0)
+#define PINMUX_GPIO203__FUNC_MSDC2_DAT3 (MTK_PIN_NO(203) | 1)
+#define PINMUX_GPIO203__FUNC_ANT_SEL5 (MTK_PIN_NO(203) | 2)
+#define PINMUX_GPIO203__FUNC_SCL2 (MTK_PIN_NO(203) | 3)
+#define PINMUX_GPIO203__FUNC_C2K_RTCK (MTK_PIN_NO(203) | 4)
+#define PINMUX_GPIO203__FUNC_URXD1 (MTK_PIN_NO(203) | 5)
+#define PINMUX_GPIO203__FUNC_KCOL6 (MTK_PIN_NO(203) | 6)
+
+#endif /* _DT_BINDINGS_PINCTRL_MEDIATEK_MT6735_PINFUNC_H */
diff --git a/include/dt-bindings/power/qcom,rpmhpd.h b/include/dt-bindings/power/qcom,rpmhpd.h
index 07bd2a7b0150..92c8408dbc57 100644
--- a/include/dt-bindings/power/qcom,rpmhpd.h
+++ b/include/dt-bindings/power/qcom,rpmhpd.h
@@ -32,6 +32,7 @@
#define RPMHPD_GBX 22
#define RPMHPD_NSP3 23
#define RPMHPD_GFX1 24
+#define RPMHPD_NMXC 25
/* RPMh Power Domain performance levels */
#define RPMH_REGULATOR_LEVEL_RETENTION 16
diff --git a/include/dt-bindings/power/renesas,r8a774a3-sysc.h b/include/dt-bindings/power/renesas,r8a774a3-sysc.h
new file mode 100644
index 000000000000..ddee6812e9a4
--- /dev/null
+++ b/include/dt-bindings/power/renesas,r8a774a3-sysc.h
@@ -0,0 +1,30 @@
+/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */
+/*
+ * Copyright (C) 2026 Renesas Electronics Corp.
+ */
+#ifndef __DT_BINDINGS_POWER_RENESAS_R8A774A3_SYSC_H__
+#define __DT_BINDINGS_POWER_RENESAS_R8A774A3_SYSC_H__
+
+/*
+ * These power domain indices match the numbers of the interrupt bits
+ * representing the power areas in the various Interrupt Registers
+ * (e.g. SYSCISR, Interrupt Status Register)
+ */
+
+#define R8A774A3_PD_CA57_CPU0 0
+#define R8A774A3_PD_CA57_CPU1 1
+#define R8A774A3_PD_CA53_CPU0 5
+#define R8A774A3_PD_CA53_CPU1 6
+#define R8A774A3_PD_CA53_CPU2 7
+#define R8A774A3_PD_CA53_CPU3 8
+#define R8A774A3_PD_CA57_SCU 12
+#define R8A774A3_PD_A3VC 14
+#define R8A774A3_PD_3DG_A 17
+#define R8A774A3_PD_3DG_B 18
+#define R8A774A3_PD_CA53_SCU 21
+#define R8A774A3_PD_A2VC1 26
+
+/* Always-on power area */
+#define R8A774A3_PD_ALWAYS_ON 32
+
+#endif /* __DT_BINDINGS_POWER_RENESAS_R8A774A3_SYSC_H__ */
diff --git a/include/dt-bindings/reset/mediatek,mt8167-wdt.h b/include/dt-bindings/reset/mediatek,mt8167-wdt.h
new file mode 100644
index 000000000000..1a24bfe079ca
--- /dev/null
+++ b/include/dt-bindings/reset/mediatek,mt8167-wdt.h
@@ -0,0 +1,21 @@
+/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause) */
+#ifndef _DT_BINDINGS_RESET_MEDIATEK_MT8167_WDT_H_
+#define _DT_BINDINGS_RESET_MEDIATEK_MT8167_WDT_H_
+
+/* TOPRGU reset IDs */
+#define MT8167_TOPRGU_DDRPHY_FLASH_RST 0
+#define MT8167_TOPRGU_AUD_PAD_RST 1
+#define MT8167_TOPRGU_MM_RST 2
+#define MT8167_TOPRGU_MFG_RST 3
+#define MT8167_TOPRGU_MDSYS_RST 4
+#define MT8167_TOPRGU_CONN_RST 5
+#define MT8167_TOPRGU_PAD2CAM_DIG_MIPI_RX_RST 6
+#define MT8167_TOPRGU_DIG_MIPI_TX_RST 7
+#define MT8167_TOPRGU_SPI_PAD_MACRO_RST 8
+#define MT8167_TOPRGU_APMIXED_RST 9
+#define MT8167_TOPRGU_VDEC_RST 10
+#define MT8167_TOPRGU_CONN_MCU_RST 11
+#define MT8167_TOPRGU_EFUSE_RST 12
+#define MT8167_TOPRGU_PWRAP_SPICTL_RST 13
+
+#endif /* _DT_BINDINGS_RESET_MEDIATEK_MT8167_WDT_H_ */
diff --git a/include/dt-bindings/reset/starfive,jhb100-crg.h b/include/dt-bindings/reset/starfive,jhb100-crg.h
new file mode 100644
index 000000000000..1489bb01c2bd
--- /dev/null
+++ b/include/dt-bindings/reset/starfive,jhb100-crg.h
@@ -0,0 +1,189 @@
+/* SPDX-License-Identifier: GPL-2.0 OR MIT */
+/*
+ * Copyright (C) 2024 StarFive Technology Co., Ltd.
+ * Author: Changhuang Liang <changhuang.liang@starfivetech.com>
+ *
+ */
+
+#ifndef __DT_BINDINGS_RESET_STARFIVE_JHB100_CRG_H__
+#define __DT_BINDINGS_RESET_STARFIVE_JHB100_CRG_H__
+
+/* SYS0CRG resets */
+#define JHB100_SYS0RST_RESOURCE_ARB 0
+#define JHB100_SYS0RST_SYS0_IOMUX_PRESETN 1
+#define JHB100_SYS0RST_SYS0H_IOMUX_PRESETN 2
+#define JHB100_SYS0RST_RST_ADAPTOR_TIMEOUT_RSTN 3
+#define JHB100_SYS0RST_BMCPCIERP_RSTN_BUS 4
+#define JHB100_SYS0RST_BMCPCIERP_RSTN_CRG 5
+#define JHB100_SYS0RST_HOSTSS0_RSTN_BUS_ESPI 6
+#define JHB100_SYS0RST_HOSTSS0_RSTN_BUS_PCIE 7
+#define JHB100_SYS0RST_HOSTSS0_RSTN_CRG 8
+#define JHB100_SYS0RST_BMCPERIPH2_RSTN_CRG 9
+#define JHB100_SYS0RST_BMCPERIPH2_RSTN_BUS 10
+#define JHB100_SYS0RST_VCE_RSTN_CRG 11
+#define JHB100_SYS0RST_VCE_RSTN_BUS 12
+#define JHB100_SYS0RST_BMCUSB_RSTN_BUS 13
+#define JHB100_SYS0RST_BMCUSB_RSTN_CRG 14
+
+/* SYS1CRG resets */
+#define JHB100_SYS1RST_SYS1_IOMUX_PRESETN 0
+#define JHB100_SYS1RST_MAIN_RSTN_CHIPTOP_SENSOR 1
+#define JHB100_SYS1RST_VOUT_RSTN_HOST0 2
+#define JHB100_SYS1RST_VOUT_RSTN_HOST1 3
+#define JHB100_SYS1RST_HOSTSS1_RSTN_BUS_ESPI 4
+#define JHB100_SYS1RST_HOSTSS1_RSTN_BUS_PCIE 5
+#define JHB100_SYS1RST_HOSTSS1_RSTN_CRG 6
+#define JHB100_SYS1RST_BMCPERIPH3_RSTN_CRG 7
+#define JHB100_SYS1RST_BMCPERIPH3_RSTN_BUS 8
+
+/* SYS2CRG resets */
+#define JHB100_SYS2RST_JTAG0_MST_WRAP_HRESETN 0
+#define JHB100_SYS2RST_JTAG0_MST_WRAP_APB_PRESETN 1
+#define JHB100_SYS2RST_JTAG1_MST_WRAP_HRESETN 2
+#define JHB100_SYS2RST_JTAG1_MST_WRAP_APB_PRESETN 3
+#define JHB100_SYS2RST_HUSBCMN_HOSTCMN_RSTN_BUS_NCNOC_INIT 4
+#define JHB100_SYS2RST_HUSBCMN_RSTN_HOSTCMN_CRG 5
+#define JHB100_SYS2RST_HUSBCMN_HOSTUSB0_RSTN_BUS_NCNOC_BMC_TARG 6
+#define JHB100_SYS2RST_HUSBCMN_HOSTUSB0_RSTN_BUS_NCNOC_HOST_TARG 7
+#define JHB100_SYS2RST_HUSBCMN_RSTN_BMC_CRG 8
+#define JHB100_SYS2RST_HUSBCMN_RSTN_HOSTUSB0_CRG 9
+#define JHB100_SYS2RST_HUSBCMN_HOSTUSB1_RSTN_BUS_NCNOC_BMC_TARG 10
+#define JHB100_SYS2RST_HUSBCMN_HOSTUSB1_RSTN_BUS_NCNOC_HOST_TARG 11
+#define JHB100_SYS2RST_HUSBCMN_RSTN_HOSTUSB1_CRG 12
+#define JHB100_SYS2RST_BMCPERIPH1_RSTN_CRG 13
+#define JHB100_SYS2RST_BMCPERIPH1_RSTN_BUS 14
+#define JHB100_SYS2RST_BMCPERIPH0_RSTN_CRG 15
+#define JHB100_SYS2RST_BMCPERIPH0_RSTN_BUS 16
+#define JHB100_SYS2RST_GPU0_RSTN_CRG 17
+#define JHB100_SYS2RST_GPU0_RSTN_BUS 18
+#define JHB100_SYS2RST_GPU0_HOST_PCIE_RST_N 19
+#define JHB100_SYS2RST_GPU1_RSTN_CRG 20
+#define JHB100_SYS2RST_GPU1_RSTN_BUS 21
+#define JHB100_SYS2RST_GPU1_HOST_PCIE_RST_N 22
+
+/* PER0CRG resets */
+#define JHB100_PER0RST_MAIN_RSTN_UART4 0
+#define JHB100_PER0RST_MAIN_RSTN_UART5 1
+#define JHB100_PER0RST_MAIN_RSTN_UART6 2
+#define JHB100_PER0RST_MAIN_RSTN_UART7 3
+#define JHB100_PER0RST_MAIN_RSTN_UART8 4
+#define JHB100_PER0RST_MAIN_RSTN_UART9 5
+#define JHB100_PER0RST_MAIN_RSTN_UART10 6
+#define JHB100_PER0RST_MAIN_RSTN_UART11 7
+#define JHB100_PER0RST_MAIN_RSTN_UART12 8
+#define JHB100_PER0RST_MAIN_RSTN_UART13 9
+#define JHB100_PER0RST_MAIN_RSTN_UART14 10
+#define JHB100_PER0RST_MAIN_RSTN_I2C0 11
+#define JHB100_PER0RST_MAIN_RSTN_I2C1 12
+#define JHB100_PER0RST_MAIN_RSTN_I2C2 13
+#define JHB100_PER0RST_MAIN_RSTN_I2C3 14
+#define JHB100_PER0RST_MAIN_RSTN_I2C4 15
+#define JHB100_PER0RST_MAIN_RSTN_I2C5 16
+#define JHB100_PER0RST_MAIN_RSTN_I2C6 17
+#define JHB100_PER0RST_MAIN_RSTN_I2C7 18
+#define JHB100_PER0RST_MAIN_RSTN_I2C8 19
+#define JHB100_PER0RST_MAIN_RSTN_I2C9 20
+#define JHB100_PER0RST_MAIN_RSTN_I2C10 21
+#define JHB100_PER0RST_MAIN_RSTN_I2C11 22
+#define JHB100_PER0RST_MAIN_RSTN_I2C12 23
+#define JHB100_PER0RST_MAIN_RSTN_I2C13 24
+#define JHB100_PER0RST_MAIN_RSTN_I2C14 25
+#define JHB100_PER0RST_MAIN_RSTN_I2C15 26
+#define JHB100_PER0RST_MAIN_RSTN_I3C0 27
+#define JHB100_PER0RST_MAIN_RSTN_I3C1 28
+#define JHB100_PER0RST_MAIN_RSTN_I3C2 29
+#define JHB100_PER0RST_MAIN_RSTN_I3C3 30
+#define JHB100_PER0RST_MAIN_RSTN_I3C4 31
+#define JHB100_PER0RST_MAIN_RSTN_I3C5 32
+#define JHB100_PER0RST_MAIN_RSTN_I3C6 33
+#define JHB100_PER0RST_MAIN_RSTN_I3C7 34
+#define JHB100_PER0RST_MAIN_RSTN_I3C8 35
+#define JHB100_PER0RST_MAIN_RSTN_I3C9 36
+#define JHB100_PER0RST_MAIN_RSTN_I3C10 37
+#define JHB100_PER0RST_MAIN_RSTN_I3C11 38
+#define JHB100_PER0RST_MAIN_RSTN_I3C12 39
+#define JHB100_PER0RST_MAIN_RSTN_I3C13 40
+#define JHB100_PER0RST_MAIN_RSTN_I3C14 41
+#define JHB100_PER0RST_MAIN_RSTN_I3C15 42
+#define JHB100_PER0RST_MAIN_RSTN_WDT0 43
+#define JHB100_PER0RST_MAIN_RSTN_WDT1 44
+#define JHB100_PER0RST_MAIN_RSTN_WDT2 45
+#define JHB100_PER0RST_MAIN_RSTN_WDT3 46
+#define JHB100_PER0RST_MAIN_RSTN_WDT4 47
+#define JHB100_PER0RST_MAIN_RSTN_DUALTIMER0 48
+#define JHB100_PER0RST_MAIN_RSTN_DUALTIMER1 49
+#define JHB100_PER0RST_MAIN_RSTN_DUALTIMER2 50
+#define JHB100_PER0RST_MAIN_RSTN_TRNG 51
+#define JHB100_PER0RST_MAIN_RSTN_DMAC0 52
+#define JHB100_PER0RST_MAIN_RSTN_DMAC1 53
+#define JHB100_PER0RST_MAIN_RSTN_DMAC2 54
+#define JHB100_PER0RST_MAIN_RSTN_LTPI0 55
+#define JHB100_PER0RST_MAIN_RSTN_LTPI1 56
+#define JHB100_PER0RST_MAIN_RSTN_SOL4 57
+#define JHB100_PER0RST_MAIN_RSTN_SOL5 58
+#define JHB100_PER0RST_MAIN_RSTN_SOL6 59
+#define JHB100_PER0RST_MAIN_RSTN_SOL7 60
+#define JHB100_PER0RST_MAIN_RSTN_SOL8 61
+#define JHB100_PER0RST_MAIN_RSTN_SOL9 62
+#define JHB100_PER0RST_MAIN_RSTN_SOL10 63
+#define JHB100_PER0RST_MAIN_RSTN_SOL11 64
+#define JHB100_PER0RST_MAIN_RSTN_SOL12 65
+#define JHB100_PER0RST_MAIN_RSTN_SOL13 66
+#define JHB100_PER0RST_MAIN_RSTN_SOL14 67
+#define JHB100_PER0RST_MAIN_RSTN_LDO0 68
+#define JHB100_PER0RST_MAIN_RSTN_LDO1 69
+#define JHB100_PER0RST_MAIN_RSTN_PERIPH0_SENSORS 70
+#define JHB100_PER0RST_MAIN_RSTN_DMAC0_SENSORS 71
+#define JHB100_PER0RST_SYSCON_PRESETN 72
+#define JHB100_PER0RST_GPIO_IOMUX_PRESETN 73
+#define JHB100_PER0RST_UART_MUX_REG_WRAP 74
+
+/* PER1CRG resets */
+#define JHB100_PER1RST_IOMUX_PRESETN 0
+#define JHB100_PER1RST_SYSCON_PRESETN 1
+#define JHB100_PER1RST_MAIN_RSTN_SFC0 2
+#define JHB100_PER1RST_MAIN_RSTN_SFC1 3
+#define JHB100_PER1RST_MAIN_RSTN_SFC2 4
+#define JHB100_PER1RST_MAIN_RSTN_SPI0 5
+#define JHB100_PER1RST_MAIN_RSTN_PERIPH1_SENSORS 6
+#define JHB100_PER1RST_MAIN_RSTN_SGPIO0 7
+#define JHB100_PER1RST_MAIN_RSTN_SGPIO1 8
+#define JHB100_PER1RST_MAIN_RSTN_EMMC0 9
+#define JHB100_PER1RST_MAIN_RSTN_UFS 10
+#define JHB100_PER1RST_MAIN_RSTN_UFS_PHY 11
+#define JHB100_PER1RST_MAIN_RSTN_DMAC_SFC0 12
+#define JHB100_PER1RST_MAIN_RSTN_DMAC_SFC1 13
+#define JHB100_PER1RST_MAIN_RSTN_DMAC_SFC2 14
+#define JHB100_PER1RST_MAIN_RSTN_DMAC_SPI0 15
+#define JHB100_PER1RST_MAIN_RSTN_PERIPH1_RAS 16
+
+/* PER2CRG resets */
+#define JHB100_PER2RST_IOMUX_PRESETN 0
+#define JHB100_PER2RST_POK_IOMUX_PRESETN 1
+#define JHB100_PER2RST_SYSREG_RSTN 2
+#define JHB100_PER2RST_MAIN_RSTN_CAN0 3
+#define JHB100_PER2RST_MAIN_RSTN_CAN1 4
+#define JHB100_PER2RST_FAN_TACH_PRESETN 5
+#define JHB100_PER2RST_MAIN_RSTN_GMAC2 6
+#define JHB100_PER2RST_MAIN_RSTN_GMAC3 7
+#define JHB100_PER2RST_MAIN_RSTN_DMAC_8CH 8
+#define JHB100_PER2RST_MAIN_RSTN_RTC 9
+#define JHB100_PER2RST_ADC0_PRESETN 10
+#define JHB100_PER2RST_ADC0_IOMUX_PRESETN 11
+#define JHB100_PER2RST_ADC1_PRESETN 12
+#define JHB100_PER2RST_ADC1_IOMUX_PRESETN 13
+#define JHB100_PER2RST_MAIN_RSTN_PERIPH2_SENSORS 14
+
+/* PER3CRG resets */
+#define JHB100_PER3RST_SYSREG_RSTN 0
+#define JHB100_PER3RST_MAIN_RSTN_GMAC0 1
+#define JHB100_PER3RST_MAIN_RSTN_GMAC1 2
+#define JHB100_PER3RST_MAIN_RSTN_PECI0 3
+#define JHB100_PER3RST_MAIN_RSTN_PECI1 4
+#define JHB100_PER3RST_MAIN_RSTN_PERIPH3_SENSORS 5
+#define JHB100_PER3RST_IOMUX_PRESETN 6
+
+/* PCIERP SYSCON resets */
+#define JHB100_PCIERP_SYSCONRST_PE2RST_OUT 0
+
+#endif /* __DT_BINDINGS_RESET_STARFIVE_JHB100_CRG_H__ */
diff --git a/include/dt-bindings/sound/cs35l45.h b/include/dt-bindings/sound/cs35l45.h
index 25386af18445..5cb77d48b0b8 100644
--- a/include/dt-bindings/sound/cs35l45.h
+++ b/include/dt-bindings/sound/cs35l45.h
@@ -18,6 +18,33 @@
#define CS35L45_ASP_TX_HIZ_DISABLED 0x2
/*
+ * cirrus,boost-low-power-mode
+ *
+ * BST_LPMODE_NO_REACTION: No reaction
+ * BST_LPMODE_DCM_MODE: Force boost DCM low power mode
+ * BST_LPMODE_STATIC_BYPASS: Force boost static bypass
+ */
+#define CS35L45_BST_LPMODE_NO_REACTION 0x0
+#define CS35L45_BST_LPMODE_DCM_MODE 0x1
+#define CS35L45_BST_LPMODE_STATIC_BYPASS 0x2
+
+/*
+ * cirrus,amplifier-low-power-mode
+ *
+ * AMP_LPMODE_NG_MODE: Noise gate mode
+ * AMP_LPMODE_NFR_MODE: Noise floor reduction mode
+ */
+ #define CS35L45_AMP_LPMODE_NG_MODE 0x0
+ #define CS35L45_AMP_LPMODE_NFR_MODE 0x1
+
+/*
+ * cirrus,ldpm-groupX-pcm-threshold-db
+ *
+ * LDPM_PCM_THLD_TRUE_ZERO:
+ */
+#define CS35L45_LDPM_PCM_THLD_TRUE_ZERO -2147483648
+
+/*
* Optional GPIOX Sub-nodes:
* The cs35l45 node can have up to three "cirrus,gpio-ctrlX" ('X' = [1,2,3])
* sub-nodes for configuring the GPIO pins.
diff --git a/include/dt-bindings/sound/qcom,q6dsp-lpass-ports.h b/include/dt-bindings/sound/qcom,q6dsp-lpass-ports.h
index 3a99703dbc4a..e6c792d9312f 100644
--- a/include/dt-bindings/sound/qcom,q6dsp-lpass-ports.h
+++ b/include/dt-bindings/sound/qcom,q6dsp-lpass-ports.h
@@ -156,6 +156,58 @@
#define LPI_MI2S_TX_5 150
#define LPI_MI2S_RX_6 151
#define LPI_MI2S_TX_6 152
+#define AIF_MI2S_RX_0 153
+#define AIF_MI2S_TX_0 154
+#define AIF_MI2S_RX_1 155
+#define AIF_MI2S_TX_1 156
+#define AIF_MI2S_RX_2 157
+#define AIF_MI2S_TX_2 158
+#define AIF_MI2S_RX_3 159
+#define AIF_MI2S_TX_3 160
+#define AIF_MI2S_RX_4 161
+#define AIF_MI2S_TX_4 162
+#define AIF_MI2S_RX_5 163
+#define AIF_MI2S_TX_5 164
+#define AIF_MI2S_RX_6 165
+#define AIF_MI2S_TX_6 166
+#define AIF_MI2S_RX_7 167
+#define AIF_MI2S_TX_7 168
+#define AIF_MI2S_RX_8 169
+#define AIF_MI2S_TX_8 170
+#define AIF_MI2S_RX_9 171
+#define AIF_MI2S_TX_9 172
+#define AIF_MI2S_RX_10 173
+#define AIF_MI2S_TX_10 174
+#define AIF_MI2S_RX_11 175
+#define AIF_MI2S_TX_11 176
+#define AIF_MI2S_RX_12 177
+#define AIF_MI2S_TX_12 178
+#define AIF_TDM_RX_0 179
+#define AIF_TDM_TX_0 180
+#define AIF_TDM_RX_1 181
+#define AIF_TDM_TX_1 182
+#define AIF_TDM_RX_2 183
+#define AIF_TDM_TX_2 184
+#define AIF_TDM_RX_3 185
+#define AIF_TDM_TX_3 186
+#define AIF_TDM_RX_4 187
+#define AIF_TDM_TX_4 188
+#define AIF_TDM_RX_5 189
+#define AIF_TDM_TX_5 190
+#define AIF_TDM_RX_6 191
+#define AIF_TDM_TX_6 192
+#define AIF_TDM_RX_7 193
+#define AIF_TDM_TX_7 194
+#define AIF_TDM_RX_8 195
+#define AIF_TDM_TX_8 196
+#define AIF_TDM_RX_9 197
+#define AIF_TDM_TX_9 198
+#define AIF_TDM_RX_10 199
+#define AIF_TDM_TX_10 200
+#define AIF_TDM_RX_11 201
+#define AIF_TDM_TX_11 202
+#define AIF_TDM_RX_12 203
+#define AIF_TDM_TX_12 204
#define LPASS_CLK_ID_PRI_MI2S_IBIT 1
#define LPASS_CLK_ID_PRI_MI2S_EBIT 2
diff --git a/include/hyperv/hvgdk_mini.h b/include/hyperv/hvgdk_mini.h
index 6a4e8b9d570f..966945f0504f 100644
--- a/include/hyperv/hvgdk_mini.h
+++ b/include/hyperv/hvgdk_mini.h
@@ -37,6 +37,7 @@ struct hv_u128 {
#define HV_STATUS_PROCESSOR_FEATURE_NOT_SUPPORTED 0x20
#define HV_STATUS_INVALID_LP_INDEX 0x41
#define HV_STATUS_INVALID_REGISTER_VALUE 0x50
+#define HV_STATUS_DEVICE_ALREADY_IN_DOMAIN 0x66
#define HV_STATUS_OPERATION_FAILED 0x71
#define HV_STATUS_INSUFFICIENT_ROOT_MEMORY 0x73
#define HV_STATUS_INSUFFICIENT_CONTIGUOUS_MEMORY 0x75
@@ -486,10 +487,17 @@ union hv_vp_assist_msr_contents { /* HV_REGISTER_VP_ASSIST_PAGE */
#define HVCALL_GET_VP_INDEX_FROM_APIC_ID 0x009a
#define HVCALL_FLUSH_GUEST_PHYSICAL_ADDRESS_SPACE 0x00af
#define HVCALL_FLUSH_GUEST_PHYSICAL_ADDRESS_LIST 0x00b0
+#define HVCALL_CREATE_DEVICE_DOMAIN 0x00b1
+#define HVCALL_ATTACH_DEVICE_DOMAIN 0x00b2
#define HVCALL_SIGNAL_EVENT_DIRECT 0x00c0
#define HVCALL_POST_MESSAGE_DIRECT 0x00c1
#define HVCALL_DISPATCH_VP 0x00c2
+#define HVCALL_DETACH_DEVICE_DOMAIN 0x00c4
+#define HVCALL_DELETE_DEVICE_DOMAIN 0x00c5
#define HVCALL_GET_GPA_PAGES_ACCESS_STATES 0x00c9
+#define HVCALL_CONFIGURE_DEVICE_DOMAIN 0x00ce
+#define HVCALL_FLUSH_DEVICE_DOMAIN 0x00d0
+#define HVCALL_FLUSH_DEVICE_DOMAIN_LIST 0x00d1
#define HVCALL_ACQUIRE_SPARSE_SPA_PAGE_HOST_ACCESS 0x00d7
#define HVCALL_RELEASE_SPARSE_SPA_PAGE_HOST_ACCESS 0x00d8
#define HVCALL_MODIFY_SPARSE_GPA_PAGE_HOST_VISIBILITY 0x00db
@@ -502,6 +510,8 @@ union hv_vp_assist_msr_contents { /* HV_REGISTER_VP_ASSIST_PAGE */
#define HVCALL_MMIO_READ 0x0106
#define HVCALL_MMIO_WRITE 0x0107
#define HVCALL_DISABLE_HYP_EX 0x010f
+#define HVCALL_GET_IOMMU_CAPABILITIES 0x0125
+#define HVCALL_GET_LOGICAL_DEVICE_PROPERTY 0x0127
#define HVCALL_MAP_STATS_PAGE2 0x0131
/* HV_HYPERCALL_INPUT */
diff --git a/include/hyperv/hvhdk_mini.h b/include/hyperv/hvhdk_mini.h
index 035ba20870f7..57b70efe60d4 100644
--- a/include/hyperv/hvhdk_mini.h
+++ b/include/hyperv/hvhdk_mini.h
@@ -548,4 +548,159 @@ union hv_device_id { /* HV_DEVICE_ID */
} acpi;
} __packed;
+/* Device domain types */
+#define HV_DEVICE_DOMAIN_TYPE_S1 1 /* HV_DEVICE_DOMAIN_ID_TYPE_S1 */
+
+/* ID for default domain and NULL domain */
+#define HV_DEVICE_DOMAIN_ID_DEFAULT 0
+#define HV_DEVICE_DOMAIN_ID_NULL 0xFFFFFFFFULL
+
+union hv_device_domain_id { /* HV_DEVICE_DOMAIN_ID */
+ u64 as_uint64;
+ struct {
+ u32 type: 4;
+ u32 reserved: 28;
+ u32 id;
+ } __packed;
+};
+
+struct hv_input_device_domain { /* HV_INPUT_DEVICE_DOMAIN */
+ u64 partition_id;
+ union hv_input_vtl owner_vtl;
+ u8 padding[7];
+ union hv_device_domain_id domain_id;
+} __packed;
+
+/* HV_CREATE_DEVICE_DOMAIN_FLAGS */
+union hv_create_device_domain_flags {
+ u32 as_uint32;
+ struct {
+ u32 forward_progress_required: 1;
+ u32 inherit_owning_vtl: 1;
+ u32 reserved: 30;
+ } __packed;
+};
+
+/* HV_INPUT_CREATE_DEVICE_DOMAIN */
+struct hv_input_create_device_domain {
+ struct hv_input_device_domain device_domain;
+ union hv_create_device_domain_flags create_device_domain_flags;
+ u32 padding;
+} __packed;
+
+/* HV_INPUT_DELETE_DEVICE_DOMAIN */
+struct hv_input_delete_device_domain {
+ struct hv_input_device_domain device_domain;
+} __packed;
+
+/* HV_INPUT_ATTACH_DEVICE_DOMAIN */
+struct hv_input_attach_device_domain {
+ struct hv_input_device_domain device_domain;
+ union hv_device_id device_id;
+} __packed;
+
+/* HV_INPUT_DETACH_DEVICE_DOMAIN */
+struct hv_input_detach_device_domain {
+ u64 partition_id;
+ union hv_device_id device_id;
+} __packed;
+
+struct hv_device_domain_settings { /* HV_DEVICE_DOMAIN_SETTINGS */
+ struct {
+ /*
+ * Enable translations. If not enabled, all transaction bypass
+ * S1 translations.
+ */
+ u64 translation_enabled: 1;
+ u64 blocked: 1;
+ /*
+ * First stage address translation paging mode:
+ * 0: 4-level paging (default)
+ * 1: 5-level paging
+ */
+ u64 first_stage_paging_mode: 1;
+ u64 reserved: 61;
+ } flags;
+
+ /* Address of translation table */
+ u64 page_table_root;
+} __packed;
+
+/* HV_INPUT_CONFIGURE_DEVICE_DOMAIN */
+struct hv_input_configure_device_domain {
+ struct hv_input_device_domain device_domain;
+ struct hv_device_domain_settings settings;
+} __packed;
+
+/* HV_INPUT_GET_IOMMU_CAPABILITIES */
+struct hv_input_get_iommu_capabilities {
+ u64 partition_id;
+ u64 reserved;
+} __packed;
+
+/* HV_OUTPUT_GET_IOMMU_CAPABILITIES */
+struct hv_output_get_iommu_capabilities {
+ u32 size;
+ u16 reserved;
+ u8 max_iova_width;
+ u8 max_pasid_width;
+
+#define HV_IOMMU_CAP_PRESENT BIT_ULL(0)
+#define HV_IOMMU_CAP_S2 BIT_ULL(1)
+#define HV_IOMMU_CAP_S1 BIT_ULL(2)
+#define HV_IOMMU_CAP_S1_5LVL BIT_ULL(3)
+#define HV_IOMMU_CAP_PASID BIT_ULL(4)
+#define HV_IOMMU_CAP_ATS BIT_ULL(5)
+#define HV_IOMMU_CAP_PRI BIT_ULL(6)
+
+ u64 iommu_cap;
+ u64 pgsize_bitmap;
+} __packed;
+
+/* HV_LOGICAL_DEVICE_PROPERTY_CODE */
+enum hv_logical_device_property_code {
+ HV_LOGICAL_DEVICE_PROPERTY_PVIOMMU = 10,
+};
+
+/* HV_INPUT_GET_LOGICAL_DEVICE_PROPERTY */
+struct hv_input_get_logical_device_property {
+ u64 partition_id;
+ u64 logical_device_id;
+ /* Takes values from enum hv_logical_device_property_code. */
+ u32 code;
+ u32 reserved;
+} __packed;
+
+/* HV_OUTPUT_GET_LOGICAL_DEVICE_PROPERTY */
+struct hv_output_get_logical_device_property {
+#define HV_DEVICE_IOMMU_ENABLED BIT_ULL(0)
+ u64 device_iommu;
+ u64 reserved;
+} __packed;
+
+/* HV_INPUT_FLUSH_DEVICE_DOMAIN */
+struct hv_input_flush_device_domain {
+ struct hv_input_device_domain device_domain;
+ u32 flags;
+ u32 reserved;
+} __packed;
+
+union hv_iommu_flush_va { /* HV_IOMMU_GVA_RANGE */
+ u64 as_uint64;
+ struct {
+ u64 page_mask_shift : 6;
+ u64 reserved : 6;
+ u64 page_number : 52;
+ };
+} __packed;
+
+/* HV_INPUT_FLUSH_DEVICE_DOMAIN_LIST */
+struct hv_input_flush_device_domain_list {
+ struct hv_input_device_domain device_domain;
+#define HV_FLUSH_DEVICE_DOMAIN_LIST_IOMMU_FORMAT BIT(0)
+ u32 flags;
+ u32 reserved;
+ union hv_iommu_flush_va iova_list[];
+} __packed;
+
#endif /* _HV_HVHDK_MINI_H */
diff --git a/include/keys/request_key_auth-type.h b/include/keys/request_key_auth-type.h
index 01e42ee5f409..464636278c4f 100644
--- a/include/keys/request_key_auth-type.h
+++ b/include/keys/request_key_auth-type.h
@@ -22,7 +22,7 @@ struct request_key_auth {
const struct cred *cred;
void *callout_info;
size_t callout_len;
- pid_t pid;
+ struct pid *pid;
char op[8];
} __randomize_layout;
diff --git a/include/keys/trusted-type.h b/include/keys/trusted-type.h
index 9f9940482da4..3db61b57cf73 100644
--- a/include/keys/trusted-type.h
+++ b/include/keys/trusted-type.h
@@ -39,17 +39,6 @@ struct trusted_key_payload {
struct trusted_key_options {
uint16_t keytype;
- uint32_t keyhandle;
- unsigned char keyauth[TPM_DIGEST_SIZE];
- uint32_t blobauth_len;
- unsigned char blobauth[TPM_DIGEST_SIZE];
- uint32_t pcrinfo_len;
- unsigned char pcrinfo[MAX_PCRINFO_SIZE];
- int pcrlock;
- uint32_t hash;
- uint32_t policydigest_len;
- unsigned char policydigest[MAX_DIGEST_SIZE];
- uint32_t policyhandle;
void *private;
};
diff --git a/include/keys/trusted_tpm.h b/include/keys/trusted_tpm.h
index 3a0fa3bc8454..9a83269821e5 100644
--- a/include/keys/trusted_tpm.h
+++ b/include/keys/trusted_tpm.h
@@ -6,6 +6,20 @@
extern struct trusted_key_ops trusted_key_tpm_ops;
+struct trusted_key_tpm {
+ u32 keyhandle;
+ unsigned char keyauth[TPM_DIGEST_SIZE];
+ u32 blobauth_len;
+ unsigned char blobauth[TPM_DIGEST_SIZE];
+ u32 pcrinfo_len;
+ unsigned char pcrinfo[MAX_PCRINFO_SIZE];
+ int pcrlock;
+ u32 hash;
+ u32 policydigest_len;
+ unsigned char policydigest[MAX_DIGEST_SIZE];
+ u32 policyhandle;
+};
+
int tpm2_seal_trusted(struct tpm_chip *chip,
struct trusted_key_payload *payload,
struct trusted_key_options *options);
diff --git a/include/kunit/test.h b/include/kunit/test.h
index da5312e0dfa5..31d549578f8e 100644
--- a/include/kunit/test.h
+++ b/include/kunit/test.h
@@ -400,11 +400,10 @@ struct kunit_suite_set kunit_merge_suite_sets(struct kunit_suite_set init_suite_
const void *kunit_array_gen_params(struct kunit *test, const void *prev, char *desc);
#if IS_BUILTIN(CONFIG_KUNIT)
-int kunit_run_all_tests(void);
+void kunit_run_all_tests(void);
#else
-static inline int kunit_run_all_tests(void)
+static inline void kunit_run_all_tests(void)
{
- return 0;
}
#endif /* IS_BUILTIN(CONFIG_KUNIT) */
diff --git a/include/kvm/arm_arch_timer.h b/include/kvm/arm_arch_timer.h
index bc6f2fdd7ad3..80f96ea59f1a 100644
--- a/include/kvm/arm_arch_timer.h
+++ b/include/kvm/arm_arch_timer.h
@@ -195,4 +195,19 @@ static inline void timer_set_offset(struct arch_timer_context *ctxt, u64 offset)
WRITE_ONCE(*ctxt->offset.vm_offset, offset);
}
+/*
+ * CVAL to program when the hardware won't apply the timer's offset, so that
+ * its compare against the raw counter matches the guest's at 'now'. An
+ * expired timer stays expired; one past the wrap never fires.
+ */
+static inline u64 timer_apply_offset(u64 cval, u64 offset, u64 now)
+{
+ u64 hw = cval + offset;
+
+ if (now - offset >= cval)
+ return 0;
+
+ return hw > now ? hw : U64_MAX;
+}
+
#endif
diff --git a/include/kvm/arm_psci.h b/include/kvm/arm_psci.h
index f86a006d6713..06c20612e9e7 100644
--- a/include/kvm/arm_psci.h
+++ b/include/kvm/arm_psci.h
@@ -10,6 +10,8 @@
#include <linux/kvm_host.h>
#include <uapi/linux/psci.h>
+#include <asm/kvm_emulate.h>
+
#define KVM_ARM_PSCI_0_1 PSCI_VERSION(0, 1)
#define KVM_ARM_PSCI_0_2 PSCI_VERSION(0, 2)
#define KVM_ARM_PSCI_1_0 PSCI_VERSION(1, 0)
diff --git a/include/kvm/arm_vgic.h b/include/kvm/arm_vgic.h
index 086b7578e5f3..7be81b936bf1 100644
--- a/include/kvm/arm_vgic.h
+++ b/include/kvm/arm_vgic.h
@@ -31,7 +31,12 @@
#define VGIC_MAX_SPI 1019
#define VGIC_MAX_RESERVED 1023
#define VGIC_MIN_LPI 8192
-#define KVM_IRQCHIP_NUM_PINS (1020 - 32)
+
+/*
+ * The common IRQ routing table must accommodate all GIC types. GICv2 and
+ * GICv3 need 988 pins, while GICv5 needs 1024 pins.
+ */
+#define KVM_IRQCHIP_NUM_PINS 1024
/*
* GICv5 supports 128 PPIs, but only the first 64 are architected. We only
@@ -40,6 +45,8 @@
* in KVM for now. At a future stage, this can be bumped up to 128, if required.
*/
#define VGIC_V5_NR_PRIVATE_IRQS 64
+#define VGIC_V5_DEFAULT_NR_SPIS 32
+#define VGIC_V5_MAX_NR_SPIS BIT(10)
#define is_v5_type(t, i) (FIELD_GET(GICV5_HWIRQ_TYPE, (i)) == (t))
@@ -132,6 +139,19 @@ enum vgic_type {
VGIC_V5, /* Newer, fancier GICv5 */
};
+struct vgic_v5_irs_caps {
+ /* Base address of the host IRS's CONFIG_FRAME */
+ void __iomem *irs_base;
+
+ /* Raw host IRS ID registers */
+ u32 idr2;
+ u32 idr3;
+ u32 idr4;
+
+ /* Is the IRS coherent with us, or not? */
+ bool non_coherent;
+};
+
/* same for all guests, as depending only on the _host's_ GIC model */
struct vgic_global {
/* type of the host GIC */
@@ -159,9 +179,16 @@ struct vgic_global {
/* Maintenance IRQ number */
unsigned int maint_irq;
- /* maximum number of VCPUs allowed (GICv2 limits us to 8) */
+ /*
+ * Maximum number of VCPUs exposed before userspace has selected a
+ * VGIC model. Individual VGIC models can impose a lower limit
+ * (GICv2 limits us to 8).
+ */
int max_gic_vcpus;
+ /* Maximum number of VCPUs allowed for a GICv5 VM. */
+ int max_gicv5_vcpus;
+
/* Only needed for the legacy KVM_CREATE_IRQCHIP */
bool can_emulate_gicv2;
@@ -182,6 +209,9 @@ struct vgic_global {
struct {
DECLARE_BITMAP(impl_ppi_mask, VGIC_V5_NR_PRIVATE_IRQS);
} vgic_v5_ppi_caps;
+
+ /* GICv5 IRS capabilities */
+ struct vgic_v5_irs_caps vgic_v5_irs_caps;
};
extern struct vgic_global kvm_vgic_global_state;
@@ -217,6 +247,12 @@ struct irq_ops {
bool (*get_input_level)(int vintid);
/*
+ * Function pointer to directly update hardware pending state after the
+ * VGIC shadow pending state has changed.
+ */
+ bool (*set_pending_state)(struct kvm_vcpu *vcpu, struct vgic_irq *irq);
+
+ /*
* Function pointer to override the queuing of an IRQ.
*/
bool (*queue_irq_unlock)(struct kvm *kvm, struct vgic_irq *irq,
@@ -287,7 +323,8 @@ enum iodev_type {
IODEV_CPUIF,
IODEV_DIST,
IODEV_REDIST,
- IODEV_ITS
+ IODEV_ITS,
+ IODEV_GICV5_IRS
};
struct vgic_io_device {
@@ -345,7 +382,11 @@ struct vgic_redist_region {
struct list_head list;
};
+#define VGIC_V5_VM_ID_INVAL (-1)
+
struct vgic_v5_vm {
+ struct kvm *kvm;
+
/*
* We only expose a subset of PPIs to the guest. This subset is a
* combination of the PPIs that are actually implemented and what we
@@ -363,6 +404,96 @@ struct vgic_v5_vm {
* convenient way to do that).
*/
DECLARE_BITMAP(vgic_ppi_hmr, VGIC_V5_NR_PRIVATE_IRQS);
+
+ struct fwnode_handle *fwnode;
+ struct irq_domain *domain;
+ int vpe_db_base;
+ u32 vm_id;
+ bool vmte_allocated;
+};
+
+/*** GICv5 ***/
+struct vgic_v5_irs {
+ /* base addresses in guest physical address space: */
+ gpa_t vgic_v5_irs_base;
+
+ struct vgic_io_device iodev;
+ struct kvm_device *dev;
+
+ /* IRS state - used for registers etc */
+ struct {
+ u8 domain;
+ u8 pa_range;
+ bool virt;
+ bool setlpi;
+ bool mec;
+ bool mpam;
+ bool swe;
+ u16 irs_id;
+ } idr0;
+
+ struct {
+ /* PE_CNT is populated from online_vcpus at runtime */
+ u8 priority_bits;
+ } idr1;
+
+ struct {
+ u8 id_bits;
+ u8 min_lpi_id_bits;
+ bool ist_levels;
+ u8 ist_l2sz;
+ bool istmd;
+ u8 istmd_sz;
+ } idr2;
+
+ struct {
+ u32 spi_range;
+ } idr5;
+
+ struct {
+ u32 spi_irs_range;
+ } idr6;
+
+ struct {
+ u32 spi_base;
+ } idr7;
+
+ struct {
+ u8 sh;
+ u8 oc;
+ u8 ic;
+ bool ist_ra;
+ bool ist_wa;
+ bool vmt_ra;
+ bool vpet_ra;
+ bool vmd_ra;
+ bool vmd_wa;
+ bool vped_ra;
+ bool vped_wa;
+ } cr1;
+
+ struct {
+ u32 id;
+ } spi_selr;
+
+ struct {
+ u32 iaffid;
+ } pe_selr;
+
+ struct {
+ u8 lpi_id_bits;
+ u8 l2sz;
+ u8 istsz;
+ bool structure;
+ } ist_cfgr;
+
+ struct {
+ bool valid;
+ u64 addr;
+ } ist_baser;
+
+ /* A valid userspace-restored BASER still needs its host LPI IST. */
+ bool lpi_ist_restore_pending;
};
struct vgic_dist {
@@ -442,6 +573,11 @@ struct vgic_dist {
* GICv5 per-VM data.
*/
struct vgic_v5_vm gicv5_vm;
+
+ /*
+ * GICv5 IRS data. Dynamically allocated due to the size.
+ */
+ struct vgic_v5_irs *vgic_v5_irs_data;
};
struct vgic_v2_cpu_if {
@@ -492,6 +628,9 @@ struct vgic_v5_cpu_if {
*/
u64 vgic_icsr;
+ /* The contextr used to make VPEs resident and non-resident */
+ u64 vgic_contextr;
+
struct gicv5_vpe gicv5_vpe;
};
@@ -598,10 +737,11 @@ void kvm_vgic_process_async_update(struct kvm_vcpu *vcpu);
void vgic_v3_dispatch_sgi(struct kvm_vcpu *vcpu, u64 reg, bool allow_group1);
/**
- * kvm_vgic_get_max_vcpus - Get the maximum number of VCPUs allowed by HW
+ * kvm_vgic_get_max_vcpus - Get the pre-VGIC-selection VCPU limit
*
- * The host's GIC naturally limits the maximum amount of VCPUs a guest
- * can use.
+ * Userspace can query KVM_CAP_MAX_VCPUS before selecting a VGIC model, so
+ * expose the highest model-specific limit and let kvm_vgic_create() enforce
+ * the selected model's actual limit.
*/
static inline int kvm_vgic_get_max_vcpus(void)
{
@@ -627,7 +767,66 @@ int vgic_v4_load(struct kvm_vcpu *vcpu);
void vgic_v4_commit(struct kvm_vcpu *vcpu);
int vgic_v4_put(struct kvm_vcpu *vcpu);
-int vgic_v5_finalize_ppi_state(struct kvm *kvm);
+static inline u8 vgic_v5_irs_ist_id_bits(const struct vgic_v5_irs_caps *caps)
+{
+ return FIELD_GET(GICV5_IRS_IDR2_ID_BITS, caps->idr2);
+}
+
+static inline u8 vgic_v5_irs_min_lpi_id_bits(const struct vgic_v5_irs_caps *caps)
+{
+ return FIELD_GET(GICV5_IRS_IDR2_MIN_LPI_ID_BITS, caps->idr2);
+}
+
+static inline bool vgic_v5_irs_ist_levels(const struct vgic_v5_irs_caps *caps)
+{
+ return !!(caps->idr2 & GICV5_IRS_IDR2_IST_LEVELS);
+}
+
+static inline u8 vgic_v5_irs_ist_l2sz(const struct vgic_v5_irs_caps *caps)
+{
+ return FIELD_GET(GICV5_IRS_IDR2_IST_L2SZ, caps->idr2);
+}
+
+static inline bool vgic_v5_irs_istmd(const struct vgic_v5_irs_caps *caps)
+{
+ return !!(caps->idr2 & GICV5_IRS_IDR2_ISTMD);
+}
+
+static inline u8 vgic_v5_irs_istmd_sz(const struct vgic_v5_irs_caps *caps)
+{
+ return FIELD_GET(GICV5_IRS_IDR2_ISTMD_SZ, caps->idr2);
+}
+
+static inline u32 vgic_v5_irs_max_vms(const struct vgic_v5_irs_caps *caps)
+{
+ return BIT(FIELD_GET(GICV5_IRS_IDR3_VM_ID_BITS, caps->idr3));
+}
+
+static inline bool vgic_v5_irs_two_level_vmt_support(const struct vgic_v5_irs_caps *caps)
+{
+ return !!(caps->idr3 & GICV5_IRS_IDR3_VMT_LEVELS);
+}
+
+static inline u16 vgic_v5_irs_vmd_size(const struct vgic_v5_irs_caps *caps)
+{
+ if (!(caps->idr3 & GICV5_IRS_IDR3_VMD))
+ return 0;
+
+ return BIT(FIELD_GET(GICV5_IRS_IDR3_VMD_SZ, caps->idr3));
+}
+
+static inline u16 vgic_v5_irs_vped_size(const struct vgic_v5_irs_caps *caps)
+{
+ return BIT(FIELD_GET(GICV5_IRS_IDR4_VPED_SZ, caps->idr4));
+}
+
+static inline u32 vgic_v5_irs_max_vpes(const struct vgic_v5_irs_caps *caps)
+{
+ /* Field stores VPE_ID_BITS - 1 */
+ return BIT(FIELD_GET(GICV5_IRS_IDR4_VPE_ID_BITS, caps->idr4) + 1);
+}
+
+int vgic_v5_finalize_ppi_state(struct kvm_vcpu *vcpu);
bool vgic_v5_ppi_queue_irq_unlock(struct kvm *kvm, struct vgic_irq *irq,
unsigned long flags);
void vgic_v5_set_ppi_dvi(struct kvm_vcpu *vcpu, struct vgic_irq *irq, bool dvi);
diff --git a/include/linux/acpi.h b/include/linux/acpi.h
index ddacac812094..d7f1f3d05390 100644
--- a/include/linux/acpi.h
+++ b/include/linux/acpi.h
@@ -25,17 +25,19 @@ struct irq_domain_ops;
#define _LINUX
#endif
#include <acpi/acpi.h>
+#include <acpi/acpi_bus.h>
#include <acpi/acpi_numa.h>
#ifdef CONFIG_ACPI
+DEFINE_FREE(acpi_object_free, union acpi_object *, if (_T) ACPI_FREE(_T));
+
#include <linux/list.h>
#include <linux/dynamic_debug.h>
#include <linux/module.h>
#include <linux/mutex.h>
#include <linux/fw_table.h>
-#include <acpi/acpi_bus.h>
#include <acpi/acpi_drivers.h>
#include <acpi/acpi_io.h>
#include <asm/acpi.h>
@@ -105,8 +107,6 @@ static inline const char *acpi_dev_name(struct acpi_device *adev)
return dev_name(&adev->dev);
}
-struct device *acpi_get_first_physical_node(struct acpi_device *adev);
-
enum acpi_irq_model_id {
ACPI_IRQ_MODEL_PIC = 0,
ACPI_IRQ_MODEL_IOAPIC,
@@ -434,7 +434,7 @@ extern acpi_handle ec_get_handle(void);
extern bool acpi_is_pnp_device(struct acpi_device *);
-#if defined(CONFIG_ACPI_WMI) || defined(CONFIG_ACPI_WMI_MODULE)
+#if IS_ENABLED(CONFIG_ACPI_WMI)
typedef void (*wmi_notify_handler) (union acpi_object *data, void *context);
@@ -938,11 +938,6 @@ static inline const char *acpi_dev_name(struct acpi_device *adev)
return NULL;
}
-static inline struct device *acpi_get_first_physical_node(struct acpi_device *adev)
-{
- return NULL;
-}
-
static inline void acpi_early_init(void) { }
static inline void acpi_subsystem_init(void) { }
@@ -1305,34 +1300,34 @@ void __acpi_handle_debug(struct _ddebug *descriptor, acpi_handle handle, const c
#endif
/*
- * acpi_handle_<level>: Print message with ACPI prefix and object path
+ * acpi_handle_<level> - Print a message with ACPI prefix and object path
*
- * These interfaces acquire the global namespace mutex to obtain an object
- * path. In interrupt context, it shows the object path as <n/a>.
+ * In thread context, the global namespace mutex is acquired to obtain the
+ * object path. In interrupt context, the object path is shown as <n/a>.
*/
#define acpi_handle_emerg(handle, fmt, ...) \
- acpi_handle_printk(KERN_EMERG, handle, fmt, ##__VA_ARGS__)
+ acpi_handle_printk(KERN_EMERG, handle, dev_fmt(fmt), ##__VA_ARGS__)
#define acpi_handle_alert(handle, fmt, ...) \
- acpi_handle_printk(KERN_ALERT, handle, fmt, ##__VA_ARGS__)
+ acpi_handle_printk(KERN_ALERT, handle, dev_fmt(fmt), ##__VA_ARGS__)
#define acpi_handle_crit(handle, fmt, ...) \
- acpi_handle_printk(KERN_CRIT, handle, fmt, ##__VA_ARGS__)
+ acpi_handle_printk(KERN_CRIT, handle, dev_fmt(fmt), ##__VA_ARGS__)
#define acpi_handle_err(handle, fmt, ...) \
- acpi_handle_printk(KERN_ERR, handle, fmt, ##__VA_ARGS__)
+ acpi_handle_printk(KERN_ERR, handle, dev_fmt(fmt), ##__VA_ARGS__)
#define acpi_handle_warn(handle, fmt, ...) \
- acpi_handle_printk(KERN_WARNING, handle, fmt, ##__VA_ARGS__)
+ acpi_handle_printk(KERN_WARNING, handle, dev_fmt(fmt), ##__VA_ARGS__)
#define acpi_handle_notice(handle, fmt, ...) \
- acpi_handle_printk(KERN_NOTICE, handle, fmt, ##__VA_ARGS__)
+ acpi_handle_printk(KERN_NOTICE, handle, dev_fmt(fmt), ##__VA_ARGS__)
#define acpi_handle_info(handle, fmt, ...) \
- acpi_handle_printk(KERN_INFO, handle, fmt, ##__VA_ARGS__)
+ acpi_handle_printk(KERN_INFO, handle, dev_fmt(fmt), ##__VA_ARGS__)
#if defined(DEBUG)
#define acpi_handle_debug(handle, fmt, ...) \
- acpi_handle_printk(KERN_DEBUG, handle, fmt, ##__VA_ARGS__)
+ acpi_handle_printk(KERN_DEBUG, handle, dev_fmt(fmt), ##__VA_ARGS__)
#else
#if defined(CONFIG_DYNAMIC_DEBUG)
#define acpi_handle_debug(handle, fmt, ...) \
_dynamic_func_call(fmt, __acpi_handle_debug, \
- handle, pr_fmt(fmt), ##__VA_ARGS__)
+ handle, dev_fmt(fmt), ##__VA_ARGS__)
#else
#define acpi_handle_debug(handle, fmt, ...) \
({ \
diff --git a/include/linux/aer.h b/include/linux/aer.h
index df0f5c382286..043ee76b6f53 100644
--- a/include/linux/aer.h
+++ b/include/linux/aer.h
@@ -24,6 +24,13 @@
#define PCIE_STD_MAX_TLP_PREFIXLOG 4
#define PCIE_STD_MAX_TLP_HEADERLOG (PCIE_STD_NUM_TLP_HEADERLOG + 10)
+/*
+ * Size of the AER Capability register block in hardware, long enough for the
+ * longest Flit mode TLP Log. struct aer_capability_regs below is larger and
+ * laid out differently; use aer_cap_regs_unpack() to convert.
+ */
+#define PCIE_AER_CAP_HW_SIZE 96
+
struct pci_dev;
struct pcie_tlp_log {
@@ -68,6 +75,8 @@ static inline void pci_aer_unmask_internal_errors(struct pci_dev *dev) { }
void pci_print_aer(struct pci_dev *dev, int aer_severity,
struct aer_capability_regs *aer);
+void aer_cap_regs_unpack(struct aer_capability_regs *regs, const void *raw,
+ size_t raw_len);
int cper_severity_to_aer(int cper_severity);
void aer_recover_queue(int domain, unsigned int bus, unsigned int devfn,
int severity, struct aer_capability_regs *aer_regs);
diff --git a/include/linux/amd-iommu.h b/include/linux/amd-iommu.h
index edcee9f5335a..104817e8d897 100644
--- a/include/linux/amd-iommu.h
+++ b/include/linux/amd-iommu.h
@@ -11,11 +11,11 @@
#include <linux/types.h>
struct amd_iommu;
+struct pci_dev;
#ifdef CONFIG_AMD_IOMMU
struct task_struct;
-struct pci_dev;
extern void amd_iommu_detect(void);
@@ -76,4 +76,15 @@ static inline int amd_iommu_snp_disable(void) { return 0; }
static inline bool amd_iommu_sev_tio_supported(void) { return false; }
#endif
+#ifdef CONFIG_AMD_IOMMU
+int amd_iommu_enable_perfopt(struct pci_dev *pdev);
+void amd_iommu_disable_perfopt(struct pci_dev *pdev);
+#else
+static inline int amd_iommu_enable_perfopt(struct pci_dev *pdev)
+{
+ return 0;
+}
+static inline void amd_iommu_disable_perfopt(struct pci_dev *pdev) { }
+#endif
+
#endif /* _ASM_X86_AMD_IOMMU_H */
diff --git a/include/linux/apple-gmux.h b/include/linux/apple-gmux.h
index 206d97ffda79..d7939c3a08fd 100644
--- a/include/linux/apple-gmux.h
+++ b/include/linux/apple-gmux.h
@@ -109,7 +109,7 @@ static inline bool apple_gmux_detect(struct pnp_dev *pnp_dev, enum apple_gmux_ty
if (!adev)
return false;
- dev = get_device(acpi_get_first_physical_node(adev));
+ dev = acpi_bus_get_primary_device(adev);
acpi_dev_put(adev);
if (!dev)
return false;
diff --git a/include/linux/arm-rmi-cmds.h b/include/linux/arm-rmi-cmds.h
new file mode 100644
index 000000000000..a84e50ac851c
--- /dev/null
+++ b/include/linux/arm-rmi-cmds.h
@@ -0,0 +1,581 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (C) 2026 ARM Ltd.
+ */
+
+#ifndef __LINUX_ARM_RMI_CMDS_H_
+#define __LINUX_ARM_RMI_CMDS_H_
+
+#include <linux/arm-smccc-rmi.h>
+#include <linux/bug.h>
+#include <linux/gfp.h>
+#include <linux/processor.h>
+#include <linux/string.h>
+#include <linux/types.h>
+
+#define RMI_MAX_ADDR_LIST 256
+
+struct rmi_sro_state {
+ struct arm_smccc_1_2_regs regs;
+ int addr_count;
+ unsigned long addr_list[RMI_MAX_ADDR_LIST];
+};
+
+#define RMM_BLOCKED_RETRY_COUNT 2
+/*
+ * rmi_smccc_invoke: Invoke the RMI call and return the results, retrying the
+ * command when status is RMI_BUSY. If we encounter RMI_BLOCKED, we retry
+ * it one more time before we give up. The caller is supposed to handle the
+ * result and reissue if required.
+ *
+ * We don't expect to see RMI_BLOCKED on a practical system, except when
+ * there are parallel requests that results in long standing operation,
+ * with one blocking the other.
+ *
+ * @regs: Input parameters filled in. Updated with the output results
+ * after the call.
+ */
+static inline void rmi_smccc_invoke(struct arm_smccc_1_2_regs *regs)
+{
+ struct arm_smccc_1_2_regs args = *regs;
+ long status;
+ int i = 0;
+
+ while (i < RMM_BLOCKED_RETRY_COUNT) {
+ arm_smccc_1_2_smc(&args, regs);
+
+ status = RMI_RESULT_STATUS(regs->a0);
+ if (status != RMI_BUSY && status != RMI_BLOCKED)
+ break;
+ if (status == RMI_BLOCKED)
+ i++;
+ cpu_relax();
+ }
+}
+
+/*
+ * rmi_smccc_invoke_once: Invoke the RMI call and return the results. Do not
+ * retry the command. Let the caller deal with RMI_BUSY or RMI_BLOCKED.
+ *
+ * @regs: Input parameters filled in. Updated with the output results
+ * after the call.
+ */
+static __always_inline void rmi_smccc_invoke_once(struct arm_smccc_1_2_regs *regs)
+{
+ arm_smccc_1_2_smc(regs, regs);
+}
+
+unsigned long rmi_feat_reg(unsigned int index);
+
+int rmi_delegate_range(phys_addr_t phys, unsigned long size,
+ phys_addr_t *out_phys);
+int rmi_undelegate_range(phys_addr_t phys, unsigned long size);
+int rmi_free_delegated_page(phys_addr_t phys);
+
+static inline int rmi_delegate_page(phys_addr_t phys)
+{
+ return rmi_delegate_range(phys, PAGE_SIZE, NULL);
+}
+
+static inline int rmi_undelegate_page(phys_addr_t phys)
+{
+ return rmi_undelegate_range(phys, PAGE_SIZE);
+}
+
+long rmi_sro_memxfer_execute(struct rmi_sro_state *sro, gfp_t gfp);
+void rmi_sro_free(struct rmi_sro_state *sro);
+long rmi_sro_execute(struct arm_smccc_1_2_regs *regs);
+
+/*
+ * Resetting the addr_count is sufficient to ignore the addr_list contents.
+ */
+#define rmi_sro_memxfer_cmd(sro, gfp, ...) ({ \
+ struct rmi_sro_state *__sro = (sro); \
+ __sro->addr_count = 0; \
+ __sro->regs = (struct arm_smccc_1_2_regs){ __VA_ARGS__ }; \
+ long __ret = rmi_sro_memxfer_execute(__sro, gfp); \
+ rmi_sro_free(__sro); \
+ __ret; \
+})
+
+#ifdef CONFIG_ARM_RMM_RMI
+
+bool is_rmm_active(void);
+bool is_rmi_available(void);
+
+#else
+
+static inline bool is_rmm_active(void)
+{
+ return false;
+}
+
+static inline bool is_rmi_available(void)
+{
+ return false;
+}
+#endif /* CONFIG_ARM_RMM_RMI */
+
+/**
+ * rmi_rtt_data_map_init() - Create a mapping at protected IPA, copying contents
+ * from a given non-secure source granule.
+ * @rd: PA of the RD
+ * @data: PA of the target granule mapped in the guest
+ * @ipa: IPA at which the granule @data will be mapped in the guest
+ * @src: PA of the source granule with contents
+ * @flags: RMI_MEASURE_CONTENT if the contents should be measured
+ *
+ * Create a mapping from Protected IPA space to conventional memory, copying
+ * contents from a Non-secure Granule provided by the caller.
+ *
+ * Return: 0 on success, positive RMI result code or negative Linux error code
+ */
+static inline long rmi_rtt_data_map_init(unsigned long rd, unsigned long data,
+ unsigned long ipa, unsigned long src,
+ unsigned long flags)
+{
+ struct arm_smccc_1_2_regs regs = {
+ SMC_RMI_RTT_DATA_MAP_INIT, rd, data, ipa, src, flags
+ };
+
+ return rmi_sro_execute(&regs);
+}
+
+/**
+ * rmi_rtt_data_map() - Create mappings in protected IPA range with unknown contents
+ * @rd: PA of the RD
+ * @base: Base of the target IPA range
+ * @top: Top of the target IPA range
+ * @flags: Flags
+ * @oaddr: Output address set descriptor
+ * @out_top: Top address of range which was processed.
+ *
+ * Return: 0 on success, positive RMI result code or negative Linux error code.
+ * NOTE: out_top is only valid with ret == RMI_SUCCESS
+ */
+static inline long rmi_rtt_data_map(unsigned long rd,
+ unsigned long base,
+ unsigned long top,
+ unsigned long flags,
+ unsigned long oaddr,
+ unsigned long *out_top)
+{
+ struct arm_smccc_1_2_regs regs = {
+ SMC_RMI_RTT_DATA_MAP, rd, base, top, flags, oaddr
+ };
+ long ret;
+
+ ret = rmi_sro_execute(&regs);
+
+ if (ret == RMI_SUCCESS && out_top)
+ *out_top = regs.a1;
+
+ return ret;
+}
+
+/**
+ * rmi_rtt_data_unmap() - Remove mappings to conventional memory at a protected
+ * IPA range
+ * @rd: PA of the RD
+ * @base: Base of the target IPA range
+ * @top: Top of the target IPA range
+ * @flags: Flags
+ * @oaddr: Output address set descriptor
+ * @out_top: Returns top IPA of range which has been unmapped
+ * @out_range: Output address range
+ * @out_count: Number of entries in output address list
+ *
+ * Removes mappings to convention memory with a target Protected IPA range.
+ *
+ * Return: 0 on success, positive RMI result code or negative Linux error code
+ * NOTE: out_top is only valid with ret == RMI_SUCCESS
+ */
+static inline long rmi_rtt_data_unmap(unsigned long rd,
+ unsigned long base,
+ unsigned long top,
+ unsigned long flags,
+ unsigned long oaddr,
+ unsigned long *out_top,
+ unsigned long *out_range,
+ unsigned long *out_count)
+{
+ struct arm_smccc_1_2_regs regs = {
+ SMC_RMI_RTT_DATA_UNMAP, rd, base, top, flags, oaddr
+ };
+ long ret;
+
+ ret = rmi_sro_execute(&regs);
+
+ if (ret != RMI_SUCCESS)
+ return ret;
+
+ if (out_top)
+ *out_top = regs.a1;
+ if (out_range)
+ *out_range = regs.a2;
+ if (out_count)
+ *out_count = regs.a3;
+
+ return RMI_SUCCESS;
+}
+
+/**
+ * rmi_psci_complete() - Complete pending PSCI command
+ * @calling_rec: PA of the calling REC
+ * @status: Status of the PSCI request
+ *
+ * Completes a pending PSCI command.
+ *
+ * Return: RMI return code
+ */
+static inline long rmi_psci_complete(unsigned long calling_rec,
+ unsigned long status)
+{
+ struct arm_smccc_1_2_regs regs = {
+ SMC_RMI_PSCI_COMPLETE, calling_rec, status,
+ };
+
+ rmi_smccc_invoke(&regs);
+ return regs.a0;
+}
+
+/**
+ * rmi_realm_activate() - Activate a realm
+ * @rd: PA of the RD
+ *
+ * Mark a realm as Active, signalling that creation is completed, allowing
+ * execution of the realm.
+ *
+ * Return: RMI return code
+ */
+static inline long rmi_realm_activate(unsigned long rd)
+{
+ struct arm_smccc_1_2_regs regs = {
+ SMC_RMI_REALM_ACTIVATE, rd,
+ };
+
+ rmi_smccc_invoke(&regs);
+ return regs.a0;
+}
+
+/**
+ * rmi_realm_create() - Create a realm
+ * @rd: PA of the RD
+ * @params: PA of realm parameters
+ * @sro: Preallocated SRO context
+ *
+ * Create a new realm using the given parameters.
+ *
+ * Return: 0 on success, positive RMI result code or negative Linux error code
+ */
+static inline long rmi_realm_create(unsigned long rd, unsigned long params,
+ struct rmi_sro_state *sro)
+{
+ return rmi_sro_memxfer_cmd(sro, GFP_KERNEL,
+ SMC_RMI_REALM_CREATE, rd, params);
+}
+
+/**
+ * rmi_realm_terminate() - Terminate a realm
+ * @rd: PA of the RD
+ * @sro: Preallocated SRO context
+ *
+ * Terminates a realm, moving it into a ZOMBIE state
+ *
+ * Return: 0 on success, positive RMI result code or negative Linux error code
+ */
+static inline long rmi_realm_terminate(unsigned long rd,
+ struct rmi_sro_state *sro)
+{
+ return rmi_sro_memxfer_cmd(sro, GFP_KERNEL,
+ SMC_RMI_REALM_TERMINATE, rd);
+}
+
+/**
+ * rmi_realm_destroy() - Destroy a realm
+ * @rd: PA of the RD
+ * @sro: Preallocated SRO context
+ *
+ * Destroys a realm, all objects belonging to the realm must be destroyed first.
+ *
+ * Return: 0 on success, positive RMI result code or negative Linux error code
+ */
+static inline long rmi_realm_destroy(unsigned long rd,
+ struct rmi_sro_state *sro)
+{
+ return rmi_sro_memxfer_cmd(sro, GFP_KERNEL,
+ SMC_RMI_REALM_DESTROY, rd);
+}
+
+/**
+ * rmi_rec_create() - Create a REC
+ * @rd: PA of the RD
+ * @rec: PA of the target REC
+ * @params: PA of REC parameters
+ * @sro: Allocated SRO context to be used
+ *
+ * Create a REC using the parameters specified in the struct rec_params pointed
+ * to by @params.
+ *
+ * Return: 0 on success, positive RMI result code or negative Linux error code
+ */
+static inline long rmi_rec_create(unsigned long rd,
+ unsigned long rec,
+ unsigned long params,
+ struct rmi_sro_state *sro)
+{
+ return rmi_sro_memxfer_cmd(sro, GFP_KERNEL,
+ SMC_RMI_REC_CREATE, rd, rec, params);
+}
+
+/**
+ * rmi_rec_destroy() - Destroy a REC
+ * @rec: PA of the target REC
+ * @sro: Allocated SRO context to be used
+ *
+ * Destroys a REC. The REC must not be running.
+ *
+ * Return: 0 on success, positive RMI result code or negative Linux error code
+ */
+static __always_inline long rmi_rec_destroy(unsigned long rec,
+ struct rmi_sro_state *sro)
+{
+ return rmi_sro_memxfer_cmd(sro, GFP_KERNEL, SMC_RMI_REC_DESTROY, rec);
+}
+
+/**
+ * rmi_rec_enter() - Enter a REC
+ * @rec: PA of the target REC
+ * @run_ptr: PA of RecRun structure
+ *
+ * Starts (or continues) execution within a REC.
+ *
+ * Return: RMI result
+ */
+static __always_inline long rmi_rec_enter(unsigned long rec, unsigned long run_ptr)
+{
+ struct arm_smccc_1_2_regs regs = {
+ SMC_RMI_REC_ENTER, rec, run_ptr,
+ };
+
+ rmi_smccc_invoke_once(&regs);
+ return regs.a0;
+}
+
+/**
+ * rmi_rtt_create() - Creates an RTT
+ * @rd: PA of the RD
+ * @rtt: PA of the target RTT
+ * @ipa: Base of the IPA range described by the RTT
+ * @level: Depth of the RTT within the tree
+ *
+ * Creates an RTT (Realm Translation Table) at the specified level for the
+ * translation of the specified address within the realm.
+ *
+ * Return: 0 on success, positive RMI result code or negative Linux error code
+ */
+static inline long rmi_rtt_create(unsigned long rd, unsigned long rtt,
+ unsigned long ipa, long level)
+{
+ struct arm_smccc_1_2_regs regs = {
+ SMC_RMI_RTT_CREATE, rd, rtt, ipa, level
+ };
+
+ return rmi_sro_execute(&regs);
+}
+
+/**
+ * rmi_rtt_destroy() - Destroy an RTT
+ * @rd: PA of the RD
+ * @ipa: Base of the IPA range described by the RTT
+ * @level: RTT level
+ * @out_rtt: Pointer to write the PA of the RTT which was destroyed
+ * @out_top: Pointer to write the top IPA of non-live RTT entries, from entry
+ * at which the RTT walk terminated.
+ *
+ * Destroys an RTT. The RTT must be non-live, i.e. none of the entries in the
+ * table are in ASSIGNED or TABLE state.
+ *
+ * Return: 0 on success, positive RMI result code or negative Linux error code.
+ */
+static inline long rmi_rtt_destroy(unsigned long rd,
+ unsigned long ipa,
+ long level,
+ unsigned long *out_rtt,
+ unsigned long *out_top)
+{
+ struct arm_smccc_1_2_regs regs = {
+ SMC_RMI_RTT_DESTROY, rd, ipa, level
+ };
+ long ret = rmi_sro_execute(&regs);
+
+ switch (RMI_RESULT_STATUS(ret)) {
+ case RMI_SUCCESS:
+ if (out_rtt)
+ *out_rtt = regs.a1;
+ fallthrough;
+ case RMI_ERROR_RTT:
+ if (out_top)
+ *out_top = regs.a2;
+ break;
+ default:
+ break;
+ }
+
+ return ret;
+}
+
+/**
+ * rmi_rtt_fold() - Fold an RTT
+ * @rd: PA of the RD
+ * @ipa: Base of the IPA range described by the RTT
+ * @level: Depth of the RTT within the tree
+ * @out_rtt: Pointer to write the PA of the RTT which was destroyed
+ *
+ * Folds an RTT. If all entries with the RTT are 'homogeneous' the RTT can be
+ * folded into the parent and the RTT destroyed.
+ *
+ * Return: 0 on success, positive RMI result code or negative Linux error code
+ */
+static inline long rmi_rtt_fold(unsigned long rd, unsigned long ipa,
+ long level, unsigned long *out_rtt)
+{
+ struct arm_smccc_1_2_regs regs = {
+ SMC_RMI_RTT_FOLD, rd, ipa, level
+ };
+ long ret = rmi_sro_execute(&regs);
+
+ if (ret == RMI_SUCCESS && out_rtt)
+ *out_rtt = regs.a1;
+
+ return ret;
+}
+
+/**
+ * rmi_rtt_init_ripas() - Set RIPAS for new realm
+ * @rd: PA of the RD
+ * @base: Base of target IPA region
+ * @top: Top of target IPA region
+ * @out_top: Top IPA of range whose RIPAS was modified
+ *
+ * Sets the RIPAS of a target IPA range to RAM, for a realm in the NEW state.
+ *
+ * Return: 0 on success, positive RMI result code or negative Linux error code
+ */
+static inline long rmi_rtt_init_ripas(unsigned long rd, unsigned long base,
+ unsigned long top, unsigned long *out_top)
+{
+ struct arm_smccc_1_2_regs regs = {
+ SMC_RMI_RTT_INIT_RIPAS, rd, base, top
+ };
+ long ret = rmi_sro_execute(&regs);
+
+ if (ret == RMI_SUCCESS && out_top)
+ *out_top = regs.a1;
+
+ return ret;
+}
+
+/**
+ * rmi_rtt_unprot_map() - Map unprotected granules into a realm
+ * @rd: PA of the RD
+ * @base: Base IPA of the mapping
+ * @top: Top of the target IPA range
+ * @flags: Flags
+ * @oaddr: Output address set descriptor
+ * @out_top: Top IPA of range which has been mapped
+ *
+ * Create mappings to memory within a target unprotected IPA range.
+ *
+ * Return: 0 on success, positive RMI result code or negative Linux error code
+ */
+static inline long rmi_rtt_unprot_map(unsigned long rd,
+ unsigned long base,
+ unsigned long top,
+ unsigned long flags,
+ unsigned long oaddr,
+ unsigned long *out_top)
+{
+ struct arm_smccc_1_2_regs regs = {
+ SMC_RMI_RTT_UNPROT_MAP, rd, base, top, flags, oaddr
+ };
+ long ret = rmi_sro_execute(&regs);
+
+ if (ret == RMI_SUCCESS && out_top)
+ *out_top = regs.a1;
+
+ return ret;
+}
+
+/**
+ * rmi_rtt_set_ripas() - Set RIPAS for an running realm
+ * @rd: PA of the RD
+ * @rec: PA of the REC making the request
+ * @base: Base of target IPA region
+ * @top: Top of target IPA region
+ * @out_top: Pointer to write top IPA of range whose RIPAS was modified
+ *
+ * Completes a request made by the realm to change the RIPAS of a target IPA
+ * range.
+ *
+ * Return: 0 on success, positive RMI result code or negative Linux error code
+ */
+static inline long rmi_rtt_set_ripas(unsigned long rd, unsigned long rec,
+ unsigned long base, unsigned long top,
+ unsigned long *out_top)
+{
+ struct arm_smccc_1_2_regs regs = {
+ SMC_RMI_RTT_SET_RIPAS, rd, rec, base, top
+ };
+ long ret = rmi_sro_execute(&regs);
+
+ if (ret == RMI_SUCCESS && out_top)
+ *out_top = regs.a1;
+
+ return ret;
+}
+
+/**
+ * rmi_rtt_unprot_unmap() - Remove mappings within an unprotected IPA range
+ * @rd: PA of the RD
+ * @base: Base IPA of the mapping
+ * @top: Top of the target IPA range
+ * @flags: Flags
+ * @oaddr: Output address set descriptor
+ * @out_top: Top IPA which has been unmapped
+ * @out_range: Output address range
+ * @out_count: Number of entries in output address list
+ *
+ * Removes mappings to memory within a target unprotected IPA range.
+ *
+ * Return: 0 on success, positive RMI result code or negative Linux error code
+ * NOTE: out_top is only valid with ret == RMI_SUCCESS.
+ */
+static inline long rmi_rtt_unprot_unmap(unsigned long rd,
+ unsigned long base,
+ unsigned long top,
+ unsigned long flags,
+ unsigned long oaddr,
+ unsigned long *out_top,
+ unsigned long *out_range,
+ unsigned long *out_count)
+{
+ struct arm_smccc_1_2_regs regs = {
+ SMC_RMI_RTT_UNPROT_UNMAP, rd, base, top, flags, oaddr
+ };
+ long ret = rmi_sro_execute(&regs);
+
+ if (ret != RMI_SUCCESS)
+ return ret;
+
+ if (out_top)
+ *out_top = regs.a1;
+ if (out_range)
+ *out_range = regs.a2;
+ if (out_count)
+ *out_count = regs.a3;
+
+ return RMI_SUCCESS;
+}
+
+#endif /* __LINUX_ARM_RMI_CMDS_H_ */
diff --git a/include/linux/arm-rsi-cmds.h b/include/linux/arm-rsi-cmds.h
new file mode 100644
index 000000000000..3f7a6a833993
--- /dev/null
+++ b/include/linux/arm-rsi-cmds.h
@@ -0,0 +1,239 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (C) 2023 ARM Ltd.
+ */
+
+#ifndef __LINUX_ARM_RSI_CMDS_H_
+#define __LINUX_ARM_RSI_CMDS_H_
+
+#include <linux/arm-smccc-rsi.h>
+#include <linux/jump_label.h>
+#include <linux/string.h>
+#include <asm/memory.h>
+
+#ifdef CONFIG_ARM_RMM_RSI
+DECLARE_STATIC_KEY_FALSE(rsi_present);
+
+void __init arm64_rsi_init(void);
+
+bool arm64_rsi_is_protected(phys_addr_t base, size_t size);
+
+static inline bool is_realm_world(void)
+{
+ return static_branch_unlikely(&rsi_present);
+}
+#else
+static inline void arm64_rsi_init(void) { }
+
+static inline bool arm64_rsi_is_protected(phys_addr_t base, size_t size)
+{
+ return false;
+}
+
+static inline bool is_realm_world(void) { return false; }
+#endif
+
+#define RSI_GRANULE_SHIFT 12
+#define RSI_GRANULE_SIZE (_AC(1, UL) << RSI_GRANULE_SHIFT)
+
+enum ripas {
+ RSI_RIPAS_EMPTY = 0,
+ RSI_RIPAS_RAM = 1,
+ RSI_RIPAS_DESTROYED = 2,
+ RSI_RIPAS_DEV = 3,
+};
+
+static inline unsigned long rsi_request_version(unsigned long req,
+ unsigned long *out_lower,
+ unsigned long *out_higher)
+{
+ struct arm_smccc_res res;
+
+ arm_smccc_smc(SMC_RSI_ABI_VERSION, req, 0, 0, 0, 0, 0, 0, &res);
+
+ if (out_lower)
+ *out_lower = res.a1;
+ if (out_higher)
+ *out_higher = res.a2;
+
+ return res.a0;
+}
+
+static inline unsigned long rsi_get_realm_config(struct realm_config *cfg)
+{
+ struct arm_smccc_res res;
+
+ arm_smccc_smc(SMC_RSI_REALM_CONFIG, virt_to_phys(cfg),
+ 0, 0, 0, 0, 0, 0, &res);
+ return res.a0;
+}
+
+static inline unsigned long rsi_ipa_state_get(phys_addr_t start,
+ phys_addr_t end,
+ enum ripas *state,
+ phys_addr_t *top)
+{
+ struct arm_smccc_res res;
+
+ arm_smccc_smc(SMC_RSI_IPA_STATE_GET,
+ start, end, 0, 0, 0, 0, 0,
+ &res);
+
+ if (res.a0 == RSI_SUCCESS) {
+ if (top)
+ *top = res.a1;
+ if (state)
+ *state = res.a2;
+ }
+
+ return res.a0;
+}
+
+static inline long rsi_set_addr_range_state(phys_addr_t start,
+ phys_addr_t end,
+ enum ripas state,
+ unsigned long flags,
+ phys_addr_t *top)
+{
+ struct arm_smccc_res res;
+
+ arm_smccc_smc(SMC_RSI_IPA_STATE_SET, start, end, state,
+ flags, 0, 0, 0, &res);
+
+ if (top)
+ *top = res.a1;
+
+ if (res.a2 != RSI_ACCEPT)
+ return -EPERM;
+
+ return res.a0;
+}
+
+static inline int rsi_set_memory_range(phys_addr_t start, phys_addr_t end,
+ enum ripas state, unsigned long flags)
+{
+ unsigned long ret;
+ phys_addr_t top;
+
+ while (start != end) {
+ ret = rsi_set_addr_range_state(start, end, state, flags, &top);
+ if (ret || top < start || top > end)
+ return -EINVAL;
+ start = top;
+ }
+
+ return 0;
+}
+
+/*
+ * Convert the specified range to RAM. Do not use this if you rely on the
+ * contents of a page that may already be in RAM state.
+ */
+static inline int rsi_set_memory_range_protected(phys_addr_t start,
+ phys_addr_t end)
+{
+ return rsi_set_memory_range(start, end, RSI_RIPAS_RAM,
+ RSI_CHANGE_DESTROYED);
+}
+
+/*
+ * Convert the specified range to RAM. Do not convert any pages that may have
+ * been DESTROYED, without our permission.
+ */
+static inline int rsi_set_memory_range_protected_safe(phys_addr_t start,
+ phys_addr_t end)
+{
+ return rsi_set_memory_range(start, end, RSI_RIPAS_RAM,
+ RSI_NO_CHANGE_DESTROYED);
+}
+
+static inline int rsi_set_memory_range_shared(phys_addr_t start,
+ phys_addr_t end)
+{
+ return rsi_set_memory_range(start, end, RSI_RIPAS_EMPTY,
+ RSI_CHANGE_DESTROYED);
+}
+
+#define RSI_ATTEST_CHALLENGE_MIN_SIZE 32
+#define RSI_ATTEST_CHALLENGE_MAX_SIZE 64
+
+struct rsi_attestation_token_init_args {
+ unsigned long fid;
+ u8 challenge[RSI_ATTEST_CHALLENGE_MAX_SIZE];
+};
+
+/**
+ * rsi_attestation_token_init - Initialise the operation to retrieve an
+ * attestation token.
+ *
+ * @challenge: The challenge data to be used in the attestation token
+ * generation.
+ * @size: Size of the challenge data in bytes.
+ *
+ * Initialises the attestation token generation and returns an upper bound
+ * on the attestation token size that can be used to allocate an adequate
+ * buffer. The caller is expected to subsequently call
+ * rsi_attestation_token_continue() to retrieve the attestation token data on
+ * the same CPU.
+ *
+ * Returns:
+ * On success, returns the upper limit of the attestation report size.
+ * Otherwise, -EINVAL
+ */
+static inline long
+rsi_attestation_token_init(const u8 *challenge, unsigned long size)
+{
+ union {
+ struct arm_smccc_1_2_regs regs;
+ struct rsi_attestation_token_init_args init;
+ } args = { 0 };
+
+ if (!challenge || size < RSI_ATTEST_CHALLENGE_MIN_SIZE ||
+ size > RSI_ATTEST_CHALLENGE_MAX_SIZE)
+ return -EINVAL;
+
+ args.init.fid = SMC_RSI_ATTESTATION_TOKEN_INIT;
+ memcpy(args.init.challenge, challenge, size);
+ arm_smccc_1_2_smc(&args.regs, &args.regs);
+
+ if (args.regs.a0 == RSI_SUCCESS)
+ return args.regs.a1;
+
+ return -EINVAL;
+}
+
+/**
+ * rsi_attestation_token_continue - Continue the operation to retrieve an
+ * attestation token.
+ *
+ * @granule: {I}PA of the Granule to which the token will be written.
+ * @offset: Offset within Granule to start of buffer in bytes.
+ * @size: The size of the buffer.
+ * @len: The number of bytes written to the buffer.
+ *
+ * Retrieves up to a RSI_GRANULE_SIZE worth of token data per call. The caller
+ * is expected to call rsi_attestation_token_init() before calling this
+ * function to retrieve the attestation token.
+ *
+ * Return:
+ * * %RSI_SUCCESS - Attestation token retrieved successfully.
+ * * %RSI_INCOMPLETE - Token generation is not complete.
+ * * %RSI_ERROR_INPUT - A parameter was not valid.
+ * * %RSI_ERROR_STATE - Attestation not in progress.
+ */
+static inline unsigned long rsi_attestation_token_continue(phys_addr_t granule,
+ unsigned long offset,
+ unsigned long size,
+ unsigned long *len)
+{
+ struct arm_smccc_res res;
+
+ arm_smccc_1_1_invoke(SMC_RSI_ATTESTATION_TOKEN_CONTINUE,
+ granule, offset, size, 0, &res);
+
+ if (len)
+ *len = res.a1;
+ return res.a0;
+}
+
+#endif /* __LINUX_ARM_RSI_CMDS_H_ */
diff --git a/include/linux/arm-smccc-bus.h b/include/linux/arm-smccc-bus.h
new file mode 100644
index 000000000000..05c0c850510e
--- /dev/null
+++ b/include/linux/arm-smccc-bus.h
@@ -0,0 +1,48 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (C) 2026 Arm Limited
+ */
+#ifndef __LINUX_ARM_SMCCC_BUS_H
+#define __LINUX_ARM_SMCCC_BUS_H
+
+#include <linux/device.h>
+#include <linux/device-id/arm_smccc.h>
+#include <linux/module.h>
+
+struct arm_smccc_device {
+ struct device dev;
+ u32 func_id;
+};
+
+#define to_arm_smccc_device(d) container_of_const(d, struct arm_smccc_device, dev)
+
+struct arm_smccc_driver {
+ struct device_driver driver;
+
+ const char *name;
+ int (*probe)(struct arm_smccc_device *sdev);
+ void (*remove)(struct arm_smccc_device *sdev);
+ const struct arm_smccc_device_id *id_table;
+};
+
+#define to_arm_smccc_driver(d) \
+ container_of_const(d, struct arm_smccc_driver, driver)
+
+int arm_smccc_driver_register(struct arm_smccc_driver *driver,
+ struct module *owner, const char *mod_name);
+void arm_smccc_driver_unregister(struct arm_smccc_driver *driver);
+struct arm_smccc_device *arm_smccc_device_register(const char *name, u32 func_id);
+void arm_smccc_device_unregister(struct arm_smccc_device *smcc_dev);
+
+#define arm_smccc_register(driver) \
+ arm_smccc_driver_register(driver, THIS_MODULE, KBUILD_MODNAME)
+#define arm_smccc_unregister(driver) \
+ arm_smccc_driver_unregister(driver)
+
+#define module_arm_smccc_driver(__arm_smccc_driver) \
+ module_driver(__arm_smccc_driver, arm_smccc_register, \
+ arm_smccc_unregister)
+
+extern const struct bus_type arm_smccc_bus_type;
+
+#endif /* __LINUX_ARM_SMCCC_BUS_H */
diff --git a/include/linux/arm-smccc-rmi.h b/include/linux/arm-smccc-rmi.h
new file mode 100644
index 000000000000..655726b37462
--- /dev/null
+++ b/include/linux/arm-smccc-rmi.h
@@ -0,0 +1,516 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (C) 2023-2026 ARM Ltd.
+ *
+ * The values and structures in this file are from the Realm Management Monitor
+ * specification (DEN0137) version 2.0-bet3:
+ * https://developer.arm.com/documentation/den0137/2-0bet3/
+ */
+
+#ifndef __LINUX_ARM_SMCCC_RMI_H_
+#define __LINUX_ARM_SMCCC_RMI_H_
+
+#include <linux/arm-smccc.h>
+#include <linux/bitfield.h>
+#include <linux/bits.h>
+#include <linux/build_bug.h>
+#include <linux/sizes.h>
+#include <linux/stddef.h>
+
+#include <asm/page.h>
+
+#define SMC_RMI_CALL(func) \
+ ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, \
+ ARM_SMCCC_SMC_64, \
+ ARM_SMCCC_OWNER_STANDARD, \
+ (func))
+
+#define SMC_RMI_VERSION SMC_RMI_CALL(0x0150)
+
+#define SMC_RMI_RTT_DATA_MAP_INIT SMC_RMI_CALL(0x0153)
+
+#define SMC_RMI_REALM_ACTIVATE SMC_RMI_CALL(0x0157)
+#define SMC_RMI_REALM_CREATE SMC_RMI_CALL(0x0158)
+#define SMC_RMI_REALM_DESTROY SMC_RMI_CALL(0x0159)
+#define SMC_RMI_REC_CREATE SMC_RMI_CALL(0x015a)
+#define SMC_RMI_REC_DESTROY SMC_RMI_CALL(0x015b)
+#define SMC_RMI_REC_ENTER SMC_RMI_CALL(0x015c)
+#define SMC_RMI_RTT_CREATE SMC_RMI_CALL(0x015d)
+#define SMC_RMI_RTT_DESTROY SMC_RMI_CALL(0x015e)
+
+#define SMC_RMI_RTT_READ_ENTRY SMC_RMI_CALL(0x0161)
+
+#define SMC_RMI_RTT_DEV_VALIDATE SMC_RMI_CALL(0x0163)
+#define SMC_RMI_PSCI_COMPLETE SMC_RMI_CALL(0x0164)
+#define SMC_RMI_FEATURES SMC_RMI_CALL(0x0165)
+#define SMC_RMI_RTT_FOLD SMC_RMI_CALL(0x0166)
+
+#define SMC_RMI_RTT_INIT_RIPAS SMC_RMI_CALL(0x0168)
+#define SMC_RMI_RTT_SET_RIPAS SMC_RMI_CALL(0x0169)
+#define SMC_RMI_VSMMU_CREATE SMC_RMI_CALL(0x016a)
+#define SMC_RMI_VSMMU_DESTROY SMC_RMI_CALL(0x016b)
+
+#define SMC_RMI_RMM_CONFIG_SET SMC_RMI_CALL(0x016e)
+#define SMC_RMI_PSMMU_IRQ_NOTIFY SMC_RMI_CALL(0x016f)
+#define SMC_RMI_ATTEST_PLAT_TOKEN_REFRESH SMC_RMI_CALL(0x0170)
+
+#define SMC_RMI_PDEV_ABORT SMC_RMI_CALL(0x0174)
+#define SMC_RMI_PDEV_COMMUNICATE SMC_RMI_CALL(0x0175)
+#define SMC_RMI_PDEV_CREATE SMC_RMI_CALL(0x0176)
+#define SMC_RMI_PDEV_DESTROY SMC_RMI_CALL(0x0177)
+#define SMC_RMI_PDEV_GET_STATE SMC_RMI_CALL(0x0178)
+
+#define SMC_RMI_PDEV_STREAM_KEY_REFRESH SMC_RMI_CALL(0x017a)
+#define SMC_RMI_PDEV_SET_PUBKEY SMC_RMI_CALL(0x017b)
+#define SMC_RMI_PDEV_STOP SMC_RMI_CALL(0x017c)
+#define SMC_RMI_RTT_AUX_CREATE SMC_RMI_CALL(0x017d)
+#define SMC_RMI_RTT_AUX_DESTROY SMC_RMI_CALL(0x017e)
+#define SMC_RMI_RTT_AUX_FOLD SMC_RMI_CALL(0x017f)
+
+#define SMC_RMI_VDEV_ABORT SMC_RMI_CALL(0x0185)
+#define SMC_RMI_VDEV_COMMUNICATE SMC_RMI_CALL(0x0186)
+#define SMC_RMI_VDEV_CREATE SMC_RMI_CALL(0x0187)
+#define SMC_RMI_VDEV_DESTROY SMC_RMI_CALL(0x0188)
+#define SMC_RMI_VDEV_GET_STATE SMC_RMI_CALL(0x0189)
+#define SMC_RMI_VDEV_UNLOCK SMC_RMI_CALL(0x018a)
+#define SMC_RMI_RTT_SET_S2AP SMC_RMI_CALL(0x018b)
+
+#define SMC_RMI_VDEV_GET_INTERFACE_REPORT SMC_RMI_CALL(0x01d0)
+#define SMC_RMI_VDEV_GET_MEASUREMENTS SMC_RMI_CALL(0x01d1)
+#define SMC_RMI_VDEV_LOCK SMC_RMI_CALL(0x01d2)
+#define SMC_RMI_VDEV_START SMC_RMI_CALL(0x01d3)
+
+#define SMC_RMI_VSMMU_EVENT_HANDLE SMC_RMI_CALL(0x01d6)
+#define SMC_RMI_PSMMU_ACTIVATE SMC_RMI_CALL(0x01d7)
+#define SMC_RMI_PSMMU_DEACTIVATE SMC_RMI_CALL(0x01d8)
+
+#define SMC_RMI_PSMMU_ST_L2_CREATE SMC_RMI_CALL(0x01db)
+#define SMC_RMI_PSMMU_ST_L2_DESTROY SMC_RMI_CALL(0x01dc)
+#define SMC_RMI_DPT_L0_CREATE SMC_RMI_CALL(0x01dd)
+#define SMC_RMI_DPT_L0_DESTROY SMC_RMI_CALL(0x01de)
+#define SMC_RMI_DPT_L1_CREATE SMC_RMI_CALL(0x01df)
+#define SMC_RMI_DPT_L1_DESTROY SMC_RMI_CALL(0x01e0)
+#define SMC_RMI_GRANULE_TRACKING_GET SMC_RMI_CALL(0x01e1)
+
+#define SMC_RMI_GRANULE_TRACKING_SET SMC_RMI_CALL(0x01e3)
+
+#define SMC_RMI_RMM_CONFIG_GET SMC_RMI_CALL(0x01ec)
+
+#define SMC_RMI_RMM_STATE_GET SMC_RMI_CALL(0x01ee)
+
+#define SMC_RMI_PSMMU_EVENT_CONSUME SMC_RMI_CALL(0x01f0)
+#define SMC_RMI_GRANULE_RANGE_DELEGATE SMC_RMI_CALL(0x01f1)
+#define SMC_RMI_GRANULE_RANGE_UNDELEGATE SMC_RMI_CALL(0x01f2)
+#define SMC_RMI_GPT_L1_CREATE SMC_RMI_CALL(0x01f3)
+#define SMC_RMI_GPT_L1_DESTROY SMC_RMI_CALL(0x01f4)
+#define SMC_RMI_RTT_DATA_MAP SMC_RMI_CALL(0x01f5)
+#define SMC_RMI_RTT_DATA_UNMAP SMC_RMI_CALL(0x01f6)
+#define SMC_RMI_RTT_DEV_MAP SMC_RMI_CALL(0x01f7)
+#define SMC_RMI_RTT_DEV_UNMAP SMC_RMI_CALL(0x01f8)
+#define SMC_RMI_RTT_ARCH_DEV_MAP SMC_RMI_CALL(0x01f9)
+#define SMC_RMI_RTT_ARCH_DEV_UNMAP SMC_RMI_CALL(0x01fa)
+#define SMC_RMI_RTT_UNPROT_MAP SMC_RMI_CALL(0x01fb)
+#define SMC_RMI_RTT_UNPROT_UNMAP SMC_RMI_CALL(0x01fc)
+#define SMC_RMI_RTT_AUX_PROT_MAP SMC_RMI_CALL(0x01fd)
+#define SMC_RMI_RTT_AUX_PROT_UNMAP SMC_RMI_CALL(0x01fe)
+#define SMC_RMI_RTT_AUX_UNPROT_MAP SMC_RMI_CALL(0x01ff)
+#define SMC_RMI_RTT_AUX_UNPROT_UNMAP SMC_RMI_CALL(0x0200)
+#define SMC_RMI_REALM_TERMINATE SMC_RMI_CALL(0x0201)
+#define SMC_RMI_RMM_ACTIVATE SMC_RMI_CALL(0x0202)
+#define SMC_RMI_OP_CONTINUE SMC_RMI_CALL(0x0203)
+#define SMC_RMI_PDEV_STREAM_CONNECT SMC_RMI_CALL(0x0204)
+#define SMC_RMI_PDEV_STREAM_DISCONNECT SMC_RMI_CALL(0x0205)
+#define SMC_RMI_PDEV_STREAM_COMPLETE SMC_RMI_CALL(0x0206)
+#define SMC_RMI_PDEV_STREAM_KEY_PURGE SMC_RMI_CALL(0x0207)
+#define SMC_RMI_OP_MEM_DONATE SMC_RMI_CALL(0x0208)
+#define SMC_RMI_OP_MEM_RECLAIM SMC_RMI_CALL(0x0209)
+#define SMC_RMI_OP_CANCEL SMC_RMI_CALL(0x020a)
+#define SMC_RMI_VSMMU_FEATURES SMC_RMI_CALL(0x020b)
+#define SMC_RMI_VSMMU_CMD_GET SMC_RMI_CALL(0x020c)
+#define SMC_RMI_VSMMU_CMD_COMPLETE SMC_RMI_CALL(0x020d)
+#define SMC_RMI_PSMMU_INFO SMC_RMI_CALL(0x020e)
+#define SMC_RMI_RMM_DEACTIVATE SMC_RMI_CALL(0x020f)
+#define SMC_RMI_PDEV_STREAM_INFO SMC_RMI_CALL(0x0210)
+#define SMC_RMI_GPT_INFO SMC_RMI_CALL(0x0211)
+
+#define RMI_ABI_MAJOR_VERSION 2
+#define RMI_ABI_MINOR_VERSION 0
+
+#define RMI_ABI_VERSION_MAJOR_MASK GENMASK(30, 16)
+#define RMI_ABI_VERSION_MINOR_MASK GENMASK(15, 0)
+
+#define RMI_ABI_VERSION_GET_MAJOR(v) FIELD_GET(RMI_ABI_VERSION_MAJOR_MASK, (v))
+#define RMI_ABI_VERSION_GET_MINOR(v) FIELD_GET(RMI_ABI_VERSION_MINOR_MASK, (v))
+#define RMI_ABI_VERSION(major, minor) \
+ (FIELD_PREP(RMI_ABI_VERSION_MAJOR_MASK, (major)) | \
+ FIELD_PREP(RMI_ABI_VERSION_MINOR_MASK, (minor)))
+
+/* RmiResult Type definitions */
+#define RMI_RESULT_STATUS_MASK GENMASK(7, 0)
+/* RmiResultDataLevel field */
+#define RMI_RESULT_DATA_LEVEL_MASK GENMASK(15, 8)
+/* RmiResultDataIncomplete fields */
+#define RMI_RESULT_MEMREQ_MASK GENMASK(9, 8)
+#define RMI_RESULT_CAN_CANCEL_MASK BIT(10)
+
+#define RMI_RESULT_STATUS(ret) FIELD_GET(RMI_RESULT_STATUS_MASK, ret)
+#define RMI_RESULT_DATA_LEVEL(ret) FIELD_GET(RMI_RESULT_DATA_LEVEL_MASK, ret)
+#define RMI_RESULT_MEMREQ(ret) FIELD_GET(RMI_RESULT_MEMREQ_MASK, ret)
+#define RMI_RESULT_CAN_CANCEL(ret) FIELD_GET(RMI_RESULT_CAN_CANCEL_MASK, ret)
+
+#define RMI_SUCCESS 0
+#define RMI_ERROR_INPUT 1
+#define RMI_ERROR_REALM 2
+#define RMI_ERROR_REC 3
+#define RMI_ERROR_RTT 4
+#define RMI_ERROR_NOT_SUPPORTED 5
+#define RMI_ERROR_DEVICE 6
+#define RMI_ERROR_RTT_AUX 7
+#define RMI_ERROR_PSMMU_ST 8
+#define RMI_ERROR_DPT 9
+#define RMI_BUSY 10
+#define RMI_ERROR_GLOBAL 11
+#define RMI_ERROR_TRACKING 12
+#define RMI_INCOMPLETE 13
+#define RMI_BLOCKED 14
+#define RMI_ERROR_GPT 15
+#define RMI_ERROR_GRANULE 16
+
+#define RMI_CONTINUE_KEEP_GOING 0
+#define RMI_CONTINUE_STOP 1
+
+#define RMI_OP_MEM_REQ_NONE 0
+#define RMI_OP_MEM_REQ_DONATE 1
+#define RMI_OP_MEM_REQ_RECLAIM 2
+
+#define RMI_OP_CANNOT_CANCEL 0
+#define RMI_OP_CAN_CANCEL 1
+
+#define RMI_DONATE_STATE_MASK GENMASK(18, 17)
+#define RMI_DONATE_CONTIG_MASK BIT(16)
+#define RMI_DONATE_COUNT_MASK GENMASK(15, 2)
+#define RMI_DONATE_BLOCK_SIZE_MASK GENMASK(1, 0)
+
+#define RMI_DONATE_STATE(req) FIELD_GET(RMI_DONATE_STATE_MASK, req)
+#define RMI_DONATE_CONTIG(req) FIELD_GET(RMI_DONATE_CONTIG_MASK, req)
+#define RMI_DONATE_COUNT(req) FIELD_GET(RMI_DONATE_COUNT_MASK, req)
+#define RMI_DONATE_BLOCK_SIZE(req) FIELD_GET(RMI_DONATE_BLOCK_SIZE_MASK, req)
+
+#define RMI_OP_MEM_DELEGATED 0
+#define RMI_OP_MEM_UNDELEGATED 1
+#define RMI_OP_MEM_CONDITIONAL 2
+
+#define RMI_OP_MEM_NON_CONTIG 0
+#define RMI_OP_MEM_CONTIG 1
+
+#define RMI_ADDR_TYPE_NONE 0
+#define RMI_ADDR_TYPE_SINGLE 1
+#define RMI_ADDR_TYPE_LIST 2
+
+#define RMI_ADDR_RANGE_STATE_MASK GENMASK_ULL(63, 62)
+#define RMI_ADDR_RANGE_ADDR_MASK GENMASK_ULL(51, PAGE_SHIFT)
+#define RMI_ADDR_RANGE_COUNT_MASK GENMASK(PAGE_SHIFT - 1, 2)
+#define RMI_ADDR_RANGE_BLOCK_SIZE_MASK GENMASK(1, 0)
+
+#define RMI_ADDR_RANGE_STATE(r) FIELD_GET(RMI_ADDR_RANGE_STATE_MASK, (r))
+#define RMI_ADDR_RANGE_ADDR(r) ((r) & RMI_ADDR_RANGE_ADDR_MASK)
+#define RMI_ADDR_RANGE_COUNT(r) FIELD_GET(RMI_ADDR_RANGE_COUNT_MASK, (r))
+#define RMI_ADDR_RANGE_BLOCK_SIZE(r) FIELD_GET(RMI_ADDR_RANGE_BLOCK_SIZE_MASK, (r))
+
+enum rmi_ripas {
+ RMI_EMPTY = 0,
+ RMI_RAM = 1,
+ RMI_DESTROYED = 2,
+ RMI_DEV = 3,
+};
+
+#define RMI_NO_MEASURE_CONTENT 0
+#define RMI_MEASURE_CONTENT 1
+
+#define RMI_FEATURE_REGISTER_0_S2OASZ GENMASK_ULL(40, 33)
+#define RMI_FEATURE_REGISTER_0_L0GPT_BLOCK_DELEGATE BIT_ULL(32)
+#define RMI_FEATURE_REGISTER_0_PMU_NUM_CTRS GENMASK(31, 27)
+#define RMI_FEATURE_REGISTER_0_PMU BIT(26)
+#define RMI_FEATURE_REGISTER_0_NUM_WPS GENMASK(25, 20)
+#define RMI_FEATURE_REGISTER_0_NUM_BPS GENMASK(19, 14)
+#define RMI_FEATURE_REGISTER_0_SVE_VL GENMASK(13, 10)
+#define RMI_FEATURE_REGISTER_0_SVE BIT(9)
+#define RMI_FEATURE_REGISTER_0_LPA2 BIT(8)
+#define RMI_FEATURE_REGISTER_0_S2SZ GENMASK(7, 0)
+
+#define RMI_FEATURE_REGISTER_1_PPS GENMASK(16, 14)
+#define RMI_FEATURE_REGISTER_1_L0GPTSZ GENMASK(13, 10)
+#define RMI_FEATURE_REGISTER_1_MAX_RECS_ORDER GENMASK(9, 6)
+#define RMI_FEATURE_REGISTER_1_HASH_SHA_512 BIT(5)
+#define RMI_FEATURE_REGISTER_1_HASH_SHA_384 BIT(4)
+#define RMI_FEATURE_REGISTER_1_HASH_SHA_256 BIT(3)
+#define RMI_FEATURE_REGISTER_1_RMI_GRAN_SZ_64KB BIT(2)
+#define RMI_FEATURE_REGISTER_1_RMI_GRAN_SZ_16KB BIT(1)
+#define RMI_FEATURE_REGISTER_1_RMI_GRAN_SZ_4KB BIT(0)
+
+#define RMI_FEATURE_REGISTER_2_REALM_MAX_VDEVS_ORDER GENMASK(14, 10)
+#define RMI_FEATURE_REGISTER_2_NON_TEE_STREAM BIT(9)
+#define RMI_FEATURE_REGISTER_2_VDEV_KROU BIT(8)
+#define RMI_FEATURE_REGISTER_2_PDEV_MAX_VDEVS_ORDER GENMASK(7, 4)
+#define RMI_FEATURE_REGISTER_2_ATS BIT(3)
+#define RMI_FEATURE_REGISTER_2_VSMMU BIT(2)
+#define RMI_FEATURE_REGISTER_2_DA_COH BIT(1)
+#define RMI_FEATURE_REGISTER_2_DA BIT(0)
+
+#define RMI_FEATURE_REGISTER_3_RTT_S2AP_INDIRECT BIT(6)
+#define RMI_FEATURE_REGISTER_3_RTT_PLANE GENMASK(5, 4)
+#define RMI_FEATURE_REGISTER_3_MAX_NUM_AUX_PLANES GENMASK(3, 0)
+
+#define RMI_FEATURE_REGISTER_4_MEC_COUNT GENMASK_ULL(63, 0)
+
+#define RMI_MEM_CATEGORY_CONVENTIONAL 0
+#define RMI_MEM_CATEGORY_DEV_NCOH 1
+#define RMI_MEM_CATEGORY_DEV_COH 2
+#define RMI_MEM_CATEGORY_NONE 3
+
+#define RMI_TRACKING_RESERVED 0
+#define RMI_TRACKING_NONE 1
+#define RMI_TRACKING_FINE 2
+#define RMI_TRACKING_COARSE 3
+#define RMI_TRACKING_INTERMEDIATE 4
+
+#define RMI_GRANULE_SIZE_4KB 0
+#define RMI_GRANULE_SIZE_16KB 1
+#define RMI_GRANULE_SIZE_64KB 2
+
+#define RMI_GPT_PAR_RESERVED 0U
+#define RMI_GPT_PAR_PLAT 1U
+#define RMI_GPT_PAR_HOST_NOT_CREATED 2U
+#define RMI_GPT_PAR_HOST_CREATED 3U
+
+/*
+ * Note many of these fields are smaller than u64 but all fields have u64
+ * alignment, so use u64 to ensure correct alignment.
+ */
+struct rmm_config {
+ union { /* 0x0 */
+ struct {
+ u64 tracking_region_size;
+ u64 rmi_granule_size;
+ };
+ u8 sizer[SZ_4K];
+ };
+};
+
+static_assert(sizeof(struct rmm_config) == SZ_4K);
+
+#define RMI_REALM_PARAM_FLAG_MEC_POLICY_MASK GENMASK(8, 7)
+#define RMI_REALM_PARAM_FLAG_LFA_POLICY_MASK GENMASK(6, 5)
+#define RMI_REALM_PARAM_FLAG_DA BIT(3)
+#define RMI_REALM_PARAM_FLAG_PMU BIT(2)
+#define RMI_REALM_PARAM_FLAG_SVE BIT(1)
+
+#define RMI_HASH_SHA_256 0
+#define RMI_HASH_SHA_512 1
+#define RMI_HASH_SHA_384 2
+
+struct realm_params {
+ union { /* 0x0 */
+ struct {
+ u64 flags0;
+ u64 s2sz;
+ u64 sve_vl;
+ u64 num_bps;
+ u64 num_wps;
+ u64 pmu_num_ctrs;
+ u64 hash_algo;
+ u64 num_aux_planes;
+ };
+ u8 sizer0[0x400];
+ };
+ union { /* 0x400 */
+ struct {
+ u8 rpv[64];
+ u64 ats_plane;
+ };
+ u8 sizer1[0x400];
+ };
+ union { /* 0x800 */
+ struct {
+ u64 sizer2;
+ u64 rtt_base;
+ s64 rtt_level_start;
+ u64 rtt_num_start;
+ u64 flags1;
+ u64 max_num_vdevs;
+ };
+ u8 sizer3[0x700];
+ };
+ union { /* 0xf00 */
+ struct {
+ u8 sizer4[0x80];
+ u64 aux_rtt_base[3];
+ };
+ u8 sizer5[0x100];
+ };
+};
+
+static_assert(offsetof(struct realm_params, rpv) == 0x400);
+static_assert(offsetof(struct realm_params, rtt_base) == 0x808);
+static_assert(offsetof(struct realm_params, aux_rtt_base) == 0xf80);
+static_assert(sizeof(struct realm_params) == SZ_4K);
+
+/*
+ * The number of GPRs (starting from X0) that are configured by the host when
+ * a REC is created.
+ */
+#define REC_CREATE_NR_GPRS 8
+
+#define REC_PARAMS_FLAG_RUNNABLE BIT(0)
+
+struct rec_params {
+ union { /* 0x0 */
+ u64 flags;
+ u8 sizer0[0x100];
+ };
+ union { /* 0x100 */
+ u64 mpidr;
+ u8 sizer1[0x100];
+ };
+ union { /* 0x200 */
+ u64 pc;
+ u8 sizer2[0x100];
+ };
+ union { /* 0x300 */
+ u64 gprs[REC_CREATE_NR_GPRS];
+ u8 sizer3[0xd00];
+ };
+};
+
+static_assert(offsetof(struct rec_params, mpidr) == 0x100);
+static_assert(offsetof(struct rec_params, pc) == 0x200);
+static_assert(offsetof(struct rec_params, gprs) == 0x300);
+static_assert(sizeof(struct rec_params) == SZ_4K);
+
+#define REC_ENTER_FLAG_FORCE_P0 BIT(7)
+#define REC_ENTER_FLAG_DEV_MEM_RESPONSE BIT(6)
+#define REC_ENTER_FLAG_S2AP_RESPONSE BIT(5)
+#define REC_ENTER_FLAG_RIPAS_RESPONSE BIT(4)
+#define REC_ENTER_FLAG_TRAP_WFE BIT(3)
+#define REC_ENTER_FLAG_TRAP_WFI BIT(2)
+#define REC_ENTER_FLAG_INJECT_SEA BIT(1)
+#define REC_ENTER_FLAG_EMULATED_MMIO BIT(0)
+
+#define REC_RUN_GPRS 31
+
+struct rec_enter {
+ union { /* 0x000 */
+ u64 flags;
+ u8 sizer0[0x200];
+ };
+ union { /* 0x200 */
+ u64 gprs[REC_RUN_GPRS];
+ u8 sizer1[0x600];
+ };
+};
+
+static_assert(offsetof(struct rec_enter, gprs) == 0x200);
+static_assert(sizeof(struct rec_enter) == SZ_2K);
+
+#define RMI_EXIT_SYNC 0x00
+#define RMI_EXIT_IRQ 0x01
+#define RMI_EXIT_FIQ 0x02
+#define RMI_EXIT_PSCI 0x03
+#define RMI_EXIT_RIPAS_CHANGE 0x04
+#define RMI_EXIT_HOST_CALL 0x05
+#define RMI_EXIT_SERROR 0x06
+#define RMI_EXIT_S2AP_CHANGE 0x07
+#define RMI_EXIT_VDEV_VALIDATE_MAPPING 0x08
+#define RMI_EXIT_VSMMU_COMMAND 0x0a
+
+struct rec_exit {
+ union { /* 0x000 */
+ u8 exit_reason;
+ u8 sizer0[0x100];
+ };
+ union { /* 0x100 */
+ struct {
+ u64 esr;
+ u64 far;
+ u64 hpfar;
+ u64 rtt_tree;
+ };
+ u8 sizer1[0x100];
+ };
+ union { /* 0x200 */
+ u64 gprs[REC_RUN_GPRS];
+ u8 sizer2[0x200];
+ };
+ union { /* 0x400 */
+ struct {
+ u64 cntp_ctl;
+ u64 cntp_cval;
+ u64 cntv_ctl;
+ u64 cntv_cval;
+ };
+ u8 sizer4[0x100];
+ };
+ union { /* 0x500 */
+ struct {
+ u64 ripas_base;
+ u64 ripas_top;
+ u8 ripas_value;
+ u8 sizer5[0xf];
+ u64 s2ap_base;
+ u64 s2ap_top;
+ u64 vdev_id_1;
+ u64 vdev_id_2;
+ u64 dev_mem_base;
+ u64 dev_mem_top;
+ u64 dev_mem_pa;
+ };
+ u8 sizer6[0x100];
+ };
+ union { /* 0x600 */
+ struct {
+ u16 imm;
+ u8 sizer7[0x6];
+ u64 plane;
+ };
+ u8 sizer8[0x100];
+ };
+ union { /* 0x700 */
+ struct {
+ u8 pmu_ovf_status;
+ u8 sizer9[0xf];
+ u64 vsmmu;
+ };
+ u8 sizer10[0x100];
+ };
+};
+
+static_assert(sizeof(struct rec_exit) == SZ_2K);
+static_assert(offsetof(struct rec_exit, esr) == 0x100);
+static_assert(offsetof(struct rec_exit, gprs) == 0x200);
+static_assert(offsetof(struct rec_exit, cntp_ctl) == 0x400);
+static_assert(offsetof(struct rec_exit, ripas_base) == 0x500);
+static_assert(offsetof(struct rec_exit, imm) == 0x600);
+static_assert(offsetof(struct rec_exit, pmu_ovf_status) == 0x700);
+
+struct rec_run {
+ struct rec_enter enter;
+ struct rec_exit exit;
+};
+
+static_assert(sizeof(struct rec_run) == SZ_4K);
+
+/* RMI_RTT_UNPROT_MAP_FLAGS definitions */
+#define RMI_RTT_UNPROT_MAP_FLAGS_S2AP_MASK GENMASK(22, 19)
+#define RMI_RTT_UNPROT_MAP_FLAGS_MEMATTR_MASK GENMASK(18, 16)
+#define RMI_RTT_UNPROT_MAP_FLAGS_LIST_COUNT_MASK GENMASK(15, 2)
+#define RMI_RTT_UNPROT_MAP_FLAGS_OADDR_TYPE_MASK GENMASK(1, 0)
+
+/* RMI_RTT_PROT_MAP_FLAGS definitions */
+#define RMI_RTT_PROT_MAP_FLAGS_LIST_COUNT_MASK GENMASK(15, 2)
+#define RMI_RTT_PROT_MAP_FLAGS_OADDR_TYPE_MASK GENMASK(1, 0)
+
+/* S2AP Direct Encodings, used in RMI_RTT_UNPROT_MAP_FLAGS_S2AP */
+#define RMI_S2AP_DIRECT_READ BIT(1)
+#define RMI_S2AP_DIRECT_WRITE BIT(0)
+
+#endif /* __LINUX_ARM_SMCCC_RMI_H_ */
diff --git a/include/linux/arm-smccc-rsi.h b/include/linux/arm-smccc-rsi.h
new file mode 100644
index 000000000000..cca881ddfdba
--- /dev/null
+++ b/include/linux/arm-smccc-rsi.h
@@ -0,0 +1,193 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (C) 2023 ARM Ltd.
+ */
+
+#ifndef __LINUX_ARM_SMCCC_RSI_H_
+#define __LINUX_ARM_SMCCC_RSI_H_
+
+#include <linux/arm-smccc.h>
+
+/*
+ * This file describes the Realm Services Interface (RSI) Application Binary
+ * Interface (ABI) for SMC calls made from within the Realm to the RMM and
+ * serviced by the RMM.
+ */
+
+/*
+ * The major version number of the RSI implementation. This is increased when
+ * the binary format or semantics of the SMC calls change.
+ */
+#define RSI_ABI_VERSION_MAJOR UL(1)
+
+/*
+ * The minor version number of the RSI implementation. This is increased when
+ * a bug is fixed, or a feature is added without breaking binary compatibility.
+ */
+#define RSI_ABI_VERSION_MINOR UL(0)
+
+#define RSI_ABI_VERSION ((RSI_ABI_VERSION_MAJOR << 16) | \
+ RSI_ABI_VERSION_MINOR)
+
+#define RSI_ABI_VERSION_GET_MAJOR(_version) ((_version) >> 16)
+#define RSI_ABI_VERSION_GET_MINOR(_version) ((_version) & 0xFFFF)
+
+#define RSI_SUCCESS UL(0)
+#define RSI_ERROR_INPUT UL(1)
+#define RSI_ERROR_STATE UL(2)
+#define RSI_INCOMPLETE UL(3)
+#define RSI_ERROR_UNKNOWN UL(4)
+
+#define SMC_RSI_FID(n) ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, \
+ ARM_SMCCC_SMC_64, \
+ ARM_SMCCC_OWNER_STANDARD, \
+ n)
+
+/*
+ * Returns RSI version.
+ *
+ * arg1 == Requested interface revision
+ * ret0 == Status / error
+ * ret1 == Lower implemented interface revision
+ * ret2 == Higher implemented interface revision
+ */
+#define SMC_RSI_ABI_VERSION SMC_RSI_FID(0x190)
+
+/*
+ * Read feature register.
+ *
+ * arg1 == Feature register index
+ * ret0 == Status / error
+ * ret1 == Feature register value
+ */
+#define SMC_RSI_FEATURES SMC_RSI_FID(0x191)
+
+/*
+ * Read measurement for the current Realm.
+ *
+ * arg1 == Index, which measurements slot to read
+ * ret0 == Status / error
+ * ret1 == Measurement value, bytes: 0 - 7
+ * ret2 == Measurement value, bytes: 8 - 15
+ * ret3 == Measurement value, bytes: 16 - 23
+ * ret4 == Measurement value, bytes: 24 - 31
+ * ret5 == Measurement value, bytes: 32 - 39
+ * ret6 == Measurement value, bytes: 40 - 47
+ * ret7 == Measurement value, bytes: 48 - 55
+ * ret8 == Measurement value, bytes: 56 - 63
+ */
+#define SMC_RSI_MEASUREMENT_READ SMC_RSI_FID(0x192)
+
+/*
+ * Extend Realm Extensible Measurement (REM) value.
+ *
+ * arg1 == Index, which measurements slot to extend
+ * arg2 == Size of realm measurement in bytes, max 64 bytes
+ * arg3 == Measurement value, bytes: 0 - 7
+ * arg4 == Measurement value, bytes: 8 - 15
+ * arg5 == Measurement value, bytes: 16 - 23
+ * arg6 == Measurement value, bytes: 24 - 31
+ * arg7 == Measurement value, bytes: 32 - 39
+ * arg8 == Measurement value, bytes: 40 - 47
+ * arg9 == Measurement value, bytes: 48 - 55
+ * arg10 == Measurement value, bytes: 56 - 63
+ * ret0 == Status / error
+ */
+#define SMC_RSI_MEASUREMENT_EXTEND SMC_RSI_FID(0x193)
+
+/*
+ * Initialize the operation to retrieve an attestation token.
+ *
+ * arg1 == Challenge value, bytes: 0 - 7
+ * arg2 == Challenge value, bytes: 8 - 15
+ * arg3 == Challenge value, bytes: 16 - 23
+ * arg4 == Challenge value, bytes: 24 - 31
+ * arg5 == Challenge value, bytes: 32 - 39
+ * arg6 == Challenge value, bytes: 40 - 47
+ * arg7 == Challenge value, bytes: 48 - 55
+ * arg8 == Challenge value, bytes: 56 - 63
+ * ret0 == Status / error
+ * ret1 == Upper bound of token size in bytes
+ */
+#define SMC_RSI_ATTESTATION_TOKEN_INIT SMC_RSI_FID(0x194)
+
+/*
+ * Continue the operation to retrieve an attestation token.
+ *
+ * arg1 == The IPA of token buffer
+ * arg2 == Offset within the granule of the token buffer
+ * arg3 == Size of the granule buffer
+ * ret0 == Status / error
+ * ret1 == Length of token bytes copied to the granule buffer
+ */
+#define SMC_RSI_ATTESTATION_TOKEN_CONTINUE SMC_RSI_FID(0x195)
+
+#ifndef __ASSEMBLER__
+
+struct realm_config {
+ union {
+ struct {
+ unsigned long ipa_bits; /* Width of IPA in bits */
+ u8 hash_algo; /* Hash algorithm */
+ };
+ u8 pad[0x200];
+ };
+ union {
+ u8 rpv[64]; /* Realm Personalization Value */
+ u8 pad2[0xe00];
+ };
+ /*
+ * The RMM requires the configuration structure to be aligned to a 4k
+ * boundary, ensure this happens by aligning this structure.
+ */
+} __aligned(0x1000);
+
+#endif /* __ASSEMBLER__ */
+
+/*
+ * Read configuration for the current Realm.
+ *
+ * arg1 == struct realm_config addr
+ * ret0 == Status / error
+ */
+#define SMC_RSI_REALM_CONFIG SMC_RSI_FID(0x196)
+
+/*
+ * Request RIPAS of a target IPA range to be changed to a specified value.
+ *
+ * arg1 == Base IPA address of target region
+ * arg2 == Top of the region
+ * arg3 == RIPAS value
+ * arg4 == flags
+ * ret0 == Status / error
+ * ret1 == Top of modified IPA range
+ * ret2 == Whether the Host accepted or rejected the request
+ */
+#define SMC_RSI_IPA_STATE_SET SMC_RSI_FID(0x197)
+
+#define RSI_NO_CHANGE_DESTROYED UL(0)
+#define RSI_CHANGE_DESTROYED UL(1)
+
+#define RSI_ACCEPT UL(0)
+#define RSI_REJECT UL(1)
+
+/*
+ * Get RIPAS of a target IPA range.
+ *
+ * arg1 == Base IPA of target region
+ * arg2 == End of target IPA region
+ * ret0 == Status / error
+ * ret1 == Top of IPA region which has the reported RIPAS value
+ * ret2 == RIPAS value
+ */
+#define SMC_RSI_IPA_STATE_GET SMC_RSI_FID(0x198)
+
+/*
+ * Make a Host call.
+ *
+ * arg1 == IPA of host call structure
+ * ret0 == Status / error
+ */
+#define SMC_RSI_HOST_CALL SMC_RSI_FID(0x199)
+
+#endif /* __LINUX_ARM_SMCCC_RSI_H_ */
diff --git a/include/linux/arm_mpam.h b/include/linux/arm_mpam.h
index f92a36187a52..002f56e15362 100644
--- a/include/linux/arm_mpam.h
+++ b/include/linux/arm_mpam.h
@@ -12,7 +12,7 @@ struct mpam_msc;
enum mpam_msc_iface {
MPAM_IFACE_MMIO, /* a real MPAM MSC */
- MPAM_IFACE_PCC, /* a fake MPAM MSC */
+ MPAM_IFACE_PCC, /* using the MPAM-Fb firmware redirection */
};
enum mpam_class_types {
diff --git a/include/linux/audit.h b/include/linux/audit.h
index 45abb3722d30..767e349d4834 100644
--- a/include/linux/audit.h
+++ b/include/linux/audit.h
@@ -449,6 +449,7 @@ extern void __audit_tk_injoffset(struct timespec64 offset);
extern void __audit_ntp_log(const struct audit_ntp_data *ad);
extern void __audit_log_nfcfg(const char *name, u8 af, unsigned int nentries,
enum audit_nfcfgop op, gfp_t gfp);
+extern void __audit_log_fsopen(const char *fs_name);
static inline void audit_ipc_obj(struct kern_ipc_perm *ipcp)
{
@@ -547,7 +548,7 @@ static inline void audit_openat2_how(struct open_how *how)
static inline void audit_log_kern_module(const char *name)
{
- if (!audit_dummy_context())
+ if (unlikely(!audit_dummy_context()))
__audit_log_kern_module(name);
}
@@ -563,7 +564,7 @@ static inline void audit_tk_injoffset(struct timespec64 offset)
if (offset.tv_sec == 0 && offset.tv_nsec == 0)
return;
- if (!audit_dummy_context())
+ if (unlikely(!audit_dummy_context()))
__audit_tk_injoffset(offset);
}
@@ -586,7 +587,7 @@ static inline void audit_ntp_set_new(struct audit_ntp_data *ad,
static inline void audit_ntp_log(const struct audit_ntp_data *ad)
{
- if (!audit_dummy_context())
+ if (unlikely(!audit_dummy_context()))
__audit_ntp_log(ad);
}
@@ -598,6 +599,12 @@ static inline void audit_log_nfcfg(const char *name, u8 af,
__audit_log_nfcfg(name, af, nentries, op, gfp);
}
+static inline void audit_log_fsopen(const char *fs_name)
+{
+ if (!audit_dummy_context())
+ __audit_log_fsopen(fs_name);
+}
+
extern int audit_n_rules;
extern int audit_signals;
#else /* CONFIG_AUDITSYSCALL */
@@ -730,6 +737,9 @@ static inline void audit_log_nfcfg(const char *name, u8 af,
enum audit_nfcfgop op, gfp_t gfp)
{ }
+static inline void audit_log_fsopen(const char *fs_name)
+{ }
+
#define audit_n_rules 0
#define audit_signals 0
#endif /* CONFIG_AUDITSYSCALL */
diff --git a/include/linux/binfmts.h b/include/linux/binfmts.h
index f686a37f7a0a..2e87faf9a8c2 100644
--- a/include/linux/binfmts.h
+++ b/include/linux/binfmts.h
@@ -128,7 +128,8 @@ struct linux_binfmt {
struct module *module;
int (*load_binary)(struct linux_binprm *);
#ifdef CONFIG_COREDUMP
- int (*core_dump)(struct coredump_params *cprm);
+ /* Returns true if the whole coredump was written. */
+ bool (*core_dump)(struct coredump_params *cprm);
unsigned long min_coredump; /* minimal dump size */
#endif
} __randomize_layout;
diff --git a/include/linux/bio-integrity.h b/include/linux/bio-integrity.h
index 0ea2a8bf7efb..a954c97be0b3 100644
--- a/include/linux/bio-integrity.h
+++ b/include/linux/bio-integrity.h
@@ -151,7 +151,6 @@ void bio_integrity_setup_default(struct bio *bio);
unsigned int fs_bio_integrity_alloc(struct bio *bio);
void fs_bio_integrity_free(struct bio *bio);
void fs_bio_integrity_generate(struct bio *bio);
-int fs_bio_integrity_verify(struct bio *bio, sector_t sector,
- unsigned int size);
+int fs_bio_integrity_verify(struct bio *bio, struct bvec_iter *data_iter);
#endif /* _LINUX_BIO_INTEGRITY_H */
diff --git a/include/linux/bio.h b/include/linux/bio.h
index bb3235497e67..17944e44b584 100644
--- a/include/linux/bio.h
+++ b/include/linux/bio.h
@@ -479,6 +479,7 @@ static inline void bio_init_inline(struct bio *bio, struct block_device *bdev,
extern void bio_uninit(struct bio *);
void bio_reset(struct bio *bio, struct block_device *bdev, blk_opf_t opf);
void bio_reuse(struct bio *bio, blk_opf_t opf);
+void bio_prepare_reissue(struct bio *bio, struct block_device *bdev);
void bio_chain(struct bio *, struct bio *);
void bio_await(struct bio *bio, void *priv,
void (*submit)(struct bio *bio, void *priv));
@@ -516,16 +517,18 @@ int bdev_rw_virt(struct block_device *bdev, sector_t sector, void *data,
size_t len, enum req_op op);
int bio_iov_iter_get_pages(struct bio *bio, struct iov_iter *iter,
- unsigned mem_align_mask, unsigned len_align_mask);
+ unsigned maxlen, unsigned mem_align_mask,
+ unsigned len_align_mask);
bool bio_iov_iter_set(struct bio *bio, const struct iov_iter *iter);
void __bio_release_pages(struct bio *bio, bool mark_dirty);
extern void bio_set_pages_dirty(struct bio *bio);
extern void bio_check_pages_dirty(struct bio *bio);
-int bio_iov_iter_bounce(struct bio *bio, struct iov_iter *iter, size_t maxlen,
- size_t minsize);
-void bio_iov_iter_unbounce(struct bio *bio, bool is_error, bool mark_dirty);
+int bio_alloc_bounce_folios(struct bio *bio, size_t total_len, size_t minsize);
+void bio_free_folios(struct bio *bio);
+int bio_iov_iter_bounce_write(struct bio *bio, struct iov_iter *iter,
+ size_t maxlen, size_t minsize);
extern void bio_copy_data(struct bio *dst, struct bio *src);
extern void bio_free_pages(struct bio *bio);
diff --git a/include/linux/bitfield-fix-width.h b/include/linux/bitfield-fix-width.h
new file mode 100644
index 000000000000..f73b8cd65601
--- /dev/null
+++ b/include/linux/bitfield-fix-width.h
@@ -0,0 +1,241 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+
+#ifndef _LINUX_BITFIELD_FIX_WIDTH_H
+#define _LINUX_BITFIELD_FIX_WIDTH_H
+
+#include <linux/compiler.h>
+#include <linux/types.h>
+#include <asm/byteorder.h>
+
+extern void __compiletime_error("value doesn't fit into mask")
+__field_overflow(void);
+
+extern void __compiletime_error("bad bitfield mask")
+__bad_mask(void);
+
+static __always_inline
+u64 field_multiplier(u64 field)
+{
+ if ((field | (field - 1)) & ((field | (field - 1)) + 1))
+ __bad_mask();
+ return field & -field;
+}
+
+static __always_inline
+u64 field_mask(u64 field)
+{
+ return field / field_multiplier(field);
+}
+
+#define field_max(field) ((typeof(field))field_mask(field))
+
+#define __assert_field(v, field) \
+ do { \
+ if (__builtin_constant_p(v) && \
+ ((v) & ~field_mask(field))) \
+ __field_overflow(); \
+ } while (0)
+
+static __always_inline __must_check
+__u8 u8_encode_bits(u8 v, u8 field)
+{
+ __assert_field(v, field);
+ return (v & field_mask(field)) * field_multiplier(field);
+}
+
+static __always_inline __must_check
+__u8 u8_replace_bits(__u8 old, u8 val, u8 field)
+{
+ return (old & ~field) | u8_encode_bits(val, field);
+}
+
+static __always_inline
+void u8p_replace_bits(__u8 *p, u8 val, u8 field)
+{
+ *p = (*p & ~field) | u8_encode_bits(val, field);
+}
+
+static __always_inline __must_check
+u8 u8_get_bits(__u8 v, u8 field)
+{
+ return (v & field) / field_multiplier(field);
+}
+
+static __always_inline __must_check
+__le16 le16_encode_bits(u16 v, u16 field)
+{
+ __assert_field(v, field);
+ return cpu_to_le16((v & field_mask(field)) * field_multiplier(field));
+}
+
+static __always_inline
+void le16p_replace_bits(__le16 *p, u16 val, u16 field)
+{
+ *p = (*p & ~cpu_to_le16(field)) | le16_encode_bits(val, field);
+}
+
+static __always_inline __must_check
+u16 le16_get_bits(__le16 v, u16 field)
+{
+ return (le16_to_cpu(v) & field) / field_multiplier(field);
+}
+
+static __always_inline __must_check
+__be16 be16_encode_bits(u16 v, u16 field)
+{
+ __assert_field(v, field);
+ return cpu_to_be16((v & field_mask(field)) * field_multiplier(field));
+}
+
+static __always_inline __must_check
+u16 be16_get_bits(__be16 v, u16 field)
+{
+ return (be16_to_cpu(v) & field) / field_multiplier(field);
+}
+
+static __always_inline __must_check
+__be16 be16_replace_bits(__be16 old, u16 val, u16 field)
+{
+ return (old & ~cpu_to_be16(field)) | be16_encode_bits(val, field);
+}
+
+static __always_inline __must_check
+__u16 u16_encode_bits(u16 v, u16 field)
+{
+ __assert_field(v, field);
+ return (v & field_mask(field)) * field_multiplier(field);
+}
+
+static __always_inline __must_check
+__u16 u16_replace_bits(__u16 old, u16 val, u16 field)
+{
+ return (old & ~field) | u16_encode_bits(val, field);
+}
+
+static __always_inline
+void u16p_replace_bits(__u16 *p, u16 val, u16 field)
+{
+ *p = (*p & ~field) | u16_encode_bits(val, field);
+}
+
+static __always_inline __must_check
+u16 u16_get_bits(__u16 v, u16 field)
+{
+ return (v & field) / field_multiplier(field);
+}
+
+static __always_inline __must_check
+__le32 le32_encode_bits(u32 v, u32 field)
+{
+ __assert_field(v, field);
+ return cpu_to_le32((v & field_mask(field)) * field_multiplier(field));
+}
+
+static __always_inline
+void le32p_replace_bits(__le32 *p, u32 val, u32 field)
+{
+ *p = (*p & ~cpu_to_le32(field)) | le32_encode_bits(val, field);
+}
+
+static __always_inline __must_check
+u32 le32_get_bits(__le32 v, u32 field)
+{
+ return (le32_to_cpu(v) & field) / field_multiplier(field);
+}
+
+static __always_inline __must_check
+__be32 be32_encode_bits(u32 v, u32 field)
+{
+ __assert_field(v, field);
+ return cpu_to_be32((v & field_mask(field)) * field_multiplier(field));
+}
+
+static __always_inline
+void be32p_replace_bits(__be32 *p, u32 val, u32 field)
+{
+ *p = (*p & ~cpu_to_be32(field)) | be32_encode_bits(val, field);
+}
+
+static __always_inline __must_check
+u32 be32_get_bits(__be32 v, u32 field)
+{
+ return (be32_to_cpu(v) & field) / field_multiplier(field);
+}
+
+static __always_inline __must_check
+__u32 u32_encode_bits(u32 v, u32 field)
+{
+ __assert_field(v, field);
+ return (v & field_mask(field)) * field_multiplier(field);
+}
+
+static __always_inline __must_check
+__u32 u32_replace_bits(__u32 old, u32 val, u32 field)
+{
+ return (old & ~field) | u32_encode_bits(val, field);
+}
+
+static __always_inline
+void u32p_replace_bits(__u32 *p, u32 val, u32 field)
+{
+ *p = (*p & ~field) | u32_encode_bits(val, field);
+}
+
+static __always_inline __must_check
+u32 u32_get_bits(__u32 v, u32 field)
+{
+ return (v & field) / field_multiplier(field);
+}
+
+static __always_inline __must_check
+__le64 le64_encode_bits(u64 v, u64 field)
+{
+ __assert_field(v, field);
+ return cpu_to_le64((v & field_mask(field)) * field_multiplier(field));
+}
+
+static __always_inline __must_check
+u64 le64_get_bits(__le64 v, u64 field)
+{
+ return (le64_to_cpu(v) & field) / field_multiplier(field);
+}
+
+static __always_inline __must_check
+__be64 be64_encode_bits(u64 v, u64 field)
+{
+ __assert_field(v, field);
+ return cpu_to_be64((v & field_mask(field)) * field_multiplier(field));
+}
+
+static __always_inline __must_check
+u64 be64_get_bits(__be64 v, u64 field)
+{
+ return (be64_to_cpu(v) & field) / field_multiplier(field);
+}
+
+static __always_inline __must_check
+__u64 u64_encode_bits(u64 v, u64 field)
+{
+ __assert_field(v, field);
+ return (v & field_mask(field)) * field_multiplier(field);
+}
+
+static __always_inline __must_check
+__u64 u64_replace_bits(__u64 old, u64 val, u64 field)
+{
+ return (old & ~field) | u64_encode_bits(val, field);
+}
+
+static __always_inline
+void u64p_replace_bits(__u64 *p, u64 val, u64 field)
+{
+ *p = (*p & ~field) | u64_encode_bits(val, field);
+}
+
+static __always_inline __must_check
+u64 u64_get_bits(__u64 v, u64 field)
+{
+ return (v & field) / field_multiplier(field);
+}
+
+#endif /* _LINUX_BITFIELD_FIX_WIDTH_H */
diff --git a/include/linux/bitfield.h b/include/linux/bitfield.h
index 14f86e455a67..e3f7315c1d53 100644
--- a/include/linux/bitfield.h
+++ b/include/linux/bitfield.h
@@ -10,7 +10,7 @@
#include <linux/build_bug.h>
#include <linux/compiler.h>
#include <linux/typecheck.h>
-#include <asm/byteorder.h>
+#include <linux/bitfield-fix-width.h>
/*
* Bitfield access macros
@@ -211,53 +211,6 @@
*(_reg_p) |= (((typeof(_mask))(_val) << __bf_shf(_mask)) & (_mask)); \
})
-extern void __compiletime_error("value doesn't fit into mask")
-__field_overflow(void);
-extern void __compiletime_error("bad bitfield mask")
-__bad_mask(void);
-static __always_inline u64 field_multiplier(u64 field)
-{
- if ((field | (field - 1)) & ((field | (field - 1)) + 1))
- __bad_mask();
- return field & -field;
-}
-static __always_inline u64 field_mask(u64 field)
-{
- return field / field_multiplier(field);
-}
-#define field_max(field) ((typeof(field))field_mask(field))
-#define ____MAKE_OP(type,base,to,from) \
-static __always_inline __##type __must_check type##_encode_bits(base v, base field) \
-{ \
- if (__builtin_constant_p(v) && (v & ~field_mask(field))) \
- __field_overflow(); \
- return to((v & field_mask(field)) * field_multiplier(field)); \
-} \
-static __always_inline __##type __must_check type##_replace_bits(__##type old, \
- base val, base field) \
-{ \
- return (old & ~to(field)) | type##_encode_bits(val, field); \
-} \
-static __always_inline void type##p_replace_bits(__##type *p, \
- base val, base field) \
-{ \
- *p = (*p & ~to(field)) | type##_encode_bits(val, field); \
-} \
-static __always_inline base __must_check type##_get_bits(__##type v, base field) \
-{ \
- return (from(v) & field)/field_multiplier(field); \
-}
-#define __MAKE_OP(size) \
- ____MAKE_OP(le##size,u##size,cpu_to_le##size,le##size##_to_cpu) \
- ____MAKE_OP(be##size,u##size,cpu_to_be##size,be##size##_to_cpu) \
- ____MAKE_OP(u##size,u##size,,)
-____MAKE_OP(u8,u8,,)
-__MAKE_OP(16)
-__MAKE_OP(32)
-__MAKE_OP(64)
-#undef __MAKE_OP
-#undef ____MAKE_OP
-
#define __field_prep(mask, val) \
({ \
auto __mask = (mask); \
diff --git a/include/linux/bitmap.h b/include/linux/bitmap.h
index 7df1573a409c..adafbcf2016b 100644
--- a/include/linux/bitmap.h
+++ b/include/linux/bitmap.h
@@ -52,6 +52,7 @@ struct device;
* bitmap_complement(dst, src, nbits) *dst = ~(*src)
* bitmap_equal(src1, src2, nbits) Are *src1 and *src2 equal?
* bitmap_intersects(src1, src2, nbits) Do *src1 and *src2 overlap?
+ * bitmap_intersects_and(src1, src2, src3, nbits) Do *src1, *src2 and *src3 overlap?
* bitmap_subset(src1, src2, nbits) Is *src1 a subset of *src2?
* bitmap_empty(src, nbits) Are all bits zero in *src?
* bitmap_full(src, nbits) Are all bits set in *src?
@@ -181,6 +182,9 @@ void __bitmap_replace(unsigned long *dst,
const unsigned long *mask, unsigned int nbits);
bool __bitmap_intersects(const unsigned long *bitmap1,
const unsigned long *bitmap2, unsigned int nbits);
+bool __bitmap_intersects_and(const unsigned long *bitmap1,
+ const unsigned long *bitmap2,
+ const unsigned long *bitmap3, unsigned int nbits);
bool __bitmap_subset(const unsigned long *bitmap1,
const unsigned long *bitmap2, unsigned int nbits);
unsigned int __bitmap_weight(const unsigned long *bitmap, unsigned int nbits);
@@ -446,6 +450,16 @@ bool bitmap_intersects(const unsigned long *src1, const unsigned long *src2, uns
}
static __always_inline
+bool bitmap_intersects_and(const unsigned long *src1, const unsigned long *src2,
+ const unsigned long *src3, unsigned int nbits)
+{
+ if (small_const_nbits(nbits))
+ return ((*src1 & *src2 & *src3) & BITMAP_LAST_WORD_MASK(nbits)) != 0;
+ else
+ return __bitmap_intersects_and(src1, src2, src3, nbits);
+}
+
+static __always_inline
bool bitmap_subset(const unsigned long *src1, const unsigned long *src2, unsigned int nbits)
{
if (small_const_nbits(nbits))
diff --git a/include/linux/blk-mq.h b/include/linux/blk-mq.h
index af878597afb8..5e130b282b42 100644
--- a/include/linux/blk-mq.h
+++ b/include/linux/blk-mq.h
@@ -525,8 +525,6 @@ enum hctx_type {
* request_queue.tag_set_list.
* @srcu: Use as lock when type of the request queue is blocking
* (BLK_MQ_F_BLOCKING).
- * @tags_srcu: SRCU used to defer freeing of tags page_list to prevent
- * use-after-free when iterating tags.
* @update_nr_hwq_lock:
* Synchronize updating nr_hw_queues with add/del disk &
* switching elevator.
@@ -551,7 +549,6 @@ struct blk_mq_tag_set {
struct mutex tag_list_lock;
struct list_head tag_list;
struct srcu_struct *srcu;
- struct srcu_struct tags_srcu;
struct rw_semaphore update_nr_hwq_lock;
};
diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h
index 4f7905c3412b..d003a9d2d1f6 100644
--- a/include/linux/blkdev.h
+++ b/include/linux/blkdev.h
@@ -191,14 +191,17 @@ struct gendisk {
#ifdef CONFIG_BLK_DEV_ZONED
/*
* Zoned block device information. Reads of this information must be
- * protected with blk_queue_enter() / blk_queue_exit(). Modifying this
- * information is only allowed while no requests are being processed.
- * See also blk_mq_freeze_queue() and blk_mq_unfreeze_queue().
+ * protected with blk_queue_enter() / blk_queue_exit() or by holding a
+ * lock on zone_revalidate_mutex. blk_revalidate_disk_zones() may modify
+ * this information while no requests are being processed (disk queue
+ * frozen with blk_mq_freeze_queue()) and while holding a lock on
+ * zone_revalidate_mutex.
*/
+ struct mutex zone_revalidate_mutex;
unsigned int nr_zones;
unsigned int zone_capacity;
unsigned int last_zone_capacity;
- u8 __rcu *zones_cond;
+ u8 __rcu *zones_state;
unsigned int zone_wplugs_hash_bits;
atomic_t nr_zone_wplugs;
spinlock_t zone_wplugs_hash_lock;
@@ -1816,9 +1819,11 @@ static inline int bio_split_rw_at(struct bio *bio,
*/
static inline unsigned int max_integrity_io_size(struct queue_limits *lim)
{
- return min_t(unsigned int, lim->max_segment_size,
- (BLK_INTEGRITY_MAX_SIZE / lim->integrity.metadata_size) <<
- lim->integrity.interval_exp);
+ u64 max_intervals;
+
+ max_intervals = BLK_INTEGRITY_MAX_SIZE / lim->integrity.metadata_size;
+ return min_t(u64, lim->max_segment_size,
+ max_intervals << lim->integrity.interval_exp);
}
#define DEFINE_IO_COMP_BATCH(name) struct io_comp_batch name = { }
diff --git a/include/linux/bnge/hsi.h b/include/linux/bnge/hsi.h
index 1f7bd96415a5..d4fe662d60b1 100644
--- a/include/linux/bnge/hsi.h
+++ b/include/linux/bnge/hsi.h
@@ -8607,6 +8607,7 @@ struct hwrm_cfa_l2_filter_alloc_input {
#define CFA_L2_FILTER_ALLOC_REQ_ENABLES_MIRROR_VNIC_ID 0x10000UL
#define CFA_L2_FILTER_ALLOC_REQ_ENABLES_NUM_VLANS 0x20000UL
#define CFA_L2_FILTER_ALLOC_REQ_ENABLES_T_NUM_VLANS 0x40000UL
+ #define CFA_L2_FILTER_ALLOC_REQ_ENABLES_RFS_RING_TBL_IDX 0x80000UL
u8 l2_addr[6];
u8 num_vlans;
u8 t_num_vlans;
@@ -8663,7 +8664,8 @@ struct hwrm_cfa_l2_filter_alloc_input {
#define CFA_L2_FILTER_ALLOC_REQ_PRI_HINT_MIN 0x4UL
#define CFA_L2_FILTER_ALLOC_REQ_PRI_HINT_LAST CFA_L2_FILTER_ALLOC_REQ_PRI_HINT_MIN
u8 unused_5;
- __le32 unused_6;
+ __le16 rfs_ring_tbl_idx;
+ __le16 unused_6;
__le64 l2_filter_id_hint;
};
@@ -8900,6 +8902,95 @@ struct hwrm_cfa_tunnel_filter_free_output {
u8 valid;
};
+/* hwrm_cfa_ntuple_filter_alloc_input (size:1024b/128B) */
+struct hwrm_cfa_ntuple_filter_alloc_input {
+ __le16 req_type;
+ __le16 cmpl_ring;
+ __le16 seq_id;
+ __le16 target_id;
+ __le64 resp_addr;
+ __le32 flags;
+ #define CFA_NTUPLE_FILTER_ALLOC_REQ_FLAGS_LOOPBACK 0x1UL
+ #define CFA_NTUPLE_FILTER_ALLOC_REQ_FLAGS_DROP 0x2UL
+ #define CFA_NTUPLE_FILTER_ALLOC_REQ_FLAGS_METER 0x4UL
+ #define CFA_NTUPLE_FILTER_ALLOC_REQ_FLAGS_DEST_FID 0x8UL
+ #define CFA_NTUPLE_FILTER_ALLOC_REQ_FLAGS_ARP_REPLY 0x10UL
+ #define CFA_NTUPLE_FILTER_ALLOC_REQ_FLAGS_DEST_RFS_RING_IDX 0x20UL
+ #define CFA_NTUPLE_FILTER_ALLOC_REQ_FLAGS_NO_L2_CONTEXT 0x40UL
+ __le32 enables;
+ #define CFA_NTUPLE_FILTER_ALLOC_REQ_ENABLES_L2_FILTER_ID 0x1UL
+ #define CFA_NTUPLE_FILTER_ALLOC_REQ_ENABLES_ETHERTYPE 0x2UL
+ #define CFA_NTUPLE_FILTER_ALLOC_REQ_ENABLES_TUNNEL_TYPE 0x4UL
+ #define CFA_NTUPLE_FILTER_ALLOC_REQ_ENABLES_SRC_MACADDR 0x8UL
+ #define CFA_NTUPLE_FILTER_ALLOC_REQ_ENABLES_IPADDR_TYPE 0x10UL
+ #define CFA_NTUPLE_FILTER_ALLOC_REQ_ENABLES_SRC_IPADDR 0x20UL
+ #define CFA_NTUPLE_FILTER_ALLOC_REQ_ENABLES_SRC_IPADDR_MASK 0x40UL
+ #define CFA_NTUPLE_FILTER_ALLOC_REQ_ENABLES_DST_IPADDR 0x80UL
+ #define CFA_NTUPLE_FILTER_ALLOC_REQ_ENABLES_DST_IPADDR_MASK 0x100UL
+ #define CFA_NTUPLE_FILTER_ALLOC_REQ_ENABLES_IP_PROTOCOL 0x200UL
+ #define CFA_NTUPLE_FILTER_ALLOC_REQ_ENABLES_SRC_PORT 0x400UL
+ #define CFA_NTUPLE_FILTER_ALLOC_REQ_ENABLES_SRC_PORT_MASK 0x800UL
+ #define CFA_NTUPLE_FILTER_ALLOC_REQ_ENABLES_DST_PORT 0x1000UL
+ #define CFA_NTUPLE_FILTER_ALLOC_REQ_ENABLES_DST_PORT_MASK 0x2000UL
+ #define CFA_NTUPLE_FILTER_ALLOC_REQ_ENABLES_PRI_HINT 0x4000UL
+ #define CFA_NTUPLE_FILTER_ALLOC_REQ_ENABLES_NTUPLE_FILTER_ID 0x8000UL
+ #define CFA_NTUPLE_FILTER_ALLOC_REQ_ENABLES_DST_ID 0x10000UL
+ #define CFA_NTUPLE_FILTER_ALLOC_REQ_ENABLES_MIRROR_VNIC_ID 0x20000UL
+ #define CFA_NTUPLE_FILTER_ALLOC_REQ_ENABLES_DST_MACADDR 0x40000UL
+ #define CFA_NTUPLE_FILTER_ALLOC_REQ_ENABLES_RFS_RING_TBL_IDX 0x80000UL
+ __le64 l2_filter_id;
+ u8 src_macaddr[6];
+ __be16 ethertype;
+ u8 ip_addr_type;
+ #define CFA_NTUPLE_FILTER_ALLOC_REQ_IP_ADDR_TYPE_UNKNOWN 0x0UL
+ #define CFA_NTUPLE_FILTER_ALLOC_REQ_IP_ADDR_TYPE_IPV4 0x4UL
+ #define CFA_NTUPLE_FILTER_ALLOC_REQ_IP_ADDR_TYPE_IPV6 0x6UL
+ #define CFA_NTUPLE_FILTER_ALLOC_REQ_IP_ADDR_TYPE_LAST CFA_NTUPLE_FILTER_ALLOC_REQ_IP_ADDR_TYPE_IPV6
+ u8 ip_protocol;
+ #define CFA_NTUPLE_FILTER_ALLOC_REQ_IP_PROTOCOL_UNKNOWN 0x0UL
+ #define CFA_NTUPLE_FILTER_ALLOC_REQ_IP_PROTOCOL_TCP 0x6UL
+ #define CFA_NTUPLE_FILTER_ALLOC_REQ_IP_PROTOCOL_UDP 0x11UL
+ #define CFA_NTUPLE_FILTER_ALLOC_REQ_IP_PROTOCOL_ICMP 0x1UL
+ #define CFA_NTUPLE_FILTER_ALLOC_REQ_IP_PROTOCOL_ICMPV6 0x3aUL
+ #define CFA_NTUPLE_FILTER_ALLOC_REQ_IP_PROTOCOL_RSVD 0xffUL
+ #define CFA_NTUPLE_FILTER_ALLOC_REQ_IP_PROTOCOL_LAST CFA_NTUPLE_FILTER_ALLOC_REQ_IP_PROTOCOL_RSVD
+ __le16 dst_id;
+ __le16 rfs_ring_tbl_idx;
+ u8 tunnel_type;
+ #define CFA_NTUPLE_FILTER_ALLOC_REQ_TUNNEL_TYPE_NONTUNNEL 0x0UL
+ #define CFA_NTUPLE_FILTER_ALLOC_REQ_TUNNEL_TYPE_VXLAN 0x1UL
+ #define CFA_NTUPLE_FILTER_ALLOC_REQ_TUNNEL_TYPE_NVGRE 0x2UL
+ #define CFA_NTUPLE_FILTER_ALLOC_REQ_TUNNEL_TYPE_L2GRE 0x3UL
+ #define CFA_NTUPLE_FILTER_ALLOC_REQ_TUNNEL_TYPE_IPIP 0x4UL
+ #define CFA_NTUPLE_FILTER_ALLOC_REQ_TUNNEL_TYPE_GENEVE 0x5UL
+ #define CFA_NTUPLE_FILTER_ALLOC_REQ_TUNNEL_TYPE_MPLS 0x6UL
+ #define CFA_NTUPLE_FILTER_ALLOC_REQ_TUNNEL_TYPE_STT 0x7UL
+ #define CFA_NTUPLE_FILTER_ALLOC_REQ_TUNNEL_TYPE_IPGRE 0x8UL
+ #define CFA_NTUPLE_FILTER_ALLOC_REQ_TUNNEL_TYPE_VXLAN_V4 0x9UL
+ #define CFA_NTUPLE_FILTER_ALLOC_REQ_TUNNEL_TYPE_IPGRE_V1 0xaUL
+ #define CFA_NTUPLE_FILTER_ALLOC_REQ_TUNNEL_TYPE_L2_ETYPE 0xbUL
+ #define CFA_NTUPLE_FILTER_ALLOC_REQ_TUNNEL_TYPE_VXLAN_GPE_V6 0xcUL
+ #define CFA_NTUPLE_FILTER_ALLOC_REQ_TUNNEL_TYPE_VXLAN_GPE 0x10UL
+ #define CFA_NTUPLE_FILTER_ALLOC_REQ_TUNNEL_TYPE_ANYTUNNEL 0xffUL
+ #define CFA_NTUPLE_FILTER_ALLOC_REQ_TUNNEL_TYPE_LAST CFA_NTUPLE_FILTER_ALLOC_REQ_TUNNEL_TYPE_ANYTUNNEL
+ u8 pri_hint;
+ #define CFA_NTUPLE_FILTER_ALLOC_REQ_PRI_HINT_NO_PREFER 0x0UL
+ #define CFA_NTUPLE_FILTER_ALLOC_REQ_PRI_HINT_ABOVE 0x1UL
+ #define CFA_NTUPLE_FILTER_ALLOC_REQ_PRI_HINT_BELOW 0x2UL
+ #define CFA_NTUPLE_FILTER_ALLOC_REQ_PRI_HINT_HIGHEST 0x3UL
+ #define CFA_NTUPLE_FILTER_ALLOC_REQ_PRI_HINT_LOWEST 0x4UL
+ #define CFA_NTUPLE_FILTER_ALLOC_REQ_PRI_HINT_LAST CFA_NTUPLE_FILTER_ALLOC_REQ_PRI_HINT_LOWEST
+ __be32 src_ipaddr[4];
+ __be32 src_ipaddr_mask[4];
+ __be32 dst_ipaddr[4];
+ __be32 dst_ipaddr_mask[4];
+ __be16 src_port;
+ __be16 src_port_mask;
+ __be16 dst_port;
+ __be16 dst_port_mask;
+ __le64 ntuple_filter_id_hint;
+};
+
/* hwrm_cfa_ntuple_filter_alloc_output (size:192b/24B) */
struct hwrm_cfa_ntuple_filter_alloc_output {
__le16 error_code;
@@ -9014,6 +9105,49 @@ struct hwrm_cfa_ntuple_filter_cfg_output {
u8 valid;
};
+/* hwrm_cfa_adv_flow_mgnt_qcaps_input (size:256b/32B) */
+struct hwrm_cfa_adv_flow_mgnt_qcaps_input {
+ __le16 req_type;
+ __le16 cmpl_ring;
+ __le16 seq_id;
+ __le16 target_id;
+ __le64 resp_addr;
+ __le32 unused_0[4];
+};
+
+/* hwrm_cfa_adv_flow_mgnt_qcaps_output (size:128b/16B) */
+struct hwrm_cfa_adv_flow_mgnt_qcaps_output {
+ __le16 error_code;
+ __le16 req_type;
+ __le16 seq_id;
+ __le16 resp_len;
+ __le32 flags;
+ #define CFA_ADV_FLOW_MGNT_QCAPS_RESP_FLAGS_FLOW_HND_16BIT_SUPPORTED 0x1UL
+ #define CFA_ADV_FLOW_MGNT_QCAPS_RESP_FLAGS_FLOW_HND_64BIT_SUPPORTED 0x2UL
+ #define CFA_ADV_FLOW_MGNT_QCAPS_RESP_FLAGS_FLOW_BATCH_DELETE_SUPPORTED 0x4UL
+ #define CFA_ADV_FLOW_MGNT_QCAPS_RESP_FLAGS_FLOW_RESET_ALL_SUPPORTED 0x8UL
+ #define CFA_ADV_FLOW_MGNT_QCAPS_RESP_FLAGS_NTUPLE_FLOW_DEST_FUNC_SUPPORTED 0x10UL
+ #define CFA_ADV_FLOW_MGNT_QCAPS_RESP_FLAGS_TX_EEM_FLOW_SUPPORTED 0x20UL
+ #define CFA_ADV_FLOW_MGNT_QCAPS_RESP_FLAGS_RX_EEM_FLOW_SUPPORTED 0x40UL
+ #define CFA_ADV_FLOW_MGNT_QCAPS_RESP_FLAGS_FLOW_COUNTER_ALLOC_SUPPORTED 0x80UL
+ #define CFA_ADV_FLOW_MGNT_QCAPS_RESP_FLAGS_RFS_RING_TBL_IDX_SUPPORTED 0x100UL
+ #define CFA_ADV_FLOW_MGNT_QCAPS_RESP_FLAGS_UNTAGGED_VLAN_SUPPORTED 0x200UL
+ #define CFA_ADV_FLOW_MGNT_QCAPS_RESP_FLAGS_XDP_SUPPORTED 0x400UL
+ #define CFA_ADV_FLOW_MGNT_QCAPS_RESP_FLAGS_L2_HEADER_SOURCE_FIELDS_SUPPORTED 0x800UL
+ #define CFA_ADV_FLOW_MGNT_QCAPS_RESP_FLAGS_NTUPLE_FLOW_RX_ARP_SUPPORTED 0x1000UL
+ #define CFA_ADV_FLOW_MGNT_QCAPS_RESP_FLAGS_RFS_RING_TBL_IDX_V2_SUPPORTED 0x2000UL
+ #define CFA_ADV_FLOW_MGNT_QCAPS_RESP_FLAGS_NTUPLE_FLOW_RX_ETHERTYPE_IP_SUPPORTED 0x4000UL
+ #define CFA_ADV_FLOW_MGNT_QCAPS_RESP_FLAGS_TRUFLOW_CAPABLE 0x8000UL
+ #define CFA_ADV_FLOW_MGNT_QCAPS_RESP_FLAGS_L2_FILTER_TRAFFIC_TYPE_L2_ROCE_SUPPORTED 0x10000UL
+ #define CFA_ADV_FLOW_MGNT_QCAPS_RESP_FLAGS_LAG_SUPPORTED 0x20000UL
+ #define CFA_ADV_FLOW_MGNT_QCAPS_RESP_FLAGS_NTUPLE_FLOW_NO_L2CTX_SUPPORTED 0x40000UL
+ #define CFA_ADV_FLOW_MGNT_QCAPS_RESP_FLAGS_NIC_FLOW_STATS_SUPPORTED 0x80000UL
+ #define CFA_ADV_FLOW_MGNT_QCAPS_RESP_FLAGS_NTUPLE_FLOW_RX_EXT_IP_PROTO_SUPPORTED 0x100000UL
+ #define CFA_ADV_FLOW_MGNT_QCAPS_RESP_FLAGS_RFS_RING_TBL_IDX_V3_SUPPORTED 0x200000UL
+ u8 unused_0[3];
+ u8 valid;
+};
+
/* hwrm_tunnel_dst_port_alloc_input (size:192b/24B) */
struct hwrm_tunnel_dst_port_alloc_input {
__le16 req_type;
diff --git a/include/linux/bpf-cgroup-defs.h b/include/linux/bpf-cgroup-defs.h
index c9e6b26abab6..0147b8bec973 100644
--- a/include/linux/bpf-cgroup-defs.h
+++ b/include/linux/bpf-cgroup-defs.h
@@ -47,6 +47,7 @@ enum cgroup_bpf_attach_type {
CGROUP_INET6_GETSOCKNAME,
CGROUP_UNIX_GETSOCKNAME,
CGROUP_INET_SOCK_RELEASE,
+ CGROUP_TCP_SOCK_OPS,
CGROUP_LSM_START,
CGROUP_LSM_END = CGROUP_LSM_START + CGROUP_LSM_NUM - 1,
MAX_CGROUP_BPF_ATTACH_TYPE
diff --git a/include/linux/bpf-cgroup.h b/include/linux/bpf-cgroup.h
index 4d0cc65976a1..02ef7f899b3d 100644
--- a/include/linux/bpf-cgroup.h
+++ b/include/linux/bpf-cgroup.h
@@ -100,6 +100,8 @@ struct bpf_cgroup_storage {
struct bpf_cgroup_link {
struct bpf_link link;
struct cgroup *cgroup;
+ struct bpf_map *map;
+ wait_queue_head_t wait_hup;
};
struct bpf_prog_list {
@@ -110,6 +112,18 @@ struct bpf_prog_list {
u32 flags;
};
+#define bpf_cgroup_struct_ops_foreach(var, item, cgrp, atype) \
+ for (item = rcu_dereference((cgrp)->bpf.effective[atype])->items;\
+ ((var) = READ_ONCE(item->kdata)); \
+ item++)
+
+static inline bool cgroup_bpf_is_struct_ops_atype(enum cgroup_bpf_attach_type atype)
+{
+ return atype == CGROUP_TCP_SOCK_OPS;
+}
+void cgroup_bpf_struct_ops_register(int atype, u32 type_id, void *cfi_stubs, bool mult_trace);
+int cgroup_bpf_struct_ops_attach(struct bpf_map *map, const union bpf_attr *attr);
+
void __init cgroup_bpf_lifetime_notifier_init(void);
int __cgroup_bpf_run_filter_skb(struct sock *sk,
@@ -331,27 +345,19 @@ static inline bool cgroup_bpf_sock_enabled(struct sock *sk,
* calling bpf_setsockopt on listener-sk will not make sense anyway,
* so passing 'sock_ops->sk == req_sk' to the bpf prog is appropriate here.
*/
-#define BPF_CGROUP_RUN_PROG_SOCK_OPS_SK(sock_ops, sk) \
-({ \
- int __ret = 0; \
- if (cgroup_bpf_enabled(CGROUP_SOCK_OPS)) \
- __ret = __cgroup_bpf_run_filter_sock_ops(sk, \
- sock_ops, \
- CGROUP_SOCK_OPS); \
- __ret; \
-})
-
-#define BPF_CGROUP_RUN_PROG_SOCK_OPS(sock_ops) \
-({ \
- int __ret = 0; \
- if (cgroup_bpf_enabled(CGROUP_SOCK_OPS) && (sock_ops)->sk) { \
- typeof(sk) __sk = sk_to_full_sk((sock_ops)->sk); \
- if (__sk && sk_fullsock(__sk)) \
- __ret = __cgroup_bpf_run_filter_sock_ops(__sk, \
- sock_ops, \
- CGROUP_SOCK_OPS); \
- } \
- __ret; \
+#define __BPF_CGROUP_RUN_PROG_SOCK_OPS_SK(sock_ops, sk) \
+ __cgroup_bpf_run_filter_sock_ops(sk, sock_ops, \
+ CGROUP_SOCK_OPS)
+
+#define __BPF_CGROUP_RUN_PROG_SOCK_OPS(sock_ops) \
+({ \
+ int __ret = 0; \
+ typeof(sk) __sk = sk_to_full_sk((sock_ops)->sk); \
+ if (__sk && sk_fullsock(__sk)) \
+ __ret = __cgroup_bpf_run_filter_sock_ops(__sk, \
+ sock_ops, \
+ CGROUP_SOCK_OPS); \
+ __ret; \
})
#define BPF_CGROUP_RUN_PROG_DEVICE_CGROUP(atype, major, minor, access) \
@@ -479,6 +485,20 @@ static inline int bpf_percpu_cgroup_storage_update(struct bpf_map *map,
return 0;
}
+static inline bool cgroup_bpf_is_struct_ops_atype(int atype)
+{
+ return false;
+}
+static inline void cgroup_bpf_struct_ops_register(int atype, u32 type_id, void *cfi_stubs,
+ bool mult_trace)
+{
+}
+static inline int cgroup_bpf_struct_ops_attach(struct bpf_map *map,
+ const union bpf_attr *attr)
+{
+ return -EOPNOTSUPP;
+}
+
#define cgroup_bpf_enabled(atype) (0)
#define BPF_CGROUP_RUN_SA_PROG_LOCK(sk, uaddr, uaddrlen, atype, t_ctx) ({ 0; })
#define BPF_CGROUP_RUN_SA_PROG(sk, uaddr, uaddrlen, atype) ({ 0; })
@@ -501,7 +521,7 @@ static inline int bpf_percpu_cgroup_storage_update(struct bpf_map *map,
#define BPF_CGROUP_RUN_PROG_UDP4_RECVMSG_LOCK(sk, uaddr, uaddrlen) ({ 0; })
#define BPF_CGROUP_RUN_PROG_UDP6_RECVMSG_LOCK(sk, uaddr, uaddrlen) ({ 0; })
#define BPF_CGROUP_RUN_PROG_UNIX_RECVMSG_LOCK(sk, uaddr, uaddrlen) ({ 0; })
-#define BPF_CGROUP_RUN_PROG_SOCK_OPS(sock_ops) ({ 0; })
+#define __BPF_CGROUP_RUN_PROG_SOCK_OPS(sock_ops) ({ 0; })
#define BPF_CGROUP_RUN_PROG_DEVICE_CGROUP(atype, major, minor, access) ({ 0; })
#define BPF_CGROUP_RUN_PROG_SYSCTL(head,table,write,buf,count,pos) ({ 0; })
#define BPF_CGROUP_RUN_PROG_GETSOCKOPT(sock, level, optname, optval, \
diff --git a/include/linux/bpf.h b/include/linux/bpf.h
index e57af902560c..580f89c450b5 100644
--- a/include/linux/bpf.h
+++ b/include/linux/bpf.h
@@ -17,6 +17,7 @@
#include <linux/numa.h>
#include <linux/mm_types.h>
#include <linux/wait.h>
+#include <linux/irq_work_types.h>
#include <linux/refcount.h>
#include <linux/mutex.h>
#include <linux/module.h>
@@ -90,6 +91,7 @@ struct bpf_map_ops {
struct bpf_map *(*map_alloc)(union bpf_attr *attr);
void (*map_release)(struct bpf_map *map, struct file *map_file);
void (*map_free)(struct bpf_map *map);
+ void (*map_free_pre_rcu)(struct bpf_map *map);
int (*map_get_next_key)(struct bpf_map *map, void *key, void *next_key);
void (*map_release_uref)(struct bpf_map *map);
void *(*map_lookup_elem_sys_only)(struct bpf_map *map, void *key);
@@ -214,6 +216,7 @@ enum btf_field_type {
BPF_UPTR = (1 << 11),
BPF_RES_SPIN_LOCK = (1 << 12),
BPF_TASK_WORK = (1 << 13),
+ BPF_RCU_HEAD = (1 << 14),
};
enum bpf_cgroup_storage_type {
@@ -268,6 +271,7 @@ struct btf_record {
int wq_off;
int refcount_off;
int task_work_off;
+ int rcu_head_off;
struct btf_field fields[];
};
@@ -337,12 +341,23 @@ struct bpf_map {
bool frozen; /* write-once; write-protected by freeze_mutex */
bool free_after_mult_rcu_gp;
bool free_after_rcu_gp;
+ bool was_inner_map;
atomic64_t sleepable_refcnt;
s64 __percpu *elem_count;
u64 cookie; /* write-once */
char *excl_prog_sha;
+ /*
+ * Which programs use the map, see bpf_map_claim(): 0 - none so far,
+ * aux of the program - only that one, the same with BPF_MAP_USER_PATCHED
+ * set - only that one and it stored the addresses of its functions into
+ * the map, BPF_MAP_USER_MANY - more than one.
+ */
+ unsigned long user;
};
+#define BPF_MAP_USER_MANY 1UL
+#define BPF_MAP_USER_PATCHED 1UL
+
static inline const char *btf_field_type_name(enum btf_field_type type)
{
switch (type) {
@@ -373,6 +388,8 @@ static inline const char *btf_field_type_name(enum btf_field_type type)
return "bpf_refcount";
case BPF_TASK_WORK:
return "bpf_task_work";
+ case BPF_RCU_HEAD:
+ return "bpf_rcu_head";
default:
WARN_ON_ONCE(1);
return "unknown";
@@ -413,6 +430,8 @@ static inline u32 btf_field_type_size(enum btf_field_type type)
return sizeof(struct bpf_refcount);
case BPF_TASK_WORK:
return sizeof(struct bpf_task_work);
+ case BPF_RCU_HEAD:
+ return sizeof(struct bpf_rcu_head);
default:
WARN_ON_ONCE(1);
return 0;
@@ -447,6 +466,8 @@ static inline u32 btf_field_type_align(enum btf_field_type type)
return __alignof__(struct bpf_refcount);
case BPF_TASK_WORK:
return __alignof__(struct bpf_task_work);
+ case BPF_RCU_HEAD:
+ return __alignof__(struct bpf_rcu_head);
default:
WARN_ON_ONCE(1);
return 0;
@@ -479,6 +500,7 @@ static inline void bpf_obj_init_field(const struct btf_field *field, void *addr)
case BPF_KPTR_PERCPU:
case BPF_UPTR:
case BPF_TASK_WORK:
+ case BPF_RCU_HEAD:
break;
default:
WARN_ON_ONCE(1);
@@ -572,7 +594,7 @@ static inline void bpf_obj_memcpy(struct btf_record *rec,
if (long_memcpy)
bpf_long_memcpy(dst, src, size);
else
- memcpy(dst, src, size);
+ data_race(memcpy(dst, src, size));
return;
}
@@ -580,10 +602,10 @@ static inline void bpf_obj_memcpy(struct btf_record *rec,
u32 next_off = rec->fields[i].offset;
u32 sz = next_off - curr_off;
- memcpy(dst + curr_off, src + curr_off, sz);
+ data_race(memcpy(dst + curr_off, src + curr_off, sz));
curr_off += rec->fields[i].size + sz;
}
- memcpy(dst + curr_off, src + curr_off, size - curr_off);
+ data_race(memcpy(dst + curr_off, src + curr_off, size - curr_off));
}
static inline void copy_map_value(struct bpf_map *map, void *dst, void *src)
@@ -780,7 +802,10 @@ enum bpf_type_flag {
*/
PTR_UNTRUSTED = BIT(6 + BPF_BASE_TYPE_BITS),
- /* MEM can be uninitialized. */
+ /*
+ * MEM can be uninitialized. Generic memory outputs need not be fully
+ * initialized by the callee.
+ */
MEM_UNINIT = BIT(7 + BPF_BASE_TYPE_BITS),
/* DYNPTR points to memory local to the bpf program. */
@@ -874,7 +899,7 @@ enum bpf_type_flag {
/* function argument constraints */
enum bpf_arg_type {
- ARG_DONTCARE = 0, /* unused argument in helper function */
+ ARG_UNUSED = 0, /* unused argument; terminates argument iteration */
/* the following constraints used to prototype
* bpf_map_lookup/update/delete_elem() functions
@@ -909,6 +934,24 @@ enum bpf_arg_type {
ARG_PTR_TO_TIMER, /* pointer to bpf_timer */
ARG_KPTR_XCHG_DEST, /* pointer to destination that kptrs are bpf_kptr_xchg'd into */
ARG_PTR_TO_DYNPTR, /* pointer to bpf_dynptr. See bpf_type_flag for dynptr type */
+
+ ARG_CONST_SCALAR, /* scalar known at verification time */
+ ARG_CONST_MEM_SIZE, /* ARG_MEM_SIZE that must be constant */
+ ARG_PTR_TO_ALLOC_BTF_ID, /* pointer to an allocated object */
+ ARG_PTR_TO_REFCOUNTED_KPTR, /* pointer to a refcounted local kptr */
+ ARG_PTR_TO_ITER, /* pointer to an iterator */
+ ARG_PTR_TO_LIST_HEAD, /* pointer to bpf_list_head */
+ ARG_PTR_TO_LIST_NODE, /* pointer to bpf_list_node */
+ ARG_PTR_TO_RB_ROOT, /* pointer to bpf_rb_root */
+ ARG_PTR_TO_RB_NODE, /* pointer to bpf_rb_node */
+ ARG_PTR_TO_WORKQUEUE, /* pointer to bpf_wq */
+ ARG_PTR_TO_TASK_WORK, /* pointer to bpf_task_work */
+ ARG_PTR_TO_RCU_HEAD, /* pointer to bpf_rcu_head */
+ ARG_PTR_TO_IRQ_FLAG, /* pointer to saved IRQ flags on the stack */
+ ARG_PTR_TO_RES_SPIN_LOCK, /* pointer to bpf_res_spin_lock */
+ ARG_PTR_TO_CTX_OUT, /* hook output argument passed through from ctx */
+ ARG_PTR_TO_PROG_AUX, /* pointer to the caller's bpf_prog_aux */
+ ARG_IGNORE, /* argument the verifier does not check at all */
__BPF_ARG_TYPE_MAX,
/* Extended arg_types. */
@@ -977,6 +1020,13 @@ static_assert(__BPF_RET_TYPE_MAX <= BPF_BASE_TYPE_LIMIT);
*/
#define MAX_BPF_FUNC_REG_ARGS 5
+/* A by-value argument takes two eightbytes at most, so the maximum number of
+ * argument slots of any function is 2 * MAX_BPF_FUNC_ARGS. A local array may
+ * need that size for processing, although eventually the maximum slots will
+ * be capped at MAX_BPF_FUNC_ARGS.
+ */
+#define MAX_BPF_FUNC_ARG_SLOTS (2 * MAX_BPF_FUNC_ARGS)
+
/* eBPF function prototype used by verifier to allow BPF_CALLs from eBPF programs
* to in-kernel helper functions and for adjusting imm32 field in BPF_CALL
* instructions after verifying
@@ -1005,13 +1055,13 @@ struct bpf_func_proto {
};
union {
struct {
- u32 *arg1_btf_id;
- u32 *arg2_btf_id;
- u32 *arg3_btf_id;
- u32 *arg4_btf_id;
- u32 *arg5_btf_id;
+ const u32 *arg1_btf_id;
+ const u32 *arg2_btf_id;
+ const u32 *arg3_btf_id;
+ const u32 *arg4_btf_id;
+ const u32 *arg5_btf_id;
};
- u32 *arg_btf_id[MAX_BPF_FUNC_ARGS];
+ const u32 *arg_btf_id[MAX_BPF_FUNC_ARGS];
struct {
size_t arg1_size;
size_t arg2_size;
@@ -1114,6 +1164,7 @@ struct bpf_insn_access_aux {
u32 ref_id;
};
};
+ u32 mem_size;
struct bpf_verifier_log *log; /* for verbose logs */
bool is_retval; /* is accessing function return value ? */
};
@@ -1194,6 +1245,9 @@ struct bpf_prog_offload {
u32 jited_len;
};
+/* The argument is aligned to 16 bytes. */
+#define BTF_FMODEL_ALIGN16_ARG BIT(0)
+
/* The argument is signed. */
#define BTF_FMODEL_SIGNED_ARG BIT(1)
@@ -1211,6 +1265,11 @@ struct btf_func_model {
u8 arg_flags[MAX_BPF_FUNC_ARGS];
};
+static inline u32 btf_func_model_arg_slots(const struct btf_func_model *m, u32 arg)
+{
+ return (m->arg_size[arg] + sizeof(u64) - 1) / sizeof(u64);
+}
+
/* Restore arguments before returning from trampoline to let original function
* continue executing. This flag is used for fentry progs when there are no
* fexit progs.
@@ -1258,11 +1317,15 @@ struct btf_func_model {
#define BPF_TRAMP_F_INDIRECT BIT(8)
/* Each call __bpf_prog_enter + call bpf_func + call __bpf_prog_exit is ~50
- * bytes on x86.
+ * bytes on x86. The trampoline image has to fit in PAGE_SIZE.
*/
enum {
-#if defined(__s390x__)
+#if defined(__s390x__) || defined(__powerpc64__)
BPF_MAX_TRAMP_LINKS = 27,
+#elif defined(__x86_64__)
+ BPF_MAX_TRAMP_LINKS = 36,
+#elif defined(__aarch64__)
+ BPF_MAX_TRAMP_LINKS = 37,
#else
BPF_MAX_TRAMP_LINKS = 38,
#endif
@@ -1315,6 +1378,7 @@ int arch_prepare_bpf_trampoline(struct bpf_tramp_image *im, void *image, void *i
void *arch_alloc_bpf_trampoline(unsigned int size);
void arch_free_bpf_trampoline(void *image, unsigned int size);
int __must_check arch_protect_bpf_trampoline(void *image, unsigned int size);
+int arch_bpf_trampoline_skip(void *nop, void *target);
int arch_bpf_trampoline_size(const struct btf_func_model *m, u32 flags,
struct bpf_tramp_nodes *tnodes, void *func_addr);
@@ -1363,19 +1427,48 @@ enum bpf_tramp_prog_type {
BPF_TRAMP_FSESSION,
};
+/*
+ * Each prog call in a trampoline image is preceded by a nop. When the prog is
+ * detached, the nop is patched to a jump to target, right after the call, so
+ * that tasks still running in the image skip the prog.
+ */
+struct bpf_tramp_skip {
+ struct bpf_prog *prog;
+ void *nop;
+ void *target;
+};
+
struct bpf_tramp_image {
void *image;
int size;
struct bpf_ksym ksym;
struct percpu_ref pcref;
- void *ip_after_call;
- void *ip_epilogue;
+ bool call_orig;
+ /* entry in tr->images, the image holds a reference on tr */
+ struct bpf_trampoline *tr;
+ struct list_head list;
+ int nr_skips;
+ struct bpf_tramp_skip *skips;
union {
struct rcu_head rcu;
struct work_struct work;
};
};
+static inline void bpf_tramp_image_add_skip(struct bpf_tramp_image *im, struct bpf_prog *prog,
+ void *nop, void *target)
+{
+ struct bpf_tramp_skip *skip;
+
+ /* struct_ops trampolines and arch_bpf_trampoline_size() have no image */
+ if (!im || !im->skips)
+ return;
+ skip = &im->skips[im->nr_skips++];
+ skip->prog = prog;
+ skip->nop = nop;
+ skip->target = target;
+}
+
struct bpf_trampoline {
/* hlist for trampoline_key_table */
struct hlist_node hlist_key;
@@ -1402,6 +1495,8 @@ struct bpf_trampoline {
int progs_cnt[BPF_TRAMP_MAX];
/* Executable image of trampoline */
struct bpf_tramp_image *cur_image;
+ /* Images not freed yet, cur_image and older ones still in use */
+ struct list_head images;
/* Used as temporary old image storage for multi_attach */
struct {
struct bpf_tramp_image *old_image;
@@ -1648,11 +1743,21 @@ static inline void bpf_trampoline_multi_detach(struct bpf_prog *prog,
static inline void bpf_trampoline_set_flags(struct bpf_trampoline *tr, u32 flags) {}
#endif
+/* The contexts that a global function is called in, and is verified for. */
+enum bpf_func_context {
+ BPF_FUNC_CTX_NON_SLEEPABLE,
+ BPF_FUNC_CTX_SLEEPABLE,
+ /* Sleepable code has disabled preemption or interrupts: no RCU read lock. */
+ BPF_FUNC_CTX_NO_RCU_LOCK,
+ BPF_FUNC_CTX_CNT,
+};
+
struct bpf_func_info_aux {
u16 linkage;
bool unreliable;
- bool called : 1;
- bool verified : 1;
+ bool called[BPF_FUNC_CTX_CNT];
+ bool verified[BPF_FUNC_CTX_CNT];
+ bool called_with_pkt_ptrs;
};
enum bpf_jit_poke_reason {
@@ -1684,6 +1789,7 @@ struct bpf_ctx_arg_aux {
struct btf *btf;
u32 btf_id;
u32 ref_id;
+ u32 mem_size;
bool refcounted;
};
@@ -1712,12 +1818,18 @@ enum {
};
struct bpf_stream {
- atomic_t capacity;
+ refcount_t refcnt;
+ atomic_t capacity; /* bytes reserved against the stream limit */
+ atomic_t readable; /* published bytes available to readers */
struct llist_head log; /* list of in-flight stream elements in LIFO order */
struct mutex lock; /* lock protecting backlog_{head,tail} */
struct llist_node *backlog_head; /* list of in-flight stream elements in FIFO order */
struct llist_node *backlog_tail; /* tail of the list above */
+ wait_queue_head_t waitq;
+ struct irq_work notify_work;
+ bool notify_used; /* notify_work was queued at least once */
+ bool dead;
};
struct bpf_stream_stage {
@@ -1736,6 +1848,7 @@ enum bpf_sig_keyring {
BPF_SIG_KEYRING_SECONDARY,
BPF_SIG_KEYRING_PLATFORM,
BPF_SIG_KEYRING_USER,
+ BPF_SIG_KEYRING_BPF,
};
struct bpf_prog_aux {
@@ -1755,6 +1868,9 @@ struct bpf_prog_aux {
u32 ctx_arg_info_size;
u32 max_rdonly_access;
u32 max_rdwr_access;
+ /* [min, max): the bytes of a rdwr buffer that may be written */
+ u32 min_rdwr_write;
+ u32 max_rdwr_write;
u32 subprog_start;
struct btf *attach_btf;
struct bpf_ctx_arg_aux *ctx_arg_info;
@@ -1769,24 +1885,29 @@ struct bpf_prog_aux {
bool offload_requested; /* Program is bound and offloaded to the netdev. */
bool attach_btf_trace; /* true if attaching to BTF-enabled raw tp */
bool attach_tracing_prog; /* true if tracing another tracing program */
+ bool tramp_linked; /* true if it was ever linked to a trampoline */
+ bool sleepable_async_cb; /* has a bpf_wq or bpf_task_work callback */
bool func_proto_unreliable;
bool tail_call_reachable;
bool xdp_has_frags;
bool exception_cb;
bool exception_boundary;
- bool is_extended; /* true if extended by freplace program */
bool jits_use_priv_stack;
bool priv_stack_requested;
bool changes_pkt_data;
+ bool has_prologue;
bool might_sleep;
+ bool can_unwind;
bool kprobe_write_ctx;
+ /* has insns that work with the arena base, see bpf_prog_has_arena_insns() */
+ bool uses_arena_insns;
struct {
s32 keyring_serial;
u8 keyring_type;
u8 verdict;
} sig;
u64 prog_array_member_cnt; /* counts how many times as member of prog_array */
- struct mutex ext_mutex; /* mutex for is_extended and prog_array_member_cnt */
+ struct mutex ext_mutex; /* mutex for freplace_link_cnt and prog_array_member_cnt */
struct bpf_arena *arena;
void (*recursion_detected)(struct bpf_prog *prog); /* callback if recursion is detected */
/* BTF_KIND_FUNC_PROTO for valid attach_btf_id */
@@ -1818,6 +1939,7 @@ struct bpf_prog_aux {
char name[BPF_OBJ_NAME_LEN];
u64 (*bpf_exception_cb)(u64 cookie, u64 sp, u64 bp, u64, u64);
u16 stack_arg_sp_adjust;
+ u16 freplace_link_cnt; /* counts freplace links extending this prog */
#ifdef CONFIG_SECURITY
void *security;
#endif
@@ -1854,8 +1976,9 @@ struct bpf_prog_aux {
union {
struct work_struct work;
struct rcu_head rcu;
+ struct rcu_work rwork;
};
- struct bpf_stream stream[2];
+ struct bpf_stream *stream[2];
struct mutex st_ops_assoc_mutex;
struct bpf_map __rcu *st_ops_assoc;
};
@@ -1902,6 +2025,15 @@ struct bpf_prog {
};
};
+/*
+ * Does the program, or a callback of it, run under RCU Tasks Trace protection
+ * only, outside of any RCU read side critical section?
+ */
+static inline bool bpf_prog_runs_sleepable(const struct bpf_prog *prog)
+{
+ return prog->sleepable || prog->aux->sleepable_async_cb;
+}
+
struct bpf_array_aux {
/* Programs with direct jumps into programs part of this array. */
struct list_head poke_progs;
@@ -2099,6 +2231,18 @@ struct btf_member;
* unloaded while in use.
* @name: The name of the struct bpf_struct_ops object.
* @func_models: Func models
+ * @cgroup_atype: A value in enum cgroup_bpf_attach_type for cgroup attachment.
+ * 0 means the struct_ops type does not support cgroup attachment.
+ * If cgroup_atype is non-zero, the @reg and @unreg must be NULL
+ * because the attachment/detachment will be handled by the bpf core.
+ * @free_after_tasks_rcu_gp: Set to true if it needs the bpf core to wait for
+ * a tasks_rcu gp before freeing the struct_ops map
+ * and its progs. It is unnecessary if the @unreg
+ * has waited for the correct rcu gp or the @unreg
+ * has ensured all struct_ops prog has finished running.
+ * @free_after_mult_rcu_gp: Same as @free_after_tasks_rcu_gp but waiting for
+ * both tasks_trace_rcu and regular rcu grace period.
+ * It is usually needed if the struct_ops has sleepable prog.
*/
struct bpf_struct_ops {
const struct bpf_verifier_ops *verifier_ops;
@@ -2117,6 +2261,9 @@ struct bpf_struct_ops {
struct module *owner;
const char *name;
struct btf_func_model func_models[BPF_STRUCT_OPS_MAX_NR_MEMBERS];
+ int cgroup_atype;
+ bool free_after_tasks_rcu_gp;
+ bool free_after_mult_rcu_gp;
};
/* Every member of a struct_ops type has an instance even a member is not
@@ -2251,6 +2398,12 @@ u32 bpf_struct_ops_id(const void *kdata);
int bpf_struct_ops_for_each_prog(const void *kdata,
int (*cb)(struct bpf_prog *prog, void *data),
void *data);
+void *bpf_struct_ops_map_kdata(struct bpf_map *map);
+void *bpf_struct_ops_map_cfi_stubs(struct bpf_map *map);
+bool bpf_struct_ops_valid_to_reg(struct bpf_map *map);
+int bpf_struct_ops_link_update_check(struct bpf_map *new_map, struct bpf_map *old_map,
+ struct bpf_map *expected_old_map);
+int bpf_struct_ops_map_cgroup_atype(struct bpf_map *map);
#ifdef CONFIG_NET
/* Define it here to avoid the use of forward declaration */
@@ -2315,6 +2468,32 @@ static inline void bpf_map_struct_ops_info_fill(struct bpf_map_info *info, struc
static inline void bpf_struct_ops_desc_release(struct bpf_struct_ops_desc *st_ops_desc)
{
}
+static inline u32 bpf_struct_ops_id(void *kdata)
+{
+ return 0;
+}
+static inline void *bpf_struct_ops_map_kdata(struct bpf_map *map)
+{
+ return NULL;
+}
+static inline int bpf_struct_ops_map_cgroup_atype(struct bpf_map *map)
+{
+ return 0;
+}
+static inline void *bpf_struct_ops_map_cfi_stubs(struct bpf_map *map)
+{
+ return NULL;
+}
+static inline bool bpf_struct_ops_valid_to_reg(struct bpf_map *map)
+{
+ return false;
+}
+static inline int bpf_struct_ops_link_update_check(struct bpf_map *new_map,
+ struct bpf_map *old_map,
+ struct bpf_map *expected_old_map)
+{
+ return -EOPNOTSUPP;
+}
#endif
@@ -2490,7 +2669,10 @@ u64 bpf_event_output(struct bpf_map *map, u64 flags, void *meta, u64 meta_size,
* since other cpus are walking the array of pointers in parallel.
*/
struct bpf_prog_array_item {
- struct bpf_prog *prog;
+ union {
+ struct bpf_prog *prog;
+ void *kdata;
+ };
union {
struct bpf_cgroup_storage *cgroup_storage[MAX_BPF_CGROUP_STORAGE_TYPE];
u64 bpf_cookie;
@@ -2532,6 +2714,7 @@ int bpf_prog_array_copy(struct bpf_prog_array *old_array,
struct bpf_prog *include_prog,
u64 bpf_cookie,
struct bpf_prog_array **new_array);
+struct bpf_prog *bpf_prog_dummy(void);
struct bpf_run_ctx {};
@@ -2550,6 +2733,7 @@ struct bpf_trace_run_ctx {
struct bpf_tramp_run_ctx {
struct bpf_run_ctx run_ctx;
u64 bpf_cookie;
+ int retval;
struct bpf_run_ctx *saved_run_ctx;
};
@@ -2783,8 +2967,10 @@ struct bpf_map *bpf_map_get_curr_or_next(u32 *id);
struct bpf_prog *bpf_prog_get_curr_or_next(u32 *id);
-int bpf_map_alloc_pages(const struct bpf_map *map, int nid,
- unsigned long nr_pages, struct page **page_array);
+struct page *bpf_alloc_page(int nid, bool sleepable);
+int bpf_alloc_pages(int nid, unsigned long nr_pages,
+ struct llist_head *pages, bool sleepable);
+void bpf_free_pages(struct llist_head *pages);
#ifdef CONFIG_MEMCG
void bpf_map_memcg_enter(const struct bpf_map *map, struct mem_cgroup **old_memcg,
struct mem_cgroup **new_memcg);
@@ -2970,6 +3156,8 @@ typedef int (*bpf_iter_attach_target_t)(struct bpf_prog *prog,
union bpf_iter_link_info *linfo,
struct bpf_iter_aux_info *aux);
typedef void (*bpf_iter_detach_target_t)(struct bpf_iter_aux_info *aux);
+typedef int (*bpf_iter_check_prog_t)(const struct bpf_prog *prog,
+ const struct bpf_iter_aux_info *aux);
typedef void (*bpf_iter_show_fdinfo_t) (const struct bpf_iter_aux_info *aux,
struct seq_file *seq);
typedef int (*bpf_iter_fill_link_info_t)(const struct bpf_iter_aux_info *aux,
@@ -2979,7 +3167,8 @@ typedef const struct bpf_func_proto *
const struct bpf_prog *prog);
enum bpf_iter_feature {
- BPF_ITER_RESCHED = BIT(0),
+ BPF_ITER_RESCHED = BIT(0), /* may cond_resched() between objects */
+ BPF_ITER_NOSLEEP = BIT(1), /* ->show() can't run sleepable progs */
};
#define BPF_ITER_CTX_ARG_MAX 2
@@ -2987,6 +3176,8 @@ struct bpf_iter_reg {
const char *target;
bpf_iter_attach_target_t attach_target;
bpf_iter_detach_target_t detach_target;
+ /* may the program run on what the link is attached to? */
+ bpf_iter_check_prog_t check_prog;
bpf_iter_show_fdinfo_t show_fdinfo;
bpf_iter_fill_link_info_t fill_link_info;
bpf_iter_get_func_proto_t get_func_proto;
@@ -3023,6 +3214,8 @@ void bpf_iter_map_show_fdinfo(const struct bpf_iter_aux_info *aux,
struct seq_file *seq);
int bpf_iter_map_fill_link_info(const struct bpf_iter_aux_info *aux,
struct bpf_link_info *info);
+int bpf_iter_map_check_value_write(const struct bpf_prog *prog,
+ const struct bpf_map *map);
int map_set_for_each_callback_args(struct bpf_verifier_env *env,
struct bpf_func_state *caller,
@@ -3180,7 +3373,7 @@ const struct btf_func_model *
bpf_jit_find_kfunc_model(const struct bpf_prog *prog,
const struct bpf_insn *insn);
int bpf_get_kfunc_addr(const struct bpf_prog *prog, u32 func_id,
- u16 btf_fd_idx, u8 **func_addr);
+ u16 desc_idx, u8 **func_addr);
struct bpf_core_ctx {
struct bpf_verifier_log *log;
@@ -3523,7 +3716,7 @@ bpf_jit_find_kfunc_model(const struct bpf_prog *prog,
static inline int
bpf_get_kfunc_addr(const struct bpf_prog *prog, u32 func_id,
- u16 btf_fd_idx, u8 **func_addr)
+ u16 desc_idx, u8 **func_addr)
{
return -ENOTSUPP;
}
@@ -3629,6 +3822,7 @@ int bpf_dev_bound_kfunc_check(struct bpf_verifier_log *log,
void *bpf_dev_bound_resolve_kfunc(struct bpf_prog *prog, u32 func_id);
int bpf_prog_dev_bound_init(struct bpf_prog *prog, union bpf_attr *attr);
int bpf_prog_dev_bound_inherit(struct bpf_prog *new_prog, struct bpf_prog *old_prog);
+void bpf_prog_dev_bound_moved(struct bpf_prog *prog);
void bpf_dev_bound_netdev_unregister(struct net_device *dev);
static inline bool bpf_prog_is_dev_bound(const struct bpf_prog_aux *aux)
@@ -3690,6 +3884,10 @@ static inline int bpf_prog_dev_bound_inherit(struct bpf_prog *new_prog,
return -EOPNOTSUPP;
}
+static inline void bpf_prog_dev_bound_moved(struct bpf_prog *prog)
+{
+}
+
static inline void bpf_dev_bound_netdev_unregister(struct net_device *dev)
{
}
@@ -3820,6 +4018,8 @@ struct bpf_key {
#if defined(CONFIG_KEYS) && defined(CONFIG_BPF_SYSCALL)
struct bpf_key *bpf_lookup_user_key(s32 serial, u64 flags);
struct bpf_key *bpf_lookup_system_key(u64 id);
+struct bpf_key *bpf_lookup_keyring(void);
+bool bpf_keyring_enforced(void);
void bpf_key_put(struct bpf_key *bkey);
int bpf_verify_pkcs7_signature(const struct bpf_dynptr *data_p,
const struct bpf_dynptr *sig_p,
@@ -3840,6 +4040,16 @@ static inline struct bpf_key *bpf_lookup_system_key(u64 id)
return NULL;
}
+static inline struct bpf_key *bpf_lookup_keyring(void)
+{
+ return NULL;
+}
+
+static inline bool bpf_keyring_enforced(void)
+{
+ return false;
+}
+
static inline void bpf_key_put(struct bpf_key *bkey)
{
}
@@ -4100,9 +4310,10 @@ void bpf_bprintf_cleanup(struct bpf_bprintf_data *data);
int bpf_try_get_buffers(struct bpf_bprintf_buffers **bufs);
void bpf_put_buffers(void);
-void bpf_prog_stream_init(struct bpf_prog *prog);
+int bpf_prog_stream_init(struct bpf_prog *prog, gfp_t gfp_extra_flags);
void bpf_prog_stream_free(struct bpf_prog *prog);
-int bpf_prog_stream_read(struct bpf_prog *prog, enum bpf_stream_id stream_id, void __user *buf, int len);
+int bpf_prog_stream_read(struct bpf_prog *prog, enum bpf_stream_id stream_id, void __user *buf, u32 len);
+int bpf_prog_stream_new_fd(struct bpf_prog *prog, enum bpf_stream_id stream_id, u32 flags);
void bpf_stream_stage_init(struct bpf_stream_stage *ss);
void bpf_stream_stage_free(struct bpf_stream_stage *ss);
__printf(2, 3)
@@ -4165,7 +4376,7 @@ struct bpf_prog *bpf_prog_find_from_stack(void);
int bpf_insn_array_init(struct bpf_map *map, const struct bpf_prog *prog);
int bpf_insn_array_ready(struct bpf_map *map);
void bpf_insn_array_release(struct bpf_map *map);
-void bpf_insn_array_adjust(struct bpf_map *map, u32 off, u32 len);
+void bpf_insn_array_adjust(struct bpf_map *map, u32 first, u32 len);
void bpf_insn_array_adjust_after_remove(struct bpf_map *map, u32 off, u32 len);
#ifdef CONFIG_BPF_SYSCALL
@@ -4190,6 +4401,9 @@ static inline bool bpf_map_is_percpu_map(enum bpf_map_type map_type)
}
}
+#define BPF_EXIST_FLAGS (BPF_EXIST | BPF_NOEXIST)
+#define BPF_CPU_FLAGS (BPF_F_CPU | BPF_F_ALL_CPUS)
+
static inline int bpf_map_check_op_flags(struct bpf_map *map, u64 flags, u64 allowed_flags)
{
u32 cpu;
diff --git a/include/linux/bpf_compiler_types.h b/include/linux/bpf_compiler_types.h
new file mode 100644
index 000000000000..5c9e71acfdac
--- /dev/null
+++ b/include/linux/bpf_compiler_types.h
@@ -0,0 +1,21 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef __LINUX_BPF_COMPILER_TYPES_H
+#define __LINUX_BPF_COMPILER_TYPES_H
+
+#include <linux/compiler_types.h>
+
+/*
+ * Qualifiers for the BPF verifier rather than address spaces: __arena marks a
+ * pointer into a BPF arena, __nullable a pointer that may be NULL. They reach
+ * BPF programs as BTF type tags on the members of kernel structs shared with
+ * them; to kernel code and to sparse the pointers are ordinary.
+ */
+#ifdef __CHECKER__
+# define __arena
+# define __nullable
+#else
+# define __arena BTF_TYPE_TAG(arena)
+# define __nullable BTF_TYPE_TAG(nullable)
+#endif
+
+#endif /* __LINUX_BPF_COMPILER_TYPES_H */
diff --git a/include/linux/bpf_crypto.h b/include/linux/bpf_crypto.h
deleted file mode 100644
index a41e71d4e2d9..000000000000
--- a/include/linux/bpf_crypto.h
+++ /dev/null
@@ -1,24 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-only */
-/* Copyright (c) 2024 Meta Platforms, Inc. and affiliates. */
-#ifndef _BPF_CRYPTO_H
-#define _BPF_CRYPTO_H
-
-struct bpf_crypto_type {
- void *(*alloc_tfm)(const char *algo);
- void (*free_tfm)(void *tfm);
- int (*has_algo)(const char *algo);
- int (*setkey)(void *tfm, const u8 *key, unsigned int keylen);
- int (*setauthsize)(void *tfm, unsigned int authsize);
- int (*encrypt)(void *tfm, const u8 *src, u8 *dst, unsigned int len, u8 *iv);
- int (*decrypt)(void *tfm, const u8 *src, u8 *dst, unsigned int len, u8 *iv);
- unsigned int (*ivsize)(void *tfm);
- unsigned int (*statesize)(void *tfm);
- u32 (*get_flags)(void *tfm);
- struct module *owner;
- char name[14];
-};
-
-int bpf_crypto_register_type(const struct bpf_crypto_type *type);
-int bpf_crypto_unregister_type(const struct bpf_crypto_type *type);
-
-#endif /* _BPF_CRYPTO_H */
diff --git a/include/linux/bpf_local_storage.h b/include/linux/bpf_local_storage.h
index 9e4f5c45c974..6c643ac51079 100644
--- a/include/linux/bpf_local_storage.h
+++ b/include/linux/bpf_local_storage.h
@@ -104,6 +104,19 @@ struct bpf_local_storage {
refcount_t owner_refcnt;/* Used to pin owner when map_free is uncharging */
};
+/*
+ * Drop a reference got by refcount_inc_not_zero(&local_storage->owner_refcnt).
+ * bpf_local_storage_destroy() may have dropped the owner's reference meanwhile
+ * and wait for the count to reach zero, so this one can be the last.
+ */
+static inline void
+bpf_local_storage_unpin_owner(struct bpf_local_storage *local_storage)
+{
+ bool last __maybe_unused;
+
+ last = refcount_dec_and_test(&local_storage->owner_refcnt);
+}
+
/* U16_MAX is much more than enough for sk local storage
* considering a tcp_sock is ~2k.
*/
diff --git a/include/linux/bpf_lsm.h b/include/linux/bpf_lsm.h
index dda272d78f01..eb4a38eef87e 100644
--- a/include/linux/bpf_lsm.h
+++ b/include/linux/bpf_lsm.h
@@ -21,6 +21,13 @@ extern bool bpf_lsm_initialized __ro_after_init;
#include <linux/lsm_hook_defs.h>
#undef LSM_HOOK
+/*
+ * Number of xattr slots the BPF LSM reserves in the array handed to
+ * security_inode_init_security(), i.e. the maximum number of labels
+ * a policy may attach to an inode while it is being created.
+ */
+#define BPF_LSM_INODE_INIT_XATTRS 2
+
struct bpf_storage_blob {
struct bpf_local_storage __rcu *storage;
};
@@ -28,7 +35,7 @@ struct bpf_storage_blob {
extern struct lsm_blob_sizes bpf_lsm_blob_sizes;
int bpf_lsm_verify_prog(struct bpf_verifier_log *vlog,
- const struct bpf_prog *prog);
+ struct bpf_prog *prog);
bool bpf_lsm_is_sleepable_hook(u32 btf_id);
bool bpf_lsm_is_trusted(const struct bpf_prog *prog);
@@ -71,7 +78,7 @@ static inline bool bpf_lsm_is_trusted(const struct bpf_prog *prog)
}
static inline int bpf_lsm_verify_prog(struct bpf_verifier_log *vlog,
- const struct bpf_prog *prog)
+ struct bpf_prog *prog)
{
return -EOPNOTSUPP;
}
diff --git a/include/linux/bpf_verifier.h b/include/linux/bpf_verifier.h
index 36b65797877d..5926f13ff43c 100644
--- a/include/linux/bpf_verifier.h
+++ b/include/linux/bpf_verifier.h
@@ -9,6 +9,20 @@
#include <linux/filter.h> /* for MAX_BPF_STACK */
#include <linux/tnum.h>
#include <linux/cnum.h>
+#include <linux/math64.h> /* for div_s64_rem() */
+
+/*
+ * Mathematical modulo, the residue of 'v' modulo 'step', normalized to [0, step).
+ * This differs from C's '%' operator, which truncates the quotient toward zero
+ * and so returns a remainder with the sign of the dividend (e.g. -1 % 3 == -1, not 2).
+ */
+static inline u16 imod(s64 v, u16 step)
+{
+ s32 rem;
+
+ div_s64_rem(v, step, &rem);
+ return rem < 0 ? rem + step : rem;
+}
/* Maximum variable offset umax_value permitted when resolving memory accesses.
* In practice this is far bigger than any realistic pointer offset; this limit
@@ -19,11 +33,12 @@
* that converting umax_value to int cannot overflow.
*/
#define BPF_MAX_VAR_SIZ (1 << 29)
-/* size of tmp_str_buf in bpf_verifier.
- * we need at least 306 bytes to fit full stack mask representation
- * (in the "-8,-16,...,-512" form)
+/*
+ * size of tmp_str_buf in bpf_verifier.
+ * we need at least 1399 bytes to fit full stack mask representation
+ * (in the "-8,-16,...,-2048" form)
*/
-#define TMP_STR_BUF_LEN 320
+#define TMP_STR_BUF_LEN 1408
/* Patch buffer size */
#define INSN_BUF_SIZE 32
@@ -45,18 +60,20 @@ struct bpf_reg_state {
union {
/* valid when type == PTR_TO_PACKET */
int range;
+ /*
+ * Valid when type == PTR_TO_STACK. Inside the callee two registers
+ * can be both PTR_TO_STACK like R1=fp-8 and R2=fp-8, but one of them
+ * points to this function stack while another to the caller's stack.
+ * To differentiate them 'frameno' is used which is an index in
+ * bpf_verifier_state->frame[] array pointing to bpf_func_state.
+ */
+ u8 frameno;
- /* valid when type == CONST_PTR_TO_MAP | PTR_TO_MAP_VALUE |
- * PTR_TO_MAP_VALUE_OR_NULL
+ /*
+ * For CONST_PTR_TO_MAP, PTR_TO_MAP_KEY, PTR_TO_MAP_VALUE and
+ * PTR_TO_INSN.
*/
- struct {
- struct bpf_map *map_ptr;
- /* To distinguish map lookups from outer map
- * the map_uid is non-zero for registers
- * pointing to inner maps.
- */
- u32 map_uid;
- };
+ struct bpf_map *map_ptr;
/* for PTR_TO_BTF_ID */
struct {
@@ -122,6 +139,13 @@ struct bpf_reg_state {
*/
struct cnum64 r64; /* 64-bit range as circular number */
struct cnum32 r32; /* 32-bit range as circular number */
+ /*
+ * The value described by this register, interpreted as s64, lies on
+ * a line described by a linear equation base + step * k.
+ * Invariant: base < step.
+ */
+ u16 base;
+ u16 step;
/* For PTR_TO_PACKET, used to find other pointers with the same variable
* offset, so they can share range knowledge.
* For PTR_TO_MAP_VALUE_OR_NULL this is used to share which map value we
@@ -155,15 +179,14 @@ struct bpf_reg_state {
* gets parent_id set to the dynptr's id.
*/
u32 parent_id;
- /* Inside the callee two registers can be both PTR_TO_STACK like
- * R1=fp-8 and R2=fp-8, but one of them points to this function stack
- * while another to the caller's stack. To differentiate them 'frameno'
- * is used which is an index in bpf_verifier_state->frame[] array
- * pointing to bpf_func_state.
+ /*
+ * Distinguishes inner-map lookups and their keys and values. Zero for
+ * other registers. Kept outside the metadata union for ID remapping
+ * during state comparisons.
*/
- u32 frameno;
+ u32 map_uid:31;
/* if (!precise && SCALAR_VALUE) min/max/tnum don't affect safety */
- bool precise;
+ u32 precise:1;
};
static inline s64 reg_smin(const struct bpf_reg_state *reg)
@@ -242,55 +265,18 @@ enum bpf_stack_slot_type {
#define BPF_REG_SIZE 8 /* size of eBPF register in bytes */
+/*
+ * Largest number of BPF_REG_SIZE stack slots a single frame can have, sized
+ * for the largest stack budget any JIT supports. A frame may use any part of
+ * its program's budget; check_max_stack_depth() enforces the budget on the
+ * combined depth of frames sharing the kernel stack and on each frame using
+ * a private stack.
+ */
+#define MAX_BPF_STACK_SLOTS (MAX_BPF_STACK_JIT / BPF_REG_SIZE)
+
/* 4-byte stack slot granularity for liveness analysis */
#define BPF_HALF_REG_SIZE 4
#define STACK_SLOT_SZ 4
-#define STACK_SLOTS (MAX_BPF_STACK / BPF_HALF_REG_SIZE) /* 128 */
-
-typedef struct {
- u64 v[2];
-} spis_t;
-
-#define SPIS_ZERO ((spis_t){})
-#define SPIS_ALL ((spis_t){{ U64_MAX, U64_MAX }})
-
-static inline bool spis_is_zero(spis_t s)
-{
- return s.v[0] == 0 && s.v[1] == 0;
-}
-
-static inline bool spis_equal(spis_t a, spis_t b)
-{
- return a.v[0] == b.v[0] && a.v[1] == b.v[1];
-}
-
-static inline spis_t spis_or(spis_t a, spis_t b)
-{
- return (spis_t){{ a.v[0] | b.v[0], a.v[1] | b.v[1] }};
-}
-
-static inline spis_t spis_and(spis_t a, spis_t b)
-{
- return (spis_t){{ a.v[0] & b.v[0], a.v[1] & b.v[1] }};
-}
-
-static inline spis_t spis_not(spis_t s)
-{
- return (spis_t){{ ~s.v[0], ~s.v[1] }};
-}
-
-static inline bool spis_test_bit(spis_t s, u32 slot)
-{
- return s.v[slot / 64] & BIT_ULL(slot % 64);
-}
-
-static inline void spis_or_range(spis_t *mask, u32 lo, u32 hi)
-{
- u32 w;
-
- for (w = lo; w <= hi && w < STACK_SLOTS; w++)
- mask->v[w / 64] |= BIT_ULL(w % 64);
-}
#define BPF_REGMASK_ARGS ((1 << BPF_REG_1) | (1 << BPF_REG_2) | \
(1 << BPF_REG_3) | (1 << BPF_REG_4) | \
@@ -342,6 +328,25 @@ struct bpf_retval_range {
bool return_32bit;
};
+/* SCEV/widening register space: r0..r10 plus every stack slot of a frame. */
+#define BPF_SCEV_REGS_NUM (MAX_BPF_REG + MAX_BPF_STACK_SLOTS)
+
+struct bpf_loop_iters {
+ u32 min_header_count; /* min number of times header is executed */
+ u32 max_header_count; /* max number of times header is executed */
+ unsigned long precise_regs[BITS_TO_LONGS(BPF_SCEV_REGS_NUM)];
+};
+
+struct loop_stack_entry {
+ struct bpf_verifier_state *entry_state;
+ u32 min_header_count;
+ u32 max_header_count;
+ u32 loop_id:31;
+ u32 terminates:1;
+};
+
+#define LOOP_STACK_SIZE 16
+
/* state of the program:
* type of all registers and stack info
*/
@@ -374,6 +379,11 @@ struct bpf_func_state {
bool in_async_callback_fn;
bool in_exception_callback_fn;
bool no_stack_arg_load;
+ /*
+ * The helper invokes this callback under rcu_read_lock(), so the
+ * callback and its callees run in an RCU read-side critical section.
+ */
+ bool in_rcu_callback_fn;
/* For callback calling functions that limit number of possible
* callback executions (e.g. bpf_loop) keeps track of current
* simulated iteration number.
@@ -387,6 +397,11 @@ struct bpf_func_state {
u32 callback_depth;
/* Instructions processed in this frame and callees on the current path. */
u32 insns_subtotal;
+ /*
+ * Control-flow loop nesting at the current insn within this frame's
+ * subprogram (loops never cross subprogram boundaries).
+ */
+ u32 loop_stack_cnt;
/* The following fields should be last. See copy_func_state() */
/* The state of the stack. Each element of the array describes BPF_REG_SIZE
@@ -404,6 +419,7 @@ struct bpf_func_state {
u16 out_stack_arg_cnt; /* Number of outgoing on-stack argument slots */
struct bpf_reg_state *stack_arg_regs; /* Outgoing on-stack arguments */
+ struct loop_stack_entry *loop_stack;
};
#define MAX_CALL_FRAMES 16
@@ -420,30 +436,37 @@ enum {
INSN_F_STACK_ARG_ACCESS = BIT(3),
};
+/* Registers linked to one jump condition that a history entry can record */
+#define BPF_LINKED_REGS_MAX 5
+
struct bpf_jmp_history_entry {
/* insn idx can't be bigger than 1 million */
u32 idx : 20;
u32 frame : 4; /* stack access frame number */
- u32 spi : 6; /* stack slot index (0..63) */
- u32 : 2;
- u32 prev_idx : 20;
/* special INSN_F_xxx flags */
u32 flags : 4;
- u32 : 8;
+ u32 : 4;
+ u32 prev_idx : 20;
+ u32 spi : 12; /* stack slot index */
/*
- * additional registers that need precision tracking when this
- * jump is backtracked, vector of five 11-bit records
+ * Scalar registers and spilled scalars linked to the condition of
+ * this jump, which need precision tracking together when the jump is
+ * backtracked. Each is packed as 4 bits of frame number, one bit
+ * telling a register from a stack slot and 11 bits of register or
+ * slot index, see linked_regs_pack().
*/
- u64 linked_regs;
+ u16 linked_regs[BPF_LINKED_REGS_MAX];
+ u8 linked_regs_cnt;
};
static_assert(MAX_CALL_FRAMES <= (1 << 4));
-static_assert(MAX_BPF_STACK / 8 <= (1 << 6));
+static_assert(MAX_BPF_STACK_SLOTS <= (1 << 12));
/* Maximum number of bpf_reg_state objects that can exist at once */
#define MAX_STACK_ARG_SLOTS (MAX_BPF_FUNC_ARGS - MAX_BPF_FUNC_REG_ARGS)
-#define BPF_ID_MAP_SIZE ((MAX_BPF_REG + MAX_BPF_STACK / BPF_REG_SIZE + \
- MAX_STACK_ARG_SLOTS) * MAX_CALL_FRAMES)
+#define BPF_ID_MAP_SIZE ((MAX_BPF_REG + MAX_BPF_STACK_SLOTS + MAX_STACK_ARG_SLOTS) * \
+ MAX_CALL_FRAMES)
+
struct bpf_verifier_state {
/* call stack tracking */
struct bpf_func_state *frame[MAX_CALL_FRAMES];
@@ -509,8 +532,13 @@ struct bpf_verifier_state {
bool speculative;
bool in_sleepable;
+ /* The callee left with unwind_exit. Next insn is unwind_goto. */
+ bool unwound;
- /* first and last insn idx of this verifier state */
+ /*
+ * First and last insn idx of this verifier state.
+ * last_insn_idx is -1 if no instructions have been executed yet.
+ */
u32 first_insn_idx;
u32 last_insn_idx;
/* if this state is a backedge state then equal_state
@@ -529,12 +557,31 @@ struct bpf_verifier_state {
u32 may_goto_depth;
};
+/* Number of BPF_REG_SIZE stack slots tracked for the frame so far. */
+static inline u32 bpf_stack_nr_slots(const struct bpf_func_state *frame)
+{
+ return frame->allocated_stack / BPF_REG_SIZE;
+}
+
+/*
+ * Stack slot @spi of @frame, covering bytes [fp - (spi + 1) * 8, fp - spi * 8).
+ * The caller must ensure spi < bpf_stack_nr_slots(frame), see bpf_grow_stack_state().
+ */
+static inline struct bpf_stack_state *bpf_stack_slot(const struct bpf_func_state *frame, u32 spi)
+{
+ return &frame->stack[spi];
+}
+
static inline struct bpf_reg_state *
bpf_get_spilled_reg(int slot, struct bpf_func_state *frame, u32 mask)
{
- if (slot < frame->allocated_stack / BPF_REG_SIZE &&
- (1 << frame->stack[slot].slot_type[BPF_REG_SIZE - 1]) & mask)
- return &frame->stack[slot].spilled_ptr;
+ struct bpf_stack_state *ss;
+
+ if (slot >= bpf_stack_nr_slots(frame))
+ return NULL;
+ ss = bpf_stack_slot(frame, slot);
+ if ((1 << ss->slot_type[BPF_REG_SIZE - 1]) & mask)
+ return &ss->spilled_ptr;
return NULL;
}
@@ -550,7 +597,7 @@ bpf_get_spilled_stack_arg(int slot, struct bpf_func_state *frame)
/* Iterate over 'frame', setting 'reg' to either NULL or a spilled register. */
#define bpf_for_each_spilled_reg(iter, frame, reg, mask) \
for (iter = 0, reg = bpf_get_spilled_reg(iter, frame, mask); \
- iter < frame->allocated_stack / BPF_REG_SIZE; \
+ iter < bpf_stack_nr_slots(frame); \
iter++, reg = bpf_get_spilled_reg(iter, frame, mask))
/* Iterate over 'frame', setting 'reg' to either NULL or a spilled stack arg. */
@@ -575,7 +622,7 @@ bpf_get_spilled_stack_arg(int slot, struct bpf_func_state *frame)
bpf_for_each_spilled_reg(___j, __state, __reg, __mask) { \
if (!__reg) \
continue; \
- __stack = &__state->stack[___j]; \
+ __stack = bpf_stack_slot(__state, ___j); \
(void)(__expr); \
} \
__stack = NULL; \
@@ -639,6 +686,52 @@ struct bpf_iarray {
u32 items[];
};
+#define iarray_for_each(item, arr) \
+ for (int ___idx = 0; \
+ ___idx < (arr)->cnt && ({ item = (arr)->items[___idx]; 1; }); \
+ ___idx++)
+
+#define MAX_BACKEDGES 16
+#define MAX_LOOP_EXITS 256
+
+/* Number of exit conditions dominating a backedge. */
+#define MAX_LATCHES 4
+
+struct bpf_backedge {
+ int from;
+ /*
+ * Conditional jumps within the loop that dominate 'from' and have
+ * a successor outside the loop, nearest first. latches[0] is the
+ * latch; the remaining entries are additional exit conditions.
+ * Each usable condition gives an upper bound on the iteration count,
+ * so keeping only a subset is sound.
+ */
+ int latches[MAX_LATCHES];
+ u8 latches_cnt;
+};
+
+struct bpf_loop_exit {
+ int from; /* instruction inside the loop */
+ int to; /* instruction outside the loop */
+};
+
+struct bpf_loop {
+ struct bpf_backedge backedges[MAX_BACKEDGES];
+ /* edges exiting from this loop, includes edges from nested loops */
+ struct bpf_loop_exit *exits;
+ int backedges_cnt;
+ int exits_cnt;
+ bool irreducible;
+ bool backedges_overflow;
+ bool exits_overflow;
+ /*
+ * Loop-entry registers used to compute stack addresses for loads,
+ * stores and calls requiring fixed stack offsets, in this and nested
+ * loops.
+ */
+ unsigned long store_base_regs[BITS_TO_LONGS(BPF_SCEV_REGS_NUM)];
+};
+
struct bpf_insn_aux_data {
union {
enum bpf_reg_type ptr_type; /* pointer type for load/store insns */
@@ -670,44 +763,64 @@ struct bpf_insn_aux_data {
/* remember the offset of node field within type to rewrite */
u64 insert_off;
};
- struct bpf_iarray *jt; /* jump table for gotox or bpf_tailcall call instruction */
struct btf_struct_meta *kptr_struct_meta;
u64 map_key_state; /* constant (32 bit) key tracking for maps */
+ /*
+ * Per-instruction summary of stack slots in the current frame
+ * that this instruction may write to.
+ */
+ DECLARE_BITMAP(may_write_mask, MAX_BPF_STACK_SLOTS);
+ DECLARE_BITMAP(live_stack_before, MAX_BPF_STACK_SLOTS);
+ u16 stack_ptrs; /* bitmask of regs that may hold a frame pointer here (arg_track) */
int ctx_field_size; /* the ctx field size for load insn, maybe 0 */
u32 seen; /* this insn was processed by the verifier at env->pass_cnt */
- bool nospec; /* do not execute this instruction speculatively */
- bool nospec_result; /* result is unsafe under speculation, nospec must follow */
- bool zext_dst; /* this insn zero extends dst reg */
- bool needs_zext; /* alu op needs to clear upper bits */
- bool non_sleepable; /* helper/kfunc may be called from non-sleepable context */
- bool is_iter_next; /* bpf_iter_<type>_next() kfunc call */
- bool call_with_percpu_alloc_ptr; /* {this,per}_cpu_ptr() with prog percpu alloc */
- u8 alu_state; /* used in combination with alu_limit */
+ u64 nospec:1; /* do not execute this instruction speculatively */
+ u64 nospec_result:1; /* result is unsafe under speculation, nospec must follow */
+ u64 zext_dst:1; /* this insn zero extends dst reg */
+ u64 needs_zext:1; /* alu op needs to clear upper bits */
+ u64 prevent_zext:1; /* alu op cannot be zext (already used with 64-bit scalars) */
+ u64 non_sleepable:1; /* helper/kfunc may be called from non-sleepable context */
+ u64 is_iter_next:1; /* bpf_iter_<type>_next() kfunc call */
+ u64 call_with_percpu_alloc_ptr:1; /* {this,per}_cpu_ptr() with prog percpu alloc */
+ u64 arena_scalar:1; /* ldx/stx/st/atomic through a number, it's an address in arena */
+ u64 bb_end:1; /* last instruction of a basic block */
+ u64 need_scev:1;
+ u64 alu_state:5; /* used in combination with alu_limit */
/* true if STX or LDX instruction is a part of a spill/fill
* pattern for a bpf_fastcall call.
*/
- u8 fastcall_pattern:1;
+ u64 fastcall_pattern:1;
/* for CALL instructions, a number of spill/fill pairs in the
* bpf_fastcall pattern.
*/
- u8 fastcall_spills_num:3;
- u8 arg_prog:4;
+ u64 fastcall_spills_num:3;
+ u64 arg_prog:4;
+ /*
+ * What a load found, on any path: an __arena pointer member of a
+ * kernel struct, which arena_member_fixup() rewrites, one that is
+ * __nullable as well, or anything else through any pointer.
+ */
+ u64 arena_member:1;
+ u64 arena_member_nullable:1;
+ u64 non_arena_load:1;
- /* below fields are initialized once */
- unsigned int orig_idx; /* original instruction index */
- u32 jmp_point:1;
- u32 prune_point:1;
+ /* below flags are initialized once */
+ u64 jmp_point:1;
+ u64 prune_point:1;
/* ensure we check state equivalence and save state checkpoint and
* this instruction, regardless of any heuristics
*/
- u32 force_checkpoint:1;
+ u64 force_checkpoint:1;
/* true if instruction is a call to a helper function that
* accepts callback function as a parameter.
*/
- u32 calls_callback:1;
- u32 indirect_target:1; /* if it is an indirect jump target */
+ u64 calls_callback:1;
+ u64 indirect_target:1; /* if it is an indirect jump target */
+ u64 non_stack_access:1; /* instruction can access non-stack memory */
/* true if some jump or call instruction targets this instruction */
- u32 jump_target:1;
+ u64 jump_target:1;
+
+ unsigned int orig_idx; /* original instruction index, initialized once */
/*
* CFG strongly connected component this instruction belongs to,
* zero if it is a singleton SCC.
@@ -727,12 +840,23 @@ struct bpf_insn_aux_data {
u16 const_reg_map_mask;
u16 const_reg_subprog_mask;
u32 const_reg_vals[10];
+ /*
+ * Header index of the innermost loop containing this instruction, -1 if none.
+ * For a loop header, identifies the parent loop instead.
+ */
+ s32 loop_header;
+ /* additional information about the loop if this instruction is a loop header */
+ struct bpf_loop *loop;
};
#define MAX_USED_MAPS 64 /* max number of maps accessed by one eBPF program */
#define MAX_USED_BTFS 64 /* max number of BTFs accessed by one BPF program */
-#define BPF_VERIFIER_TMP_LOG_SIZE 1024
+/*
+ * Longest line the verifier log can carry: a full stack mask of
+ * MAX_BPF_STACK_SLOTS slots, see TMP_STR_BUF_LEN, plus its prefix.
+ */
+#define BPF_VERIFIER_TMP_LOG_SIZE 2048
struct bpf_verifier_log {
/* Logical start and end positions of a "log window" of the verifier log.
@@ -785,6 +909,21 @@ int bpf_log_attr_finalize(struct bpf_log_attr *attr, struct bpf_verifier_log *lo
#define BPF_MAX_SUBPROGS 256
+/*
+ * A pointer to a static subprog in the value of a frozen read-only array map:
+ * a 64-bit value that is the offset in bytes of the first instruction of
+ * the subprog in the program.
+ */
+struct bpf_func_ptr {
+ struct bpf_map *map;
+ u32 map_off; /* offset of the pointer in the value of the map */
+ u32 orig_off; /* what the map has: the first instruction of the subprog */
+ u32 xlated_off; /* the same after instructions were patched and removed */
+};
+
+/* the subprog that a bpf_func_ptr pointed to was removed as dead code */
+#define BPF_FUNC_PTR_DELETED ((u32)-1)
+
struct bpf_subprog_arg_info {
enum bpf_arg_type arg_type;
union {
@@ -804,7 +943,12 @@ struct bpf_subprog_info {
u32 start; /* insn idx of function entry point */
u32 linfo_idx; /* The idx to the main_prog->aux->linfo */
u32 postorder_start; /* The idx to the env->cfg.insn_postorder */
- u32 exit_idx; /* Index of one of the BPF_EXIT instructions in this subprogram */
+ /*
+ * Index of one of the BPF_EXIT instructions in this subprogram, or
+ * U32_MAX when it has none.
+ */
+ u32 exit_idx;
+ struct bpf_iarray *jt; /* jump table shared by all gotox of this subprogram */
u16 stack_depth; /* max. stack depth used by this function */
u16 stack_extra;
u32 insns_total;
@@ -815,17 +959,20 @@ struct bpf_subprog_info {
s16 fastcall_stack_off;
bool has_tail_call: 1;
bool might_throw: 1;
+ bool can_unwind: 1; /* has unwind_exit */
bool tail_call_reachable: 1;
bool has_ld_abs: 1;
bool is_cb: 1;
bool is_async_cb: 1;
bool is_exception_cb: 1;
bool args_cached: 1;
+ /* true if the return value is passed in the R0:R2 register pair */
+ bool ret_reg_pair: 1;
/* true if bpf_fastcall stack region is used by functions that can't be inlined */
bool keep_fastcall_stack: 1;
bool changes_pkt_data: 1;
bool might_sleep: 1;
- u8 arg_cnt:4;
+ u8 arg_slot_cnt:4;
enum priv_stack_mode priv_stack_mode;
struct bpf_subprog_arg_info args[MAX_BPF_FUNC_ARGS];
@@ -835,8 +982,8 @@ struct bpf_subprog_info {
static inline u16 bpf_in_stack_arg_cnt(const struct bpf_subprog_info *sub)
{
- if (sub->arg_cnt > MAX_BPF_FUNC_REG_ARGS)
- return sub->arg_cnt - MAX_BPF_FUNC_REG_ARGS;
+ if (sub->arg_slot_cnt > MAX_BPF_FUNC_REG_ARGS)
+ return sub->arg_slot_cnt - MAX_BPF_FUNC_REG_ARGS;
return 0;
}
@@ -847,7 +994,7 @@ struct backtrack_state {
struct bpf_verifier_env *env;
u32 frame;
u32 reg_masks[MAX_CALL_FRAMES];
- u64 stack_masks[MAX_CALL_FRAMES];
+ unsigned long stack_masks[MAX_CALL_FRAMES][BITS_TO_LONGS(MAX_BPF_STACK_SLOTS)];
u8 stack_arg_masks[MAX_CALL_FRAMES];
};
@@ -903,6 +1050,7 @@ struct bpf_scc_info {
};
struct bpf_liveness;
+struct scev;
struct bpf_fd_array {
union {
@@ -926,6 +1074,7 @@ struct bpf_verifier_env {
bool strict_alignment; /* perform strict pointer alignment checks */
bool test_state_freq; /* test verifier with different pruning frequency */
bool test_reg_invariants; /* fail verification on register invariants violations */
+ bool arena_scalar; /* load and store through a number is arena access */
struct bpf_verifier_state *cur_state; /* current verifier state */
/* Search pruning optimization, array of list_heads for
* lists of struct bpf_verifier_state_list.
@@ -952,6 +1101,8 @@ struct bpf_verifier_env {
bool bypass_spec_v1;
bool bypass_spec_v4;
bool seen_direct_write;
+ /* a global function is verified for BPF_FUNC_CTX_NO_RCU_LOCK */
+ bool no_rcu_read_lock;
bool seen_exception;
bool signature;
u32 insn_aux_data_len;
@@ -959,9 +1110,24 @@ struct bpf_verifier_env {
const struct bpf_line_info *prev_linfo;
struct bpf_verifier_log log;
struct bpf_diag *diag;
+ struct bpf_func_proto bpf_subprog_scratch;
struct bpf_subprog_info subprog_info[BPF_MAX_SUBPROGS + 2]; /* max + 2 for the fake and exception subprogs */
/* subprog indices sorted in topological order: leaves first, callers last */
int subprog_topo_order[BPF_MAX_SUBPROGS + 2];
+ /*
+ * Pointers to static subprogs found in frozen read-only maps of the
+ * program, see resolve_func_ptrs(). Sorted by map and map_off.
+ */
+ struct bpf_func_ptr *func_ptrs;
+ u32 func_ptr_cnt;
+ bool has_callx;
+ /*
+ * Call graph edges created by callx instructions. A bitmap of
+ * subprog_cnt * subprog_cnt bits, where bit (caller * subprog_cnt + callee)
+ * is set when the main verification pass sees 'caller' calling 'callee'
+ * via callx. Allocated when the first such edge is recorded.
+ */
+ unsigned long *callx_edges;
union {
struct bpf_idmap idmap_scratch;
struct bpf_idset idset_scratch;
@@ -974,14 +1140,17 @@ struct bpf_verifier_env {
* see bpf_subprog_info->postorder_start.
*/
int *insn_postorder;
+ int *postorder_nums;
int cur_stack;
/* current position in the insn_postorder vector */
int cur_postorder;
+ u32 gotox_edges;
+ bool subprog_jts_ready;
} cfg;
struct backtrack_state bt;
struct bpf_jmp_history_entry *cur_hist_ent;
- /* Per-callsite copy of parent's converged at_stack_in for cross-frame fills. */
- struct arg_track **callsite_at_stack;
+ /* Per-callsite snapshot of the parent's tracked spill slots for cross-frame fills. */
+ struct spill_snapshot **callsite_at_stack;
u32 pass_cnt; /* number of times do_check() was called */
u32 subprog_cnt;
/* number of instructions analyzed by the verifier */
@@ -990,6 +1159,8 @@ struct bpf_verifier_env {
u32 prev_jmps_processed, jmps_processed;
/* maximum combined stack depth */
u32 max_stack_depth;
+ /* stack budget of the program, see bpf_prog_stack_limit() */
+ u32 stack_limit;
/* total verification time */
u64 verification_time;
/* maximum number of verifier states kept in 'branching' instructions */
@@ -1025,7 +1196,7 @@ struct bpf_verifier_env {
*/
u32 scratched_regs;
/* Same as scratched_regs but for stack slots */
- u64 scratched_stack_slots;
+ DECLARE_BITMAP(scratched_stack_slots, MAX_BPF_STACK_SLOTS);
u64 prev_log_pos, prev_insn_print_pos;
/* buffer used to temporary hold constants as scalar registers */
struct bpf_reg_state fake_reg[1];
@@ -1045,6 +1216,8 @@ struct bpf_verifier_env {
u32 scc_cnt;
struct bpf_iarray *succ;
struct bpf_iarray *gotox_tmp_buf;
+ int *idoms;
+ struct scev *scev;
};
static inline struct bpf_func_info_aux *subprog_aux(struct bpf_verifier_env *env, int subprog)
@@ -1057,8 +1230,13 @@ static inline struct bpf_subprog_info *subprog_info(struct bpf_verifier_env *env
return &env->subprog_info[subprog];
}
+static inline bool bpf_ret_reg_pair(struct bpf_verifier_env *env, int subprog)
+{
+ return subprog_info(env, subprog)->ret_reg_pair;
+}
+
struct bpf_call_summary {
- u8 num_params;
+ u8 arg_slot_cnt;
bool is_void;
bool fastcall;
};
@@ -1081,6 +1259,12 @@ static inline bool bpf_pseudo_kfunc_call(const struct bpf_insn *insn)
insn->src_reg == BPF_PSEUDO_KFUNC_CALL;
}
+/* callx: indirect call of a bpf subprog whose address is in insn->dst_reg */
+static inline bool bpf_is_callx(const struct bpf_insn *insn)
+{
+ return insn->code == (BPF_JMP | BPF_CALL | BPF_X);
+}
+
__printf(2, 0) void bpf_verifier_vlog(struct bpf_verifier_log *log,
const char *fmt, va_list args);
__printf(2, 3) void bpf_verifier_log_write(struct bpf_verifier_env *env,
@@ -1095,6 +1279,7 @@ int bpf_vlog_finalize(struct bpf_verifier_log *log, u32 *log_size_actual);
__printf(3, 4) void verbose_linfo(struct bpf_verifier_env *env,
u32 insn_off,
const char *prefix_fmt, ...);
+void bpf_verbose_snum(struct bpf_verifier_env *env, s64 num);
#define verifier_bug_if(cond, env, fmt, args...) \
({ \
@@ -1197,6 +1382,8 @@ static inline void bpf_trampoline_unpack_key(u64 key, u32 *obj_id, u32 *btf_id)
int bpf_prepare_btf_info(struct bpf_verifier_env *env,
const union bpf_attr *attr, bpfptr_t uattr);
+int bpf_check_core_relo(struct bpf_verifier_env *env,
+ const union bpf_attr *attr, bpfptr_t uattr);
int bpf_check_btf_info(struct bpf_verifier_env *env,
const union bpf_attr *attr, bpfptr_t uattr);
@@ -1205,11 +1392,14 @@ int bpf_check_attach_target(struct bpf_verifier_log *log,
const struct bpf_prog *tgt_prog,
u32 btf_id,
struct bpf_attach_target_info *tgt_info);
+int bpf_check_ext_prologue(struct bpf_verifier_log *log,
+ const struct bpf_prog *tgt_prog, u32 btf_id);
void bpf_free_kfunc_btf_tab(struct bpf_kfunc_btf_tab *tab);
int mark_chain_precision(struct bpf_verifier_env *env, int regno);
int bpf_is_state_visited(struct bpf_verifier_env *env, int insn_idx);
+int bpf_split_cur_state(struct bpf_verifier_env *env);
int bpf_update_branch_counts(struct bpf_verifier_env *env, struct bpf_verifier_state *st);
void bpf_clear_jmp_history(struct bpf_verifier_state *state);
@@ -1219,11 +1409,14 @@ struct list_head *bpf_explored_state(struct bpf_verifier_env *env, int idx);
void bpf_free_verifier_state(struct bpf_verifier_state *state, bool free_self);
void bpf_free_backedges(struct bpf_scc_visit *visit);
int bpf_push_jmp_history(struct bpf_verifier_env *env, struct bpf_verifier_state *cur,
- int insn_flags, int spi, int frame, u64 linked_regs);
+ int insn_flags, int spi, int frame, const u16 *linked_regs,
+ u8 linked_regs_cnt);
void bpf_bt_sync_linked_regs(struct backtrack_state *bt, struct bpf_jmp_history_entry *hist);
void bpf_mark_reg_not_init(const struct bpf_verifier_env *env,
struct bpf_reg_state *reg);
+void bpf_mark_reg_known_scalar(struct bpf_reg_state *reg, u64 imm);
void bpf_mark_reg_unknown_imprecise(struct bpf_reg_state *reg);
+int bpf_grow_stack_state(struct bpf_verifier_env *env, struct bpf_func_state *state, int size);
void bpf_mark_all_scalars_precise(struct bpf_verifier_env *env,
struct bpf_verifier_state *st);
void bpf_clear_singular_ids(struct bpf_verifier_env *env, struct bpf_verifier_state *st);
@@ -1236,11 +1429,36 @@ static inline int bpf_get_spi(s32 off)
return (-off - 1) / BPF_REG_SIZE;
}
+/*
+ * Stack a program may use in total: combined over the frames of a call
+ * chain on the kernel stack, or per frame on a private stack. Any single
+ * frame may reach that deep. Only a JIT that lays out such frames may go
+ * beyond MAX_BPF_STACK, the interpreter's frame size, and only one whose
+ * tail calls let the target set up its own frame: without subprogram
+ * tail calls, do_misc_fixups() gives every program with tail calls a
+ * MAX_BPF_STACK frame, which a deeper frame would overrun.
+ */
+static inline u32 bpf_prog_stack_limit(const struct bpf_prog *prog)
+{
+ /* an offloaded program never runs on the host JIT, whatever it supports */
+ if (prog->jit_requested && !bpf_prog_is_offloaded(prog->aux) &&
+ bpf_jit_supports_large_stack() && bpf_jit_supports_subprog_tailcalls())
+ return MAX_BPF_STACK_JIT;
+ return MAX_BPF_STACK;
+}
+
+/*
+ * Return the function state a stack pointer register refers to. frameno
+ * shares storage with other pointer metadata, so return NULL for any
+ * other register type instead of indexing frame[] with aliased bytes.
+ */
static inline struct bpf_func_state *bpf_func(struct bpf_verifier_env *env,
const struct bpf_reg_state *reg)
{
struct bpf_verifier_state *cur = env->cur_state;
+ if (reg->type != PTR_TO_STACK)
+ return NULL;
return cur->frame[reg->frameno];
}
@@ -1262,6 +1480,15 @@ static inline bool bpf_is_spilled_reg(const struct bpf_stack_state *stack)
return stack->slot_type[BPF_REG_SIZE - 1] == STACK_SPILL;
}
+static inline int bpf_spill_size(const struct bpf_stack_state *stack)
+{
+ int i, spill_size = 0;
+
+ for (i = BPF_REG_SIZE - 1; i >= 0 && stack->slot_type[i] == STACK_SPILL; i--)
+ spill_size++;
+ return spill_size;
+}
+
static inline bool bpf_is_spilled_scalar_reg(const struct bpf_stack_state *stack)
{
return bpf_is_spilled_reg(stack) && stack->spilled_ptr.type == SCALAR_VALUE;
@@ -1279,12 +1506,7 @@ static inline void bpf_bt_set_frame_reg(struct backtrack_state *bt, u32 frame, u
static inline void bpf_bt_set_frame_slot(struct backtrack_state *bt, u32 frame, u32 slot)
{
- bt->stack_masks[frame] |= 1ull << slot;
-}
-
-static inline void bpf_bt_set_frame_slot_mask(struct backtrack_state *bt, u32 frame, u64 mask)
-{
- bt->stack_masks[frame] |= mask;
+ __set_bit(slot, bt->stack_masks[frame]);
}
static inline void bt_set_frame_stack_arg_slot(struct backtrack_state *bt, u32 frame, u32 slot)
@@ -1299,10 +1521,17 @@ static inline bool bt_is_frame_reg_set(struct backtrack_state *bt, u32 frame, u3
static inline bool bt_is_frame_slot_set(struct backtrack_state *bt, u32 frame, u32 slot)
{
- return bt->stack_masks[frame] & (1ull << slot);
+ return test_bit(slot, bt->stack_masks[frame]);
}
bool bpf_map_is_rdonly(const struct bpf_map *map);
+struct bpf_func_ptr *bpf_map_func_ptrs(struct bpf_verifier_env *env,
+ const struct bpf_map *map, u32 *cnt);
+struct bpf_func_ptr *bpf_map_range_func_ptrs(struct bpf_verifier_env *env,
+ const struct bpf_map *map,
+ u64 off, u64 size, u32 *cnt);
+void bpf_adjust_func_ptrs(struct bpf_verifier_env *env, u32 off, u32 len);
+void bpf_adjust_func_ptrs_after_remove(struct bpf_verifier_env *env, u32 off, u32 len);
int bpf_map_direct_read(struct bpf_map *map, int off, int size, u64 *val,
bool is_ldsx);
@@ -1430,7 +1659,7 @@ static inline void mark_reg_scratched(struct bpf_verifier_env *env, u32 regno)
static inline void mark_stack_slot_scratched(struct bpf_verifier_env *env, u32 spi)
{
- env->scratched_stack_slots |= 1ULL << spi;
+ __set_bit(spi, env->scratched_stack_slots);
}
static inline bool reg_scratched(const struct bpf_verifier_env *env, u32 regno)
@@ -1438,27 +1667,28 @@ static inline bool reg_scratched(const struct bpf_verifier_env *env, u32 regno)
return (env->scratched_regs >> regno) & 1;
}
-static inline bool stack_slot_scratched(const struct bpf_verifier_env *env, u64 regno)
+static inline bool stack_slot_scratched(const struct bpf_verifier_env *env, u32 spi)
{
- return (env->scratched_stack_slots >> regno) & 1;
+ return test_bit(spi, env->scratched_stack_slots);
}
static inline bool verifier_state_scratched(const struct bpf_verifier_env *env)
{
- return env->scratched_regs || env->scratched_stack_slots;
+ return env->scratched_regs ||
+ !bitmap_empty(env->scratched_stack_slots, MAX_BPF_STACK_SLOTS);
}
static inline void mark_verifier_state_clean(struct bpf_verifier_env *env)
{
env->scratched_regs = 0U;
- env->scratched_stack_slots = 0ULL;
+ bitmap_zero(env->scratched_stack_slots, MAX_BPF_STACK_SLOTS);
}
/* Used for printing the entire verifier state. */
static inline void mark_verifier_state_scratched(struct bpf_verifier_env *env)
{
env->scratched_regs = ~0U;
- env->scratched_stack_slots = ~0ULL;
+ bitmap_fill(env->scratched_stack_slots, MAX_BPF_STACK_SLOTS);
}
static inline bool bpf_stack_narrow_access_ok(int off, int fill_size, int spill_size)
@@ -1493,14 +1723,25 @@ struct bpf_subprog_info *bpf_find_containing_subprog(struct bpf_verifier_env *en
const char *bpf_subprog_name(const struct bpf_verifier_env *env, int subprog);
int bpf_jmp_offset(struct bpf_insn *insn);
struct bpf_iarray *bpf_insn_successors(struct bpf_verifier_env *env, u32 idx);
-void bpf_fmt_stack_mask(char *buf, ssize_t buf_sz, u64 stack_mask);
+void bpf_fmt_stack_mask(char *buf, ssize_t buf_sz, const unsigned long *stack_mask);
bool bpf_subprog_is_global(const struct bpf_verifier_env *env, int subprog);
+/* Kinds of member a by-value struct or union may be composed of. */
+enum btf_member_kind {
+ BTF_MEMBER_SCALAR = BIT(0), /* an int or an enum */
+ BTF_MEMBER_ARENA_PTR = BIT(1), /* a pointer carrying the "arena" type tag */
+};
+
+bool btf_struct_is_composed_of(struct bpf_verifier_env *env, const struct btf *btf,
+ const struct btf_type *t, u32 member_kinds);
+u32 btf_func_arg_align(const struct btf *btf, const struct btf_type *t);
+
int bpf_find_subprog(struct bpf_verifier_env *env, int off);
bool bpf_is_throw_kfunc(struct bpf_insn *insn);
int bpf_compute_const_regs(struct bpf_verifier_env *env);
int bpf_prune_dead_branches(struct bpf_verifier_env *env);
int bpf_check_cfg(struct bpf_verifier_env *env);
+void bpf_free_subprog_jts(struct bpf_verifier_env *env);
int bpf_compute_postorder(struct bpf_verifier_env *env);
int bpf_compute_scc(struct bpf_verifier_env *env);
@@ -1529,12 +1770,15 @@ struct ref_obj_desc {
};
/*
- * A memory argument a call fills in. The verifier allows the stack to be uninitialized if
- * the range is a known constant. Stack slots are marked as STACK_MISC by check_mem_access().
+ * Generic MEM_UNINIT arguments, indexed by ABI slot. var_size_mask excludes
+ * variable-sized buffers from raw mode without losing the output annotation.
+ * size records constant ranges to mark initialized after checking all arguments,
+ * only when the caller is allowed to read uninitialized stack memory.
*/
struct arg_raw_mem_desc {
- u8 regno;
- int size;
+ u16 mask;
+ u16 var_size_mask;
+ int size[MAX_BPF_FUNC_ARGS];
};
/* Size of PTR_TO_MEM returned, taken from a constant allocation-size argument */
@@ -1554,6 +1798,7 @@ struct bpf_call_arg_meta {
struct btf *btf;
u32 func_id;
const struct bpf_func_proto *fn;
+ const struct btf_type *func_proto;
u8 release_regno;
u32 ret_btf_id;
u32 subprogno;
@@ -1561,20 +1806,25 @@ struct bpf_call_arg_meta {
struct bpf_dynptr_desc dynptr;
struct ref_obj_desc ref_obj;
struct ret_mem_desc ret_mem;
+ struct arg_raw_mem_desc arg_raw_mem;
+
+ /* Only set by subprog */
+ bool subprog_may_change_pkt;
/* Only set by kfunc */
bool r0_rdonly;
u32 kfunc_flags;
- const struct btf_type *func_proto;
const char *func_name;
struct arg_constant_desc arg_constant;
+ /* The type of the dynptr that the kfunc writes through */
+ enum bpf_dynptr_type dynptr_write_type;
/* arg_{btf,btf_id,owning_ref} are used by kfunc-specific handling,
* generally to pass info about user-defined local kptr types to later
* verification logic
* bpf_obj_drop/bpf_percpu_obj_drop
* Record the local kptr type to be drop'd
- * bpf_refcount_acquire (via KF_ARG_PTR_TO_REFCOUNTED_KPTR arg type)
+ * bpf_refcount_acquire (via ARG_PTR_TO_REFCOUNTED_KPTR arg type)
* Record the local kptr type to be refcount_incr'd and use
* arg_owning_ref to determine whether refcount_acquire should be
* fallible
@@ -1582,7 +1832,6 @@ struct bpf_call_arg_meta {
struct btf *arg_btf;
u32 arg_btf_id;
bool arg_owning_ref;
- bool arg_prog;
struct {
struct btf_field *field;
@@ -1600,7 +1849,6 @@ struct bpf_call_arg_meta {
s64 const_map_key;
struct btf *ret_btf;
struct btf_field *kptr_field;
- struct arg_raw_mem_desc arg_raw_mem;
};
int bpf_get_helper_proto(struct bpf_verifier_env *env, int func_id,
@@ -1627,17 +1875,37 @@ bool bpf_is_may_goto_insn(struct bpf_insn *insn);
void bpf_verbose_insn(struct bpf_verifier_env *env, struct bpf_insn *insn);
bool bpf_get_call_summary(struct bpf_verifier_env *env, struct bpf_insn *call,
struct bpf_call_summary *cs);
-s64 bpf_helper_stack_access_bytes(struct bpf_verifier_env *env,
- struct bpf_insn *insn, int arg,
- int insn_idx);
-s64 bpf_kfunc_stack_access_bytes(struct bpf_verifier_env *env,
- struct bpf_insn *insn, int arg,
- int insn_idx);
+/* Stack effects used for state pruning; must_write implies may_write. */
+struct arg_access_info {
+ u32 size; /* Maximum extent; U32_MAX if unknown. */
+ u8 may_read:1; /* Incoming contents or initialization may be needed. */
+ u8 may_write:1;
+ u8 must_write:1; /* Prior verifier state is destroyed throughout size. */
+};
+
+struct arg_access_info
+bpf_helper_stack_access_bytes(struct bpf_verifier_env *env,
+ struct bpf_insn *insn, int arg, int insn_idx);
+struct arg_access_info
+bpf_kfunc_stack_access_bytes(struct bpf_verifier_env *env,
+ struct bpf_insn *insn, int arg, int insn_idx);
+struct arg_access_info
+bpf_global_subprog_stack_access_bytes(struct bpf_verifier_env *env,
+ struct bpf_insn *insn, int arg, int insn_idx);
int bpf_compute_subprog_arg_access(struct bpf_verifier_env *env);
+bool bpf_same_memory_origin(const struct bpf_reg_state *reg_a,
+ const struct bpf_reg_state *reg_b);
+int bpf_set_reg_range(struct bpf_verifier_env *env, struct bpf_reg_state *reg,
+ struct cnum64 r64, struct cnum32 r32, u16 base, u16 step);
+bool bpf_reg_union_compatible(const struct bpf_reg_state *a, const struct bpf_reg_state *b);
+int bpf_reg_union(struct bpf_verifier_env *env, struct bpf_reg_state *acc,
+ const struct bpf_reg_state *src);
int bpf_stack_liveness_init(struct bpf_verifier_env *env);
void bpf_stack_liveness_free(struct bpf_verifier_env *env);
int bpf_live_stack_query_init(struct bpf_verifier_env *env, struct bpf_verifier_state *st);
+const unsigned long *bpf_may_write_mask(struct bpf_verifier_env *env, u32 insn_idx);
+bool bpf_needs_fixed_stack_off(struct bpf_verifier_env *env, int insn_idx);
bool bpf_stack_slot_alive(struct bpf_verifier_env *env, u32 frameno, u32 spi);
int bpf_compute_live_registers(struct bpf_verifier_env *env);
@@ -1669,6 +1937,21 @@ static inline u64 bpf_map_key_immediate(const struct bpf_insn_aux_data *aux)
return aux->map_key_state & ~(BPF_MAP_KEY_SEEN | BPF_MAP_KEY_POISON);
}
+static inline bool bpf_is_mem_insn(struct bpf_insn *insn)
+{
+ if (BPF_CLASS(insn->code) != BPF_ST &&
+ BPF_CLASS(insn->code) != BPF_STX &&
+ BPF_CLASS(insn->code) != BPF_LDX)
+ return false;
+
+ if (insn->code == (BPF_ST | BPF_NOSPEC))
+ return false;
+
+ return (BPF_MODE(insn->code) == BPF_MEM ||
+ BPF_MODE(insn->code) == BPF_MEMSX ||
+ BPF_MODE(insn->code) == BPF_ATOMIC);
+}
+
#define MAX_PACKET_OFF 0xffff
#define CALLER_SAVED_REGS 6
@@ -1679,30 +1962,34 @@ enum bpf_reg_arg_type {
};
#define MAX_KFUNC_DESCS 256
+/* Each kfunc can have its canonical and one specialized call target. */
+#define MAX_KFUNC_CALL_DESCS (MAX_KFUNC_DESCS * 2)
+static_assert(MAX_KFUNC_CALL_DESCS <= S16_MAX + 1);
struct bpf_kfunc_desc {
struct btf_func_model func_model;
struct bpf_func_proto proto;
u32 func_id;
- s32 imm;
u16 offset;
unsigned long addr;
};
struct bpf_kfunc_desc_tab {
u32 nr_descs;
+ u32 nr_base_descs;
/* Sorted by func_id (BTF ID) and offset (fd_array offset) during
- * verification. JITs do lookups by bpf_insn, where func_id may not be
- * available, therefore at the end of verification do_misc_fixups()
- * sorts this by imm and offset.
+ * verification. JITs use the descriptor index stored in the finalized
+ * call's off field. The first nr_base_descs entries are the canonical
+ * descriptors used for verifier lookups. Call specialization may append
+ * immutable descriptors for additional targets.
*
- * Grown one entry at a time by bpf_add_kfunc_call().
+ * Grown one entry at a time by bpf_add_kfunc_call() and during
+ * call specialization.
*/
struct bpf_kfunc_desc descs[];
};
/* Functions exported from verifier.c, used by fixups.c */
-void bpf_clear_insn_aux_data(struct bpf_verifier_env *env, int start, int len);
void bpf_mark_subprog_exc_cb(struct bpf_verifier_env *env, int subprog);
bool bpf_allow_tail_call_in_subprogs(struct bpf_verifier_env *env);
bool bpf_verifier_inlines_helper_call(struct bpf_verifier_env *env, s32 imm);
@@ -1715,6 +2002,7 @@ int bpf_check_attach_btf_id_multi(struct btf *btf, struct bpf_prog *prog, u32 bt
struct bpf_attach_target_info *tgt_info);
/* Functions in fixups.c, called from bpf_check() */
+void bpf_clear_insn_aux_data(struct bpf_verifier_env *env, int start, int len);
int bpf_remove_fastcall_spills_fills(struct bpf_verifier_env *env);
int bpf_optimize_bpf_loop(struct bpf_verifier_env *env);
void bpf_opt_hard_wire_dead_code_branches(struct bpf_verifier_env *env);
@@ -1727,4 +2015,23 @@ int bpf_fixup_call_args(struct bpf_verifier_env *env);
int bpf_do_misc_fixups(struct bpf_verifier_env *env);
int bpf_insn_def32(struct bpf_prog *prog, struct bpf_insn *insn);
+int bpf_flip_opcode(u32 opcode);
+u8 bpf_rev_opcode(u8 opcode);
+
+int bpf_compute_idoms(struct bpf_verifier_env *env);
+int bpf_compute_loops(struct bpf_verifier_env *env);
+int bpf_loop_at_index(struct bpf_verifier_env *env, u32 idx);
+bool bpf_is_nested_loop(struct bpf_verifier_env *env, int inner_header, int outer_header);
+
+int bpf_init_scev(struct bpf_verifier_env *env);
+void bpf_free_scev(struct bpf_verifier_env *env);
+int bpf_compute_scev(struct bpf_verifier_env *env);
+
+int bpf_compute_loop_iters(struct bpf_verifier_env *env, struct bpf_verifier_state *st,
+ struct bpf_loop_iters *iters);
+int bpf_widen_scev_regs(struct bpf_verifier_env *env, struct bpf_verifier_state *st,
+ struct bpf_verifier_state *loop_entry, struct bpf_loop_iters *iters);
+int bpf_clamp_scev_regs(struct bpf_verifier_env *env, struct bpf_func_state *st, u32 insn_idx,
+ struct bpf_verifier_state *entry_state, u32 max_header_count);
+
#endif /* _LINUX_BPF_VERIFIER_H */
diff --git a/include/linux/bsg-lib.h b/include/linux/bsg-lib.h
index 14fa93268630..a697246feeac 100644
--- a/include/linux/bsg-lib.h
+++ b/include/linux/bsg-lib.h
@@ -66,7 +66,8 @@ void bsg_job_done(struct bsg_job *job, int result,
unsigned int reply_payload_rcv_len);
struct request_queue *bsg_setup_queue(struct device *dev, const char *name,
struct queue_limits *lim, bsg_job_fn *job_fn,
- bsg_timeout_fn *timeout, int dd_job_size);
+ bsg_timeout_fn *timeout, int dd_job_size,
+ unsigned int reply_len);
void bsg_remove_queue(struct request_queue *q);
void bsg_job_put(struct bsg_job *job);
int __must_check bsg_job_get(struct bsg_job *job);
diff --git a/include/linux/btf.h b/include/linux/btf.h
index 89d5a5c4f117..b66e20a18c54 100644
--- a/include/linux/btf.h
+++ b/include/linux/btf.h
@@ -5,6 +5,7 @@
#define _LINUX_BTF_H 1
#include <linux/types.h>
+#include <linux/module.h>
#include <linux/bpfptr.h>
#include <linux/bsearch.h>
#include <linux/btf_ids.h>
@@ -80,6 +81,7 @@
#define KF_ARENA_ARG2 (1 << 15) /* kfunc takes an arena pointer as its second argument */
#define KF_IMPLICIT_ARGS (1 << 16) /* kfunc has implicit arguments supplied by the verifier */
#define KF_SPINLOCK_SAFE (1 << 17) /* kfunc is allowed inside bpf_spin_lock-ed region */
+#define KF_PERFMON (1 << 18) /* kfunc requires CAP_PERFMON */
/*
* Tag marking a kernel function as a kfunc. This is meant to minimize the
@@ -117,6 +119,19 @@ struct btf_show;
struct btf_id_set;
struct bpf_prog;
+#define BTF_LINK_SHA256_LEN 32
+
+/*
+ * A .BTF.link or .BTF.inline.link section identifies the module which
+ * carries a vmlinux BTF section. The module name is NUL terminated and the
+ * field is padded to __MODULE_NAME_LEN.
+ */
+struct btf_link {
+ char module_name[__MODULE_NAME_LEN];
+ u8 sha256[BTF_LINK_SHA256_LEN];
+ u32 btf_size;
+} __packed;
+
typedef int (*btf_kfunc_filter_t)(const struct bpf_prog *prog, u32 kfunc_id);
struct btf_kfunc_id_set {
@@ -235,6 +250,7 @@ struct btf_record *btf_parse_fields(const struct btf *btf, const struct btf_type
u32 field_mask, u32 value_size);
int btf_check_and_fixup_fields(const struct btf *btf, struct btf_record *rec);
bool btf_type_is_void(const struct btf_type *t);
+bool btf_type_is_arena_ptr(const struct btf *btf, const struct btf_type *t);
s32 btf_find_by_name_kind(const struct btf *btf, const char *name, u8 kind);
s32 bpf_find_btf_id(const char *name, u32 kind, struct btf **btf_p);
struct btf *btf_get_module_btf(const struct module *module);
@@ -260,6 +276,11 @@ const char *btf_type_str(const struct btf_type *t);
i < btf_type_vlen(datasec_type); \
i++, member++)
+#define for_each_loc(i, locsec_type, member) \
+ for (i = 0, member = btf_type_loc_secinfo(locsec_type); \
+ i < btf_type_vlen(locsec_type); \
+ i++, member++)
+
static inline bool btf_type_is_ptr(const struct btf_type *t)
{
return BTF_INFO_KIND(t->info) == BTF_KIND_PTR;
@@ -328,6 +349,21 @@ static inline u64 btf_enum64_value(const struct btf_enum64 *e)
return ((u64)e->val_hi32 << 32) | e->val_lo32;
}
+static inline struct btf_loc_param *btf_loc_param(const struct btf_type *t)
+{
+ return (struct btf_loc_param *)(t + 1);
+}
+
+static inline __u32 *btf_loc_proto_params(const struct btf_type *t)
+{
+ return (__u32 *)(t + 1);
+}
+
+static inline struct btf_loc *btf_type_loc_secinfo(const struct btf_type *t)
+{
+ return (struct btf_loc *)(t + 1);
+}
+
static inline bool btf_is_composite(const struct btf_type *t)
{
u16 kind = btf_kind(t);
@@ -558,7 +594,7 @@ struct btf_field_desc {
/* member struct size, or zero, if no members */
int m_sz;
/* repeated per-member offsets */
- int m_off_cnt, m_offs[1];
+ int m_off_cnt, m_offs[2];
};
struct btf_field_iter {
@@ -572,7 +608,8 @@ struct btf_field_iter {
#ifdef CONFIG_BPF_SYSCALL
const struct btf_type *btf_type_by_id(const struct btf *btf, u32 type_id);
void btf_set_base_btf(struct btf *btf, const struct btf *base_btf);
-int btf_relocate(struct btf *btf, const struct btf *base_btf, __u32 **map_ids);
+int btf_relocate(struct btf *btf, const struct btf *base_btf, __u32 **map_ids,
+ __u32 **map_strs);
int btf_field_iter_init(struct btf_field_iter *it, struct btf_type *t,
enum btf_field_iter_kind iter_kind);
__u32 *btf_field_iter_next(struct btf_field_iter *it);
@@ -602,6 +639,29 @@ bool btf_types_are_same(const struct btf *btf1, u32 id1,
const struct btf *btf2, u32 id2);
int btf_check_iter_arg(struct btf *btf, const struct btf_type *func, int arg_idx);
+#if IS_ENABLED(CONFIG_SYSFS)
+struct bin_attribute *sysfs_btf_add(const char *name, void *data, size_t data_size,
+ bool mmap, const char *lazy_module_name);
+bool sysfs_btf_update(struct bin_attribute *attr, void *data);
+void sysfs_btf_remove(struct bin_attribute *attr);
+#else
+static inline struct bin_attribute *
+sysfs_btf_add(const char *name, void *data, size_t data_size, bool mmap,
+ const char *lazy_module_name)
+{
+ return NULL;
+}
+
+static inline bool sysfs_btf_update(struct bin_attribute *attr, void *data)
+{
+ return false;
+}
+
+static inline void sysfs_btf_remove(struct bin_attribute *attr)
+{
+}
+#endif
+
static inline bool btf_type_is_struct_ptr(struct btf *btf, const struct btf_type *t)
{
if (!btf_type_is_ptr(t))
@@ -623,7 +683,7 @@ static inline void btf_set_base_btf(struct btf *btf, const struct btf *base_btf)
}
static inline int btf_relocate(void *log, struct btf *btf, const struct btf *base_btf,
- __u32 **map_ids)
+ __u32 **map_ids, __u32 **map_strs)
{
return -EOPNOTSUPP;
}
diff --git a/include/linux/buffer_head.h b/include/linux/buffer_head.h
index fd2c7115c054..f8782b719026 100644
--- a/include/linux/buffer_head.h
+++ b/include/linux/buffer_head.h
@@ -59,10 +59,7 @@ struct address_space;
struct buffer_head {
unsigned long b_state; /* buffer state bitmap (see above) */
struct buffer_head *b_this_page;/* circular list of page's buffers */
- union {
- struct page *b_page; /* the page this bh is mapped to */
- struct folio *b_folio; /* the folio this bh is mapped to */
- };
+ struct folio *b_folio; /* the folio this bh is mapped to */
sector_t b_blocknr; /* start block number */
size_t b_size; /* size of mapping */
@@ -172,15 +169,39 @@ static __always_inline int buffer_uptodate(const struct buffer_head *bh)
static inline unsigned long bh_offset(const struct buffer_head *bh)
{
- return (unsigned long)(bh)->b_data & (page_size(bh->b_page) - 1);
+ return (unsigned long)(bh)->b_data & (folio_size(bh->b_folio) - 1);
}
-/* If we *know* page->private refers to buffer_heads */
-#define page_buffers(page) \
- ({ \
- BUG_ON(!PagePrivate(page)); \
- ((struct buffer_head *)page_private(page)); \
- })
+/**
+ * kmap_local_bh - Map the data of a buffer.
+ * @bh: The buffer.
+ *
+ * Buffers usually live in the page cache, but a few are built over memory
+ * which is not. Those carry no folio and b_data is already a kernel address
+ * which is always mapped, so there is nothing to do for them. Pair with
+ * kunmap_local_bh().
+ *
+ * Return: A pointer to the buffer's data.
+ */
+static inline void *kmap_local_bh(const struct buffer_head *bh)
+{
+ if (!bh->b_folio)
+ return bh->b_data;
+ return kmap_local_folio(bh->b_folio, bh_offset(bh));
+}
+
+/**
+ * kunmap_local_bh - Unmap the data of a buffer.
+ * @bh: The buffer.
+ * @addr: The address returned by kmap_local_bh().
+ */
+static inline void kunmap_local_bh(const struct buffer_head *bh, void *addr)
+{
+ if (bh->b_folio)
+ kunmap_local(addr);
+}
+
+/* If we *know* folio->private refers to buffer_heads */
#define folio_buffers(folio) folio_get_private(folio)
void buffer_check_dirty_writeback(struct folio *folio,
@@ -197,7 +218,6 @@ void folio_set_bh(struct buffer_head *bh, struct folio *folio,
unsigned long offset);
struct buffer_head *folio_alloc_buffers(struct folio *folio, unsigned long size,
gfp_t gfp);
-struct buffer_head *alloc_page_buffers(struct page *page, unsigned long size);
struct buffer_head *create_empty_buffers(struct folio *folio,
unsigned long blocksize, unsigned long b_state);
void end_buffer_read_sync(struct buffer_head *bh, int uptodate);
@@ -338,20 +358,58 @@ static inline void bforget(struct buffer_head *bh)
__bforget(bh);
}
-static inline struct buffer_head *
-sb_bread(struct super_block *sb, sector_t block)
+/**
+ * sb_bread - Read a block.
+ * @sb: The superblock to read from.
+ * @block: Block number in units of block size.
+ *
+ * Read a specified block, and return the buffer head that refers
+ * to it. The memory is allocated from the movable area so that it can
+ * be migrated. The returned buffer head has its refcount increased.
+ * The caller should call brelse() when it has finished with the buffer.
+ *
+ * Context: May sleep waiting for I/O.
+ * Return: NULL if the block was unreadable.
+ */
+static inline
+struct buffer_head *sb_bread(struct super_block *sb, sector_t block)
{
return __bread_gfp(sb->s_bdev, block, sb->s_blocksize, __GFP_MOVABLE);
}
-static inline struct buffer_head *
-sb_bread_unmovable(struct super_block *sb, sector_t block)
+/**
+ * sb_bread_unmovable - Read a block.
+ * @sb: The superblock to read from.
+ * @block: Block number in units of block size.
+ *
+ * Read a specified block, and return the buffer head that refers to it.
+ * The memory is allocated from the unmovable area so that pointers into
+ * it remain valid after compaction runs. The returned buffer head has
+ * its refcount increased. The caller should call brelse() when it has
+ * finished with the buffer.
+ *
+ * Context: May sleep waiting for I/O.
+ * Return: NULL if the block was unreadable.
+ */
+static inline
+struct buffer_head *sb_bread_unmovable(struct super_block *sb, sector_t block)
{
return __bread_gfp(sb->s_bdev, block, sb->s_blocksize, 0);
}
-static inline void
-sb_breadahead(struct super_block *sb, sector_t block)
+/**
+ * sb_breadahead - Start readahead.
+ * @sb: Superblock identifying the block device.
+ * @block: The block to read.
+ *
+ * Read this block. The I/O will be flagged as being readahead rather
+ * than immediate read, but (unlike the page cache), surrounding blocks
+ * will not be read.
+ *
+ * Context: May sleep in order to allocate memory.
+ */
+static inline
+void sb_breadahead(struct super_block *sb, sector_t block)
{
__breadahead(sb->s_bdev, block, sb->s_blocksize);
}
diff --git a/include/linux/cacheinfo.h b/include/linux/cacheinfo.h
index fc879ac4cc4f..56fa646df0d1 100644
--- a/include/linux/cacheinfo.h
+++ b/include/linux/cacheinfo.h
@@ -82,6 +82,7 @@ struct cpu_cacheinfo {
};
struct cpu_cacheinfo *get_cpu_cacheinfo(unsigned int cpu);
+int get_cpu_cacheinfo_id(int cpu, int level);
int early_cache_level(unsigned int cpu);
int init_cache_level(unsigned int cpu);
int init_of_cache_level(unsigned int cpu);
@@ -137,17 +138,6 @@ static inline struct cacheinfo *get_cpu_cacheinfo_level(int cpu, int level)
return NULL;
}
-/*
- * Get the id of the cache associated with @cpu at level @level.
- * cpuhp lock must be held.
- */
-static inline int get_cpu_cacheinfo_id(int cpu, int level)
-{
- struct cacheinfo *ci = get_cpu_cacheinfo_level(cpu, level);
-
- return ci ? ci->id : -1;
-}
-
#if defined(CONFIG_ARM64) || defined(CONFIG_ARM)
#define use_arch_cache_info() (true)
#else
diff --git a/include/linux/can/core.h b/include/linux/can/core.h
index 3287232e3cad..2de74c2b78b6 100644
--- a/include/linux/can/core.h
+++ b/include/linux/can/core.h
@@ -17,6 +17,7 @@
#include <linux/can.h>
#include <linux/skbuff.h>
#include <linux/netdevice.h>
+#include <net/can.h>
#define DNAME(dev) ((dev) ? (dev)->name : "any")
@@ -58,7 +59,7 @@ extern void can_rx_unregister(struct net *net, struct net_device *dev,
void *data);
extern int can_send(struct sk_buff *skb, int loop);
-void can_set_skb_uid(struct sk_buff *skb);
+void can_set_skb_uid(struct can_skb_ext *csx);
void can_sock_destruct(struct sock *sk);
#endif /* !_CAN_CORE_H */
diff --git a/include/linux/can/skb.h b/include/linux/can/skb.h
index a70a02967071..5d27843862fc 100644
--- a/include/linux/can/skb.h
+++ b/include/linux/can/skb.h
@@ -43,8 +43,10 @@ static inline struct can_skb_ext *can_skb_ext_add(struct sk_buff *skb)
struct can_skb_ext *csx = skb_ext_add(skb, SKB_EXT_CAN);
/* skb_ext_add() returns uninitialized space */
- if (csx)
+ if (csx) {
csx->can_gw_hops = 0;
+ csx->can_skb_uid = 0;
+ }
return csx;
}
diff --git a/include/linux/capability.h b/include/linux/capability.h
index f8532d92fcad..622137f66f09 100644
--- a/include/linux/capability.h
+++ b/include/linux/capability.h
@@ -186,9 +186,9 @@ static inline bool ns_capable_setid(struct user_namespace *ns, int cap)
}
#endif /* CONFIG_MULTIUSER */
bool privileged_wrt_inode_uidgid(struct user_namespace *ns,
- struct mnt_idmap *idmap,
+ const struct mnt_idmap *idmap,
const struct inode *inode);
-bool capable_wrt_inode_uidgid(struct mnt_idmap *idmap,
+bool capable_wrt_inode_uidgid(const struct mnt_idmap *idmap,
const struct inode *inode, int cap);
extern bool file_ns_capable(const struct file *file, struct user_namespace *ns, int cap);
extern bool ptracer_capable(struct task_struct *tsk, struct user_namespace *ns);
@@ -215,11 +215,11 @@ static inline bool checkpoint_restore_ns_capable_noaudit(struct user_namespace *
}
/* audit system wants to get cap info from files as well */
-int get_vfs_caps_from_disk(struct mnt_idmap *idmap,
+int get_vfs_caps_from_disk(const struct mnt_idmap *idmap,
const struct dentry *dentry,
struct cpu_vfs_cap_data *cpu_caps);
-int cap_convert_nscap(struct mnt_idmap *idmap, struct dentry *dentry,
+int cap_convert_nscap(const struct mnt_idmap *idmap, struct dentry *dentry,
const void **ivalue, size_t size);
#endif /* !_LINUX_CAPABILITY_H */
diff --git a/include/linux/ccp.h b/include/linux/ccp.h
index 868924dec5a1..e6c599243f11 100644
--- a/include/linux/ccp.h
+++ b/include/linux/ccp.h
@@ -26,7 +26,7 @@ struct ccp_cmd;
/**
* ccp_present - check if a CCP device is present
*
- * Returns zero if a CCP device is present, -ENODEV otherwise.
+ * Returns: zero if a CCP device is present, -ENODEV otherwise.
*/
int ccp_present(void);
@@ -38,7 +38,7 @@ int ccp_present(void);
/**
* ccp_version - get the version of the CCP
*
- * Returns a positive version number, or zero if no CCP
+ * Returns: a positive version number, or zero if no CCP
*/
unsigned int ccp_version(void);
@@ -61,9 +61,9 @@ unsigned int ccp_version(void);
* will be -EINPROGRESS. Any other "err" value during callback is
* the result of the operation.
*
- * The cmd has been successfully queued if:
- * the return code is -EINPROGRESS or
- * the return code is -EBUSY and CCP_CMD_MAY_BACKLOG flag is set
+ * Returns: The cmd has been successfully queued if:
+ * * the return code is -EINPROGRESS or
+ * * the return code is -EBUSY and CCP_CMD_MAY_BACKLOG flag is set
*/
int ccp_enqueue_cmd(struct ccp_cmd *cmd);
@@ -89,7 +89,7 @@ static inline int ccp_enqueue_cmd(struct ccp_cmd *cmd)
/***** AES engine *****/
/**
- * ccp_aes_type - AES key size
+ * enum ccp_aes_type - AES key size
*
* @CCP_AES_TYPE_128: 128-bit key
* @CCP_AES_TYPE_192: 192-bit key
@@ -99,11 +99,12 @@ enum ccp_aes_type {
CCP_AES_TYPE_128 = 0,
CCP_AES_TYPE_192,
CCP_AES_TYPE_256,
+ /* private: */
CCP_AES_TYPE__LAST,
};
/**
- * ccp_aes_mode - AES operation mode
+ * enum ccp_aes_mode - AES operation mode
*
* @CCP_AES_MODE_ECB: ECB mode
* @CCP_AES_MODE_CBC: CBC mode
@@ -111,6 +112,10 @@ enum ccp_aes_type {
* @CCP_AES_MODE_CFB: CFB mode
* @CCP_AES_MODE_CTR: CTR mode
* @CCP_AES_MODE_CMAC: CMAC mode
+ * @CCP_AES_MODE_GHASH: GHASH mode
+ * @CCP_AES_MODE_GCTR: GCTR mode
+ * @CCP_AES_MODE_GCM: GCM mode
+ * @CCP_AES_MODE_GMAC: GMAC mode
*/
enum ccp_aes_mode {
CCP_AES_MODE_ECB = 0,
@@ -123,11 +128,12 @@ enum ccp_aes_mode {
CCP_AES_MODE_GCTR,
CCP_AES_MODE_GCM,
CCP_AES_MODE_GMAC,
+ /* private: */
CCP_AES_MODE__LAST,
};
/**
- * ccp_aes_mode - AES operation mode
+ * enum ccp_aes_action - AES operation mode
*
* @CCP_AES_ACTION_DECRYPT: AES decrypt operation
* @CCP_AES_ACTION_ENCRYPT: AES encrypt operation
@@ -135,6 +141,7 @@ enum ccp_aes_mode {
enum ccp_aes_action {
CCP_AES_ACTION_DECRYPT = 0,
CCP_AES_ACTION_ENCRYPT,
+ /* private: */
CCP_AES_ACTION__LAST,
};
/* Overloaded field */
@@ -146,6 +153,7 @@ enum ccp_aes_action {
* @type: AES operation key size
* @mode: AES operation mode
* @action: AES operation (decrypt/encrypt)
+ * @authsize: AES block request size
* @key: key to be used for this AES operation
* @key_len: length in bytes of key
* @iv: IV to be used for this AES operation
@@ -156,6 +164,7 @@ enum ccp_aes_action {
* @cmac_final: indicates final operation when running in CMAC mode
* @cmac_key: K1/K2 key used in final CMAC operation
* @cmac_key_len: length in bytes of cmac_key
+ * @aad_len: length in bytes of Additional Authenticated Data
*
* Variables required to be set when calling ccp_enqueue_cmd():
* - type, mode, action, key, key_len, src, dst, src_len
@@ -192,7 +201,7 @@ struct ccp_aes_engine {
/***** XTS-AES engine *****/
/**
- * ccp_xts_aes_unit_size - XTS unit size
+ * enum ccp_xts_aes_unit_size - XTS unit size
*
* @CCP_XTS_AES_UNIT_SIZE_16: Unit size of 16 bytes
* @CCP_XTS_AES_UNIT_SIZE_512: Unit size of 512 bytes
@@ -206,11 +215,13 @@ enum ccp_xts_aes_unit_size {
CCP_XTS_AES_UNIT_SIZE_1024,
CCP_XTS_AES_UNIT_SIZE_2048,
CCP_XTS_AES_UNIT_SIZE_4096,
+ /* private: */
CCP_XTS_AES_UNIT_SIZE__LAST,
};
/**
* struct ccp_xts_aes_engine - CCP XTS AES operation
+ * @type: ccp_aes_type - AES key size
* @action: AES operation (decrypt/encrypt)
* @unit_size: unit size of the XTS operation
* @key: key to be used for this XTS AES operation
@@ -247,11 +258,13 @@ struct ccp_xts_aes_engine {
/***** SHA engine *****/
/**
- * ccp_sha_type - type of SHA operation
+ * enum ccp_sha_type - type of SHA operation
*
* @CCP_SHA_TYPE_1: SHA-1 operation
* @CCP_SHA_TYPE_224: SHA-224 operation
* @CCP_SHA_TYPE_256: SHA-256 operation
+ * @CCP_SHA_TYPE_384: SHA-384 operation
+ * @CCP_SHA_TYPE_512: SHA-512 operation
*/
enum ccp_sha_type {
CCP_SHA_TYPE_1 = 1,
@@ -259,6 +272,7 @@ enum ccp_sha_type {
CCP_SHA_TYPE_256,
CCP_SHA_TYPE_384,
CCP_SHA_TYPE_512,
+ /* private: */
CCP_SHA_TYPE__LAST,
};
@@ -384,7 +398,7 @@ struct ccp_rsa_engine {
/***** Passthru engine *****/
/**
- * ccp_passthru_bitwise - type of bitwise passthru operation
+ * enum ccp_passthru_bitwise - type of bitwise passthru operation
*
* @CCP_PASSTHRU_BITWISE_NOOP: no bitwise operation performed
* @CCP_PASSTHRU_BITWISE_AND: perform bitwise AND of src with mask
@@ -398,11 +412,12 @@ enum ccp_passthru_bitwise {
CCP_PASSTHRU_BITWISE_OR,
CCP_PASSTHRU_BITWISE_XOR,
CCP_PASSTHRU_BITWISE_MASK,
+ /* private: */
CCP_PASSTHRU_BITWISE__LAST,
};
/**
- * ccp_passthru_byteswap - type of byteswap passthru operation
+ * enum ccp_passthru_byteswap - type of byteswap passthru operation
*
* @CCP_PASSTHRU_BYTESWAP_NOOP: no byte swapping performed
* @CCP_PASSTHRU_BYTESWAP_32BIT: swap bytes within 32-bit words
@@ -412,6 +427,7 @@ enum ccp_passthru_byteswap {
CCP_PASSTHRU_BYTESWAP_NOOP = 0,
CCP_PASSTHRU_BYTESWAP_32BIT,
CCP_PASSTHRU_BYTESWAP_256BIT,
+ /* private: */
CCP_PASSTHRU_BYTESWAP__LAST,
};
@@ -450,8 +466,8 @@ struct ccp_passthru_engine {
* @byte_swap: byteswap operation to perform
* @mask: mask to be applied to data
* @mask_len: length in bytes of mask
- * @src: data to be used for this operation
- * @dst: data produced by this operation
+ * @src_dma: data to be used for this operation
+ * @dst_dma: data produced by this operation
* @src_len: length in bytes of data used for this operation
* @final: indicate final pass-through operation
*
@@ -478,7 +494,7 @@ struct ccp_passthru_nomap_engine {
#define CCP_ECC_MAX_OUTPUTS 3
/**
- * ccp_ecc_function - type of ECC function
+ * enum ccp_ecc_function - type of ECC function
*
* @CCP_ECC_FUNCTION_MMUL_384BIT: 384-bit modular multiplication
* @CCP_ECC_FUNCTION_MADD_384BIT: 384-bit modular addition
@@ -564,8 +580,9 @@ struct ccp_ecc_point_math {
* @function: ECC function to perform
* @mod: ECC modulus
* @mod_len: length in bytes of modulus
- * @mm: module math parameters
- * @pm: point math parameters
+ * @u: union for math parameters
+ * @u.mm: module math parameters
+ * @u.pm: point math parameters
* @ecc_result: result of the ECC operation
*
* Variables required to be set when calling ccp_enqueue_cmd():
@@ -589,11 +606,11 @@ struct ccp_ecc_engine {
/**
- * ccp_engine - CCP operation identifiers
+ * enum ccp_engine - CCP operation identifiers
*
* @CCP_ENGINE_AES: AES operation
- * @CCP_ENGINE_XTS_AES: 128-bit XTS AES operation
- * @CCP_ENGINE_RSVD1: unused
+ * @CCP_ENGINE_XTS_AES_128: 128-bit XTS AES operation
+ * @CCP_ENGINE_DES3: 3DES operation
* @CCP_ENGINE_SHA: SHA operation
* @CCP_ENGINE_RSA: RSA operation
* @CCP_ENGINE_PASSTHRU: pass-through operation
@@ -609,6 +626,7 @@ enum ccp_engine {
CCP_ENGINE_PASSTHRU,
CCP_ENGINE_ZLIB_DECOMPRESS,
CCP_ENGINE_ECC,
+ /* private: */
CCP_ENGINE__LAST,
};
diff --git a/include/linux/cgroup-defs.h b/include/linux/cgroup-defs.h
index 3754d697854b..cbfe8937647c 100644
--- a/include/linux/cgroup-defs.h
+++ b/include/linux/cgroup-defs.h
@@ -556,6 +556,14 @@ struct cgroup {
struct cgroup_subsys_state __rcu *subsys[CGROUP_SUBSYS_COUNT];
/*
+ * Effective css for each subsystem: the css of the nearest ancestor,
+ * including this cgroup, that has the subsystem enabled, or the root
+ * css if the subsystem isn't bound to this hierarchy. Updated under
+ * cgroup_mutex and read under RCU.
+ */
+ struct cgroup_subsys_state __rcu *e_css[CGROUP_SUBSYS_COUNT];
+
+ /*
* Keep track of total number of dying CSSes at and below this cgroup.
* Protected by cgroup_mutex.
*/
diff --git a/include/linux/cgroup.h b/include/linux/cgroup.h
index 5dfa915a630e..2afb4cb2bb4f 100644
--- a/include/linux/cgroup.h
+++ b/include/linux/cgroup.h
@@ -154,6 +154,9 @@ struct cgroup *cgroup_get_from_path(const char *path);
struct cgroup *cgroup_get_from_fd(int fd);
struct cgroup *cgroup_v1v2_get_from_fd(int fd);
+/* Was this controller blocked from v1 hierarchies by cgroup_no_v1= ? */
+bool cgroup1_ssid_disabled(int ssid);
+
int cgroup_attach_task_all(struct task_struct *from, struct task_struct *);
int cgroup_transfer_tasks(struct cgroup *to, struct cgroup *from);
diff --git a/include/linux/cleanup.h b/include/linux/cleanup.h
index b1b5698cbf1b..1fb8058b897d 100644
--- a/include/linux/cleanup.h
+++ b/include/linux/cleanup.h
@@ -261,10 +261,6 @@ const volatile void * __must_check_fn(const volatile void *val)
* CLASS(name, var)(args...):
* declare the variable @var as an instance of the named class
*
- * CLASS_INIT(name, var, init_expr):
- * declare the variable @var as an instance of the named class with
- * custom initialization expression.
- *
* Ex.
*
* DEFINE_CLASS(fdget, struct fd, fdput(_T), fdget(fd), int fd)
@@ -302,9 +298,6 @@ static __always_inline class_##_name##_t class_##_name##ext##_constructor(_init_
class_##_name##_t var __cleanup(class_##_name##_destructor) = \
class_##_name##_constructor
-#define CLASS_INIT(_name, _var, _init_expr) \
- class_##_name##_t _var __cleanup(class_##_name##_destructor) = (_init_expr)
-
#define __scoped_class(_name, var, _label, args...) \
for (CLASS(_name, var)(args); ; ({ goto _label; })) \
if (0) { \
diff --git a/include/linux/cmpxchg-emu.h b/include/linux/cmpxchg-emu.h
index 998deec67740..2db70f1e3925 100644
--- a/include/linux/cmpxchg-emu.h
+++ b/include/linux/cmpxchg-emu.h
@@ -4,12 +4,14 @@
* lacking direct support for these sizes. These are implemented in terms
* of 4-byte cmpxchg operations.
*
- * Copyright (C) 2024 Paul E. McKenney.
+ * Copyright (C) 2024 Paul E. McKenney <paulmck@kernel.org>
+ * Copyright (C) 2026 Bradley Morgan <brads@mainlining.org>
*/
#ifndef __LINUX_CMPXCHG_EMU_H
#define __LINUX_CMPXCHG_EMU_H
uintptr_t cmpxchg_emu_u8(volatile u8 *p, uintptr_t old, uintptr_t new);
+unsigned long cmpxchg_emu_u16(volatile u16 *p, unsigned long old, unsigned long new);
#endif /* __LINUX_CMPXCHG_EMU_H */
diff --git a/include/linux/cnum.h b/include/linux/cnum.h
index 49b7d0c7645d..49160318adf9 100644
--- a/include/linux/cnum.h
+++ b/include/linux/cnum.h
@@ -39,6 +39,7 @@ u32 cnum32_umin(struct cnum32 cnum);
u32 cnum32_umax(struct cnum32 cnum);
s32 cnum32_smin(struct cnum32 cnum);
s32 cnum32_smax(struct cnum32 cnum);
+struct cnum32 cnum32_union(struct cnum32 a, struct cnum32 b);
struct cnum32 cnum32_intersect(struct cnum32 a, struct cnum32 b);
void cnum32_intersect_with(struct cnum32 *dst, struct cnum32 src);
void cnum32_intersect_with_urange(struct cnum32 *dst, u32 min, u32 max);
@@ -65,6 +66,7 @@ u64 cnum64_umin(struct cnum64 cnum);
u64 cnum64_umax(struct cnum64 cnum);
s64 cnum64_smin(struct cnum64 cnum);
s64 cnum64_smax(struct cnum64 cnum);
+struct cnum64 cnum64_union(struct cnum64 a, struct cnum64 b);
struct cnum64 cnum64_intersect(struct cnum64 a, struct cnum64 b);
void cnum64_intersect_with(struct cnum64 *dst, struct cnum64 src);
void cnum64_intersect_with_urange(struct cnum64 *dst, u64 min, u64 max);
@@ -78,5 +80,6 @@ bool cnum64_is_subset(struct cnum64 outer, struct cnum64 inner);
struct cnum32 cnum32_from_cnum64(struct cnum64 cnum);
struct cnum64 cnum64_cnum32_intersect(struct cnum64 a, struct cnum32 b);
+struct cnum64 cnum64_intersect_linear(struct cnum64 in, u16 base, u16 step);
#endif /* _LINUX_CNUM_H */
diff --git a/include/linux/compaction.h b/include/linux/compaction.h
index 66a2f70e9e01..691c09f0a697 100644
--- a/include/linux/compaction.h
+++ b/include/linux/compaction.h
@@ -81,10 +81,6 @@ static inline unsigned long compact_gap(unsigned int order)
return min(2UL << order, COMPACT_CLUSTER_MAX);
}
-static inline int current_is_kcompactd(void)
-{
- return current->flags & PF_KCOMPACTD;
-}
#ifdef CONFIG_COMPACTION
@@ -103,7 +99,7 @@ extern void compaction_defer_reset(struct zone *zone, int order,
bool compaction_zonelist_suitable(struct alloc_context *ac, int order,
int alloc_flags, gfp_t gfp_mask);
-
+bool current_is_kcompactd(void);
extern void __meminit kcompactd_run(int nid);
extern void __meminit kcompactd_stop(int nid);
extern void wakeup_kcompactd(pg_data_t *pgdat, int order, int highest_zoneidx);
@@ -120,6 +116,11 @@ static inline bool compaction_suitable(struct zone *zone, int order,
return false;
}
+static inline bool current_is_kcompactd(void)
+{
+ return false;
+}
+
static inline void kcompactd_run(int nid)
{
}
diff --git a/include/linux/compat.h b/include/linux/compat.h
index 8da0a15c95f4..ad37ca617e65 100644
--- a/include/linux/compat.h
+++ b/include/linux/compat.h
@@ -18,6 +18,7 @@
#include <linux/aio_abi.h> /* for aio_context_t */
#include <linux/uaccess.h>
#include <linux/unistd.h>
+#include <linux/error-injection.h>
#include <asm/compat.h>
#include <asm/siginfo.h>
diff --git a/include/linux/compiler.h b/include/linux/compiler.h
index cb2f6050bdf7..0ea7150dba7b 100644
--- a/include/linux/compiler.h
+++ b/include/linux/compiler.h
@@ -239,6 +239,23 @@ void ftrace_likely_update(struct ftrace_likely_data *f, int val,
# define TYPEOF_UNQUAL(exp) __typeof__(exp)
#endif
+/*
+ * TYPEOF_NO_ADDRESS_SPACE() - typeof() without the address space qualifiers
+ *
+ * No operator strips only the address space qualifiers: typeof() keeps every
+ * qualifier and TYPEOF_UNQUAL() drops every qualifier, const and volatile
+ * included.
+ *
+ * Approximate one by dropping the qualifiers for sparse only, as it is the
+ * only one that knows about address spaces. The compiler keeps seeing the fully
+ * qualified type, so a missing const or volatile will still throw a warning.
+ */
+#ifdef __CHECKER__
+# define TYPEOF_NO_ADDRESS_SPACE(exp) TYPEOF_UNQUAL(exp)
+#else
+# define TYPEOF_NO_ADDRESS_SPACE(exp) __typeof__(exp)
+#endif
+
#endif /* __KERNEL__ */
#if defined(CONFIG_CFI) && !defined(__DISABLE_EXPORTS) && !defined(BUILD_VDSO)
@@ -275,6 +292,11 @@ static inline void *offset_to_ptr(const int *off)
#define __ADDRESSABLE(sym) \
___ADDRESSABLE(sym, __section(".discard.addressable"))
+/* Enforce static storage duration. */
+#define ASSERT_STATIC_STORAGE(name) \
+ static typeof(name) * const __always_unused \
+ name##_storage_check = &(name)
+
/*
* This returns a constant expression while determining if an argument is
* a constant expression, most importantly without evaluating the argument.
diff --git a/include/linux/configfs.h b/include/linux/configfs.h
index ef65c75beeaa..5bead9173ec1 100644
--- a/include/linux/configfs.h
+++ b/include/linux/configfs.h
@@ -66,8 +66,11 @@ struct config_item_type {
struct module *ct_owner;
const struct configfs_item_operations *ct_item_ops;
const struct configfs_group_operations *ct_group_ops;
- struct configfs_attribute **ct_attrs;
- struct configfs_bin_attribute **ct_bin_attrs;
+ union {
+ struct configfs_attribute **ct_attrs;
+ const struct configfs_attribute *const *ct_attrs_const;
+ };
+ const struct configfs_bin_attribute *const *ct_bin_attrs;
};
/**
@@ -160,41 +163,41 @@ struct configfs_bin_attribute {
ssize_t (*write)(struct config_item *, const void *, size_t);
};
-#define CONFIGFS_BIN_ATTR(_pfx, _name, _priv, _maxsz) \
-static struct configfs_bin_attribute _pfx##attr_##_name = { \
- .cb_attr = { \
- .ca_name = __stringify(_name), \
- .ca_mode = S_IRUGO | S_IWUSR, \
- .ca_owner = THIS_MODULE, \
- }, \
- .cb_private = _priv, \
- .cb_max_size = _maxsz, \
- .read = _pfx##_name##_read, \
- .write = _pfx##_name##_write, \
+#define CONFIGFS_BIN_ATTR(_pfx, _name, _priv, _maxsz) \
+static const struct configfs_bin_attribute _pfx##attr_##_name = { \
+ .cb_attr = { \
+ .ca_name = __stringify(_name), \
+ .ca_mode = S_IRUGO | S_IWUSR, \
+ .ca_owner = THIS_MODULE, \
+ }, \
+ .cb_private = _priv, \
+ .cb_max_size = _maxsz, \
+ .read = _pfx##_name##_read, \
+ .write = _pfx##_name##_write, \
}
-#define CONFIGFS_BIN_ATTR_RO(_pfx, _name, _priv, _maxsz) \
-static struct configfs_bin_attribute _pfx##attr_##_name = { \
- .cb_attr = { \
- .ca_name = __stringify(_name), \
- .ca_mode = S_IRUGO, \
- .ca_owner = THIS_MODULE, \
- }, \
- .cb_private = _priv, \
- .cb_max_size = _maxsz, \
- .read = _pfx##_name##_read, \
+#define CONFIGFS_BIN_ATTR_RO(_pfx, _name, _priv, _maxsz) \
+static const struct configfs_bin_attribute _pfx##attr_##_name = { \
+ .cb_attr = { \
+ .ca_name = __stringify(_name), \
+ .ca_mode = S_IRUGO, \
+ .ca_owner = THIS_MODULE, \
+ }, \
+ .cb_private = _priv, \
+ .cb_max_size = _maxsz, \
+ .read = _pfx##_name##_read, \
}
-#define CONFIGFS_BIN_ATTR_WO(_pfx, _name, _priv, _maxsz) \
-static struct configfs_bin_attribute _pfx##attr_##_name = { \
- .cb_attr = { \
- .ca_name = __stringify(_name), \
- .ca_mode = S_IWUSR, \
- .ca_owner = THIS_MODULE, \
- }, \
- .cb_private = _priv, \
- .cb_max_size = _maxsz, \
- .write = _pfx##_name##_write, \
+#define CONFIGFS_BIN_ATTR_WO(_pfx, _name, _priv, _maxsz) \
+static const struct configfs_bin_attribute _pfx##attr_##_name = { \
+ .cb_attr = { \
+ .ca_name = __stringify(_name), \
+ .ca_mode = S_IWUSR, \
+ .ca_owner = THIS_MODULE, \
+ }, \
+ .cb_private = _priv, \
+ .cb_max_size = _maxsz, \
+ .write = _pfx##_name##_write, \
}
/*
@@ -220,8 +223,8 @@ struct configfs_group_operations {
struct config_group *(*make_group)(struct config_group *group, const char *name);
void (*disconnect_notify)(struct config_group *group, struct config_item *item);
void (*drop_item)(struct config_group *group, struct config_item *item);
- bool (*is_visible)(struct config_item *item, struct configfs_attribute *attr, int n);
- bool (*is_bin_visible)(struct config_item *item, struct configfs_bin_attribute *attr,
+ bool (*is_visible)(struct config_item *item, const struct configfs_attribute *attr, int n);
+ bool (*is_bin_visible)(struct config_item *item, const struct configfs_bin_attribute *attr,
int n);
};
diff --git a/include/linux/console.h b/include/linux/console.h
index d624200cfc17..df23148987ee 100644
--- a/include/linux/console.h
+++ b/include/linux/console.h
@@ -173,7 +173,7 @@ static inline void con_debug_leave(void) { }
* @CON_BRL: Indicates a braille device which is exempt from
* receiving the printk spam for obvious reasons.
* @CON_EXTENDED: The console supports the extended output format of
- * /dev/kmesg which requires a larger output buffer.
+ * /dev/kmsg which requires a larger output buffer.
* @CON_SUSPENDED: Indicates if a console is suspended. If true, the
* printing callbacks must not be called.
* @CON_NBCON: Console can operate outside of the legacy style console_lock
@@ -615,6 +615,15 @@ extern bool nbcon_allow_unsafe_takeover(void);
extern bool nbcon_kdb_try_acquire(struct console *con,
struct nbcon_write_context *wctxt);
extern void nbcon_kdb_release(struct nbcon_write_context *wctxt);
+extern bool nbcon_write_context_is_braille(struct nbcon_write_context *wctxt);
+extern bool nbcon_braille_try_acquire(struct console *con,
+ struct nbcon_write_context *wctxt);
+extern void nbcon_braille_release(struct nbcon_write_context *wctxt);
+
+static inline bool nbcon_is_braille(struct console *con)
+{
+ return con && (con->flags & CON_BRL);
+}
/*
* Check if the given console is currently capable and allowed to print
@@ -678,8 +687,14 @@ static inline void nbcon_reacquire_nobuf(struct nbcon_write_context *wctxt) { }
static inline bool nbcon_kdb_try_acquire(struct console *con,
struct nbcon_write_context *wctxt) { return false; }
static inline void nbcon_kdb_release(struct nbcon_write_context *wctxt) { }
+static inline
+bool nbcon_write_context_is_braille(struct nbcon_write_context *wctxt) { return false; }
static inline bool console_is_usable(struct console *con, short flags,
bool use_atomic) { return false; }
+static inline bool nbcon_braille_try_acquire(struct console *con,
+ struct nbcon_write_context *wctxt) { return false; }
+static inline void nbcon_braille_release(struct nbcon_write_context *wctxt) { }
+static inline bool nbcon_is_braille(struct console *con) { return false; }
#endif
extern int console_set_on_cmdline;
diff --git a/include/linux/console_struct.h b/include/linux/console_struct.h
index fe915afdece5..de9e91429a88 100644
--- a/include/linux/console_struct.h
+++ b/include/linux/console_struct.h
@@ -204,6 +204,10 @@ struct vc {
extern struct vc vc_cons [MAX_NR_CONSOLES];
extern void vc_SAK(struct work_struct *work);
+/*
+ * Cursors
+ */
+
#define CUR_MAKE(size, change, set) ((size) | ((change) << 8) | \
((set) << 16))
#define CUR_SIZE(c) ((c) & 0x00000f)
@@ -222,6 +226,10 @@ extern void vc_SAK(struct work_struct *work);
#define CUR_CHANGE(c) ((c) & 0x00ff00)
#define CUR_SET(c) (((c) & 0xff0000) >> 8)
+unsigned int vc_cursor_valid_size(unsigned int cursor_size);
+unsigned int vc_cursor_start(unsigned int cell_height, unsigned int cursor_size);
+unsigned int vc_cursor_end(unsigned int cell_height, unsigned int cursor_size);
+
bool con_is_visible(const struct vc_data *vc);
#endif /* _LINUX_CONSOLE_STRUCT_H */
diff --git a/include/linux/coredump.h b/include/linux/coredump.h
index 7b38ee2e7913..8e857770dd21 100644
--- a/include/linux/coredump.h
+++ b/include/linux/coredump.h
@@ -5,10 +5,22 @@
#include <linux/types.h>
#include <linux/mm.h>
#include <linux/fs.h>
+#include <linux/pid_types.h>
#include <linux/sched/coredump.h>
+#include <uapi/linux/coredump.h>
#include <asm/siginfo.h>
#ifdef CONFIG_COREDUMP
+/**
+ * enum coredump_state - what happened while the coredump was written
+ * @COREDUMP_STATE_STARTED: the dumper committed to writing a coredump
+ * @COREDUMP_STATE_TRUNCATED: the dumper stopped before it had written all of it
+ */
+enum coredump_state {
+ COREDUMP_STATE_STARTED = (1U << 0),
+ COREDUMP_STATE_TRUNCATED = (1U << 1),
+};
+
struct core_vma_metadata {
unsigned long start, end;
vm_flags_t flags;
@@ -21,18 +33,27 @@ struct coredump_params {
const kernel_siginfo_t *siginfo;
struct file *file;
unsigned long limit;
- /* MMF_DUMP_FILTER_* bits, snapshot of mm->flags at dump start. */
- unsigned long mm_flags;
+ /* COREDUMP_MEMORY_* types to dump, the task's or the server's. */
+ u64 memory_types;
/* Snapshot of dumpable at dump start. */
enum task_dumpable dumpable;
int cpu;
+ /* COREDUMP_* options negotiated with the coredump server. */
+ u64 mask;
+ /* COREDUMP_STATE_* raised while the coredump is written. */
+ enum coredump_state state;
+ /* Record header scratch, NULL unless the coredump is a record stream. */
+ struct coredump_record_header *record_hdr;
+ /* Bytes handed to the file, record headers included. */
loff_t written;
+ /* Offset in the coredump, record headers excluded. */
loff_t pos;
loff_t to_skip;
int vma_count;
size_t vma_data_size;
struct core_vma_metadata *vma_meta;
- struct pid *pid;
+ /* Dumping thread and its thread-group leader by pid type. */
+ DECLARE_PIDS(pid, PIDTYPE_TGID);
};
extern unsigned int core_file_note_size_limit;
@@ -41,13 +62,13 @@ extern unsigned int core_file_note_size_limit;
* These are the only things you should do on a core-file: use only these
* functions to write out all the necessary info.
*/
-extern void dump_skip_to(struct coredump_params *cprm, unsigned long to);
-extern void dump_skip(struct coredump_params *cprm, size_t nr);
-extern int dump_emit(struct coredump_params *cprm, const void *addr, int nr);
-extern int dump_align(struct coredump_params *cprm, int align);
-int dump_user_range(struct coredump_params *cprm, unsigned long start,
- unsigned long len);
-extern void vfs_coredump(const kernel_siginfo_t *siginfo);
+void dump_skip_to(struct coredump_params *cprm, unsigned long to);
+void dump_skip(struct coredump_params *cprm, size_t nr);
+bool dump_emit(struct coredump_params *cprm, const void *addr, int nr);
+bool dump_align(struct coredump_params *cprm, int align);
+bool dump_user_range(struct coredump_params *cprm, unsigned long start,
+ unsigned long len);
+void vfs_coredump(const kernel_siginfo_t *siginfo);
/*
* Logging for the coredump code, ratelimited.
diff --git a/include/linux/coresight.h b/include/linux/coresight.h
index ddf18c970e34..edf2a2fc697c 100644
--- a/include/linux/coresight.h
+++ b/include/linux/coresight.h
@@ -142,6 +142,8 @@ struct csdev_access {
})
#define CORESIGHT_DESC_CPU_BOUND BIT(0)
+/* Device can't be activated from sysfs, only via Perf. */
+#define CORESIGHT_DESC_NO_SYSFS_MODE BIT(1)
/**
* struct coresight_desc - description of a component required from drivers
@@ -310,6 +312,8 @@ struct coresight_device {
struct list_head config_csdev_list;
raw_spinlock_t cscfg_csdev_lock;
void *active_cscfg_ctxt;
+ /* CORESIGHT_DESC_[x] flags */
+ u32 flags;
};
/*
diff --git a/include/linux/cpufreq.h b/include/linux/cpufreq.h
index 35ce665edfd8..d3d0d9d02aa4 100644
--- a/include/linux/cpufreq.h
+++ b/include/linux/cpufreq.h
@@ -420,6 +420,9 @@ struct cpufreq_driver {
/* Will be called after the driver is fully initialized */
void (*ready)(struct cpufreq_policy *policy);
+ /* Return the capacity reference frequency for policy. */
+ unsigned int (*scale_freq_ref)(struct cpufreq_policy *policy);
+
struct freq_attr **attr;
/* platform specific boost support code */
diff --git a/include/linux/cpuhotplug.h b/include/linux/cpuhotplug.h
index feb32949aeea..1b6dba159bb2 100644
--- a/include/linux/cpuhotplug.h
+++ b/include/linux/cpuhotplug.h
@@ -209,12 +209,6 @@ enum cpuhp_state {
CPUHP_AP_PERF_S390_SF_ONLINE,
CPUHP_AP_PERF_ARM_CCI_ONLINE,
CPUHP_AP_PERF_ARM_CCN_ONLINE,
- CPUHP_AP_PERF_ARM_HISI_CPA_ONLINE,
- CPUHP_AP_PERF_ARM_HISI_DDRC_ONLINE,
- CPUHP_AP_PERF_ARM_HISI_HHA_ONLINE,
- CPUHP_AP_PERF_ARM_HISI_L3_ONLINE,
- CPUHP_AP_PERF_ARM_HISI_PA_ONLINE,
- CPUHP_AP_PERF_ARM_HISI_SLLC_ONLINE,
CPUHP_AP_PERF_ARM_HISI_PCIE_PMU_ONLINE,
CPUHP_AP_PERF_ARM_HNS3_PMU_ONLINE,
CPUHP_AP_PERF_ARM_L2X0_ONLINE,
diff --git a/include/linux/cpumask.h b/include/linux/cpumask.h
index 4c8bb6953107..bf89bb3f30f6 100644
--- a/include/linux/cpumask.h
+++ b/include/linux/cpumask.h
@@ -121,12 +121,20 @@ extern struct cpumask __cpu_enabled_mask;
extern struct cpumask __cpu_present_mask;
extern struct cpumask __cpu_active_mask;
extern struct cpumask __cpu_dying_mask;
+
+#ifdef CONFIG_PREFERRED_CPU
+extern struct cpumask __cpu_preferred_mask;
+#else
+#define __cpu_preferred_mask __cpu_active_mask
+#endif
+
#define cpu_possible_mask ((const struct cpumask *)&__cpu_possible_mask)
#define cpu_online_mask ((const struct cpumask *)&__cpu_online_mask)
#define cpu_enabled_mask ((const struct cpumask *)&__cpu_enabled_mask)
#define cpu_present_mask ((const struct cpumask *)&__cpu_present_mask)
#define cpu_active_mask ((const struct cpumask *)&__cpu_active_mask)
#define cpu_dying_mask ((const struct cpumask *)&__cpu_dying_mask)
+#define cpu_preferred_mask ((const struct cpumask *)&__cpu_preferred_mask)
extern atomic_t __num_online_cpus;
extern unsigned int __num_possible_cpus;
@@ -825,6 +833,24 @@ bool cpumask_intersects(const struct cpumask *src1p, const struct cpumask *src2p
}
/**
+ * cpumask_intersects_and - (*src1p & *src2p & *src3p) != 0
+ * @src1p: the first input
+ * @src2p: the second input
+ * @src3p: the third input
+ *
+ * Return: true if AND of the three cpumasks is non-empty,
+ * otherwise false
+ */
+static __always_inline
+bool cpumask_intersects_and(const struct cpumask *src1p,
+ const struct cpumask *src2p,
+ const struct cpumask *src3p)
+{
+ return bitmap_intersects_and(cpumask_bits(src1p), cpumask_bits(src2p),
+ cpumask_bits(src3p), small_cpumask_bits);
+}
+
+/**
* cpumask_subset - (*src1p & ~*src2p) == 0
* @src1p: the first input
* @src2p: the second input
@@ -1163,6 +1189,12 @@ void init_cpu_possible(const struct cpumask *src);
#define set_cpu_active(cpu, active) assign_cpu((cpu), &__cpu_active_mask, (active))
#define set_cpu_dying(cpu, dying) assign_cpu((cpu), &__cpu_dying_mask, (dying))
+#ifdef CONFIG_PREFERRED_CPU
+#define set_cpu_preferred(cpu, preferred) assign_cpu((cpu), &__cpu_preferred_mask, (preferred))
+#else
+#define set_cpu_preferred(cpu, preferred) do { } while (0)
+#endif
+
void set_cpu_online(unsigned int cpu, bool online);
void set_cpu_possible(unsigned int cpu, bool possible);
@@ -1257,6 +1289,11 @@ static __always_inline bool cpu_dying(unsigned int cpu)
return cpumask_test_cpu(cpu, cpu_dying_mask);
}
+static __always_inline bool cpu_preferred(unsigned int cpu)
+{
+ return cpumask_test_cpu(cpu, cpu_preferred_mask);
+}
+
#else
#define num_online_cpus() 1U
@@ -1295,6 +1332,11 @@ static __always_inline bool cpu_dying(unsigned int cpu)
return false;
}
+static __always_inline bool cpu_preferred(unsigned int cpu)
+{
+ return cpu == 0;
+}
+
#endif /* NR_CPUS > 1 */
#define cpu_is_offline(cpu) unlikely(!cpu_online(cpu))
diff --git a/include/linux/cred.h b/include/linux/cred.h
index 6ef1750c93e2..49c26af37349 100644
--- a/include/linux/cred.h
+++ b/include/linux/cred.h
@@ -180,12 +180,18 @@ static inline bool cap_ambient_invariant_ok(const struct cred *cred)
static inline const struct cred *override_creds(const struct cred *override_cred)
{
- return rcu_replace_pointer(current->cred, override_cred, 1);
+ const struct cred *old = current->cred;
+
+ current->cred = override_cred;
+ return old;
}
static inline const struct cred *revert_creds(const struct cred *revert_cred)
{
- return rcu_replace_pointer(current->cred, revert_cred, 1);
+ const struct cred *override_cred = current->cred;
+
+ current->cred = revert_cred;
+ return override_cred;
}
DEFINE_CLASS(override_creds,
@@ -293,11 +299,10 @@ DEFINE_FREE(put_cred, struct cred *, if (!IS_ERR_OR_NULL(_T)) put_cred(_T))
/**
* current_cred - Access the current task's subjective credentials
*
- * Access the subjective credentials of the current task. RCU-safe,
- * since nobody else can modify it.
+ * Access the subjective credentials of the current task.
+ * Nobody else can modify it.
*/
-#define current_cred() \
- rcu_dereference_protected(current->cred, 1)
+#define current_cred() (current->cred)
/**
* current_real_cred - Access the current task's objective credentials
diff --git a/include/linux/damon.h b/include/linux/damon.h
index 0c8b7ddef9ab..844b175120f0 100644
--- a/include/linux/damon.h
+++ b/include/linux/damon.h
@@ -153,6 +153,7 @@ enum damos_action {
* @DAMOS_QUOTA_INACTIVE_MEM_BP: Inactive to total LRU memory ratio.
* @DAMOS_QUOTA_NODE_ELIGIBLE_MEM_BP: Scheme-eligible memory ratio of a
* node in basis points (0-10000).
+ * @DAMOS_QUOTA_HUGEPAGE_MEM_BP: Huge page to total used memory ratio.
* @NR_DAMOS_QUOTA_GOAL_METRICS: Number of DAMOS quota goal metrics.
*
* Metrics equal to larger than @NR_DAMOS_QUOTA_GOAL_METRICS are unsupported.
@@ -167,6 +168,7 @@ enum damos_quota_goal_metric {
DAMOS_QUOTA_ACTIVE_MEM_BP,
DAMOS_QUOTA_INACTIVE_MEM_BP,
DAMOS_QUOTA_NODE_ELIGIBLE_MEM_BP,
+ DAMOS_QUOTA_HUGEPAGE_MEM_BP,
NR_DAMOS_QUOTA_GOAL_METRICS,
};
@@ -357,7 +359,8 @@ struct damos_watermarks {
* Total bytes that passed ops layer-handled DAMOS filters.
* @qt_exceeds: Total number of times the quota of the scheme has exceeded.
* @nr_snapshots:
- * Total number of DAMON snapshots that the scheme has tried.
+ * Total number of DAMON snapshots that the scheme is completely
+ * tried to be applied.
*
* "Tried an action to a region" in this context means the DAMOS core logic
* determined the region as eligible to apply the action. The access pattern
@@ -396,14 +399,14 @@ struct damos_stat {
* @DAMOS_FILTER_TYPE_UNMAPPED: Unmapped pages.
* @DAMOS_FILTER_TYPE_ADDR: Address range.
* @DAMOS_FILTER_TYPE_TARGET: Data Access Monitoring target.
- * @NR_DAMOS_FILTER_TYPES: Number of filter types.
+ * @DAMOS_FILTER_TYPE_PROBE_HITS_WSUM: probe_hits weighted sum range.
*
- * All types except &DAMOS_FILTER_TYPE_ADDR and &DAMOS_FILTER_TYPE_TARGET
- * are handled by the underlying &struct damon_operations as a part of scheme
- * action trying, and therefore accounted as 'tried'. In contrast,
- * &DAMOS_FILTER_TYPE_ADDR and &DAMOS_FILTER_TYPE_TARGET filters are handled
- * by the core layer before trying of the action, and therefore not accounted
- * as 'tried'.
+ * All types except &DAMOS_FILTER_TYPE_ADDR, &DAMOS_FILTER_TYPE_TARGET and
+ * &DAMOS_FILTER_TYPE_PROBE_HITS_WSUM are handled by the underlying &struct
+ * damon_operations as a part of scheme action trying, and therefore accounted
+ * as 'tried'. In contrast, &DAMOS_FILTER_TYPE_ADDR, &DAMOS_FILTER_TYPE_TARGET
+ * and &DAMOS_FILTER_TYPE_PROBE_HITS_WSUM filters are handled by the core layer
+ * before trying of the action, and therefore not accounted as 'tried'.
*
* Support for the operations-handled filters depends on the running
* &struct damon_operations.
@@ -417,7 +420,7 @@ enum damos_filter_type {
DAMOS_FILTER_TYPE_UNMAPPED,
DAMOS_FILTER_TYPE_ADDR,
DAMOS_FILTER_TYPE_TARGET,
- NR_DAMOS_FILTER_TYPES,
+ DAMOS_FILTER_TYPE_PROBE_HITS_WSUM,
};
/**
@@ -431,6 +434,8 @@ enum damos_filter_type {
* &damon_ctx->adaptive_targets if @type is
* DAMOS_FILTER_TYPE_TARGET.
* @sz_range: Size range if @type is DAMOS_FILTER_TYPE_HUGEPAGE_SIZE.
+ * @range_min: Minimum value of range arguments.
+ * @range_max: Maximum value of range arguments.
*
* Before applying the &damos->action to a memory region, DAMOS checks if each
* byte of the region matches to this given condition and avoid applying the
@@ -447,6 +452,10 @@ struct damos_filter {
struct damon_addr_range addr_range;
int target_idx;
struct damon_size_range sz_range;
+ struct {
+ unsigned long range_min;
+ unsigned long range_max;
+ };
};
/* private: */
/* List head for siblings. */
@@ -548,7 +557,7 @@ struct damos_migrate_dests {
*
* After applying the &action to each region, &stat is updated.
*
- * If &max_nr_snapshots is set as non-zero and &stat.nr_snapshots be same to or
+ * If &max_nr_snapshots is set as non-zero and &stat.nr_snapshots equals or is
* greater than it, the scheme is deactivated.
*/
struct damos {
@@ -627,6 +636,7 @@ enum damon_ops_id {
* @update: Update operations-related data structures.
* @prepare_access_checks: Prepare next access check of target regions.
* @check_accesses: Check the accesses to target regions.
+ * @prep_probes: Prepare applying probes for each region.
* @apply_probes: Apply probes for each region.
* @get_scheme_score: Get the score of a region for a scheme.
* @apply_scheme: Apply a DAMON-based operation scheme.
@@ -654,6 +664,9 @@ enum damon_ops_id {
* last preparation and update the number of observed accesses of each region.
* It should also return max number of observed accesses that made as a result
* of its update. The value will be used for regions adjustment threshold.
+ * @prep_probes should execute required &struct damon_prep for next &struct
+ * damon_probe applications to each region. It should also set
+ * &damon_region->sampling_addr of each region if ``set_samples`` is true.
* @apply_probes should apply the data attribute probes to each region and
* accordingly update the probe hits counter of the region. It should also
* set &damon_region->sampling_addr of each region if ``set_samples`` is true.
@@ -676,6 +689,7 @@ struct damon_operations {
void (*update)(struct damon_ctx *context);
void (*prepare_access_checks)(struct damon_ctx *context);
unsigned int (*check_accesses)(struct damon_ctx *context);
+ void (*prep_probes)(struct damon_ctx *context, bool set_samples);
unsigned int (*apply_probes)(struct damon_ctx *context,
bool set_samples, bool return_max_wsum);
int (*get_scheme_score)(struct damon_ctx *context,
@@ -740,14 +754,41 @@ struct damon_intervals_goal {
};
/**
+ * enum damon_prep_action - DAMON probing preparation action.
+ *
+ * @DAMON_PREP_SET_PGIDLE: Set the probing memory as idle page.
+ */
+enum damon_prep_action {
+ DAMON_PREP_SET_PGIDLE,
+};
+
+/**
+ * struct damon_prep - DAMON probing preparation request.
+ *
+ * @action: Action to do to the probing memory for the preparation.
+ */
+struct damon_prep {
+ enum damon_prep_action action;
+/* private: */
+ /* siblings list. */
+ struct list_head list;
+};
+
+/**
* enum damon_filter_type - Type of &struct damon_filter
*
- * @DAMON_FILTER_TYPE_ANON: Anonymous pages.
- * @DAMON_FILTER_TYPE_MEMCG: Specific memcg's pages.
+ * @DAMON_FILTER_TYPE_ANON: Anonymous pages.
+ * @DAMON_FILTER_TYPE_MEMCG: Specific memcg's pages.
+ * @DAMON_FILTER_TYPE_PGIDLE_UNSET: Pgidle is unset.
+ * @DAMON_FILTER_TYPE_PGIDLE_SET: Pgidle is set.
+ * @DAMON_FILTER_TYPE_HUGEPAGE_SIZE: Page is part of a hugepage.
*/
enum damon_filter_type {
DAMON_FILTER_TYPE_ANON,
DAMON_FILTER_TYPE_MEMCG,
+ DAMON_FILTER_TYPE_PGIDLE_UNSET,
+ DAMON_FILTER_TYPE_PGIDLE_SET,
+ DAMON_FILTER_TYPE_HUGEPAGE_SIZE,
};
/**
@@ -757,6 +798,8 @@ enum damon_filter_type {
* @matching: Whether this filter is for the type-matching ones.
* @allow: Whether the @type-@matching ones should pass this filter.
* @memcg_id: Memcg id of the question if @type is DAMON_FILTER_MEMCG.
+ * @range_min: Minimum value of range arguments.
+ * @range_max: Maximum value of range arguments.
*/
struct damon_filter {
enum damon_filter_type type;
@@ -764,6 +807,10 @@ struct damon_filter {
bool allow;
union {
u64 memcg_id;
+ struct {
+ unsigned long range_min;
+ unsigned long range_max;
+ };
};
/* private: */
/* Siblings list. */
@@ -778,6 +825,8 @@ struct damon_filter {
struct damon_probe {
unsigned int weight;
/* private: */
+ /* Preparation actions to apply to each probing memory. */
+ struct list_head preps;
/* Filters for assessing if a given region is for this probe. */
struct list_head filters;
/* Siblings list. */
@@ -787,7 +836,8 @@ struct damon_probe {
/**
* struct damon_attrs - Monitoring attributes for accuracy/overhead control.
*
- * @sample_interval: The time between access samplings.
+ * @sample_interval: The time between access samplings. Zero is
+ * accepted.
* @aggr_interval: The time between monitor results aggregations.
* @ops_update_interval: The time between monitoring operations updates.
* @intervals_goal: Intervals auto-tuning goal.
@@ -957,6 +1007,12 @@ static inline unsigned long damon_sz_region(struct damon_region *r)
return r->ar.end - r->ar.start;
}
+#define damon_for_each_prep(p, probe) \
+ list_for_each_entry(p, &(probe)->preps, list)
+
+#define damon_for_each_prep_safe(p, next, probe) \
+ list_for_each_entry_safe(p, next, &(probe)->preps, list)
+
#define damon_for_each_filter(f, p) \
list_for_each_entry(f, &(p)->filters, list)
@@ -1010,6 +1066,9 @@ static inline unsigned long damon_sz_region(struct damon_region *r)
#ifdef CONFIG_DAMON
+struct damon_prep *damon_new_prep(enum damon_prep_action action);
+void damon_add_prep(struct damon_probe *p, struct damon_prep *prep);
+
struct damon_filter *damon_new_filter(enum damon_filter_type type,
bool matching, bool allow);
void damon_add_filter(struct damon_probe *probe, struct damon_filter *f);
@@ -1023,7 +1082,7 @@ unsigned int damon_nr_accesses_mvsum(struct damon_region *r,
struct damon_ctx *ctx);
unsigned char damon_probe_hits_mvsum(int probe_idx, struct damon_region *r,
struct damon_ctx *ctx);
-unsigned int damon_probe_hits_wsum(struct damon_region *r, bool last,
+unsigned int damon_probe_hits_wsum(struct damon_region *r, bool last, bool mv,
struct damon_ctx *ctx);
int damon_set_regions(struct damon_target *t, struct damon_addr_range *ranges,
@@ -1054,7 +1113,7 @@ int damos_commit_quota_goals(struct damos_quota *dst, struct damos_quota *src);
struct damon_target *damon_new_target(void);
void damon_add_target(struct damon_ctx *ctx, struct damon_target *t);
-bool damon_targets_empty(struct damon_ctx *ctx);
+int damon_set_target_pid(struct damon_target *t, int pid);
void damon_free_target(struct damon_target *t);
void damon_destroy_target(struct damon_target *t, struct damon_ctx *ctx);
unsigned int damon_nr_regions(struct damon_target *t);
@@ -1065,7 +1124,6 @@ int damon_set_attrs(struct damon_ctx *ctx, struct damon_attrs *attrs);
void damon_set_schemes(struct damon_ctx *ctx,
struct damos **schemes, ssize_t nr_schemes);
int damon_commit_ctx(struct damon_ctx *old_ctx, struct damon_ctx *new_ctx);
-int damon_nr_running_ctxs(void);
bool damon_is_registered_ops(enum damon_ops_id id);
int damon_register_ops(struct damon_operations *ops);
int damon_select_ops(struct damon_ctx *ctx, enum damon_ops_id id);
diff --git a/include/linux/dax.h b/include/linux/dax.h
index fe6c3ded1b50..f2d47975d905 100644
--- a/include/linux/dax.h
+++ b/include/linux/dax.h
@@ -155,8 +155,6 @@ int dax_writeback_mapping_range(struct address_space *mapping,
struct dax_device *dax_dev, struct writeback_control *wbc);
int dax_folio_reset_order(struct folio *folio);
-struct page *dax_layout_busy_page(struct address_space *mapping);
-struct page *dax_layout_busy_page_range(struct address_space *mapping, loff_t start, loff_t end);
dax_entry_t dax_lock_folio(struct folio *folio);
void dax_unlock_folio(struct folio *folio, dax_entry_t cookie);
dax_entry_t dax_lock_mapping_entry(struct address_space *mapping,
@@ -173,16 +171,6 @@ static inline int fs_dax_get(struct dax_device *dax_dev, void *holder,
{
return -EOPNOTSUPP;
}
-static inline struct page *dax_layout_busy_page(struct address_space *mapping)
-{
- return NULL;
-}
-
-static inline struct page *dax_layout_busy_page_range(struct address_space *mapping, pgoff_t start, pgoff_t nr_pages)
-{
- return NULL;
-}
-
static inline int dax_writeback_mapping_range(struct address_space *mapping,
struct dax_device *dax_dev, struct writeback_control *wbc)
{
diff --git a/include/linux/dcache.h b/include/linux/dcache.h
index 4b1ff99608e0..796282817181 100644
--- a/include/linux/dcache.h
+++ b/include/linux/dcache.h
@@ -116,6 +116,8 @@ struct dentry {
* possible!
*/
+ /* lockdep tracking of DCACHE_PAR_LOOKUP locks */
+ struct lockdep_map dep_map;
struct list_head d_lru; /* LRU list */
struct hlist_node d_sib; /* child of parent list */
struct hlist_head d_children; /* our children */
@@ -236,7 +238,9 @@ enum dentry_flags {
DCACHE_PAR_LOOKUP = BIT(24), /* being looked up (with parent locked shared) */
DCACHE_DENTRY_CURSOR = BIT(25),
DCACHE_NORCU = BIT(26), /* No RCU delay for freeing */
- DCACHE_PERSISTENT = BIT(27)
+ DCACHE_PERSISTENT = BIT(27),
+/* 28, 29, 30 free */
+ DCACHE_PRIVATE = BIT(31) /* fs-specific flag */
};
#define DCACHE_MANAGED_DENTRY \
@@ -257,7 +261,9 @@ extern void d_delete(struct dentry *);
extern struct dentry * d_alloc(struct dentry *, const struct qstr *);
extern struct dentry * d_alloc_anon(struct super_block *);
extern struct dentry * d_alloc_parallel(struct dentry *, const struct qstr *);
+extern struct dentry * d_alloc_trylock(struct dentry *, struct qstr *);
extern struct dentry * d_splice_alias(struct inode *, struct dentry *);
+struct dentry *d_duplicate(struct dentry *dentry);
/* weird procfs mess; *NOT* exported */
extern struct dentry * d_splice_alias_ops(struct inode *, struct dentry *,
const struct dentry_operations *);
@@ -553,6 +559,36 @@ static inline int simple_positive(const struct dentry *dentry)
unsigned long vfs_pressure_ratio(unsigned long val);
/**
+ * d_lookup_release - release ownership of DCACHE_PAR_LOOKUP lock
+ * @dentry: dentry that is locked
+ *
+ * If an in-lookup dentry is to be passed to another thread which
+ * will drop the in-lookup lock, then d_lookup_release() must be called
+ * to tell lockdep that this thread no lock holds the lock. The
+ * thread that receives the lock must call d_lookup_acquire() to
+ * acquire the lock.
+ */
+static inline void d_lookup_release(struct dentry *dentry)
+{
+ if (d_in_lookup(dentry))
+ lock_map_release(&dentry->dep_map);
+}
+
+/**
+ * d_lookup_acquire - acquire ownership of DCACHE_PAR_LOOKUP lock
+ * @dentry: dentry that is locked
+ *
+ * If an in-lookup dentry was passed to this thread, the
+ * d_lookup_acquire() must be called to tell lockdep that this
+ * thread now owns the DCACHE_PAR_LOOKUP lock.
+ */
+static inline void d_lookup_acquire(struct dentry *dentry)
+{
+ if (d_in_lookup(dentry))
+ lock_map_acquire_try(&dentry->dep_map);
+}
+
+/**
* d_inode - Get the actual inode of this dentry
* @dentry: The dentry to query
*
diff --git a/include/linux/device-id/apr.h b/include/linux/device-id/apr.h
deleted file mode 100644
index f282608ea018..000000000000
--- a/include/linux/device-id/apr.h
+++ /dev/null
@@ -1,21 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-#ifndef LINUX_DEVICE_ID_APR_H
-#define LINUX_DEVICE_ID_APR_H
-
-#ifdef __KERNEL__
-#include <linux/types.h>
-typedef unsigned long kernel_ulong_t;
-#endif
-
-#define APR_NAME_SIZE 32
-#define APR_MODULE_PREFIX "apr:"
-
-struct apr_device_id {
- char name[APR_NAME_SIZE];
- __u32 domain_id;
- __u32 svc_id;
- __u32 svc_version;
- kernel_ulong_t driver_data; /* Data private to the driver */
-};
-
-#endif /* ifndef LINUX_DEVICE_ID_APR_H */
diff --git a/include/linux/device-id/arm_smccc.h b/include/linux/device-id/arm_smccc.h
new file mode 100644
index 000000000000..a8579832fc1c
--- /dev/null
+++ b/include/linux/device-id/arm_smccc.h
@@ -0,0 +1,19 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef __LINUX_DEVICE_ID_ARM_SMCCC_H
+#define __LINUX_DEVICE_ID_ARM_SMCCC_H
+
+#ifdef __KERNEL__
+#include <linux/types.h>
+#endif
+
+#define ARM_SMCCC_MODULE_PREFIX "arm_smccc:"
+
+/**
+ * struct arm_smccc_device_id - Arm SMCCC bus device identifier
+ * @func_id: SMCCC function identifier
+ */
+struct arm_smccc_device_id {
+ __u32 func_id;
+};
+
+#endif /* __LINUX_DEVICE_ID_ARM_SMCCC_H */
diff --git a/include/linux/device-id/scmi.h b/include/linux/device-id/scmi.h
new file mode 100644
index 000000000000..1b4ccfa9dcc5
--- /dev/null
+++ b/include/linux/device-id/scmi.h
@@ -0,0 +1,17 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+#ifndef LINUX_DEVICE_ID_SCMI_H
+#define LINUX_DEVICE_ID_SCMI_H
+
+#ifdef __KERNEL__
+#include <linux/types.h>
+#endif
+
+#define SCMI_NAME_SIZE 32
+#define SCMI_MODULE_PREFIX "scmi:"
+
+struct scmi_device_id {
+ __u8 protocol_id;
+ char name[SCMI_NAME_SIZE];
+};
+
+#endif /* ifndef LINUX_DEVICE_ID_SCMI_H */
diff --git a/include/linux/device.h b/include/linux/device.h
index aee79fd6b32b..90cdd77458bb 100644
--- a/include/linux/device.h
+++ b/include/linux/device.h
@@ -129,19 +129,19 @@ struct dev_ext_attribute {
void *var;
};
-ssize_t device_show_ulong(struct device *dev, struct device_attribute *attr,
+ssize_t device_show_ulong(struct device *dev, const struct device_attribute *attr,
char *buf);
-ssize_t device_store_ulong(struct device *dev, struct device_attribute *attr,
+ssize_t device_store_ulong(struct device *dev, const struct device_attribute *attr,
const char *buf, size_t count);
-ssize_t device_show_int(struct device *dev, struct device_attribute *attr,
+ssize_t device_show_int(struct device *dev, const struct device_attribute *attr,
char *buf);
-ssize_t device_store_int(struct device *dev, struct device_attribute *attr,
+ssize_t device_store_int(struct device *dev, const struct device_attribute *attr,
const char *buf, size_t count);
-ssize_t device_show_bool(struct device *dev, struct device_attribute *attr,
+ssize_t device_show_bool(struct device *dev, const struct device_attribute *attr,
char *buf);
-ssize_t device_store_bool(struct device *dev, struct device_attribute *attr,
+ssize_t device_store_bool(struct device *dev, const struct device_attribute *attr,
const char *buf, size_t count);
-ssize_t device_show_string(struct device *dev, struct device_attribute *attr,
+ssize_t device_show_string(struct device *dev, const struct device_attribute *attr,
char *buf);
typedef ssize_t __device_show_handler_const(struct device *dev, const struct device_attribute *attr,
diff --git a/include/linux/device/bus.h b/include/linux/device/bus.h
index a38f7229b8f4..89e156b9acb5 100644
--- a/include/linux/device/bus.h
+++ b/include/linux/device/bus.h
@@ -113,6 +113,7 @@ struct bus_type {
bool need_parent_lock;
};
+int __must_check companion_bus_register(const struct bus_type *bus);
int __must_check bus_register(const struct bus_type *bus);
void bus_unregister(const struct bus_type *bus);
diff --git a/include/linux/device/devres.h b/include/linux/device/devres.h
index 14ab9159bdda..7656c9ecd4da 100644
--- a/include/linux/device/devres.h
+++ b/include/linux/device/devres.h
@@ -62,6 +62,108 @@ static inline void *devm_kcalloc(struct device *dev, size_t n, size_t size, gfp_
{
return devm_kmalloc_array(dev, n, size, flags | __GFP_ZERO);
}
+
+/**
+ * __devm_alloc_objs - Device-managed allocation of objects of a given type
+ * @DEVM_ALLOC: which device-managed size-based allocator to use.
+ * @DEV: device to scope the allocation lifetime to.
+ * @GFP: GFP flags for the allocation.
+ * @TYPE: type to allocate space for.
+ * @COUNT: how many @TYPE objects to allocate.
+ *
+ * Device-managed counterpart of __alloc_objs().
+ * @DEVM_ALLOC takes (@DEV, size, gfp).
+ *
+ * Returns: Newly allocated pointer to (first) @TYPE of @COUNT-many allocated
+ * @TYPE objects, or NULL on failure.
+ */
+#define __devm_alloc_objs(DEVM_ALLOC, DEV, GFP, TYPE, COUNT) \
+({ \
+ const size_t __obj_size = size_mul(sizeof(TYPE), COUNT); \
+ (TYPE *)DEVM_ALLOC(DEV, __obj_size, GFP); \
+})
+
+/**
+ * devm_kmalloc_obj - Device-managed allocation of a single typed object
+ * @DEV: Device to scope the allocation lifetime to.
+ * @VAR_OR_TYPE: Variable or type to allocate.
+ * @GFP: Optional GFP flags (defaults to %GFP_KERNEL).
+ *
+ * Device-managed counterpart of kmalloc_obj(): the allocation is sized from
+ * @VAR_OR_TYPE and returned as a pointer to that type, not void *.
+ *
+ * Returns: newly allocated pointer to a @VAR_OR_TYPE on success, or NULL on
+ * failure.
+ */
+#define devm_kmalloc_obj(DEV, VAR_OR_TYPE, ...) \
+ __devm_alloc_objs(devm_kmalloc, DEV, default_gfp(__VA_ARGS__), \
+ typeof(VAR_OR_TYPE), 1)
+
+/**
+ * devm_kmalloc_objs - Device-managed allocation of an array of a typed object
+ * @DEV: Device to scope the allocation lifetime to.
+ * @VAR_OR_TYPE: Variable or type to allocate an array of.
+ * @COUNT: How many elements in the array.
+ * @GFP: Optional GFP flags (defaults to %GFP_KERNEL).
+ *
+ * Returns: newly allocated pointer to an array of @VAR_OR_TYPE on success, or
+ * NULL on failure (including when the total size overflows).
+ */
+#define devm_kmalloc_objs(DEV, VAR_OR_TYPE, COUNT, ...) \
+ __devm_alloc_objs(devm_kmalloc, DEV, default_gfp(__VA_ARGS__), \
+ typeof(VAR_OR_TYPE), COUNT)
+
+/**
+ * __devm_alloc_flex - Device-managed allocation of a trailing-flex-array object
+ * @DEVM_ALLOC: which device-managed allocator to use.
+ * @DEV: device to scope the allocation lifetime to.
+ * @GFP: GFP flags for the allocation.
+ * @TYPE: type of structure to allocate space for.
+ * @FAM: name of the flexible array member of @TYPE.
+ * @COUNT: how many @FAM elements to allocate space for.
+ *
+ * Device-managed counterpart of __alloc_flex().
+ * @DEVM_ALLOC takes (@DEV, size, gfp).
+ *
+ * Returns: Newly allocated pointer to @TYPE with @COUNT-many trailing @FAM
+ * elements, or NULL on failure.
+ */
+#define __devm_alloc_flex(DEVM_ALLOC, DEV, GFP, TYPE, FAM, COUNT) \
+({ \
+ const size_t __count = (COUNT); \
+ const size_t __obj_size = struct_size_t(TYPE, FAM, __count); \
+ TYPE *__obj_ptr = DEVM_ALLOC(DEV, __obj_size, GFP); \
+ if (__obj_ptr) \
+ __set_flex_counter(__obj_ptr->FAM, __count); \
+ __obj_ptr; \
+})
+
+/**
+ * devm_kmalloc_flex - Device-managed allocation of a flexible-array structure
+ * @DEV: Device to scope the allocation lifetime to.
+ * @VAR_OR_TYPE: Variable or type to allocate (with its flexible array).
+ * @FAM: The name of the flexible array member of the structure.
+ * @COUNT: How many flexible array member elements to allocate.
+ * @GFP: Optional GFP flags (defaults to %GFP_KERNEL).
+ *
+ * Returns: newly allocated pointer to @VAR_OR_TYPE on success, or NULL on
+ * failure. If @FAM has been annotated with __counted_by(), its counter is set
+ * to @COUNT.
+ */
+#define devm_kmalloc_flex(DEV, VAR_OR_TYPE, FAM, COUNT, ...) \
+ __devm_alloc_flex(devm_kmalloc, DEV, default_gfp(__VA_ARGS__), \
+ typeof(VAR_OR_TYPE), FAM, COUNT)
+
+/* All devm_kzalloc aliases for devm_kmalloc_(obj|objs|flex). */
+#define devm_kzalloc_obj(DEV, P, ...) \
+ __devm_alloc_objs(devm_kzalloc, DEV, default_gfp(__VA_ARGS__), typeof(P), 1)
+#define devm_kzalloc_objs(DEV, P, COUNT, ...) \
+ __devm_alloc_objs(devm_kzalloc, DEV, default_gfp(__VA_ARGS__), \
+ typeof(P), COUNT)
+#define devm_kzalloc_flex(DEV, P, FAM, COUNT, ...) \
+ __devm_alloc_flex(devm_kzalloc, DEV, default_gfp(__VA_ARGS__), \
+ typeof(P), FAM, COUNT)
+
static inline __realloc_size(3, 4) void * __must_check
devm_krealloc_array(struct device *dev, void *p, size_t new_n, size_t new_size, gfp_t flags)
{
diff --git a/include/linux/dibs.h b/include/linux/dibs.h
index d3e0777f25ae..0c10c224bcca 100644
--- a/include/linux/dibs.h
+++ b/include/linux/dibs.h
@@ -261,12 +261,12 @@ struct dibs_dev_ops {
* @vlan_id: deprecated, ignored if device does not support vlan
* Upon return in addition the following fields will be valid:
* @dmb_tok: for usage by remote and local devices and clients
- * @cpu_addr: allocated buffer
+ * @cpu_addr: allocated, zerorized buffer
* @idx: dmb index, unique per dibs device
* @dma_addr: to be used by device driver,if applicable
*
- * Allocate a dmb buffer and register it with this device and for this
- * client.
+ * Allocate and zerorize a dmb buffer and register it with this device
+ * and for this client.
* Return: zero on success
*/
int (*register_dmb)(struct dibs_dev *dev, struct dibs_dmb *dmb,
diff --git a/include/linux/dma-fence.h b/include/linux/dma-fence.h
index 158cd609f103..dd07d128adc3 100644
--- a/include/linux/dma-fence.h
+++ b/include/linux/dma-fence.h
@@ -141,6 +141,9 @@ struct dma_fence_ops {
* compute the name at runtime, without having it to store permanently
* for each fence, or build a cache of some sort.
*
+ * The returned string is RCU protected and can be freed after the fence
+ * signaled and a RCU grace period passed.
+ *
* This callback is mandatory.
*/
const char * (*get_driver_name)(struct dma_fence *fence);
@@ -153,6 +156,9 @@ struct dma_fence_ops {
* having it to store permanently for each fence, or build a cache of
* some sort.
*
+ * The returned string is RCU protected and can be freed after the fence
+ * signaled and a RCU grace period passed.
+ *
* This callback is mandatory.
*/
const char * (*get_timeline_name)(struct dma_fence *fence);
@@ -501,7 +507,7 @@ dma_fence_test_signaled_flag(struct dma_fence *fence)
* Returns true if the fence was already signaled, false if not. Since this
* function doesn't enable signaling, it is not guaranteed to ever return
* true if dma_fence_add_callback(), dma_fence_wait() or
- * dma_fence_enable_sw_signaling() haven't been called before.
+ * dma_fence_enable_signaling() haven't been called before.
*
* This function requires &dma_fence.lock to be held.
*
diff --git a/include/linux/dma-map-ops.h b/include/linux/dma-map-ops.h
index 8fae2b7deb20..afaf2c12189b 100644
--- a/include/linux/dma-map-ops.h
+++ b/include/linux/dma-map-ops.h
@@ -60,7 +60,7 @@ struct dma_map_ops {
int (*dma_supported)(struct device *dev, u64 mask);
u64 (*get_required_mask)(struct device *dev);
size_t (*max_mapping_size)(struct device *dev);
- size_t (*opt_mapping_size)(void);
+ size_t (*max_opt_mapping_size)(void);
unsigned long (*get_merge_boundary)(struct device *dev);
};
@@ -143,7 +143,7 @@ static inline struct page *dma_alloc_contiguous(struct device *dev, size_t size,
static inline void dma_free_contiguous(struct device *dev, struct page *page,
size_t size)
{
- __free_pages(page, get_order(size));
+ free_pages_exact(page_address(page), size);
}
#endif /* CONFIG_DMA_CMA*/
diff --git a/include/linux/dma-mapping.h b/include/linux/dma-mapping.h
index a3e880649fa4..efde0e5a58dc 100644
--- a/include/linux/dma-mapping.h
+++ b/include/linux/dma-mapping.h
@@ -207,7 +207,7 @@ int dma_set_coherent_mask(struct device *dev, u64 mask);
u64 dma_get_required_mask(struct device *dev);
bool dma_addressing_limited(struct device *dev);
size_t dma_max_mapping_size(struct device *dev);
-size_t dma_opt_mapping_size(struct device *dev);
+size_t dma_max_opt_mapping_size(struct device *dev);
unsigned long dma_get_merge_boundary(struct device *dev);
struct sg_table *dma_alloc_noncontiguous(struct device *dev, size_t size,
enum dma_data_direction dir, gfp_t gfp, unsigned long attrs);
@@ -326,7 +326,7 @@ static inline size_t dma_max_mapping_size(struct device *dev)
{
return 0;
}
-static inline size_t dma_opt_mapping_size(struct device *dev)
+static inline size_t dma_max_opt_mapping_size(struct device *dev)
{
return 0;
}
diff --git a/include/linux/dmaengine.h b/include/linux/dmaengine.h
index fe33a20abc61..f322e501ff62 100644
--- a/include/linux/dmaengine.h
+++ b/include/linux/dmaengine.h
@@ -1760,15 +1760,6 @@ void dma_run_dependencies(struct dma_async_tx_descriptor *tx);
#define dma_request_channel(mask, x, y) \
__dma_request_channel(&(mask), x, y, NULL)
-/* Deprecated, please use dma_request_chan() directly */
-static inline struct dma_chan * __deprecated
-dma_request_slave_channel(struct device *dev, const char *name)
-{
- struct dma_chan *ch = dma_request_chan(dev, name);
-
- return IS_ERR(ch) ? NULL : ch;
-}
-
static inline struct dma_chan
*dma_request_slave_channel_compat(const dma_cap_mask_t mask,
dma_filter_fn fn, void *fn_param,
diff --git a/include/linux/efi.h b/include/linux/efi.h
index aa15ff88539b..cc1df1577d5f 100644
--- a/include/linux/efi.h
+++ b/include/linux/efi.h
@@ -631,6 +631,8 @@ typedef struct {
extern unsigned long __ro_after_init efi_rng_seed; /* RNG Seed table */
+enum efi_rts_ids;
+
/*
* All runtime access to EFI goes through this structure:
*/
@@ -650,6 +652,7 @@ extern struct efi {
unsigned long mokvar_table; /* MOK variable config table */
unsigned long coco_secret; /* Confidential computing secret table */
unsigned long unaccepted; /* Unaccepted memory table */
+ unsigned long mem_reserve; /* Persistent memory reservations */
efi_get_time_t *get_time;
efi_set_time_t *set_time;
@@ -666,6 +669,10 @@ extern struct efi {
efi_get_next_high_mono_count_t *get_next_high_mono_count;
efi_reset_system_t *reset_system;
+#if IS_ENABLED(CONFIG_LKDTM)
+ efi_status_t (*lkdtm_rt_test)(enum efi_rts_ids id);
+#endif
+
struct efi_memory_map memmap;
unsigned long flags;
} efi;
@@ -957,6 +964,17 @@ extern int efi_status_to_err(efi_status_t status);
#define EFI_DEV_END_INSTANCE 0x01
#define EFI_DEV_END_ENTIRE 0xFF
+enum efi_hd_partition_format {
+ EFI_HD_PARTITION_FORMAT_MBR = 1,
+ EFI_HD_PARTITION_FORMAT_GPT,
+};
+
+enum efi_hd_signature_type {
+ EFI_HD_SIGNATURE_TYPE_NONE,
+ EFI_HD_SIGNATURE_TYPE_MBR,
+ EFI_HD_SIGNATURE_TYPE_GUID,
+};
+
struct efi_generic_dev_path {
u8 type;
u8 sub_type;
@@ -988,6 +1006,16 @@ struct efi_rel_offset_dev_path {
u64 ending_offset;
} __packed;
+struct efi_hd_dev_path {
+ struct efi_generic_dev_path header;
+ u32 partition_number;
+ u64 partition_start;
+ u64 partition_size;
+ efi_guid_t signature;
+ u8 partition_format;
+ u8 signature_type;
+} __packed;
+
struct efi_mem_mapped_dev_path {
struct efi_generic_dev_path header;
u32 memory_type;
@@ -1007,6 +1035,7 @@ struct efi_dev_path {
struct efi_pci_dev_path pci;
struct efi_vendor_dev_path vendor;
struct efi_rel_offset_dev_path rel_offset;
+ struct efi_hd_dev_path hd;
};
} __packed;
@@ -1109,6 +1138,7 @@ extern void efi_call_virt_check_flags(unsigned long flags, const void *caller);
extern unsigned long efi_call_virt_save_flags(void);
void efi_runtime_assert_lock_held(void);
+efi_status_t efi_runtime_set_enable_flag(bool enable);
enum efi_secureboot_mode {
efi_secureboot_mode_unset,
@@ -1230,6 +1260,10 @@ enum efi_rts_ids {
EFI_UPDATE_CAPSULE,
EFI_QUERY_CAPSULE_CAPS,
EFI_ACPI_PRM_HANDLER,
+#if IS_ENABLED(CONFIG_LKDTM)
+ EFI_LKDTM_RUNTIME_RO_TEST,
+ EFI_LKDTM_RUNTIME_NX_TEST,
+#endif
};
union efi_rts_args;
@@ -1330,7 +1364,8 @@ bool efi_config_table_is_usable(const efi_guid_t *guid, unsigned long table)
return xen_efi_config_table_is_usable(guid, table);
}
-umode_t efi_attr_is_visible(struct kobject *kobj, struct attribute *attr, int n);
+umode_t efi_attr_is_visible(struct kobject *kobj, const struct attribute *attr,
+ int n);
int ovmf_log_probe(unsigned long ovmf_debug_log_table);
diff --git a/include/linux/entry-common.h b/include/linux/entry-common.h
index 6574b7183c01..fa2854fed1f2 100644
--- a/include/linux/entry-common.h
+++ b/include/linux/entry-common.h
@@ -102,7 +102,14 @@ static __always_inline long syscall_trace_enter(struct pt_regs *regs, unsigned l
if (unlikely(work & SYSCALL_WORK_SYSCALL_TRACEPOINT))
trace_syscall_enter(regs);
- if (unlikely(audit_context()))
+ /*
+ * The config check works around broken compilers which fail to
+ * eliminate the dead code in case of CONFIG_AUDITSYSCALL=n as they
+ * insist on creating a always false runtime condition based on
+ * audit_context() which returns NULL in that case. The explicit
+ * IS_ENABLED() check makes that madness go away.
+ */
+ if (IS_ENABLED(CONFIG_AUDITSYSCALL) && unlikely(audit_context()))
syscall_enter_audit(regs);
return true;
diff --git a/include/linux/ethtool.h b/include/linux/ethtool.h
index 12683b5d125e..c3a41fbd5426 100644
--- a/include/linux/ethtool.h
+++ b/include/linux/ethtool.h
@@ -944,6 +944,7 @@ struct kernel_ethtool_ts_info {
#define ETHTOOL_OP_NEEDS_RTNL_SPAUSEPARAM BIT(6)
#define ETHTOOL_OP_NEEDS_RTNL_RSS BIT(7)
#define ETHTOOL_OP_NEEDS_RTNL_GLINK BIT(8)
+#define ETHTOOL_OP_NEEDS_RTNL_TEST BIT(9)
/**
* struct ethtool_ops - optional netdev operations
@@ -981,6 +982,7 @@ struct kernel_ethtool_ts_info {
* - netdev_update_features()
* - netif_set_real_num_tx_queues()
* - ethtool_op_get_link() (syncs link watch under rtnl_lock)
+ * - netif_open() / netif_close() (used by @self_test)
*
* @get_drvinfo: Report driver/device information. Modern drivers no
* longer have to implement this callback. Most fields are
@@ -1023,7 +1025,9 @@ struct kernel_ethtool_ts_info {
* types should be set in @supported_coalesce_params.
* Returns a negative error code or zero.
* @get_ringparam: Report ring sizes
- * @set_ringparam: Set ring sizes. Returns a negative error code or zero.
+ * @set_ringparam: Set ring sizes. The &struct ethtool_ringparam argument is
+ * also an output; drivers which normalize requested sizes must update it
+ * with the applied sizes. Returns a negative error code or zero.
* @get_pause_stats: Report pause frame statistics. Drivers must not zero
* statistics which they don't report. The stats structure is initialized
* to ETHTOOL_STAT_NOT_SET indicating driver does not report statistics.
@@ -1057,6 +1061,12 @@ struct kernel_ethtool_ts_info {
* @get_sset_count: Get number of strings that @get_strings will write.
* @get_rxnfc: Get RX flow classification rules. Returns a negative
* error code or zero.
+ * Note that for %ETHTOOL_GRXCLSRLALL rule_cnt and size of the arrays
+ * is user-provided, and not guaranteed to match what driver would
+ * have reported via %ETHTOOL_GRXCLSRLCNT. Drivers must return -%EMSGSIZE
+ * when rule_cnt is too small. rule_locs is %NULL when rule_cnt is zero.
+ * On success drivers must set rule_cnt to the number of locations they
+ * filled in, the core copies out exactly that many.
* @set_rxnfc: Set RX flow classification rules. Returns a negative
* error code or zero.
* @flash_device: Write a firmware image to device's flash memory.
diff --git a/include/linux/fdtable.h b/include/linux/fdtable.h
index c45306a9f007..ba2536c3b911 100644
--- a/include/linux/fdtable.h
+++ b/include/linux/fdtable.h
@@ -25,7 +25,7 @@
struct fdtable {
unsigned int max_fds;
- struct file __rcu **fd; /* current fd array */
+ struct file __rcu **fd __counted_by_ptr(max_fds); /* current fd array */
unsigned long *close_on_exec;
unsigned long *open_fds;
unsigned long *full_fds_bits;
@@ -100,12 +100,22 @@ static inline bool close_on_exec(unsigned int fd, const struct files_struct *fil
struct task_struct;
void put_files_struct(struct files_struct *fs);
-int unshare_files(void);
+void switch_files_struct(struct task_struct *tsk, struct files_struct *files);
+int unshare_fd(unsigned long unshare_flags, struct files_struct **new_fdp);
+enum fd_range_flags {
+ /* Leave behind all descriptors outside of the specified range. */
+ FD_RANGE_EXCEPT = (1U << 0),
+
+ /* Only select descriptors that have close-on-exec set. */
+ FD_RANGE_CLOEXEC_ONLY = (1U << 1),
+};
+
struct fd_range {
unsigned int from, to;
+ enum fd_range_flags flags;
};
struct files_struct *dup_fd(struct files_struct *, struct fd_range *) __latent_entropy;
-void do_close_on_exec(struct files_struct *);
+void close_cloexec_files(struct files_struct *);
int iterate_fd(struct files_struct *, unsigned,
int (*)(const void *, struct file *, unsigned),
const void *);
diff --git a/include/linux/file.h b/include/linux/file.h
index 27484b444d31..41c3c0be1064 100644
--- a/include/linux/file.h
+++ b/include/linux/file.h
@@ -12,6 +12,7 @@
#include <linux/errno.h>
#include <linux/cleanup.h>
#include <linux/err.h>
+#include <linux/vfsdebug.h>
struct file;
@@ -129,117 +130,84 @@ extern unsigned int sysctl_nr_open_min, sysctl_nr_open_max;
/*
* fd_prepare: Combined fd + file allocation cleanup class.
- * @err: Error code to indicate if allocation succeeded.
- * @__fd: Allocated fd (may not be accessed directly)
- * @__file: Allocated struct file pointer (may not be accessed directly)
+ * @fd: Allocated fd
+ * @file: Allocated struct file pointer
*
* Allocates an fd and a file together. On error paths, automatically cleans
* up whichever resource was successfully allocated. Allows flexible file
* allocation with different functions per usage.
*
- * Do not use directly.
+ * Do not declare directly, use FD_PREPARE().
*/
struct fd_prepare {
- s32 err;
- s32 __fd; /* do not access directly */
- struct file *__file; /* do not access directly */
+ int fd;
+ struct file *file;
};
-/* Typedef for fd_prepare cleanup guards. */
-typedef struct fd_prepare class_fd_prepare_t;
-
-/*
- * Accessors for fd_prepare class members.
- * _Generic() is used for zero-cost type safety.
- */
-#define fd_prepare_fd(_fdf) \
- (_Generic((_fdf), struct fd_prepare: (_fdf).__fd))
-
-#define fd_prepare_file(_fdf) \
- (_Generic((_fdf), struct fd_prepare: (_fdf).__file))
-
/* Do not use directly. */
-static inline void class_fd_prepare_destructor(const struct fd_prepare *fdf)
+static __always_inline void __fd_prepare_cleanup(const struct fd_prepare *fdf)
{
- if (unlikely(fdf->__fd >= 0))
- put_unused_fd(fdf->__fd);
- if (unlikely(!IS_ERR_OR_NULL(fdf->__file)))
- fput(fdf->__file);
+ if (unlikely(fdf->fd >= 0)) {
+ put_unused_fd(fdf->fd);
+ fput(fdf->file);
+ }
}
/* Do not use directly. */
-static inline int class_fd_prepare_lock_err(const struct fd_prepare *fdf)
+static __always_inline struct fd_prepare __fd_prepare(int fd, struct file *file)
{
- if (unlikely(fdf->err))
- return fdf->err;
- if (unlikely(fdf->__fd < 0))
- return fdf->__fd;
- if (unlikely(IS_ERR(fdf->__file)))
- return PTR_ERR(fdf->__file);
- if (unlikely(!fdf->__file))
- return -ENOMEM;
- return 0;
+ if (fd >= 0 && IS_ERR_OR_NULL(file)) {
+ int err = file ? PTR_ERR(file) : -ENOMEM;
+
+ put_unused_fd(fd);
+ fd = err;
+ file = NULL;
+ }
+ return (struct fd_prepare){ .fd = fd, .file = file };
}
/*
- * __FD_PREPARE_INIT - Helper to initialize fd_prepare class.
- * @_fd_flags: flags for get_unused_fd_flags()
- * @_file_owned: expression that returns struct file *
- *
- * Returns a struct fd_prepare with fd, file, and err set.
- * If fd allocation fails, fd will be negative and err will be set. If
- * fd succeeds but file_init_expr fails, file will be ERR_PTR and err
- * will be set. The err field is the single source of truth for error
- * checking.
- */
-#define __FD_PREPARE_INIT(_fd_flags, _file_owned) \
- ({ \
- struct fd_prepare fdf = { \
- .__fd = get_unused_fd_flags((_fd_flags)), \
- }; \
- if (likely(fdf.__fd >= 0)) \
- fdf.__file = (_file_owned); \
- fdf.err = ACQUIRE_ERR(fd_prepare, &fdf); \
- fdf; \
- })
-
-/*
- * FD_PREPARE - Macro to declare and initialize an fd_prepare variable.
+ * FD_PREPARE - Declare and initialize an fd_prepare instance.
*
- * Declares and initializes an fd_prepare variable with automatic
- * cleanup. No separate scope required - cleanup happens when variable
- * goes out of scope.
+ * This allocates a new fd and only evaluates @_file_owned if the
+ * allocation succeeded. Cleanup happens when the variable goes out of
+ * scope and the guard releases whichever of the descriptor and the file
+ * was allocated. If fd_publish() was called the fd and file are
+ * published and cleanup becomes a nop.
*
- * @_fdf: name of struct fd_prepare variable to define
+ * @_fdf: name of the const struct fd_prepare pointer to define
* @_fd_flags: flags for get_unused_fd_flags()
* @_file_owned: struct file to take ownership of (can be expression)
*/
+#define __FD_PREPARE(_guard, _fdf, _fd_flags, _file_owned) \
+ struct fd_prepare _guard __cleanup(__fd_prepare_cleanup) = ({ \
+ int __fd = get_unused_fd_flags(_fd_flags); \
+ __fd_prepare(__fd, __fd < 0 ? NULL : (_file_owned)); \
+ }); \
+ const struct fd_prepare *const _fdf = &_guard
+
#define FD_PREPARE(_fdf, _fd_flags, _file_owned) \
- CLASS_INIT(fd_prepare, _fdf, __FD_PREPARE_INIT(_fd_flags, _file_owned))
+ __FD_PREPARE(__UNIQUE_ID(fd_prepare), _fdf, _fd_flags, _file_owned)
/*
* fd_publish - Publish prepared fd and file to the fd table.
- * @_fdf: struct fd_prepare variable
+ * @fdf: struct fd_prepare pointer defined by FD_PREPARE()
*/
-#define fd_publish(_fdf) \
- ({ \
- struct fd_prepare *fdp = &(_fdf); \
- VFS_WARN_ON_ONCE(fdp->err); \
- VFS_WARN_ON_ONCE(fdp->__fd < 0); \
- VFS_WARN_ON_ONCE(IS_ERR_OR_NULL(fdp->__file)); \
- fd_install(fdp->__fd, fdp->__file); \
- retain_and_null_ptr(fdp->__file); \
- take_fd(fdp->__fd); \
- })
+static __always_inline int fd_publish(const struct fd_prepare *fdf)
+{
+ /* Callers only get a const view, the guard itself is writable. */
+ struct fd_prepare *guard = (struct fd_prepare *)fdf;
+
+ VFS_WARN_ON_ONCE(guard->fd < 0);
+ fd_install(guard->fd, guard->file);
+ return take_fd(guard->fd);
+}
/* Do not use directly. */
-#define __FD_ADD(_fdf, _fd_flags, _file_owned) \
- ({ \
- FD_PREPARE(_fdf, _fd_flags, _file_owned); \
- s32 ret = _fdf.err; \
- if (likely(!ret)) \
- ret = fd_publish(_fdf); \
- ret; \
+#define __FD_ADD(_fdf, _fd_flags, _file_owned) \
+ ({ \
+ FD_PREPARE(_fdf, _fd_flags, _file_owned); \
+ _fdf->fd < 0 ? _fdf->fd : fd_publish(_fdf); \
})
/*
diff --git a/include/linux/fileattr.h b/include/linux/fileattr.h
index 58044b598016..09e32b84e02a 100644
--- a/include/linux/fileattr.h
+++ b/include/linux/fileattr.h
@@ -74,7 +74,7 @@ static inline bool fileattr_has_fsx(const struct file_kattr *fa)
}
int vfs_fileattr_get(struct dentry *dentry, struct file_kattr *fa);
-int vfs_fileattr_set(struct mnt_idmap *idmap, struct dentry *dentry,
+int vfs_fileattr_set(const struct mnt_idmap *idmap, struct dentry *dentry,
struct file_kattr *fa);
int ioctl_getflags(struct file *file, unsigned int __user *argp);
int ioctl_setflags(struct file *file, unsigned int __user *argp);
diff --git a/include/linux/filter.h b/include/linux/filter.h
index 39decde7fc73..e0218e677a1d 100644
--- a/include/linux/filter.h
+++ b/include/linux/filter.h
@@ -98,6 +98,11 @@ struct ctl_table_header;
/* BPF program can access up to 512 bytes of stack space. */
#define MAX_BPF_STACK 512
+/*
+ * Stack budget of a program on a JIT that lays out frames of that size.
+ * The interpreter and JITs without such support keep MAX_BPF_STACK.
+ */
+#define MAX_BPF_STACK_JIT 2048
/* Helper macros for filter block array initializers. */
@@ -249,6 +254,29 @@ static inline bool insn_is_mov_percpu_addr(const struct bpf_insn *insn)
.off = 0, \
.imm = 1 })
+static inline bool bpf_is_unwind_goto(const struct bpf_insn *insn)
+{
+ return insn->code == (BPF_JMP | BPF_JCOND) && insn->src_reg == BPF_UNWIND_GOTO;
+}
+
+static inline bool bpf_is_unwind_exit(const struct bpf_insn *insn)
+{
+ return insn->code == (BPF_JMP | BPF_EXIT) && insn->src_reg == BPF_UNWIND_EXIT;
+}
+
+/*
+ * The caller of the main prog doesn't tell unwind_exit from exit. An extension
+ * is different: its caller is the caller of the subprog that it replaced.
+ * An exception callback returns from the frame of the main prog. After freplace
+ * or a tail call it returns to a prog that wasn't verified with the callback.
+ */
+static inline bool bpf_prog_can_unwind(const struct bpf_prog *prog)
+{
+ if (prog->aux->exception_cb)
+ return false;
+ return bpf_is_subprog(prog) || prog->type == BPF_PROG_TYPE_EXT;
+}
+
static inline bool insn_is_zext(const struct bpf_insn *insn)
{
return insn->code == (BPF_ALU | BPF_MOV | BPF_X) && insn->imm == 1;
@@ -1105,6 +1133,19 @@ static inline unsigned int bpf_prog_size(unsigned int proglen)
offsetof(struct bpf_prog, insns[proglen]));
}
+bool bpf_prog_has_arena_insns(const struct bpf_prog *prog);
+
+/*
+ * Whether a JIT has to set up the arena base for @prog. A program bound to
+ * an arena need not touch it, libbpf binds the arena of an object to every
+ * program in it. The flag caches bpf_prog_has_arena_insns() for the function
+ * about to be JITed, see bpf_prog_jit_compile() and jit_subprogs().
+ */
+static inline bool bpf_prog_uses_arena_insns(const struct bpf_prog *prog)
+{
+ return prog->aux->uses_arena_insns;
+}
+
static inline bool bpf_prog_was_classic(const struct bpf_prog *prog)
{
/* When classic BPF programs have been loaded and the arch
@@ -1237,16 +1278,53 @@ bool bpf_jit_inlines_helper_call(s32 imm);
bool bpf_jit_supports_subprog_tailcalls(void);
bool bpf_jit_supports_percpu_insn(void);
bool bpf_jit_supports_kfunc_call(void);
+bool bpf_jit_supports_callx(void);
+bool bpf_jit_supports_kfunc_ret_reg_pair(void);
+bool bpf_jit_supports_unwind(void);
bool bpf_jit_supports_stack_args(void);
bool bpf_jit_supports_arena_args(void);
bool bpf_jit_supports_far_kfunc_call(void);
bool bpf_jit_supports_exceptions(void);
bool bpf_jit_supports_ptr_xchg(void);
bool bpf_jit_supports_arena(void);
+bool bpf_jit_supports_arena_scalar(void);
bool bpf_jit_supports_insn(struct bpf_insn *insn, bool in_arena);
bool bpf_jit_supports_private_stack(void);
+bool bpf_jit_supports_large_stack(void);
bool bpf_jit_supports_timed_may_goto(void);
bool bpf_jit_supports_fsession(void);
+
+struct bpf_jit_arg_abi {
+ /* Argument registers of the kernel convention. */
+ u8 nr_arg_regs;
+ /* Round the register number up to an even one for 16-byte alignment. */
+ bool even_reg_align;
+ /* Round the stack slot up to an even one for 16-byte alignment. */
+ bool even_stack_align;
+ /* An argument may straddle the last register and the stack. */
+ bool split_at_boundary;
+ /* A later argument may reuse a register a stack-passed one skipped. */
+ bool backfill_after_stack;
+};
+
+const struct bpf_jit_arg_abi *bpf_jit_arg_abi(void);
+u32 bpf_jit_place_args(const struct bpf_jit_arg_abi *abi,
+ const struct btf_func_model *fm, u8 *pos_of_slot);
+
+/* The JIT's scratch register, in place of an argument slot. */
+#define BPF_JIT_ARG_TMP 0xff
+
+/* Every argument slot moves at most once, and the scratch goes out and back. */
+#define BPF_JIT_MAX_ARG_MOVES (MAX_BPF_FUNC_ARG_SLOTS + 2)
+
+struct bpf_jit_arg_move {
+ u8 dst;
+ u8 src;
+};
+
+u32 bpf_jit_plan_arg_moves(const struct bpf_jit_arg_abi *abi,
+ const struct btf_func_model *fm,
+ struct bpf_jit_arg_move *moves);
u64 bpf_arch_uaddress_limit(void);
void arch_bpf_stack_walk(bool (*consume_fn)(void *cookie, u64 ip, u64 sp, u64 bp), void *cookie);
u64 arch_bpf_timed_may_goto(void);
@@ -1897,6 +1975,11 @@ static __always_inline long __bpf_xdp_redirect_map(struct bpf_map *map, u64 inde
return XDP_REDIRECT;
}
+int __bpf_sock_ops_load_hdr_opt(struct bpf_sock_ops_kern *bpf_sock,
+ void *search_res, u32 len, u64 flags);
+int __bpf_sock_ops_store_hdr_opt(struct bpf_sock_ops_kern *bpf_sock,
+ const void *from, u32 len, u64 flags);
+
#ifdef CONFIG_NET
int __bpf_skb_load_bytes(const struct sk_buff *skb, u32 offset, void *to, u32 len);
int __bpf_skb_store_bytes(struct sk_buff *skb, u32 offset, const void *from,
diff --git a/include/linux/firewire.h b/include/linux/firewire.h
index fd35a6570cd8..9c563fbdbbf0 100644
--- a/include/linux/firewire.h
+++ b/include/linux/firewire.h
@@ -92,17 +92,17 @@ struct fw_card {
u64 reset_jiffies;
struct {
- int current_tlabel;
- u64 tlabel_mask;
- struct list_head list;
+ int current_tlabel __guarded_by(&lock);
+ u64 tlabel_mask __guarded_by(&lock);
+ struct list_head list __guarded_by(&lock);
spinlock_t lock;
} transactions;
struct {
- u32 hi;
- u32 lo;
- unsigned int cycles;
- unsigned int jiffies;
+ u32 hi __guarded_by(&lock);
+ u32 lo __guarded_by(&lock);
+ unsigned int cycles __guarded_by(&lock);
+ unsigned int jiffies __guarded_by(&lock);
spinlock_t lock;
} split_timeout;
@@ -139,7 +139,7 @@ struct fw_card {
u32 broadcast_channel;
struct {
- __be32 buffer[(CSR_TOPOLOGY_MAP_END - CSR_TOPOLOGY_MAP) / 4];
+ __be32 buffer[(CSR_TOPOLOGY_MAP_END - CSR_TOPOLOGY_MAP) / 4] __guarded_by(&lock);
spinlock_t lock;
} topology_map;
@@ -172,10 +172,10 @@ struct fw_attribute_group {
};
enum fw_device_quirk {
- // See afa1282a35d3 ("firewire: core: check for 1394a compliant IRM, fix inaccessibility of Sony camcorder").
+ // See 10389536742c ("firewire: core: check for 1394a compliant IRM, fix inaccessibility of Sony camcorder").
FW_DEVICE_QUIRK_IRM_IS_1394_1995_ONLY = BIT(0),
- // See a509e43ff338 ("firewire: core: fix unstable I/O with Canon camcorder").
+ // See 6044565af458 ("firewire: core: fix unstable I/O with Canon camcorder").
FW_DEVICE_QUIRK_IRM_IGNORES_BUS_MANAGER = BIT(1),
// MOTU Audio Express transfers acknowledge packet with 0x10 for pending state.
@@ -224,7 +224,7 @@ struct fw_device {
struct mutex client_list_mutex;
struct list_head client_list;
- const u32 *config_rom;
+ const u32 *config_rom __counted_by_ptr(config_rom_length);
size_t config_rom_length;
int config_rom_retries;
unsigned is_local:1;
@@ -286,28 +286,87 @@ struct fw_request;
typedef void (*fw_packet_callback_t)(struct fw_packet *packet,
struct fw_card *card, int status);
+
+/**
+ * typedef fw_transaction_callback_t - Function to handle the result of outgoing transaction.
+ * @card: the interface to send the request at
+ * @rcode: the response code
+ * @data: the data for the response subaction
+ * @length: the length of data
+ * @callback_data: the data registered with this callback
+ *
+ * This callback is called from a workqueue in process context after the outgoing transaction is
+ * completed successfully or unsuccessfully.
+ *
+ * Among its parameters is the response code which is either one of the rcodes per IEEE 1394 or, in
+ * case of internal errors, the firewire-core specific %RCODE_SEND_ERROR. The other firewire-core
+ * specific rcodes (%RCODE_CANCELLED, %RCODE_BUSY, %RCODE_GENERATION, %RCODE_NO_ACK) denote
+ * transaction timeout, busy responder, stale request generation, or missing ACK respectively.
+ *
+ * Context: Process context.
+ */
typedef void (*fw_transaction_callback_t)(struct fw_card *card, int rcode,
void *data, size_t length,
void *callback_data);
+
+/**
+ * typedef fw_transaction_callback_with_tstamp_t - Function to handle the result of outgoing
+ * transaction with hardware time stamps.
+ * @card: the interface to send the request at
+ * @rcode: the response code
+ * @request_tstamp: the time stamp at which the request subaction finished
+ * @response_tstamp: the time stamp at which the response subaction finished
+ * @data: the data for the response subaction
+ * @length: the length of data
+ * @callback_data: the data registered with this callback
+ *
+ * This callback is called from a workqueue in process context after the outgoing transaction is
+ * completed successfully or unsuccessfully.
+ *
+ * Among its parameters is the response code which is either one of the rcodes per IEEE 1394 or, in
+ * case of internal errors, the firewire-core specific %RCODE_SEND_ERROR. The other firewire-core
+ * specific rcodes (%RCODE_CANCELLED, %RCODE_BUSY, %RCODE_GENERATION, %RCODE_NO_ACK) denote
+ * transaction timeout, busy responder, stale request generation, or missing ACK respectively.
+ *
+ * The timestamp consists of the low order 3 bits of second field and the full 13 bits of count
+ * field of isochronous cycle time register.
+ *
+ * Context: Process context.
+ */
typedef void (*fw_transaction_callback_with_tstamp_t)(struct fw_card *card, int rcode,
u32 request_tstamp, u32 response_tstamp, void *data,
size_t length, void *callback_data);
+/**
+ * union fw_transaction_callback - A union to store the outgoing transaction callback.
+ * @without_tstamp: Callback without hardware timestamps.
+ * @with_tstamp: Callback with hardware timestamps.
+ */
union fw_transaction_callback {
fw_transaction_callback_t without_tstamp;
fw_transaction_callback_with_tstamp_t with_tstamp;
};
-/*
- * This callback handles an inbound request subaction. It is called in
- * RCU read-side context, therefore must not sleep.
+/**
+ * typedef fw_address_callback_t - Function to handle the request of the incoming transaction.
+ * @card: the card instance which receives the request
+ * @request: the request instance.
+ * @tcode: the transaction code
+ * @destination: the destination node ID
+ * @source: the source node ID
+ * @generation: the bus generation in which the request was sent
+ * @offset: the destination offset in source node.
+ * @data: the request content if available.
+ * @length: the length of data.
+ * @callback_data: the data registered with this function.
*
- * The callback should not initiate outbound request subactions directly.
- * Otherwise there is a danger of recursion of inbound and outbound
- * transactions from and to the local node.
+ * This callback handles an inbound request subaction.
*
- * The callback is responsible that fw_send_response() is called on the @request, except for FCP
- * registers for which the core takes care of that.
+ * The contents of @request are opaque to the callback. The callback is responsible for calling
+ * fw_send_response() for @request, except for FCP registers, for which the core handles the
+ * response.
+ *
+ * Context: Process context.
*/
typedef void (*fw_address_callback_t)(struct fw_card *card,
struct fw_request *request,
@@ -322,26 +381,36 @@ struct fw_packet {
int generation;
u32 header[4];
size_t header_length;
- void *payload;
+ void *payload __counted_by_ptr(payload_length);
size_t payload_length;
dma_addr_t payload_bus;
bool payload_mapped;
u32 timestamp;
+ // Used to handle the local-to-local packets in the AT request/response contexts.
+ struct list_head link_for_local;
+
/*
* This callback is called when the packet transmission has completed.
* For successful transmission, the status code is the ack received
* from the destination. Otherwise it is one of the juju-specific
* rcodes: RCODE_SEND_ERROR, _CANCELLED, _BUSY, _GENERATION, _NO_ACK.
- * The callback can be called from workqueue and thus must never block.
+ * The callback is called from a workqueue. It is not preferable to block it so long.
*/
fw_packet_callback_t callback;
int ack;
- struct list_head link;
void *driver_data;
};
+/**
+ * struct fw_transaction - A structure to hold outgoing transaction state.
+ *
+ * All structure members are for internal use only. Once passed to __fw_send_request(), this
+ * structure holds the state of an outgoing transaction. It must not be freed until the callback
+ * reports the transaction result.
+ */
struct fw_transaction {
+ /* private: */
int node_id; /* The generation is implied; it is always the current. */
int tlabel;
struct list_head link;
@@ -359,20 +428,44 @@ struct fw_transaction {
union fw_transaction_callback callback;
bool with_tstamp;
void *callback_data;
+
+ // For some error cases.
+ struct work_struct error_work;
+ int rcode;
+ u32 response_timestamp;
};
+/**
+ * struct fw_address_handler - A handler for incoming transaction requests to a registered address
+ * region.
+ * @offset: The registered offset, available after successful registration.
+ * @length: The length of the address region in bytes, a multiple of a quadlet.
+ * @address_callback: Callback invoked when a transaction request is received for the registered
+ * address region.
+ * @callback_data: Data passed to @address_callback.
+ *
+ * This structure represents a handler registered to receive incoming asynchronous requests to a
+ * specific region of the address space on the local node.
+ */
struct fw_address_handler {
u64 offset;
u64 length;
fw_address_callback_t address_callback;
void *callback_data;
- // Only for core functions.
+ /* private: */
struct list_head link;
struct kref kref;
struct completion done;
};
+/**
+ * struct fw_address_region - An address range.
+ * @start: The starting offset in bytes, a multiple of a quadlet.
+ * @end: The ending offset in bytes, a multiple of a quadlet.
+ *
+ * Represents a range of addresses in the local node's address space.
+ */
struct fw_address_region {
u64 start;
u64 end;
@@ -411,9 +504,10 @@ void __fw_send_request(struct fw_card *card, struct fw_transaction *t, int tcode
* A variation of __fw_send_request() to generate callback for response subaction without time
* stamp.
*
- * The callback is invoked in the workqueue context in most cases. However, if an error is detected
- * before queueing or the destination address refers to the local node, it is invoked in the
- * current context instead.
+ * After the transaction is completed successfully or unsuccessfully, the @callback will be called
+ * in process context.
+ *
+ * Context: Any context.
*/
static inline void fw_send_request(struct fw_card *card, struct fw_transaction *t, int tcode,
int destination_id, int generation, int speed,
@@ -444,9 +538,10 @@ static inline void fw_send_request(struct fw_card *card, struct fw_transaction *
*
* A variation of __fw_send_request() to generate callback for response subaction with time stamp.
*
- * The callback is invoked in the workqueue context in most cases. However, if an error is detected
- * before queueing or the destination address refers to the local node, it is invoked in the current
- * context instead.
+ * After the transaction is completed successfully or unsuccessfully, the @callback will be called
+ * in process context.
+ *
+ * Context: Any context.
*/
static inline void fw_send_request_with_tstamp(struct fw_card *card, struct fw_transaction *t,
int tcode, int destination_id, int generation, int speed, unsigned long long offset,
diff --git a/include/linux/firmware/cirrus/cs_dsp.h b/include/linux/firmware/cirrus/cs_dsp.h
index 4e3baa557068..6aa1e1b2b4a5 100644
--- a/include/linux/firmware/cirrus/cs_dsp.h
+++ b/include/linux/firmware/cirrus/cs_dsp.h
@@ -96,7 +96,7 @@ struct cs_dsp_alg_region {
struct cs_dsp_coeff_ctl {
struct list_head list;
struct cs_dsp *dsp;
- void *cache;
+ void *cache __counted_by_ptr(len);
const char *fw_name;
/* Subname is needed to match with firmware */
const char *subname;
diff --git a/include/linux/firmware/intel/stratix10-smc.h b/include/linux/firmware/intel/stratix10-smc.h
index 366309260121..6a6fa51ad39e 100644
--- a/include/linux/firmware/intel/stratix10-smc.h
+++ b/include/linux/firmware/intel/stratix10-smc.h
@@ -725,6 +725,27 @@ INTEL_SIP_SMC_FAST_CALL_VAL(INTEL_SIP_SMC_FUNCID_FPGA_CONFIG_COMPLETED_WRITE)
INTEL_SIP_SMC_ASYNC_VAL(INTEL_SIP_SMC_ASYNC_FUNC_ID_POLL)
/**
+ * Request INTEL_SIP_SMC_ASYNC_POLL_ON_IRQ
+ * Async call used by service driver at EL1 to retrieve the transaction IDs
+ * of available responses from the SDM mailbox (typically after an IRQ).
+ *
+ * Call register usage:
+ * a0 INTEL_SIP_SMC_ASYNC_POLL_ON_IRQ
+ * a1-a17 not used
+ *
+ * Return status
+ * a0 INTEL_SIP_SMC_STATUS_OK
+ * a1-a4 contain a bitmap of pending transaction IDs (set bit positions)
+ * a5-a17 not used
+ * Or
+ * a0 INTEL_SIP_SMC_STATUS_NO_RESPONSE
+ * a1-a17 not used
+ */
+#define INTEL_SIP_SMC_ASYNC_FUNC_ID_IRQ_POLL (0xC9)
+#define INTEL_SIP_SMC_ASYNC_POLL_ON_IRQ \
+ INTEL_SIP_SMC_ASYNC_VAL(INTEL_SIP_SMC_ASYNC_FUNC_ID_IRQ_POLL)
+
+/**
* Request INTEL_SIP_SMC_ASYNC_HWMON_READTEMP
* Async call to request temperature
*
@@ -813,4 +834,27 @@ INTEL_SIP_SMC_FAST_CALL_VAL(INTEL_SIP_SMC_FUNCID_FPGA_CONFIG_COMPLETED_WRITE)
#define INTEL_SIP_SMC_ASYNC_FUNC_ID_RSU_NOTIFY (0xEC)
#define INTEL_SIP_SMC_ASYNC_RSU_NOTIFY \
INTEL_SIP_SMC_ASYNC_VAL(INTEL_SIP_SMC_ASYNC_FUNC_ID_RSU_NOTIFY)
+
+/**
+ * Request INTEL_SIP_SMC_SDM_REMAPPER_CONFIG
+ *
+ * Sync call to configure the SDM address remapper. On Agilex5, the remapper
+ * must be bypassed when the SMMU is active to avoid conflicts with IOMMU
+ * address translation.
+ *
+ * Call register usage:
+ * a0: INTEL_SIP_SMC_SDM_REMAPPER_CONFIG
+ * a1: INTEL_SIP_SMC_SDM_REMAPPER_ENABLE or INTEL_SIP_SMC_SDM_REMAPPER_BYPASS
+ * a2-7: not used
+ *
+ * Return status:
+ * a0: INTEL_SIP_SMC_STATUS_OK
+ * a1-3: not used
+ */
+#define INTEL_SIP_SMC_FUNCID_SDM_REMAPPER_CONFIG 513
+#define INTEL_SIP_SMC_SDM_REMAPPER_CONFIG \
+ INTEL_SIP_SMC_FAST_CALL_VAL(INTEL_SIP_SMC_FUNCID_SDM_REMAPPER_CONFIG)
+#define INTEL_SIP_SMC_SDM_REMAPPER_ENABLE 0
+#define INTEL_SIP_SMC_SDM_REMAPPER_BYPASS 1
+
#endif
diff --git a/include/linux/firmware/qcom/qcom_scm.h b/include/linux/firmware/qcom/qcom_scm.h
index 5747bd191bf1..a0a6bc0229c4 100644
--- a/include/linux/firmware/qcom/qcom_scm.h
+++ b/include/linux/firmware/qcom/qcom_scm.h
@@ -64,35 +64,6 @@ bool qcom_scm_is_available(void);
int qcom_scm_set_cold_boot_addr(void *entry);
int qcom_scm_set_warm_boot_addr(void *entry);
void qcom_scm_cpu_power_down(u32 flags);
-int qcom_scm_set_remote_state(u32 state, u32 id);
-
-struct qcom_scm_pas_context {
- struct device *dev;
- u32 pas_id;
- phys_addr_t mem_phys;
- size_t mem_size;
- void *ptr;
- dma_addr_t phys;
- ssize_t size;
- bool use_tzmem;
-};
-
-struct qcom_scm_pas_context *devm_qcom_scm_pas_context_alloc(struct device *dev,
- u32 pas_id,
- phys_addr_t mem_phys,
- size_t mem_size);
-int qcom_scm_pas_init_image(u32 pas_id, const void *metadata, size_t size,
- struct qcom_scm_pas_context *ctx);
-void qcom_scm_pas_metadata_release(struct qcom_scm_pas_context *ctx);
-int qcom_scm_pas_mem_setup(u32 pas_id, phys_addr_t addr, phys_addr_t size);
-int qcom_scm_pas_auth_and_reset(u32 pas_id);
-int qcom_scm_pas_shutdown(u32 pas_id);
-bool qcom_scm_pas_supported(u32 pas_id);
-struct resource_table *qcom_scm_pas_get_rsc_table(struct qcom_scm_pas_context *ctx,
- void *input_rt, size_t input_rt_size,
- size_t *output_rt_size);
-
-int qcom_scm_pas_prepare_and_auth_reset(struct qcom_scm_pas_context *ctx);
int qcom_scm_io_readl(phys_addr_t addr, unsigned int *val);
int qcom_scm_io_writel(phys_addr_t addr, unsigned int val);
diff --git a/include/linux/firmware/xlnx-zynqmp-ufs.h b/include/linux/firmware/xlnx-zynqmp-ufs.h
index d3538dd5822a..00383dd835f2 100644
--- a/include/linux/firmware/xlnx-zynqmp-ufs.h
+++ b/include/linux/firmware/xlnx-zynqmp-ufs.h
@@ -9,17 +9,17 @@
#define __FIRMWARE_XLNX_ZYNQMP_UFS_H__
#if IS_REACHABLE(CONFIG_ZYNQMP_FIRMWARE)
-int zynqmp_pm_is_mphy_tx_rx_config_ready(bool *is_ready);
-int zynqmp_pm_is_sram_init_done(bool *is_done);
+int zynqmp_pm_wait_mphy_tx_rx_config_ready(u32 timeout_us);
+int zynqmp_pm_wait_sram_init_done(u32 timeout_us);
int zynqmp_pm_set_sram_bypass(void);
int zynqmp_pm_get_ufs_calibration_values(u32 *val);
#else
-static inline int zynqmp_pm_is_mphy_tx_rx_config_ready(bool *is_ready)
+static inline int zynqmp_pm_wait_mphy_tx_rx_config_ready(u32 timeout_us)
{
return -ENODEV;
}
-static inline int zynqmp_pm_is_sram_init_done(bool *is_done)
+static inline int zynqmp_pm_wait_sram_init_done(u32 timeout_us)
{
return -ENODEV;
}
diff --git a/include/linux/firmware/xlnx-zynqmp.h b/include/linux/firmware/xlnx-zynqmp.h
index f4b3df614c77..41a1cd810bda 100644
--- a/include/linux/firmware/xlnx-zynqmp.h
+++ b/include/linux/firmware/xlnx-zynqmp.h
@@ -277,11 +277,6 @@ enum rpu_oper_mode {
PM_RPU_MODE_SPLIT = 1,
};
-enum rpu_boot_mem {
- PM_RPU_BOOTMEM_LOVEC = 0,
- PM_RPU_BOOTMEM_HIVEC = 1,
-};
-
enum rpu_tcm_comb {
PM_RPU_TCM_SPLIT = 0,
PM_RPU_TCM_COMB = 1,
diff --git a/include/linux/firmware_attributes.h b/include/linux/firmware_attributes.h
new file mode 100644
index 000000000000..d4026ba1fcc2
--- /dev/null
+++ b/include/linux/firmware_attributes.h
@@ -0,0 +1,12 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+
+/* Firmware attributes class helper module */
+
+#ifndef _LINUX_FIRMWARE_ATTRIBUTES_H
+#define _LINUX_FIRMWARE_ATTRIBUTES_H
+
+#include <linux/device/class.h>
+
+extern const struct class firmware_attributes_class;
+
+#endif /* _LINUX_FIRMWARE_ATTRIBUTES_H */
diff --git a/include/linux/font.h b/include/linux/font.h
index 5e1cf9830084..be1a26ff8ae9 100644
--- a/include/linux/font.h
+++ b/include/linux/font.h
@@ -109,6 +109,10 @@ const unsigned char *font_data_glyph_buf(font_data_t *fd,
bool font_data_is_equal(font_data_t *lhs, font_data_t *rhs);
int font_data_export(font_data_t *fd, struct console_font *font, unsigned int vpitch);
+/* font_cursor.c */
+void font_glyph_cursor(unsigned int width, unsigned int height,
+ unsigned int from, unsigned int to, unsigned char *out);
+
/* font_rotate.c */
void font_glyph_rotate_90(const unsigned char *glyph, unsigned int width, unsigned int height,
unsigned char *out);
diff --git a/include/linux/fortify-string.h b/include/linux/fortify-string.h
index cf841dc71fef..7e7c369e0a6c 100644
--- a/include/linux/fortify-string.h
+++ b/include/linux/fortify-string.h
@@ -458,10 +458,8 @@ __FORTIFY_INLINE bool fortify_memset_chk(__kernel_size_t size,
* __struct_size() vs __member_size() must be captured here to avoid
* evaluating argument side-effects further into the macro layers.
*/
-#ifndef CONFIG_KMSAN
#define memset(p, c, s) __fortify_memset_chk(p, c, s, \
__struct_size(p), __member_size(p))
-#endif
/*
* To make sure the compiler can enforce protection against buffer overflows,
diff --git a/include/linux/fs.h b/include/linux/fs.h
index f9d1e05e8ae6..a5585872e48c 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -1436,10 +1436,10 @@ static inline void i_gid_write(struct inode *inode, gid_t gid)
* @idmap: idmap of the mount the inode was found from
* @inode: inode to map
*
- * Return: whe inode's i_uid mapped down according to @idmap.
+ * Return: the inode's i_uid mapped down according to @idmap.
* If the inode's i_uid has no mapping INVALID_VFSUID is returned.
*/
-static inline vfsuid_t i_uid_into_vfsuid(struct mnt_idmap *idmap,
+static inline vfsuid_t i_uid_into_vfsuid(const struct mnt_idmap *idmap,
const struct inode *inode)
{
return make_vfsuid(idmap, i_user_ns(inode), inode->i_uid);
@@ -1456,7 +1456,7 @@ static inline vfsuid_t i_uid_into_vfsuid(struct mnt_idmap *idmap,
*
* Return: true if @inode's i_uid field needs to be updated, false if not.
*/
-static inline bool i_uid_needs_update(struct mnt_idmap *idmap,
+static inline bool i_uid_needs_update(const struct mnt_idmap *idmap,
const struct iattr *attr,
const struct inode *inode)
{
@@ -1474,7 +1474,7 @@ static inline bool i_uid_needs_update(struct mnt_idmap *idmap,
* Safely update @inode's i_uid field translating the vfsuid of any idmapped
* mount into the filesystem kuid.
*/
-static inline void i_uid_update(struct mnt_idmap *idmap,
+static inline void i_uid_update(const struct mnt_idmap *idmap,
const struct iattr *attr,
struct inode *inode)
{
@@ -1491,7 +1491,7 @@ static inline void i_uid_update(struct mnt_idmap *idmap,
* Return: the inode's i_gid mapped down according to @idmap.
* If the inode's i_gid has no mapping INVALID_VFSGID is returned.
*/
-static inline vfsgid_t i_gid_into_vfsgid(struct mnt_idmap *idmap,
+static inline vfsgid_t i_gid_into_vfsgid(const struct mnt_idmap *idmap,
const struct inode *inode)
{
return make_vfsgid(idmap, i_user_ns(inode), inode->i_gid);
@@ -1508,7 +1508,7 @@ static inline vfsgid_t i_gid_into_vfsgid(struct mnt_idmap *idmap,
*
* Return: true if @inode's i_gid field needs to be updated, false if not.
*/
-static inline bool i_gid_needs_update(struct mnt_idmap *idmap,
+static inline bool i_gid_needs_update(const struct mnt_idmap *idmap,
const struct iattr *attr,
const struct inode *inode)
{
@@ -1526,7 +1526,7 @@ static inline bool i_gid_needs_update(struct mnt_idmap *idmap,
* Safely update @inode's i_gid field translating the vfsgid of any idmapped
* mount into the filesystem kgid.
*/
-static inline void i_gid_update(struct mnt_idmap *idmap,
+static inline void i_gid_update(const struct mnt_idmap *idmap,
const struct iattr *attr,
struct inode *inode)
{
@@ -1544,7 +1544,7 @@ static inline void i_gid_update(struct mnt_idmap *idmap,
* an idmapped mount map the caller's fsuid according to @idmap.
*/
static inline void inode_fsuid_set(struct inode *inode,
- struct mnt_idmap *idmap)
+ const struct mnt_idmap *idmap)
{
inode->i_uid = mapped_fsuid(idmap, i_user_ns(inode));
}
@@ -1558,7 +1558,7 @@ static inline void inode_fsuid_set(struct inode *inode,
* an idmapped mount map the caller's fsgid according to @idmap.
*/
static inline void inode_fsgid_set(struct inode *inode,
- struct mnt_idmap *idmap)
+ const struct mnt_idmap *idmap)
{
inode->i_gid = mapped_fsgid(idmap, i_user_ns(inode));
}
@@ -1575,7 +1575,7 @@ static inline void inode_fsgid_set(struct inode *inode,
* Return: true if fsuid and fsgid is mapped, false if not.
*/
static inline bool fsuidgid_has_mapping(struct super_block *sb,
- struct mnt_idmap *idmap)
+ const struct mnt_idmap *idmap)
{
struct user_namespace *fs_userns = sb->s_user_ns;
kuid_t kuid;
@@ -1755,25 +1755,25 @@ static inline bool file_write_not_started(const struct file *file)
return sb_write_not_started(file_inode(file)->i_sb);
}
-bool inode_owner_or_capable(struct mnt_idmap *idmap,
+bool inode_owner_or_capable(const struct mnt_idmap *idmap,
const struct inode *inode);
/*
* VFS helper functions..
*/
-int vfs_create(struct mnt_idmap *, struct dentry *, umode_t,
+int vfs_create(const struct mnt_idmap *, struct dentry *, umode_t,
struct delegated_inode *);
-struct dentry *vfs_mkdir(struct mnt_idmap *, struct inode *,
+struct dentry *vfs_mkdir(const struct mnt_idmap *, struct inode *,
struct dentry *, umode_t, struct delegated_inode *);
-int vfs_mknod(struct mnt_idmap *, struct inode *, struct dentry *,
+int vfs_mknod(const struct mnt_idmap *, struct inode *, struct dentry *,
umode_t, dev_t, struct delegated_inode *);
-int vfs_symlink(struct mnt_idmap *, struct inode *,
+int vfs_symlink(const struct mnt_idmap *, struct inode *,
struct dentry *, const char *, struct delegated_inode *);
-int vfs_link(struct dentry *, struct mnt_idmap *, struct inode *,
+int vfs_link(struct dentry *, const struct mnt_idmap *, struct inode *,
struct dentry *, struct delegated_inode *);
-int vfs_rmdir(struct mnt_idmap *, struct inode *, struct dentry *,
+int vfs_rmdir(const struct mnt_idmap *, struct inode *, struct dentry *,
struct delegated_inode *);
-int vfs_unlink(struct mnt_idmap *, struct inode *, struct dentry *,
+int vfs_unlink(const struct mnt_idmap *, struct inode *, struct dentry *,
struct delegated_inode *);
/**
@@ -1787,7 +1787,7 @@ int vfs_unlink(struct mnt_idmap *, struct inode *, struct dentry *,
* @flags: rename flags
*/
struct renamedata {
- struct mnt_idmap *mnt_idmap;
+ const struct mnt_idmap *mnt_idmap;
struct dentry *old_parent;
struct dentry *old_dentry;
struct dentry *new_parent;
@@ -1798,14 +1798,14 @@ struct renamedata {
int vfs_rename(struct renamedata *);
-static inline int vfs_whiteout(struct mnt_idmap *idmap,
+static inline int vfs_whiteout(const struct mnt_idmap *idmap,
struct inode *dir, struct dentry *dentry)
{
return vfs_mknod(idmap, dir, dentry, S_IFCHR | WHITEOUT_MODE,
WHITEOUT_DEV, NULL);
}
-struct file *kernel_tmpfile_open(struct mnt_idmap *idmap,
+struct file *kernel_tmpfile_open(const struct mnt_idmap *idmap,
const struct path *parentpath,
umode_t mode, int open_flag,
const struct cred *cred);
@@ -1830,12 +1830,12 @@ extern long compat_ptr_ioctl(struct file *file, unsigned int cmd,
/*
* VFS file helper functions.
*/
-void inode_init_owner(struct mnt_idmap *idmap, struct inode *inode,
+void inode_init_owner(const struct mnt_idmap *idmap, struct inode *inode,
const struct inode *dir, umode_t mode);
extern bool may_open_dev(const struct path *path);
-umode_t mode_strip_sgid(struct mnt_idmap *idmap,
+umode_t mode_strip_sgid(const struct mnt_idmap *idmap,
const struct inode *dir, umode_t mode);
-bool in_group_or_capable(struct mnt_idmap *idmap,
+bool in_group_or_capable(const struct mnt_idmap *idmap,
const struct inode *inode, vfsgid_t vfsgid);
/*
@@ -1978,6 +1978,8 @@ struct file_operations {
#define FOP_ASYNC_LOCK ((__force fop_flags_t)(1 << 6))
/* File system supports uncached read/write buffered IO */
#define FOP_DONTCACHE ((__force fop_flags_t)(1 << 7))
+/* Never changes and is never removed, readdir of a directory takes no lock */
+#define FOP_IMMUTABLE ((__force fop_flags_t)(1 << 8))
/* Wrap a directory iterator that needs exclusive inode access */
int wrap_directory_iterator(struct file *, struct dir_context *,
@@ -1994,26 +1996,26 @@ enum fs_update_time {
struct inode_operations {
struct dentry * (*lookup) (struct inode *,struct dentry *, unsigned int);
const char * (*get_link) (struct dentry *, struct inode *, struct delayed_call *);
- int (*permission) (struct mnt_idmap *, struct inode *, int);
+ int (*permission) (const struct mnt_idmap *, struct inode *, int);
struct posix_acl * (*get_inode_acl)(struct inode *, int, bool);
int (*readlink) (struct dentry *, char __user *,int);
- int (*create) (struct mnt_idmap *, struct inode *,struct dentry *,
+ int (*create) (const struct mnt_idmap *, struct inode *,struct dentry *,
umode_t);
int (*link) (struct dentry *,struct inode *,struct dentry *);
int (*unlink) (struct inode *,struct dentry *);
- int (*symlink) (struct mnt_idmap *, struct inode *,struct dentry *,
+ int (*symlink) (const struct mnt_idmap *, struct inode *,struct dentry *,
const char *);
- struct dentry *(*mkdir) (struct mnt_idmap *, struct inode *,
+ struct dentry *(*mkdir) (const struct mnt_idmap *, struct inode *,
struct dentry *, umode_t);
int (*rmdir) (struct inode *,struct dentry *);
- int (*mknod) (struct mnt_idmap *, struct inode *,struct dentry *,
+ int (*mknod) (const struct mnt_idmap *, struct inode *,struct dentry *,
umode_t,dev_t);
- int (*rename) (struct mnt_idmap *, struct inode *, struct dentry *,
+ int (*rename) (const struct mnt_idmap *, struct inode *, struct dentry *,
struct inode *, struct dentry *, unsigned int);
- int (*setattr) (struct mnt_idmap *, struct dentry *, struct iattr *);
- int (*getattr) (struct mnt_idmap *, const struct path *,
+ int (*setattr) (const struct mnt_idmap *, struct dentry *, struct iattr *);
+ int (*getattr) (const struct mnt_idmap *, const struct path *,
struct kstat *, u32, unsigned int);
ssize_t (*listxattr) (struct dentry *, char *, size_t);
int (*fiemap)(struct inode *, struct fiemap_extent_info *, u64 start,
@@ -2024,13 +2026,13 @@ struct inode_operations {
int (*atomic_open)(struct inode *, struct dentry *,
struct file *, unsigned open_flag,
umode_t create_mode);
- int (*tmpfile) (struct mnt_idmap *, struct inode *,
+ int (*tmpfile) (const struct mnt_idmap *, struct inode *,
struct file *, umode_t);
- struct posix_acl *(*get_acl)(struct mnt_idmap *, struct dentry *,
+ struct posix_acl *(*get_acl)(const struct mnt_idmap *, struct dentry *,
int);
- int (*set_acl)(struct mnt_idmap *, struct dentry *,
+ int (*set_acl)(const struct mnt_idmap *, struct dentry *,
struct posix_acl *, int);
- int (*fileattr_set)(struct mnt_idmap *idmap,
+ int (*fileattr_set)(const struct mnt_idmap *idmap,
struct dentry *dentry, struct file_kattr *fa);
int (*fileattr_get)(struct dentry *dentry, struct file_kattr *fa);
struct offset_ctx *(*get_offset_ctx)(struct inode *inode);
@@ -2173,7 +2175,7 @@ extern loff_t vfs_dedupe_file_range_one(struct file *src_file, loff_t src_pos,
(inode)->i_rdev == WHITEOUT_DEV)
#define IS_ANON_FILE(inode) ((inode)->i_flags & S_ANON_INODE)
-static inline bool HAS_UNMAPPED_ID(struct mnt_idmap *idmap,
+static inline bool HAS_UNMAPPED_ID(const struct mnt_idmap *idmap,
struct inode *inode)
{
return !vfsuid_valid(i_uid_into_vfsuid(idmap, inode)) ||
@@ -2296,6 +2298,7 @@ struct file_system_type {
#define FS_POWER_FREEZE 256 /* Always freeze on suspend/hibernate */
#define FS_USERNS_MOUNT_RESTRICTED 512 /* Restrict mount in userns if not already visible */
#define FS_USERNS_DELEGATABLE 1024 /* Can be mounted inside userns from outside */
+#define FS_DISALLOW_NOTIFY 2048 /* No fsnotify marks on its objects */
#define FS_RENAME_DOES_D_MOVE 32768 /* FS will handle d_move() during rename() internally. */
int (*init_fs_context)(struct fs_context *);
const struct fs_parameter_spec *parameters;
@@ -2313,6 +2316,8 @@ struct file_system_type {
struct lock_class_key i_mutex_key;
struct lock_class_key invalidate_lock_key;
struct lock_class_key i_mutex_dir_key;
+
+ struct lock_class_key d_lookup_key;
};
#define MODULE_ALIAS_FS(NAME) MODULE_ALIAS("fs-" NAME)
@@ -2459,7 +2464,7 @@ struct filename {
static_assert(offsetof(struct filename, iname) % sizeof(long) == 0);
static_assert(sizeof(struct filename) % 64 == 0);
-static inline struct mnt_idmap *file_mnt_idmap(const struct file *file)
+static inline const struct mnt_idmap *file_mnt_idmap(const struct file *file)
{
return mnt_idmap(file->f_path.mnt);
}
@@ -2483,7 +2488,7 @@ static inline bool is_idmapped_mnt(const struct vfsmount *mnt)
}
int vfs_truncate(const struct path *, loff_t);
-int do_truncate(struct mnt_idmap *, struct dentry *, loff_t start,
+int do_truncate(const struct mnt_idmap *, struct dentry *, loff_t start,
unsigned int time_attrs, struct file *filp);
extern int vfs_fallocate(struct file *file, int mode, loff_t offset,
loff_t len);
@@ -2707,10 +2712,10 @@ static inline int bmap(struct inode *inode, sector_t *block)
}
#endif
-int notify_change(struct mnt_idmap *, struct dentry *,
+int notify_change(const struct mnt_idmap *, struct dentry *,
struct iattr *, struct delegated_inode *);
-int inode_permission(struct mnt_idmap *, struct inode *, int);
-int generic_permission(struct mnt_idmap *, struct inode *, int);
+int inode_permission(const struct mnt_idmap *, struct inode *, int);
+int generic_permission(const struct mnt_idmap *, struct inode *, int);
static inline int file_permission(struct file *file, int mask)
{
return inode_permission(file_mnt_idmap(file),
@@ -2721,12 +2726,12 @@ static inline int path_permission(const struct path *path, int mask)
return inode_permission(mnt_idmap(path->mnt),
d_inode(path->dentry), mask);
}
-int __check_sticky(struct mnt_idmap *idmap, struct inode *dir,
+int __check_sticky(const struct mnt_idmap *idmap, struct inode *dir,
struct inode *inode);
-int may_delete_dentry(struct mnt_idmap *idmap, struct inode *dir,
+int may_delete_dentry(const struct mnt_idmap *idmap, struct inode *dir,
struct dentry *victim, bool isdir);
-int may_create_dentry(struct mnt_idmap *idmap,
+int may_create_dentry(const struct mnt_idmap *idmap,
struct inode *dir, struct dentry *child);
static inline bool execute_ok(struct inode *inode)
@@ -3045,9 +3050,9 @@ static inline struct inode *new_inode_pseudo(struct super_block *sb)
}
extern struct inode *new_inode(struct super_block *sb);
extern void free_inode_nonrcu(struct inode *inode);
-extern int setattr_should_drop_suidgid(struct mnt_idmap *, struct inode *);
+extern int setattr_should_drop_suidgid(const struct mnt_idmap *, struct inode *);
extern int file_remove_privs(struct file *);
-int setattr_should_drop_sgid(struct mnt_idmap *idmap,
+int setattr_should_drop_sgid(const struct mnt_idmap *idmap,
const struct inode *inode);
/*
@@ -3204,7 +3209,7 @@ extern int page_symlink(struct inode *inode, const char *symname, int len);
extern const struct inode_operations page_symlink_inode_operations;
extern void kfree_link(void *);
void fill_mg_cmtime(struct kstat *stat, u32 request_mask, struct inode *inode);
-void generic_fillattr(struct mnt_idmap *, u32, struct inode *, struct kstat *);
+void generic_fillattr(const struct mnt_idmap *, u32, struct inode *, struct kstat *);
void generic_fill_statx_attr(struct inode *inode, struct kstat *stat);
void generic_fill_statx_atomic_writes(struct kstat *stat,
unsigned int unit_min,
@@ -3261,9 +3266,9 @@ extern int dcache_dir_open(struct inode *, struct file *);
extern int dcache_dir_close(struct inode *, struct file *);
extern loff_t dcache_dir_lseek(struct file *, loff_t, int);
extern int dcache_readdir(struct file *, struct dir_context *);
-extern int simple_setattr(struct mnt_idmap *, struct dentry *,
+extern int simple_setattr(const struct mnt_idmap *, struct dentry *,
struct iattr *);
-extern int simple_getattr(struct mnt_idmap *, const struct path *,
+extern int simple_getattr(const struct mnt_idmap *, const struct path *,
struct kstat *, u32, unsigned int);
extern int simple_statfs(struct dentry *, struct kstatfs *);
extern int simple_open(struct inode *inode, struct file *file);
@@ -3276,7 +3281,7 @@ void simple_rename_timestamp(struct inode *old_dir, struct dentry *old_dentry,
struct inode *new_dir, struct dentry *new_dentry);
extern int simple_rename_exchange(struct inode *old_dir, struct dentry *old_dentry,
struct inode *new_dir, struct dentry *new_dentry);
-extern int simple_rename(struct mnt_idmap *, struct inode *,
+extern int simple_rename(const struct mnt_idmap *, struct inode *,
struct dentry *, struct inode *, struct dentry *,
unsigned int);
extern void simple_recursive_removal(struct dentry *,
@@ -3397,11 +3402,11 @@ static inline bool generic_ci_validate_strict_name(struct inode *dir,
}
#endif
-int may_setattr(struct mnt_idmap *idmap, struct inode *inode,
+int may_setattr(const struct mnt_idmap *idmap, struct inode *inode,
unsigned int ia_valid);
-int setattr_prepare(struct mnt_idmap *, struct dentry *, struct iattr *);
+int setattr_prepare(const struct mnt_idmap *, struct dentry *, struct iattr *);
extern int inode_newsize_ok(const struct inode *, loff_t offset);
-void setattr_copy(struct mnt_idmap *, struct inode *inode,
+void setattr_copy(const struct mnt_idmap *, struct inode *inode,
const struct iattr *attr);
extern int file_update_time(struct file *file);
@@ -3578,7 +3583,7 @@ static inline bool is_sxid(umode_t mode)
return mode & (S_ISUID | S_ISGID);
}
-static inline int check_sticky(struct mnt_idmap *idmap,
+static inline int check_sticky(const struct mnt_idmap *idmap,
struct inode *dir, struct inode *inode)
{
if (!(dir->i_mode & S_ISVTX))
@@ -3653,23 +3658,6 @@ extern int vfs_fadvise(struct file *file, loff_t offset, loff_t len,
extern int generic_fadvise(struct file *file, loff_t offset, loff_t len,
int advice);
-static inline bool vfs_empty_path(int dfd, const char __user *path)
-{
- char c;
-
- if (dfd < 0)
- return false;
-
- /* We now allow NULL to be used for empty path. */
- if (!path)
- return true;
-
- if (unlikely(get_user(c, path)))
- return false;
-
- return !c;
-}
-
int generic_atomic_write_valid(struct kiocb *iocb, struct iov_iter *iter);
static inline bool extensible_ioctl_valid(unsigned int cmd_a,
diff --git a/include/linux/fs_context.h b/include/linux/fs_context.h
index 0d6c8a6d7be2..d1727dffecc5 100644
--- a/include/linux/fs_context.h
+++ b/include/linux/fs_context.h
@@ -150,6 +150,10 @@ extern int vfs_parse_fs_param_source(struct fs_context *fc,
struct fs_parameter *param);
extern void fc_drop_locked(struct fs_context *fc);
+int get_tree_super(struct fs_context *fc,
+ int (*test)(struct super_block *, struct fs_context *),
+ int (*fill_super)(struct super_block *sb,
+ struct fs_context *fc));
extern int get_tree_nodev(struct fs_context *fc,
int (*fill_super)(struct super_block *sb,
struct fs_context *fc));
diff --git a/include/linux/fscache-cache.h b/include/linux/fscache-cache.h
index 4c91a019972b..2b83ffa4510e 100644
--- a/include/linux/fscache-cache.h
+++ b/include/linux/fscache-cache.h
@@ -67,7 +67,7 @@ struct fscache_cache_ops {
/* Change the size of a data object */
void (*resize_cookie)(struct netfs_cache_resources *cres,
- loff_t new_size);
+ uoff_t new_size, bool shrank);
/* Invalidate an object */
bool (*invalidate_cookie)(struct fscache_cookie *cookie);
diff --git a/include/linux/fscache.h b/include/linux/fscache.h
index 58fdb9605425..ecd14d645690 100644
--- a/include/linux/fscache.h
+++ b/include/linux/fscache.h
@@ -112,7 +112,7 @@ struct fscache_cookie {
struct list_head proc_link; /* Link in proc list */
struct list_head commit_link; /* Link in commit queue */
struct work_struct work; /* Commit/relinq/withdraw work */
- loff_t object_size; /* Size of the netfs object */
+ uoff_t object_size; /* Size of the netfs object */
unsigned long unused_at; /* Time at which unused (jiffies) */
unsigned long flags;
#define FSCACHE_COOKIE_RELINQUISHED 0 /* T if cookie has been relinquished */
@@ -147,6 +147,23 @@ struct fscache_cookie {
};
};
+enum fscache_extent_type {
+ FSCACHE_EXTENT_DATA,
+ FSCACHE_EXTENT_ZERO,
+} __mode(byte);
+
+/*
+ * Cache occupancy information.
+ */
+struct fscache_occupancy {
+ unsigned long long query_from; /* Point to query from */
+ unsigned long long query_to; /* Point to query to */
+ unsigned long long cached_from[2]; /* Point at which cache extents start */
+ unsigned long long cached_to[2]; /* Point at which cache extents end */
+ unsigned int granularity; /* Granularity desired */
+ enum fscache_extent_type cached_type[2]; /* Type of cache extent */
+};
+
/*
* slow-path functions for when there is actually caching available, and the
* netfs does actually have a valid token
@@ -163,22 +180,22 @@ extern struct fscache_cookie *__fscache_acquire_cookie(
u8,
const void *, size_t,
const void *, size_t,
- loff_t);
+ uoff_t);
extern void __fscache_use_cookie(struct fscache_cookie *, bool);
-extern void __fscache_unuse_cookie(struct fscache_cookie *, const void *, const loff_t *);
+extern void __fscache_unuse_cookie(struct fscache_cookie *, const void *, const uoff_t *);
extern void __fscache_relinquish_cookie(struct fscache_cookie *, bool);
-extern void __fscache_resize_cookie(struct fscache_cookie *, loff_t);
-extern void __fscache_invalidate(struct fscache_cookie *, const void *, loff_t, unsigned int);
+void __fscache_resize_cookie(struct fscache_cookie *cookie, uoff_t new_size, bool shrank);
+extern void __fscache_invalidate(struct fscache_cookie *, const void *, uoff_t, unsigned int);
extern int __fscache_begin_read_operation(struct netfs_cache_resources *, struct fscache_cookie *);
extern int __fscache_begin_write_operation(struct netfs_cache_resources *, struct fscache_cookie *);
void __fscache_write_to_cache(struct fscache_cookie *cookie,
struct address_space *mapping,
- loff_t start, size_t len, loff_t i_size,
+ uoff_t start, size_t len, uoff_t i_size,
netfs_io_terminated_t term_func,
void *term_func_priv,
bool using_pgpriv2, bool cond);
-extern void __fscache_clear_page_bits(struct address_space *, loff_t, size_t);
+extern void __fscache_clear_page_bits(struct address_space *, uoff_t, size_t);
/**
* fscache_acquire_volume - Register a volume as desiring caching services
@@ -249,7 +266,7 @@ struct fscache_cookie *fscache_acquire_cookie(struct fscache_volume *volume,
size_t index_key_len,
const void *aux_data,
size_t aux_data_len,
- loff_t object_size)
+ uoff_t object_size)
{
if (!fscache_volume_valid(volume))
return NULL;
@@ -286,7 +303,7 @@ static inline void fscache_use_cookie(struct fscache_cookie *cookie,
*/
static inline void fscache_unuse_cookie(struct fscache_cookie *cookie,
const void *aux_data,
- const loff_t *object_size)
+ const uoff_t *object_size)
{
if (fscache_cookie_valid(cookie))
__fscache_unuse_cookie(cookie, aux_data, object_size);
@@ -327,7 +344,7 @@ static inline void *fscache_get_aux(struct fscache_cookie *cookie)
*/
static inline
void fscache_update_aux(struct fscache_cookie *cookie,
- const void *aux_data, const loff_t *object_size)
+ const void *aux_data, const uoff_t *object_size)
{
void *p = fscache_get_aux(cookie);
@@ -343,7 +360,7 @@ extern atomic_t fscache_n_updates;
static inline
void __fscache_update_cookie(struct fscache_cookie *cookie, const void *aux_data,
- const loff_t *object_size)
+ const uoff_t *object_size)
{
#ifdef CONFIG_FSCACHE_STATS
atomic_inc(&fscache_n_updates);
@@ -369,7 +386,7 @@ void __fscache_update_cookie(struct fscache_cookie *cookie, const void *aux_data
*/
static inline
void fscache_update_cookie(struct fscache_cookie *cookie, const void *aux_data,
- const loff_t *object_size)
+ const uoff_t *object_size)
{
if (fscache_cookie_enabled(cookie))
__fscache_update_cookie(cookie, aux_data, object_size);
@@ -377,8 +394,9 @@ void fscache_update_cookie(struct fscache_cookie *cookie, const void *aux_data,
/**
* fscache_resize_cookie - Request that a cache object be resized
- * @cookie: The cookie representing the cache object
- * @new_size: The new size of the object (may be NULL)
+ * @cookie: The cookie representing the cache object (may be NULL)
+ * @new_size: The new size of the object
+ * @shrank: True if the file shrank; false if it expanded
*
* Request that the size of an object be changed.
*
@@ -386,10 +404,10 @@ void fscache_update_cookie(struct fscache_cookie *cookie, const void *aux_data,
* description.
*/
static inline
-void fscache_resize_cookie(struct fscache_cookie *cookie, loff_t new_size)
+void fscache_resize_cookie(struct fscache_cookie *cookie, uoff_t new_size, bool shrank)
{
if (fscache_cookie_enabled(cookie))
- __fscache_resize_cookie(cookie, new_size);
+ __fscache_resize_cookie(cookie, new_size, shrank);
}
/**
@@ -413,7 +431,7 @@ void fscache_resize_cookie(struct fscache_cookie *cookie, loff_t new_size)
*/
static inline
void fscache_invalidate(struct fscache_cookie *cookie,
- const void *aux_data, loff_t size, unsigned int flags)
+ const void *aux_data, uoff_t size, unsigned int flags)
{
if (fscache_cookie_enabled(cookie))
__fscache_invalidate(cookie, aux_data, size, flags);
@@ -502,7 +520,7 @@ static inline void fscache_end_operation(struct netfs_cache_resources *cres)
*/
static inline
int fscache_read(struct netfs_cache_resources *cres,
- loff_t start_pos,
+ uoff_t start_pos,
struct iov_iter *iter,
enum netfs_read_from_hole read_hole,
netfs_io_terminated_t term_func,
@@ -561,7 +579,7 @@ int fscache_begin_write_operation(struct netfs_cache_resources *cres,
*/
static inline
int fscache_write(struct netfs_cache_resources *cres,
- loff_t start_pos,
+ uoff_t start_pos,
struct iov_iter *iter,
netfs_io_terminated_t term_func,
void *term_func_priv)
@@ -581,7 +599,7 @@ int fscache_write(struct netfs_cache_resources *cres,
* waiting.
*/
static inline void fscache_clear_page_bits(struct address_space *mapping,
- loff_t start, size_t len,
+ uoff_t start, size_t len,
bool caching)
{
if (caching)
@@ -615,7 +633,7 @@ static inline void fscache_clear_page_bits(struct address_space *mapping,
*/
static inline void fscache_write_to_cache(struct fscache_cookie *cookie,
struct address_space *mapping,
- loff_t start, size_t len, loff_t i_size,
+ uoff_t start, size_t len, uoff_t i_size,
netfs_io_terminated_t term_func,
void *term_func_priv,
bool using_pgpriv2, bool caching)
diff --git a/include/linux/fsl/mc.h b/include/linux/fsl/mc.h
index c25f0f7e6dd4..0b2c0eb9b605 100644
--- a/include/linux/fsl/mc.h
+++ b/include/linux/fsl/mc.h
@@ -336,7 +336,7 @@ struct fsl_mc_io {
u16 flags;
u32 portal_size;
phys_addr_t portal_phys_addr;
- void __iomem *portal_virt_addr;
+ void __iomem *portal_virt_addr __counted_by_ptr(portal_size);
struct fsl_mc_device *dpmcp_dev;
union {
/*
diff --git a/include/linux/fsnotify_backend.h b/include/linux/fsnotify_backend.h
index 618eed4d6d72..a6d5c1a89cff 100644
--- a/include/linux/fsnotify_backend.h
+++ b/include/linux/fsnotify_backend.h
@@ -566,6 +566,7 @@ struct fsnotify_mark_connector {
unsigned char prio; /* Highest priority group */
#define FSNOTIFY_CONN_FLAG_IS_WATCHED 0x01
#define FSNOTIFY_CONN_FLAG_HAS_IREF 0x02
+#define FSNOTIFY_CONN_FLAG_DESTROYING 0x04
unsigned short flags; /* flags [lock] */
union {
/* Object pointer [lock] */
diff --git a/include/linux/fsverity.h b/include/linux/fsverity.h
index 6c467ded9751..f9433332c274 100644
--- a/include/linux/fsverity.h
+++ b/include/linux/fsverity.h
@@ -124,6 +124,8 @@ struct fsverity_operations {
* @buf: the Merkle tree block to write
* @pos: the position of the block in the Merkle tree (in bytes)
* @size: the Merkle tree block size (in bytes)
+ * @zero_digest: the hash of the all-zeroes block
+ * @digest_size: size of zero_digest, in bytes
*
* This is only called between ->begin_enable_verity() and
* ->end_enable_verity().
@@ -131,7 +133,9 @@ struct fsverity_operations {
* Return: 0 on success, -errno on failure
*/
int (*write_merkle_tree_block)(struct file *file, const void *buf,
- u64 pos, unsigned int size);
+ u64 pos, unsigned int size,
+ const u8 *zero_digest,
+ unsigned int digest_size);
};
#ifdef CONFIG_FS_VERITY
@@ -317,10 +321,14 @@ static inline int fsverity_file_open(struct inode *inode, struct file *filp)
return 0;
}
+int fsverity_ensure_verity_info(struct inode *inode);
+
void fsverity_cleanup_inode(struct inode *inode);
struct page *generic_read_merkle_tree_page(struct inode *inode, pgoff_t index);
void generic_readahead_merkle_tree(struct inode *inode, pgoff_t index,
unsigned long nr_pages);
+int fsverity_pagecache_read(struct inode *inode, void *buf, size_t count,
+ loff_t pos);
#endif /* _LINUX_FSVERITY_H */
diff --git a/include/linux/ftrace.h b/include/linux/ftrace.h
index bd76a16a63af..b041d9142d2b 100644
--- a/include/linux/ftrace.h
+++ b/include/linux/ftrace.h
@@ -416,6 +416,7 @@ void free_ftrace_hash(struct ftrace_hash *hash);
struct ftrace_func_entry *add_ftrace_hash_entry_direct(struct ftrace_hash *hash,
unsigned long ip, unsigned long direct);
void add_ftrace_hash_entry(struct ftrace_hash *hash, struct ftrace_func_entry *entry);
+struct ftrace_func_entry *ftrace_lookup_ip(struct ftrace_hash *hash, unsigned long ip);
void ftrace_hash_remove(struct ftrace_hash *hash);
/* The hash used to know what functions callbacks trace */
diff --git a/include/linux/futex.h b/include/linux/futex.h
index 18ed18d5cbc1..a895d8c69d66 100644
--- a/include/linux/futex.h
+++ b/include/linux/futex.h
@@ -23,28 +23,32 @@ struct task_struct;
* 01 : Shared futex (PTHREAD_PROCESS_SHARED)
* mapped on a file (reference on the underlying inode)
* 10 : Shared futex (PTHREAD_PROCESS_SHARED)
- * (but private mapping on an mm, and reference taken on it)
+ * (but private mapping on an mm)
*/
-#define FUT_OFF_INODE 1 /* We set bit 0 if key has a reference on inode */
-#define FUT_OFF_MMSHARED 2 /* We set bit 1 if key has a reference on mm */
+#define FUT_OFF_INODE 1 /* We set bit 0 if shared key identifies an inode */
+#define FUT_OFF_MMSHARED 2 /* We set bit 1 if shared key identifies an mm */
union futex_key {
+ /* For FUT_OFF_INODE */
struct {
u64 i_seq;
unsigned long pgoff;
unsigned int offset;
/* unsigned int node; */
} shared;
+
+ /* For FUT_OFF_MMSHARED or private */
struct {
union {
- struct mm_struct *mm;
- u64 __tmp;
+ struct mm_struct *mm; /* for private */
+ u64 mm_seq; /* for FUT_OFF_MMSHARED */
};
unsigned long address;
unsigned int offset;
/* unsigned int node; */
} private;
+
struct {
u64 ptr;
unsigned long word;
@@ -152,11 +156,10 @@ static inline void futex_set_vdso_cs_range(struct futex_mm_data *fd, unsigned in
static inline void futex_fixup_robust_unlock(struct pt_regs *regs) { }
#endif /* !CONFIG_FUTEX_ROBUST_UNLOCK */
-
-#if defined(CONFIG_FUTEX_PRIVATE_HASH) || defined(CONFIG_FUTEX_ROBUST_UNLOCK)
+#ifdef CONFIG_FUTEX
void futex_mm_init(struct mm_struct *mm);
#else
static inline void futex_mm_init(struct mm_struct *mm) { }
-#endif
+#endif /* !CONFIG_FUTEX */
#endif /* _LINUX_FUTEX_H */
diff --git a/include/linux/futex_types.h b/include/linux/futex_types.h
index d320c0571f0c..34b16f2828e7 100644
--- a/include/linux/futex_types.h
+++ b/include/linux/futex_types.h
@@ -85,10 +85,12 @@ struct futex_unlock_cs_ranges { };
* struct futex_mm_data - Futex related per MM data
* @phash: Futex private hash related data
* @unlock: Futex unlock VDSO critical sections
+ * @unique_id: Unique ID of the MM, for FUT_OFF_MMSHARED futexes
*/
struct futex_mm_data {
struct futex_mm_phash phash;
struct futex_unlock_cs_ranges unlock;
+ atomic64_t unique_id;
};
#else /* CONFIG_FUTEX */
struct futex_sched_data { };
diff --git a/include/linux/generic_pt/common.h b/include/linux/generic_pt/common.h
index 07ef1c8341a4..1b39b27f0cfa 100644
--- a/include/linux/generic_pt/common.h
+++ b/include/linux/generic_pt/common.h
@@ -213,4 +213,10 @@ enum {
PT_FEAT_X86_64_AMD_ENCRYPT_TABLES = PT_FEAT_FMT_START,
};
+struct pt_bcm2712 {
+ struct pt_common common;
+ u8 bigpage_lg2;
+ u8 superpage_lg2;
+};
+
#endif
diff --git a/include/linux/generic_pt/iommu.h b/include/linux/generic_pt/iommu.h
index dd0edd02a48a..13ebb72a67de 100644
--- a/include/linux/generic_pt/iommu.h
+++ b/include/linux/generic_pt/iommu.h
@@ -346,6 +346,18 @@ struct pt_iommu_x86_64_hw_info {
IOMMU_FORMAT(x86_64, x86_64_pt);
+struct pt_iommu_bcm2712_cfg {
+ struct pt_iommu_cfg common;
+ u8 bigpage_lg2;
+ u8 superpage_lg2;
+};
+
+struct pt_iommu_bcm2712_hw_info {
+ phys_addr_t pt_base;
+};
+
+IOMMU_FORMAT(bcm2712, bcm2712pt);
+
#undef IOMMU_PROTOTYPES
#undef IOMMU_FORMAT
#endif
diff --git a/include/linux/gfp.h b/include/linux/gfp.h
index 872bc53f32ec..63a7654c725f 100644
--- a/include/linux/gfp.h
+++ b/include/linux/gfp.h
@@ -13,10 +13,6 @@
struct vm_area_struct;
struct mempolicy;
-/* Helper macro to avoid gfp flags if they are the default one */
-#define __default_gfp(a,b,...) b
-#define default_gfp(...) __default_gfp(,##__VA_ARGS__,GFP_KERNEL)
-
static inline bool gfpflags_allow_blocking(const gfp_t gfp_flags)
{
return !!(gfp_flags & __GFP_DIRECT_RECLAIM);
@@ -329,7 +325,7 @@ void *alloc_pages_exact_noprof(size_t size, gfp_t gfp_mask) __alloc_size(1);
void free_pages_exact(void *virt, size_t size);
-__meminit void *alloc_pages_exact_nid_noprof(int nid, size_t size, gfp_t gfp_mask) __alloc_size(2);
+void *alloc_pages_exact_nid_noprof(int nid, size_t size, gfp_t gfp_mask) __alloc_size(2);
#define alloc_pages_exact_nid(...) \
alloc_hooks(alloc_pages_exact_nid_noprof(__VA_ARGS__))
diff --git a/include/linux/gfp_types.h b/include/linux/gfp_types.h
index 190191411009..c1331bf0b239 100644
--- a/include/linux/gfp_types.h
+++ b/include/linux/gfp_types.h
@@ -244,7 +244,7 @@ enum {
* definitely preferable to use the flag rather than opencode endless
* loop around allocator.
* Allocating pages from the buddy with __GFP_NOFAIL and order > 1 is
- * not supported. Please consider using kvmalloc() instead.
+ * discouraged. Please consider using kvmalloc() instead if possible.
*/
#define __GFP_IO ((__force gfp_t)___GFP_IO)
#define __GFP_FS ((__force gfp_t)___GFP_FS)
@@ -382,4 +382,8 @@ enum {
__GFP_NOMEMALLOC | __GFP_NOWARN) & ~__GFP_RECLAIM)
#define GFP_TRANSHUGE (GFP_TRANSHUGE_LIGHT | __GFP_DIRECT_RECLAIM)
+/* Helper macro to avoid gfp flags if they are the default one */
+#define __default_gfp(a,b,...) b
+#define default_gfp(...) __default_gfp(,##__VA_ARGS__,GFP_KERNEL)
+
#endif /* __LINUX_GFP_TYPES_H */
diff --git a/include/linux/gpio/driver.h b/include/linux/gpio/driver.h
index 17511434ed07..4077dc678cae 100644
--- a/include/linux/gpio/driver.h
+++ b/include/linux/gpio/driver.h
@@ -359,6 +359,10 @@ struct gpio_irq_chip {
* @set_config: optional hook for all kinds of settings. Uses the same
* packed config format as generic pinconf. Must return 0 on success and
* a negative error number on failure.
+ * @get_config: optional hook to read back a setting. Takes the packed
+ * generic pinconf parameter to query and returns its bare argument in
+ * the same variable, like pinctrl_gpio_get_config(). Must return 0 on
+ * success and a negative error number on failure.
* @to_irq: optional hook supporting non-static gpiod_to_irq() mappings;
* implementation may not sleep
* @dbg_show: optional routine to show contents in debugfs; default code
@@ -434,6 +438,9 @@ struct gpio_chip {
int (*set_config)(struct gpio_chip *gc,
unsigned int offset,
unsigned long config);
+ int (*get_config)(struct gpio_chip *gc,
+ unsigned int offset,
+ unsigned long *config);
int (*to_irq)(struct gpio_chip *gc,
unsigned int offset);
@@ -708,6 +715,8 @@ int gpiochip_generic_request(struct gpio_chip *gc, unsigned int offset);
void gpiochip_generic_free(struct gpio_chip *gc, unsigned int offset);
int gpiochip_generic_config(struct gpio_chip *gc, unsigned int offset,
unsigned long config);
+int gpiochip_generic_get_config(struct gpio_chip *gc, unsigned int offset,
+ unsigned long *config);
/**
* struct gpio_pin_range - pin range controlled by a gpio chip
diff --git a/include/linux/gpio/legacy.h b/include/linux/gpio/legacy.h
index 557ef635935e..4001208d5d63 100644
--- a/include/linux/gpio/legacy.h
+++ b/include/linux/gpio/legacy.h
@@ -63,10 +63,6 @@ static inline int gpio_get_value_cansleep(unsigned gpio)
{
return gpiod_get_raw_value_cansleep(gpio_to_desc(gpio));
}
-static inline void gpio_set_value_cansleep(unsigned gpio, int value)
-{
- gpiod_set_raw_value_cansleep(gpio_to_desc(gpio), value);
-}
static inline int gpio_get_value(unsigned gpio)
{
@@ -148,12 +144,6 @@ static inline int gpio_get_value_cansleep(unsigned gpio)
return 0;
}
-static inline void gpio_set_value_cansleep(unsigned gpio, int value)
-{
- /* GPIO can never have been requested or set as output */
- WARN_ON(1);
-}
-
static inline int gpio_to_irq(unsigned gpio)
{
/* GPIO can never have been requested or set as input */
diff --git a/include/linux/gpio/regmap.h b/include/linux/gpio/regmap.h
index 6f52c140e50d..6fe0877717cb 100644
--- a/include/linux/gpio/regmap.h
+++ b/include/linux/gpio/regmap.h
@@ -46,6 +46,7 @@ enum gpio_regmap_operation {
* @parent: The parent device
* @regmap: The regmap used to access the registers
* given, the name of the device is used
+ * @pm_dev: (Optional) Device to use for runtime power management.
* @fwnode: (Optional) The firmware node.
* If not given, the fwnode of the parent is used.
* @label: (Optional) Descriptive name for GPIO controller.
@@ -117,6 +118,7 @@ enum gpio_regmap_operation {
struct gpio_regmap_config {
struct device *parent;
struct regmap *regmap;
+ struct device *pm_dev;
struct fwnode_handle *fwnode;
const char *label;
diff --git a/include/linux/gpu_buddy.h b/include/linux/gpu_buddy.h
index 2c36124bb696..ddc4eca84175 100644
--- a/include/linux/gpu_buddy.h
+++ b/include/linux/gpu_buddy.h
@@ -43,8 +43,8 @@
/**
* GPU_BUDDY_CLEAR_ALLOCATION - Prefer pre-cleared (zeroed) memory
*
- * Attempt to allocate from the clear tree first. If insufficient clear
- * memory is available, falls back to dirty memory. Useful when the
+ * Attempt to allocate outside dirty-tracked ranges first. If insufficient
+ * clear memory is available, falls back to dirty memory. Useful when the
* caller needs zeroed memory and wants to avoid GPU clear operations.
*/
#define GPU_BUDDY_CLEAR_ALLOCATION BIT(3)
@@ -53,8 +53,8 @@
* GPU_BUDDY_CLEARED - Mark returned blocks as cleared
*
* Used with gpu_buddy_free_list() to indicate that the memory being
- * freed has been cleared (zeroed). The blocks will be placed in the
- * clear tree for future GPU_BUDDY_CLEAR_ALLOCATION requests.
+ * freed has been cleared (zeroed). The blocks will be removed from the
+ * dirty tracker for future GPU_BUDDY_CLEAR_ALLOCATION requests.
*/
#define GPU_BUDDY_CLEARED BIT(4)
@@ -67,15 +67,17 @@
*/
#define GPU_BUDDY_TRIM_DISABLE BIT(5)
-enum gpu_buddy_free_tree {
- GPU_BUDDY_CLEAR_TREE = 0,
- GPU_BUDDY_DIRTY_TREE,
- GPU_BUDDY_MAX_FREE_TREES,
+/*
+ * Clear/dirty state of a free block. Ordered so a numerically larger value
+ * is "more clear" (DIRTY < MIXED < CLEAR) which lets subtree_block_state be
+ * maintained as a simple max-augment over the per-order free tree.
+ */
+enum gpu_block_state {
+ GPU_BLOCK_DIRTY = 0,
+ GPU_BLOCK_MIXED = 1,
+ GPU_BLOCK_CLEAR = 2,
};
-#define for_each_free_tree(tree) \
- for ((tree) = 0; (tree) < GPU_BUDDY_MAX_FREE_TREES; (tree)++)
-
/**
* struct gpu_buddy_block - Block within a buddy allocator
*
@@ -103,6 +105,13 @@ struct gpu_buddy_block {
#define GPU_BUDDY_ALLOCATED (1 << 10)
#define GPU_BUDDY_FREE (2 << 10)
#define GPU_BUDDY_SPLIT (3 << 10)
+/*
+ * GPU_BUDDY_HEADER_CLEAR has two roles:
+ * - FREE state: set when the block's full range is cleared (dirty
+ * tracker confirmed no overlap).
+ * - ALLOCATED state: set when the block was served from cleared memory,
+ * informing the caller that no GPU clear pass is needed.
+ */
#define GPU_BUDDY_HEADER_CLEAR GENMASK_ULL(9, 9)
/* Free to be used, if needed in the future */
#define GPU_BUDDY_HEADER_UNUSED GENMASK_ULL(8, 6)
@@ -128,14 +137,45 @@ struct gpu_buddy_block {
struct list_head link;
};
/* private: */
- struct list_head tmp_link;
+ enum gpu_block_state subtree_block_state;
unsigned int subtree_max_alignment;
+ struct list_head tmp_link;
+ bool has_clear;
};
/* Order-zero must be at least SZ_4K */
#define GPU_BUDDY_MAX_ORDER (63 - 12)
/**
+ * struct gpu_dirty_extent - a contiguous dirty address range
+ *
+ * Tracks a single contiguous address range whose memory content is known
+ * to be dirty. Extents are non-overlapping and stored in an augmented
+ * red-black tree sorted by @start. The augmented value @subtree_max_size
+ * allows O(log N) search for an extent of at least a given size.
+ */
+struct gpu_dirty_extent {
+/* private: */
+ struct rb_node rb;
+ u64 start;
+ u64 end;
+ u64 subtree_max_size;
+};
+
+/**
+ * struct gpu_dirty_tracker - tracks dirty address intervals
+ *
+ * Maintains a set of non-overlapping dirty extents as an augmented
+ * red-black tree.
+ */
+struct gpu_dirty_tracker {
+/* private: */
+ struct rb_root root;
+ /* Total bytes of dirty memory currently tracked. */
+ u64 total_dirty;
+};
+
+/**
* struct gpu_buddy - GPU binary buddy allocator
*
* The buddy allocator provides efficient power-of-two memory allocation
@@ -152,20 +192,21 @@ struct gpu_buddy_block {
* @chunk_size: Minimum allocation granularity in bytes. Must be at least SZ_4K.
* @size: Total size of the address space managed by this allocator in bytes.
* @avail: Total free space currently available for allocation in bytes.
- * @clear_avail: Free space available in the clear tree (zeroed memory) in bytes.
- * This is a subset of @avail.
* @lock_dep_map: Annotates gpu_buddy API with a driver provided lock.
*/
struct gpu_buddy {
/* private: */
+ /* Tracker of dirty address ranges (decoupled from free_tree). */
+ struct gpu_dirty_tracker dirty;
/*
- * Array of red-black trees for free block management.
- * Indexed as free_trees[clear/dirty][order] where:
- * - Index 0 (GPU_BUDDY_CLEAR_TREE): blocks with zeroed content
- * - Index 1 (GPU_BUDDY_DIRTY_TREE): blocks with unknown content
- * Each tree holds free blocks of the corresponding order.
+ * One RB-tree per order containing all free blocks (clear and
+ * dirty alike). The augment field subtree_block_state (a max over
+ * the subtree of each block's state) lets clear allocations
+ * find the right-most fully-clear or mixed block in O(log N).
+ * Dirty free blocks coexist here but are also indexed by the
+ * @dirty tracker for fast dirty allocation lookups.
*/
- struct rb_root **free_trees;
+ struct rb_root *free_tree;
/*
* Array of root blocks representing the top-level blocks of the
* binary tree(s). Multiple roots exist when the total size is not
@@ -194,7 +235,6 @@ struct gpu_buddy {
u64 chunk_size;
u64 size;
u64 avail;
- u64 clear_avail;
#ifdef CONFIG_LOCKDEP
struct lockdep_map *lock_dep_map;
#endif
@@ -226,17 +266,32 @@ struct gpu_buddy {
*
* Ensure driver lock is held.
*/
-static inline void gpu_buddy_driver_lock_held(struct gpu_buddy *mm)
+static inline void gpu_buddy_driver_lock_held(const struct gpu_buddy *mm)
{
if (mm->lock_dep_map)
lockdep_assert(lock_is_held_type(mm->lock_dep_map, 0));
}
#else
-static inline void gpu_buddy_driver_lock_held(struct gpu_buddy *mm)
+static inline void gpu_buddy_driver_lock_held(const struct gpu_buddy *mm)
{
}
#endif
+/**
+ * gpu_buddy_clear_avail - free space that is clear (zeroed), in bytes
+ * @mm: gpu buddy allocator
+ *
+ * A subset of @mm->avail. Derived on demand as @mm->avail minus the bytes
+ * the dirty tracker records as dirty, so it is always consistent with the
+ * tracker without a cached field to keep in sync. Zero for a fresh pool,
+ * which is fully dirty.
+ */
+static inline u64 gpu_buddy_clear_avail(const struct gpu_buddy *mm)
+{
+ gpu_buddy_driver_lock_held(mm);
+ return mm->avail - mm->dirty.total_dirty;
+}
+
static inline u64
gpu_buddy_block_offset(const struct gpu_buddy_block *block)
{
diff --git a/include/linux/greybus/bundle.h b/include/linux/greybus/bundle.h
index df8d88424cb7..361a94d3499b 100644
--- a/include/linux/greybus/bundle.h
+++ b/include/linux/greybus/bundle.h
@@ -59,14 +59,9 @@ static inline int gb_pm_runtime_get_sync(struct gb_bundle *bundle)
return 0;
}
-static inline int gb_pm_runtime_put_autosuspend(struct gb_bundle *bundle)
+static inline void gb_pm_runtime_put_autosuspend(struct gb_bundle *bundle)
{
- int retval;
-
- pm_runtime_mark_last_busy(&bundle->dev);
- retval = pm_runtime_put_autosuspend(&bundle->dev);
-
- return retval;
+ pm_runtime_put_autosuspend(&bundle->dev);
}
static inline void gb_pm_runtime_get_noresume(struct gb_bundle *bundle)
@@ -82,8 +77,7 @@ static inline void gb_pm_runtime_put_noidle(struct gb_bundle *bundle)
#else
static inline int gb_pm_runtime_get_sync(struct gb_bundle *bundle)
{ return 0; }
-static inline int gb_pm_runtime_put_autosuspend(struct gb_bundle *bundle)
-{ return 0; }
+static inline void gb_pm_runtime_put_autosuspend(struct gb_bundle *bundle) {}
static inline void gb_pm_runtime_get_noresume(struct gb_bundle *bundle) {}
static inline void gb_pm_runtime_put_noidle(struct gb_bundle *bundle) {}
diff --git a/include/linux/hardirq.h b/include/linux/hardirq.h
index 73b48dd9f135..2648c49cd8f6 100644
--- a/include/linux/hardirq.h
+++ b/include/linux/hardirq.h
@@ -108,7 +108,7 @@ DECLARE_PER_CPU(unsigned int, nmi_nesting);
#define __preempt_count_nmi_enter() \
do { \
__preempt_count_add(HARDIRQ_OFFSET); \
- /* Maximum NMI nesting is 15. */ \
+ /* NMI nesting is represented in 4 bits. */ \
BUG_ON(__this_cpu_read(nmi_nesting) >= 15); \
__this_cpu_inc(nmi_nesting); \
preempt_count_set(preempt_count() | NMI_MASK); \
diff --git a/include/linux/hdmi.h b/include/linux/hdmi.h
index 8dab78e1f61b..b80a5ee63bb2 100644
--- a/include/linux/hdmi.h
+++ b/include/linux/hdmi.h
@@ -27,6 +27,18 @@
#include <linux/types.h>
#include <linux/device.h>
+enum hdmi_version {
+ HDMI_VERSION_UNKNOWN,
+ HDMI_VERSION_1_0,
+ HDMI_VERSION_1_1,
+ HDMI_VERSION_1_2,
+ HDMI_VERSION_1_3,
+ HDMI_VERSION_1_4,
+ HDMI_VERSION_2_0,
+ HDMI_VERSION_2_1,
+ HDMI_VERSION_2_2,
+};
+
enum hdmi_packet_type {
HDMI_PACKET_TYPE_NULL = 0x00,
HDMI_PACKET_TYPE_AUDIO_CLOCK_REGEN = 0x01,
diff --git a/include/linux/hiddev.h b/include/linux/hiddev.h
index 2164c03d2c72..8e9f8a33e359 100644
--- a/include/linux/hiddev.h
+++ b/include/linux/hiddev.h
@@ -13,6 +13,7 @@
#ifndef _HIDDEV_H
#define _HIDDEV_H
+#include <linux/refcount.h>
#include <uapi/linux/hiddev.h>
@@ -24,6 +25,7 @@ struct hiddev {
int minor;
int exist;
int open;
+ refcount_t refcount;
struct mutex existancelock;
wait_queue_head_t wait;
struct hid_device *hid;
diff --git a/include/linux/hisi_acc_qm.h b/include/linux/hisi_acc_qm.h
index f7570a409905..f2885d60b468 100644
--- a/include/linux/hisi_acc_qm.h
+++ b/include/linux/hisi_acc_qm.h
@@ -196,7 +196,7 @@ struct qm_dev_dfx {
};
struct dfx_diff_registers {
- u32 *regs;
+ u32 *regs __counted_by_ptr(reg_len);
u32 reg_offset;
u32 reg_len;
};
@@ -332,9 +332,9 @@ struct hisi_qm_cap_record {
struct hisi_qm_cap_tables {
u32 qm_cap_size;
- struct hisi_qm_cap_record *qm_cap_table;
+ struct hisi_qm_cap_record *qm_cap_table __counted_by_ptr(qm_cap_size);
u32 dev_cap_size;
- struct hisi_qm_cap_record *dev_cap_table;
+ struct hisi_qm_cap_record *dev_cap_table __counted_by_ptr(dev_cap_size);
};
struct hisi_qm_list {
diff --git a/include/linux/host1x.h b/include/linux/host1x.h
index a7a675783136..e7ba601b2afb 100644
--- a/include/linux/host1x.h
+++ b/include/linux/host1x.h
@@ -237,6 +237,8 @@ void host1x_syncpt_release_vblank_reservation(struct host1x_client *client,
struct dma_fence *host1x_fence_create(struct host1x_syncpt *sp, u32 threshold,
bool timeout);
void host1x_fence_cancel(struct dma_fence *fence);
+int host1x_fence_extract(struct dma_fence *fence, struct host1x **host1x,
+ u32 *id, u32 *threshold);
/*
* host1x channel
@@ -465,13 +467,26 @@ int host1x_client_resume(struct host1x_client *client);
struct host1x_memory_context {
struct host1x *host;
+ struct device *dev; /* Owning engine */
+ struct pid *pid;
+
refcount_t ref;
- struct pid *owner;
+ bool static_alloc;
- struct device_dma_parameters dma_parms;
- struct device dev;
- u64 dma_mask;
- u32 stream_id;
+ struct host1x_hw_memory_context *hw;
+ struct list_head entry; /* Entry in hw_memory_context's list */
+ struct list_head mappings; /* List of mappings */
+};
+
+struct host1x_context_mapping {
+ struct host1x *host;
+
+ struct host1x_bo_mapping *mapping;
+
+ struct host1x_bo *bo;
+ enum dma_data_direction direction;
+
+ struct list_head entry;
};
#ifdef CONFIG_IOMMU_API
@@ -480,6 +495,12 @@ struct host1x_memory_context *host1x_memory_context_alloc(struct host1x *host1x,
struct pid *pid);
void host1x_memory_context_get(struct host1x_memory_context *cd);
void host1x_memory_context_put(struct host1x_memory_context *cd);
+int host1x_memory_context_active(struct host1x_memory_context *cd);
+void host1x_memory_context_inactive(struct host1x_memory_context *cd);
+struct host1x_context_mapping *host1x_memory_context_map(struct host1x_memory_context *ctx,
+ struct host1x_bo *bo,
+ enum dma_data_direction direction);
+void host1x_memory_context_unmap(struct host1x_context_mapping *m);
#else
static inline struct host1x_memory_context *host1x_memory_context_alloc(struct host1x *host1x,
struct device *dev,
@@ -495,6 +516,26 @@ static inline void host1x_memory_context_get(struct host1x_memory_context *cd)
static inline void host1x_memory_context_put(struct host1x_memory_context *cd)
{
}
+
+static inline int host1x_memory_context_active(struct host1x_memory_context *cd)
+{
+ return -ENODEV;
+}
+
+static inline void host1x_memory_context_inactive(struct host1x_memory_context *cd)
+{
+}
+
+static inline struct host1x_context_mapping *
+host1x_memory_context_map(struct host1x_memory_context *ctx, struct host1x_bo *bo,
+ enum dma_data_direction direction)
+{
+ return ERR_PTR(-ENODEV);
+}
+
+static inline void host1x_memory_context_unmap(struct host1x_context_mapping *m)
+{
+}
#endif
#endif
diff --git a/include/linux/hrtimer.h b/include/linux/hrtimer.h
index 29072d89e5cb..cad8482337cb 100644
--- a/include/linux/hrtimer.h
+++ b/include/linux/hrtimer.h
@@ -72,7 +72,7 @@ enum hrtimer_mode {
*/
struct hrtimer_sleeper {
struct hrtimer timer;
- struct task_struct *task;
+ struct task_struct *__private task;
};
static inline void hrtimer_set_expires(struct hrtimer *timer, ktime_t time)
@@ -320,6 +320,14 @@ extern int schedule_hrtimeout_range_clock(ktime_t *expires,
const enum hrtimer_mode mode,
clockid_t clock_id);
extern int schedule_hrtimeout(ktime_t *expires, const enum hrtimer_mode mode);
+static inline struct task_struct *hrtimer_sleeper_task_get(struct hrtimer_sleeper *sl)
+{
+ return READ_ONCE(ACCESS_PRIVATE(sl, task));
+}
+static inline void hrtimer_sleeper_task_set(struct hrtimer_sleeper *sl, struct task_struct *t)
+{
+ WRITE_ONCE(ACCESS_PRIVATE(sl, task), t);
+}
/* Soft interrupt function to run the hrtimer queues: */
extern void hrtimer_run_queues(void);
diff --git a/include/linux/hrtimer_rearm.h b/include/linux/hrtimer_rearm.h
index 17a81826bd9a..12e42721c8e0 100644
--- a/include/linux/hrtimer_rearm.h
+++ b/include/linux/hrtimer_rearm.h
@@ -45,7 +45,7 @@ hrtimer_rearm_deferred_user_irq(unsigned long *tif_work, const unsigned long tif
clear_thread_flag(TIF_HRTIMER_REARM);
__hrtimer_rearm_deferred();
/* Don't go into the loop if HRTIMER_REARM was the only flag */
- *tif_work &= ~TIF_HRTIMER_REARM;
+ *tif_work &= ~_TIF_HRTIMER_REARM;
return !*tif_work;
}
return false;
diff --git a/include/linux/hugetlb.h b/include/linux/hugetlb.h
index 16c4c4caa126..80a5a03e9cee 100644
--- a/include/linux/hugetlb.h
+++ b/include/linux/hugetlb.h
@@ -171,7 +171,6 @@ struct address_space *hugetlb_folio_mapping_lock_write(struct folio *folio);
extern int movable_gigantic_pages __read_mostly;
extern int sysctl_hugetlb_shm_group __read_mostly;
-extern struct list_head huge_boot_pages[MAX_NUMNODES];
void hugetlb_bootmem_struct_page_init(void);
void hugetlb_bootmem_alloc(void);
@@ -676,10 +675,6 @@ struct hstate {
char name[HSTATE_NAME_LEN];
};
-#define HUGE_BOOTMEM_HVO 0x0001
-#define HUGE_BOOTMEM_ZONES_VALID 0x0002
-#define HUGE_BOOTMEM_CMA 0x0004
-
int isolate_or_dissolve_huge_folio(struct folio *folio, struct list_head *list);
int replace_free_hugepage_folios(unsigned long start_pfn, unsigned long end_pfn);
void wait_for_freed_hugetlb_folios(void);
@@ -699,7 +694,8 @@ enum hugetlb_alloc_flag {
#define HUGETLB_ALLOC_USE_GLOBAL_RESERVATIONS BIT(HUGETLB_ALLOC_USE_GLOBAL_RESERVATIONS_BIT)
struct folio *hugetlb_alloc_folio(struct hstate *h,
- struct mempolicy_interpreted *mpoli, u8 alloc_flags);
+ struct mempolicy_interpreted *mpoli, struct mm_struct *mm,
+ u8 alloc_flags);
struct folio *alloc_hugetlb_folio(struct vm_area_struct *vma,
unsigned long addr, bool cow_from_owner);
struct folio *alloc_hugetlb_folio_nodemask(struct hstate *h, int preferred_nid,
diff --git a/include/linux/hyperv.h b/include/linux/hyperv.h
index 9e109d91aa14..e61f9a4cb7c3 100644
--- a/include/linux/hyperv.h
+++ b/include/linux/hyperv.h
@@ -1299,6 +1299,14 @@ struct hv_device {
#define device_to_hv_device(d) container_of_const(d, struct hv_device, device)
#define drv_to_hv_drv(d) container_of_const(d, struct hv_driver, driver)
+static inline u32 hv_build_logical_dev_id_prefix(struct hv_device *hdev)
+{
+ return ((u32)hdev->dev_instance.b[5] << 24) |
+ ((u32)hdev->dev_instance.b[4] << 16) |
+ ((u32)hdev->dev_instance.b[7] << 8) |
+ (hdev->dev_instance.b[6] & 0xf8u);
+}
+
static inline void hv_set_drvdata(struct hv_device *dev, void *data)
{
dev_set_drvdata(&dev->device, data);
diff --git a/include/linux/i2c.h b/include/linux/i2c.h
index 14ab4d3055af..f3192ab1982e 100644
--- a/include/linux/i2c.h
+++ b/include/linux/i2c.h
@@ -174,8 +174,23 @@ i2c_smbus_write_word_swapped(const struct i2c_client *client,
}
/* Returns the number of read bytes */
-s32 i2c_smbus_read_block_data(const struct i2c_client *client,
- u8 command, u8 *values);
+s32 __i2c_smbus_read_block_data(const struct i2c_client *client,
+ u8 command, u8 length, u8 *values);
+/*
+ * This monstrosity allows to call i2c_smbus_read_block_data() with either
+ * 3 or 4 arguments and will be removed once all users have been switched
+ * to the 4 argument version.
+ */
+#define __i2c_smbus_read_block_data_3arg(client, cmd, values) \
+ __i2c_smbus_read_block_data(client, cmd, I2C_SMBUS_BLOCK_MAX, values)
+#define __i2c_smbus_read_block_data_4arg(client, cmd, length, values) \
+ __i2c_smbus_read_block_data(client, cmd, length, values)
+#define __i2c_smbus_read_block_data_impl(_1, _2, _3, _4, impl, ...) impl
+#define i2c_smbus_read_block_data(client, cmd, varargs...) \
+ __i2c_smbus_read_block_data_impl(client, cmd, varargs, \
+ __i2c_smbus_read_block_data_4arg, \
+ __i2c_smbus_read_block_data_3arg) \
+ (client, cmd, varargs)
s32 i2c_smbus_write_block_data(const struct i2c_client *client,
u8 command, u8 length, const u8 *values);
/* Returns the number of read bytes */
@@ -919,8 +934,8 @@ static inline u32 i2c_get_functionality(struct i2c_adapter *adap)
return adap->algo->functionality(adap);
}
-/* Return 1 if adapter supports everything we need, 0 if not. */
-static inline int i2c_check_functionality(struct i2c_adapter *adap, u32 func)
+/* Return true if adapter supports everything we need, false if not. */
+static inline bool i2c_check_functionality(struct i2c_adapter *adap, u32 func)
{
return (func & i2c_get_functionality(adap)) == func;
}
diff --git a/include/linux/idr.h b/include/linux/idr.h
index 789e23e67444..e2a4b6298511 100644
--- a/include/linux/idr.h
+++ b/include/linux/idr.h
@@ -16,6 +16,7 @@
#include <linux/gfp.h>
#include <linux/percpu.h>
#include <linux/cleanup.h>
+#include <linux/compiler.h>
struct idr {
struct radix_tree_root idr_rt;
@@ -269,7 +270,9 @@ struct ida {
#define IDA_INIT(name) { \
.xa = XARRAY_INIT(name, IDA_INIT_FLAGS) \
}
-#define DEFINE_IDA(name) struct ida name = IDA_INIT(name)
+#define DEFINE_IDA(name) \
+ struct ida name = IDA_INIT(name); \
+ ASSERT_STATIC_STORAGE(name)
int ida_alloc_range(struct ida *, unsigned int min, unsigned int max, gfp_t);
void ida_free(struct ida *, unsigned int id);
diff --git a/include/linux/ieee80211-eht.h b/include/linux/ieee80211-eht.h
index b62297a978e7..a699d108eee6 100644
--- a/include/linux/ieee80211-eht.h
+++ b/include/linux/ieee80211-eht.h
@@ -482,6 +482,7 @@ struct ieee80211_multi_link_elem {
#define IEEE80211_MLC_BASIC_PRES_MLD_ID 0x0200
#define IEEE80211_MLC_BASIC_PRES_EXT_MLD_CAPA_OP 0x0400
#define IEEE80211_MLC_BASIC_PRES_ENH_CRIT_UPD 0x0800
+#define IEEE80211_MLC_BASIC_PRES_AGE_OF_BSS_LOAD 0x1000
#define IEEE80211_MED_SYNC_DELAY_DURATION 0x00ff
#define IEEE80211_MED_SYNC_DELAY_SYNC_OFDM_ED_THRESH 0x0f00
@@ -550,6 +551,8 @@ struct ieee80211_mle_basic_common_info {
} __packed;
#define IEEE80211_MLC_PREQ_PRES_MLD_ID 0x0010
+#define IEEE80211_MLC_PREQ_PRES_MLD_MAC_ADDR 0x0020
+#define IEEE80211_MLC_PREQ_PRES_NEIGH_AP_MLD_MAC_ADDR 0x0040
struct ieee80211_mle_preq_common_info {
u8 len;
@@ -560,6 +563,7 @@ struct ieee80211_mle_preq_common_info {
#define IEEE80211_MLC_RECONF_PRES_EML_CAPA 0x0020
#define IEEE80211_MLC_RECONF_PRES_MLD_CAPA_OP 0x0040
#define IEEE80211_MLC_RECONF_PRES_EXT_MLD_CAPA_OP 0x0080
+#define IEEE80211_MLC_RECONF_PRES_TARGET_AP_MLD_ADDR 0x0100
/* no fixed fields in RECONF */
@@ -766,7 +770,7 @@ static inline u16 ieee80211_mle_get_mld_capa_op(const u8 *data)
#define IEEE80211_EHT_ML_EXT_MLD_CAPA_NSTR_UPDATE 0x0020
#define IEEE80211_EHT_ML_EXT_MLD_CAPA_EMLSR_ENA_ON_ONE_LINK 0x0040
#define IEEE80211_EHT_ML_EXT_MLD_CAPA_BTM_MLD_RECO_MULTI_AP 0x0080
-/* defined by UHR Draft P802.11bn_D1.3 Figure 9-1147 */
+/* defined by UHR Draft P802.11bn_D1.5 Figure 9-1168 */
#define IEEE80211_UHR_ML_EXT_MLD_CAPA_ML_PM 0x0100
/**
@@ -928,11 +932,17 @@ static inline bool ieee80211_mle_size_ok(const u8 *data, size_t len)
common += 2;
if (control & IEEE80211_MLC_BASIC_PRES_ENH_CRIT_UPD)
common += 1;
+ if (control & IEEE80211_MLC_BASIC_PRES_AGE_OF_BSS_LOAD)
+ common += 1;
break;
case IEEE80211_ML_CONTROL_TYPE_PREQ:
common += sizeof(struct ieee80211_mle_preq_common_info);
if (control & IEEE80211_MLC_PREQ_PRES_MLD_ID)
common += 1;
+ if (control & IEEE80211_MLC_PREQ_PRES_MLD_MAC_ADDR)
+ common += ETH_ALEN;
+ if (control & IEEE80211_MLC_PREQ_PRES_NEIGH_AP_MLD_MAC_ADDR)
+ common += ETH_ALEN;
break;
case IEEE80211_ML_CONTROL_TYPE_RECONF:
common += 1;
@@ -944,6 +954,8 @@ static inline bool ieee80211_mle_size_ok(const u8 *data, size_t len)
common += 2;
if (control & IEEE80211_MLC_RECONF_PRES_EXT_MLD_CAPA_OP)
common += 2;
+ if (control & IEEE80211_MLC_RECONF_PRES_TARGET_AP_MLD_ADDR)
+ common += ETH_ALEN;
break;
case IEEE80211_ML_CONTROL_TYPE_TDLS:
common += sizeof(struct ieee80211_mle_tdls_common_info);
@@ -1003,6 +1015,7 @@ enum ieee80211_mle_subelems {
#define IEEE80211_MLE_STA_CONTROL_BSS_PARAM_CHANGE_CNT_PRESENT 0x0800
#define IEEE80211_MLE_STA_CONTROL_ENH_CRIT_UPD_PRESENT 0x1000
#define IEEE80211_MLE_STA_CONTROL_AP_CONDUCTED_TX_PWR_PRESENT 0x2000
+#define IEEE80211_MLE_STA_CONTROL_AGE_OF_BSS_LOAD_PRESENT 0x4000
struct ieee80211_mle_per_sta_profile {
__le16 control;
@@ -1054,6 +1067,9 @@ static inline bool ieee80211_mle_basic_sta_prof_size_ok(const u8 *data,
if (control & IEEE80211_MLE_STA_CONTROL_AP_CONDUCTED_TX_PWR_PRESENT)
info_len += 1;
+ if (control & IEEE80211_MLE_STA_CONTROL_AGE_OF_BSS_LOAD_PRESENT)
+ info_len += 1;
+
return prof->sta_info_len >= info_len &&
fixed + prof->sta_info_len - 1 <= len;
}
diff --git a/include/linux/ieee80211-mesh.h b/include/linux/ieee80211-mesh.h
index 7eb15834531c..9e548b9173df 100644
--- a/include/linux/ieee80211-mesh.h
+++ b/include/linux/ieee80211-mesh.h
@@ -361,8 +361,7 @@ ieee80211_mesh_hwmp_perr_get_rcode(const u8 *ie, u8 dst_idx)
/* IEEE Std 802.11-2016 9.4.2.113 PREQ element */
static inline bool ieee80211_mesh_preq_size_ok(const u8 *pos, u8 elen)
{
- struct ieee80211_mesh_hwmp_preq_bottom *preq_elem_bottom =
- ieee80211_mesh_hwmp_preq_get_bottom(pos);
+ struct ieee80211_mesh_hwmp_preq_bottom *preq_elem_bottom;
u8 target_count;
int needed;
@@ -378,6 +377,7 @@ static inline bool ieee80211_mesh_preq_size_ok(const u8 *pos, u8 elen)
if (elen < needed)
return false;
+ preq_elem_bottom = ieee80211_mesh_hwmp_preq_get_bottom(pos);
target_count = preq_elem_bottom->target_count;
/* IEEE Std 802.11-2016 Table 14-10 to 14-16 */
if (target_count < 1)
diff --git a/include/linux/ieee80211-nan.h b/include/linux/ieee80211-nan.h
index 455033955e54..7815a6cf8160 100644
--- a/include/linux/ieee80211-nan.h
+++ b/include/linux/ieee80211-nan.h
@@ -40,6 +40,8 @@
/* NAN attributes, as defined in Wi-Fi Aware (TM) specification 4.0 Table 42 */
#define NAN_ATTR_MASTER_INDICATION 0x00
#define NAN_ATTR_CLUSTER_INFO 0x01
+#define NAN_ATTR_SERVICE_ID_LIST 0x02
+#define NAN_ATTR_SUBSCRIBE_SERVICE_ID_LIST 0x28
struct ieee80211_nan_attr {
u8 attr;
@@ -74,4 +76,30 @@ struct ieee80211_nan_anchor_master_info {
_attr = (const struct ieee80211_nan_attr *) \
(_attr->data + le16_to_cpu(_attr->length)))
+static inline bool ieee80211_is_nan_beacon(const struct ieee80211_mgmt *mgmt,
+ size_t len)
+{
+ const struct element *elem;
+
+ /* The NAN IE is at least 6 octets */
+ if (len < offsetofend(struct ieee80211_mgmt, u.beacon) + 6)
+ return false;
+
+ if (!ieee80211_is_beacon(mgmt->frame_control))
+ return false;
+
+ /* NAN Cluster IDs range from 50-6F-9A-01-00-00 to 50-6F-9A-01-FF-FF */
+ if (get_unaligned_be32(mgmt->bssid) != ((WLAN_OUI_WFA << 8) | 0x01))
+ return false;
+
+ elem = (const struct element *)mgmt->u.beacon.variable;
+ if (elem->id != WLAN_EID_VENDOR_SPECIFIC ||
+ elem->datalen < 4 ||
+ get_unaligned_be32(elem->data) !=
+ (WLAN_OUI_WFA << 8 | WLAN_OUI_TYPE_WFA_NAN))
+ return false;
+
+ return true;
+}
+
#endif /* LINUX_IEEE80211_NAN_H */
diff --git a/include/linux/ieee80211-uhr.h b/include/linux/ieee80211-uhr.h
index 665d4b3a5b41..19e9260d0db8 100644
--- a/include/linux/ieee80211-uhr.h
+++ b/include/linux/ieee80211-uhr.h
@@ -17,32 +17,32 @@
#define IEEE80211_UHR_OPER_PARAMS_PEDCA_ENA 0x0004
#define IEEE80211_UHR_OPER_PARAMS_DBE_ENA 0x0008
#define IEEE80211_UHR_OPER_PARAMS_DBE_BW 0x0070
-#define IEEE80211_UHR_OPER_PARAMS_DUO_PRES 0x0080
-#define IEEE80211_UHR_OPER_PARAMS_DPS_PRES 0x0100
-#define IEEE80211_UHR_OPER_PARAMS_NPCA_PRES 0x0200
-#define IEEE80211_UHR_OPER_PARAMS_PEDCA_PRES 0x0400
-#define IEEE80211_UHR_OPER_PARAMS_DBE_PRES 0x0800
+#define IEEE80211_UHR_OPER_PARAMS_ELR_RX 0x0080
+#define IEEE80211_UHR_OPER_PARAMS_DUO_PRES 0x0100
+#define IEEE80211_UHR_OPER_PARAMS_DPS_PRES 0x0200
+#define IEEE80211_UHR_OPER_PARAMS_NPCA_PRES 0x0400
+#define IEEE80211_UHR_OPER_PARAMS_PEDCA_PRES 0x0800
+#define IEEE80211_UHR_OPER_PARAMS_DBE_PRES 0x1000
struct ieee80211_uhr_operation {
__le16 params;
- u8 basic_mcs_nss_set[4];
u8 variable[];
} __packed;
-#define IEEE80211_UHR_NPCA_PARAMS_PRIMARY_CHAN_OFFS 0x0000000F
-#define IEEE80211_UHR_NPCA_PARAMS_MIN_DUR_THRESH 0x000000F0
-#define IEEE80211_UHR_NPCA_PARAMS_SWITCH_DELAY 0x00003F00
-#define IEEE80211_UHR_NPCA_PARAMS_SWITCH_BACK_DELAY 0x000FC000
-#define IEEE80211_UHR_NPCA_PARAMS_INIT_QSRC 0x00300000
-#define IEEE80211_UHR_NPCA_PARAMS_MOPLEN 0x00400000
-#define IEEE80211_UHR_NPCA_PARAMS_DIS_SUBCH_BMAP_PRES 0x00800000
+#define IEEE80211_UHR_NPCA_PARAMS_PRIMARY_CHAN 0x000000FF
+#define IEEE80211_UHR_NPCA_PARAMS_MIN_DUR_THRESH 0x00000F00
+#define IEEE80211_UHR_NPCA_PARAMS_SWITCH_DELAY 0x0003F000
+#define IEEE80211_UHR_NPCA_PARAMS_SWITCH_BACK_DELAY 0x00FC0000
+#define IEEE80211_UHR_NPCA_PARAMS_INIT_QSRC 0x03000000
+#define IEEE80211_UHR_NPCA_PARAMS_MOPLEN 0x04000000
+#define IEEE80211_UHR_NPCA_PARAMS_DIS_SUBCH_BMAP_PRES 0x08000000
/**
* struct ieee80211_uhr_npca_info - npca operation information
*
* This structure is the "NPCA Operation Parameters field format" of "UHR
- * Operation Element" fields as described in P802.11bn_D1.3
- * subclause 9.4.2.353. See Figure 9-aa4.
+ * Operation Element" fields as described in P802.11bn_D1.5
+ * subclause 9.4.2.355.2, see Figure 9-aa6.
*
* Refer to IEEE80211_UHR_NPCA*
* @params:
@@ -97,7 +97,7 @@ struct ieee80211_uhr_npca_info {
* struct ieee80211_uhr_dps_info - DPS operation information
*
* This structure is the "DPS Operation Parameter field" of "UHR
- * Operation Element" fields as described in P802.11bn_D1.3
+ * Operation Element" fields as described in P802.11bn_D1.5
* subclause 9.4.1.87. See Figure 9-207u.
*
* Refer to IEEE80211_UHR_DPS*
@@ -211,8 +211,8 @@ static inline int ieee80211_uhr_dbe_bw_mhz(enum ieee80211_uhr_dbe_oper_bw bw)
* struct ieee80211_uhr_dbe_info - DBE operation information
*
* This structure is the "DBE Operation Parameters field" of
- * "UHR Operation Element" fields as described in P802.11bn_D1.3
- * subclause 9.4.2.353. See Figure 9-aa6.
+ * "UHR Operation Element" fields as described in P802.11bn_D1.5
+ * subclause 9.4.2.355.4, see Figure 9-aa9.
*
* Refer to IEEE80211_UHR_DBE_OPER*
* @params:
@@ -234,25 +234,23 @@ struct ieee80211_uhr_dbe_info {
__le16 dis_subch_bmap[];
} __packed;
-#define IEEE80211_UHR_P_EDCA_ECWMIN 0x0F
-#define IEEE80211_UHR_P_EDCA_ECWMAX 0xF0
-#define IEEE80211_UHR_P_EDCA_AIFSN 0x000F
-#define IEEE80211_UHR_P_EDCA_CW_DS 0x0030
-#define IEEE80211_UHR_P_EDCA_PSRC_THRESHOLD 0x01C0
-#define IEEE80211_UHR_P_EDCA_QSRC_THRESHOLD 0x0600
+#define IEEE80211_UHR_P_EDCA_ECWMIN 0x0007
+#define IEEE80211_UHR_P_EDCA_ECWMAX 0x0038
+#define IEEE80211_UHR_P_EDCA_AIFSN 0x01C0
+#define IEEE80211_UHR_P_EDCA_CW_DS 0x0600
+#define IEEE80211_UHR_P_EDCA_PSRC_THRESHOLD 0x3800
+#define IEEE80211_UHR_P_EDCA_QSRC_THRESHOLD 0xC000
/**
* struct ieee80211_uhr_p_edca_info - P-EDCA operation information
*
* This structure is the "P-EDCA Operation Parameters field" of
- * "UHR Operation Element" fields as described in P802.11bn_D1.3
- * subclause 9.4.2.353. See Figure 9-aa5.
+ * "UHR Operation Element" fields as described in P802.11bn_D1.5
+ * subclause 9.4.2.355.3, see Figure 9-aa8.
*
* Refer to IEEE80211_UHR_P_EDCA*
- * @p_edca_ec: P-EDCA ECWmin and ECWmax.
- * These fields indicate the CWmin and CWmax values used by a
- * P-EDCA STA during P-EDCA contention.
- * @params: AIFSN, CW DS, PSRC threshold, and QSRC threshold.
+ * @params: ECWmin, ECWmax, AIFSN, CW DS, PSRC threshold, and QSRC threshold.
+ * - CWmin/CWmax values used by a P-EDCA STA during P-EDCA contention.
* - The AIFSN field indicates the AIFSN value used by a P-EDCA STA
* during P-EDCA contention.
* - The CW DS field indicates the value used for randomization of the
@@ -266,7 +264,6 @@ struct ieee80211_uhr_dbe_info {
* value 0 is reserved.
*/
struct ieee80211_uhr_p_edca_info {
- u8 p_edca_ec;
__le16 params;
} __packed;
@@ -302,7 +299,7 @@ static inline bool ieee80211_uhr_oper_size_ok(const u8 *data, u8 len)
}
}
- /* P-EDCA Operation Parameters (fixed 3 bytes) */
+ /* P-EDCA Operation Parameters */
if (oper->params & cpu_to_le16(IEEE80211_UHR_OPER_PARAMS_PEDCA_PRES)) {
needed += sizeof(struct ieee80211_uhr_p_edca_info);
if (len < needed)
@@ -341,6 +338,9 @@ ieee80211_uhr_npca_info(const struct ieee80211_uhr_operation *oper)
if (!(oper->params & cpu_to_le16(IEEE80211_UHR_OPER_PARAMS_NPCA_ENA)))
return NULL;
+ if (oper->params & cpu_to_le16(IEEE80211_UHR_OPER_PARAMS_DUO_PRES))
+ pos += 1;
+
if (oper->params & cpu_to_le16(IEEE80211_UHR_OPER_PARAMS_DPS_PRES))
pos += sizeof(struct ieee80211_uhr_dps_info);
@@ -372,6 +372,9 @@ ieee80211_uhr_oper_dbe_info(const struct ieee80211_uhr_operation *oper)
if (!(oper->params & cpu_to_le16(IEEE80211_UHR_OPER_PARAMS_DBE_ENA)))
return NULL;
+ if (oper->params & cpu_to_le16(IEEE80211_UHR_OPER_PARAMS_DUO_PRES))
+ pos += 1;
+
if (oper->params & cpu_to_le16(IEEE80211_UHR_OPER_PARAMS_DPS_PRES))
pos += sizeof(struct ieee80211_uhr_dps_info);
@@ -415,28 +418,42 @@ ieee80211_uhr_oper_dbe_info(const struct ieee80211_uhr_operation *oper)
#define IEEE80211_UHR_MAC_CAP2_UHR_OM_PU_TO_LOW 0xC0
#define IEEE80211_UHR_MAC_CAP3_UHR_OM_PU_TO_HIGH 0x03
-#define IEEE80211_UHR_MAC_CAP3_PARAM_UPD_ADV_NOTIF_INTV 0x1C
-#define IEEE80211_UHR_MAC_CAP3_UPD_IND_TIM_INTV_LOW 0xE0
+#define IEEE80211_UHR_MAC_CAP3_PARAM_UPD_ADV_NOTIF_INTV 0x7C
+#define IEEE80211_UHR_MAC_CAP3_UPD_IND_TIM_INTV_LOW 0x80
-#define IEEE80211_UHR_MAC_CAP4_UPD_IND_TIM_INTV_HIGH 0x03
-#define IEEE80211_UHR_MAC_CAP4_BOUNDED_ESS 0x04
-#define IEEE80211_UHR_MAC_CAP4_BTM_ASSURANCE 0x08
-#define IEEE80211_UHR_MAC_CAP4_CO_BF_SUPP 0x10
+#define IEEE80211_UHR_MAC_CAP4_UPD_IND_TIM_INTV_HIGH 0x0F
+#define IEEE80211_UHR_MAC_CAP4_BOUNDED_ESS 0x10
+#define IEEE80211_UHR_MAC_CAP4_BTM_ASSURANCE 0x20
+#define IEEE80211_UHR_MAC_CAP4_CO_BF_SUPP 0x40
+#define IEEE80211_UHR_MAC_CAP4_CO_SR_SUPP 0x80
+
+#define IEEE80211_UHR_MAC_CAP5_MAPC_ENH_MSRMT_SUPP 0x01
#define IEEE80211_UHR_MAC_CAP_DBE_MAX_BW 0x07
#define IEEE80211_UHR_MAC_CAP_DBE_EHT_MCS_MAP_160_PRES 0x08
#define IEEE80211_UHR_MAC_CAP_DBE_EHT_MCS_MAP_320_PRES 0x10
+/* struct ieee80211_uhr_cap_dbe::bwcap[].cap */
+#define IEEE80211_UHR_MAC_CAP_DBE_CAP_NUM_SND_DIMS 0x07
+#define IEEE80211_UHR_MAC_CAP_DBE_CAP_NON_OFDMA_UL_MUMIMO 0x08
+#define IEEE80211_UHR_MAC_CAP_DBE_CAP_MU_BEAMFORMER 0x10
+#define IEEE80211_UHR_MAC_CAP_DBE_CAP_BEAMFORMEE_SS 0xe0
+
struct ieee80211_uhr_cap_dbe {
u8 cap;
+ u8 max_switch_time_period;
+ u8 mode_change_intvl;
/* present 0, 1 or 2 times depending on _PRES bits */
- struct ieee80211_eht_mcs_nss_supp_bw eht_mcs_map[];
+ struct {
+ struct ieee80211_eht_mcs_nss_supp_bw eht_mcs_map;
+ u8 cap;
+ } __packed bwcap[];
} __packed;
/**
* enum ieee80211_uhr_dbe_max_supported_bw - DBE Maximum Supported Bandwidth
*
- * As per spec P802.11bn_D1.3 "Table 9-bb5—Encoding of the DBE Maximum
+ * As per spec P802.11bn_D1.5 Table 9-bb8 "Encoding of the DBE Maximum
* Supported Bandwidth field".
*
* @IEEE80211_UHR_DBE_MAX_BW_40: Indicates 40 MHz DBE max supported bw
@@ -520,10 +537,10 @@ static inline bool ieee80211_uhr_capa_size_ok(const u8 *data, u8 len,
dbe = (const void *)cap->variable;
if (dbe->cap & IEEE80211_UHR_MAC_CAP_DBE_EHT_MCS_MAP_160_PRES)
- needed += sizeof(dbe->eht_mcs_map[0]);
+ needed += sizeof(dbe->bwcap[0]);
if (dbe->cap & IEEE80211_UHR_MAC_CAP_DBE_EHT_MCS_MAP_320_PRES)
- needed += sizeof(dbe->eht_mcs_map[0]);
+ needed += sizeof(dbe->bwcap[0]);
}
return len >= needed;
diff --git a/include/linux/ieee80211.h b/include/linux/ieee80211.h
index 26e674038865..66f9ebe79c61 100644
--- a/include/linux/ieee80211.h
+++ b/include/linux/ieee80211.h
@@ -1828,6 +1828,7 @@ enum ieee80211_eid_ext {
WLAN_EID_EXT_BANDWIDTH_INDICATION = 135,
WLAN_EID_EXT_KNOWN_STA_IDENTIFCATION = 136,
WLAN_EID_EXT_NON_AP_STA_REG_CON = 137,
+ WLAN_EID_EXT_CIP_CAPA = 150,
WLAN_EID_EXT_UHR_OPER = 151,
WLAN_EID_EXT_UHR_CAPA = 152,
WLAN_EID_EXT_MACP = 153,
@@ -2421,8 +2422,7 @@ static inline bool ieee80211_is_bufferable_mmpdu(struct sk_buff *skb)
/* action frame - additionally check for non-bufferable FTM */
- if (mgmt->u.action.category != WLAN_CATEGORY_PUBLIC &&
- mgmt->u.action.category != WLAN_CATEGORY_PROTECTED_DUAL_OF_ACTION)
+ if (mgmt->u.action.category != WLAN_CATEGORY_PUBLIC)
return true;
if (mgmt->u.action.action_code == WLAN_PUB_ACTION_FTM_REQUEST ||
@@ -2730,6 +2730,10 @@ struct element {
u8 data[];
} __packed;
+/* trigger enum comparison warnings if applicable (constant id) */
+#define element_iteration_typecheck(type, id) \
+ (((type)0 == (id)) || true)
+
/* element iteration helpers */
#define for_each_element(_elem, _data, _datalen) \
for (_elem = (const struct element *)(_data); \
@@ -2741,11 +2745,15 @@ struct element {
#define for_each_element_id(element, _id, data, datalen) \
for_each_element(element, data, datalen) \
- if (element->id == (_id))
+ if (element_iteration_typecheck(enum ieee80211_eid, \
+ _id) && \
+ element->id == (_id))
#define for_each_element_extid(element, extid, _data, _datalen) \
for_each_element(element, _data, _datalen) \
- if (element->id == WLAN_EID_EXTENSION && \
+ if (element_iteration_typecheck(enum ieee80211_eid_ext, \
+ extid) && \
+ element->id == WLAN_EID_EXTENSION && \
element->datalen > 0 && \
element->data[0] == (extid))
@@ -2753,10 +2761,11 @@ struct element {
for_each_element(sub, (element)->data, (element)->datalen)
#define for_each_subelement_id(sub, id, element) \
- for_each_element_id(sub, id, (element)->data, (element)->datalen)
+ for_each_element_id(sub, (u8)id, (element)->data, (element)->datalen)
#define for_each_subelement_extid(sub, extid, element) \
- for_each_element_extid(sub, extid, (element)->data, (element)->datalen)
+ for_each_element_extid(sub, (u8)extid, (element)->data, \
+ (element)->datalen)
/**
* for_each_element_completed - determine if element parsing consumed all data
@@ -2900,4 +2909,25 @@ static inline bool ieee80211_check_tim(const struct ieee80211_tim_ie *tim,
__ieee80211_check_tim(tim, tim_len, aid);
}
+/**
+ * enum ieee80211_cip_cap_fields - CIP Capabilities element fields
+ * @IEEE80211_CIP_CAP_MIC_PADDING: The MIC padding subfield in the CIP
+ * capabilities
+ * @IEEE80211_CIP_CAP_PROTECTED_CTRL_FRAME_ONLY: The MIC Padding For Protected
+ * Control Frames Only bit in CIP capabilities
+ */
+enum ieee80211_cip_cap_fields {
+ IEEE80211_CIP_CAP_MIC_PADDING = 0x0F,
+ IEEE80211_CIP_CAP_PROTECTED_CTRL_FRAME_ONLY = 0x10,
+};
+
+/**
+ * struct ieee80211_cip_cap - CIP Capabilities element
+ *
+ * @v: The value of the Control Integrity Protocol Capability element
+ */
+struct ieee80211_cip_cap {
+ u8 v;
+} __packed;
+
#endif /* LINUX_IEEE80211_H */
diff --git a/include/linux/if_vlan.h b/include/linux/if_vlan.h
index 20cc16ea4e5a..c863cdf60f01 100644
--- a/include/linux/if_vlan.h
+++ b/include/linux/if_vlan.h
@@ -365,6 +365,9 @@ static inline int __vlan_insert_inner_tag(struct sk_buff *skb,
const u8 meta_len = mac_len > ETH_TLEN ? skb_metadata_len(skb) : 0;
struct vlan_ethhdr *veth;
+ if (unlikely(!pskb_may_pull(skb, mac_len)))
+ return -EINVAL;
+
if (skb_cow_head(skb, meta_len + VLAN_HLEN) < 0)
return -ENOMEM;
@@ -424,8 +427,8 @@ static inline int __vlan_insert_tag(struct sk_buff *skb,
* Inserts the VLAN tag into @skb as part of the payload at offset mac_len
* Returns a VLAN tagged skb. This might change skb->head.
*
- * Following the skb_unshare() example, in case of error, the calling function
- * doesn't have to worry about freeing the original skb.
+ * Following the skb_unclone_full() example, in case of error, the calling
+ * function doesn't have to worry about freeing the original skb.
*
* Does not change skb->protocol so this function can be used during receive.
*
@@ -455,8 +458,8 @@ static inline struct sk_buff *vlan_insert_inner_tag(struct sk_buff *skb,
* Inserts the VLAN tag into @skb as part of the payload
* Returns a VLAN tagged skb. This might change skb->head.
*
- * Following the skb_unshare() example, in case of error, the calling function
- * doesn't have to worry about freeing the original skb.
+ * Following the skb_unclone_full() example, in case of error, the calling
+ * function doesn't have to worry about freeing the original skb.
*
* Does not change skb->protocol so this function can be used during receive.
*
@@ -477,8 +480,8 @@ static inline struct sk_buff *vlan_insert_tag(struct sk_buff *skb,
* Inserts the VLAN tag into @skb as part of the payload
* Returns a VLAN tagged skb. This might change skb->head.
*
- * Following the skb_unshare() example, in case of error, the calling function
- * doesn't have to worry about freeing the original skb.
+ * Following the skb_unclone_full() example, in case of error, the calling
+ * function doesn't have to worry about freeing the original skb.
*
* Return: modified @skb on success, NULL on error (@skb is freed).
*/
@@ -521,8 +524,8 @@ static inline void __vlan_hwaccel_copy_tag(struct sk_buff *dst, const struct sk_
*
* Pushes the VLAN tag from @skb->vlan_tci inside to the payload.
*
- * Following the skb_unshare() example, in case of error, the calling function
- * doesn't have to worry about freeing the original skb.
+ * Following the skb_unclone_full() example, in case of error, the calling
+ * function doesn't have to worry about freeing the original skb.
*/
static inline struct sk_buff *__vlan_hwaccel_push_inside(struct sk_buff *skb)
{
@@ -695,7 +698,6 @@ static inline void vlan_set_encap_proto(struct sk_buff *skb,
struct vlan_hdr *vhdr)
{
__be16 proto;
- unsigned short *rawp;
/*
* Was a VLAN packet, grab the encapsulated protocol, which the layer
@@ -708,21 +710,8 @@ static inline void vlan_set_encap_proto(struct sk_buff *skb,
return;
}
- rawp = (unsigned short *)(vhdr + 1);
- if (*rawp == 0xFFFF)
- /*
- * This is a magic hack to spot IPX packets. Older Novell
- * breaks the protocol design and runs IPX over 802.3 without
- * an 802.2 LLC layer. We look for FFFF which isn't a used
- * 802.2 SSAP/DSAP. This won't work for fault tolerant netware
- * but does for the rest.
- */
- skb->protocol = htons(ETH_P_802_3);
- else
- /*
- * Real 802.2 LLC
- */
- skb->protocol = htons(ETH_P_802_2);
+ /* No ethertype: this is an 802.2 LLC frame (length field). */
+ skb->protocol = htons(ETH_P_802_2);
}
/**
diff --git a/include/linux/igmp.h b/include/linux/igmp.h
index a0cf0398519f..e075611344ef 100644
--- a/include/linux/igmp.h
+++ b/include/linux/igmp.h
@@ -14,6 +14,7 @@
#include <linux/timer.h>
#include <linux/in.h>
#include <linux/ip.h>
+#include <linux/net.h>
#include <linux/refcount.h>
#include <linux/sockptr.h>
#include <uapi/linux/igmp.h>
@@ -273,7 +274,7 @@ extern int ip_mc_source(int add, int omode, struct sock *sk,
struct ip_mreq_source *mreqs, int ifindex);
extern int ip_mc_msfilter(struct sock *sk, struct ip_msfilter *msf,int ifindex);
extern int ip_mc_msfget(struct sock *sk, struct ip_msfilter *msf,
- sockptr_t optval, sockptr_t optlen);
+ sockopt_t *opt);
extern int ip_mc_gsfget(struct sock *sk, struct group_filter *gsf,
sockptr_t optval, size_t offset);
extern int ip_mc_sf_allow(const struct sock *sk, __be32 local, __be32 rmt,
diff --git a/include/linux/iio/adc/qcom-adc5-gen3-common.h b/include/linux/iio/adc/qcom-adc5-gen3-common.h
index 39cbfcbdb101..b3e2c2f50e8f 100644
--- a/include/linux/iio/adc/qcom-adc5-gen3-common.h
+++ b/include/linux/iio/adc/qcom-adc5-gen3-common.h
@@ -137,7 +137,7 @@ struct adc5_sdam_data {
*/
struct adc5_device_data {
struct regmap *regmap;
- struct adc5_sdam_data *base;
+ struct adc5_sdam_data *base __counted_by_ptr(num_sdams);
int num_sdams;
};
diff --git a/include/linux/iio/backend.h b/include/linux/iio/backend.h
index 3f95ed1fdf9e..9c16b695a602 100644
--- a/include/linux/iio/backend.h
+++ b/include/linux/iio/backend.h
@@ -133,6 +133,8 @@ enum iio_backend_capabilities {
* @filter_type_set: Set filter type.
* @interface_data_align: Perform the data alignment process.
* @num_lanes_set: Set the number of lanes enabled.
+ * @crc_enable: Enable direction-specific CRC handling.
+ * @crc_disable: Disable direction-specific CRC handling.
* @ddr_enable: Enable interface DDR (Double Data Rate) mode.
* @ddr_disable: Disable interface DDR (Double Data Rate) mode.
* @data_stream_enable: Enable data stream.
@@ -189,6 +191,8 @@ struct iio_backend_ops {
enum iio_backend_filter_type type);
int (*interface_data_align)(struct iio_backend *back, u32 timeout_us);
int (*num_lanes_set)(struct iio_backend *back, unsigned int num_lanes);
+ int (*crc_enable)(struct iio_backend *back);
+ int (*crc_disable)(struct iio_backend *back);
int (*ddr_enable)(struct iio_backend *back);
int (*ddr_disable)(struct iio_backend *back);
int (*data_stream_enable)(struct iio_backend *back);
@@ -237,6 +241,8 @@ int iio_backend_filter_type_set(struct iio_backend *back,
enum iio_backend_filter_type type);
int iio_backend_interface_data_align(struct iio_backend *back, u32 timeout_us);
int iio_backend_num_lanes_set(struct iio_backend *back, unsigned int num_lanes);
+int iio_backend_crc_enable(struct iio_backend *back);
+int iio_backend_crc_disable(struct iio_backend *back);
int iio_backend_ddr_enable(struct iio_backend *back);
int iio_backend_ddr_disable(struct iio_backend *back);
int iio_backend_data_stream_enable(struct iio_backend *back);
diff --git a/include/linux/iio/iio-gts-helper.h b/include/linux/iio/iio-gts-helper.h
index 66f830ab9b49..0c4b2e9fbe1e 100644
--- a/include/linux/iio/iio-gts-helper.h
+++ b/include/linux/iio/iio-gts-helper.h
@@ -7,6 +7,7 @@
#ifndef __IIO_GTS_HELPER__
#define __IIO_GTS_HELPER__
+#include <linux/errno.h>
#include <linux/types.h>
struct device;
@@ -58,14 +59,14 @@ struct iio_itime_sel_mul {
struct iio_gts {
u64 max_scale;
- const struct iio_gain_sel_pair *hwgain_table;
+ const struct iio_gain_sel_pair *hwgain_table __counted_by_ptr(num_hwgain);
int num_hwgain;
- const struct iio_itime_sel_mul *itime_table;
+ const struct iio_itime_sel_mul *itime_table __counted_by_ptr(num_itime);
int num_itime;
- int **per_time_avail_scale_tables;
- int *avail_all_scales_table;
+ int **per_time_avail_scale_tables __counted_by_ptr(num_itime);
+ int *avail_all_scales_table __counted_by_ptr(num_avail_all_scales);
int num_avail_all_scales;
- int *avail_time_tables;
+ int *avail_time_tables __counted_by_ptr(num_avail_time_tables);
int num_avail_time_tables;
};
diff --git a/include/linux/iio/iio-opaque.h b/include/linux/iio/iio-opaque.h
index b87841a355f8..98330385e08d 100644
--- a/include/linux/iio/iio-opaque.h
+++ b/include/linux/iio/iio-opaque.h
@@ -73,7 +73,7 @@ struct iio_dev_opaque {
#if defined(CONFIG_DEBUG_FS)
struct dentry *debugfs_dentry;
unsigned int cached_reg_addr;
- char read_buf[20];
+ char read_buf[24];
unsigned int read_buf_len;
#endif
};
diff --git a/include/linux/iio/iio.h b/include/linux/iio/iio.h
index 711c00f67371..9b63785d5aec 100644
--- a/include/linux/iio/iio.h
+++ b/include/linux/iio/iio.h
@@ -264,6 +264,10 @@ struct iio_scan_type {
* @ext_info: Array of extended info attributes for this channel.
* The array is NULL terminated, the last element should
* have its name field set to NULL.
+ * @parent: Optional pointer to the parent channel spec for
+ * hierarchical channel relationships. When set, a read-only
+ * "parent" sysfs attribute is created containing the
+ * parent channel's sysfs name prefix (e.g. "in_voltage0").
* @extend_name: Allows labeling of channel attributes with an
* informative name. Note this has no effect codes etc,
* unlike modifiers.
@@ -309,6 +313,7 @@ struct iio_chan_spec {
const struct iio_event_spec *event_spec;
unsigned int num_event_specs;
const struct iio_chan_spec_ext_info *ext_info;
+ const struct iio_chan_spec *parent;
const char *extend_name;
const char *datasheet_name;
unsigned int modified:1;
@@ -484,6 +489,10 @@ struct iio_trigger; /* forward declaration */
* @update_scan_mode: function to configure device and scan buffer when
* channels have changed
* @debugfs_reg_access: function to read or write register value of device
+ * @debugfs_reg64_access: function to read or write 64-bit register value of
+ * device. debugfs_reg_access() and debugfs_reg64_access()
+ * are mutually exclusive, but the 64-bit variant has
+ * precedence in case both are implemented.
* @fwnode_xlate: fwnode based function pointer to obtain channel specifier index.
* @hwfifo_set_watermark: function pointer to set the current hardware
* fifo watermark level; see hwfifo_* entries in
@@ -572,6 +581,9 @@ struct iio_info {
int (*debugfs_reg_access)(struct iio_dev *indio_dev,
unsigned int reg, unsigned int writeval,
unsigned int *readval);
+ int (*debugfs_reg64_access)(struct iio_dev *indio_dev,
+ unsigned int reg, u64 writeval,
+ u64 *readval);
int (*fwnode_xlate)(struct iio_dev *indio_dev,
const struct fwnode_reference_args *iiospec);
int (*hwfifo_set_watermark)(struct iio_dev *indio_dev, unsigned int val);
@@ -648,7 +660,7 @@ struct iio_dev {
struct iio_poll_func *pollfunc;
struct iio_poll_func *pollfunc_event;
- struct iio_chan_spec const *channels;
+ struct iio_chan_spec const *channels __counted_by_ptr(num_channels);
int num_channels;
const char *name;
@@ -789,7 +801,7 @@ DEFINE_GUARD_COND(__priv__iio_dev_mode_lock, _try_direct,
*
* Tries to acquire the direct mode lock with cleanup ACQUIRE() semantics and
* automatically releases it at the end of the scope. It most be always paired
- * with IIO_DEV_ACQUIRE_ERR(), for example (notice the scope braces)::
+ * with IIO_DEV_ACQUIRE_FAILED(), for example (notice the scope braces)::
*
* switch() {
* case IIO_CHAN_INFO_RAW: {
@@ -1083,6 +1095,15 @@ static inline unsigned int iio_get_masklength(const struct iio_dev *indio_dev)
return ACCESS_PRIVATE(indio_dev, masklength);
}
+/**
+ * iio_scan_timestamp_enabled - Is the timestamp channel in the current scan
+ * @indio_dev: the IIO device to check
+ */
+static inline bool iio_scan_timestamp_enabled(const struct iio_dev *indio_dev)
+{
+ return ACCESS_PRIVATE(indio_dev, scan_timestamp);
+}
+
int iio_active_scan_mask_index(struct iio_dev *indio_dev);
/**
diff --git a/include/linux/input/samsung-keypad.h b/include/linux/input/samsung-keypad.h
deleted file mode 100644
index ab6b97114c08..000000000000
--- a/include/linux/input/samsung-keypad.h
+++ /dev/null
@@ -1,39 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-or-later */
-/*
- * Samsung Keypad platform data definitions
- *
- * Copyright (C) 2010 Samsung Electronics Co.Ltd
- * Author: Joonyoung Shim <jy0922.shim@samsung.com>
- */
-
-#ifndef __SAMSUNG_KEYPAD_H
-#define __SAMSUNG_KEYPAD_H
-
-#include <linux/input/matrix_keypad.h>
-
-#define SAMSUNG_MAX_ROWS 8
-#define SAMSUNG_MAX_COLS 8
-
-/**
- * struct samsung_keypad_platdata - Platform device data for Samsung Keypad.
- * @keymap_data: pointer to &matrix_keymap_data.
- * @rows: number of keypad row supported.
- * @cols: number of keypad col supported.
- * @no_autorepeat: disable key autorepeat.
- * @wakeup: controls whether the device should be set up as wakeup source.
- * @cfg_gpio: configure the GPIO.
- *
- * Initialisation data specific to either the machine or the platform
- * for the device driver to use or call-back when configuring gpio.
- */
-struct samsung_keypad_platdata {
- const struct matrix_keymap_data *keymap_data;
- unsigned int rows;
- unsigned int cols;
- bool no_autorepeat;
- bool wakeup;
-
- void (*cfg_gpio)(unsigned int rows, unsigned int cols);
-};
-
-#endif /* __SAMSUNG_KEYPAD_H */
diff --git a/include/linux/interrupt.h b/include/linux/interrupt.h
index 3bf969ad8fe0..ee2dd5349697 100644
--- a/include/linux/interrupt.h
+++ b/include/linux/interrupt.h
@@ -119,6 +119,7 @@ typedef irqreturn_t (*irq_handler_t)(int, void *);
* @thread_flags: flags related to @thread
* @thread_mask: bitmask for keeping track of @thread activity
* @dir: pointer to the proc/irq/NN/name entry
+ * @thread_dtor: task_work for @thread irregular exit cleanup
*/
struct irqaction {
irq_handler_t handler;
@@ -137,6 +138,7 @@ struct irqaction {
unsigned long thread_mask;
const char *name;
struct proc_dir_entry *dir;
+ struct callback_head thread_dtor;
} ____cacheline_internodealigned_in_smp;
extern irqreturn_t no_action(int cpl, void *dev_id);
@@ -573,9 +575,11 @@ enum
* _ IRQ_POLL: irq_poll_cpu_dead() migrates the queue
*
* _ (HR)TIMER_SOFTIRQ: (hr)timers_dead_cpu() migrates the queue
+ *
+ * _ BLOCK_SOFTIRQ: blk_softirq_cpu_dead() completes the remaining requests
*/
-#define SOFTIRQ_HOTPLUG_SAFE_MASK (BIT(TIMER_SOFTIRQ) | BIT(IRQ_POLL_SOFTIRQ) |\
- BIT(HRTIMER_SOFTIRQ) | BIT(RCU_SOFTIRQ))
+#define SOFTIRQ_HOTPLUG_SAFE_MASK (BIT(TIMER_SOFTIRQ) | BIT(BLOCK_SOFTIRQ) |\
+ BIT(IRQ_POLL_SOFTIRQ) | BIT(HRTIMER_SOFTIRQ) | BIT(RCU_SOFTIRQ))
/* map softirq index to softirq name. update 'softirq_to_name' in
diff --git a/include/linux/interrupt_rc.h b/include/linux/interrupt_rc.h
index a9ed937a80e7..d385ab05a2b6 100644
--- a/include/linux/interrupt_rc.h
+++ b/include/linux/interrupt_rc.h
@@ -11,6 +11,7 @@
* make it easier to include without hitting circular header dependencies.
*/
+#include <linux/debug_locks.h>
#include <linux/irqflags.h>
#include <linux/preempt.h>
#include <linux/processor.h>
@@ -65,6 +66,13 @@ static inline void local_interrupt_disable(void)
local_irq_save(flags);
new_count = hardirq_disable_enter();
+ /* Is hardirq disable count overflow soon? */
+ if (IS_ENABLED(CONFIG_DEBUG_PREEMPT) &&
+ DEBUG_LOCKS_WARN_ON(((new_count & HARDIRQ_DISABLE_MASK) +
+ (10 << HARDIRQ_DISABLE_SHIFT)) >=
+ HARDIRQ_DISABLE_MASK))
+ return;
+
if ((new_count & HARDIRQ_DISABLE_MASK) == HARDIRQ_DISABLE_OFFSET)
_local_interrupt_save_state(flags);
}
@@ -73,6 +81,11 @@ static inline void local_interrupt_enable(void)
{
int new_count;
+ /* Unpaired local_interrupt_enable()? Warn and abort. */
+ if (IS_ENABLED(CONFIG_DEBUG_PREEMPT) &&
+ DEBUG_LOCKS_WARN_ON((preempt_count() & HARDIRQ_DISABLE_MASK) == 0))
+ return;
+
new_count = hardirq_disable_exit();
if ((new_count & HARDIRQ_DISABLE_MASK) == 0)
diff --git a/include/linux/io_uring.h b/include/linux/io_uring.h
index d1aa4edfc2a5..505caa99c621 100644
--- a/include/linux/io_uring.h
+++ b/include/linux/io_uring.h
@@ -2,10 +2,42 @@
#ifndef _LINUX_IO_URING_H
#define _LINUX_IO_URING_H
+#include <linux/io_uring_types.h>
#include <linux/sched.h>
#include <linux/xarray.h>
#include <uapi/linux/io_uring.h>
+static inline void req_set_fail(struct io_kiocb *req)
+{
+ req->flags |= REQ_F_FAIL;
+ if (req->flags & REQ_F_CQE_SKIP) {
+ req->flags &= ~REQ_F_CQE_SKIP;
+ req->flags |= REQ_F_SKIP_LINK_CQES;
+ }
+}
+
+static inline void io_req_set_res(struct io_kiocb *req, s32 res, u32 cflags)
+{
+ req->cqe.res = res;
+ req->cqe.flags = cflags;
+}
+
+static inline u32 ctx_cqe32_flags(struct io_ring_ctx *ctx)
+{
+ if (ctx->flags & IORING_SETUP_CQE_MIXED)
+ return IORING_CQE_F_32;
+ return 0;
+}
+
+static inline void io_req_set_res32(struct io_kiocb *req, s32 res, u32 cflags,
+ __u64 extra1, __u64 extra2)
+{
+ req->cqe.res = res;
+ req->cqe.flags = cflags | ctx_cqe32_flags(req->ctx);
+ req->big_cqe.extra1 = extra1;
+ req->big_cqe.extra2 = extra2;
+}
+
#if defined(CONFIG_IO_URING)
void __io_uring_cancel(bool cancel_all);
void __io_uring_free(struct task_struct *tsk);
diff --git a/include/linux/io_uring/cmd.h b/include/linux/io_uring/cmd.h
index 42801f0b6456..e18d4af62e1a 100644
--- a/include/linux/io_uring/cmd.h
+++ b/include/linux/io_uring/cmd.h
@@ -3,6 +3,7 @@
#define _LINUX_IO_URING_CMD_H
#include <uapi/linux/io_uring.h>
+#include <linux/io_uring.h>
#include <linux/io_uring_types.h>
#include <linux/blk-mq.h>
@@ -41,6 +42,24 @@ static inline void io_uring_cmd_private_sz_check(size_t cmd_sz)
((pdu_type *)&(cmd)->pdu) \
)
+static inline void io_uring_cmd_set_res(struct io_uring_cmd *cmd, s32 ret)
+{
+ struct io_kiocb *req = cmd_to_io_kiocb(cmd);
+
+ if (ret < 0)
+ req_set_fail(req);
+ io_req_set_res(req, ret, 0);
+}
+
+static inline void io_uring_cmd_set_res32(struct io_uring_cmd *cmd, s32 ret, u64 res2)
+{
+ struct io_kiocb *req = cmd_to_io_kiocb(cmd);
+
+ if (ret < 0)
+ req_set_fail(req);
+ io_req_set_res32(req, ret, 0, res2, 0);
+}
+
#if defined(CONFIG_IO_URING)
int io_uring_cmd_import_fixed(u64 ubuf, unsigned long len, int rw,
struct iov_iter *iter,
@@ -56,11 +75,12 @@ int io_uring_cmd_import_fixed_vec(struct io_uring_cmd *ioucmd,
* Completes the request, i.e. posts an io_uring CQE and deallocates @ioucmd
* and the corresponding io_uring request.
*
+ * io_uring_cmd_set_res()/io_uring_cmd_set_res32() must be called first.
+ *
* Note: the caller should never hard code @issue_flags and is only allowed
* to pass the mask provided by the core io_uring code.
*/
-void __io_uring_cmd_done(struct io_uring_cmd *cmd, s32 ret, u64 res2,
- unsigned issue_flags, bool is_cqe32);
+void __io_uring_cmd_done(struct io_uring_cmd *, unsigned issue_flags);
void __io_uring_cmd_do_in_task(struct io_uring_cmd *ioucmd,
io_req_tw_func_t task_work_cb,
@@ -116,8 +136,8 @@ static inline int io_uring_cmd_import_fixed_vec(struct io_uring_cmd *ioucmd,
{
return -EOPNOTSUPP;
}
-static inline void __io_uring_cmd_done(struct io_uring_cmd *cmd, s32 ret,
- u64 ret2, unsigned issue_flags, bool is_cqe32)
+static inline void __io_uring_cmd_done(struct io_uring_cmd *cmd,
+ unsigned issue_flags)
{
}
static inline void __io_uring_cmd_do_in_task(struct io_uring_cmd *ioucmd,
@@ -205,13 +225,15 @@ static inline void *io_uring_cmd_ctx_handle(struct io_uring_cmd *cmd)
static inline void io_uring_cmd_done(struct io_uring_cmd *ioucmd, s32 ret,
unsigned issue_flags)
{
- return __io_uring_cmd_done(ioucmd, ret, 0, issue_flags, false);
+ io_uring_cmd_set_res(ioucmd, ret);
+ __io_uring_cmd_done(ioucmd, issue_flags);
}
static inline void io_uring_cmd_done32(struct io_uring_cmd *ioucmd, s32 ret,
u64 res2, unsigned issue_flags)
{
- return __io_uring_cmd_done(ioucmd, ret, res2, issue_flags, true);
+ io_uring_cmd_set_res32(ioucmd, ret, res2);
+ __io_uring_cmd_done(ioucmd, issue_flags);
}
#endif /* _LINUX_IO_URING_CMD_H */
diff --git a/include/linux/io_uring_types.h b/include/linux/io_uring_types.h
index 39629ee77b91..2e5a786f2a2a 100644
--- a/include/linux/io_uring_types.h
+++ b/include/linux/io_uring_types.h
@@ -322,6 +322,8 @@ enum {
IO_RING_F_DRAIN_DISABLED = BIT(10),
IO_RING_F_COMPAT = BIT(11),
IO_RING_F_IOWQ_LIMITS_SET = BIT(12),
+ /* restrictions were inherited from the task that created the ring */
+ IO_RING_F_RESTRICT_INHERITED = BIT(13),
};
struct iou_ctx {};
@@ -517,11 +519,18 @@ struct io_ring_ctx {
u32 iowq_limits[2];
struct callback_head poll_wq_task_work;
+ /* deferred ->poll_wq wake up for local task_work */
+ struct rcu_head poll_wq_rcu;
+ atomic_t poll_wq_rcu_pending;
struct list_head defer_list;
unsigned nr_drained;
+ /* drain request dispatched from ->defer_list, until it completes */
+ struct io_kiocb *drain_req;
/* protected by ->completion_lock */
unsigned nr_req_allocated;
+ /* pending SEND_ZC notifications, protected by ->uring_lock */
+ unsigned nr_notifs;
#ifdef CONFIG_NET_RX_BUSY_POLL
struct list_head napi_list; /* track busy poll napi_id */
diff --git a/include/linux/iomap.h b/include/linux/iomap.h
index bc7ae6327dbf..59718f73c15a 100644
--- a/include/linux/iomap.h
+++ b/include/linux/iomap.h
@@ -483,13 +483,35 @@ sector_t iomap_bmap(struct address_space *mapping, sector_t bno,
#define IOMAP_IOEND_BOUNDARY (1U << 2)
/* is direct I/O */
#define IOMAP_IOEND_DIRECT (1U << 3)
+/* generate integrity (PI) information */
+#ifdef CONFIG_BLK_DEV_INTEGRITY
+#define IOMAP_IOEND_INTEGRITY (1U << 4)
+#else
+#define IOMAP_IOEND_INTEGRITY 0
+#endif /* CONFIG_BLK_DEV_INTEGRITY */
/*
* Flags that if set on either ioend prevent the merge of two ioends.
* (IOMAP_IOEND_BOUNDARY also prevents merges, but only one-way)
*/
#define IOMAP_IOEND_NOMERGE_FLAGS \
- (IOMAP_IOEND_SHARED | IOMAP_IOEND_UNWRITTEN | IOMAP_IOEND_DIRECT)
+ (IOMAP_IOEND_SHARED | IOMAP_IOEND_UNWRITTEN | IOMAP_IOEND_DIRECT | \
+ IOMAP_IOEND_INTEGRITY)
+
+/* ioend flags directly implied by iomap flags */
+static inline u16 iomap_ioend_flags(const struct iomap *iomap)
+{
+ unsigned int flags = 0;
+
+ if (iomap->type == IOMAP_UNWRITTEN)
+ flags |= IOMAP_IOEND_UNWRITTEN;
+ if (iomap->flags & IOMAP_F_SHARED)
+ flags |= IOMAP_IOEND_SHARED;
+ if (iomap->flags & IOMAP_F_INTEGRITY)
+ flags |= IOMAP_IOEND_INTEGRITY;
+
+ return flags;
+}
/*
* Structure for writeback I/O completions.
@@ -500,6 +522,7 @@ sector_t iomap_bmap(struct address_space *mapping, sector_t bno,
struct iomap_ioend {
struct list_head io_list; /* next ioend in chain */
u16 io_flags; /* IOMAP_IOEND_* */
+ u32 io_bvec_offset; /* offset into first bvec */
struct inode *io_inode; /* file being written to */
size_t io_size; /* size of the extent */
atomic_t io_remaining; /* completetion defer count */
@@ -517,6 +540,13 @@ static inline struct iomap_ioend *iomap_ioend_from_bio(struct bio *bio)
return container_of(bio, struct iomap_ioend, io_bio);
}
+#define BVEC_ITER_IOEND(_ioend) \
+{ \
+ .bi_sector = (_ioend)->io_sector, \
+ .bi_size = (_ioend)->io_size, \
+ .bi_offset = (_ioend)->io_bvec_offset, \
+}
+
struct iomap_writeback_ops {
/*
* Performs writeback on the passed in range
@@ -565,6 +595,7 @@ void iomap_finish_ioends(struct iomap_ioend *ioend, int error);
void iomap_ioend_try_merge(struct iomap_ioend *ioend,
struct list_head *more_ioends);
void iomap_sort_ioends(struct list_head *ioend_list);
+int iomap_ioend_integrity_verify(struct iomap_ioend *ioend);
ssize_t iomap_add_to_ioend(struct iomap_writepage_ctx *wpc, struct folio *folio,
loff_t pos, loff_t end_pos, unsigned int dirty_len);
int iomap_ioend_writeback_submit(struct iomap_writepage_ctx *wpc, int error);
@@ -577,6 +608,11 @@ void iomap_finish_folio_write(struct inode *inode, struct folio *folio,
int iomap_writeback_folio(struct iomap_writepage_ctx *wpc, struct folio *folio);
int iomap_writepages(struct iomap_writepage_ctx *wpc);
+void iomap_bounce_read(struct iomap_ioend *orig_ioend, unsigned int minsize,
+ void (*submit_ioend)(struct iomap_ioend *ioend));
+void iomap_bounce_read_end_io(struct iomap_ioend *ioend, struct bio *orig_bio,
+ int error);
+
struct iomap_read_folio_ctx {
const struct iomap_read_ops *ops;
struct folio *cur_folio;
diff --git a/include/linux/iommu-dma.h b/include/linux/iommu-dma.h
index 060f6e23ab3c..fae5d50e4f27 100644
--- a/include/linux/iommu-dma.h
+++ b/include/linux/iommu-dma.h
@@ -39,7 +39,7 @@ int iommu_dma_get_sgtable(struct device *dev, struct sg_table *sgt,
void *cpu_addr, dma_addr_t dma_addr, size_t size,
unsigned long attrs);
unsigned long iommu_dma_get_merge_boundary(struct device *dev);
-size_t iommu_dma_opt_mapping_size(void);
+size_t iommu_dma_max_opt_mapping_size(void);
size_t iommu_dma_max_mapping_size(struct device *dev);
void iommu_dma_free(struct device *dev, size_t size, void *cpu_addr,
dma_addr_t handle, unsigned long attrs);
diff --git a/include/linux/iommu.h b/include/linux/iommu.h
index ac43b8b93f14..ef5043752a36 100644
--- a/include/linux/iommu.h
+++ b/include/linux/iommu.h
@@ -773,8 +773,10 @@ struct iommu_ops {
* passes in the cache invalidation requests, in form
* of a driver data structure. The driver must update
* array->entry_num to report the number of handled
- * invalidation requests. The driver data structure
- * must be defined in include/uapi/linux/iommufd.h
+ * invalidation requests. A driver may handle fewer than
+ * the requested, in which case the core re-invokes the
+ * op for the remainder. The driver data structure must
+ * be defined in include/uapi/linux/iommufd.h
* @iova_to_phys: translate iova to physical address
* @enforce_cache_coherency: Prevent any kind of DMA from bypassing IOMMU_CACHE,
* including no-snoop TLPs on PCIe or other platform
@@ -898,7 +900,6 @@ int iommu_device_sysfs_add(struct iommu_device *iommu,
void iommu_device_sysfs_remove(struct iommu_device *iommu);
int iommu_device_link(struct iommu_device *iommu, struct device *link);
void iommu_device_unlink(struct iommu_device *iommu, struct device *link);
-int iommu_deferred_attach(struct device *dev, struct iommu_domain *domain);
static inline struct iommu_device *dev_to_iommu_device(struct device *dev)
{
@@ -943,7 +944,6 @@ extern void iommu_detach_device(struct iommu_domain *domain,
struct device *dev);
extern struct iommu_domain *iommu_get_domain_for_dev(struct device *dev);
struct iommu_domain *iommu_driver_get_domain_for_dev(struct device *dev);
-extern struct iommu_domain *iommu_get_dma_domain(struct device *dev);
extern int iommu_map(struct iommu_domain *domain, unsigned long iova,
phys_addr_t paddr, size_t size, int prot, gfp_t gfp);
int iommu_map_nosync(struct iommu_domain *domain, unsigned long iova,
diff --git a/include/linux/iommufd.h b/include/linux/iommufd.h
index 6e7efe83bc5d..3087f5b2def8 100644
--- a/include/linux/iommufd.h
+++ b/include/linux/iommufd.h
@@ -154,6 +154,8 @@ struct iommufd_hw_queue {
* The @array passes in the cache invalidation requests, in
* form of a driver data structure. A driver must update the
* array->entry_num to report the number of handled requests.
+ * A driver may handle fewer than the requested entry_num, in
+ * which case the core re-invokes the op for the remainder.
* The data structure of the array entry must be defined in
* include/uapi/linux/iommufd.h
* @vdevice_size: Size of the driver-defined vDEVICE structure per this vIOMMU
diff --git a/include/linux/irq-entry-common.h b/include/linux/irq-entry-common.h
index 0bb6c03481fa..d5a66f54d70b 100644
--- a/include/linux/irq-entry-common.h
+++ b/include/linux/irq-entry-common.h
@@ -346,22 +346,7 @@ typedef struct irqentry_state {
*
* Conditional reschedule with additional sanity checks.
*/
-void raw_irqentry_exit_cond_resched(void);
-
-#ifdef CONFIG_PREEMPT_DYNAMIC
-#if defined(CONFIG_HAVE_PREEMPT_DYNAMIC_CALL)
-#define irqentry_exit_cond_resched_dynamic_enabled raw_irqentry_exit_cond_resched
-#define irqentry_exit_cond_resched_dynamic_disabled NULL
-DECLARE_STATIC_CALL(irqentry_exit_cond_resched, raw_irqentry_exit_cond_resched);
-#define irqentry_exit_cond_resched() static_call(irqentry_exit_cond_resched)()
-#elif defined(CONFIG_HAVE_PREEMPT_DYNAMIC_KEY)
-DECLARE_STATIC_KEY_TRUE(sk_dynamic_irqentry_exit_cond_resched);
-void dynamic_irqentry_exit_cond_resched(void);
-#define irqentry_exit_cond_resched() dynamic_irqentry_exit_cond_resched()
-#endif
-#else /* CONFIG_PREEMPT_DYNAMIC */
-#define irqentry_exit_cond_resched() raw_irqentry_exit_cond_resched()
-#endif /* CONFIG_PREEMPT_DYNAMIC */
+void irqentry_exit_cond_resched(void);
/**
* irqentry_enter_from_kernel_mode - Establish state before invoking the irq handler
@@ -468,6 +453,25 @@ static inline void irqentry_exit_to_kernel_mode_preempt(struct pt_regs *regs,
irqentry_exit_cond_resched();
}
+/*
+ * The deferred hrtimer rearm is the tail of the timer interrupt, moved to the
+ * interrupt return path so that it runs after a possible reschedule. By now
+ * irq_exit_rcu() has left lockdep's hardirq context. Re-enter it for the
+ * rearm, so that the hrtimer base lock and the timekeeping sequence count are
+ * not chained onto the locks held by the interrupted context, which would add
+ * new lock chains for every lock stack an interrupt hits.
+ *
+ * The rearm on return to user mode needs no such annotation: no locks are
+ * held there, so it uses the same lock chains as the rearm in hardirq
+ * context.
+ */
+static __always_inline void irqentry_hrtimer_rearm_deferred(void)
+{
+ lockdep_hardirq_enter();
+ hrtimer_rearm_deferred();
+ lockdep_hardirq_exit();
+}
+
/**
* irqentry_exit_to_kernel_mode_after_preempt - Establish trace, lockdep and RCU state
* @regs: Pointer to current's pt_regs
@@ -491,7 +495,7 @@ irqentry_exit_to_kernel_mode_after_preempt(struct pt_regs *regs, irqentry_state_
*/
if (state.exit_rcu) {
instrumentation_begin();
- hrtimer_rearm_deferred();
+ irqentry_hrtimer_rearm_deferred();
/* Tell the tracer that IRET will enable interrupts */
trace_hardirqs_on_prepare();
lockdep_hardirqs_on_prepare();
@@ -502,7 +506,7 @@ irqentry_exit_to_kernel_mode_after_preempt(struct pt_regs *regs, irqentry_state_
}
instrumentation_begin();
- hrtimer_rearm_deferred();
+ irqentry_hrtimer_rearm_deferred();
/* Covers both tracing and lockdep */
trace_hardirqs_on();
instrumentation_end();
diff --git a/include/linux/irq_work.h b/include/linux/irq_work.h
index c5afd053ae32..7184e1273965 100644
--- a/include/linux/irq_work.h
+++ b/include/linux/irq_work.h
@@ -59,6 +59,7 @@ void irq_work_sync(struct irq_work *work);
#include <asm/irq_work.h>
void irq_work_run(void);
+void irq_work_run_cpu(unsigned int cpu);
bool irq_work_needs_cpu(void);
void irq_work_single(void *arg);
@@ -67,6 +68,7 @@ void arch_irq_work_raise(void);
#else
static inline bool irq_work_needs_cpu(void) { return false; }
static inline void irq_work_run(void) { }
+static inline void irq_work_run_cpu(unsigned int cpu) { }
static inline void irq_work_single(void *arg) { }
#endif
diff --git a/include/linux/irqchip/arm-gic-v5.h b/include/linux/irqchip/arm-gic-v5.h
index 2c2fb39f049c..299e75bc9525 100644
--- a/include/linux/irqchip/arm-gic-v5.h
+++ b/include/linux/irqchip/arm-gic-v5.h
@@ -63,20 +63,34 @@
#define GICV5_OUTER_SHARE 0b10
#define GICV5_INNER_SHARE 0b11
+#define GICV5_AIDR_COMPONENT_IRS 0b00
+#define GICV5_AIDR_COMPONENT_ITS 0b01
+#define GICV5_AIDR_COMPONENT_IWB 0b10
+
+#define GICV5_AIDR_ARCH_MAJ_REV_V5 0
+#define GICV5_AIDR_ARCH_MIN_REV_V0 0
+
/*
* IRS registers and tables structures
*/
#define GICV5_IRS_IDR0 0x0000
#define GICV5_IRS_IDR1 0x0004
#define GICV5_IRS_IDR2 0x0008
+#define GICV5_IRS_IDR3 0x000c
+#define GICV5_IRS_IDR4 0x0010
#define GICV5_IRS_IDR5 0x0014
#define GICV5_IRS_IDR6 0x0018
#define GICV5_IRS_IDR7 0x001c
+#define GICV5_IRS_IIDR 0x0040
+#define GICV5_IRS_AIDR 0x0044
#define GICV5_IRS_CR0 0x0080
#define GICV5_IRS_CR1 0x0084
#define GICV5_IRS_SYNCR 0x00c0
#define GICV5_IRS_SYNC_STATUSR 0x00c4
+#define GICV5_IRS_SPI_VMR 0x0100
#define GICV5_IRS_SPI_SELR 0x0108
+#define GICV5_IRS_SPI_DOMAINR 0x010c
+#define GICV5_IRS_SPI_RESAMPLER 0x0110
#define GICV5_IRS_SPI_CFGR 0x0114
#define GICV5_IRS_SPI_STATUSR 0x0118
#define GICV5_IRS_PE_SELR 0x0140
@@ -86,11 +100,51 @@
#define GICV5_IRS_IST_CFGR 0x0190
#define GICV5_IRS_IST_STATUSR 0x0194
#define GICV5_IRS_MAP_L2_ISTR 0x01c0
-
+#define GICV5_IRS_VMT_BASER 0x0200
+#define GICV5_IRS_VMT_CFGR 0x0210
+#define GICV5_IRS_VMT_STATUSR 0x0214
+#define GICV5_IRS_VPE_SELR 0x0240
+#define GICV5_IRS_VPE_DBR 0x0248
+#define GICV5_IRS_VPE_HPPIR 0x0250
+#define GICV5_IRS_VPE_CR0 0x0258
+#define GICV5_IRS_VPE_STATUSR 0x025c
+#define GICV5_IRS_VM_DBR 0x0280
+#define GICV5_IRS_VM_SELR 0x0288
+#define GICV5_IRS_VM_STATUSR 0x028c
+#define GICV5_IRS_VMAP_L2_VMTR 0x02c0
+#define GICV5_IRS_VMAP_VMR 0x02c8
+#define GICV5_IRS_VMAP_VISTR 0x02d0
+#define GICV5_IRS_VMAP_L2_VISTR 0x02d8
+#define GICV5_IRS_VMAP_VPER 0x02e0
+#define GICV5_IRS_SAVE_VMR 0x0300
+#define GICV5_IRS_SAVE_VM_STATUSR 0x0308
+#define GICV5_IRS_MEC_IDR 0x0340
+#define GICV5_IRS_MEC_MECID_R 0x0344
+#define GICV5_IRS_MPAM_IDR 0x0380
+#define GICV5_IRS_MPAM_PARTID_R 0x0384
+#define GICV5_IRS_SWERR_STATUSR 0x03c0
+#define GICV5_IRS_SWERR_SYNDROMER0 0x03c8
+#define GICV5_IRS_SWERR_SYNDROMER1 0x03d0
+
+#define GICV5_IRS_IDR0_IRSID GENMASK(31, 16)
+#define GICV5_IRS_IDR0_SWE BIT(12)
+#define GICV5_IRS_IDR0_MPAM BIT(11)
+#define GICV5_IRS_IDR0_MEC BIT(10)
+#define GICV5_IRS_IDR0_SETLPI BIT(9)
+#define GICV5_IRS_IDR0_VIRT_ONE_N BIT(8)
+#define GICV5_IRS_IDR0_ONE_N BIT(7)
#define GICV5_IRS_IDR0_VIRT BIT(6)
+#define GICV5_IRS_IDR0_PA_RANGE GENMASK(5, 2)
+#define GICV5_IRS_IDR0_INT_DOM GENMASK(1, 0)
+
+#define GICV5_IRS_IDR0_INT_DOM_SECURE 0b00
+#define GICV5_IRS_IDR0_INT_DOM_NON_SECURE 0b01
+#define GICV5_IRS_IDR0_INT_DOM_EL3 0b10
+#define GICV5_IRS_IDR0_INT_DOM_REALM 0b11
#define GICV5_IRS_IDR1_PRIORITY_BITS GENMASK(22, 20)
#define GICV5_IRS_IDR1_IAFFID_BITS GENMASK(19, 16)
+#define GICV5_IRS_IDR1_PE_CNT GENMASK(15, 0)
#define GICV5_IRS_IDR1_PRIORITY_BITS_1BITS 0b000
#define GICV5_IRS_IDR1_PRIORITY_BITS_2BITS 0b001
@@ -106,13 +160,30 @@
#define GICV5_IRS_IDR2_LPI BIT(5)
#define GICV5_IRS_IDR2_ID_BITS GENMASK(4, 0)
+#define GICV5_IRS_IST_L2SZ_SUPPORT_4KB(r) FIELD_GET(BIT(0), (r))
+#define GICV5_IRS_IST_L2SZ_SUPPORT_16KB(r) FIELD_GET(BIT(1), (r))
+#define GICV5_IRS_IST_L2SZ_SUPPORT_64KB(r) FIELD_GET(BIT(2), (r))
+
+#define GICV5_IRS_IDR3_VMT_LEVELS BIT(10)
+#define GICV5_IRS_IDR3_VM_ID_BITS GENMASK(9, 5)
+#define GICV5_IRS_IDR3_VMD_SZ GENMASK(4, 1)
+#define GICV5_IRS_IDR3_VMD BIT(0)
+
+#define GICV5_IRS_IDR4_VPE_ID_BITS GENMASK(9, 6)
+#define GICV5_IRS_IDR4_VPED_SZ GENMASK(5, 0)
+
#define GICV5_IRS_IDR5_SPI_RANGE GENMASK(24, 0)
#define GICV5_IRS_IDR6_SPI_IRS_RANGE GENMASK(24, 0)
#define GICV5_IRS_IDR7_SPI_BASE GENMASK(23, 0)
-#define GICV5_IRS_IST_L2SZ_SUPPORT_4KB(r) FIELD_GET(BIT(11), (r))
-#define GICV5_IRS_IST_L2SZ_SUPPORT_16KB(r) FIELD_GET(BIT(12), (r))
-#define GICV5_IRS_IST_L2SZ_SUPPORT_64KB(r) FIELD_GET(BIT(13), (r))
+#define GICV5_IRS_IIDR_PRODUCT_ID GENMASK(31, 20)
+#define GICV5_IRS_IIDR_VARIANT GENMASK(19, 16)
+#define GICV5_IRS_IIDR_REVISION GENMASK(15, 12)
+#define GICV5_IRS_IIDR_IMPLEMENTER GENMASK(11, 0)
+
+#define GICV5_IRS_AIDR_COMPONENT GENMASK(11, 8)
+#define GICV5_IRS_AIDR_ARCHMAJORREV GENMASK(7, 4)
+#define GICV5_IRS_AIDR_ARCHMINORREV GENMASK(3, 0)
#define GICV5_IRS_CR0_IDLE BIT(1)
#define GICV5_IRS_CR0_IRSEN BIT(0)
@@ -135,21 +206,39 @@
#define GICV5_IRS_SYNC_STATUSR_IDLE BIT(0)
-#define GICV5_IRS_SPI_STATUSR_V BIT(1)
-#define GICV5_IRS_SPI_STATUSR_IDLE BIT(0)
+#define GICV5_IRS_SPI_VMR_VIRT BIT_ULL(63)
+#define GICV5_IRS_SPI_VMR_VM_ID GENMASK_ULL(15, 0)
#define GICV5_IRS_SPI_SELR_ID GENMASK(23, 0)
+#define GICV5_IRS_SPI_DOMAINR_DOMAIN GENMASK(1, 0)
+
+#define GICV5_IRS_SPI_DOMAINR_DOMAIN_SECURE 0b00
+#define GICV5_IRS_SPI_DOMAINR_DOMAIN_NON_SECURE 0b01
+#define GICV5_IRS_SPI_DOMAINR_DOMAIN_EL3 0b10
+#define GICV5_IRS_SPI_DOMAINR_DOMAIN_REALM 0b11
+
+#define GICV5_IRS_SPI_RESAMPLER_ID GENMASK(23, 0)
+
#define GICV5_IRS_SPI_CFGR_TM BIT(0)
+#define GICV5_IRS_SPI_CFGR_TM_EDGE 0b0
+#define GICV5_IRS_SPI_CFGR_TM_LEVEL 0b1
+
+#define GICV5_IRS_SPI_STATUSR_V BIT(1)
+#define GICV5_IRS_SPI_STATUSR_IDLE BIT(0)
+
#define GICV5_IRS_PE_SELR_IAFFID GENMASK(15, 0)
+#define GICV5_IRS_PE_STATUSR_ONLINE BIT(2)
#define GICV5_IRS_PE_STATUSR_V BIT(1)
#define GICV5_IRS_PE_STATUSR_IDLE BIT(0)
#define GICV5_IRS_PE_CR0_DPS BIT(0)
-#define GICV5_IRS_IST_STATUSR_IDLE BIT(0)
+#define GICV5_IRS_IST_BASER_ADDR_MASK GENMASK_ULL(55, 6)
+#define GICV5_IRS_IST_BASER_VALID BIT_ULL(0)
+#define GICV5_IRS_IST_BASER_ADDR_SHIFT 6ULL
#define GICV5_IRS_IST_CFGR_STRUCTURE BIT(16)
#define GICV5_IRS_IST_CFGR_ISTSZ GENMASK(8, 7)
@@ -167,15 +256,111 @@
#define GICV5_IRS_IST_CFGR_L2SZ_16K 0b01
#define GICV5_IRS_IST_CFGR_L2SZ_64K 0b10
-#define GICV5_IRS_IST_BASER_ADDR_MASK GENMASK_ULL(55, 6)
-#define GICV5_IRS_IST_BASER_VALID BIT_ULL(0)
+#define GICV5_IRS_IST_STATUSR_IDLE BIT(0)
#define GICV5_IRS_MAP_L2_ISTR_ID GENMASK(23, 0)
+#define GICV5_IRS_VMT_BASER_ADDR GENMASK_ULL(55, 3)
+#define GICV5_IRS_VMT_BASER_ADDR_SHIFT 3ULL
+#define GICV5_IRS_VMT_BASER_VALID BIT_ULL(0)
+
+#define GICV5_IRS_VMT_CFGR_STRUCTURE_TWO_LEVEL 0b1
+#define GICV5_IRS_VMT_CFGR_STRUCTURE_LINEAR 0b0
+
+#define GICV5_IRS_VMT_CFGR_STRUCTURE BIT(16)
+#define GICV5_IRS_VMT_CFGR_VM_ID_BITS GENMASK(4, 0)
+
+#define GICV5_IRS_VMT_STATUSR_IDLE BIT(0)
+
+#define GICV5_IRS_VPE_SELR_S BIT_ULL(63)
+#define GICV5_IRS_VPE_SELR_VPE_ID GENMASK_ULL(47, 32)
+#define GICV5_IRS_VPE_SELR_VM_ID GENMASK_ULL(15, 0)
+
+#define GICV5_IRS_VPE_DBR_DBV BIT_ULL(63)
+#define GICV5_IRS_VPE_DBR_REQ_DB BIT_ULL(62)
+#define GICV5_IRS_VPE_DBR_DBPM GENMASK_ULL(36, 32)
+#define GICV5_IRS_VPE_DBR_INTID GENMASK_ULL(23, 0)
+
+#define GICV5_IRS_VPE_HPPIR_HPPIV BIT_ULL(32)
+#define GICV5_IRS_VPE_HPPIR_TYPE GENMASK_ULL(31, 29)
+#define GICV5_IRS_VPE_HPPIR_ID GENMASK_ULL(23, 0)
+
+#define GICV5_IRS_VPE_CR0_DPS BIT(0)
+
+#define GICV5_IRS_VPE_STATUSR_V BIT(1)
+#define GICV5_IRS_VPE_STATUSR_IDLE BIT(0)
+
+#define GICV5_IRS_VM_DBR_EN BIT_ULL(63)
+#define GICV5_IRS_VM_DBR_VPE_ID GENMASK_ULL(15, 0)
+
+#define GICV5_IRS_VM_SELR_VM_ID GENMASK(15, 0)
+
+#define GICV5_IRS_VM_STATUSR_V BIT(1)
+#define GICV5_IRS_VM_STATUSR_IDLE BIT(0)
+
+#define GICV5_IRS_VMAP_L2_VMTR_M BIT_ULL(63)
+#define GICV5_IRS_VMAP_L2_VMTR_VM_ID GENMASK_ULL(15, 0)
+
+#define GICV5_IRS_VMAP_VMR_M BIT_ULL(63)
+#define GICV5_IRS_VMAP_VMR_U BIT_ULL(62)
+#define GICV5_IRS_VMAP_VMR_VM_ID GENMASK_ULL(15, 0)
+
+#define GICV5_IRS_VMAP_VISTR_M BIT_ULL(63)
+#define GICV5_IRS_VMAP_VISTR_U BIT_ULL(62)
+#define GICV5_IRS_VMAP_VISTR_VM_ID GENMASK_ULL(47, 32)
+#define GICV5_IRS_VMAP_VISTR_TYPE GENMASK_ULL(31, 29)
+
+#define GICV5_IRS_VMAP_L2_VISTR_M BIT_ULL(63)
+#define GICV5_IRS_VMAP_L2_VISTR_VM_ID GENMASK_ULL(47, 32)
+#define GICV5_IRS_VMAP_L2_VISTR_TYPE GENMASK_ULL(31, 29)
+#define GICV5_IRS_VMAP_L2_VISTR_ID GENMASK_ULL(23, 0)
+
+#define GICV5_IRS_VMAP_VPER_M BIT_ULL(63)
+#define GICV5_IRS_VMAP_VPER_VM_ID GENMASK_ULL(47, 32)
+#define GICV5_IRS_VMAP_VPER_VPE_ID GENMASK_ULL(15, 0)
+
+#define GICV5_IRS_SAVE_VMR_VM_ID GENMASK_ULL(15, 0)
+#define GICV5_IRS_SAVE_VMR_Q BIT_ULL(62)
+#define GICV5_IRS_SAVE_VMR_S BIT_ULL(63)
+
+#define GICV5_IRS_SAVE_VM_STATUSR_IDLE BIT(0)
+#define GICV5_IRS_SAVE_VM_STATUSR_Q BIT(1)
+
+#define GICV5_IRS_MEC_IDR_MECIDSIZE GENMASK(3, 0)
+
+#define GICV5_IRS_MEC_MECID_R_MECID GENMASK(15, 0)
+
+#define GICV5_IRS_MPAM_IDR_HAS_MPAM_SP BIT(24)
+#define GICV5_IRS_MPAM_IDR_PMG_MAX GENMASK(23, 16)
+#define GICV5_IRS_MPAM_IDR_PARTID_MAX GENMASK(15, 0)
+
+#define GICV5_IRS_MPAM_PARTID_R_IDLE BIT(31)
+#define GICV5_IRS_MPAM_PARTID_R_MPAM_SP GENMASK(25, 24)
+#define GICV5_IRS_MPAM_PARTID_R_PMG GENMASK(23, 16)
+#define GICV5_IRS_MPAM_PARTID_R_PARTID GENMASK(15, 0)
+
+#define GICV5_IRS_SWERR_STATUSR_IMP_EC GENMASK_ULL(31, 24)
+#define GICV5_IRS_SWERR_STATUSR_EC GENMASK_ULL(23, 16)
+#define GICV5_IRS_SWERR_STATUSR_OF BIT_ULL(3)
+#define GICV5_IRS_SWERR_STATUSR_S1V BIT_ULL(2)
+#define GICV5_IRS_SWERR_STATUSR_S0V BIT_ULL(1)
+#define GICV5_IRS_SWERR_STATUSR_V BIT_ULL(0)
+
+#define GICV5_IRS_SWERR_SYNDROMER0_VIRTUAL BIT_ULL(63)
+#define GICV5_IRS_SWERR_SYNDROMER0_TYPE GENMASK_ULL(62, 60)
+#define GICV5_IRS_SWERR_SYNDROMER0_ID GENMASK_ULL(55, 32)
+#define GICV5_IRS_SWERR_SYNDROMER0_VM_ID GENMASK_ULL(15, 0)
+
+#define GICV5_IRS_SWERR_SYNDROMER1_ADDR GENMASK_ULL(55, 3)
+
#define GICV5_ISTL1E_VALID BIT_ULL(0)
+#define GICV5_IRS_ISTL1E_SIZE 8UL
#define GICV5_ISTL1E_L2_ADDR_MASK GENMASK_ULL(55, 12)
+#define GICV5_IRS_SETLPIR 0x0000
+#define GICV5_IRS_SETLPIR_ID GENMASK(23, 0)
+
/*
* ITS registers and tables structures
*/
@@ -298,6 +483,42 @@
#define GICV5_GSI_IWB_WIRE GENMASK(15, 0)
/*
+ * CoreSight identification registers - ordered by increasing offset.
+ */
+#define GICV5_CORESIGHT_DEVARCH 0xffbc
+#define GICV5_CORESIGHT_PIDR4 0xffd0
+#define GICV5_CORESIGHT_PIDR5 0xffd4
+#define GICV5_CORESIGHT_PIDR6 0xffd8
+#define GICV5_CORESIGHT_PIDR7 0xffdc
+#define GICV5_CORESIGHT_PIDR0 0xffe0
+#define GICV5_CORESIGHT_PIDR1 0xffe4
+#define GICV5_CORESIGHT_PIDR2 0xffe8
+#define GICV5_CORESIGHT_PIDR3 0xffec
+#define GICV5_CORESIGHT_CIDR0 0xfff0
+#define GICV5_CORESIGHT_CIDR1 0xfff4
+#define GICV5_CORESIGHT_CIDR2 0xfff8
+#define GICV5_CORESIGHT_CIDR3 0xfffc
+
+#define GICV5_CORESIGHT_DEVARCH_VAL \
+ (FIELD_PREP(GENMASK(31, 21), 0x23b) | \
+ BIT(20) | \
+ 0x5a19)
+
+#define GICV5_CORESIGHT_PIDR4_JEP106_CONT 0x04
+#define GICV5_CORESIGHT_PIDR5_RES0 0x00
+#define GICV5_CORESIGHT_PIDR6_RES0 0x00
+#define GICV5_CORESIGHT_PIDR7_RES0 0x00
+#define GICV5_CORESIGHT_PIDR0_PART_0 0x4b
+#define GICV5_CORESIGHT_PIDR1_DES_0_PART_1 0xb0
+#define GICV5_CORESIGHT_PIDR2_DES_1 0x0b
+#define GICV5_CORESIGHT_PIDR3_REVAND_CMOD 0x00
+
+#define GICV5_CORESIGHT_CIDR0_VAL 0x0d
+#define GICV5_CORESIGHT_CIDR1_VAL 0xf0
+#define GICV5_CORESIGHT_CIDR2_VAL 0x05
+#define GICV5_CORESIGHT_CIDR3_VAL 0xb1
+
+/*
* Global Data structures and functions
*/
struct gicv5_chip_data {
@@ -332,6 +553,8 @@ struct gicv5_irs_chip_data {
raw_spinlock_t spi_config_lock;
};
+#define IRS_FLAGS_NON_COHERENT BIT(0)
+
static inline int gicv5_wait_for_op_s_atomic(void __iomem *addr, u32 offset,
const char *reg_s, u32 mask,
u32 *val)
@@ -379,6 +602,7 @@ void __init gicv5_free_lpi_domain(void);
int gicv5_irs_of_probe(struct device_node *parent);
int gicv5_irs_acpi_probe(void);
+struct gicv5_irs_chip_data *gicv5_irs_get_chip_data(void);
void gicv5_irs_remove(void);
int gicv5_irs_enable(void);
void gicv5_irs_its_probe(void);
@@ -387,10 +611,13 @@ int gicv5_irs_cpu_to_iaffid(int cpu_id, u16 *iaffid);
struct gicv5_irs_chip_data *gicv5_irs_lookup_by_spi_id(u32 spi_id);
int gicv5_spi_irq_set_type(struct irq_data *d, unsigned int type);
int gicv5_irs_iste_alloc(u32 lpi);
+unsigned int gicv5_irs_l2_sz(u32 l2sz);
void gicv5_irs_syncr(void);
/* Embedded in kvm.arch */
struct gicv5_vpe {
+ int db;
+ bool db_fired;
bool resident;
};
@@ -429,4 +656,15 @@ void gicv5_deinit_lpis(void);
void __init gicv5_its_of_probe(struct device_node *parent);
void __init gicv5_its_acpi_probe(void);
+
+enum gicv5_vcpu_cmd {
+ VMT_L2_MAP, /* Map in a L2 VMT - *may* happen on VM init */
+ VMTE_MAKE_VALID, /* Make the VMTE valid */
+ VMTE_MAKE_INVALID, /* Make the VMTE (et al.) invalid */
+ VPE_MAKE_VALID, /* No corresponding invalid */
+ SPI_VIST_MAKE_VALID, /* No corresponding invalid */
+ LPI_VIST_MAKE_VALID, /* Triggered by a guest */
+ LPI_VIST_MAKE_INVALID, /* Triggered by a guest */
+};
+
#endif
diff --git a/include/linux/irqchip/arm-vgic-info.h b/include/linux/irqchip/arm-vgic-info.h
index 67d9d960273b..f05370e2debf 100644
--- a/include/linux/irqchip/arm-vgic-info.h
+++ b/include/linux/irqchip/arm-vgic-info.h
@@ -38,6 +38,11 @@ struct gic_kvm_info {
bool has_v4_1;
/* Deactivation impared, subpar stuff */
bool no_hw_deactivation;
+ /* GICv5 IRS base */
+ struct {
+ void __iomem *base;
+ bool non_coherent;
+ } gicv5_irs;
};
#ifdef CONFIG_KVM
diff --git a/include/linux/irqchip/riscv-imsic.h b/include/linux/irqchip/riscv-imsic.h
index 61af3a5bea09..b7be1aad7774 100644
--- a/include/linux/irqchip/riscv-imsic.h
+++ b/include/linux/irqchip/riscv-imsic.h
@@ -46,6 +46,9 @@ struct imsic_local_config {
};
struct imsic_global_config {
+ /* Device details */
+ struct fwnode_handle *fwnode;
+
/*
* MSI Target Address Scheme
*
diff --git a/include/linux/kernel-page-flags.h b/include/linux/kernel-page-flags.h
index 196778a087c4..fe5ab6e50bd7 100644
--- a/include/linux/kernel-page-flags.h
+++ b/include/linux/kernel-page-flags.h
@@ -11,7 +11,6 @@
#define KPF_RESERVED 32
#define KPF_MLOCKED 33
#define KPF_OWNER_2 34
-#define KPF_PRIVATE 35
#define KPF_PRIVATE_2 36
#define KPF_OWNER_PRIVATE 37
#define KPF_ARCH 38
diff --git a/include/linux/kernel.h b/include/linux/kernel.h
index 24414c79e59a..4b11d1dc0a67 100644
--- a/include/linux/kernel.h
+++ b/include/linux/kernel.h
@@ -43,30 +43,10 @@ struct completion;
struct user;
#ifdef CONFIG_PREEMPT_VOLUNTARY_BUILD
-
extern int __cond_resched(void);
# define might_resched() __cond_resched()
-
-#elif defined(CONFIG_PREEMPT_DYNAMIC) && defined(CONFIG_HAVE_PREEMPT_DYNAMIC_CALL)
-
-extern int __cond_resched(void);
-
-DECLARE_STATIC_CALL(might_resched, __cond_resched);
-
-static __always_inline void might_resched(void)
-{
- static_call_mod(might_resched)();
-}
-
-#elif defined(CONFIG_PREEMPT_DYNAMIC) && defined(CONFIG_HAVE_PREEMPT_DYNAMIC_KEY)
-
-extern int dynamic_might_resched(void);
-# define might_resched() dynamic_might_resched()
-
#else
-
# define might_resched() do { } while (0)
-
#endif /* CONFIG_PREEMPT_* */
#ifdef CONFIG_DEBUG_ATOMIC_SLEEP
diff --git a/include/linux/kernel_stat.h b/include/linux/kernel_stat.h
index 9ca6c2259dfe..9f0f91dc8d7d 100644
--- a/include/linux/kernel_stat.h
+++ b/include/linux/kernel_stat.h
@@ -40,6 +40,9 @@ struct kernel_cpustat {
seqcount_t idle_sleeptime_seq;
u64 idle_entrytime;
u64 idle_stealtime[2];
+ u64 idle_dyntick_entry;
+ u64 idle_tick_period;
+ u64 idle_tick_overlap;
#endif
u64 cpustat[NR_STATS];
};
@@ -111,7 +114,7 @@ static inline unsigned long kstat_cpu_irqs_sum(unsigned int cpu)
#ifdef CONFIG_HAVE_VIRT_CPU_ACCOUNTING_IDLE
static inline void kcpustat_dyntick_start(u64 now) { }
-static inline void kcpustat_dyntick_stop(u64 now) { }
+static inline void kcpustat_dyntick_stop(u64 now, u64 tick_start) { }
static inline void kcpustat_irq_enter(u64 now) { }
static inline void kcpustat_irq_exit(u64 now) { }
static inline bool kcpustat_idle_dyntick(void) { return false; }
@@ -132,7 +135,7 @@ static inline u64 kcpustat_field_iowait(int cpu)
#else /* !CONFIG_HAVE_VIRT_CPU_ACCOUNTING_IDLE */
extern void kcpustat_dyntick_start(u64 now);
-extern void kcpustat_dyntick_stop(u64 now);
+extern void kcpustat_dyntick_stop(u64 now, u64 tick_start);
extern void kcpustat_irq_enter(u64 now);
extern void kcpustat_irq_exit(u64 now);
extern u64 kcpustat_field_idle(int cpu);
@@ -196,6 +199,17 @@ static inline void kcpustat_cpu_fetch(struct kernel_cpustat *dst, int cpu)
}
#endif /* !CONFIG_VIRT_CPU_ACCOUNTING_GEN */
+static inline u64 kcpustat_field_total(enum cpu_usage_stat usage, const struct cpumask *cpus)
+{
+ u64 total = 0;
+ int cpu;
+
+ for_each_cpu(cpu, cpus)
+ total += kcpustat_field(usage, cpu);
+
+ return total;
+}
+
extern void account_user_time(struct task_struct *, u64);
extern void account_guest_time(struct task_struct *, u64);
extern void account_system_time(struct task_struct *, int, u64);
diff --git a/include/linux/kernfs.h b/include/linux/kernfs.h
index 351a5101c862..73786b567ccd 100644
--- a/include/linux/kernfs.h
+++ b/include/linux/kernfs.h
@@ -309,7 +309,7 @@ struct kernfs_ops {
* write() is bounced through kernel buffer. If atomic_write_len
* is not set, a write larger than PAGE_SIZE results in partial
* operations of PAGE_SIZE chunks. If atomic_write_len is set,
- * writes upto the specified size are executed atomically but
+ * writes up to the specified size are executed atomically but
* larger ones are rejected with -E2BIG.
*/
size_t atomic_write_len;
diff --git a/include/linux/key-type.h b/include/linux/key-type.h
index bb97bd3e5af4..c4f329b6ae3f 100644
--- a/include/linux/key-type.h
+++ b/include/linux/key-type.h
@@ -161,6 +161,7 @@ struct key_type {
const void *in, const void *in2);
/* internal fields */
+ atomic64_t index_id; /* Opaque keyring index ID */
struct list_head link; /* link in types list */
struct lock_class_key lock_class; /* key->sem lock class */
} __randomize_layout;
diff --git a/include/linux/key.h b/include/linux/key.h
index 81b8f05c6898..dae5ba255ad1 100644
--- a/include/linux/key.h
+++ b/include/linux/key.h
@@ -107,6 +107,7 @@ struct keyring_name;
struct key_tag {
struct rcu_head rcu;
+ atomic64_t index_id; /* Opaque keyring index ID */
refcount_t usage;
bool removed; /* T when subject removed */
};
@@ -129,6 +130,8 @@ struct keyring_index_key {
struct key_type *type;
struct key_tag *domain_tag; /* Domain of operation */
const char *description;
+ u64 type_id; /* Cached index IDs */
+ u64 domain_id;
};
union key_payload {
@@ -251,6 +254,8 @@ struct key {
struct key_type *type; /* type of key */
struct key_tag *domain_tag; /* Domain of operation */
char *description;
+ u64 type_id;
+ u64 domain_id;
};
};
@@ -440,6 +445,8 @@ extern key_ref_t keyring_search(key_ref_t keyring,
extern int keyring_restrict(key_ref_t keyring, const char *type,
const char *restriction);
+extern void key_register_bpf_keyring(struct key *keyring);
+
extern struct key *key_lookup(key_serial_t id);
static inline key_serial_t key_serial(const struct key *key)
diff --git a/include/linux/kmod.h b/include/linux/kmod.h
index 9a07c3215389..b9474a62a568 100644
--- a/include/linux/kmod.h
+++ b/include/linux/kmod.h
@@ -2,17 +2,9 @@
#ifndef __LINUX_KMOD_H__
#define __LINUX_KMOD_H__
-/*
- * include/linux/kmod.h
- */
-
-#include <linux/umh.h>
-#include <linux/gfp.h>
-#include <linux/stddef.h>
+#include <linux/compiler_attributes.h>
#include <linux/errno.h>
-#include <linux/compiler.h>
-#include <linux/workqueue.h>
-#include <linux/sysctl.h>
+#include <linux/types.h>
#ifdef CONFIG_MODULES
/* modprobe exit status on success, -ve on error. Return value
diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h
index 03bfc92864b6..e7fc94e2910a 100644
--- a/include/linux/kvm_host.h
+++ b/include/linux/kvm_host.h
@@ -45,6 +45,10 @@
#include <asm/kvm_host.h>
#include <linux/kvm_dirty_ring.h>
+#define __KVM_DEV_STRING(name, x) __stringify(name ## _ ## x)
+#define _KVM_DEV_STRING(name, x) __KVM_DEV_STRING(name, x)
+#define KVM_DEV_STRING(x) _KVM_DEV_STRING(KVM_DEV_NAME, x)
+
#ifndef KVM_MAX_VCPU_IDS
#define KVM_MAX_VCPU_IDS KVM_MAX_VCPUS
#endif
@@ -562,7 +566,7 @@ static inline int kvm_vcpu_exiting_guest_mode(struct kvm_vcpu *vcpu)
/*
* The memory barrier ensures a previous write to vcpu->requests cannot
* be reordered with the read of vcpu->mode. It pairs with the general
- * memory barrier following the write of vcpu->mode in VCPU RUN.
+ * memory barrier following the write of vcpu->mode in KVM_RUN.
*/
smp_mb__before_atomic();
return cmpxchg(&vcpu->mode, IN_GUEST_MODE, EXITING_GUEST_MODE);
@@ -722,31 +726,14 @@ static inline int kvm_arch_vcpu_memslots_id(struct kvm_vcpu *vcpu)
}
#endif
-#ifndef CONFIG_KVM_GENERIC_MEMORY_ATTRIBUTES
-static inline bool kvm_arch_has_private_mem(struct kvm *kvm)
-{
- return false;
-}
-#endif
-
-#ifdef CONFIG_KVM_GUEST_MEMFD
-bool kvm_arch_supports_gmem_init_shared(struct kvm *kvm);
-
-static inline u64 kvm_gmem_get_supported_flags(struct kvm *kvm)
-{
- u64 flags = GUEST_MEMFD_FLAG_MMAP;
-
- if (!kvm || kvm_arch_supports_gmem_init_shared(kvm))
- flags |= GUEST_MEMFD_FLAG_INIT_SHARED;
-
- return flags;
-}
-#endif
-
#ifndef kvm_arch_has_readonly_mem
static inline bool kvm_arch_has_readonly_mem(struct kvm *kvm)
{
- return IS_ENABLED(CONFIG_HAVE_KVM_READONLY_MEM);
+#ifdef __KVM_HAVE_READONLY_MEM
+ return true;
+#else
+ return false;
+#endif
}
#endif
@@ -784,6 +771,12 @@ struct kvm {
* kvm_swap_active_memslots().
*/
struct mutex slots_arch_lock;
+ /*
+ * Back-reference to the VM file for subsystems (e.g., VFIO). Holds no
+ * reference to avoid pinning the VM. Callers storing the file must
+ * take their own reference.
+ */
+ struct file *file;
struct mm_struct *mm; /* userspace tied to this vm */
unsigned long nr_memslot_pages;
/* The two memslot sets - active and inactive (per address space) */
@@ -791,7 +784,6 @@ struct kvm {
/* The current active memslot set for each address space */
struct kvm_memslots __rcu *memslots[KVM_MAX_NR_ADDRESS_SPACES];
struct xarray vcpu_array;
- DECLARE_BITMAP(vcpu_ids, KVM_MAX_VCPU_IDS);
/*
* Protected by slots_lock, but can be read outside if an
* incorrect answer is acceptable.
@@ -833,7 +825,7 @@ struct kvm {
struct kvm_vm_stat stat;
struct kvm_arch arch;
refcount_t users_count;
-#ifdef CONFIG_KVM_MMIO
+#ifndef __KVM_NO_MMIO
struct kvm_coalesced_mmio_ring *coalesced_mmio_ring;
spinlock_t ring_lock;
struct list_head coalesced_zones;
@@ -855,6 +847,8 @@ struct kvm {
gfn_t mmu_invalidate_range_start;
gfn_t mmu_invalidate_range_end;
+ unsigned long gpc_invalidate_seq;
+
struct list_head devices;
u64 manual_dirty_log_protect;
struct dentry *debugfs_dentry;
@@ -872,7 +866,7 @@ struct kvm {
#ifdef CONFIG_HAVE_KVM_PM_NOTIFIER
struct notifier_block pm_notifier;
#endif
-#ifdef CONFIG_KVM_GENERIC_MEMORY_ATTRIBUTES
+#ifdef CONFIG_KVM_VM_MEMORY_ATTRIBUTES
/* Protected by slots_lock (for writes) and RCU (for reads) */
struct xarray mem_attr_array;
#endif
@@ -1081,7 +1075,18 @@ void kvm_exit(void);
void kvm_get_kvm(struct kvm *kvm);
bool kvm_get_kvm_safe(struct kvm *kvm);
void kvm_put_kvm(struct kvm *kvm);
-bool file_is_kvm(struct file *file);
+
+/*
+ * Architectures define kvm_file_to_kvm_arch to <arch>
+ * to get a typed, arch-namespaced helper:
+ *
+ * struct kvm *file_to_kvm_<arch>(struct file *file)
+ */
+#ifdef kvm_file_to_kvm_arch
+#define kvm_file_to_kvm_fn CONCATENATE(file_to_kvm_, kvm_file_to_kvm_arch)
+struct kvm *kvm_file_to_kvm_fn(struct file *file);
+#endif /* kvm_file_to_kvm_arch */
+
void kvm_put_kvm_no_destroy(struct kvm *kvm);
static inline struct kvm_memslots *__kvm_memslots(struct kvm *kvm, int as_id)
@@ -2324,13 +2329,18 @@ static inline bool kvm_test_request(int req, struct kvm_vcpu *vcpu)
return test_bit(req & KVM_REQUEST_MASK, (void *)&vcpu->requests);
}
-static inline void kvm_clear_request(int req, struct kvm_vcpu *vcpu)
+static __always_inline void kvm_clear_request(int req, struct kvm_vcpu *vcpu)
{
+ BUILD_BUG_ON(req == KVM_REQ_VM_DEAD);
+
clear_bit(req & KVM_REQUEST_MASK, (void *)&vcpu->requests);
}
-static inline bool kvm_check_request(int req, struct kvm_vcpu *vcpu)
+static __always_inline bool kvm_check_request(int req, struct kvm_vcpu *vcpu)
{
+ /* Once a VM is dead, it needs to stay dead. */
+ BUILD_BUG_ON(req == KVM_REQ_VM_DEAD);
+
if (kvm_test_request(req, vcpu)) {
kvm_clear_request(req, vcpu);
@@ -2460,7 +2470,7 @@ void kvm_arch_update_irqfd_routing(struct kvm_kernel_irqfd *irqfd,
struct kvm_kernel_irq_routing_entry *new);
#endif /* CONFIG_HAVE_KVM_IRQ_BYPASS */
-#ifdef CONFIG_HAVE_KVM_INVALID_WAKEUPS
+#ifdef __KVM_HAVE_INVALID_WAKEUPS
/* If we wakeup during the poll time, was it a sucessful poll? */
static inline bool vcpu_valid_wakeup(struct kvm_vcpu *vcpu)
{
@@ -2472,9 +2482,9 @@ static inline bool vcpu_valid_wakeup(struct kvm_vcpu *vcpu)
{
return true;
}
-#endif /* CONFIG_HAVE_KVM_INVALID_WAKEUPS */
+#endif /* __KVM_HAVE_INVALID_WAKEUPS */
-#ifdef CONFIG_HAVE_KVM_NO_POLL
+#ifdef __KVM_HAVE_NO_POLL
/* Callback that tells if we must not poll */
bool kvm_arch_no_poll(struct kvm_vcpu *vcpu);
#else
@@ -2482,18 +2492,18 @@ static inline bool kvm_arch_no_poll(struct kvm_vcpu *vcpu)
{
return false;
}
-#endif /* CONFIG_HAVE_KVM_NO_POLL */
+#endif /* __KVM_HAVE_NO_POLL */
void kvm_arch_guest_memory_reclaimed(struct kvm *kvm);
-#ifdef CONFIG_HAVE_KVM_VCPU_RUN_PID_CHANGE
+#ifdef __KVM_HAVE_VCPU_RUN_PID_CHANGE
int kvm_arch_vcpu_run_pid_change(struct kvm_vcpu *vcpu);
#else
static inline int kvm_arch_vcpu_run_pid_change(struct kvm_vcpu *vcpu)
{
return 0;
}
-#endif /* CONFIG_HAVE_KVM_VCPU_RUN_PID_CHANGE */
+#endif /* __KVM_HAVE_VCPU_RUN_PID_CHANGE */
#ifdef CONFIG_VIRT_XFER_TO_GUEST_WORK
static inline void kvm_handle_signal_exit(struct kvm_vcpu *vcpu)
@@ -2560,48 +2570,79 @@ static inline bool kvm_memslot_is_gmem_only(const struct kvm_memory_slot *slot)
return slot->flags & KVM_MEMSLOT_GMEM_ONLY;
}
-#ifdef CONFIG_KVM_GENERIC_MEMORY_ATTRIBUTES
-static inline unsigned long kvm_get_memory_attributes(struct kvm *kvm, gfn_t gfn)
+#ifdef CONFIG_KVM_VM_MEMORY_ATTRIBUTES
+static inline unsigned long kvm_get_vm_memory_attributes(struct kvm *kvm, gfn_t gfn)
{
return xa_to_value(xa_load(&kvm->mem_attr_array, gfn));
}
-bool kvm_range_has_memory_attributes(struct kvm *kvm, gfn_t start, gfn_t end,
- unsigned long mask, unsigned long attrs);
-bool kvm_arch_pre_set_memory_attributes(struct kvm *kvm,
- struct kvm_gfn_range *range);
-bool kvm_arch_post_set_memory_attributes(struct kvm *kvm,
- struct kvm_gfn_range *range);
+bool kvm_range_has_vm_memory_attributes(struct kvm *kvm, gfn_t start, gfn_t end,
+ unsigned long mask, unsigned long attrs);
+bool kvm_arch_pre_set_vm_memory_attributes(struct kvm *kvm,
+ struct kvm_gfn_range *range);
+bool kvm_arch_post_set_vm_memory_attributes(struct kvm *kvm,
+ struct kvm_gfn_range *range);
+#endif /* CONFIG_KVM_VM_MEMORY_ATTRIBUTES */
-static inline bool kvm_mem_is_private(struct kvm *kvm, gfn_t gfn)
+#ifdef CONFIG_KVM_PRIVATE_MEMATTR_VM
+extern bool gmem_in_place_conversion;
+typedef bool (kvm_is_private_gfn_t)(struct kvm *kvm, gfn_t gfn);
+DECLARE_STATIC_CALL(__kvm_is_private_gfn, kvm_is_private_gfn_t);
+
+static inline bool kvm_is_private_gfn(struct kvm *kvm, gfn_t gfn)
{
- return kvm_get_memory_attributes(kvm, gfn) & KVM_MEMORY_ATTRIBUTE_PRIVATE;
+ return static_call(__kvm_is_private_gfn)(kvm, gfn);
}
+
+#elif defined kvm_arch_has_private_mem
+#define gmem_in_place_conversion true
+#define kvm_is_private_gfn kvm_gmem_is_private_gfn
+
#else
-static inline bool kvm_mem_is_private(struct kvm *kvm, gfn_t gfn)
+#define gmem_in_place_conversion false
+
+static inline bool kvm_arch_has_private_mem(struct kvm *kvm)
+{
+ return false;
+}
+
+static inline bool kvm_is_private_gfn(struct kvm *kvm, gfn_t gfn)
{
return false;
}
-#endif /* CONFIG_KVM_GENERIC_MEMORY_ATTRIBUTES */
+#endif /* kvm_arch_has_private_mem */
#ifdef CONFIG_KVM_GUEST_MEMFD
+bool kvm_gmem_is_private_gfn(struct kvm *kvm, gfn_t gfn);
+bool kvm_arch_supports_gmem_init_shared(struct kvm *kvm);
+
+static inline u64 kvm_gmem_get_supported_flags(struct kvm *kvm)
+{
+ u64 flags = GUEST_MEMFD_FLAG_MMAP;
+
+ if (!kvm || kvm_arch_supports_gmem_init_shared(kvm))
+ flags |= GUEST_MEMFD_FLAG_INIT_SHARED;
+
+ return flags;
+}
+
int kvm_gmem_get_pfn(struct kvm *kvm, struct kvm_memory_slot *slot,
- gfn_t gfn, kvm_pfn_t *pfn, struct page **page,
- int *max_order);
+ gfn_t gfn, kvm_pfn_t *pfn, int *max_order);
#else
static inline int kvm_gmem_get_pfn(struct kvm *kvm,
struct kvm_memory_slot *slot, gfn_t gfn,
- kvm_pfn_t *pfn, struct page **page,
- int *max_order)
+ kvm_pfn_t *pfn, int *max_order)
{
KVM_BUG_ON(1, kvm);
return -EIO;
}
#endif /* CONFIG_KVM_GUEST_MEMFD */
-#ifdef CONFIG_HAVE_KVM_ARCH_GMEM_CONVERT
int kvm_arch_gmem_make_private(struct kvm *kvm, gfn_t gfn, kvm_pfn_t pfn,
kvm_pfn_t nr_pages);
+void kvm_arch_gmem_make_shared(kvm_pfn_t pfn, kvm_pfn_t nr_pages);
+#ifndef CONFIG_HAVE_KVM_ARCH_GMEM_CONVERT
+#define kvm_arch_has_gmem_convert() false
#endif
#ifdef CONFIG_HAVE_KVM_ARCH_GMEM_POPULATE
@@ -2643,6 +2684,7 @@ void kvm_arch_gmem_invalidate_range(struct kvm *kvm, struct kvm_gfn_range *range
#endif
#ifdef CONFIG_KVM_GENERIC_PRE_FAULT_MEMORY
+int kvm_arch_pre_fault_allowed(struct kvm_vcpu *vcpu);
long kvm_arch_vcpu_pre_fault_memory(struct kvm_vcpu *vcpu,
struct kvm_pre_fault_memory *range);
#endif
diff --git a/include/linux/landlock.h b/include/linux/landlock.h
index 004cbd0b9298..0ee4880988ba 100644
--- a/include/linux/landlock.h
+++ b/include/linux/landlock.h
@@ -13,14 +13,16 @@
#include <uapi/linux/landlock.h>
/*
- * Access-right and scope names, shared between the audit records (get_blocker()
- * in security/landlock/audit.c) and the trace events
+ * Access-right, scope, and permission names, shared between the audit records
+ * (get_blocker() in security/landlock/audit.c) and the trace events
* (include/trace/events/landlock.h). A consumer defines
* _LANDLOCK_NAME_ENTRY(mask, name) before expanding a list and undefines it
* afterwards: audit maps each entry to a "[bit] = name" slot for O(1) lookup,
* the trace events map it to a __print_flags() { mask, name } pair. The bit
* value lives only in the LANDLOCK_* UAPI constant each entry references.
- * Names are unprefixed; audit prepends the "fs."/"net."/"scope." category.
+ * Access-right and scope names are unprefixed; audit prepends the
+ * "fs."/"net."/"scope." category. Permission entries carry an action and a
+ * domain for the qualified and bare views below.
*/
#define _LANDLOCK_ACCESS_FS_NAMES \
_LANDLOCK_NAME_ENTRY(LANDLOCK_ACCESS_FS_EXECUTE, "execute"), \
@@ -53,4 +55,25 @@
"abstract_unix_socket"), \
_LANDLOCK_NAME_ENTRY(LANDLOCK_SCOPE_SIGNAL, "signal")
+#define _LANDLOCK_PERMISSION_NAMESPACE_NAME "namespace"
+#define _LANDLOCK_PERMISSION_CAPABILITY_NAME "capability"
+
+#define _LANDLOCK_PERMISSION_LIST(entry) \
+ entry(LANDLOCK_PERMISSION_NAMESPACE_USE, "use", \
+ _LANDLOCK_PERMISSION_NAMESPACE_NAME), \
+ entry(LANDLOCK_PERMISSION_CAPABILITY_USE, "use", \
+ _LANDLOCK_PERMISSION_CAPABILITY_NAME)
+
+#define _LANDLOCK_PERMISSION_QUALIFIED_ENTRY(mask, action, domain) \
+ _LANDLOCK_NAME_ENTRY(mask, domain "." action)
+
+#define _LANDLOCK_PERMISSION_BARE_ENTRY(mask, action, ...) \
+ _LANDLOCK_NAME_ENTRY(mask, action)
+
+#define _LANDLOCK_PERMISSION_NAMES \
+ _LANDLOCK_PERMISSION_LIST(_LANDLOCK_PERMISSION_QUALIFIED_ENTRY)
+
+#define _LANDLOCK_PERMISSION_BLOCKER_NAMES \
+ _LANDLOCK_PERMISSION_LIST(_LANDLOCK_PERMISSION_BARE_ENTRY)
+
#endif /* _LINUX_LANDLOCK_H */
diff --git a/include/linux/libata.h b/include/linux/libata.h
index 313e96173b19..48bde275968d 100644
--- a/include/linux/libata.h
+++ b/include/linux/libata.h
@@ -76,7 +76,7 @@ enum ata_quirks {
__ATA_QUIRK_MAX_SEC, /* Limit max sectors */
__ATA_QUIRK_MAX_TRIM_128M, /* Limit max trim size to 128M */
__ATA_QUIRK_NO_NCQ_ON_ATI, /* Disable NCQ on ATI chipset */
- __ATA_QUIRK_NO_LPM_ON_ATI, /* Disable LPM on ATI chipset */
+ __ATA_QUIRK_NO_LPM_ON_ATI_AND_AMD, /* Disable LPM on ATI and AMD chipsets */
__ATA_QUIRK_NO_ID_DEV_LOG, /* Identify device log missing */
__ATA_QUIRK_NO_LOG_DIR, /* Do not read log directory */
__ATA_QUIRK_NO_FUA, /* Do not use FUA */
@@ -115,7 +115,7 @@ enum {
ATA_QUIRK_MAX_SEC = BIT_ULL(__ATA_QUIRK_MAX_SEC),
ATA_QUIRK_MAX_TRIM_128M = BIT_ULL(__ATA_QUIRK_MAX_TRIM_128M),
ATA_QUIRK_NO_NCQ_ON_ATI = BIT_ULL(__ATA_QUIRK_NO_NCQ_ON_ATI),
- ATA_QUIRK_NO_LPM_ON_ATI = BIT_ULL(__ATA_QUIRK_NO_LPM_ON_ATI),
+ ATA_QUIRK_NO_LPM_ON_ATI_AND_AMD = BIT_ULL(__ATA_QUIRK_NO_LPM_ON_ATI_AND_AMD),
ATA_QUIRK_NO_ID_DEV_LOG = BIT_ULL(__ATA_QUIRK_NO_ID_DEV_LOG),
ATA_QUIRK_NO_LOG_DIR = BIT_ULL(__ATA_QUIRK_NO_LOG_DIR),
ATA_QUIRK_NO_FUA = BIT_ULL(__ATA_QUIRK_NO_FUA),
diff --git a/include/linux/list.h b/include/linux/list.h
index 77fb62f79928..e3753695e76c 100644
--- a/include/linux/list.h
+++ b/include/linux/list.h
@@ -1172,7 +1172,7 @@ static inline void hlist_move_list(struct hlist_head *old,
{
new->first = old->first;
if (new->first)
- new->first->pprev = &new->first;
+ WRITE_ONCE(new->first->pprev, &new->first);
old->first = NULL;
}
@@ -1189,10 +1189,10 @@ static inline void hlist_splice_init(struct hlist_head *from,
struct hlist_head *to)
{
if (to->first)
- to->first->pprev = &last->next;
+ WRITE_ONCE(to->first->pprev, &last->next);
last->next = to->first;
to->first = from->first;
- from->first->pprev = &to->first;
+ WRITE_ONCE(from->first->pprev, &to->first);
from->first = NULL;
}
diff --git a/include/linux/livepatch.h b/include/linux/livepatch.h
index ba9e3988c07c..5f74f79c22b4 100644
--- a/include/linux/livepatch.h
+++ b/include/linux/livepatch.h
@@ -33,6 +33,7 @@
* @kobj: kobject for sysfs resources
* @node: list node for klp_object func_list
* @stack_node: list node for klp_ops func_stack list
+ * @obj: back pointer to the owning object
* @old_size: size of the old function
* @new_size: size of the new function
* @nop: temporary patch to use the original code again; dyn. allocated
@@ -72,6 +73,7 @@ struct klp_func {
struct kobject kobj;
struct list_head node;
struct list_head stack_node;
+ struct klp_object *obj;
unsigned long old_size, new_size;
bool nop;
bool patched;
@@ -86,6 +88,7 @@ struct klp_func {
* @kobj: kobject for sysfs resources
* @func_list: dynamic list of the function entries
* @node: list node for klp_patch obj_list
+ * @patch: back pointer to the owning patch
* @mod: kernel module associated with the patched object
* (NULL for vmlinux)
* @dynamic: temporary object for nop functions; dynamically allocated
@@ -101,6 +104,7 @@ struct klp_object {
struct kobject kobj;
struct list_head func_list;
struct list_head node;
+ struct klp_patch *patch;
struct module *mod;
bool dynamic;
bool patched;
diff --git a/include/linux/llc.h b/include/linux/llc.h
index 944e9e213112..c03bb12bcc9c 100644
--- a/include/linux/llc.h
+++ b/include/linux/llc.h
@@ -9,9 +9,4 @@
#include <uapi/linux/llc.h>
-#define LLC_SAP_DYN_START 0xC0
-#define LLC_SAP_DYN_STOP 0xDE
-#define LLC_SAP_DYN_TRIES 4
-
-#define llc_ui_skb_cb(__skb) ((struct sockaddr_llc *)&((__skb)->cb[0]))
#endif /* __LINUX_LLC_H */
diff --git a/include/linux/lsm_audit.h b/include/linux/lsm_audit.h
index 584db296e43b..5cf0b4795065 100644
--- a/include/linux/lsm_audit.h
+++ b/include/linux/lsm_audit.h
@@ -44,7 +44,7 @@ struct lsm_network_audit {
struct lsm_ioctlop_audit {
struct path path;
- u16 cmd;
+ unsigned int cmd;
};
struct lsm_ibpkey_audit {
@@ -78,6 +78,7 @@ struct common_audit_data {
#define LSM_AUDIT_DATA_NOTIFICATION 16
#define LSM_AUDIT_DATA_ANONINODE 17
#define LSM_AUDIT_DATA_NLMSGTYPE 18
+#define LSM_AUDIT_DATA_NS 19
union {
struct path path;
struct dentry *dentry;
@@ -100,6 +101,10 @@ struct common_audit_data {
int reason;
const char *anonclass;
u16 nlmsg_type;
+ struct {
+ u32 ns_type;
+ u64 ns_id;
+ } ns;
} u;
/* this union contains LSM specific data */
union {
diff --git a/include/linux/lsm_hook_defs.h b/include/linux/lsm_hook_defs.h
index 65c9609ec207..87d9d06710cb 100644
--- a/include/linux/lsm_hook_defs.h
+++ b/include/linux/lsm_hook_defs.h
@@ -94,7 +94,7 @@ LSM_HOOK(int, 0, path_mkdir, const struct path *dir, struct dentry *dentry,
LSM_HOOK(int, 0, path_rmdir, const struct path *dir, struct dentry *dentry)
LSM_HOOK(int, 0, path_mknod, const struct path *dir, struct dentry *dentry,
umode_t mode, unsigned int dev)
-LSM_HOOK(void, LSM_RET_VOID, path_post_mknod, struct mnt_idmap *idmap,
+LSM_HOOK(void, LSM_RET_VOID, path_post_mknod, const struct mnt_idmap *idmap,
struct dentry *dentry)
LSM_HOOK(int, 0, path_truncate, const struct path *path)
LSM_HOOK(int, 0, path_symlink, const struct path *dir, struct dentry *dentry,
@@ -120,59 +120,60 @@ LSM_HOOK(int, -EOPNOTSUPP, inode_init_security, struct inode *inode,
int *xattr_count)
LSM_HOOK(int, 0, inode_init_security_anon, struct inode *inode,
const struct qstr *name, const struct inode *context_inode)
-LSM_HOOK(int, 0, inode_create, struct inode *dir, struct dentry *dentry,
- umode_t mode)
-LSM_HOOK(void, LSM_RET_VOID, inode_post_create_tmpfile, struct mnt_idmap *idmap,
+LSM_HOOK(int, 0, inode_create, const struct mnt_idmap *idmap, struct inode *dir,
+ struct dentry *dentry, umode_t mode)
+LSM_HOOK(void, LSM_RET_VOID, inode_post_create_tmpfile, const struct mnt_idmap *idmap,
struct inode *inode)
-LSM_HOOK(int, 0, inode_link, struct dentry *old_dentry, struct inode *dir,
- struct dentry *new_dentry)
+LSM_HOOK(int, 0, inode_link, const struct mnt_idmap *idmap,
+ struct dentry *old_dentry, struct inode *dir, struct dentry *new_dentry)
LSM_HOOK(int, 0, inode_unlink, struct inode *dir, struct dentry *dentry)
-LSM_HOOK(int, 0, inode_symlink, struct inode *dir, struct dentry *dentry,
- const char *old_name)
-LSM_HOOK(int, 0, inode_mkdir, struct inode *dir, struct dentry *dentry,
- umode_t mode)
+LSM_HOOK(int, 0, inode_symlink, const struct mnt_idmap *idmap, struct inode *dir,
+ struct dentry *dentry, const char *old_name)
+LSM_HOOK(int, 0, inode_mkdir, const struct mnt_idmap *idmap, struct inode *dir,
+ struct dentry *dentry, umode_t mode)
LSM_HOOK(int, 0, inode_rmdir, struct inode *dir, struct dentry *dentry)
-LSM_HOOK(int, 0, inode_mknod, struct inode *dir, struct dentry *dentry,
- umode_t mode, dev_t dev)
+LSM_HOOK(int, 0, inode_mknod, const struct mnt_idmap *idmap, struct inode *dir,
+ struct dentry *dentry, umode_t mode, dev_t dev)
LSM_HOOK(int, 0, inode_rename, struct inode *old_dir, struct dentry *old_dentry,
struct inode *new_dir, struct dentry *new_dentry)
LSM_HOOK(int, 0, inode_readlink, struct dentry *dentry)
LSM_HOOK(int, 0, inode_follow_link, struct dentry *dentry, struct inode *inode,
bool rcu)
-LSM_HOOK(int, 0, inode_permission, struct inode *inode, int mask)
-LSM_HOOK(int, 0, inode_setattr, struct mnt_idmap *idmap, struct dentry *dentry,
+LSM_HOOK(int, 0, inode_permission, const struct mnt_idmap *idmap,
+ struct inode *inode, int mask)
+LSM_HOOK(int, 0, inode_setattr, const struct mnt_idmap *idmap, struct dentry *dentry,
struct iattr *attr)
-LSM_HOOK(void, LSM_RET_VOID, inode_post_setattr, struct mnt_idmap *idmap,
+LSM_HOOK(void, LSM_RET_VOID, inode_post_setattr, const struct mnt_idmap *idmap,
struct dentry *dentry, int ia_valid)
LSM_HOOK(int, 0, inode_getattr, const struct path *path)
LSM_HOOK(int, 0, inode_xattr_skipcap, const char *name)
-LSM_HOOK(int, 0, inode_setxattr, struct mnt_idmap *idmap,
+LSM_HOOK(int, 0, inode_setxattr, const struct mnt_idmap *idmap,
struct dentry *dentry, const char *name, const void *value,
size_t size, int flags)
LSM_HOOK(void, LSM_RET_VOID, inode_post_setxattr, struct dentry *dentry,
const char *name, const void *value, size_t size, int flags)
LSM_HOOK(int, 0, inode_getxattr, struct dentry *dentry, const char *name)
LSM_HOOK(int, 0, inode_listxattr, struct dentry *dentry)
-LSM_HOOK(int, 0, inode_removexattr, struct mnt_idmap *idmap,
+LSM_HOOK(int, 0, inode_removexattr, const struct mnt_idmap *idmap,
struct dentry *dentry, const char *name)
LSM_HOOK(void, LSM_RET_VOID, inode_post_removexattr, struct dentry *dentry,
const char *name)
LSM_HOOK(int, 0, inode_file_setattr, struct dentry *dentry, struct file_kattr *fa)
LSM_HOOK(int, 0, inode_file_getattr, struct dentry *dentry, struct file_kattr *fa)
-LSM_HOOK(int, 0, inode_set_acl, struct mnt_idmap *idmap,
+LSM_HOOK(int, 0, inode_set_acl, const struct mnt_idmap *idmap,
struct dentry *dentry, const char *acl_name, struct posix_acl *kacl)
LSM_HOOK(void, LSM_RET_VOID, inode_post_set_acl, struct dentry *dentry,
const char *acl_name, struct posix_acl *kacl)
-LSM_HOOK(int, 0, inode_get_acl, struct mnt_idmap *idmap,
+LSM_HOOK(int, 0, inode_get_acl, const struct mnt_idmap *idmap,
struct dentry *dentry, const char *acl_name)
-LSM_HOOK(int, 0, inode_remove_acl, struct mnt_idmap *idmap,
+LSM_HOOK(int, 0, inode_remove_acl, const struct mnt_idmap *idmap,
struct dentry *dentry, const char *acl_name)
-LSM_HOOK(void, LSM_RET_VOID, inode_post_remove_acl, struct mnt_idmap *idmap,
+LSM_HOOK(void, LSM_RET_VOID, inode_post_remove_acl, const struct mnt_idmap *idmap,
struct dentry *dentry, const char *acl_name)
LSM_HOOK(int, 0, inode_need_killpriv, struct dentry *dentry)
-LSM_HOOK(int, 0, inode_killpriv, struct mnt_idmap *idmap,
+LSM_HOOK(int, 0, inode_killpriv, const struct mnt_idmap *idmap,
struct dentry *dentry)
-LSM_HOOK(int, -EOPNOTSUPP, inode_getsecurity, struct mnt_idmap *idmap,
+LSM_HOOK(int, -EOPNOTSUPP, inode_getsecurity, const struct mnt_idmap *idmap,
struct inode *inode, const char *name, void **buffer, bool alloc)
LSM_HOOK(int, -EOPNOTSUPP, inode_setsecurity, struct inode *inode,
const char *name, const void *value, size_t size, int flags)
@@ -265,6 +266,9 @@ LSM_HOOK(int, -ENOSYS, task_prctl, int option, unsigned long arg2,
LSM_HOOK(void, LSM_RET_VOID, task_to_inode, struct task_struct *p,
struct inode *inode)
LSM_HOOK(int, 0, userns_create, const struct cred *cred)
+LSM_HOOK(int, 0, namespace_init, struct ns_common *ns)
+LSM_HOOK(void, LSM_RET_VOID, namespace_free, struct ns_common *ns)
+LSM_HOOK(int, 0, namespace_install, const struct nsset *nsset, struct ns_common *ns)
LSM_HOOK(int, 0, ipc_permission, struct kern_ipc_perm *ipcp, short flag)
LSM_HOOK(void, LSM_RET_VOID, ipc_getlsmprop, struct kern_ipc_perm *ipcp,
struct lsm_prop *prop)
diff --git a/include/linux/lsm_hooks.h b/include/linux/lsm_hooks.h
index c4488c4a6d8a..13621e9e233e 100644
--- a/include/linux/lsm_hooks.h
+++ b/include/linux/lsm_hooks.h
@@ -112,6 +112,7 @@ struct lsm_blob_sizes {
unsigned int lbs_ipc;
unsigned int lbs_key;
unsigned int lbs_msg_msg;
+ unsigned int lbs_ns;
unsigned int lbs_perf_event;
unsigned int lbs_task;
unsigned int lbs_xattr_count; /* num xattr slots in new_xattrs array */
diff --git a/include/linux/mailbox/riscv-rpmi-message.h b/include/linux/mailbox/riscv-rpmi-message.h
index e135c6564d0c..d5362b5821f9 100644
--- a/include/linux/mailbox/riscv-rpmi-message.h
+++ b/include/linux/mailbox/riscv-rpmi-message.h
@@ -93,6 +93,7 @@ static inline int rpmi_to_linux_error(int rpmi_error)
/* RPMI service group IDs */
#define RPMI_SRVGRP_SYSTEM_MSI 0x00002
#define RPMI_SRVGRP_CLOCK 0x00008
+#define RPMI_SRVGRP_DEVICE_POWER 0x00009
/* RPMI clock service IDs */
enum rpmi_clock_service_id {
@@ -119,6 +120,16 @@ enum rpmi_sysmsi_service_id {
RPMI_SYSMSI_SRV_ID_MAX_COUNT
};
+/* RPMI device power service IDs */
+enum rpmi_device_power_service_id {
+ RPMI_DP_SRV_ENABLE_NOTIFICATION = 0x01,
+ RPMI_DP_SRV_GET_NUM_DOMAINS = 0x02,
+ RPMI_DP_SRV_GET_ATTRS = 0x03,
+ RPMI_DP_SRV_SET_STATE = 0x04,
+ RPMI_DP_SRV_GET_STATE = 0x05,
+ RPMI_DP_SRV_ID_MAX_COUNT,
+};
+
/* RPMI Linux mailbox attribute IDs */
enum rpmi_mbox_attribute_id {
RPMI_MBOX_ATTR_SPEC_VERSION,
diff --git a/include/linux/maple_tree.h b/include/linux/maple_tree.h
index e595ae5cd0ee..691f6012daea 100644
--- a/include/linux/maple_tree.h
+++ b/include/linux/maple_tree.h
@@ -9,6 +9,7 @@
*/
#include <linux/kernel.h>
+#include <linux/compiler.h>
#include <linux/rcupdate.h>
#include <linux/spinlock.h>
@@ -297,7 +298,8 @@ struct maple_tree {
#endif
#define DEFINE_MTREE(name) \
- struct maple_tree name = MTREE_INIT(name, 0)
+ struct maple_tree name = MTREE_INIT(name, 0); \
+ ASSERT_STATIC_STORAGE(name)
#define mtree_lock(mt) spin_lock((&(mt)->ma_lock))
#define mtree_lock_nested(mas, subclass) \
@@ -507,9 +509,13 @@ struct ma_wr_state {
};
#define mas_lock(mas) spin_lock(&((mas)->tree->ma_lock))
+#define mas_lock_irqsave(mas, flags) \
+ spin_lock_irqsave(&((mas)->tree->ma_lock), flags)
#define mas_lock_nested(mas, subclass) \
spin_lock_nested(&((mas)->tree->ma_lock), subclass)
#define mas_unlock(mas) spin_unlock(&((mas)->tree->ma_lock))
+#define mas_unlock_irqrestore(mas, flags) \
+ spin_unlock_irqrestore(&((mas)->tree->ma_lock), flags)
/*
* Special values for ma_state.node.
diff --git a/include/linux/mdio-mux.h b/include/linux/mdio-mux.h
index a5d58f221939..e2af9cb8e017 100644
--- a/include/linux/mdio-mux.h
+++ b/include/linux/mdio-mux.h
@@ -1,5 +1,5 @@
/*
- * MDIO bus multiplexer framwork.
+ * MDIO bus multiplexer framework.
*
* This file is subject to the terms and conditions of the GNU General Public
* License. See the file "COPYING" in the main directory of this archive
diff --git a/include/linux/memcontrol.h b/include/linux/memcontrol.h
index 7d1c0ce189a8..64c183be8cbf 100644
--- a/include/linux/memcontrol.h
+++ b/include/linux/memcontrol.h
@@ -23,6 +23,7 @@
#include <linux/writeback.h>
#include <linux/page-flags.h>
#include <linux/shrinker.h>
+#include <linux/irq_work_types.h>
struct mem_cgroup;
struct obj_cgroup;
@@ -66,11 +67,6 @@ struct mem_cgroup_reclaim_cookie {
#define MEM_CGROUP_ID_SHIFT 16
-struct mem_cgroup_private_id {
- int id;
- refcount_t ref;
-};
-
struct memcg_vmstats_percpu;
struct memcg1_events_percpu;
struct memcg_vmstats;
@@ -87,50 +83,48 @@ struct mem_cgroup_reclaim_iter {
* per-node information in memory controller.
*/
struct mem_cgroup_per_node {
- /* Keep the read-only fields at the start */
+ /* Set when the memcg is created, then only read. */
+ __cacheline_group_begin_aligned(memcg_pn_read_mostly);
struct mem_cgroup *memcg; /* Back pointer, we cannot */
/* use container_of */
struct lruvec_stats_percpu __percpu *lruvec_stats_percpu;
struct lruvec_stats *lruvec_stats;
struct shrinker_info __rcu *shrinker_info;
+ struct obj_cgroup __rcu *objcg;
+
+ __cacheline_group_end_aligned(memcg_pn_read_mostly);
-#ifdef CONFIG_MEMCG_V1
/*
- * Memcg-v1 only stuff in middle as buffer between read mostly fields
- * and update often fields to avoid false sharing. If v1 stuff is
- * not present, an explicit padding is needed.
+ * Keep lruvec on its own lines. Sharing them with lru_zone_size[]
+ * regressed, see commit f59adcf59332 ("mm: memcg: add cacheline
+ * padding after lruvec in mem_cgroup_per_node").
*/
-
- struct rb_node tree_node; /* RB tree node */
- unsigned long usage_in_excess;/* Set to the value by which */
- /* the soft limit is exceeded*/
- bool on_tree;
-#else
- CACHELINE_PADDING(_pad1_);
-#endif
-
- /* Fields which get updated often at the end. */
+ __cacheline_group_begin_aligned(memcg_pn_lruvec);
struct lruvec lruvec;
- CACHELINE_PADDING(_pad2_);
- unsigned long lru_zone_size[MAX_NR_ZONES][NR_LRU_LISTS];
+ __cacheline_group_end_aligned(memcg_pn_lruvec);
+
+ /* Written on every LRU update and on every reclaim iteration. */
+ __cacheline_group_begin_aligned(memcg_pn_write_hot);
+ long lru_zone_size[MAX_NR_ZONES][NR_LRU_LISTS];
struct mem_cgroup_reclaim_iter iter;
+#ifdef CONFIG_MEMCG_NMI_SAFETY_REQUIRES_ATOMIC
+ /* slab stats for nmi context */
+ atomic_t slab_reclaimable;
+ atomic_t slab_unreclaimable;
+#endif
+ __cacheline_group_end_aligned(memcg_pn_write_hot);
+ /* Touched only when the memcg is reparented or freed. */
+ __cacheline_group_begin_aligned(memcg_pn_cold);
/*
- * objcg is wiped out as a part of the objcg repaprenting process.
* orig_objcg preserves a pointer (and a reference) to the original
- * objcg until the end of live of memcg.
+ * objcg until the end of life of memcg.
*/
- struct obj_cgroup __rcu *objcg;
struct obj_cgroup *orig_objcg;
/* list of inherited objcgs, protected by objcg_lock */
struct list_head objcg_list;
-
-#ifdef CONFIG_MEMCG_NMI_SAFETY_REQUIRES_ATOMIC
- /* slab stats for nmi context */
- atomic_t slab_reclaimable;
- atomic_t slab_unreclaimable;
-#endif
+ __cacheline_group_end_aligned(memcg_pn_cold);
};
struct mem_cgroup_threshold {
@@ -202,9 +196,6 @@ struct obj_cgroup {
struct mem_cgroup {
struct cgroup_subsys_state css;
- /* Private memcg ID. Used to ID objects that outlive the cgroup */
- struct mem_cgroup_private_id id;
-
/* Accounted resources */
struct page_counter memory; /* Both v1 & v2 */
@@ -213,70 +204,62 @@ struct mem_cgroup {
struct page_counter memsw; /* v1 only */
};
- /* registered local peak watchers */
- struct list_head memory_peaks;
- struct list_head swap_peaks;
- spinlock_t peaks_lock;
-
- /* Range enforcement for interrupt charges */
- struct work_struct high_work;
-
-#ifdef CONFIG_ZSWAP
- unsigned long zswap_max;
-
+ /* Written on the charge, reclaim and socket paths. */
+ __cacheline_group_begin_aligned(memcg_write_hot);
/*
- * Prevent pages from this memcg from being written back from zswap to
- * swap, and from being swapped out on zswap store failures.
+ * Hint of reclaim pressure for socket memory management. Note
+ * that this indicator should NOT be used in legacy cgroup mode
+ * where socket memory is accounted/charged separately.
*/
- bool zswap_writeback;
+ u64 socket_pressure;
+#if BITS_PER_LONG < 64
+ seqlock_t socket_pressure_seqlock;
#endif
-
- /* vmpressure notifications */
- struct vmpressure vmpressure;
-
/*
- * Should the OOM killer kill all belonging tasks, had it kill one?
+ * memory.events is bumped for this memcg and all its ancestors, so a
+ * busy child dirties every ancestor.
*/
- bool oom_group;
-
- /* memory.events and memory.events.local */
- struct cgroup_file events_file;
- struct cgroup_file events_local_file;
-
- /* handle for "memory.swap.events" */
- struct cgroup_file swap_events_file;
-
- /* memory.stat */
- struct memcg_vmstats *vmstats;
-
- /* memory.events */
atomic_long_t memory_events[MEMCG_NR_MEMORY_EVENTS];
atomic_long_t memory_events_local[MEMCG_NR_MEMORY_EVENTS];
+ /* vmpressure notifications. Written on every reclaim iteration. */
+ struct vmpressure vmpressure;
+
+ /* Written on every swap charge and uncharge. */
+ refcount_t private_id_ref;
+
#ifdef CONFIG_MEMCG_NMI_SAFETY_REQUIRES_ATOMIC
/* MEMCG_KMEM for nmi context */
atomic_t kmem_stat;
#endif
+
+ /* Range enforcement for interrupt charges */
+ struct irq_work high_irq_work;
+ struct work_struct high_work;
+
+ __cacheline_group_end_aligned(memcg_write_hot);
+
/*
- * Hint of reclaim pressure for socket memroy management. Note
- * that this indicator should NOT be used in legacy cgroup mode
- * where socket memory is accounted/charged separately.
+ * Off the charge and fault paths. Not write free: cgwb_domain is
+ * written on every writeout completion and mm_list on fork, exit and
+ * MGLRU aging. They are grouped here so those writes cannot land on
+ * a line that the fast paths read.
*/
- u64 socket_pressure;
-#if BITS_PER_LONG < 64
- seqlock_t socket_pressure_seqlock;
-#endif
- int kmemcg_id;
+ __cacheline_group_begin_aligned(memcg_cold);
+ /* registered local peak watchers */
+ struct list_head memory_peaks;
+ struct list_head swap_peaks;
+ spinlock_t peaks_lock;
-#ifdef CONFIG_CGROUP_WRITEBACK
- struct list_head cgwb_list;
-#endif
+ /* memory.events and memory.events.local */
+ struct cgroup_file events_file;
+ struct cgroup_file events_local_file;
- /* Keep the hot per-CPU stats pointer away from memory event counters. */
- struct memcg_vmstats_percpu __percpu *vmstats_percpu
- ____cacheline_aligned_in_smp;
+ /* handle for "memory.swap.events" */
+ struct cgroup_file swap_events_file;
#ifdef CONFIG_CGROUP_WRITEBACK
+ struct list_head cgwb_list;
struct wb_domain cgwb_domain;
struct memcg_cgwb_frn cgwb_frn[MEMCG_CGWB_FRN_CNT];
#endif
@@ -285,16 +268,17 @@ struct mem_cgroup {
/* per-memcg mm_struct list */
struct lru_gen_mm_list mm_list;
#endif
+ __cacheline_group_end_aligned(memcg_cold);
#ifdef CONFIG_MEMCG_V1
+ /* v1 only. Not grouped: v1 is legacy, sorting it is not worth it. */
+
/* Legacy consumer-oriented counters */
struct page_counter kmem; /* v1 only */
struct page_counter tcpmem; /* v1 only */
struct memcg1_events_percpu __percpu *events_percpu;
- unsigned long soft_limit;
-
/* protected by memcg_oom_lock */
bool oom_lock;
int under_oom;
@@ -325,6 +309,41 @@ struct mem_cgroup {
int swappiness;
#endif /* CONFIG_MEMCG_V1 */
+ /*
+ * Set when the memcg is created and cleared when it is offlined.
+ * Never written on a hot path.
+ */
+ __cacheline_group_begin_aligned(memcg_read_mostly);
+ /* Read on every stat update */
+ struct memcg_vmstats_percpu __percpu *vmstats_percpu;
+
+ /* memory.stat */
+ struct memcg_vmstats *vmstats;
+
+#ifdef CONFIG_ZSWAP
+ unsigned long zswap_max;
+#endif
+
+ /* Private memcg ID. Used to ID objects that outlive the cgroup */
+ int private_id;
+
+ int kmemcg_id;
+
+ /*
+ * Should the OOM killer kill all belonging tasks, had it kill one?
+ */
+ bool oom_group;
+
+#ifdef CONFIG_ZSWAP
+ /*
+ * Prevent pages from this memcg from being written back from zswap to
+ * swap, and from being swapped out on zswap store failures.
+ */
+ bool zswap_writeback;
+#endif
+ /* Not padded: nodeinfo[] is read-mostly too, let it share the line. */
+ __cacheline_group_end(memcg_read_mostly);
+
struct mem_cgroup_per_node *nodeinfo[];
};
@@ -377,10 +396,10 @@ enum objext_flags {
*
* The caller must ensure that the returned memcg won't be released.
*/
-static inline struct mem_cgroup *obj_cgroup_memcg(struct obj_cgroup *objcg)
+static inline struct mem_cgroup *obj_cgroup_memcg(const struct obj_cgroup *objcg)
{
lockdep_assert_once(rcu_read_lock_held() || lockdep_is_held(&cgroup_mutex));
- return READ_ONCE(objcg->memcg);
+ return objcg ? READ_ONCE(objcg->memcg) : NULL;
}
/*
@@ -391,7 +410,7 @@ static inline struct mem_cgroup *obj_cgroup_memcg(struct obj_cgroup *objcg)
* or NULL. This function assumes that the folio is known to have a
* proper object cgroup pointer.
*/
-static inline struct obj_cgroup *folio_objcg(struct folio *folio)
+static inline struct obj_cgroup *folio_objcg(const struct folio *folio)
{
unsigned long memcg_data = folio->memcg_data;
@@ -429,11 +448,11 @@ static inline struct obj_cgroup *folio_objcg(struct folio *folio)
* Note: The caller should hold an rcu read lock or cgroup_mutex to protect
* memcg associated with a folio from being released.
*/
-static inline struct mem_cgroup *folio_memcg(struct folio *folio)
+static inline struct mem_cgroup *folio_memcg(const struct folio *folio)
{
struct obj_cgroup *objcg = folio_objcg(folio);
- return objcg ? obj_cgroup_memcg(objcg) : NULL;
+ return obj_cgroup_memcg(objcg);
}
/*
@@ -442,7 +461,7 @@ static inline struct mem_cgroup *folio_memcg(struct folio *folio)
*
* Returns true if folio is charged to a memory cgroup, otherwise returns false.
*/
-static inline bool folio_memcg_charged(struct folio *folio)
+static inline bool folio_memcg_charged(const struct folio *folio)
{
return folio->memcg_data != 0;
}
@@ -462,7 +481,7 @@ static inline bool folio_memcg_charged(struct folio *folio)
* A caller should hold an rcu read lock to protect memcg associated with a
* page from being released.
*/
-static inline struct mem_cgroup *folio_memcg_check(struct folio *folio)
+static inline struct mem_cgroup *folio_memcg_check(const struct folio *folio)
{
/*
* Because folio->memcg_data might be changed asynchronously
@@ -476,17 +495,17 @@ static inline struct mem_cgroup *folio_memcg_check(struct folio *folio)
objcg = (void *)(memcg_data & ~OBJEXTS_FLAGS_MASK);
- return objcg ? obj_cgroup_memcg(objcg) : NULL;
+ return obj_cgroup_memcg(objcg);
}
-static inline struct mem_cgroup *page_memcg_check(struct page *page)
+static inline struct mem_cgroup *page_memcg_check(const struct page *page)
{
if (PageTail(page))
return NULL;
- return folio_memcg_check((struct folio *)page);
+ return folio_memcg_check((const struct folio *)page);
}
-static inline struct mem_cgroup *get_mem_cgroup_from_objcg(struct obj_cgroup *objcg)
+static inline struct mem_cgroup *get_mem_cgroup_from_objcg(const struct obj_cgroup *objcg)
{
struct mem_cgroup *memcg;
@@ -508,19 +527,19 @@ retry:
* that the folio has an associated memory cgroup. It's not safe to call
* this function against some types of folios, e.g. slab folios.
*/
-static inline bool folio_memcg_kmem(struct folio *folio)
+static inline bool folio_memcg_kmem(const struct folio *folio)
{
VM_BUG_ON_PGFLAGS(PageTail(&folio->page), &folio->page);
VM_BUG_ON_FOLIO(folio->memcg_data & MEMCG_DATA_OBJEXTS, folio);
return folio->memcg_data & MEMCG_DATA_KMEM;
}
-static inline bool PageMemcgKmem(struct page *page)
+static inline bool PageMemcgKmem(const struct page *page)
{
return folio_memcg_kmem(page_folio(page));
}
-static inline bool mem_cgroup_is_root(struct mem_cgroup *memcg)
+static inline bool mem_cgroup_is_root(const struct mem_cgroup *memcg)
{
return (memcg == root_mem_cgroup);
}
@@ -536,7 +555,7 @@ static inline bool mem_cgroup_is_root(struct mem_cgroup *memcg)
* and do not honour sc->memcg can use this to early-return 0 in per-memcg
* contexts.
*/
-static inline bool mem_cgroup_shrink_is_root(struct shrink_control *sc)
+static inline bool mem_cgroup_shrink_is_root(const struct shrink_control *sc)
{
return !sc->memcg || mem_cgroup_is_root(sc->memcg);
}
@@ -551,8 +570,8 @@ static inline bool mem_cgroup_disabled(void)
return !cgroup_subsys_enabled(memory_cgrp_subsys);
}
-static inline void mem_cgroup_protection(struct mem_cgroup *root,
- struct mem_cgroup *memcg,
+static inline void mem_cgroup_protection(const struct mem_cgroup *root,
+ const struct mem_cgroup *memcg,
unsigned long *min,
unsigned long *low,
unsigned long *usage)
@@ -606,8 +625,8 @@ static inline void mem_cgroup_protection(struct mem_cgroup *root,
void mem_cgroup_calculate_protection(struct mem_cgroup *root,
struct mem_cgroup *memcg);
-static inline bool mem_cgroup_unprotected(struct mem_cgroup *target,
- struct mem_cgroup *memcg)
+static inline bool mem_cgroup_unprotected(const struct mem_cgroup *target,
+ const struct mem_cgroup *memcg)
{
/*
* The root memcg doesn't account charges, and doesn't support
@@ -618,8 +637,8 @@ static inline bool mem_cgroup_unprotected(struct mem_cgroup *target,
memcg == target;
}
-static inline bool mem_cgroup_below_low(struct mem_cgroup *target,
- struct mem_cgroup *memcg)
+static inline bool mem_cgroup_below_low(const struct mem_cgroup *target,
+ const struct mem_cgroup *memcg)
{
if (mem_cgroup_unprotected(target, memcg))
return false;
@@ -628,8 +647,8 @@ static inline bool mem_cgroup_below_low(struct mem_cgroup *target,
page_counter_read(&memcg->memory);
}
-static inline bool mem_cgroup_below_min(struct mem_cgroup *target,
- struct mem_cgroup *memcg)
+static inline bool mem_cgroup_below_min(const struct mem_cgroup *target,
+ const struct mem_cgroup *memcg)
{
if (mem_cgroup_unprotected(target, memcg))
return false;
@@ -662,7 +681,8 @@ static inline int mem_cgroup_charge(struct folio *folio, struct mm_struct *mm,
return __mem_cgroup_charge(folio, mm, gfp);
}
-int mem_cgroup_charge_hugetlb(struct folio* folio, gfp_t gfp);
+int mem_cgroup_charge_hugetlb(struct folio *folio, struct mm_struct *mm,
+ gfp_t gfp);
int mem_cgroup_swapin_charge_folio(struct folio *folio, unsigned short id,
struct mm_struct *mm, gfp_t gfp);
@@ -702,7 +722,7 @@ void mem_cgroup_migrate(struct folio *old, struct folio *new);
* @pgdat combination. This can be the node lruvec, if the memory
* controller is disabled.
*/
-static inline struct lruvec *mem_cgroup_lruvec(struct mem_cgroup *memcg,
+static inline struct lruvec *mem_cgroup_lruvec(const struct mem_cgroup *memcg,
struct pglist_data *pgdat)
{
struct mem_cgroup_per_node *mz;
@@ -743,7 +763,7 @@ out:
* their binding is stable if the returned lruvec matches the one the caller has
* locked. Useful for lock batching.
*/
-static inline struct lruvec *folio_lruvec(struct folio *folio)
+static inline struct lruvec *folio_lruvec(const struct folio *folio)
{
struct mem_cgroup *memcg = folio_memcg(folio);
@@ -757,11 +777,11 @@ struct mem_cgroup *get_mem_cgroup_from_mm(struct mm_struct *mm);
struct mem_cgroup *get_mem_cgroup_from_current(void);
-struct mem_cgroup *get_mem_cgroup_from_folio(struct folio *folio);
+struct mem_cgroup *get_mem_cgroup_from_folio(const struct folio *folio);
-struct lruvec *folio_lruvec_lock(struct folio *folio);
-struct lruvec *folio_lruvec_lock_irq(struct folio *folio);
-struct lruvec *folio_lruvec_lock_irqsave(struct folio *folio,
+struct lruvec *folio_lruvec_lock(const struct folio *folio);
+struct lruvec *folio_lruvec_lock_irq(const struct folio *folio);
+struct lruvec *folio_lruvec_lock_irqsave(const struct folio *folio,
unsigned long *flags);
static inline
@@ -820,16 +840,16 @@ void mem_cgroup_iter_break(struct mem_cgroup *, struct mem_cgroup *);
void mem_cgroup_scan_tasks(struct mem_cgroup *memcg,
int (*)(struct task_struct *, void *), void *arg);
-static inline unsigned short mem_cgroup_private_id(struct mem_cgroup *memcg)
+static inline unsigned short mem_cgroup_private_id(const struct mem_cgroup *memcg)
{
if (mem_cgroup_disabled())
return 0;
- return memcg->id.id;
+ return memcg->private_id;
}
struct mem_cgroup *mem_cgroup_from_private_id(unsigned short id);
-static inline u64 mem_cgroup_id(struct mem_cgroup *memcg)
+static inline u64 mem_cgroup_id(const struct mem_cgroup *memcg)
{
return memcg ? cgroup_id(memcg->css.cgroup) : 0;
}
@@ -841,14 +861,14 @@ static inline struct mem_cgroup *mem_cgroup_from_seq(struct seq_file *m)
return mem_cgroup_from_css(seq_css(m));
}
-static inline struct mem_cgroup *lruvec_memcg(struct lruvec *lruvec)
+static inline struct mem_cgroup *lruvec_memcg(const struct lruvec *lruvec)
{
- struct mem_cgroup_per_node *mz;
+ const struct mem_cgroup_per_node *mz;
if (mem_cgroup_disabled())
return NULL;
- mz = container_of(lruvec, struct mem_cgroup_per_node, lruvec);
+ mz = container_of_const(lruvec, struct mem_cgroup_per_node, lruvec);
return mz->memcg;
}
@@ -858,13 +878,13 @@ static inline struct mem_cgroup *lruvec_memcg(struct lruvec *lruvec)
*
* Returns the parent memcg, or NULL if this is the root.
*/
-static inline struct mem_cgroup *parent_mem_cgroup(struct mem_cgroup *memcg)
+static inline struct mem_cgroup *parent_mem_cgroup(const struct mem_cgroup *memcg)
{
return mem_cgroup_from_css(memcg->css.parent);
}
-static inline bool mem_cgroup_is_descendant(struct mem_cgroup *memcg,
- struct mem_cgroup *root)
+static inline bool mem_cgroup_is_descendant(const struct mem_cgroup *memcg,
+ const struct mem_cgroup *root)
{
if (root == memcg)
return true;
@@ -872,7 +892,7 @@ static inline bool mem_cgroup_is_descendant(struct mem_cgroup *memcg,
}
static inline bool mm_match_cgroup(struct mm_struct *mm,
- struct mem_cgroup *memcg)
+ const struct mem_cgroup *memcg)
{
struct mem_cgroup *task_memcg;
bool match = false;
@@ -885,8 +905,8 @@ static inline bool mm_match_cgroup(struct mm_struct *mm,
return match;
}
-struct cgroup_subsys_state *get_mem_cgroup_css_from_folio(struct folio *folio);
-ino_t page_cgroup_ino(struct page *page);
+struct cgroup_subsys_state *get_mem_cgroup_css_from_folio(const struct folio *folio);
+ino_t page_cgroup_ino(const struct page *page);
static inline bool mem_cgroup_online(struct mem_cgroup *memcg)
{
@@ -899,13 +919,18 @@ void mem_cgroup_update_lru_size(struct lruvec *lruvec, enum lru_list lru,
int zid, long nr_pages);
static inline
-unsigned long mem_cgroup_get_zone_lru_size(struct lruvec *lruvec,
+unsigned long mem_cgroup_get_zone_lru_size(const struct lruvec *lruvec,
enum lru_list lru, int zone_idx)
{
- struct mem_cgroup_per_node *mz;
+ long val;
+ const struct mem_cgroup_per_node *mz;
+
+ mz = container_of_const(lruvec, struct mem_cgroup_per_node, lruvec);
+ val = READ_ONCE(mz->lru_zone_size[zone_idx][lru]);
+ if (WARN_ON_ONCE(val < 0))
+ return 0;
- mz = container_of(lruvec, struct mem_cgroup_per_node, lruvec);
- return READ_ONCE(mz->lru_zone_size[zone_idx][lru]);
+ return val;
}
void __mem_cgroup_handle_over_high(gfp_t gfp_mask);
@@ -916,9 +941,9 @@ static inline void mem_cgroup_handle_over_high(gfp_t gfp_mask)
__mem_cgroup_handle_over_high(gfp_mask);
}
-unsigned long mem_cgroup_get_max(struct mem_cgroup *memcg);
+unsigned long mem_cgroup_get_max(const struct mem_cgroup *memcg);
-void mem_cgroup_print_oom_context(struct mem_cgroup *memcg,
+void mem_cgroup_print_oom_context(const struct mem_cgroup *memcg,
struct task_struct *p);
void mem_cgroup_print_oom_meminfo(struct mem_cgroup *memcg);
@@ -931,7 +956,7 @@ void mem_cgroup_print_oom_group(struct mem_cgroup *memcg);
void mod_memcg_state(struct mem_cgroup *memcg,
enum memcg_stat_item idx, int val);
-static inline void mod_memcg_page_state(struct page *page,
+static inline void mod_memcg_page_state(const struct page *page,
enum memcg_stat_item idx, int val)
{
struct mem_cgroup *memcg;
@@ -946,15 +971,16 @@ static inline void mod_memcg_page_state(struct page *page,
rcu_read_unlock();
}
-unsigned long memcg_events(struct mem_cgroup *memcg, int event);
-unsigned long memcg_page_state(struct mem_cgroup *memcg, int idx);
-unsigned long memcg_page_state_output(struct mem_cgroup *memcg, int item);
+unsigned long memcg_events(const struct mem_cgroup *memcg, int event);
+unsigned long memcg_page_state(const struct mem_cgroup *memcg, int idx);
+unsigned long memcg_page_state_output(const struct mem_cgroup *memcg, int item);
bool memcg_stat_item_valid(int idx);
bool memcg_vm_event_item_valid(enum vm_event_item idx);
-unsigned long lruvec_page_state(struct lruvec *lruvec, enum node_stat_item idx);
-unsigned long lruvec_page_state_monotonic(struct lruvec *lruvec,
+unsigned long lruvec_page_state(const struct lruvec *lruvec,
+ enum node_stat_item idx);
+unsigned long lruvec_page_state_monotonic(const struct lruvec *lruvec,
enum node_stat_item idx);
-unsigned long lruvec_page_state_local(struct lruvec *lruvec,
+unsigned long lruvec_page_state_local(const struct lruvec *lruvec,
enum node_stat_item idx);
void mem_cgroup_flush_stats(struct mem_cgroup *memcg);
@@ -965,7 +991,7 @@ void mod_lruvec_kmem_state(void *p, enum node_stat_item idx, int val);
void count_memcg_events(struct mem_cgroup *memcg, enum vm_event_item idx,
unsigned long count);
-static inline void count_memcg_folio_events(struct folio *folio,
+static inline void count_memcg_folio_events(const struct folio *folio,
enum vm_event_item idx, unsigned long nr)
{
struct mem_cgroup *memcg;
@@ -1050,51 +1076,56 @@ void mem_cgroup_flush_workqueue(void);
extern int mem_cgroup_init(void);
#else /* CONFIG_MEMCG */
+static inline struct mem_cgroup *obj_cgroup_memcg(const struct obj_cgroup *objcg)
+{
+ return NULL;
+}
+
#define MEM_CGROUP_ID_SHIFT 0
#define root_mem_cgroup (NULL)
-static inline struct mem_cgroup *folio_memcg(struct folio *folio)
+static inline struct mem_cgroup *folio_memcg(const struct folio *folio)
{
return NULL;
}
-static inline bool folio_memcg_charged(struct folio *folio)
+static inline bool folio_memcg_charged(const struct folio *folio)
{
return false;
}
-static inline struct mem_cgroup *folio_memcg_check(struct folio *folio)
+static inline struct mem_cgroup *folio_memcg_check(const struct folio *folio)
{
return NULL;
}
-static inline struct mem_cgroup *page_memcg_check(struct page *page)
+static inline struct mem_cgroup *page_memcg_check(const struct page *page)
{
return NULL;
}
-static inline struct mem_cgroup *get_mem_cgroup_from_objcg(struct obj_cgroup *objcg)
+static inline struct mem_cgroup *get_mem_cgroup_from_objcg(const struct obj_cgroup *objcg)
{
return NULL;
}
-static inline bool folio_memcg_kmem(struct folio *folio)
+static inline bool folio_memcg_kmem(const struct folio *folio)
{
return false;
}
-static inline bool PageMemcgKmem(struct page *page)
+static inline bool PageMemcgKmem(const struct page *page)
{
return false;
}
-static inline bool mem_cgroup_is_root(struct mem_cgroup *memcg)
+static inline bool mem_cgroup_is_root(const struct mem_cgroup *memcg)
{
return true;
}
-static inline bool mem_cgroup_shrink_is_root(struct shrink_control *sc)
+static inline bool mem_cgroup_shrink_is_root(const struct shrink_control *sc)
{
return true;
}
@@ -1119,8 +1150,8 @@ static inline void memcg_memory_event_mm(struct mm_struct *mm,
{
}
-static inline void mem_cgroup_protection(struct mem_cgroup *root,
- struct mem_cgroup *memcg,
+static inline void mem_cgroup_protection(const struct mem_cgroup *root,
+ const struct mem_cgroup *memcg,
unsigned long *min,
unsigned long *low,
unsigned long *usage)
@@ -1133,19 +1164,19 @@ static inline void mem_cgroup_calculate_protection(struct mem_cgroup *root,
{
}
-static inline bool mem_cgroup_unprotected(struct mem_cgroup *target,
- struct mem_cgroup *memcg)
+static inline bool mem_cgroup_unprotected(const struct mem_cgroup *target,
+ const struct mem_cgroup *memcg)
{
return true;
}
-static inline bool mem_cgroup_below_low(struct mem_cgroup *target,
- struct mem_cgroup *memcg)
+static inline bool mem_cgroup_below_low(const struct mem_cgroup *target,
+ const struct mem_cgroup *memcg)
{
return false;
}
-static inline bool mem_cgroup_below_min(struct mem_cgroup *target,
- struct mem_cgroup *memcg)
+static inline bool mem_cgroup_below_min(const struct mem_cgroup *target,
+ const struct mem_cgroup *memcg)
{
return false;
}
@@ -1156,9 +1187,10 @@ static inline int mem_cgroup_charge(struct folio *folio,
return 0;
}
-static inline int mem_cgroup_charge_hugetlb(struct folio* folio, gfp_t gfp)
+static inline int mem_cgroup_charge_hugetlb(struct folio *folio,
+ struct mm_struct *mm, gfp_t gfp)
{
- return 0;
+ return 0;
}
static inline int mem_cgroup_swapin_charge_folio(struct folio *folio,
@@ -1184,25 +1216,25 @@ static inline void mem_cgroup_migrate(struct folio *old, struct folio *new)
{
}
-static inline struct lruvec *mem_cgroup_lruvec(struct mem_cgroup *memcg,
+static inline struct lruvec *mem_cgroup_lruvec(const struct mem_cgroup *memcg,
struct pglist_data *pgdat)
{
return &pgdat->__lruvec;
}
-static inline struct lruvec *folio_lruvec(struct folio *folio)
+static inline struct lruvec *folio_lruvec(const struct folio *folio)
{
struct pglist_data *pgdat = folio_pgdat(folio);
return &pgdat->__lruvec;
}
-static inline struct mem_cgroup *parent_mem_cgroup(struct mem_cgroup *memcg)
+static inline struct mem_cgroup *parent_mem_cgroup(const struct mem_cgroup *memcg)
{
return NULL;
}
static inline bool mm_match_cgroup(struct mm_struct *mm,
- struct mem_cgroup *memcg)
+ const struct mem_cgroup *memcg)
{
return true;
}
@@ -1217,7 +1249,7 @@ static inline struct mem_cgroup *get_mem_cgroup_from_current(void)
return NULL;
}
-static inline struct mem_cgroup *get_mem_cgroup_from_folio(struct folio *folio)
+static inline struct mem_cgroup *get_mem_cgroup_from_folio(const struct folio *folio)
{
return NULL;
}
@@ -1250,7 +1282,7 @@ static inline void mem_cgroup_put(struct mem_cgroup *memcg)
{
}
-static inline struct lruvec *folio_lruvec_lock(struct folio *folio)
+static inline struct lruvec *folio_lruvec_lock(const struct folio *folio)
{
struct pglist_data *pgdat = folio_pgdat(folio);
@@ -1259,7 +1291,7 @@ static inline struct lruvec *folio_lruvec_lock(struct folio *folio)
return &pgdat->__lruvec;
}
-static inline struct lruvec *folio_lruvec_lock_irq(struct folio *folio)
+static inline struct lruvec *folio_lruvec_lock_irq(const struct folio *folio)
{
struct pglist_data *pgdat = folio_pgdat(folio);
@@ -1268,7 +1300,7 @@ static inline struct lruvec *folio_lruvec_lock_irq(struct folio *folio)
return &pgdat->__lruvec;
}
-static inline struct lruvec *folio_lruvec_lock_irqsave(struct folio *folio,
+static inline struct lruvec *folio_lruvec_lock_irqsave(const struct folio *folio,
unsigned long *flagsp)
{
struct pglist_data *pgdat = folio_pgdat(folio);
@@ -1296,7 +1328,7 @@ static inline void mem_cgroup_scan_tasks(struct mem_cgroup *memcg,
{
}
-static inline unsigned short mem_cgroup_private_id(struct mem_cgroup *memcg)
+static inline unsigned short mem_cgroup_private_id(const struct mem_cgroup *memcg)
{
return 0;
}
@@ -1308,7 +1340,7 @@ static inline struct mem_cgroup *mem_cgroup_from_private_id(unsigned short id)
return NULL;
}
-static inline u64 mem_cgroup_id(struct mem_cgroup *memcg)
+static inline u64 mem_cgroup_id(const struct mem_cgroup *memcg)
{
return 0;
}
@@ -1323,7 +1355,7 @@ static inline struct mem_cgroup *mem_cgroup_from_seq(struct seq_file *m)
return NULL;
}
-static inline struct mem_cgroup *lruvec_memcg(struct lruvec *lruvec)
+static inline struct mem_cgroup *lruvec_memcg(const struct lruvec *lruvec)
{
return NULL;
}
@@ -1334,19 +1366,20 @@ static inline bool mem_cgroup_online(struct mem_cgroup *memcg)
}
static inline
-unsigned long mem_cgroup_get_zone_lru_size(struct lruvec *lruvec,
+unsigned long mem_cgroup_get_zone_lru_size(const struct lruvec *lruvec,
enum lru_list lru, int zone_idx)
{
return 0;
}
-static inline unsigned long mem_cgroup_get_max(struct mem_cgroup *memcg)
+static inline unsigned long mem_cgroup_get_max(const struct mem_cgroup *memcg)
{
return 0;
}
static inline void
-mem_cgroup_print_oom_context(struct mem_cgroup *memcg, struct task_struct *p)
+mem_cgroup_print_oom_context(const struct mem_cgroup *memcg,
+ struct task_struct *p)
{
}
@@ -1375,17 +1408,17 @@ static inline void mod_memcg_state(struct mem_cgroup *memcg,
{
}
-static inline void mod_memcg_page_state(struct page *page,
+static inline void mod_memcg_page_state(const struct page *page,
enum memcg_stat_item idx, int val)
{
}
-static inline unsigned long memcg_page_state(struct mem_cgroup *memcg, int idx)
+static inline unsigned long memcg_page_state(const struct mem_cgroup *memcg, int idx)
{
return 0;
}
-static inline unsigned long memcg_page_state_output(struct mem_cgroup *memcg, int item)
+static inline unsigned long memcg_page_state_output(const struct mem_cgroup *memcg, int item)
{
return 0;
}
@@ -1400,19 +1433,19 @@ static inline bool memcg_vm_event_item_valid(enum vm_event_item idx)
return false;
}
-static inline unsigned long lruvec_page_state(struct lruvec *lruvec,
+static inline unsigned long lruvec_page_state(const struct lruvec *lruvec,
enum node_stat_item idx)
{
return node_page_state(lruvec_pgdat(lruvec), idx);
}
-static inline unsigned long lruvec_page_state_monotonic(struct lruvec *lruvec,
+static inline unsigned long lruvec_page_state_monotonic(const struct lruvec *lruvec,
enum node_stat_item idx)
{
return node_page_state_monotonic(lruvec_pgdat(lruvec), idx);
}
-static inline unsigned long lruvec_page_state_local(struct lruvec *lruvec,
+static inline unsigned long lruvec_page_state_local(const struct lruvec *lruvec,
enum node_stat_item idx)
{
return node_page_state(lruvec_pgdat(lruvec), idx);
@@ -1440,7 +1473,7 @@ static inline void count_memcg_events(struct mem_cgroup *memcg,
{
}
-static inline void count_memcg_folio_events(struct folio *folio,
+static inline void count_memcg_folio_events(const struct folio *folio,
enum vm_event_item idx, unsigned long nr)
{
}
@@ -1474,7 +1507,7 @@ static inline void mem_cgroup_flush_workqueue(void) { }
static inline int mem_cgroup_init(void) { return 0; }
#endif /* CONFIG_MEMCG */
-static inline struct lruvec *parent_lruvec(struct lruvec *lruvec)
+static inline struct lruvec *parent_lruvec(const struct lruvec *lruvec)
{
struct mem_cgroup *memcg;
@@ -1537,15 +1570,15 @@ static inline void lruvec_unlock_irqrestore(struct lruvec *lruvec, unsigned long
}
/* Test requires a stable folio->memcg binding, see folio_memcg() */
-static inline bool folio_matches_lruvec(struct folio *folio,
- struct lruvec *lruvec)
+static inline bool folio_matches_lruvec(const struct folio *folio,
+ const struct lruvec *lruvec)
{
return lruvec_pgdat(lruvec) == folio_pgdat(folio) &&
lruvec_memcg(lruvec) == folio_memcg(folio);
}
/* Don't lock again iff page's lruvec locked */
-static inline struct lruvec *folio_lruvec_relock_irq(struct folio *folio,
+static inline struct lruvec *folio_lruvec_relock_irq(const struct folio *folio,
struct lruvec *locked_lruvec)
{
if (locked_lruvec) {
@@ -1559,7 +1592,7 @@ static inline struct lruvec *folio_lruvec_relock_irq(struct folio *folio,
}
/* Don't lock again iff folio's lruvec locked */
-static inline void folio_lruvec_relock_irqsave(struct folio *folio,
+static inline void folio_lruvec_relock_irqsave(const struct folio *folio,
struct lruvec **lruvecp, unsigned long *flags)
{
if (*lruvecp) {
@@ -1651,7 +1684,7 @@ static inline void mem_cgroup_set_socket_pressure(struct mem_cgroup *memcg)
write_sequnlock_irqrestore(&memcg->socket_pressure_seqlock, flags);
}
-static inline u64 mem_cgroup_get_socket_pressure(struct mem_cgroup *memcg)
+static inline u64 mem_cgroup_get_socket_pressure(const struct mem_cgroup *memcg)
{
unsigned int seq;
u64 val;
@@ -1669,7 +1702,7 @@ static inline void mem_cgroup_set_socket_pressure(struct mem_cgroup *memcg)
WRITE_ONCE(memcg->socket_pressure, jiffies + HZ);
}
-static inline u64 mem_cgroup_get_socket_pressure(struct mem_cgroup *memcg)
+static inline u64 mem_cgroup_get_socket_pressure(const struct mem_cgroup *memcg)
{
return READ_ONCE(memcg->socket_pressure);
}
@@ -1736,7 +1769,7 @@ void __memcg_kmem_uncharge_page(struct page *page, int order);
* needs to be used outside of the local scope.
*/
struct obj_cgroup *current_obj_cgroup(void);
-struct obj_cgroup *get_obj_cgroup_from_folio(struct folio *folio);
+struct obj_cgroup *get_obj_cgroup_from_folio(const struct folio *folio);
static inline struct obj_cgroup *get_obj_cgroup_from_current(void)
{
@@ -1782,7 +1815,7 @@ static inline void memcg_kmem_uncharge_page(struct page *page, int order)
* A helper for accessing memcg's kmem_id, used for getting
* corresponding LRU lists.
*/
-static inline int memcg_kmem_id(struct mem_cgroup *memcg)
+static inline int memcg_kmem_id(const struct mem_cgroup *memcg)
{
return memcg ? memcg->kmemcg_id : -1;
}
@@ -1839,7 +1872,7 @@ static inline void __memcg_kmem_uncharge_page(struct page *page, int order)
{
}
-static inline struct obj_cgroup *get_obj_cgroup_from_folio(struct folio *folio)
+static inline struct obj_cgroup *get_obj_cgroup_from_folio(const struct folio *folio)
{
return NULL;
}
@@ -1854,7 +1887,7 @@ static inline bool memcg_kmem_online(void)
return false;
}
-static inline int memcg_kmem_id(struct mem_cgroup *memcg)
+static inline int memcg_kmem_id(const struct mem_cgroup *memcg)
{
return -1;
}
@@ -1870,7 +1903,7 @@ static inline void count_objcg_events(struct obj_cgroup *objcg,
{
}
-static inline ino_t page_cgroup_ino(struct page *page)
+static inline ino_t page_cgroup_ino(const struct page *page)
{
return 0;
}
@@ -1890,11 +1923,21 @@ static inline bool memcg_is_dying(struct mem_cgroup *memcg)
}
#endif /* CONFIG_MEMCG */
+#if defined(CONFIG_MEMCG) && defined(CONFIG_LRU_GEN)
+void mem_cgroup_calculate_protection_path(struct mem_cgroup *root,
+ struct mem_cgroup *memcg);
+#else
+static inline void mem_cgroup_calculate_protection_path(struct mem_cgroup *root,
+ struct mem_cgroup *memcg)
+{
+}
+#endif
+
#if defined(CONFIG_MEMCG) && defined(CONFIG_ZSWAP)
bool obj_cgroup_may_zswap(struct obj_cgroup *objcg);
void obj_cgroup_charge_zswap(struct obj_cgroup *objcg, size_t size);
void obj_cgroup_uncharge_zswap(struct obj_cgroup *objcg, size_t size);
-bool mem_cgroup_zswap_writeback_enabled(struct mem_cgroup *memcg);
+bool mem_cgroup_zswap_writeback_enabled(const struct mem_cgroup *memcg);
#else
static inline bool obj_cgroup_may_zswap(struct obj_cgroup *objcg)
{
@@ -1908,7 +1951,7 @@ static inline void obj_cgroup_uncharge_zswap(struct obj_cgroup *objcg,
size_t size)
{
}
-static inline bool mem_cgroup_zswap_writeback_enabled(struct mem_cgroup *memcg)
+static inline bool mem_cgroup_zswap_writeback_enabled(const struct mem_cgroup *memcg)
{
/* if zswap is disabled, do not block pages going to the swapping device */
return true;
@@ -1919,13 +1962,9 @@ static inline bool mem_cgroup_zswap_writeback_enabled(struct mem_cgroup *memcg)
/* Cgroup v1-related declarations */
#ifdef CONFIG_MEMCG_V1
-unsigned long memcg1_soft_limit_reclaim(pg_data_t *pgdat, int order,
- gfp_t gfp_mask,
- unsigned long *total_scanned);
-
bool mem_cgroup_oom_synchronize(bool wait);
-static inline bool task_in_memcg_oom(struct task_struct *p)
+static inline bool task_in_memcg_oom(const struct task_struct *p)
{
return p->memcg_in_oom;
}
@@ -1943,15 +1982,7 @@ static inline void mem_cgroup_exit_user_fault(void)
}
#else /* CONFIG_MEMCG_V1 */
-static inline
-unsigned long memcg1_soft_limit_reclaim(pg_data_t *pgdat, int order,
- gfp_t gfp_mask,
- unsigned long *total_scanned)
-{
- return 0;
-}
-
-static inline bool task_in_memcg_oom(struct task_struct *p)
+static inline bool task_in_memcg_oom(const struct task_struct *p)
{
return false;
}
diff --git a/include/linux/mempool.h b/include/linux/mempool.h
index a0fa6d43e0dc..6da502aef2f7 100644
--- a/include/linux/mempool.h
+++ b/include/linux/mempool.h
@@ -70,6 +70,13 @@ int mempool_alloc_bulk_noprof(struct mempool *pool, void **elem,
#define mempool_alloc_bulk(...) \
alloc_hooks(mempool_alloc_bulk_noprof(__VA_ARGS__))
+/*
+ * Allocate a new element without dipping into the pool's reserves or
+ * waiting. Returns NULL on failure.
+ */
+#define mempool_alloc_noreserve(_pool, _gfp) \
+ alloc_hooks((_pool)->alloc(_gfp, (_pool)->pool_data))
+
void *mempool_alloc_preallocated(struct mempool *pool) __malloc;
void mempool_free(void *element, struct mempool *pool);
unsigned int mempool_free_bulk(struct mempool *pool, void **elem,
diff --git a/include/linux/mfd/88pm886.h b/include/linux/mfd/88pm886.h
index 2c24dd3032ab..9e96d2cb92f5 100644
--- a/include/linux/mfd/88pm886.h
+++ b/include/linux/mfd/88pm886.h
@@ -2,6 +2,7 @@
#ifndef __MFD_88PM886_H
#define __MFD_88PM886_H
+#include <linux/bits.h>
#include <linux/i2c.h>
#include <linux/regmap.h>
@@ -130,6 +131,12 @@
#define PM886_GPADC_INDEX_TO_BIAS_uA(i) (1 + (i) * 5)
/* Battery block register definitions */
+#define PM886_REG_BATTERY_CONFIG1 0x28
+#define PM886_REG_VBUS_EN BIT(7)
+
+#define PM886_REG_BOOST_CONFIG1 0x6b
+#define PM886_REG_BOOST_MASK GENMASK(2, 0)
+
#define PM886_REG_CLS_CONFIG1 0x71
struct pm886_chip {
diff --git a/include/linux/mfd/rohm-bd73800.h b/include/linux/mfd/rohm-bd73800.h
new file mode 100644
index 000000000000..c6c0d453a40d
--- /dev/null
+++ b/include/linux/mfd/rohm-bd73800.h
@@ -0,0 +1,306 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * Copyright 2026 ROHM Semiconductors.
+ *
+ * Author: Matti Vaittinen <matti.vaittinen@fi.rohmeurope.com>
+ */
+
+#ifndef _MFD_BD73800_H
+#define _MFD_BD73800_H
+
+#include <linux/regmap.h>
+
+enum {
+ BD73800_BUCK1 = 0,
+ BD73800_BUCK2,
+ BD73800_BUCK3,
+ BD73800_BUCK4,
+ BD73800_BUCK5,
+ BD73800_BUCK6,
+ BD73800_BUCK7,
+ BD73800_BUCK8,
+ BD73800_LDO1,
+ BD73800_LDO2,
+ BD73800_LDO3,
+ BD73800_LDO4,
+};
+
+/*
+ * All regulators except BUCK 5 have full 8-bit register of valid voltage
+ * values, including 0.
+ */
+#define BD73800_NUM_VOLTS (0xff + 1)
+/*
+ * BUCK 5 has two sets of voltage ranges, both having valid voltage selectors
+ * from 0x0 to 0x7f
+ */
+#define BD73800_BUCK5_VOLTS (0x80 + 0x80)
+
+/* BD73800 interrupts */
+enum {
+ /* INT_STAT_1 register IRQs, ADC and RTC */
+ BD73800_INT_ADC_ACCUM_DONE,
+ BD73800_INT_ADC_ACCUM_OVF,
+ BD73800_INT_ADC_ACCUM_VAL,
+ BD73800_INT_ADC_ACCUM_TW,
+ BD73800_INT_ADC_POW_VAL,
+ BD73800_INT_RTC0,
+ BD73800_INT_RTC1,
+ BD73800_INT_RTC2,
+
+ /* BUCK reg interrupts */
+ /* INT_STAT_2 IRQs */
+ BD73800_INT_BUCK1_DVS_DONE,
+ BD73800_INT_BUCK2_DVS_DONE,
+ BD73800_INT_BUCK3_DVS_DONE,
+ BD73800_INT_BUCK4_DVS_DONE,
+ BD73800_INT_BUCK5_DVS_DONE,
+ BD73800_INT_BUCK6_DVS_DONE,
+ BD73800_INT_BUCK7_DVS_DONE,
+ BD73800_INT_BUCK8_DVS_DONE,
+ /* INT_STAT_3 IRQs */
+ BD73800_INT_BUCK1_OCP,
+ BD73800_INT_BUCK2_OCP,
+ BD73800_INT_BUCK3_OCP,
+ BD73800_INT_BUCK4_OCP,
+ BD73800_INT_BUCK5_OCP,
+ BD73800_INT_BUCK6_OCP,
+ BD73800_INT_BUCK7_OCP,
+ BD73800_INT_BUCK8_OCP,
+
+ /* INT_STAT_4 IRQs, power-button, WDG and reset */
+ BD73800_INT_PBTN_LONG_PRESS,
+ BD73800_INT_PBTN_MID_PRESS,
+ /*
+ * The SHORT_PUSH is generated when button is first pressed (longer
+ * than configured time limit), and then released before the MID_PRESS
+ * time limit. The SHORT_PRESS is generated immediately when button is
+ * pressed for longer than configured limit, whether it is released or
+ * not.
+ */
+ BD73800_INT_PBTN_SHORT_PUSH,
+ BD73800_INT_PBTN_SHORT_PRESS,
+ BD73800_INT_WDG,
+ BD73800_INT_SWRESET,
+ BD73800_INT_SEQ_DONE,
+
+ /* INT_STAT_5 IRQs, GPIO */
+ BD73800_INT_GPIO1,
+ BD73800_INT_GPIO2,
+ BD73800_INT_GPIO3,
+ BD73800_INT_GPIO4,
+};
+
+#define BD73800_MASK_RUN_EN BIT(2)
+#define BD73800_MASK_SUSP_EN BIT(1)
+#define BD73800_MASK_IDLE_EN BIT(0)
+#define BD73800_MASK_VOLT GENMASK(7, 0)
+#define BD73800_MASK_BUCK5_VOLT GENMASK(6, 0)
+#define BD73800_MASK_RAMP_DELAY GENMASK(2, 1)
+#define BD73800_BUCK5_RANGE_MASK BIT(7)
+
+/* BD73800 registers */
+enum {
+ BD73800_REG_PRODUCT_ID = 0x0,
+ BD73800_REG_MANUFACTURER_ID,
+ BD73800_REG_REVISION,
+ BD73800_REG_NVMVERSION,
+ BD73800_REG_POR_REASON,
+ BD73800_REG_RESET_REASON1,
+ BD73800_REG_RESET_REASON2,
+ BD73800_REG_RESET_REASON3,
+ BD73800_REG_POW_STATE,
+ BD73800_REG_WRST_SEL,
+ BD73800_REG_PS_CTRL_1,
+ BD73800_REG_PS_CTRL_2,
+ BD73800_REG_RCVCFG,
+ BD73800_REG_RCVNUM,
+ BD73800_REG_CRDCFG, /* 0x0f, followed by undocumented reg */
+
+ BD73800_REG_BUCK1_ON = 0x11,
+ BD73800_REG_BUCK1_MODE,
+ BD73800_REG_BUCK1_VOLT_RUN,
+ BD73800_REG_BUCK1_VOLT_IDLE,
+ BD73800_REG_BUCK1_VOLT_SUSP, /* 0x15, followed by undocumented reg */
+
+ BD73800_REG_BUCK2_ON = 0x17,
+ BD73800_REG_BUCK2_MODE,
+ BD73800_REG_BUCK2_VOLT_RUN,
+ BD73800_REG_BUCK2_VOLT_IDLE,
+ BD73800_REG_BUCK2_VOLT_SUSP, /* 0x1b */
+
+ BD73800_REG_BUCK3_ON = 0x1d,
+ BD73800_REG_BUCK3_MODE,
+ BD73800_REG_BUCK3_VOLT_RUN,
+ BD73800_REG_BUCK3_VOLT_IDLE,
+ BD73800_REG_BUCK3_VOLT_SUSP, /* 0x21 */
+
+ BD73800_REG_BUCK4_ON = 0x23,
+ BD73800_REG_BUCK4_MODE,
+ BD73800_REG_BUCK4_VOLT_RUN,
+ BD73800_REG_BUCK4_VOLT_IDLE,
+ BD73800_REG_BUCK4_VOLT_SUSP, /* 0x27 */
+
+ BD73800_REG_BUCK5_ON = 0x29,
+ BD73800_REG_BUCK5_MODE,
+ BD73800_REG_BUCK5_VOLT_RUN,
+ BD73800_REG_BUCK5_VOLT_IDLE,
+ BD73800_REG_BUCK5_VOLT_SUSP, /* 0x2d */
+
+ BD73800_REG_BUCK6_ON = 0x2f,
+ BD73800_REG_BUCK6_MODE,
+ BD73800_REG_BUCK6_VOLT_RUN,
+ BD73800_REG_BUCK6_VOLT_IDLE,
+ BD73800_REG_BUCK6_VOLT_SUSP, /* 0x33 */
+
+ BD73800_REG_BUCK7_ON = 0x35,
+ BD73800_REG_BUCK7_MODE,
+ BD73800_REG_BUCK7_VOLT_RUN,
+ BD73800_REG_BUCK7_VOLT_IDLE,
+ BD73800_REG_BUCK7_VOLT_SUSP, /* 0x39 */
+
+ BD73800_REG_BUCK8_ON = 0x3b,
+ BD73800_REG_BUCK8_MODE,
+ BD73800_REG_BUCK8_VOLT_RUN,
+ BD73800_REG_BUCK8_VOLT_IDLE,
+ BD73800_REG_BUCK8_VOLT_SUSP, /* 0x3f */
+
+ BD73800_REG_LDO1_ON = 0x41,
+ BD73800_REG_LDO1_VOLT,
+ BD73800_REG_LDO1_MODE,
+ BD73800_REG_LDO2_ON,
+ BD73800_REG_LDO2_VOLT,
+ BD73800_REG_LDO2_MODE,
+ BD73800_REG_LDO3_ON,
+ BD73800_REG_LDO3_VOLT,
+ BD73800_REG_LDO3_MODE,
+ BD73800_REG_LDO4_ON,
+ BD73800_REG_LDO4_VOLT,
+ BD73800_REG_LDO4_MODE, /* 0x4c */
+
+ BD73800_REG_GPO_OUT = 0x4e,
+ BD73800_REG_OUT32K = 0x50,
+ BD73800_REG_RTC_SEC,
+ BD73800_REG_RTC_MIN,
+ BD73800_REG_RTC_HOUR,
+ BD73800_REG_RTC_WEEK,
+ BD73800_REG_RTC_DAY,
+ BD73800_REG_RTC_MONTH,
+ BD73800_REG_RTC_YEAR,
+ BD73800_REG_RTC_ALM0_SEC,
+ BD73800_REG_RTC_ALM0_MIN,
+ BD73800_REG_RTC_ALM0_HOUR,
+ BD73800_REG_RTC_ALM0_WEEK,
+ BD73800_REG_RTC_ALM0_DAY,
+ BD73800_REG_RTC_ALM0_MONTH,
+ BD73800_REG_RTC_ALM0_YEAR,
+ BD73800_REG_RTC_ALM1_SEC,
+ BD73800_REG_RTC_ALM1_MIN,
+ BD73800_REG_RTC_ALM1_HOUR,
+ BD73800_REG_RTC_ALM1_WEEK,
+ BD73800_REG_RTC_ALM1_DAY,
+ BD73800_REG_RTC_ALM1_MONTH,
+ BD73800_REG_RTC_ALM1_YEAR,
+ BD73800_REG_RTC_ALM2,
+ BD73800_REG_RTC_CONF, /* 0x69 */
+
+ BD73800_REG_ADC_CTRL_1 = 0x6b,
+ BD73800_REG_ADC_CTRL_2,
+ BD73800_REG_ADC_ACCUM_NUM2,
+ BD73800_REG_ADC_ACCUM_NUM1,
+ BD73800_REG_ADC_ACCUM_NUM0,
+ BD73800_REG_ADC_ACCUM_KICK,
+ BD73800_REG_ADC_ACCUM_CNT2,
+ BD73800_REG_ADC_ACCUM_CNT1,
+ BD73800_REG_ADC_ACCUM_CNT0,
+ BD73800_REG_ADC_ACCUM_VAL2,
+ BD73800_REG_ADC_ACCUM_VAL1,
+ BD73800_REG_ADC_ACCUM_VAL0,
+ BD73800_REG_ADC_VOL_VAL1,
+ BD73800_REG_ADC_VOL_VAL0,
+ BD73800_REG_ADC_CUR_VAL1,
+ BD73800_REG_ADC_CUR_VAL0,
+ BD73800_REG_ADC_POW_VAL1,
+ BD73800_REG_ADC_POW_VAL0,
+ BD73800_REG_ADC_TEMP_VAL1,
+ BD73800_REG_ADC_TEMP_VAL0,
+ BD73800_REG_ADC_ACCUM_VAL_INT_TH4,
+ BD73800_REG_ADC_ACCUM_VAL_INT_TH3,
+ BD73800_REG_ADC_ACCUM_VAL_INT_TH2,
+ BD73800_REG_ADC_ACCUM_VAL_INT_TH1,
+ BD73800_REG_ADC_ACCUM_VAL_INT_TH0,
+ BD73800_REG_ADC_WARN_TEMP_INT_TH1,
+ BD73800_REG_ADC_WARN_TEMP_INT_TH0,
+ BD73800_REG_ADC_POW_VAL_INT_TH1,
+ BD73800_REG_ADC_POW_VAL_INT_TH0, /* 0x89 */
+
+ BD73800_REG_PBTN_CONF = 0x8b,
+
+ BD73800_REG_INT_MAIN_EN = 0x8f,
+ BD73800_REG_INT_1_EN,
+ BD73800_REG_INT_2_EN,
+ BD73800_REG_INT_3_EN,
+ BD73800_REG_INT_4_EN,
+ BD73800_REG_INT_5_EN, /* 0x94 */
+
+ BD73800_REG_INT_MAIN_STAT = 0x96,
+ BD73800_REG_INT_1_STAT,
+ BD73800_REG_INT_2_STAT,
+ BD73800_REG_INT_3_STAT,
+ BD73800_REG_INT_4_STAT,
+ BD73800_REG_INT_5_STAT, /* 0x9b */
+
+ BD73800_REG_INT_MAIN_SRC = 0x9d,
+ BD73800_REG_INT_1_SRC,
+ BD73800_REG_INT_2_SRC,
+ BD73800_REG_INT_3_SRC,
+ BD73800_REG_INT_4_SRC,
+ BD73800_REG_INT_5_SRC, /* 0xa2 */
+
+ BD73800_REG_RST_MASK = 0xaf,
+ BD73800_MAX_REGISTER,
+};
+
+#define BD73800_REG_RTC_START BD73800_REG_RTC_SEC
+#define BD73800_REG_RTC_ALM_START BD73800_REG_RTC_ALM0_SEC
+
+/* BD73800 IRQ register masks */
+
+#define BD73800_INT_MAIN_EN_ALL GENMASK(4, 0)
+#define BD73800_INT_ADC_ACCUM_DONE_MASK BIT(0)
+#define BD73800_INT_ADC_ACCUM_OVF_MASK BIT(1)
+#define BD73800_INT_ADC_ACCUM_VAL_MASK BIT(2)
+#define BD73800_INT_ADC_ACCUM_TW_MASK BIT(3)
+#define BD73800_INT_ADC_POW_VAL_MASK BIT(4)
+#define BD73800_INT_RTC0_MASK BIT(5)
+#define BD73800_INT_RTC1_MASK BIT(6)
+#define BD73800_INT_RTC2_MASK BIT(7)
+#define BD73800_INT_BUCK1_DVS_DONE_MASK BIT(0)
+#define BD73800_INT_BUCK2_DVS_DONE_MASK BIT(1)
+#define BD73800_INT_BUCK3_DVS_DONE_MASK BIT(2)
+#define BD73800_INT_BUCK4_DVS_DONE_MASK BIT(3)
+#define BD73800_INT_BUCK5_DVS_DONE_MASK BIT(4)
+#define BD73800_INT_BUCK6_DVS_DONE_MASK BIT(5)
+#define BD73800_INT_BUCK7_DVS_DONE_MASK BIT(6)
+#define BD73800_INT_BUCK8_DVS_DONE_MASK BIT(7)
+#define BD73800_INT_BUCK1_OCP_MASK BIT(0)
+#define BD73800_INT_BUCK2_OCP_MASK BIT(1)
+#define BD73800_INT_BUCK3_OCP_MASK BIT(2)
+#define BD73800_INT_BUCK4_OCP_MASK BIT(3)
+#define BD73800_INT_BUCK5_OCP_MASK BIT(4)
+#define BD73800_INT_BUCK6_OCP_MASK BIT(5)
+#define BD73800_INT_BUCK7_OCP_MASK BIT(6)
+#define BD73800_INT_BUCK8_OCP_MASK BIT(7)
+#define BD73800_INT_PBTN_LONG_PRESS_MASK BIT(0)
+#define BD73800_INT_PBTN_MID_PRESS_MASK BIT(1)
+#define BD73800_INT_PBTN_SHORT_PUSH_MASK BIT(2)
+#define BD73800_INT_PBTN_SHORT_PRESS_MASK BIT(3)
+#define BD73800_INT_WDG_MASK BIT(4)
+#define BD73800_INT_SWRESET_MASK BIT(5)
+#define BD73800_INT_SEQ_DONE_MASK BIT(6)
+#define BD73800_INT_GPIO1_MASK BIT(0)
+#define BD73800_INT_GPIO2_MASK BIT(1)
+#define BD73800_INT_GPIO3_MASK BIT(2)
+#define BD73800_INT_GPIO4_MASK BIT(3)
+
+#endif /* _MFD_BD73800_H */
diff --git a/include/linux/mfd/rohm-generic.h b/include/linux/mfd/rohm-generic.h
index 0a284919a6c3..3ec87428ee97 100644
--- a/include/linux/mfd/rohm-generic.h
+++ b/include/linux/mfd/rohm-generic.h
@@ -17,6 +17,7 @@ enum rohm_chip_type {
ROHM_CHIP_TYPE_BD71837,
ROHM_CHIP_TYPE_BD71847,
ROHM_CHIP_TYPE_BD72720,
+ ROHM_CHIP_TYPE_BD73800,
ROHM_CHIP_TYPE_BD96801,
ROHM_CHIP_TYPE_BD96802,
ROHM_CHIP_TYPE_BD96805,
diff --git a/include/linux/mhi.h b/include/linux/mhi.h
index 8616bacd8675..65e8a397cc50 100644
--- a/include/linux/mhi.h
+++ b/include/linux/mhi.h
@@ -687,7 +687,7 @@ int mhi_pm_resume(struct mhi_controller *mhi_cntrl);
* Resume the device irrespective of its MHI state. As per the MHI spec, devices
* has to be in M3 state during resume. But some devices seem to be in a
* different MHI state other than M3 but they continue working fine if allowed.
- * This API is intented to be used for such devices.
+ * This API is intended to be used for such devices.
*
* Return: 0 if the resume succeeds, a negative error code otherwise
*/
diff --git a/include/linux/mhi_ep.h b/include/linux/mhi_ep.h
index f6383a57a872..852f331f03fd 100644
--- a/include/linux/mhi_ep.h
+++ b/include/linux/mhi_ep.h
@@ -304,4 +304,20 @@ bool mhi_ep_queue_is_empty(struct mhi_ep_device *mhi_dev, enum dma_data_directio
*/
int mhi_ep_queue_skb(struct mhi_ep_device *mhi_dev, struct sk_buff *skb);
+/**
+ * mhi_ep_queue_buf - Transfer buffer contents to host over MHI Endpoint
+ * @mhi_dev: Device associated with the DL channel
+ * @buf: Buffer to be queued. On success, ownership passes to the MHI stack;
+ * the caller must not free @buf until the DL transfer callback fires
+ * with result->buf_addr equal to @buf. On failure, the caller retains
+ * ownership and must free @buf.
+ * Note: if @len spans multiple host DL TREs, the DL transfer callback
+ * fires once per TRE, each time with result->buf_addr equal to @buf.
+ * @len: Size of the buffer
+ *
+ * Return: 0 if the buffer contents have been transferred successfully, a
+ * negative error code otherwise.
+ */
+int mhi_ep_queue_buf(struct mhi_ep_device *mhi_dev, void *buf, size_t len);
+
#endif
diff --git a/include/linux/micrel_phy.h b/include/linux/micrel_phy.h
index 9c6f9817383f..bb71b2510c2c 100644
--- a/include/linux/micrel_phy.h
+++ b/include/linux/micrel_phy.h
@@ -47,11 +47,6 @@
#define MICREL_PHY_FXEN BIT(1)
#define MICREL_KSZ8_P1_ERRATA BIT(2)
-#define MICREL_KSZ9021_EXTREG_CTRL 0xB
-#define MICREL_KSZ9021_EXTREG_DATA_WRITE 0xC
-#define MICREL_KSZ9021_RGMII_CLK_CTRL_PAD_SCEW 0x104
-#define MICREL_KSZ9021_RGMII_RX_DATA_PAD_SCEW 0x105
-
/* Device specific MII_BMCR (Reg 0) bits */
/* 1 = HP Auto MDI/MDI-X mode, 0 = Microchip Auto MDI/MDI-X mode */
#define KSZ886X_BMCR_HP_MDIX BIT(5)
diff --git a/include/linux/mlx5/cq.h b/include/linux/mlx5/cq.h
index 9d47cdc727ad..a1c14479e462 100644
--- a/include/linux/mlx5/cq.h
+++ b/include/linux/mlx5/cq.h
@@ -81,16 +81,6 @@ enum {
enum {
MLX5_CQE_OWNER_MASK = 1,
- MLX5_CQE_REQ = 0,
- MLX5_CQE_RESP_WR_IMM = 1,
- MLX5_CQE_RESP_SEND = 2,
- MLX5_CQE_RESP_SEND_IMM = 3,
- MLX5_CQE_RESP_SEND_INV = 4,
- MLX5_CQE_RESIZE_CQ = 5,
- MLX5_CQE_SIG_ERR = 12,
- MLX5_CQE_REQ_ERR = 13,
- MLX5_CQE_RESP_ERR = 14,
- MLX5_CQE_INVALID = 15,
};
enum {
diff --git a/include/linux/mlx5/data_direct.h b/include/linux/mlx5/data_direct.h
new file mode 100644
index 000000000000..4cff5ff5489d
--- /dev/null
+++ b/include/linux/mlx5/data_direct.h
@@ -0,0 +1,47 @@
+/* SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB */
+/*
+ * Copyright (c) 2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved
+ */
+
+#ifndef _MLX5_DATA_DIRECT_H
+#define _MLX5_DATA_DIRECT_H
+
+#include <linux/compiler.h>
+#include <linux/list.h>
+
+struct device;
+struct mlx5_core_dev;
+struct notifier_block;
+struct pci_dev;
+
+enum mlx5_data_direct_event {
+ MLX5_DATA_DIRECT_UNBIND,
+};
+
+struct mlx5_data_direct_dev {
+ struct device *device;
+ struct pci_dev *pdev;
+ char *vuid;
+ struct list_head list;
+};
+
+struct mlx5_data_direct {
+ struct mlx5_data_direct_dev *dev;
+ u32 pdn;
+ u32 mkey;
+ u32 mkey_ro;
+ u8 mkey_ro_valid :1;
+};
+
+static inline struct mlx5_data_direct_dev *
+mlx5_data_direct_get_dev(struct mlx5_data_direct *dd)
+{
+ return dd ? READ_ONCE(dd->dev) : NULL;
+}
+
+int mlx5_data_direct_register(struct mlx5_core_dev *mdev,
+ struct notifier_block *nb);
+void mlx5_data_direct_unregister(struct mlx5_core_dev *mdev,
+ struct notifier_block *nb);
+
+#endif
diff --git a/include/linux/mlx5/device.h b/include/linux/mlx5/device.h
index 8cb321a9fb3d..37727b5ab78f 100644
--- a/include/linux/mlx5/device.h
+++ b/include/linux/mlx5/device.h
@@ -36,6 +36,7 @@
#include <linux/types.h>
#include <rdma/ib_verbs.h>
#include <linux/mlx5/mlx5_ifc.h>
+#include <linux/mlx5/mlx5_ifc_macros.h>
#include <linux/bitfield.h>
#if defined(__LITTLE_ENDIAN)
@@ -46,122 +47,6 @@
#error Host endianness not defined
#endif
-/* helper macros */
-#define __mlx5_nullp(typ) ((struct mlx5_ifc_##typ##_bits *)0)
-#define __mlx5_bit_sz(typ, fld) sizeof(__mlx5_nullp(typ)->fld)
-#define __mlx5_bit_off(typ, fld) (offsetof(struct mlx5_ifc_##typ##_bits, fld))
-#define __mlx5_16_off(typ, fld) (__mlx5_bit_off(typ, fld) / 16)
-#define __mlx5_dw_off(typ, fld) (__mlx5_bit_off(typ, fld) / 32)
-#define __mlx5_64_off(typ, fld) (__mlx5_bit_off(typ, fld) / 64)
-#define __mlx5_16_bit_off(typ, fld) (16 - __mlx5_bit_sz(typ, fld) - (__mlx5_bit_off(typ, fld) & 0xf))
-#define __mlx5_dw_bit_off(typ, fld) (32 - __mlx5_bit_sz(typ, fld) - (__mlx5_bit_off(typ, fld) & 0x1f))
-#define __mlx5_mask(typ, fld) ((u32)((1ull << __mlx5_bit_sz(typ, fld)) - 1))
-#define __mlx5_dw_mask(typ, fld) (__mlx5_mask(typ, fld) << __mlx5_dw_bit_off(typ, fld))
-#define __mlx5_mask16(typ, fld) ((u16)((1ull << __mlx5_bit_sz(typ, fld)) - 1))
-#define __mlx5_16_mask(typ, fld) (__mlx5_mask16(typ, fld) << __mlx5_16_bit_off(typ, fld))
-#define __mlx5_st_sz_bits(typ) sizeof(struct mlx5_ifc_##typ##_bits)
-
-#define MLX5_FLD_SZ_BYTES(typ, fld) (__mlx5_bit_sz(typ, fld) / 8)
-#define MLX5_ST_SZ_BYTES(typ) (sizeof(struct mlx5_ifc_##typ##_bits) / 8)
-#define MLX5_ST_SZ_DW(typ) (sizeof(struct mlx5_ifc_##typ##_bits) / 32)
-#define MLX5_ST_SZ_QW(typ) (sizeof(struct mlx5_ifc_##typ##_bits) / 64)
-#define MLX5_UN_SZ_BYTES(typ) (sizeof(union mlx5_ifc_##typ##_bits) / 8)
-#define MLX5_UN_SZ_DW(typ) (sizeof(union mlx5_ifc_##typ##_bits) / 32)
-#define MLX5_BYTE_OFF(typ, fld) (__mlx5_bit_off(typ, fld) / 8)
-#define MLX5_ADDR_OF(typ, p, fld) ((void *)((u8 *)(p) + MLX5_BYTE_OFF(typ, fld)))
-
-/* insert a value to a struct */
-#define MLX5_SET(typ, p, fld, v) do { \
- u32 _v = v; \
- BUILD_BUG_ON(__mlx5_st_sz_bits(typ) % 32); \
- *((__be32 *)(p) + __mlx5_dw_off(typ, fld)) = \
- cpu_to_be32((be32_to_cpu(*((__be32 *)(p) + __mlx5_dw_off(typ, fld))) & \
- (~__mlx5_dw_mask(typ, fld))) | (((_v) & __mlx5_mask(typ, fld)) \
- << __mlx5_dw_bit_off(typ, fld))); \
-} while (0)
-
-#define MLX5_ARRAY_SET(typ, p, fld, idx, v) do { \
- BUILD_BUG_ON(__mlx5_bit_off(typ, fld) % 32); \
- MLX5_SET(typ, p, fld[idx], v); \
-} while (0)
-
-#define MLX5_SET_TO_ONES(typ, p, fld) do { \
- BUILD_BUG_ON(__mlx5_st_sz_bits(typ) % 32); \
- *((__be32 *)(p) + __mlx5_dw_off(typ, fld)) = \
- cpu_to_be32((be32_to_cpu(*((__be32 *)(p) + __mlx5_dw_off(typ, fld))) & \
- (~__mlx5_dw_mask(typ, fld))) | ((__mlx5_mask(typ, fld)) \
- << __mlx5_dw_bit_off(typ, fld))); \
-} while (0)
-
-#define MLX5_GET(typ, p, fld) ((be32_to_cpu(*((__be32 *)(p) +\
-__mlx5_dw_off(typ, fld))) >> __mlx5_dw_bit_off(typ, fld)) & \
-__mlx5_mask(typ, fld))
-
-#define MLX5_GET_PR(typ, p, fld) ({ \
- u32 ___t = MLX5_GET(typ, p, fld); \
- pr_debug(#fld " = 0x%x\n", ___t); \
- ___t; \
-})
-
-#define __MLX5_SET64(typ, p, fld, v) do { \
- BUILD_BUG_ON(__mlx5_bit_sz(typ, fld) != 64); \
- *((__be64 *)(p) + __mlx5_64_off(typ, fld)) = cpu_to_be64(v); \
-} while (0)
-
-#define MLX5_SET64(typ, p, fld, v) do { \
- BUILD_BUG_ON(__mlx5_bit_off(typ, fld) % 64); \
- __MLX5_SET64(typ, p, fld, v); \
-} while (0)
-
-#define MLX5_ARRAY_SET64(typ, p, fld, idx, v) do { \
- BUILD_BUG_ON(__mlx5_bit_off(typ, fld) % 64); \
- __MLX5_SET64(typ, p, fld[idx], v); \
-} while (0)
-
-#define MLX5_GET64(typ, p, fld) be64_to_cpu(*((__be64 *)(p) + __mlx5_64_off(typ, fld)))
-
-#define MLX5_GET64_PR(typ, p, fld) ({ \
- u64 ___t = MLX5_GET64(typ, p, fld); \
- pr_debug(#fld " = 0x%llx\n", ___t); \
- ___t; \
-})
-
-#define MLX5_GET16(typ, p, fld) ((be16_to_cpu(*((__be16 *)(p) +\
-__mlx5_16_off(typ, fld))) >> __mlx5_16_bit_off(typ, fld)) & \
-__mlx5_mask16(typ, fld))
-
-#define MLX5_SET16(typ, p, fld, v) do { \
- u16 _v = v; \
- BUILD_BUG_ON(__mlx5_st_sz_bits(typ) % 16); \
- *((__be16 *)(p) + __mlx5_16_off(typ, fld)) = \
- cpu_to_be16((be16_to_cpu(*((__be16 *)(p) + __mlx5_16_off(typ, fld))) & \
- (~__mlx5_16_mask(typ, fld))) | (((_v) & __mlx5_mask16(typ, fld)) \
- << __mlx5_16_bit_off(typ, fld))); \
-} while (0)
-
-/* Big endian getters */
-#define MLX5_GET64_BE(typ, p, fld) (*((__be64 *)(p) +\
- __mlx5_64_off(typ, fld)))
-
-#define MLX5_GET_BE(type_t, typ, p, fld) ({ \
- type_t tmp; \
- switch (sizeof(tmp)) { \
- case sizeof(u8): \
- tmp = (__force type_t)MLX5_GET(typ, p, fld); \
- break; \
- case sizeof(u16): \
- tmp = (__force type_t)cpu_to_be16(MLX5_GET(typ, p, fld)); \
- break; \
- case sizeof(u32): \
- tmp = (__force type_t)cpu_to_be32(MLX5_GET(typ, p, fld)); \
- break; \
- case sizeof(u64): \
- tmp = (__force type_t)MLX5_GET64_BE(typ, p, fld); \
- break; \
- } \
- tmp; \
- })
-
enum mlx5_inline_modes {
MLX5_INLINE_MODE_NONE,
MLX5_INLINE_MODE_L2,
@@ -172,7 +57,7 @@ enum mlx5_inline_modes {
enum {
MLX5_MAX_COMMANDS = 32,
MLX5_CMD_DATA_BLOCK_SIZE = 512,
- MLX5_PCI_CMD_XPORT = 7,
+ MLX5_PCI_CMD_XPORT = MLX5_CMD_QUEUE_ENTRY_TYPE_PCIE_CMD_IF_TRANSPORT,
MLX5_MKEY_BSF_OCTO_SIZE = 4,
MLX5_MAX_PSVS = 4,
};
@@ -308,63 +193,6 @@ enum {
MLX5_EVENT_QUEUE_TYPE_DCT = 6,
};
-/* mlx5 components can subscribe to any one of these events via
- * mlx5_eq_notifier_register API.
- */
-enum mlx5_event {
- /* Special value to subscribe to any event */
- MLX5_EVENT_TYPE_NOTIFY_ANY = 0x0,
- /* HW events enum start: comp events are not subscribable */
- MLX5_EVENT_TYPE_COMP = 0x0,
- /* HW Async events enum start: subscribable events */
- MLX5_EVENT_TYPE_PATH_MIG = 0x01,
- MLX5_EVENT_TYPE_COMM_EST = 0x02,
- MLX5_EVENT_TYPE_SQ_DRAINED = 0x03,
- MLX5_EVENT_TYPE_SRQ_LAST_WQE = 0x13,
- MLX5_EVENT_TYPE_SRQ_RQ_LIMIT = 0x14,
-
- MLX5_EVENT_TYPE_CQ_ERROR = 0x04,
- MLX5_EVENT_TYPE_WQ_CATAS_ERROR = 0x05,
- MLX5_EVENT_TYPE_PATH_MIG_FAILED = 0x07,
- MLX5_EVENT_TYPE_WQ_INVAL_REQ_ERROR = 0x10,
- MLX5_EVENT_TYPE_WQ_ACCESS_ERROR = 0x11,
- MLX5_EVENT_TYPE_SRQ_CATAS_ERROR = 0x12,
- MLX5_EVENT_TYPE_OBJECT_CHANGE = 0x27,
-
- MLX5_EVENT_TYPE_INTERNAL_ERROR = 0x08,
- MLX5_EVENT_TYPE_PORT_CHANGE = 0x09,
- MLX5_EVENT_TYPE_GPIO_EVENT = 0x15,
- MLX5_EVENT_TYPE_PORT_MODULE_EVENT = 0x16,
- MLX5_EVENT_TYPE_TEMP_WARN_EVENT = 0x17,
- MLX5_EVENT_TYPE_XRQ_ERROR = 0x18,
- MLX5_EVENT_TYPE_REMOTE_CONFIG = 0x19,
- MLX5_EVENT_TYPE_GENERAL_EVENT = 0x22,
- MLX5_EVENT_TYPE_MONITOR_COUNTER = 0x24,
- MLX5_EVENT_TYPE_PPS_EVENT = 0x25,
-
- MLX5_EVENT_TYPE_DB_BF_CONGESTION = 0x1a,
- MLX5_EVENT_TYPE_STALL_EVENT = 0x1b,
-
- MLX5_EVENT_TYPE_CMD = 0x0a,
- MLX5_EVENT_TYPE_PAGE_REQUEST = 0xb,
-
- MLX5_EVENT_TYPE_PAGE_FAULT = 0xc,
- MLX5_EVENT_TYPE_NIC_VPORT_CHANGE = 0xd,
-
- MLX5_EVENT_TYPE_ESW_FUNCTIONS_CHANGED = 0xe,
- MLX5_EVENT_TYPE_VHCA_STATE_CHANGE = 0xf,
-
- MLX5_EVENT_TYPE_DCT_DRAINED = 0x1c,
- MLX5_EVENT_TYPE_DCT_KEY_VIOLATION = 0x1d,
-
- MLX5_EVENT_TYPE_FPGA_ERROR = 0x20,
- MLX5_EVENT_TYPE_FPGA_QP_ERROR = 0x21,
-
- MLX5_EVENT_TYPE_DEVICE_TRACER = 0x26,
-
- MLX5_EVENT_TYPE_MAX = 0x100,
-};
-
enum mlx5_driver_event {
MLX5_DRIVER_EVENT_TYPE_TRAP = 0,
MLX5_DRIVER_EVENT_UPLINK_NETDEV,
@@ -420,22 +248,6 @@ enum {
};
enum {
- MLX5_OPCODE_NOP = 0x00,
- MLX5_OPCODE_SEND_INVAL = 0x01,
- MLX5_OPCODE_RDMA_WRITE = 0x08,
- MLX5_OPCODE_RDMA_WRITE_IMM = 0x09,
- MLX5_OPCODE_SEND = 0x0a,
- MLX5_OPCODE_SEND_IMM = 0x0b,
- MLX5_OPCODE_LSO = 0x0e,
- MLX5_OPCODE_RDMA_READ = 0x10,
- MLX5_OPCODE_ATOMIC_CS = 0x11,
- MLX5_OPCODE_ATOMIC_FA = 0x12,
- MLX5_OPCODE_ATOMIC_MASKED_CS = 0x14,
- MLX5_OPCODE_ATOMIC_MASKED_FA = 0x15,
- MLX5_OPCODE_BIND_MW = 0x18,
- MLX5_OPCODE_CONFIG_CMD = 0x1f,
- MLX5_OPCODE_ENHANCED_MPSW = 0x29,
-
MLX5_RECV_OPCODE_RDMA_WRITE_IMM = 0x00,
MLX5_RECV_OPCODE_SEND = 0x01,
MLX5_RECV_OPCODE_SEND_IMM = 0x02,
@@ -443,19 +255,6 @@ enum {
MLX5_CQE_OPCODE_ERROR = 0x1e,
MLX5_CQE_OPCODE_RESIZE = 0x16,
-
- MLX5_OPCODE_SET_PSV = 0x20,
- MLX5_OPCODE_GET_PSV = 0x21,
- MLX5_OPCODE_CHECK_PSV = 0x22,
- MLX5_OPCODE_DUMP = 0x23,
- MLX5_OPCODE_RGET_PSV = 0x26,
- MLX5_OPCODE_RCHECK_PSV = 0x27,
-
- MLX5_OPCODE_UMR = 0x25,
-
- MLX5_OPCODE_FLOW_TBL_ACCESS = 0x2c,
-
- MLX5_OPCODE_ACCESS_ASO = 0x2d,
};
enum {
@@ -1224,12 +1023,6 @@ enum mlx5_flex_parser_protos {
/* MLX5 DEV CAPs */
-/* TODO: EAT.ME */
-enum mlx5_cap_mode {
- HCA_CAP_OPMOD_GET_MAX = 0,
- HCA_CAP_OPMOD_GET_CUR = 1,
-};
-
/* Any new cap addition must update mlx5_hca_caps_alloc() to allocate
* capability memory.
*/
@@ -1508,26 +1301,6 @@ enum mlx5_qcam_feature_groups {
MLX5_GET(psp_cap, (mdev)->caps.hca[MLX5_CAP_PSP]->cur, cap)
enum {
- MLX5_CMD_STAT_OK = 0x0,
- MLX5_CMD_STAT_INT_ERR = 0x1,
- MLX5_CMD_STAT_BAD_OP_ERR = 0x2,
- MLX5_CMD_STAT_BAD_PARAM_ERR = 0x3,
- MLX5_CMD_STAT_BAD_SYS_STATE_ERR = 0x4,
- MLX5_CMD_STAT_BAD_RES_ERR = 0x5,
- MLX5_CMD_STAT_RES_BUSY = 0x6,
- MLX5_CMD_STAT_NOT_READY = 0x7,
- MLX5_CMD_STAT_LIM_ERR = 0x8,
- MLX5_CMD_STAT_BAD_RES_STATE_ERR = 0x9,
- MLX5_CMD_STAT_IX_ERR = 0xa,
- MLX5_CMD_STAT_NO_RES_ERR = 0xf,
- MLX5_CMD_STAT_BAD_INP_LEN_ERR = 0x50,
- MLX5_CMD_STAT_BAD_OUTP_LEN_ERR = 0x51,
- MLX5_CMD_STAT_BAD_QP_STATE_ERR = 0x10,
- MLX5_CMD_STAT_BAD_PKT_ERR = 0x30,
- MLX5_CMD_STAT_BAD_SIZE_OUTS_CQES_ERR = 0x40,
-};
-
-enum {
MLX5_IEEE_802_3_COUNTERS_GROUP = 0x0,
MLX5_RFC_2863_COUNTERS_GROUP = 0x1,
MLX5_RFC_2819_COUNTERS_GROUP = 0x2,
diff --git a/include/linux/mlx5/driver.h b/include/linux/mlx5/driver.h
index 83d0a83bbfbc..abb99371ff13 100644
--- a/include/linux/mlx5/driver.h
+++ b/include/linux/mlx5/driver.h
@@ -707,6 +707,7 @@ struct mlx5_rsvd_gids {
struct mlx5_clock;
struct mlx5_clock_dev_state;
+struct mlx5_data_direct;
struct mlx5_dm;
struct mlx5_fw_tracer;
struct mlx5_vxlan;
@@ -801,6 +802,7 @@ struct mlx5_core_dev {
/* sync write combining state */
struct mutex wc_state_lock;
struct devlink *shd;
+ struct mlx5_data_direct *data_direct;
};
struct mlx5_db {
@@ -1395,4 +1397,10 @@ static inline struct net *mlx5_core_net(struct mlx5_core_dev *dev)
#define MLX5_SW_IMAGE_GUID_MAX_BYTES 9
+static inline bool mlx5_data_direct_supported(struct mlx5_core_dev *mdev)
+{
+ return MLX5_CAP_GEN(mdev, data_direct) &&
+ MLX5_CAP_GEN_2(mdev, query_vuid);
+}
+
#endif /* MLX5_DRIVER_H */
diff --git a/include/linux/mlx5/eswitch.h b/include/linux/mlx5/eswitch.h
index a0dd162baa78..03d3620141c8 100644
--- a/include/linux/mlx5/eswitch.h
+++ b/include/linux/mlx5/eswitch.h
@@ -222,6 +222,9 @@ static inline bool is_mdev_switchdev_mode(struct mlx5_core_dev *dev)
/* The returned number is valid only when the dev is eswitch manager. */
static inline u16 mlx5_eswitch_manager_vport(struct mlx5_core_dev *dev)
{
+ if (MLX5_CAP_ESW(dev, esw_manager_vport_number_valid))
+ return MLX5_CAP_ESW(dev, esw_manager_vport_number);
+
return mlx5_core_is_ecpf_esw_manager(dev) ?
MLX5_VPORT_ECPF : MLX5_VPORT_HOST_PF;
}
diff --git a/include/linux/mlx5/mlx5_ifc.h b/include/linux/mlx5/mlx5_ifc.h
index 12b9a81e5621..697fc9387b73 100644
--- a/include/linux/mlx5/mlx5_ifc.h
+++ b/include/linux/mlx5/mlx5_ifc.h
@@ -929,7 +929,7 @@ struct mlx5_ifc_flow_table_nic_cap_bits {
struct mlx5_ifc_port_selection_cap_bits {
u8 reserved_at_0[0x10];
u8 port_select_flow_table[0x1];
- u8 reserved_at_11[0x1];
+ u8 port_select_eswitch[0x1];
u8 port_select_flow_table_bypass[0x1];
u8 reserved_at_13[0xd];
@@ -1070,7 +1070,9 @@ struct mlx5_ifc_e_switch_cap_bits {
u8 root_ft_on_other_esw[0x1];
u8 reserved_at_a[0x1];
u8 esw_vport_state_max_tx_speed[0x1];
- u8 reserved_at_c[0xd];
+ u8 esw_vport_state_cap_tx_speed[0x1];
+ u8 esw_vport_state_effective_tx_speed[0x1];
+ u8 reserved_at_e[0xb];
u8 esw_functions_changed[0x1];
u8 reserved_at_1a[0x1];
u8 ecpf_vport_exists[0x1];
@@ -2008,7 +2010,9 @@ struct mlx5_ifc_cmd_hca_cap_bits {
u8 reserved_at_3b0[0x2];
u8 qp_latency_sensitive_disable[0x1];
u8 log_max_stride_sz_sq[0x5];
- u8 reserved_at_3b8[0x3];
+ u8 reserved_at_3b8[0x1];
+ u8 multi_uplink_eswitch[0x1];
+ u8 reserved_at_3ba[0x1];
u8 log_min_stride_sz_sq[0x5];
u8 hairpin[0x1];
@@ -5492,6 +5496,9 @@ struct mlx5_ifc_query_vport_state_out_bits {
u8 reserved_at_70[0x8];
u8 admin_state[0x4];
u8 state[0x4];
+
+ u8 cap_tx_speed[0x10];
+ u8 effective_tx_speed[0x10];
};
struct mlx5_ifc_array1024_auto_bits {
@@ -5979,6 +5986,108 @@ struct mlx5_ifc_cqe_error_syndrome_bits {
u8 syndrome[0x8];
};
+struct mlx5_ifc_wqe_ctrl_seg_bits {
+ u8 opmod[0x8];
+ u8 wqe_index[0x10];
+ u8 opcode[0x8];
+
+ u8 qp_or_sq[0x18];
+ u8 reserved_at_38[0x2];
+ u8 ds[0x6];
+
+ u8 signature[0x8];
+ u8 reserved_at_48[0x10];
+ u8 fm[0x3];
+ u8 reserved_at_5b[0x1];
+ u8 ce[0x2];
+ u8 se[0x1];
+ u8 reserved_at_5f[0x1];
+
+ u8 imm[0x20];
+};
+
+/* Values for wqe_ctrl_seg_bits.opcode */
+enum {
+ MLX5_OPCODE_NOP = 0x00,
+ MLX5_OPCODE_SEND_INVAL = 0x01,
+ MLX5_OPCODE_RDMA_WRITE = 0x08,
+ MLX5_OPCODE_RDMA_WRITE_IMM = 0x09,
+ MLX5_OPCODE_SEND = 0x0a,
+ MLX5_OPCODE_SEND_IMM = 0x0b,
+ MLX5_OPCODE_LSO = 0x0e,
+ MLX5_OPCODE_RDMA_READ = 0x10,
+ MLX5_OPCODE_ATOMIC_CS = 0x11,
+ MLX5_OPCODE_ATOMIC_FA = 0x12,
+ MLX5_OPCODE_ATOMIC_MASKED_CS = 0x14,
+ MLX5_OPCODE_ATOMIC_MASKED_FA = 0x15,
+ MLX5_OPCODE_BIND_MW = 0x18,
+ MLX5_OPCODE_CONFIG_CMD = 0x1f,
+ MLX5_OPCODE_SET_PSV = 0x20,
+ MLX5_OPCODE_GET_PSV = 0x21,
+ MLX5_OPCODE_CHECK_PSV = 0x22,
+ MLX5_OPCODE_DUMP = 0x23,
+ MLX5_OPCODE_UMR = 0x25,
+ MLX5_OPCODE_RGET_PSV = 0x26,
+ MLX5_OPCODE_RCHECK_PSV = 0x27,
+ MLX5_OPCODE_ENHANCED_MPSW = 0x29,
+ MLX5_OPCODE_FLOW_TBL_ACCESS = 0x2c,
+ MLX5_OPCODE_ACCESS_ASO = 0x2d,
+};
+
+/* Values for wqe_ctrl_seg_bits.ce */
+enum {
+ MLX5_WQE_CE_CQE_ALWAYS = 2,
+};
+
+struct mlx5_ifc_wqe_raddr_seg_bits {
+ u8 raddr[0x40];
+
+ u8 rkey[0x20];
+ u8 reserved_at_60[0x20];
+};
+
+struct mlx5_ifc_wqe_data_seg_bits {
+ u8 reserved_at_0[0x1];
+ u8 byte_count[0x1f];
+
+ u8 lkey[0x20];
+
+ u8 addr[0x40];
+};
+
+struct mlx5_ifc_cqe64_bits {
+ u8 reserved_at_0[0x1a0];
+
+ union {
+ u8 reserved_at_1a0[0x20];
+ struct mlx5_ifc_cqe_error_syndrome_bits error_syndrome;
+ };
+
+ u8 send_wqe_opcode[0x8];
+ u8 qpn_or_dctn_or_flow_tag[0x18];
+
+ u8 wqe_counter[0x10];
+ u8 signature[0x8];
+ u8 opcode[0x4];
+ u8 cqe_format[0x2];
+ u8 se[0x1];
+ u8 owner[0x1];
+};
+
+/* Values for cqe64_bits.opcode */
+enum {
+ MLX5_CQE_REQ = 0,
+ MLX5_CQE_RESP_WR_IMM = 1,
+ MLX5_CQE_RESP_SEND = 2,
+ MLX5_CQE_RESP_SEND_IMM = 3,
+ MLX5_CQE_RESP_SEND_INV = 4,
+ MLX5_CQE_RESIZE_CQ = 5,
+ MLX5_CQE_SIG_ERR = 12,
+ MLX5_CQE_REQ_ERR = 13,
+ MLX5_CQE_RESP_ERR = 14,
+ MLX5_CQE_INVALID = 15,
+};
+
struct mlx5_ifc_qp_context_extension_bits {
u8 reserved_at_0[0x60];
@@ -6475,6 +6584,12 @@ struct mlx5_ifc_query_hca_cap_in_bits {
u8 reserved_at_60[0x20];
};
+/* Values for query_hca_cap_in_bits.op_mod */
+enum mlx5_cap_mode {
+ HCA_CAP_OPMOD_GET_MAX = 0,
+ HCA_CAP_OPMOD_GET_CUR = 1,
+};
+
struct mlx5_ifc_other_hca_cap_bits {
u8 roce[0x1];
u8 reserved_at_1[0x27f];
@@ -7840,6 +7955,9 @@ struct mlx5_ifc_modify_vport_state_in_bits {
u8 reserved_at_74[0x4];
u8 admin_state[0x4];
u8 reserved_at_7c[0x4];
+
+ u8 cap_tx_speed[0x10];
+ u8 effective_tx_speed[0x10];
};
struct mlx5_ifc_modify_tis_out_bits {
@@ -11270,6 +11388,55 @@ struct mlx5_ifc_eqe_bits {
u8 owner[0x1];
};
+/* Values for eqe_bits.event_type */
+enum mlx5_event {
+ /* Special value to subscribe to any event */
+ MLX5_EVENT_TYPE_NOTIFY_ANY = 0x0,
+ /* HW events enum start: comp events are not subscribable */
+ MLX5_EVENT_TYPE_COMP = 0x0,
+ /* HW Async events enum start: subscribable events */
+ MLX5_EVENT_TYPE_PATH_MIG = 0x01,
+ MLX5_EVENT_TYPE_COMM_EST = 0x02,
+ MLX5_EVENT_TYPE_SQ_DRAINED = 0x03,
+ MLX5_EVENT_TYPE_SRQ_LAST_WQE = 0x13,
+ MLX5_EVENT_TYPE_SRQ_RQ_LIMIT = 0x14,
+
+ MLX5_EVENT_TYPE_CQ_ERROR = 0x04,
+ MLX5_EVENT_TYPE_WQ_CATAS_ERROR = 0x05,
+ MLX5_EVENT_TYPE_PATH_MIG_FAILED = 0x07,
+ MLX5_EVENT_TYPE_WQ_INVAL_REQ_ERROR = 0x10,
+ MLX5_EVENT_TYPE_WQ_ACCESS_ERROR = 0x11,
+ MLX5_EVENT_TYPE_SRQ_CATAS_ERROR = 0x12,
+ MLX5_EVENT_TYPE_OBJECT_CHANGE = 0x27,
+
+ MLX5_EVENT_TYPE_INTERNAL_ERROR = 0x08,
+ MLX5_EVENT_TYPE_PORT_CHANGE = 0x09,
+ MLX5_EVENT_TYPE_CMD = 0x0a,
+ MLX5_EVENT_TYPE_PAGE_REQUEST = 0x0b,
+ MLX5_EVENT_TYPE_PAGE_FAULT = 0x0c,
+ MLX5_EVENT_TYPE_NIC_VPORT_CHANGE = 0x0d,
+ MLX5_EVENT_TYPE_ESW_FUNCTIONS_CHANGED = 0x0e,
+ MLX5_EVENT_TYPE_VHCA_STATE_CHANGE = 0x0f,
+ MLX5_EVENT_TYPE_GPIO_EVENT = 0x15,
+ MLX5_EVENT_TYPE_PORT_MODULE_EVENT = 0x16,
+ MLX5_EVENT_TYPE_TEMP_WARN_EVENT = 0x17,
+ MLX5_EVENT_TYPE_XRQ_ERROR = 0x18,
+ MLX5_EVENT_TYPE_REMOTE_CONFIG = 0x19,
+ MLX5_EVENT_TYPE_DB_BF_CONGESTION = 0x1a,
+ MLX5_EVENT_TYPE_STALL_EVENT = 0x1b,
+ MLX5_EVENT_TYPE_DCT_DRAINED = 0x1c,
+ MLX5_EVENT_TYPE_DCT_KEY_VIOLATION = 0x1d,
+ MLX5_EVENT_TYPE_FPGA_ERROR = 0x20,
+ MLX5_EVENT_TYPE_FPGA_QP_ERROR = 0x21,
+ MLX5_EVENT_TYPE_GENERAL_EVENT = 0x22,
+ MLX5_EVENT_TYPE_MONITOR_COUNTER = 0x24,
+ MLX5_EVENT_TYPE_PPS_EVENT = 0x25,
+ MLX5_EVENT_TYPE_DEVICE_TRACER = 0x26,
+
+ MLX5_EVENT_TYPE_MAX = 0x100,
+};
+
+/* Values for cmd_queue_entry_bits.type */
enum {
MLX5_CMD_QUEUE_ENTRY_TYPE_PCIE_CMD_IF_TRANSPORT = 0x7,
};
@@ -11312,6 +11479,27 @@ struct mlx5_ifc_cmd_out_bits {
u8 command_output[0x20];
};
+/* Values for cmd_out_bits.status */
+enum {
+ MLX5_CMD_STAT_OK = 0x0,
+ MLX5_CMD_STAT_INT_ERR = 0x1,
+ MLX5_CMD_STAT_BAD_OP_ERR = 0x2,
+ MLX5_CMD_STAT_BAD_PARAM_ERR = 0x3,
+ MLX5_CMD_STAT_BAD_SYS_STATE_ERR = 0x4,
+ MLX5_CMD_STAT_BAD_RES_ERR = 0x5,
+ MLX5_CMD_STAT_RES_BUSY = 0x6,
+ MLX5_CMD_STAT_NOT_READY = 0x7,
+ MLX5_CMD_STAT_LIM_ERR = 0x8,
+ MLX5_CMD_STAT_BAD_RES_STATE_ERR = 0x9,
+ MLX5_CMD_STAT_IX_ERR = 0xa,
+ MLX5_CMD_STAT_NO_RES_ERR = 0xf,
+ MLX5_CMD_STAT_BAD_QP_STATE_ERR = 0x10,
+ MLX5_CMD_STAT_BAD_PKT_ERR = 0x30,
+ MLX5_CMD_STAT_BAD_SIZE_OUTS_CQES_ERR = 0x40,
+ MLX5_CMD_STAT_BAD_INP_LEN_ERR = 0x50,
+ MLX5_CMD_STAT_BAD_OUTP_LEN_ERR = 0x51,
+};
+
struct mlx5_ifc_cmd_in_bits {
u8 opcode[0x10];
u8 reserved_at_10[0x10];
diff --git a/include/linux/mlx5/mlx5_ifc_macros.h b/include/linux/mlx5/mlx5_ifc_macros.h
new file mode 100644
index 000000000000..1b9e39a50949
--- /dev/null
+++ b/include/linux/mlx5/mlx5_ifc_macros.h
@@ -0,0 +1,185 @@
+/* SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB */
+/*
+ * Copyright (c) 2013-2026, Mellanox Technologies. All rights reserved.
+ *
+ * Accessor macros for mlx5 IFC structures.
+ *
+ * Extracted from device.h so that code which cannot include device.h
+ * (e.g. selftests) can still use the MLX5_SET/GET family directly.
+ */
+
+#ifndef MLX5_IFC_MACROS_H
+#define MLX5_IFC_MACROS_H
+
+/* Internal helpers -- 32-bit */
+#define __mlx5_nullp(typ) ((struct mlx5_ifc_##typ##_bits *)0)
+#define __mlx5_bit_sz(typ, fld) sizeof(__mlx5_nullp(typ)->fld)
+#define __mlx5_bit_off(typ, fld) (offsetof(struct mlx5_ifc_##typ##_bits, fld))
+#define __mlx5_16_off(typ, fld) (__mlx5_bit_off(typ, fld) / 16)
+#define __mlx5_dw_off(typ, fld) (__mlx5_bit_off(typ, fld) / 32)
+#define __mlx5_64_off(typ, fld) (__mlx5_bit_off(typ, fld) / 64)
+#define __mlx5_16_bit_off(typ, fld) (16 - __mlx5_bit_sz(typ, fld) - (__mlx5_bit_off(typ, fld) & 0xf))
+#define __mlx5_dw_bit_off(typ, fld) (32 - __mlx5_bit_sz(typ, fld) - (__mlx5_bit_off(typ, fld) & 0x1f))
+#define __mlx5_mask(typ, fld) ((u32)((1ull << __mlx5_bit_sz(typ, fld)) - 1))
+#define __mlx5_dw_mask(typ, fld) (__mlx5_mask(typ, fld) << __mlx5_dw_bit_off(typ, fld))
+#define __mlx5_mask16(typ, fld) ((u16)((1ull << __mlx5_bit_sz(typ, fld)) - 1))
+#define __mlx5_16_mask(typ, fld) (__mlx5_mask16(typ, fld) << __mlx5_16_bit_off(typ, fld))
+#define __mlx5_st_sz_bits(typ) sizeof(struct mlx5_ifc_##typ##_bits)
+
+/* Size and address macros */
+#define MLX5_FLD_SZ_BYTES(typ, fld) (__mlx5_bit_sz(typ, fld) / 8)
+#define MLX5_ST_SZ_BYTES(typ) (sizeof(struct mlx5_ifc_##typ##_bits) / 8)
+#define MLX5_ST_SZ_DW(typ) (sizeof(struct mlx5_ifc_##typ##_bits) / 32)
+#define MLX5_ST_SZ_QW(typ) (sizeof(struct mlx5_ifc_##typ##_bits) / 64)
+#define MLX5_UN_SZ_BYTES(typ) (sizeof(union mlx5_ifc_##typ##_bits) / 8)
+#define MLX5_UN_SZ_DW(typ) (sizeof(union mlx5_ifc_##typ##_bits) / 32)
+#define MLX5_BYTE_OFF(typ, fld) (__mlx5_bit_off(typ, fld) / 8)
+#define MLX5_ADDR_OF(typ, p, fld) ((void *)((u8 *)(p) + MLX5_BYTE_OFF(typ, fld)))
+
+/* insert a value to a struct */
+#define MLX5_SET(typ, p, fld, v) do { \
+ u32 _v = v; \
+ BUILD_BUG_ON(__mlx5_st_sz_bits(typ) % 32); \
+ *((__be32 *)(p) + __mlx5_dw_off(typ, fld)) = \
+ cpu_to_be32((be32_to_cpu(*((__be32 *)(p) + __mlx5_dw_off(typ, fld))) & \
+ (~__mlx5_dw_mask(typ, fld))) | (((_v) & __mlx5_mask(typ, fld)) \
+ << __mlx5_dw_bit_off(typ, fld))); \
+} while (0)
+
+#define MLX5_ARRAY_SET(typ, p, fld, idx, v) do { \
+ BUILD_BUG_ON(__mlx5_bit_off(typ, fld) % 32); \
+ MLX5_SET(typ, p, fld[idx], v); \
+} while (0)
+
+#define MLX5_SET_TO_ONES(typ, p, fld) do { \
+ BUILD_BUG_ON(__mlx5_st_sz_bits(typ) % 32); \
+ *((__be32 *)(p) + __mlx5_dw_off(typ, fld)) = \
+ cpu_to_be32((be32_to_cpu(*((__be32 *)(p) + __mlx5_dw_off(typ, fld))) & \
+ (~__mlx5_dw_mask(typ, fld))) | ((__mlx5_mask(typ, fld)) \
+ << __mlx5_dw_bit_off(typ, fld))); \
+} while (0)
+
+#define MLX5_GET(typ, p, fld) ((be32_to_cpu(*((__be32 *)(p) +\
+__mlx5_dw_off(typ, fld))) >> __mlx5_dw_bit_off(typ, fld)) & \
+__mlx5_mask(typ, fld))
+
+#define MLX5_GET_PR(typ, p, fld) ({ \
+ u32 ___t = MLX5_GET(typ, p, fld); \
+ pr_debug(#fld " = 0x%x\n", ___t); \
+ ___t; \
+})
+
+/* 64-bit field accessors */
+#define __MLX5_SET64(typ, p, fld, v) do { \
+ BUILD_BUG_ON(__mlx5_bit_sz(typ, fld) != 64); \
+ *((__be64 *)(p) + __mlx5_64_off(typ, fld)) = cpu_to_be64(v); \
+} while (0)
+
+#define MLX5_SET64(typ, p, fld, v) do { \
+ BUILD_BUG_ON(__mlx5_bit_off(typ, fld) % 64); \
+ __MLX5_SET64(typ, p, fld, v); \
+} while (0)
+
+#define MLX5_ARRAY_SET64(typ, p, fld, idx, v) do { \
+ BUILD_BUG_ON(__mlx5_bit_off(typ, fld) % 64); \
+ __MLX5_SET64(typ, p, fld[idx], v); \
+} while (0)
+
+#define MLX5_ARRAY_GET64(typ, p, fld, idx) \
+ ({ \
+ BUILD_BUG_ON(__mlx5_bit_off(typ, fld) % 64); \
+ be64_to_cpu( \
+ *((__be64 *)(p) + __mlx5_64_off(typ, fld) + (idx))); \
+ })
+
+#define MLX5_GET64(typ, p, fld) be64_to_cpu(*((__be64 *)(p) + __mlx5_64_off(typ, fld)))
+
+#define MLX5_GET64_PR(typ, p, fld) ({ \
+ u64 ___t = MLX5_GET64(typ, p, fld); \
+ pr_debug(#fld " = 0x%llx\n", ___t); \
+ ___t; \
+})
+
+/* 16-bit field accessors */
+#define MLX5_GET16(typ, p, fld) ((be16_to_cpu(*((__be16 *)(p) +\
+__mlx5_16_off(typ, fld))) >> __mlx5_16_bit_off(typ, fld)) & \
+__mlx5_mask16(typ, fld))
+
+#define MLX5_SET16(typ, p, fld, v) do { \
+ u16 _v = v; \
+ BUILD_BUG_ON(__mlx5_st_sz_bits(typ) % 16); \
+ *((__be16 *)(p) + __mlx5_16_off(typ, fld)) = \
+ cpu_to_be16((be16_to_cpu(*((__be16 *)(p) + __mlx5_16_off(typ, fld))) & \
+ (~__mlx5_16_mask(typ, fld))) | (((_v) & __mlx5_mask16(typ, fld)) \
+ << __mlx5_16_bit_off(typ, fld))); \
+} while (0)
+
+/* Big endian getters */
+#define MLX5_GET64_BE(typ, p, fld) (*((__be64 *)(p) +\
+ __mlx5_64_off(typ, fld)))
+
+#define MLX5_GET_BE(type_t, typ, p, fld) ({ \
+ type_t tmp; \
+ switch (sizeof(tmp)) { \
+ case sizeof(u8): \
+ tmp = (__force type_t)MLX5_GET(typ, p, fld); \
+ break; \
+ case sizeof(u16): \
+ tmp = (__force type_t)cpu_to_be16(MLX5_GET(typ, p, fld)); \
+ break; \
+ case sizeof(u32): \
+ tmp = (__force type_t)cpu_to_be32(MLX5_GET(typ, p, fld)); \
+ break; \
+ case sizeof(u64): \
+ tmp = (__force type_t)MLX5_GET64_BE(typ, p, fld); \
+ break; \
+ } \
+ tmp; \
+ })
+
+/*
+ * Use READ_ONCE/WRITE_ONCE for a single field that hardware may read/write
+ * unpredictably, mostly owner bits. All other bits in the DW must be stable.
+ * Usually a dma_wmb() will be required before a write and a dma_rmb() after a
+ * read.
+ */
+#define MLX5_GET_ONCE(typ, p, fld) \
+ ((be32_to_cpu(READ_ONCE(*((__be32 *)(p) + __mlx5_dw_off(typ, fld)))) >> \
+ __mlx5_dw_bit_off(typ, fld)) & \
+ __mlx5_mask(typ, fld))
+
+#define MLX5_SET_ONCE(typ, p, fld, v) \
+ do { \
+ u32 _v = v; \
+ __be32 *_dw = (__be32 *)(p) + __mlx5_dw_off(typ, fld); \
+ BUILD_BUG_ON(__mlx5_st_sz_bits(typ) % 32); \
+ WRITE_ONCE(*_dw, \
+ cpu_to_be32((be32_to_cpu(READ_ONCE(*_dw)) & \
+ (~__mlx5_dw_mask(typ, fld))) | \
+ (((_v) & __mlx5_mask(typ, fld)) \
+ << __mlx5_dw_bit_off(typ, fld)))); \
+ } while (0)
+
+/* Access MMIO registers, usually the init segment, using IFC structs. */
+#define MLX5_GET_MMIO(typ, p, fld) \
+ ((ioread32be(((__be32 __iomem *)(p) + __mlx5_dw_off(typ, fld))) >> \
+ __mlx5_dw_bit_off(typ, fld)) & \
+ __mlx5_mask(typ, fld))
+
+/* The set is not relaxed so there is an integrated dma_wmb(). */
+#define MLX5_SET_MMIO(typ, p, fld, v) \
+ do { \
+ u32 _v = v; \
+ void __iomem *_dw = \
+ ((__be32 __iomem *)(p) + __mlx5_dw_off(typ, fld)); \
+ if (__mlx5_bit_sz(typ, fld) == 32) \
+ iowrite32be(_v, _dw); \
+ else \
+ iowrite32be((ioread32be(_dw) & \
+ (~__mlx5_dw_mask(typ, fld))) | \
+ ((_v & __mlx5_mask(typ, fld)) \
+ << __mlx5_dw_bit_off(typ, fld)), \
+ _dw); \
+ } while (0)
+
+#endif /* MLX5_IFC_MACROS_H */
diff --git a/include/linux/mm.h b/include/linux/mm.h
index dd09c438fa23..6882ad400935 100644
--- a/include/linux/mm.h
+++ b/include/linux/mm.h
@@ -38,6 +38,7 @@
#include <linux/bitops.h>
#include <linux/iommu-debug-pagealloc.h>
#include <linux/kcsan-checks.h>
+#include <linux/vmemmap-optimization.h>
struct mempolicy;
struct anon_vma;
@@ -57,16 +58,6 @@ static inline unsigned long totalram_pages(void)
return (unsigned long)atomic_long_read(&_totalram_pages);
}
-static inline void totalram_pages_inc(void)
-{
- atomic_long_inc(&_totalram_pages);
-}
-
-static inline void totalram_pages_dec(void)
-{
- atomic_long_dec(&_totalram_pages);
-}
-
static inline void totalram_pages_add(long count)
{
atomic_long_add(count, &_totalram_pages);
@@ -928,7 +919,6 @@ static inline void vma_numab_state_free(struct vm_area_struct *vma) {}
* These must be here rather than mmap_lock.h as dependent on vm_fault type,
* declared in this header.
*/
-#ifdef CONFIG_PER_VMA_LOCK
static inline void release_fault_lock(struct vm_fault *vmf)
{
if (vmf->flags & FAULT_FLAG_VMA_LOCK)
@@ -944,17 +934,6 @@ static inline void assert_fault_locked(const struct vm_fault *vmf)
else
mmap_assert_locked(vmf->vma->vm_mm);
}
-#else
-static inline void release_fault_lock(struct vm_fault *vmf)
-{
- mmap_read_unlock(vmf->vma->vm_mm);
-}
-
-static inline void assert_fault_locked(const struct vm_fault *vmf)
-{
- mmap_assert_locked(vmf->vma->vm_mm);
-}
-#endif /* CONFIG_PER_VMA_LOCK */
static inline bool mm_flags_test(int flag, const struct mm_struct *mm)
{
@@ -1551,11 +1530,6 @@ static inline void vma_set_anonymous(struct vm_area_struct *vma)
vma->vm_ops = NULL;
}
-static inline void vma_desc_set_anonymous(struct vm_area_desc *desc)
-{
- desc->vm_ops = NULL;
-}
-
static inline bool vma_is_anonymous(const struct vm_area_struct *vma)
{
return !vma->vm_ops;
@@ -2075,20 +2049,21 @@ vm_fault_t finish_fault(struct vm_fault *vmf);
*
* A pagecache page contains an opaque `private' member, which belongs to the
* page's address_space. Usually, this is the address of a circular list of
- * the page's disk buffers. PG_private must be set to tell the VM to call
- * into the filesystem to release these pages.
+ * the page's disk buffers. It tells the VM to call into the filesystem to
+ * release these pages.
*
* A folio may belong to an inode's memory mapping. In this case,
* folio->mapping points to the inode, and folio->index is the file
* offset of the folio, in units of PAGE_SIZE.
*
- * If pagecache pages are not associated with an inode, they are said to be
- * anonymous pages. These may become associated with the swapcache, and in that
- * case PG_swapcache is set, and page->private is an offset into the swapcache.
+ * If pagecache folios are not associated with an inode, they are said to be
+ * anonymous folios. These may become associated with the swapcache, and in that
+ * case PG_swapcache is set, and folio->private is an offset into the swapcache.
*
* In either case (swapcache or inode backed), the pagecache itself holds one
- * reference to the page. Setting PG_private should also increment the
- * refcount. The each user mapping also has a reference to the page.
+ * reference to the folio. Attaching filesystem private data via
+ * folio_attach_private() also increments the refcount. Each user mapping also
+ * has a reference to the folio.
*
* The pagecache pages are stored in a per-mapping radix tree, which is
* rooted at mapping->i_pages, and indexed by offset.
@@ -2644,12 +2619,23 @@ static inline void set_page_section(struct page *page, unsigned long section)
page->flags.f |= (section & SECTIONS_MASK) << SECTIONS_PGSHIFT;
}
+static inline void set_page_section_from_pfn(struct page *page,
+ unsigned long pfn)
+{
+ set_page_section(page, pfn_to_section_nr(pfn));
+}
+
static inline unsigned long memdesc_section(const memdesc_flags_t *mdf)
{
ASSERT_EXCLUSIVE_BITS(mdf->f, SECTIONS_MASK << SECTIONS_PGSHIFT);
return (mdf->f >> SECTIONS_PGSHIFT) & SECTIONS_MASK;
}
#else /* !SECTION_IN_PAGE_FLAGS */
+static inline void set_page_section_from_pfn(struct page *page,
+ unsigned long pfn)
+{
+}
+
static inline unsigned long memdesc_section(const memdesc_flags_t *mdf)
{
return 0;
@@ -2872,9 +2858,7 @@ static inline void set_page_links(struct page *page, enum zone_type zone,
{
set_page_zone(page, zone);
set_page_node(page, node);
-#ifdef SECTION_IN_PAGE_FLAGS
- set_page_section(page, pfn_to_section_nr(pfn));
-#endif
+ set_page_section_from_pfn(page, pfn);
}
/**
@@ -3022,9 +3006,9 @@ static inline bool folio_maybe_mapped_shared(struct folio *folio)
* @folio: the folio
*
* Calculate the expected folio refcount, taking references from the pagecache,
- * swapcache, PG_private and page table mappings into account. Useful in
- * combination with folio_ref_count() to detect unexpected references (e.g.,
- * GUP or other temporary references).
+ * swapcache, private data (folio->private != NULL) and page table mappings into
+ * account. Useful in combination with folio_ref_count() to detect unexpected
+ * references (e.g., GUP or other temporary references).
*
* Does currently not consider references from the LRU cache. If the folio
* was isolated from the LRU (which is the case during migration or split),
@@ -3062,10 +3046,15 @@ static inline int folio_expected_ref_count(const struct folio *folio)
ref_count += folio_test_swapcache(folio) << order;
if (!folio_test_anon(folio)) {
- /* One reference per page from the pagecache. */
- ref_count += !!folio->mapping << order;
- /* One reference from PG_private. */
- ref_count += folio_test_private(folio);
+ /*
+ * One reference per page from the pagecache.
+ * Use data_race() since folio might not be locked.
+ */
+ ref_count += !!data_race(folio->mapping) << order;
+ /*
+ * One reference from filesystem private data.
+ */
+ ref_count += folio_has_attached_private(folio);
}
/* One reference per page table mapping. */
@@ -3325,10 +3314,10 @@ extern int access_process_vm(struct task_struct *tsk, unsigned long addr,
extern int access_remote_vm(struct mm_struct *mm, unsigned long addr,
void *buf, int len, unsigned int gup_flags);
-#ifdef CONFIG_BPF_SYSCALL
-extern int copy_remote_vm_str(struct task_struct *tsk, unsigned long addr,
- void *buf, int len, unsigned int gup_flags);
-#endif
+int copy_remote_mm_str(struct mm_struct *mm, unsigned long addr,
+ void *buf, int len, unsigned int gup_flags);
+int copy_remote_vm_str(struct task_struct *tsk, unsigned long addr,
+ void *buf, int len, unsigned int gup_flags);
long get_user_pages_remote(struct mm_struct *mm,
unsigned long start, unsigned long nr_pages,
@@ -4083,12 +4072,6 @@ static inline void free_reserved_page(struct page *page)
free_reserved_pages(page, 0);
}
-static inline void mark_page_reserved(struct page *page)
-{
- SetPageReserved(page);
- adjust_managed_page_count(page, -1);
-}
-
static inline void free_reserved_ptdesc(struct ptdesc *pt)
{
free_reserved_page(ptdesc_page(pt));
@@ -4408,9 +4391,8 @@ static inline unsigned long vma_pages(const struct vm_area_struct *vma)
* If @vma is a MAP_PRIVATE file-backed mapping, then this returns the
* page offset within the file.
*
- * Edge cases: nommu does not abide by these, MAP_PRIVATE-/dev/zero satisfies
- * vma_is_anonymous() but has file-backed page offset, and MAP_PRIVATE-pfnmap
- * regions have their page offset set to the first PFN in the range.
+ * Edge cases: nommu does not abide by these and CoW MAP_PRIVATE-pfnmap regions
+ * have their page offset set to the first PFN in the range.
*
* Returns: The page offset of the start of @vma.
*/
@@ -5140,7 +5122,6 @@ static inline void print_vma_addr(char *prefix, unsigned long rip)
}
#endif
-unsigned long section_map_size(void);
struct page * __populate_section_memmap(unsigned long pfn,
unsigned long nr_pages, int nid, struct vmem_altmap *altmap,
struct dev_pagemap *pgmap);
@@ -5159,9 +5140,6 @@ int vmemmap_populate_hugepages(unsigned long start, unsigned long end,
int node, struct vmem_altmap *altmap);
int vmemmap_populate(unsigned long start, unsigned long end, int node,
struct vmem_altmap *altmap);
-int vmemmap_populate_hvo(unsigned long start, unsigned long end,
- unsigned int order, struct zone *zone,
- unsigned long headsize);
void vmemmap_wrprotect_hvo(unsigned long start, unsigned long end, int node,
unsigned long headsize);
void vmemmap_populate_print_last(void);
@@ -5196,7 +5174,6 @@ static inline void vmem_altmap_free(struct vmem_altmap *altmap,
}
#endif
-#define VMEMMAP_RESERVE_NR 2
#ifdef CONFIG_ARCH_WANT_OPTIMIZE_DAX_VMEMMAP
static inline bool __vmemmap_can_optimize(struct vmem_altmap *altmap,
struct dev_pagemap *pgmap)
@@ -5204,6 +5181,9 @@ static inline bool __vmemmap_can_optimize(struct vmem_altmap *altmap,
unsigned long nr_pages;
unsigned long nr_vmemmap_pages;
+ if (!IS_ENABLED(CONFIG_VMEMMAP_OPTIMIZATION))
+ return false;
+
if (!pgmap || !is_power_of_2(sizeof(struct page)))
return false;
@@ -5213,7 +5193,7 @@ static inline bool __vmemmap_can_optimize(struct vmem_altmap *altmap,
* For vmemmap optimization with DAX we need minimum 2 vmemmap
* pages. See layout diagram in Documentation/mm/vmemmap_dedup.rst
*/
- return !altmap && (nr_vmemmap_pages > VMEMMAP_RESERVE_NR);
+ return !altmap && (nr_vmemmap_pages > VMEMMAP_OPTIMIZATION_PAGES);
}
/*
* If we don't have an architecture override, use the generic rule
diff --git a/include/linux/mm_inline.h b/include/linux/mm_inline.h
index 621c8653d8f7..ab69b9930893 100644
--- a/include/linux/mm_inline.h
+++ b/include/linux/mm_inline.h
@@ -30,6 +30,17 @@ static inline int folio_is_file_lru(const struct folio *folio)
return !folio_test_swapbacked(folio);
}
+/**
+ * folio_flags_is_file_lru - Should the folio be on a file LRU or anon LRU?
+ * @flags: The folio's flags.
+ *
+ * Just like folio_is_file_lru but take the folio flags directly instead.
+ */
+static inline int folio_flags_is_file_lru(const unsigned long *flags)
+{
+ return !test_bit(PG_swapbacked, flags);
+}
+
static __always_inline void __update_lru_size(struct lruvec *lruvec,
enum lru_list lru, enum zone_type zid,
long nr_pages)
@@ -142,10 +153,66 @@ static inline int lru_tier_from_refs(int refs, bool workingset)
return workingset ? MAX_NR_TIERS - 1 : order_base_2(refs);
}
-static inline int folio_lru_refs(const struct folio *folio)
+/**
+ * lru_set_gen_flags - Set the LRU generation number to specified folio flags.
+ * @flags: pointer to the folio flags
+ * @gen: generation number, between 0 and (MAX_NR_GENS - 1), inclusive.
+ */
+static inline void lru_set_gen_flags(unsigned long *flags, int gen)
+{
+ BUILD_BUG_ON(LRU_GEN_MASK & LRU_REFS_MASK);
+ VM_WARN_ON_ONCE(gen >= MAX_NR_GENS || gen < 0);
+ /* Store gen offset by 1, zero means the folio is off-list. */
+ *flags &= ~LRU_GEN_MASK;
+ *flags |= (gen + 1UL) << LRU_GEN_PGOFF;
+}
+
+/**
+ * lru_get_gen_flags - Return the LRU generation number from folio flags.
+ * @flags: folio flags
+ *
+ * Returns: A number between 0 and (MAX_NR_GENS - 1), inclusive. Returns
+ * -1 if the flags indicate the folio is off the list (e.g., isolated).
+ */
+static inline int lru_get_gen_flags(unsigned long flags)
+{
+ int gen = ((flags & LRU_GEN_MASK) >> LRU_GEN_PGOFF) - 1;
+
+ /* Exclude the legal -1 from the unsigned MAX_NR_GENS comparison */
+ VM_WARN_ON_ONCE(gen != -1 && gen >= MAX_NR_GENS);
+ return gen;
+}
+
+/**
+ * lru_set_refs_flags - Set the LRU referenced count to folio flags.
+ * @flags: pointer to the folio flags
+ * @refs: referenced / access count number, between 0 and LRU_REFS_MAX, inclusive.
+ *
+ * For MGLRU, PG_referenced holds the first ref, and the extra bits hold the
+ * remaining refs. For classical LRU the extra bits are not used, so it can
+ * also be seen as the refs count never exceeds 1. In both cases, refs == 1
+ * means PG_referenced is set and the extra bits are zero, and refs == 0 means
+ * PG_referenced and the extra bits are all unset.
+ */
+static inline void lru_set_refs_flags(unsigned long *flags, unsigned int refs)
{
- unsigned long flags = READ_ONCE(folio->flags.f);
+ VM_WARN_ON_ONCE(refs > LRU_REFS_MAX);
+ BUILD_BUG_ON(LRU_REFS_MAX != (LRU_REFS_MASK >> LRU_REFS_PGOFF) + 1);
+ *flags &= ~LRU_REFS_FLAGS;
+ if (!refs)
+ return;
+ *flags |= (BIT(PG_referenced) | ((refs - 1UL) << LRU_REFS_PGOFF));
+}
+
+/**
+ * lru_get_refs_flags - Return LRU referenced / access count from folio flags.
+ * @flags: folio flags
+ *
+ * Reads the LRU referenced count set by lru_set_refs_flags().
+ */
+static inline int lru_get_refs_flags(unsigned long flags)
+{
if (!(flags & BIT(PG_referenced)))
return 0;
/*
@@ -155,11 +222,24 @@ static inline int folio_lru_refs(const struct folio *folio)
return ((flags & LRU_REFS_MASK) >> LRU_REFS_PGOFF) + 1;
}
-static inline int folio_lru_gen(const struct folio *folio)
+static inline int folio_lru_refs(const struct folio *folio)
{
- unsigned long flags = READ_ONCE(folio->flags.f);
+ return lru_get_refs_flags(READ_ONCE(*const_folio_flags(folio, 0)));
+}
- return ((flags & LRU_GEN_MASK) >> LRU_GEN_PGOFF) - 1;
+static inline void folio_set_lru_refs(struct folio *folio, unsigned int refs)
+{
+ unsigned long new_flags, old_flags = READ_ONCE(*folio_flags(folio, 0));
+
+ do {
+ new_flags = old_flags;
+ lru_set_refs_flags(&new_flags, refs);
+ } while (!try_cmpxchg(folio_flags(folio, 0), &old_flags, new_flags));
+}
+
+static inline int folio_lru_gen(const struct folio *folio)
+{
+ return lru_get_gen_flags(READ_ONCE(*const_folio_flags(folio, 0)));
}
static inline bool lru_gen_is_active(const struct lruvec *lruvec, int gen)
@@ -270,7 +350,7 @@ static inline bool lru_gen_add_folio(struct lruvec *lruvec, struct folio *folio,
gen = lru_gen_from_seq(seq);
flags = (gen + 1UL) << LRU_GEN_PGOFF;
/* see the comment on MIN_NR_GENS about PG_active */
- set_mask_bits(&folio->flags.f, LRU_GEN_MASK | BIT(PG_active), flags);
+ set_mask_bits(folio_flags(folio, 0), LRU_GEN_MASK | BIT(PG_active), flags);
lru_gen_update_size(lruvec, folio, -1, gen);
/* for folio_rotate_reclaimable() */
@@ -295,7 +375,7 @@ static inline bool lru_gen_del_folio(struct lruvec *lruvec, struct folio *folio,
/* for folio_migrate_flags() */
flags = !reclaiming && lru_gen_is_active(lruvec, gen) ? BIT(PG_active) : 0;
- flags = set_mask_bits(&folio->flags.f, LRU_GEN_MASK, flags);
+ flags = set_mask_bits(folio_flags(folio, 0), LRU_GEN_MASK, flags);
gen = ((flags & LRU_GEN_MASK) >> LRU_GEN_PGOFF) - 1;
lru_gen_update_size(lruvec, folio, gen, -1);
@@ -304,11 +384,19 @@ static inline bool lru_gen_del_folio(struct lruvec *lruvec, struct folio *folio,
return true;
}
-static inline void folio_migrate_refs(struct folio *new, const struct folio *old)
+/**
+ * folio_migrate_lru_refs - copy the reference state to a new folio
+ * @new: the destination folio
+ * @old: the source folio
+ *
+ * Transfer the reference state to @new during migration: the MGLRU
+ * refs count, including PG_referenced, or just PG_referenced for the
+ * active/inactive LRU.
+ */
+static inline void folio_migrate_lru_refs(struct folio *new, const struct folio *old)
{
- unsigned long refs = READ_ONCE(old->flags.f) & LRU_REFS_MASK;
-
- set_mask_bits(&new->flags.f, LRU_REFS_MASK, refs);
+ BUILD_BUG_ON(LRU_REFS_MASK & BIT(PG_referenced));
+ folio_set_lru_refs(new, folio_lru_refs(old));
}
#else /* !CONFIG_LRU_GEN */
@@ -337,9 +425,10 @@ static inline bool lru_gen_del_folio(struct lruvec *lruvec, struct folio *folio,
return false;
}
-static inline void folio_migrate_refs(struct folio *new, const struct folio *old)
+static inline void folio_migrate_lru_refs(struct folio *new, const struct folio *old)
{
-
+ if (folio_test_referenced(old))
+ folio_set_referenced(new);
}
#endif /* CONFIG_LRU_GEN */
diff --git a/include/linux/mm_types.h b/include/linux/mm_types.h
index 6d815f6440c9..0720a4e98286 100644
--- a/include/linux/mm_types.h
+++ b/include/linux/mm_types.h
@@ -108,7 +108,7 @@ struct page {
};
/**
* @private: Mapping-private opaque data.
- * Usually used for buffer_heads if PagePrivate.
+ * Usually used for buffer_heads.
* Used for swp_entry_t if swapcache flag set.
* Indicates order in the buddy system if PageBuddy
* or on pcp_llist.
@@ -675,7 +675,7 @@ static inline void ptdesc_pmd_pts_init(struct ptdesc *ptdesc)
#define STRUCT_PAGE_MAX_SHIFT (order_base_2(sizeof(struct page)))
/*
- * page_private can be used on tail pages. However, PagePrivate is only
+ * page_private can be used on tail pages. However, it is only
* checked by the VM on the head page. So page_private on the tail pages
* should be used for data that's ancillary to the head page (eg attaching
* buffer heads to tail pages after attaching buffer heads to the head page)
@@ -950,7 +950,6 @@ struct vm_area_struct {
vma_flags_t flags;
};
-#ifdef CONFIG_PER_VMA_LOCK
/*
* Can only be written (using WRITE_ONCE()) while holding both:
* - mmap_lock (in write mode)
@@ -966,7 +965,7 @@ struct vm_area_struct {
* slowpath.
*/
unsigned int vm_lock_seq;
-#endif
+
/*
* Low 32-bits of anonymous page offset.
* See vma_start_anon_pgoff() comment for details.
@@ -1003,7 +1002,6 @@ struct vm_area_struct {
#ifdef CONFIG_NUMA_BALANCING
struct vma_numab_state *numab_state; /* NUMA Balancing state */
#endif
-#ifdef CONFIG_PER_VMA_LOCK
/*
* Used to keep track of firstly, whether the VMA is attached, secondly,
* if attached, how many read locks are taken, and thirdly, if the
@@ -1046,7 +1044,6 @@ struct vm_area_struct {
#ifdef CONFIG_DEBUG_LOCK_ALLOC
struct lockdep_map vmlock_dep_map;
#endif
-#endif
#ifdef CONFIG_64BIT
/*
* High 32-bits of anonymous page offset.
@@ -1226,7 +1223,7 @@ struct mm_struct {
struct mm_mm_cid mm_cid;
/* sched_cache related statistics */
- struct sched_cache_stat sc_stat;
+ struct sched_cache_group *sched_cache_grp;
#ifdef CONFIG_MMU
atomic_long_t pgtables_bytes; /* size of all page tables */
#endif
@@ -1254,7 +1251,6 @@ struct mm_struct {
* init_mm.mmlist, and are protected
* by mmlist_lock
*/
-#ifdef CONFIG_PER_VMA_LOCK
struct rcuwait vma_writer_wait;
/*
* This field has lock-like semantics, meaning it is sometimes
@@ -1274,7 +1270,7 @@ struct mm_struct {
* mmap_lock.
*/
seqcount_t mm_lock_seq;
-#endif
+
struct futex_mm_data futex;
unsigned long hiwater_rss; /* High-watermark of RSS usage */
@@ -1624,8 +1620,9 @@ static inline unsigned int mm_cid_size(void)
#endif /* CONFIG_SCHED_MM_CID */
#ifdef CONFIG_SCHED_CACHE
-void mm_init_sched(struct mm_struct *mm,
- struct sched_cache_time __percpu *pcpu_sched);
+int mm_init_sched(struct mm_struct *mm,
+ struct sched_cache_time __percpu *pcpu_sched);
+void mm_destroy_sched(struct mm_struct *mm);
static inline int mm_alloc_sched_noprof(struct mm_struct *mm)
{
@@ -1635,17 +1632,11 @@ static inline int mm_alloc_sched_noprof(struct mm_struct *mm)
if (!pcpu_sched)
return -ENOMEM;
- mm_init_sched(mm, pcpu_sched);
- return 0;
+ return mm_init_sched(mm, pcpu_sched);
}
#define mm_alloc_sched(...) alloc_hooks(mm_alloc_sched_noprof(__VA_ARGS__))
-static inline void mm_destroy_sched(struct mm_struct *mm)
-{
- free_percpu(mm->sc_stat.pcpu_sched);
- mm->sc_stat.pcpu_sched = NULL;
-}
#else /* !CONFIG_SCHED_CACHE */
static inline int mm_alloc_sched(struct mm_struct *mm) { return 0; }
diff --git a/include/linux/mmap_lock.h b/include/linux/mmap_lock.h
index bec0eab6ef03..28e3696ce9ff 100644
--- a/include/linux/mmap_lock.h
+++ b/include/linux/mmap_lock.h
@@ -76,8 +76,6 @@ static inline void mmap_assert_write_locked(const struct mm_struct *mm)
rwsem_assert_held_write(&mm->mmap_lock);
}
-#ifdef CONFIG_PER_VMA_LOCK
-
#ifdef CONFIG_LOCKDEP
#define __vma_lockdep_map(vma) (&vma->vmlock_dep_map)
#else
@@ -230,10 +228,14 @@ static inline void vma_refcount_put(struct vm_area_struct *vma)
}
/*
- * Use only while holding mmap read lock which guarantees that locking will not
- * fail (nobody can concurrently write-lock the vma). vma_start_read() should
+ * Use only while holding mmap read lock which guarantees that vma lock is not
+ * contended (nobody can concurrently write-lock the vma). vma_start_read() should
* not be used in such cases because it might fail due to mm_lock_seq overflow.
* This functionality is used to obtain vma read lock and drop the mmap read lock.
+ *
+ * VMA can't be detached while we are holding mmap lock, therefore in practice this
+ * function can fail only when there are so many readers that vm_refcnt overflows.
+ * The failure case is very unlikely and is already annotated as such internally.
*/
static inline bool vma_start_read_locked_nested(struct vm_area_struct *vma, int subclass)
{
@@ -249,16 +251,23 @@ static inline bool vma_start_read_locked_nested(struct vm_area_struct *vma, int
}
/*
- * Use only while holding mmap read lock which guarantees that locking will not
- * fail (nobody can concurrently write-lock the vma). vma_start_read() should
+ * Use only while holding mmap read lock which guarantees that vma lock is not
+ * contended (nobody can concurrently write-lock the vma). vma_start_read() should
* not be used in such cases because it might fail due to mm_lock_seq overflow.
* This functionality is used to obtain vma read lock and drop the mmap read lock.
+ *
+ * VMA can't be detached while we are holding mmap lock, therefore in practice this
+ * function can fail only when there are so many readers that vm_refcnt overflows.
+ * The failure case is very unlikely and is already annotated as such internally.
*/
static inline bool vma_start_read_locked(struct vm_area_struct *vma)
{
return vma_start_read_locked_nested(vma, 0);
}
+struct vm_area_struct *vma_start_read_unlocked(struct mm_struct *mm,
+ unsigned long address);
+
static inline void vma_end_read(struct vm_area_struct *vma)
{
vma_refcount_put(vma);
@@ -297,6 +306,9 @@ int __vma_start_write(struct vm_area_struct *vma, int state);
*/
static inline void vma_start_write(struct vm_area_struct *vma)
{
+ if (!IS_ENABLED(CONFIG_MMU))
+ return;
+
if (__is_vma_write_locked(vma))
return;
@@ -319,6 +331,9 @@ static inline void vma_start_write(struct vm_area_struct *vma)
static inline __must_check
int vma_start_write_killable(struct vm_area_struct *vma)
{
+ if (!IS_ENABLED(CONFIG_MMU))
+ return 0;
+
if (__is_vma_write_locked(vma))
return 0;
@@ -331,6 +346,11 @@ int vma_start_write_killable(struct vm_area_struct *vma)
*/
static inline void vma_assert_write_locked(struct vm_area_struct *vma)
{
+ if (!IS_ENABLED(CONFIG_MMU)) {
+ mmap_assert_write_locked(vma->vm_mm);
+ return;
+ }
+
VM_WARN_ON_ONCE_VMA(!__is_vma_write_locked(vma), vma);
}
@@ -343,6 +363,11 @@ static inline void vma_assert_locked(struct vm_area_struct *vma)
{
unsigned int refcnt;
+ if (!IS_ENABLED(CONFIG_MMU)) {
+ mmap_assert_locked(vma->vm_mm);
+ return;
+ }
+
if (IS_ENABLED(CONFIG_LOCKDEP)) {
if (!lock_is_held(__vma_lockdep_map(vma)))
vma_assert_write_locked(vma);
@@ -432,6 +457,9 @@ static inline bool vma_is_attached(struct vm_area_struct *vma)
*/
static inline void vma_assert_attached(struct vm_area_struct *vma)
{
+ if (!IS_ENABLED(CONFIG_MMU))
+ return;
+
WARN_ON_ONCE(!vma_is_attached(vma));
}
@@ -442,6 +470,9 @@ static inline void vma_assert_detached(struct vm_area_struct *vma)
static inline void vma_mark_attached(struct vm_area_struct *vma)
{
+ if (!IS_ENABLED(CONFIG_MMU))
+ return;
+
vma_assert_write_locked(vma);
vma_assert_detached(vma);
refcount_set_release(&vma->vm_refcnt, 1);
@@ -451,6 +482,9 @@ void __vma_exclude_readers_for_detach(struct vm_area_struct *vma);
static inline void vma_mark_detached(struct vm_area_struct *vma)
{
+ if (!IS_ENABLED(CONFIG_MMU))
+ return;
+
vma_assert_write_locked(vma);
vma_assert_attached(vma);
@@ -484,54 +518,6 @@ struct vm_area_struct *lock_next_vma(struct mm_struct *mm,
struct vma_iterator *iter,
unsigned long address);
-#else /* CONFIG_PER_VMA_LOCK */
-
-static inline void mm_lock_seqcount_init(struct mm_struct *mm) {}
-static inline void mm_lock_seqcount_begin(struct mm_struct *mm) {}
-static inline void mm_lock_seqcount_end(struct mm_struct *mm) {}
-
-static inline bool mmap_lock_speculate_try_begin(struct mm_struct *mm, unsigned int *seq)
-{
- return false;
-}
-
-static inline bool mmap_lock_speculate_retry(struct mm_struct *mm, unsigned int seq)
-{
- return true;
-}
-static inline void vma_lock_init(struct vm_area_struct *vma, bool reset_refcnt) {}
-static inline void vma_end_read(struct vm_area_struct *vma) {}
-static inline void vma_start_write(struct vm_area_struct *vma) {}
-static inline __must_check
-int vma_start_write_killable(struct vm_area_struct *vma) { return 0; }
-static inline void vma_assert_write_locked(struct vm_area_struct *vma)
- { mmap_assert_write_locked(vma->vm_mm); }
-static inline bool vma_is_attached(struct vm_area_struct *vma)
- { return true; }
-static inline void vma_assert_attached(struct vm_area_struct *vma) {}
-static inline void vma_assert_detached(struct vm_area_struct *vma) {}
-static inline void vma_mark_attached(struct vm_area_struct *vma) {}
-static inline void vma_mark_detached(struct vm_area_struct *vma) {}
-
-static inline struct vm_area_struct *lock_vma_under_rcu(struct mm_struct *mm,
- unsigned long address)
-{
- return NULL;
-}
-
-static inline void vma_assert_locked(struct vm_area_struct *vma)
-{
- mmap_assert_locked(vma->vm_mm);
-}
-
-static inline void vma_assert_stabilised(struct vm_area_struct *vma)
-{
- /* If no VMA locks, then either mmap lock suffices to stabilise. */
- mmap_assert_locked(vma->vm_mm);
-}
-
-#endif /* CONFIG_PER_VMA_LOCK */
-
static inline void vma_assert_can_modify(struct vm_area_struct *vma)
{
if (vma_is_attached(vma))
@@ -630,6 +616,8 @@ static inline void mmap_read_unlock(struct mm_struct *mm)
DEFINE_GUARD(mmap_read_lock, struct mm_struct *,
mmap_read_lock(_T), mmap_read_unlock(_T))
DEFINE_GUARD_COND(mmap_read_lock, _try, mmap_read_trylock(_T))
+DEFINE_GUARD(mmap_write_lock, struct mm_struct *,
+ mmap_write_lock(_T), mmap_write_unlock(_T))
static inline void mmap_read_unlock_non_owner(struct mm_struct *mm)
{
diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h
index ba84f02c2a10..032c018650e0 100644
--- a/include/linux/mmc/host.h
+++ b/include/linux/mmc/host.h
@@ -23,6 +23,7 @@ struct mmc_ios {
unsigned int clock; /* clock rate */
unsigned short vdd;
unsigned int power_delay_ms; /* waiting for stable power */
+ unsigned int power_off_delay_us; /* waiting for power discharge */
/* vdd stores the bit number of the selected voltage range from below. */
@@ -463,6 +464,7 @@ struct mmc_host {
#define MMC_CAP2_CRYPTO 0
#endif
#define MMC_CAP2_ALT_GPT_TEGRA (1 << 28) /* Host with eMMC that has GPT entry at a non-standard location */
+#define MMC_CAP2_CRYPTO_NO_REPROG (1 << 29) /* Host handles inline crypto key reprogramming */
bool uhs2_sd_tran; /* UHS-II flag for SD_TRAN state */
bool uhs2_app_cmd; /* UHS-II flag for APP command */
@@ -583,11 +585,9 @@ struct mmc_host {
struct device_node;
-struct mmc_host *mmc_alloc_host(int extra, struct device *);
struct mmc_host *devm_mmc_alloc_host(struct device *dev, int extra);
int mmc_add_host(struct mmc_host *);
void mmc_remove_host(struct mmc_host *);
-void mmc_free_host(struct mmc_host *);
void mmc_of_parse_clk_phase(struct device *dev,
struct mmc_clk_phase_map *map);
int mmc_of_parse(struct mmc_host *host);
@@ -753,6 +753,8 @@ static inline int mmc_card_uhs2_hd_mode(struct mmc_host *host)
int mmc_sd_switch(struct mmc_card *card, bool mode, int group,
u8 value, u8 *resp);
int mmc_send_status(struct mmc_card *card, u32 *status);
+int mmc_send_tuning_timeout(struct mmc_host *host, u32 opcode, int *cmd_error,
+ u32 timeout_ms);
int mmc_send_tuning(struct mmc_host *host, u32 opcode, int *cmd_error);
int mmc_send_abort_tuning(struct mmc_host *host, u32 opcode);
int mmc_get_ext_csd(struct mmc_card *card, u8 **new_ext_csd);
diff --git a/include/linux/mmc/sdio_ids.h b/include/linux/mmc/sdio_ids.h
index afae93f6f245..dfffda3d8002 100644
--- a/include/linux/mmc/sdio_ids.h
+++ b/include/linux/mmc/sdio_ids.h
@@ -123,6 +123,8 @@
#define SDIO_VENDOR_ID_NXP 0x0471
#define SDIO_DEVICE_ID_NXP_IW61X_BASE 0x0204
#define SDIO_DEVICE_ID_NXP_IW61X 0x0205
+#define SDIO_DEVICE_ID_NXP_IW610_BASE 0x0214
+#define SDIO_DEVICE_ID_NXP_IW610 0x0215
#define SDIO_VENDOR_ID_REALTEK 0x024c
#define SDIO_DEVICE_ID_REALTEK_RTW8723BS 0xb723
diff --git a/include/linux/mmzone.h b/include/linux/mmzone.h
index 94f9c3ff5416..d44b04589f48 100644
--- a/include/linux/mmzone.h
+++ b/include/linux/mmzone.h
@@ -96,25 +96,6 @@
#define MAX_FOLIO_NR_PAGES (1UL << MAX_FOLIO_ORDER)
-/*
- * HugeTLB Vmemmap Optimization (HVO) requires struct pages of the head page to
- * be naturally aligned with regard to the folio size.
- *
- * HVO which is only active if the size of struct page is a power of 2.
- */
-#define MAX_FOLIO_VMEMMAP_ALIGN \
- (IS_ENABLED(CONFIG_HUGETLB_PAGE_OPTIMIZE_VMEMMAP) && \
- is_power_of_2(sizeof(struct page)) ? \
- MAX_FOLIO_NR_PAGES * sizeof(struct page) : 0)
-
-/*
- * vmemmap optimization (like HVO) is only possible for page orders that fill
- * two or more pages with struct pages.
- */
-#define VMEMMAP_TAIL_MIN_ORDER (ilog2(2 * PAGE_SIZE / sizeof(struct page)))
-#define __NR_VMEMMAP_TAILS (MAX_FOLIO_ORDER - VMEMMAP_TAIL_MIN_ORDER + 1)
-#define NR_VMEMMAP_TAILS (__NR_VMEMMAP_TAILS > 0 ? __NR_VMEMMAP_TAILS : 0)
-
enum migratetype {
MIGRATE_UNMOVABLE,
MIGRATE_MOVABLE,
@@ -492,11 +473,14 @@ enum lruvec_flags {
* folio->flags, masked by LRU_REFS_MASK.
*/
#define MAX_NR_TIERS 4U
+#define LRU_TIER_MIN 0U
+#define LRU_TIER_MAX (MAX_NR_TIERS - 1)
#ifndef __GENERATING_BOUNDS_H
#define LRU_GEN_MASK ((BIT(LRU_GEN_WIDTH) - 1) << LRU_GEN_PGOFF)
#define LRU_REFS_MASK ((BIT(LRU_REFS_WIDTH) - 1) << LRU_REFS_PGOFF)
+#define LRU_REFS_MAX BIT(LRU_REFS_WIDTH)
/*
* For folios accessed multiple times through file descriptors,
@@ -635,35 +619,32 @@ struct lru_gen_mm_walk {
* For each node, memcgs are divided into two generations: the old and the
* young. For each generation, memcgs are randomly sharded into multiple bins
* to improve scalability. For each bin, the hlist_nulls is virtually divided
- * into three segments: the head, the tail and the default.
+ * into two segments: the tail and the default.
*
* An onlining memcg is added to the tail of a random bin in the old generation.
* The eviction starts at the head of a random bin in the old generation. The
* per-node memcg generation counter, whose reminder (mod MEMCG_NR_GENS) indexes
* the old generation, is incremented when all its bins become empty.
*
- * There are four operations:
- * 1. MEMCG_LRU_HEAD, which moves a memcg to the head of a random bin in its
- * current generation (old or young) and updates its "seg" to "head";
- * 2. MEMCG_LRU_TAIL, which moves a memcg to the tail of a random bin in its
+ * There are three operations:
+ * 1. MEMCG_LRU_TAIL, which moves a memcg to the tail of a random bin in its
* current generation (old or young) and updates its "seg" to "tail";
- * 3. MEMCG_LRU_OLD, which moves a memcg to the head of a random bin in the old
+ * 2. MEMCG_LRU_OLD, which moves a memcg to the head of a random bin in the old
* generation, updates its "gen" to "old" and resets its "seg" to "default";
- * 4. MEMCG_LRU_YOUNG, which moves a memcg to the tail of a random bin in the
+ * 3. MEMCG_LRU_YOUNG, which moves a memcg to the tail of a random bin in the
* young generation, updates its "gen" to "young" and resets its "seg" to
* "default".
*
* The events that trigger the above operations are:
- * 1. Exceeding the soft limit, which triggers MEMCG_LRU_HEAD;
- * 2. The first attempt to reclaim a memcg below low, which triggers
+ * 1. The first attempt to reclaim a memcg below low, which triggers
* MEMCG_LRU_TAIL;
- * 3. The first attempt to reclaim a memcg offlined or below reclaimable size
+ * 2. The first attempt to reclaim a memcg offlined or below reclaimable size
* threshold, which triggers MEMCG_LRU_TAIL;
- * 4. The second attempt to reclaim a memcg offlined or below reclaimable size
+ * 3. The second attempt to reclaim a memcg offlined or below reclaimable size
* threshold, which triggers MEMCG_LRU_YOUNG;
- * 5. Attempting to reclaim a memcg below min, which triggers MEMCG_LRU_YOUNG;
- * 6. Finishing the aging on the eviction path, which triggers MEMCG_LRU_YOUNG;
- * 7. Offlining a memcg, which triggers MEMCG_LRU_OLD.
+ * 4. Attempting to reclaim a memcg below min, which triggers MEMCG_LRU_YOUNG;
+ * 5. Finishing the aging on the eviction path, which triggers MEMCG_LRU_YOUNG;
+ * 6. Offlining a memcg, which triggers MEMCG_LRU_OLD.
*
* Notes:
* 1. Memcg LRU only applies to global reclaim, and the round-robin incrementing
@@ -696,7 +677,6 @@ void lru_gen_exit_memcg(struct mem_cgroup *memcg);
void lru_gen_online_memcg(struct mem_cgroup *memcg);
void lru_gen_offline_memcg(struct mem_cgroup *memcg);
void lru_gen_release_memcg(struct mem_cgroup *memcg);
-void lru_gen_soft_reclaim(struct mem_cgroup *memcg, int nid);
void max_lru_gen_memcg(struct mem_cgroup *memcg, int nid);
bool recheck_lru_gen_max_memcg(struct mem_cgroup *memcg, int nid);
void lru_gen_reparent_memcg(struct mem_cgroup *memcg, struct mem_cgroup *parent, int nid);
@@ -737,10 +717,6 @@ static inline void lru_gen_release_memcg(struct mem_cgroup *memcg)
{
}
-static inline void lru_gen_soft_reclaim(struct mem_cgroup *memcg, int nid)
-{
-}
-
static inline void max_lru_gen_memcg(struct mem_cgroup *memcg, int nid)
{
}
@@ -1043,6 +1019,42 @@ struct zone {
* cma pages is present pages that are assigned for CMA use
* (MIGRATE_CMA).
*
+ * pages_with_online_memmap tracks pages within the zone that have
+ * an online memory map: present pages and memory holes whose
+ * memory map has been initialized and pfn_to_online_page()
+ * succeeds. When spanned_pages == pages_with_online_memmap,
+ * pfn_to_page() can be performed without further checks on any
+ * PFN within the zone span.
+ *
+ * Note: this counter may temporarily undercount when pages with an
+ * online memory map exist outside the current zone span. Such pages
+ * are only created during boot, when initializing the memory map of
+ * pages that do not fall into any zone span. The undercount itself
+ * can only happen after boot, during memory hotplug, when growing
+ * the zone to cover such pages and later shrinking it back, which
+ * may result in a "too small" value. This is safe: it merely
+ * prevents detecting a contiguous zone.
+ *
+ * Here is an example (page numbers are just for illustration
+ * purposes):
+ * after boot:
+ * [ zone span ]
+ * [ zone pages ]
+ * spanned=10, initialized=15, online=10
+ * online == spanned -> contiguous
+ *
+ * growing after hotplug (hotplug 5):
+ * [ zone span ]
+ * [ zone pages ] [ zone pages ]
+ * spanned=30, initialized=20, online=15
+ * online != spanned -> not contiguous
+ *
+ * shrinking after hotunplug (hotunplug 5 again):
+ * [ zone span ]
+ * [ zone pages ]
+ * spanned=15, initialized=15, online=10
+ * online != spanned -> not contiguous although contiguous
+ *
* So present_pages may be used by memory hotplug or memory power
* management logic to figure out unmanaged pages by checking
* (present_pages - managed_pages). And managed_pages should be used
@@ -1067,6 +1079,7 @@ struct zone {
atomic_long_t managed_pages;
unsigned long spanned_pages;
unsigned long present_pages;
+ unsigned long pages_with_online_memmap;
#if defined(CONFIG_MEMORY_HOTPLUG)
unsigned long present_early_pages;
#endif
@@ -1157,8 +1170,8 @@ struct zone {
/* Zone statistics */
atomic_long_t vm_stat[NR_VM_ZONE_STAT_ITEMS];
atomic_long_t vm_numa_event[NR_VM_NUMA_EVENT_ITEMS];
-#ifdef CONFIG_HUGETLB_PAGE_OPTIMIZE_VMEMMAP
- struct page *vmemmap_tails[NR_VMEMMAP_TAILS];
+#ifdef CONFIG_VMEMMAP_OPTIMIZATION
+ struct page **vmemmap_tails;
#endif
} ____cacheline_internodealigned_in_smp;
@@ -1662,7 +1675,7 @@ extern void init_currently_empty_zone(struct zone *zone, unsigned long start_pfn
extern void lruvec_init(struct lruvec *lruvec);
-static inline struct pglist_data *lruvec_pgdat(struct lruvec *lruvec)
+static inline struct pglist_data *lruvec_pgdat(const struct lruvec *lruvec)
{
#ifdef CONFIG_MEMCG
return lruvec->pgdat;
@@ -1694,6 +1707,38 @@ static inline bool zone_is_zone_device(const struct zone *zone)
}
#endif
+/**
+ * zone_is_contiguous - test whether a zone is contiguous
+ * @zone: the zone to test.
+ *
+ * In a contiguous zone, it is valid to call pfn_to_page() on any PFN in the
+ * spanned zone without requiring pfn_valid() or pfn_to_online_page() checks.
+ *
+ * Note that missing synchronization with memory offlining makes any PFN
+ * traversal prone to races.
+ *
+ * ZONE_DEVICE zones are always marked non-contiguous.
+ *
+ * Return: true if contiguous, otherwise false.
+ */
+static inline bool zone_is_contiguous(const struct zone *zone)
+{
+ return READ_ONCE(zone->contiguous);
+}
+
+static inline void set_zone_contiguous(struct zone *zone)
+{
+ if (zone_is_zone_device(zone))
+ return;
+ if (zone->spanned_pages == zone->pages_with_online_memmap)
+ WRITE_ONCE(zone->contiguous, true);
+}
+
+static inline void clear_zone_contiguous(struct zone *zone)
+{
+ WRITE_ONCE(zone->contiguous, false);
+}
+
/*
* Returns true if a zone has pages managed by the buddy allocator.
* All the reclaim decisions have to use this function rather than
@@ -2021,19 +2066,23 @@ struct mem_section {
unsigned long section_mem_map;
struct mem_section_usage *usage;
+#ifdef CONFIG_VMEMMAP_OPTIMIZATION
+ /*
+ * Normally, sections hold regular (order-0) pages. However, for
+ * sections with HVO enabled, this tracks the compound page order
+ * to enable deduplication of redundant vmemmap pages.
+ */
+ unsigned int compound_page_order;
+#endif
#ifdef CONFIG_PAGE_EXTENSION
/*
* If SPARSEMEM, pgdat doesn't have page_ext pointer. We use
* section. (see page_ext.h about this.)
*/
struct page_ext *page_ext;
- unsigned long pad;
#endif
- /*
- * WARNING: mem_section must be a power-of-2 in size for the
- * calculation and use of SECTION_ROOT_MASK to make sense.
- */
-};
+/* Sacrifice minor padding space for efficient lookup. */
+} __aligned(2 * sizeof(unsigned long));
#ifdef CONFIG_SPARSEMEM_EXTREME
#define SECTIONS_PER_ROOT (PAGE_SIZE / sizeof (struct mem_section))
@@ -2043,7 +2092,6 @@ struct mem_section {
#define SECTION_NR_TO_ROOT(sec) ((sec) / SECTIONS_PER_ROOT)
#define NR_SECTION_ROOTS DIV_ROUND_UP(NR_MEM_SECTIONS, SECTIONS_PER_ROOT)
-#define SECTION_ROOT_MASK (SECTIONS_PER_ROOT - 1)
#ifdef CONFIG_SPARSEMEM_EXTREME
extern struct mem_section **mem_section;
@@ -2067,7 +2115,7 @@ static inline struct mem_section *__nr_to_section(unsigned long nr)
if (!mem_section || !mem_section[root])
return NULL;
#endif
- return &mem_section[root][nr & SECTION_ROOT_MASK];
+ return &mem_section[root][nr % SECTIONS_PER_ROOT];
}
/*
@@ -2090,9 +2138,6 @@ enum {
#ifdef CONFIG_ZONE_DEVICE
SECTION_TAINT_ZONE_DEVICE_BIT,
#endif
-#ifdef CONFIG_SPARSEMEM_VMEMMAP_PREINIT
- SECTION_IS_VMEMMAP_PREINIT_BIT,
-#endif
SECTION_MAP_LAST_BIT,
};
@@ -2103,9 +2148,6 @@ enum {
#ifdef CONFIG_ZONE_DEVICE
#define SECTION_TAINT_ZONE_DEVICE BIT(SECTION_TAINT_ZONE_DEVICE_BIT)
#endif
-#ifdef CONFIG_SPARSEMEM_VMEMMAP_PREINIT
-#define SECTION_IS_VMEMMAP_PREINIT BIT(SECTION_IS_VMEMMAP_PREINIT_BIT)
-#endif
#define SECTION_MAP_MASK (~(BIT(SECTION_MAP_LAST_BIT) - 1))
#define SECTION_NID_SHIFT SECTION_MAP_LAST_BIT
@@ -2153,28 +2195,20 @@ static inline int online_device_section(const struct mem_section *section)
return section && ((section->section_mem_map & flags) == flags);
}
-#else
-static inline int online_device_section(const struct mem_section *section)
-{
- return 0;
-}
-#endif
-#ifdef CONFIG_SPARSEMEM_VMEMMAP_PREINIT
-static inline int preinited_vmemmap_section(const struct mem_section *section)
+static inline struct zone *device_zone(int nid)
{
- return (section &&
- (section->section_mem_map & SECTION_IS_VMEMMAP_PREINIT));
+ return &NODE_DATA(nid)->node_zones[ZONE_DEVICE];
}
-
-void sparse_vmemmap_init_nid_early(int nid);
#else
-static inline int preinited_vmemmap_section(const struct mem_section *section)
+static inline int online_device_section(const struct mem_section *section)
{
return 0;
}
-static inline void sparse_vmemmap_init_nid_early(int nid)
+
+static inline struct zone *device_zone(int nid)
{
+ return NULL;
}
#endif
@@ -2241,9 +2275,6 @@ static inline bool pfn_section_first_valid(struct mem_section *ms, unsigned long
}
#endif
-void sparse_init_early_section(int nid, struct page *map, unsigned long pnum,
- unsigned long flags);
-
#ifndef CONFIG_HAVE_ARCH_PFN_VALID
/**
* pfn_valid - check if there is a valid memory map entry for a PFN
@@ -2379,7 +2410,6 @@ static inline unsigned long next_present_section_nr(unsigned long section_nr)
#endif
#else
-#define sparse_vmemmap_init_nid_early(_nid) do {} while (0)
#define pfn_in_present_section pfn_valid
#endif /* CONFIG_SPARSEMEM */
diff --git a/include/linux/mnt_idmapping.h b/include/linux/mnt_idmapping.h
index e71a6070a8f8..78eeef4c2996 100644
--- a/include/linux/mnt_idmapping.h
+++ b/include/linux/mnt_idmapping.h
@@ -8,8 +8,8 @@
struct mnt_idmap;
struct user_namespace;
-extern struct mnt_idmap nop_mnt_idmap;
-extern struct mnt_idmap invalid_mnt_idmap;
+extern const struct mnt_idmap nop_mnt_idmap;
+extern const struct mnt_idmap invalid_mnt_idmap;
extern struct user_namespace init_user_ns;
typedef struct {
@@ -121,19 +121,19 @@ static inline bool vfsgid_eq_kgid(vfsgid_t vfsgid, kgid_t kgid)
int vfsgid_in_group_p(vfsgid_t vfsgid);
-struct mnt_idmap *mnt_idmap_get(struct mnt_idmap *idmap);
-void mnt_idmap_put(struct mnt_idmap *idmap);
+const struct mnt_idmap *mnt_idmap_get(const struct mnt_idmap *idmap);
+void mnt_idmap_put(const struct mnt_idmap *idmap);
-vfsuid_t make_vfsuid(struct mnt_idmap *idmap,
+vfsuid_t make_vfsuid(const struct mnt_idmap *idmap,
struct user_namespace *fs_userns, kuid_t kuid);
-vfsgid_t make_vfsgid(struct mnt_idmap *idmap,
+vfsgid_t make_vfsgid(const struct mnt_idmap *idmap,
struct user_namespace *fs_userns, kgid_t kgid);
-kuid_t from_vfsuid(struct mnt_idmap *idmap,
+kuid_t from_vfsuid(const struct mnt_idmap *idmap,
struct user_namespace *fs_userns, vfsuid_t vfsuid);
-kgid_t from_vfsgid(struct mnt_idmap *idmap,
+kgid_t from_vfsgid(const struct mnt_idmap *idmap,
struct user_namespace *fs_userns, vfsgid_t vfsgid);
/**
@@ -148,7 +148,7 @@ kgid_t from_vfsgid(struct mnt_idmap *idmap,
*
* Return: true if @vfsuid has a mapping in the filesystem, false if not.
*/
-static inline bool vfsuid_has_fsmapping(struct mnt_idmap *idmap,
+static inline bool vfsuid_has_fsmapping(const struct mnt_idmap *idmap,
struct user_namespace *fs_userns,
vfsuid_t vfsuid)
{
@@ -186,7 +186,7 @@ static inline kuid_t vfsuid_into_kuid(vfsuid_t vfsuid)
*
* Return: true if @vfsgid has a mapping in the filesystem, false if not.
*/
-static inline bool vfsgid_has_fsmapping(struct mnt_idmap *idmap,
+static inline bool vfsgid_has_fsmapping(const struct mnt_idmap *idmap,
struct user_namespace *fs_userns,
vfsgid_t vfsgid)
{
@@ -225,7 +225,7 @@ static inline kgid_t vfsgid_into_kgid(vfsgid_t vfsgid)
*
* Return: the caller's current fsuid mapped up according to @idmap.
*/
-static inline kuid_t mapped_fsuid(struct mnt_idmap *idmap,
+static inline kuid_t mapped_fsuid(const struct mnt_idmap *idmap,
struct user_namespace *fs_userns)
{
return from_vfsuid(idmap, fs_userns, VFSUIDT_INIT(current_fsuid()));
@@ -244,7 +244,7 @@ static inline kuid_t mapped_fsuid(struct mnt_idmap *idmap,
*
* Return: the caller's current fsgid mapped up according to @idmap.
*/
-static inline kgid_t mapped_fsgid(struct mnt_idmap *idmap,
+static inline kgid_t mapped_fsgid(const struct mnt_idmap *idmap,
struct user_namespace *fs_userns)
{
return from_vfsgid(idmap, fs_userns, VFSGIDT_INIT(current_fsgid()));
diff --git a/include/linux/mod_devicetable.h b/include/linux/mod_devicetable.h
index a397213bedac..d1581bb64729 100644
--- a/include/linux/mod_devicetable.h
+++ b/include/linux/mod_devicetable.h
@@ -15,7 +15,7 @@
#include "device-id/acpi.h"
#include "device-id/amba.h"
#include "device-id/ap.h"
-#include "device-id/apr.h"
+#include "device-id/arm_smccc.h"
#include "device-id/auxiliary.h"
#include "device-id/bcma.h"
#include "device-id/ccw.h"
diff --git a/include/linux/module.h b/include/linux/module.h
index 96cc98568eea..76f4f3596477 100644
--- a/include/linux/module.h
+++ b/include/linux/module.h
@@ -24,11 +24,11 @@
#include <linux/jump_label.h>
#include <linux/export.h>
#include <linux/rbtree_latch.h>
-#include <linux/error-injection.h>
#include <linux/tracepoint-defs.h>
#include <linux/srcu.h>
#include <linux/static_call_types.h>
#include <linux/dynamic_debug.h>
+#include <linux/panic.h>
#include <linux/percpu.h>
#include <asm/module.h>
@@ -503,6 +503,10 @@ struct module {
void *btf_data;
void *btf_base_data;
#endif
+#if IS_ENABLED(CONFIG_DEBUG_INFO_BTF_INLINE)
+ unsigned int btf_inline_data_size;
+ void *btf_inline_data;
+#endif
#ifdef CONFIG_JUMP_LABEL
struct jump_entry *jump_entries;
unsigned int num_jump_entries;
@@ -770,6 +774,9 @@ static inline bool is_livepatch_module(struct module *mod)
void module_for_each_mod(int(*func)(struct module *mod, void *data), void *data);
+void add_taint_module(struct module *mod, unsigned flag,
+ enum lockdep_ok lockdep_ok);
+
#else /* !CONFIG_MODULES... */
static inline struct module *__module_address(unsigned long addr)
@@ -877,6 +884,12 @@ static inline bool module_is_coming(struct module *mod)
static inline void module_for_each_mod(int(*func)(struct module *mod, void *data), void *data)
{
}
+
+static inline void add_taint_module(struct module *mod, unsigned flag,
+ enum lockdep_ok lockdep_ok)
+{
+ add_taint(flag, lockdep_ok);
+}
#endif /* CONFIG_MODULES */
#ifdef CONFIG_SYSFS
diff --git a/include/linux/module_symbol.h b/include/linux/module_symbol.h
index 574609aced99..698d3db2b37e 100644
--- a/include/linux/module_symbol.h
+++ b/include/linux/module_symbol.h
@@ -7,8 +7,11 @@ enum ksym_flags {
KSYM_FLAG_GPL_ONLY = 1 << 0,
};
-/* This ignores the intensely annoying "mapping symbols" found in ELF files. */
-static inline bool is_mapping_symbol(const char *str)
+/*
+ * Ignore local labels (.L*, L0*) and mapping symbols ($*). These symbols are
+ * not useful for the kernel, for example, they should not appear in kallsyms.
+ */
+static inline bool is_ignored_kernel_symbol(const char *str)
{
if (str[0] == '.' && str[1] == 'L')
return true;
diff --git a/include/linux/mount.h b/include/linux/mount.h
index acfe7ef86a1b..57860e321cf5 100644
--- a/include/linux/mount.h
+++ b/include/linux/mount.h
@@ -52,17 +52,17 @@ enum mount_flags {
MNT_ATIME_MASK = MNT_NOATIME | MNT_NODIRATIME | MNT_RELATIME,
MNT_INTERNAL_FLAGS = MNT_INTERNAL | MNT_DOOMED |
- MNT_SYNC_UMOUNT | MNT_LOCKED
+ MNT_SYNC_UMOUNT | MNT_LOCKED | MNT_UMOUNT
};
struct vfsmount {
struct dentry *mnt_root; /* root of the mounted tree */
struct super_block *mnt_sb; /* pointer to superblock */
int mnt_flags;
- struct mnt_idmap *mnt_idmap;
+ const struct mnt_idmap *mnt_idmap;
} __randomize_layout;
-static inline struct mnt_idmap *mnt_idmap(const struct vfsmount *mnt)
+static inline const struct mnt_idmap *mnt_idmap(const struct vfsmount *mnt)
{
/* Pairs with smp_store_release() in do_idmap_mount(). */
return READ_ONCE(mnt->mnt_idmap);
diff --git a/include/linux/mtd/bbm.h b/include/linux/mtd/bbm.h
index d890805f5494..67929fdf2dff 100644
--- a/include/linux/mtd/bbm.h
+++ b/include/linux/mtd/bbm.h
@@ -75,7 +75,7 @@ struct nand_bbt_descr {
* with NAND_BBT_CREATE.
*/
#define NAND_BBT_CREATE_EMPTY 0x00000400
-/* Write bbt if neccecary */
+/* Write bbt if necessary */
#define NAND_BBT_WRITE 0x00002000
/* Read and write back block contents when writing bbt */
#define NAND_BBT_SAVECONTENT 0x00004000
diff --git a/include/linux/mtd/lpc32xx_mlc.h b/include/linux/mtd/lpc32xx_mlc.h
deleted file mode 100644
index 35e971be0950..000000000000
--- a/include/linux/mtd/lpc32xx_mlc.h
+++ /dev/null
@@ -1,17 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-only */
-/*
- * Platform data for LPC32xx SoC MLC NAND controller
- *
- * Copyright © 2012 Roland Stigge
- */
-
-#ifndef __LINUX_MTD_LPC32XX_MLC_H
-#define __LINUX_MTD_LPC32XX_MLC_H
-
-#include <linux/dmaengine.h>
-
-struct lpc32xx_mlc_platform_data {
- dma_filter_fn dma_filter;
-};
-
-#endif /* __LINUX_MTD_LPC32XX_MLC_H */
diff --git a/include/linux/mtd/lpc32xx_slc.h b/include/linux/mtd/lpc32xx_slc.h
deleted file mode 100644
index a044b806566b..000000000000
--- a/include/linux/mtd/lpc32xx_slc.h
+++ /dev/null
@@ -1,17 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-only */
-/*
- * Platform data for LPC32xx SoC SLC NAND controller
- *
- * Copyright © 2012 Roland Stigge
- */
-
-#ifndef __LINUX_MTD_LPC32XX_SLC_H
-#define __LINUX_MTD_LPC32XX_SLC_H
-
-#include <linux/dmaengine.h>
-
-struct lpc32xx_slc_platform_data {
- dma_filter_fn dma_filter;
-};
-
-#endif /* __LINUX_MTD_LPC32XX_SLC_H */
diff --git a/include/linux/mtd/nand-qpic-common.h b/include/linux/mtd/nand-qpic-common.h
index 437448995187..f31fd18d837f 100644
--- a/include/linux/mtd/nand-qpic-common.h
+++ b/include/linux/mtd/nand-qpic-common.h
@@ -262,7 +262,6 @@ struct bam_transaction {
u32 tx_sgl_start;
u32 rx_sgl_pos;
u32 rx_sgl_start;
-
);
};
@@ -458,6 +457,12 @@ struct qcom_nandc_props {
bool use_codeword_fixup;
};
+struct qcom_nandc_read_stats {
+ __le32 flash;
+ __le32 buffer;
+ __le32 erased_cw;
+};
+
void qcom_free_bam_transaction(struct qcom_nand_controller *nandc);
struct bam_transaction *qcom_alloc_bam_transaction(struct qcom_nand_controller *nandc);
void qcom_clear_bam_transaction(struct qcom_nand_controller *nandc);
@@ -483,5 +488,16 @@ int qcom_submit_descs(struct qcom_nand_controller *nandc);
void qcom_clear_read_regs(struct qcom_nand_controller *nandc);
void qcom_nandc_unalloc(struct qcom_nand_controller *nandc);
int qcom_nandc_alloc(struct qcom_nand_controller *nandc);
+int qcom_nandc_check_flash_errors(struct qcom_nand_controller *nandc,
+ int cw_cnt);
+void qcom_nandc_config_page_read(struct qcom_nand_controller *nandc);
+void qcom_nandc_config_page_write(struct qcom_nand_controller *nandc);
+void qcom_nandc_config_cw_write(struct qcom_nand_controller *nandc);
+void qcom_nandc_set_read_loc_first(struct qcom_nand_controller *nandc,
+ int reg_base, u32 cw_offset,
+ u32 read_size, u32 is_last_read_loc);
+void qcom_nandc_set_read_loc_last(struct qcom_nand_controller *nandc,
+ int reg_base, u32 cw_offset,
+ u32 read_size, u32 is_last_read_loc);
#endif
diff --git a/include/linux/mtd/nand.h b/include/linux/mtd/nand.h
index 09c8c93e4dba..6936180b6ea5 100644
--- a/include/linux/mtd/nand.h
+++ b/include/linux/mtd/nand.h
@@ -305,6 +305,8 @@ int nand_ecc_prepare_io_req(struct nand_device *nand,
struct nand_page_io_req *req);
int nand_ecc_finish_io_req(struct nand_device *nand,
struct nand_page_io_req *req);
+bool nand_ecc_is_pipelined(const struct nand_device *nand);
+
bool nand_ecc_is_strong_enough(struct nand_device *nand);
#if IS_REACHABLE(CONFIG_MTD_NAND_CORE)
diff --git a/include/linux/mtd/rawnand.h b/include/linux/mtd/rawnand.h
index 5c70e7bd3ed5..43fefff02025 100644
--- a/include/linux/mtd/rawnand.h
+++ b/include/linux/mtd/rawnand.h
@@ -1592,7 +1592,7 @@ void nand_wait_ready(struct nand_chip *chip);
/*
* Free resources held by the NAND device, must be called on error after a
- * sucessful nand_scan().
+ * successful nand_scan().
*/
void nand_cleanup(struct nand_chip *chip);
diff --git a/include/linux/mtd/sh_flctl.h b/include/linux/mtd/sh_flctl.h
index 78fc2d4218c8..15adf2474fa0 100644
--- a/include/linux/mtd/sh_flctl.h
+++ b/include/linux/mtd/sh_flctl.h
@@ -60,8 +60,8 @@
* Some hardware uses bits called PULSEx instead of FCKSEL_E and QTSEL_E
* to control the clock divider used between the High-Speed Peripheral Clock
* and the FLCTL internal clock. If so, use CLK_8_BIT_xxx for connecting 8 bit
- * and CLK_16_BIT_xxx for connecting 16 bit bus bandwith NAND chips. For the 16
- * bit version the divider is seperate for the pulse width of high and low
+ * and CLK_16_BIT_xxx for connecting 16 bit bus bandwidth NAND chips. For the 16
+ * bit version the divider is separate for the pulse width of high and low
* signals.
*/
#define PULSE3 (0x1 << 27)
diff --git a/include/linux/mtd/spi-nor.h b/include/linux/mtd/spi-nor.h
index 4b92494827b1..b3e3c6b10186 100644
--- a/include/linux/mtd/spi-nor.h
+++ b/include/linux/mtd/spi-nor.h
@@ -25,6 +25,7 @@
#define SPINOR_OP_WRSR 0x01 /* Write status register 1 */
#define SPINOR_OP_RDSR2 0x3f /* Read status register 2 */
#define SPINOR_OP_WRSR2 0x3e /* Write status register 2 */
+#define SPINOR_OP_WRSR2_ALT 0x31 /* Write status register 2 (alternative) */
#define SPINOR_OP_READ 0x03 /* Read data bytes (low frequency) */
#define SPINOR_OP_READ_FAST 0x0b /* Read data bytes (high frequency) */
#define SPINOR_OP_READ_1_1_2 0x3b /* Read data bytes (Dual Output SPI) */
@@ -113,20 +114,16 @@
#define SR_E_ERR BIT(5)
#define SR_P_ERR BIT(6)
-#define SR1_QUAD_EN_BIT6 BIT(6)
-
#define SR_BP_SHIFT 2
/* Enhanced Volatile Configuration Register bits */
#define EVCR_QUAD_EN_MICRON BIT(7) /* Micron Quad I/O */
/* Status Register 2 bits. */
-#define SR2_QUAD_EN_BIT1 BIT(1)
#define SR2_LB1 BIT(3) /* Security Register Lock Bit 1 */
#define SR2_LB2 BIT(4) /* Security Register Lock Bit 2 */
#define SR2_LB3 BIT(5) /* Security Register Lock Bit 3 */
#define SR2_CMP_BIT6 BIT(6)
-#define SR2_QUAD_EN_BIT7 BIT(7)
/* Supported SPI protocols */
#define SNOR_PROTO_INST_MASK GENMASK(23, 16)
@@ -365,8 +362,6 @@ struct spi_nor_flash_parameter;
* @read_dummy: the dummy needed by the read operation
* @program_opcode: the program opcode
* @sst_write_second: used by the SST write operation
- * @flags: flag options for the current SPI NOR (SNOR_F_*)
- * @cmd_ext_type: the command opcode extension type for DTR mode.
* @read_proto: the SPI protocol for read operations
* @write_proto: the SPI protocol for write operations
* @reg_proto: the SPI protocol for read_reg/write_reg/erase operations
@@ -398,6 +393,7 @@ struct spi_nor {
u8 *id;
const struct flash_info *info;
const struct spi_nor_manufacturer *manufacturer;
+ const char *partname;
u8 addr_nbytes;
u8 erase_opcode;
u8 read_opcode;
@@ -407,8 +403,6 @@ struct spi_nor {
enum spi_nor_protocol write_proto;
enum spi_nor_protocol reg_proto;
bool sst_write_second;
- u32 flags;
- enum spi_nor_cmd_ext cmd_ext_type;
struct sfdp *sfdp;
struct dentry *debugfs_root;
u8 dfs_sr_cache[2];
diff --git a/include/linux/mtd/spinand.h b/include/linux/mtd/spinand.h
index 5f4c00ae72a7..d7c99fcfb85e 100644
--- a/include/linux/mtd/spinand.h
+++ b/include/linux/mtd/spinand.h
@@ -399,7 +399,7 @@ struct spinand_devid {
};
/**
- * struct manufacurer_ops - SPI NAND manufacturer specific operations
+ * struct spinand_manufacturer_ops - SPI NAND manufacturer specific operations
* @init: initialize a SPI NAND device
* @cleanup: cleanup a SPI NAND device
*
@@ -438,6 +438,7 @@ extern const struct spinand_manufacturer fmsh_spinand_manufacturer;
extern const struct spinand_manufacturer foresee_spinand_manufacturer;
extern const struct spinand_manufacturer gigadevice_spinand_manufacturer;
extern const struct spinand_manufacturer heyangtek_spinand_manufacturer;
+extern const struct spinand_manufacturer issi_spinand_manufacturer;
extern const struct spinand_manufacturer macronix_spinand_manufacturer;
extern const struct spinand_manufacturer micron_spinand_manufacturer;
extern const struct spinand_manufacturer paragon_spinand_manufacturer;
diff --git a/include/linux/namei.h b/include/linux/namei.h
index 86d657b24fc6..c4436e5c2ba6 100644
--- a/include/linux/namei.h
+++ b/include/linux/namei.h
@@ -32,8 +32,9 @@ enum { MAX_NESTED_LINKS = 8 };
#define LOOKUP_CREATE BIT(17) /* ... in object creation */
#define LOOKUP_EXCL BIT(18) /* ... in target must not exist */
#define LOOKUP_RENAME_TARGET BIT(19) /* ... in destination of rename() */
+#define LOOKUP_SHARED BIT(20) /* Parent lock is held shared */
-/* 4 spare bits for intent */
+/* 3 spare bits for intent */
/* Scoping flags for lookup. */
#define LOOKUP_NO_SYMLINKS BIT(24) /* No symlink crossing. */
@@ -70,24 +71,24 @@ extern struct dentry *try_lookup_noperm(struct qstr *, struct dentry *);
extern struct dentry *lookup_noperm(struct qstr *, struct dentry *);
extern struct dentry *lookup_noperm_unlocked(struct qstr *, struct dentry *);
extern struct dentry *lookup_noperm_positive_unlocked(struct qstr *, struct dentry *);
-struct dentry *lookup_one(struct mnt_idmap *, struct qstr *, struct dentry *);
-struct dentry *lookup_one_unlocked(struct mnt_idmap *idmap,
+struct dentry *lookup_one(const struct mnt_idmap *, struct qstr *, struct dentry *);
+struct dentry *lookup_one_unlocked(const struct mnt_idmap *idmap,
struct qstr *name, struct dentry *base);
-struct dentry *lookup_one_positive_unlocked(struct mnt_idmap *idmap,
+struct dentry *lookup_one_positive_unlocked(const struct mnt_idmap *idmap,
struct qstr *name,
struct dentry *base);
-struct dentry *lookup_one_positive_killable(struct mnt_idmap *idmap,
+struct dentry *lookup_one_positive_killable(const struct mnt_idmap *idmap,
struct qstr *name,
struct dentry *base);
-struct dentry *start_creating(struct mnt_idmap *idmap, struct dentry *parent,
+struct dentry *start_creating(const struct mnt_idmap *idmap, struct dentry *parent,
struct qstr *name);
-struct dentry *start_removing(struct mnt_idmap *idmap, struct dentry *parent,
+struct dentry *start_removing(const struct mnt_idmap *idmap, struct dentry *parent,
struct qstr *name);
-struct dentry *start_creating_killable(struct mnt_idmap *idmap,
+struct dentry *start_creating_killable(const struct mnt_idmap *idmap,
struct dentry *parent,
struct qstr *name);
-struct dentry *start_removing_killable(struct mnt_idmap *idmap,
+struct dentry *start_removing_killable(const struct mnt_idmap *idmap,
struct dentry *parent,
struct qstr *name);
struct dentry *start_creating_noperm(struct dentry *parent, struct qstr *name);
diff --git a/include/linux/net.h b/include/linux/net.h
index 3d82966e2243..e2a866fbcfa5 100644
--- a/include/linux/net.h
+++ b/include/linux/net.h
@@ -47,6 +47,9 @@ typedef struct sockopt {
int optlen;
} sockopt_t;
+int sockptr_to_sockopt(sockopt_t *opt, sockptr_t optval, sockptr_t optlen,
+ struct kvec *kvec);
+
/*
* Initialize a user-backed sockopt_t from the (optval, optlen) __user pair of
* a getsockopt() callback. Used by transitional __user getsockopt wrappers
@@ -70,6 +73,35 @@ static inline int sockopt_init_user(sockopt_t *opt, char __user *optval,
return 0;
}
+/*
+ * Grow optval to @size, for the options whose reply is sized by a count the
+ * caller left in optval rather than by optlen. Those write past optlen today
+ * and userspace relies on it.
+ *
+ * Call it before writing through opt->iter_out: it re-anchors the iterator at
+ * the head of optval. Only a user buffer can be longer than the optlen the
+ * caller declared, so a kernel-backed optval is refused with -EINVAL.
+ */
+static inline int sockopt_expand_out(sockopt_t *opt, size_t size)
+{
+ if (size <= (size_t)opt->optlen)
+ return 0;
+
+ if (size > INT_MAX)
+ return -EINVAL;
+
+ /* Re-anchoring reads iter_out.ubuf, so the iterator has to be a user
+ * buffer that nothing has written through yet.
+ */
+ if (WARN_ON_ONCE(!iter_is_ubuf(&opt->iter_out) ||
+ iov_iter_count(&opt->iter_out) != (size_t)opt->optlen))
+ return -EINVAL;
+
+ iov_iter_ubuf(&opt->iter_out, ITER_DEST, opt->iter_out.ubuf, size);
+
+ return 0;
+}
+
struct poll_table_struct;
struct pipe_inode_info;
struct inode;
@@ -166,7 +198,7 @@ struct socket {
struct file *file;
struct sock *sk;
- const struct proto_ops *ops; /* Might change with IPV6_ADDRFORM or MPTCP. */
+ const struct proto_ops *ops; /* Might change with MPTCP. */
struct socket_wq wq;
};
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
index 87cafc932e9e..c0ae442c4344 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -252,13 +252,19 @@ struct netdev_hw_addr {
struct netdev_hw_addr_list {
struct list_head list;
- int count;
+ /* Only changed through the __hw_addr_count_* helpers after
+ * __hw_addr_init()
+ */
+ int _count;
/* Auxiliary tree for faster lookup on addition and deletion */
struct rb_root tree;
+
+ /* Set for dev->mc only, the device the list belongs to */
+ struct net_device *mc_dev;
};
-#define netdev_hw_addr_list_count(l) ((l)->count)
+#define netdev_hw_addr_list_count(l) ((l)->_count)
#define netdev_hw_addr_list_empty(l) (netdev_hw_addr_list_count(l) == 0)
#define netdev_hw_addr_list_for_each(ha, l) \
list_for_each_entry(ha, &(l)->list, list)
@@ -433,6 +439,7 @@ enum {
NAPI_STATE_SCHED_THREADED, /* Napi is currently scheduled in threaded mode */
NAPI_STATE_HAS_NOTIFIER, /* Napi has an IRQ notifier */
NAPI_STATE_THREADED_BUSY_POLL, /* The threaded NAPI poller will busy poll */
+ NAPI_STATE_PERCPU, /* NAPI handler is run per-CPU - incompatible with threaded mode */
};
enum {
@@ -448,6 +455,7 @@ enum {
NAPIF_STATE_SCHED_THREADED = BIT(NAPI_STATE_SCHED_THREADED),
NAPIF_STATE_HAS_NOTIFIER = BIT(NAPI_STATE_HAS_NOTIFIER),
NAPIF_STATE_THREADED_BUSY_POLL = BIT(NAPI_STATE_THREADED_BUSY_POLL),
+ NAPIF_STATE_PERCPU = BIT(NAPI_STATE_PERCPU),
};
enum gro_result {
@@ -887,6 +895,7 @@ enum net_device_path_type {
DEV_PATH_DSA,
DEV_PATH_MTK_WDMA,
DEV_PATH_TUN,
+ DEV_PATH_IEEE80211,
};
struct net_device_path {
@@ -910,6 +919,7 @@ struct net_device_path {
};
u8 inner_proto;
+ u8 encap_proto;
} tun;
struct {
enum {
@@ -953,6 +963,8 @@ struct net_device_path_ctx {
u16 id;
__be16 proto;
} vlan[NET_DEVICE_PATH_VLAN_MAX];
+
+ bool ieee80211;
};
enum tc_setup_type {
@@ -1135,13 +1147,16 @@ struct netdev_net_notifier {
* struct netdev_hw_addr_list *uc,
* struct netdev_hw_addr_list *mc);
* Async version of ndo_set_rx_mode which runs in process context
- * with rtnl_lock and netdev_lock_ops(dev) held. The uc/mc parameters
+ * under the netdev instance lock for "ops locked" drivers, or
+ * rtnl_lock for all other drivers. The uc/mc parameters
* are snapshots of the address lists - iterate with
* netdev_hw_addr_list_for_each(ha, uc). Return 0 on success or a
* negative errno to request a retry via the core backoff.
*
* void (*ndo_work)(struct net_device *dev, unsigned long events);
* Run deferred work scheduled with netdev_work_sched(@events).
+ * Runs in process context under the netdev instance lock for "ops
+ * locked" drivers, or rtnl_lock for all other drivers.
*
* int (*ndo_set_mac_address)(struct net_device *dev, void *addr);
* This function is called when the Media Access Control address
@@ -1151,11 +1166,6 @@ struct netdev_net_notifier {
* int (*ndo_validate_addr)(struct net_device *dev);
* Test if Media Access Control address is valid for the device.
*
- * int (*ndo_do_ioctl)(struct net_device *dev, struct ifreq *ifr, int cmd);
- * Old-style ioctl entry point. This is used internally by the
- * ieee802154 subsystem but is no longer called by the device
- * ioctl handler.
- *
* int (*ndo_siocbond)(struct net_device *dev, struct ifreq *ifr, int cmd);
* Used by the bonding driver for its device specific ioctls:
* SIOCBONDENSLAVE, SIOCBONDRELEASE, SIOCBONDSETHWADDR, SIOCBONDCHANGEACTIVE,
@@ -1477,8 +1487,6 @@ struct net_device_ops {
int (*ndo_set_mac_address)(struct net_device *dev,
void *addr);
int (*ndo_validate_addr)(struct net_device *dev);
- int (*ndo_do_ioctl)(struct net_device *dev,
- struct ifreq *ifr, int cmd);
int (*ndo_eth_ioctl)(struct net_device *dev,
struct ifreq *ifr, int cmd);
int (*ndo_siocbond)(struct net_device *dev,
@@ -1837,6 +1845,7 @@ enum netdev_reg_state {
* drivers. Mainly used by logical interfaces, such as
* bonding and tunnels
* @netmem_tx: device netmem TX mode
+ * @pacing_offload: enable EDT pacing offload.
*
* @name: This is the first field of the "visible" part of this structure
* (i.e. as seen by users in the "Space.c" file). It is the name
@@ -2167,6 +2176,7 @@ struct net_device {
unsigned long priv_flags:32;
unsigned long lltx:1;
unsigned long netmem_tx:2;
+ unsigned long pacing_offload:1;
);
const struct net_device_ops *netdev_ops;
const struct header_ops *header_ops;
@@ -2542,6 +2552,11 @@ struct net_device {
/* protected by rtnl_lock */
struct bpf_xdp_entity xdp_state[__MAX_XDP_MODE];
+#ifdef CONFIG_XDP_SOCKETS
+ /** @xsk_pools: assigned AF_XDP pools, ops protected */
+ struct hlist_head xsk_pools;
+#endif
+
u8 dev_addr_shadow[MAX_ADDR_LEN];
netdevice_tracker linkwatch_dev_tracker;
netdevice_tracker watchdog_dev_tracker;
@@ -2838,6 +2853,13 @@ static inline void *netdev_priv(const struct net_device *dev)
*/
static inline struct net_device *netdev_from_priv(const void *priv)
{
+ /*
+ * When GCC can see that @priv came from netdev_priv(), it can
+ * compute an object size of 0 for the net_device and its members,
+ * which makes FORTIFY_SOURCE fail valid accesses through the result:
+ * https://gcc.gnu.org/bugzilla/show_bug.cgi?id=127875
+ */
+ OPTIMIZER_HIDE_VAR(priv);
return container_of(priv, struct net_device, priv);
}
@@ -3669,7 +3691,11 @@ struct page_pool_bh {
};
DECLARE_PER_CPU(struct page_pool_bh, system_page_pool);
+#ifdef CONFIG_KASAN
+#define XMIT_RECURSION_LIMIT 4
+#else
#define XMIT_RECURSION_LIMIT 8
+#endif
#ifndef CONFIG_PREEMPT_RT
static inline int dev_recursion_level(void)
@@ -5160,6 +5186,7 @@ int dev_mc_sync_multiple(struct net_device *to, struct net_device *from);
void dev_mc_unsync(struct net_device *to, struct net_device *from);
void dev_mc_flush(struct net_device *dev);
void dev_mc_init(struct net_device *dev);
+int dev_mc_dump(struct sk_buff *skb, struct netlink_callback *cb);
/**
* __dev_mc_sync - Synchronize device's multicast list
@@ -5321,7 +5348,6 @@ void netdev_lower_state_changed(struct net_device *lower_dev,
void *lower_state_info);
#define NETDEV_RSS_KEY_LEN 256
-extern u8 netdev_rss_key[NETDEV_RSS_KEY_LEN] __read_mostly;
void netdev_rss_key_fill(void *buffer, size_t len);
int skb_checksum_help(struct sk_buff *skb);
@@ -5494,7 +5520,14 @@ void netif_stacked_transfer_operstate(const struct net_device *rootdev,
netdev_features_t passthru_features_check(struct sk_buff *skb,
struct net_device *dev,
netdev_features_t features);
-netdev_features_t netif_skb_features(struct sk_buff *skb);
+netdev_features_t __netif_skb_features(struct sk_buff *skb,
+ bool check_gso_limits);
+
+static inline netdev_features_t netif_skb_features(struct sk_buff *skb)
+{
+ return __netif_skb_features(skb, true);
+}
+
void skb_warn_bad_offload(const struct sk_buff *skb);
static inline bool net_gso_ok(netdev_features_t features, int gso_type)
@@ -5560,15 +5593,6 @@ netif_get_gro_max_size(const struct net_device *dev, const struct sk_buff *skb)
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;
@@ -5606,12 +5630,12 @@ static inline bool netif_has_l3_rx_handler(const struct net_device *dev)
static inline bool netif_is_l3_master(const struct net_device *dev)
{
- return dev->priv_flags & IFF_L3MDEV_MASTER;
+ return IS_ENABLED(CONFIG_NET_VRF) && (dev->priv_flags & IFF_L3MDEV_MASTER);
}
static inline bool netif_is_l3_slave(const struct net_device *dev)
{
- return dev->priv_flags & IFF_L3MDEV_SLAVE;
+ return IS_ENABLED(CONFIG_NET_VRF) && (dev->priv_flags & IFF_L3MDEV_SLAVE);
}
static inline int dev_sdif(const struct net_device *dev)
@@ -5711,6 +5735,12 @@ static inline const char *netdev_name(const struct net_device *dev)
return dev->name;
}
+/* Caller holds RTNL, netdev->lock or RCU */
+static inline bool netif_is_alive(const struct net_device *dev)
+{
+ return READ_ONCE(dev->reg_state) <= NETREG_REGISTERED;
+}
+
static inline const char *netdev_reg_state(const struct net_device *dev)
{
u8 reg_state = READ_ONCE(dev->reg_state);
diff --git a/include/linux/netfilter_arp/arp_tables.h b/include/linux/netfilter_arp/arp_tables.h
index 05631a25e622..8b8d472eff34 100644
--- a/include/linux/netfilter_arp/arp_tables.h
+++ b/include/linux/netfilter_arp/arp_tables.h
@@ -56,23 +56,4 @@ void arpt_unregister_table(struct net *net, const char *name);
extern unsigned int arpt_do_table(void *priv, struct sk_buff *skb,
const struct nf_hook_state *state);
-#ifdef CONFIG_NETFILTER_XTABLES_COMPAT
-#include <net/compat.h>
-
-struct compat_arpt_entry {
- struct arpt_arp arp;
- __u16 target_offset;
- __u16 next_offset;
- compat_uint_t comefrom;
- struct compat_xt_counters counters;
- unsigned char elems[];
-};
-
-static inline struct xt_entry_target *
-compat_arpt_get_target(struct compat_arpt_entry *e)
-{
- return (void *)e + e->target_offset;
-}
-
-#endif /* CONFIG_COMPAT */
#endif /* _ARPTABLES_H */
diff --git a/include/linux/netfilter_netdev.h b/include/linux/netfilter_netdev.h
index 3175073a66ba..2a854a0bbd4b 100644
--- a/include/linux/netfilter_netdev.h
+++ b/include/linux/netfilter_netdev.h
@@ -133,7 +133,7 @@ static inline struct sk_buff *nf_hook_egress(struct sk_buff *skb, int *rc,
static inline void nf_skip_egress(struct sk_buff *skb, bool skip)
{
-#ifdef CONFIG_NETFILTER_SKIP_EGRESS
+#ifdef CONFIG_NET_EGRESS
skb->nf_skip_egress = skip;
#endif
}
diff --git a/include/linux/netfs.h b/include/linux/netfs.h
index f837a501008c..e5961450f3f1 100644
--- a/include/linux/netfs.h
+++ b/include/linux/netfs.h
@@ -22,6 +22,7 @@
enum netfs_sreq_ref_trace;
typedef struct mempool mempool_t;
+struct fscache_occupancy;
struct folio_queue;
/**
@@ -62,8 +63,8 @@ struct netfs_inode {
struct fscache_cookie *cache;
#endif
struct list_head wb_queue; /* Queue of processes wanting to do writeback */
- loff_t _remote_i_size; /* Size of the remote file */
- loff_t _zero_point; /* Size after which we assume there's no data
+ uoff_t _remote_i_size; /* Size of the remote file */
+ uoff_t _zero_point; /* Size after which we assume there's no data
* on the server */
spinlock_t lock; /* Lock covering wb_queue */
atomic_t io_count; /* Number of outstanding reqs */
@@ -125,6 +126,12 @@ static inline struct netfs_group *netfs_folio_group(struct folio *folio)
return priv;
}
+enum netfs_cache_collect {
+ NETFS_CACHE_COLLECT_WRITE_GAP, /* Gap in collection, no state either way */
+ NETFS_CACHE_COLLECT_WRITE_DATA, /* Currently collecting good writes */
+ NETFS_CACHE_COLLECT_WRITE_CANCEL, /* Currently collecting cancelled writes */
+};
+
/*
* Stream of I/O subrequests going to a particular destination, such as the
* server or the local cache. This is mainly intended for writing where we may
@@ -142,7 +149,7 @@ struct netfs_io_stream {
void (*issue_write)(struct netfs_io_subrequest *subreq);
/* Collection tracking */
struct list_head subrequests; /* Contributory I/O operations */
- unsigned long long collected_to; /* Position we've collected results to */
+ uoff_t collected_to; /* Position we've collected results to */
size_t transferred; /* The amount transferred from this stream */
unsigned short error; /* Aggregate error for the stream */
enum netfs_io_source source; /* Where to read from/write to */
@@ -152,6 +159,7 @@ struct netfs_io_stream {
bool need_retry; /* T if this stream needs retrying */
bool failed; /* T if this stream failed */
bool transferred_valid; /* T is ->transferred is valid */
+ enum netfs_cache_collect cache_collect; /* Current writeback cache collect state */
};
/*
@@ -161,8 +169,11 @@ struct netfs_cache_resources {
const struct netfs_cache_ops *ops;
void *cache_priv;
void *cache_priv2;
- unsigned int debug_id; /* Cookie debug ID */
+ uoff_t cache_i_size; /* Initial size of cache file */
+ unsigned int cookie_id; /* Cache cookie debug ID */
+ unsigned int object_id; /* Cache object debug ID */
unsigned int inval_counter; /* object->inval_counter at begin_op */
+ unsigned int dio_size; /* DIO block size */
};
/*
@@ -177,7 +188,7 @@ struct netfs_io_subrequest {
struct work_struct work;
struct list_head rreq_link; /* Link in rreq->subrequests */
struct iov_iter io_iter; /* Iterator for this subrequest */
- unsigned long long start; /* Where to start the I/O */
+ uoff_t start; /* Where to start the I/O */
size_t len; /* Size of the I/O */
size_t transferred; /* Amount of data transferred */
refcount_t ref;
@@ -196,6 +207,7 @@ struct netfs_io_subrequest {
#define NETFS_SREQ_IN_PROGRESS 8 /* Unlocked when the subrequest completes */
#define NETFS_SREQ_NEED_RETRY 9 /* Set if the filesystem requests a retry */
#define NETFS_SREQ_FAILED 10 /* Set if the subreq failed unretryably */
+#define NETFS_SREQ_CANCELLED 11 /* Set if the subreq was cancelled by netfslib */
};
enum netfs_io_origin {
@@ -208,7 +220,6 @@ enum netfs_io_origin {
NETFS_DIO_READ, /* This is a direct I/O read */
NETFS_WRITEBACK, /* This write was triggered by writepages */
NETFS_WRITEBACK_SINGLE, /* This monolithic write was triggered by writepages */
- NETFS_WRITETHROUGH, /* This write was made by netfs_perform_write() */
NETFS_UNBUFFERED_WRITE, /* This is an unbuffered write */
NETFS_DIO_WRITE, /* This is a direct I/O write */
NETFS_PGPRIV2_COPY_TO_CACHE, /* [DEPRECATED] This is writing read data to the cache */
@@ -243,16 +254,18 @@ struct netfs_io_request {
void *netfs_priv; /* Private data for the netfs */
void *netfs_priv2; /* Private data for the netfs */
struct bio_vec *direct_bv; /* DIO buffer list (when handling iovec-iter) */
- unsigned long long submitted; /* Amount submitted for I/O so far */
- unsigned long long len; /* Length of the request */
+ uoff_t submitted; /* Amount submitted for I/O so far */
+ uoff_t len; /* Length of the request */
size_t transferred; /* Amount to be indicated as transferred */
+ size_t progress_at; /* Report read progress when hit this much read */
long error; /* 0 or error that occurred */
- unsigned long long i_size; /* Size of the file */
- unsigned long long start; /* Start position */
+ uoff_t i_size; /* Size of the file */
+ uoff_t start; /* Start position */
atomic64_t issued_to; /* Write issuer folio cursor */
- unsigned long long collected_to; /* Point we've collected to */
- unsigned long long cleaned_to; /* Position we've cleaned folios to */
- unsigned long long abandon_to; /* Position to abandon folios to */
+ uoff_t collected_to; /* Point we've collected to */
+ uoff_t cache_coll_to; /* Point the cache has collected to */
+ uoff_t cleaned_to; /* Position we've cleaned folios to */
+ uoff_t abandon_to; /* Position to abandon folios to */
const struct folio *no_unlock_folio; /* Don't unlock this folio after read */
gfp_t gfp; /* GFP flags to use */
unsigned int direct_bv_count; /* Number of elements in direct_bv[] */
@@ -262,7 +275,6 @@ struct netfs_io_request {
atomic_t subreq_counter; /* Next subreq->debug_index */
unsigned int nr_group_rel; /* Number of refs to release on ->group */
spinlock_t lock; /* Lock for queuing subreqs */
- unsigned char front_folio_order; /* Order (size) of front folio */
enum netfs_io_origin origin; /* Origin of the request */
bool direct_bv_unpin; /* T if direct_bv[] must be unpinned */
refcount_t ref;
@@ -273,13 +285,18 @@ struct netfs_io_request {
#define NETFS_RREQ_FAILED 3 /* The request failed */
#define NETFS_RREQ_RETRYING 4 /* Set if we're in the retry path */
#define NETFS_RREQ_SHORT_TRANSFER 5 /* Set if we have a short transfer */
-#define NETFS_RREQ_OFFLOAD_COLLECTION 8 /* Offload collection to workqueue */
-#define NETFS_RREQ_NO_UNLOCK_FOLIO 9 /* Don't unlock no_unlock_folio on completion */
-#define NETFS_RREQ_FOLIO_COPY_TO_CACHE 10 /* Copy current folio to cache from read */
-#define NETFS_RREQ_UPLOAD_TO_SERVER 11 /* Need to write to the server */
-#define NETFS_RREQ_USE_IO_ITER 12 /* Use ->io_iter rather than ->i_pages */
+#define NETFS_RREQ_CACHE_STOP 8 /* Set to stop caching (ENOBUFS or error) */
+#define NETFS_RREQ_CACHE_ERROR 9 /* Set if we got an error from the cache */
+#define NETFS_RREQ_CANCEL_CACHING 10 /* Set to cancel caching */
+#define NETFS_RREQ_OFFLOAD_COLLECTION 12 /* Offload collection to workqueue */
+#define NETFS_RREQ_NO_UNLOCK_FOLIO 13 /* Don't unlock no_unlock_folio on completion */
+#define NETFS_RREQ_UPLOAD_TO_SERVER 14 /* Need to write to the server */
+#define NETFS_RREQ_USE_IO_ITER 15 /* Use ->io_iter rather than ->i_pages */
+#define NETFS_RREQ_NEED_PUT_RA_REFS 17 /* Need to put the folio refs RA gave us */
+#ifdef CONFIG_NETFS_PGPRIV2
#define NETFS_RREQ_USE_PGPRIV2 31 /* [DEPRECATED] Use PG_private_2 to mark
* write to cache on read */
+#endif
const struct netfs_request_ops *netfs_ops;
};
@@ -298,12 +315,12 @@ struct netfs_request_ops {
int (*prepare_read)(struct netfs_io_subrequest *subreq);
void (*issue_read)(struct netfs_io_subrequest *subreq);
bool (*is_still_valid)(struct netfs_io_request *rreq);
- int (*check_write_begin)(struct file *file, loff_t pos, unsigned len,
+ int (*check_write_begin)(struct file *file, uoff_t pos, unsigned len,
struct folio **foliop, void **_fsdata);
void (*done)(struct netfs_io_request *rreq);
/* Modification handling */
- void (*update_i_size)(struct inode *inode, loff_t i_size);
+ void (*update_i_size)(struct inode *inode, uoff_t i_size);
void (*post_modify)(struct inode *inode);
/* Write request handling */
@@ -331,7 +348,7 @@ struct netfs_cache_ops {
/* Read data from the cache */
int (*read)(struct netfs_cache_resources *cres,
- loff_t start_pos,
+ uoff_t start_pos,
struct iov_iter *iter,
enum netfs_read_from_hole read_hole,
netfs_io_terminated_t term_func,
@@ -339,7 +356,7 @@ struct netfs_cache_ops {
/* Write data to the cache */
int (*write)(struct netfs_cache_resources *cres,
- loff_t start_pos,
+ uoff_t start_pos,
struct iov_iter *iter,
netfs_io_terminated_t term_func,
void *term_func_priv);
@@ -349,15 +366,14 @@ struct netfs_cache_ops {
/* Expand readahead request */
void (*expand_readahead)(struct netfs_cache_resources *cres,
- unsigned long long *_start,
- unsigned long long *_len,
- unsigned long long i_size);
+ uoff_t *_start,
+ uoff_t *_len,
+ uoff_t i_size);
/* Prepare a read operation, shortening it to a cached/uncached
* boundary as appropriate.
*/
- enum netfs_io_source (*prepare_read)(struct netfs_io_subrequest *subreq,
- unsigned long long i_size);
+ int (*prepare_read)(struct netfs_io_subrequest *subreq);
/* Prepare a write subrequest, working out if we're allowed to do it
* and finding out the maximum amount of data to gather before
@@ -370,15 +386,24 @@ struct netfs_cache_ops {
* actually do.
*/
int (*prepare_write)(struct netfs_cache_resources *cres,
- loff_t *_start, size_t *_len, size_t upper_len,
- loff_t i_size, bool no_space_allocated_yet);
+ uoff_t *_start, size_t *_len, size_t upper_len,
+ uoff_t i_size, bool no_space_allocated_yet);
/* Query the occupancy of the cache in a region, returning where the
* next chunk of data starts and how long it is.
*/
int (*query_occupancy)(struct netfs_cache_resources *cres,
- loff_t start, size_t len, size_t granularity,
- loff_t *_data_start, size_t *_data_len);
+ struct fscache_occupancy *occ);
+
+ /* Collect the result of buffered writeback to the cache. This
+ * includes copying a read to the cache. block_type is one of:
+ * - NETFS_CACHE_COLLECT_WRITE_DATA for a block of data
+ * - NETFS_CACHE_COLLECT_WRITE_GAP if a discontiguity was skipped
+ * - NETFS_CACHE_COLLECT_WRITE_CANCEL for a cancellation gap
+ */
+ void (*collect_write)(struct netfs_io_request *wreq,
+ uoff_t start, size_t len,
+ enum netfs_cache_collect block_type);
};
/* High-level read API. */
@@ -396,6 +421,8 @@ ssize_t netfs_unbuffered_write_iter(struct kiocb *iocb, struct iov_iter *from);
ssize_t netfs_unbuffered_write_iter_locked(struct kiocb *iocb, struct iov_iter *iter,
struct netfs_group *netfs_group);
ssize_t netfs_file_write_iter(struct kiocb *iocb, struct iov_iter *from);
+void netfs_clear_stale_post_isize(struct inode *inode, uoff_t from,
+ uoff_t to);
/* Single, monolithic object read/write API. */
void netfs_single_mark_inode_dirty(struct inode *inode);
@@ -409,7 +436,7 @@ struct readahead_control;
void netfs_readahead(struct readahead_control *);
int netfs_read_folio(struct file *, struct folio *);
int netfs_write_begin(struct netfs_inode *, struct file *,
- struct address_space *, loff_t pos, unsigned int len,
+ struct address_space *, uoff_t pos, unsigned int len,
struct folio **, void **fsdata);
int netfs_writepages(struct address_space *mapping,
struct writeback_control *wbc);
@@ -487,10 +514,10 @@ static inline struct netfs_inode *netfs_inode(struct inode *inode)
* cmpxchg8b without the need of the lock prefix). For SMP compiles and 64bit
* archs it makes no difference if preempt is enabled or not.
*/
-static inline unsigned long long netfs_read_remote_i_size(const struct inode *inode)
+static inline uoff_t netfs_read_remote_i_size(const struct inode *inode)
{
const struct netfs_inode *ictx = container_of(inode, struct netfs_inode, inode);
- unsigned long long remote_i_size;
+ uoff_t remote_i_size;
#if BITS_PER_LONG==32 && defined(CONFIG_SMP)
unsigned int seq;
@@ -525,7 +552,7 @@ static inline unsigned long long netfs_read_remote_i_size(const struct inode *in
* spinning forever.
*/
static inline void netfs_write_remote_i_size(struct inode *inode,
- unsigned long long remote_i_size)
+ uoff_t remote_i_size)
{
struct netfs_inode *ictx = netfs_inode(inode);
@@ -562,10 +589,10 @@ static inline void netfs_write_remote_i_size(struct inode *inode,
* cmpxchg8b without the need of the lock prefix). For SMP compiles and 64bit
* archs it makes no difference if preempt is enabled or not.
*/
-static inline unsigned long long netfs_read_zero_point(const struct inode *inode)
+static inline uoff_t netfs_read_zero_point(const struct inode *inode)
{
struct netfs_inode *ictx = container_of(inode, struct netfs_inode, inode);
- unsigned long long zero_point;
+ uoff_t zero_point;
#if BITS_PER_LONG==32 && defined(CONFIG_SMP)
unsigned int seq;
@@ -600,7 +627,7 @@ static inline unsigned long long netfs_read_zero_point(const struct inode *inode
* forever.
*/
static inline void netfs_write_zero_point(struct inode *inode,
- unsigned long long zero_point)
+ uoff_t zero_point)
{
struct netfs_inode *ictx = netfs_inode(inode);
@@ -641,9 +668,9 @@ static inline void netfs_write_zero_point(struct inode *inode,
* archs it makes no difference if preempt is enabled or not.
*/
static inline void netfs_read_sizes(const struct inode *inode,
- unsigned long long *i_size,
- unsigned long long *remote_i_size,
- unsigned long long *zero_point)
+ uoff_t *i_size,
+ uoff_t *remote_i_size,
+ uoff_t *zero_point)
{
const struct netfs_inode *ictx = container_of(inode, struct netfs_inode, inode);
#if BITS_PER_LONG==32 && defined(CONFIG_SMP)
@@ -689,9 +716,9 @@ static inline void netfs_read_sizes(const struct inode *inode,
* forever.
*/
static inline void netfs_write_sizes(struct inode *inode,
- unsigned long long i_size,
- unsigned long long remote_i_size,
- unsigned long long zero_point)
+ uoff_t i_size,
+ uoff_t remote_i_size,
+ uoff_t zero_point)
{
struct netfs_inode *ictx = netfs_inode(inode);
@@ -759,7 +786,7 @@ static inline void netfs_inode_init(struct netfs_inode *ctx,
* Inform the netfs lib that a file got resized so that it can adjust its state.
*/
static inline void netfs_resize_file(struct netfs_inode *ictx,
- unsigned long long new_i_size,
+ uoff_t new_i_size,
bool changed_on_server)
{
#if BITS_PER_LONG==32 && defined(CONFIG_SMP)
diff --git a/include/linux/netpoll.h b/include/linux/netpoll.h
index 1c6b1eec5efd..ec0821a5b02d 100644
--- a/include/linux/netpoll.h
+++ b/include/linux/netpoll.h
@@ -16,11 +16,6 @@
#include <linux/ip.h>
#include <linux/udp.h>
-union inet_addr {
- __be32 ip;
- struct in6_addr in6;
-};
-
struct netpoll {
struct net_device *dev;
netdevice_tracker dev_tracker;
diff --git a/include/linux/nfs_fs.h b/include/linux/nfs_fs.h
index b85a73ae7919..d2c716322c6f 100644
--- a/include/linux/nfs_fs.h
+++ b/include/linux/nfs_fs.h
@@ -437,11 +437,11 @@ extern int nfs_refresh_inode(struct inode *, struct nfs_fattr *);
extern int nfs_post_op_update_inode(struct inode *inode, struct nfs_fattr *fattr);
extern int nfs_post_op_update_inode_force_wcc(struct inode *inode, struct nfs_fattr *fattr);
extern int nfs_post_op_update_inode_force_wcc_locked(struct inode *inode, struct nfs_fattr *fattr);
-extern int nfs_getattr(struct mnt_idmap *, const struct path *,
+extern int nfs_getattr(const struct mnt_idmap *, const struct path *,
struct kstat *, u32, unsigned int);
extern void nfs_access_add_cache(struct inode *, struct nfs_access_entry *, const struct cred *);
extern void nfs_access_set_mask(struct nfs_access_entry *, u32);
-extern int nfs_permission(struct mnt_idmap *, struct inode *, int);
+extern int nfs_permission(const struct mnt_idmap *, struct inode *, int);
extern int nfs_open(struct inode *, struct file *);
extern int nfs_attribute_cache_expired(struct inode *inode);
extern int nfs_revalidate_inode(struct inode *inode, unsigned long flags);
@@ -450,7 +450,7 @@ extern int nfs_clear_invalid_mapping(struct address_space *mapping);
extern bool nfs_mapping_need_revalidate_inode(struct inode *inode);
extern int nfs_revalidate_mapping(struct inode *inode, struct address_space *mapping);
extern int nfs_revalidate_mapping_rcu(struct inode *inode);
-extern int nfs_setattr(struct mnt_idmap *, struct dentry *, struct iattr *);
+extern int nfs_setattr(const struct mnt_idmap *, struct dentry *, struct iattr *);
extern void nfs_setattr_update_inode(struct inode *inode, struct iattr *attr, struct nfs_fattr *);
extern void nfs_setsecurity(struct inode *inode, struct nfs_fattr *fattr);
extern struct nfs_open_context *get_nfs_open_context(struct nfs_open_context *ctx);
diff --git a/include/linux/notifier.h b/include/linux/notifier.h
index 01b6c9d9956f..4eeae9741a6e 100644
--- a/include/linux/notifier.h
+++ b/include/linux/notifier.h
@@ -46,6 +46,7 @@
* often but notifier_blocks will seldom be removed.
*/
+struct device;
struct notifier_block;
typedef int (*notifier_fn_t)(struct notifier_block *nb,
@@ -145,8 +146,14 @@ extern void srcu_init_notifier_head(struct srcu_notifier_head *nh);
extern int atomic_notifier_chain_register(struct atomic_notifier_head *nh,
struct notifier_block *nb);
+int devm_atomic_notifier_chain_register(struct device *dev,
+ struct atomic_notifier_head *nh,
+ struct notifier_block *nb);
extern int blocking_notifier_chain_register(struct blocking_notifier_head *nh,
struct notifier_block *nb);
+int devm_blocking_notifier_chain_register(struct device *dev,
+ struct blocking_notifier_head *nh,
+ struct notifier_block *nb);
extern int raw_notifier_chain_register(struct raw_notifier_head *nh,
struct notifier_block *nb);
extern int srcu_notifier_chain_register(struct srcu_notifier_head *nh,
diff --git a/include/linux/ns/ns_common_types.h b/include/linux/ns/ns_common_types.h
index ea45c54e4435..47a5cfe2326a 100644
--- a/include/linux/ns/ns_common_types.h
+++ b/include/linux/ns/ns_common_types.h
@@ -116,10 +116,11 @@ struct ns_common {
struct dentry *stashed;
const struct proc_ns_operations *ops;
unsigned int inum;
- union {
- struct ns_tree;
- struct rcu_head ns_rcu;
- };
+#ifdef CONFIG_SECURITY
+ void *ns_security;
+#endif
+ struct ns_tree;
+ struct rcu_head ns_rcu;
};
#define to_ns_common(__ns) \
diff --git a/include/linux/nsproxy.h b/include/linux/nsproxy.h
index 5a67648721c7..dc2447f5f092 100644
--- a/include/linux/nsproxy.h
+++ b/include/linux/nsproxy.h
@@ -100,6 +100,7 @@ void exit_cred_namespaces(struct task_struct *tsk);
void switch_task_namespaces(struct task_struct *tsk, struct nsproxy *new);
int exec_task_namespaces(void);
void deactivate_nsproxy(struct nsproxy *ns);
+void nsproxy_free(struct nsproxy *ns);
int unshare_nsproxy_namespaces(unsigned long, struct nsproxy **,
struct cred *, struct fs_struct *);
int __init nsproxy_cache_init(void);
diff --git a/include/linux/nvme.h b/include/linux/nvme.h
index 91ce434a7e8d..6248711784b3 100644
--- a/include/linux/nvme.h
+++ b/include/linux/nvme.h
@@ -1266,8 +1266,8 @@ enum {
NVME_ZRASF_ZONE_STATE_IMP_OPEN = 0x02,
NVME_ZRASF_ZONE_STATE_EXP_OPEN = 0x03,
NVME_ZRASF_ZONE_STATE_CLOSED = 0x04,
- NVME_ZRASF_ZONE_STATE_READONLY = 0x05,
- NVME_ZRASF_ZONE_STATE_FULL = 0x06,
+ NVME_ZRASF_ZONE_STATE_FULL = 0x05,
+ NVME_ZRASF_ZONE_STATE_READONLY = 0x06,
NVME_ZRASF_ZONE_STATE_OFFLINE = 0x07,
NVME_REPORT_ZONE_PARTIAL = 1,
};
diff --git a/include/linux/of.h b/include/linux/of.h
index b920aac6b975..44d83133a65a 100644
--- a/include/linux/of.h
+++ b/include/linux/of.h
@@ -1837,7 +1837,6 @@ struct of_overlay_notify_data {
int of_overlay_fdt_apply(const void *overlay_fdt, u32 overlay_fdt_size,
int *ovcs_id, const struct device_node *target_base);
int of_overlay_remove(int *ovcs_id);
-int of_overlay_remove_all(void);
int of_overlay_notifier_register(struct notifier_block *nb);
int of_overlay_notifier_unregister(struct notifier_block *nb);
@@ -1855,11 +1854,6 @@ static inline int of_overlay_remove(int *ovcs_id)
return -ENOTSUPP;
}
-static inline int of_overlay_remove_all(void)
-{
- return -ENOTSUPP;
-}
-
static inline int of_overlay_notifier_register(struct notifier_block *nb)
{
return 0;
diff --git a/include/linux/once_lite.h b/include/linux/once_lite.h
index 236592c4eeb1..5e2b67039aaf 100644
--- a/include/linux/once_lite.h
+++ b/include/linux/once_lite.h
@@ -10,19 +10,21 @@
#define DO_ONCE_LITE(func, ...) \
DO_ONCE_LITE_IF(true, func, ##__VA_ARGS__)
-#define __ONCE_LITE_IF(condition) \
+#define __ONCE_LITE() \
({ \
static bool __section(".data..once") __already_done; \
- bool __ret_cond = !!(condition); \
bool __ret_once = false; \
\
- if (unlikely(__ret_cond) && unlikely(!__already_done)) {\
+ if (unlikely(!__already_done)) { \
__already_done = true; \
__ret_once = true; \
} \
unlikely(__ret_once); \
})
+#define __ONCE_LITE_IF(condition) \
+ (unlikely(condition) && __ONCE_LITE())
+
#define DO_ONCE_LITE_IF(condition, func, ...) \
({ \
bool __ret_do_once = !!(condition); \
diff --git a/include/linux/overflow.h b/include/linux/overflow.h
index a8cb6319b4fb..d0f04436343e 100644
--- a/include/linux/overflow.h
+++ b/include/linux/overflow.h
@@ -418,7 +418,7 @@ static __always_inline size_t __must_check size_sub(size_t minuend, size_t subtr
#define flex_array_size(p, member, count) \
__builtin_choose_expr(__is_constexpr(count), \
(count) * sizeof(*(p)->member) + __must_be_array((p)->member), \
- size_mul(count, sizeof(*(p)->member) + __must_be_array((p)->member)))
+ size_mul(count, sizeof(*(p)->member)) + __must_be_array((p)->member))
/**
* struct_size() - Calculate size of structure with trailing flexible array.
diff --git a/include/linux/page-flags.h b/include/linux/page-flags.h
index 7a863572adce..b0ddc652e76c 100644
--- a/include/linux/page-flags.h
+++ b/include/linux/page-flags.h
@@ -44,10 +44,6 @@
* Consequently, PG_reserved for a page mapped into user space can indicate
* the zero page, the vDSO, MMIO pages or device memory.
*
- * The PG_private bitflag is set on pagecache pages if they contain filesystem
- * specific data (which is normally at page->private). It can be used by
- * private allocations for its own usage.
- *
* During initiation of disk I/O, PG_locked is set. This bit is set before I/O
* and cleared when writeback _starts_ or when read _completes_. PG_writeback
* is set before writeback starts and cleared when it finishes.
@@ -105,7 +101,7 @@ enum pageflags {
PG_owner_2, /* Owner use. If pagecache, fs may use */
PG_arch_1,
PG_reserved,
- PG_private, /* If pagecache, has fs-private data */
+ PG_folio, /* Do not use: reserved for folio identification */
PG_private_2, /* If pagecache, has fs aux data */
PG_reclaim, /* To be reclaimed asap */
PG_swapbacked, /* Page is backed by RAM/swap */
@@ -208,14 +204,13 @@ enum pageflags {
static __always_inline bool compound_info_has_mask(void)
{
/*
- * Limit mask usage to HugeTLB vmemmap optimization (HVO) where it
- * makes a difference.
+ * Limit mask usage to HVO where it makes a difference.
*
* The approach with mask would work in the wider set of conditions,
* but it requires validating that struct pages are naturally aligned
* for all orders up to the MAX_FOLIO_ORDER, which can be tricky.
*/
- if (!IS_ENABLED(CONFIG_HUGETLB_PAGE_OPTIMIZE_VMEMMAP))
+ if (!IS_ENABLED(CONFIG_VMEMMAP_OPTIMIZATION))
return false;
return is_power_of_2(sizeof(struct page));
@@ -576,9 +571,19 @@ FOLIO_FLAG(swapbacked, FOLIO_HEAD_PAGE)
/*
* Private page markings that may be used by the filesystem that owns the page
* for its own purposes.
- * - PG_private and PG_private_2 cause release_folio() and co to be invoked
+ * - folio->private and PG_private_2 cause release_folio() and co to be invoked
*/
-PAGEFLAG(Private, private, PF_ANY)
+
+static __always_inline bool folio_test_private(const struct folio *folio)
+{
+ /*
+ * data_race() is added for readers without holding the folio lock.
+ * Only the NULL/non-NULL answer is used and both are valid while
+ * private is being attached or detached, so the race is benign.
+ */
+ return data_race(folio->private);
+}
+
FOLIO_FLAG(private_2, FOLIO_HEAD_PAGE)
/* owner_2 can be set on tail pages for anon memory */
@@ -588,13 +593,12 @@ FOLIO_FLAG(owner_2, FOLIO_HEAD_PAGE)
* Only test-and-set exist for PG_writeback. The unconditional operators are
* risky: they bypass page accounting.
*/
-TESTPAGEFLAG(Writeback, writeback, PF_NO_TAIL)
- TESTSCFLAG(Writeback, writeback, PF_NO_TAIL)
+FOLIO_TEST_FLAG(writeback, FOLIO_HEAD_PAGE)
+ FOLIO_TEST_SET_FLAG(writeback, FOLIO_HEAD_PAGE)
FOLIO_FLAG(mappedtodisk, FOLIO_HEAD_PAGE)
/* PG_readahead is only used for reads; PG_reclaim is only for writes */
-PAGEFLAG(Reclaim, reclaim, PF_NO_TAIL)
- TESTCLEARFLAG(Reclaim, reclaim, PF_NO_TAIL)
+FOLIO_FLAG(reclaim, FOLIO_HEAD_PAGE)
FOLIO_FLAG(readahead, FOLIO_HEAD_PAGE)
FOLIO_TEST_CLEAR_FLAG(readahead, FOLIO_HEAD_PAGE)
@@ -656,6 +660,7 @@ TESTSCFLAG(HWPoison, hwpoison, PF_ANY)
#define __PG_HWPOISON (1UL << PG_hwpoison)
#else
PAGEFLAG_FALSE(HWPoison, hwpoison)
+TESTSCFLAG_FALSE(HWPoison, hwpoison)
#define __PG_HWPOISON 0
#endif
@@ -1170,7 +1175,7 @@ static __always_inline void __ClearPageAnonExclusive(struct page *page)
*/
#define PAGE_FLAGS_CHECK_AT_FREE \
(1UL << PG_lru | 1UL << PG_locked | \
- 1UL << PG_private | 1UL << PG_private_2 | \
+ 1UL << PG_private_2 | \
1UL << PG_writeback | 1UL << PG_reserved | \
1UL << PG_active | \
1UL << PG_unevictable | __PG_MLOCKED | LRU_GEN_MASK)
@@ -1194,8 +1199,31 @@ static __always_inline void __ClearPageAnonExclusive(struct page *page)
(0xffUL /* order */ | 1UL << PG_has_hwpoisoned | \
1UL << PG_large_rmappable | 1UL << PG_partially_mapped)
-#define PAGE_FLAGS_PRIVATE \
- (1UL << PG_private | 1UL << PG_private_2)
+/**
+ * folio_has_attached_private - check if the folio has private data attached
+ * @folio: The folio to check.
+ *
+ * Use this in code that may encounter swapcache or hugetlb folios but only
+ * wants to detect attached private data.
+ *
+ * Return: true if the folio has private data attached.
+ */
+static inline bool folio_has_attached_private(const struct folio *folio)
+{
+ /*
+ * Swapcache stores swp_entry_t in folio->swap, a union with
+ * folio->private, and hugetlb stores its own flags in folio->private;
+ * both are excluded.
+ *
+ * NOTE: For swapcache, folio->swap.val PG_swapcache are not set as
+ * a whole, so folio_test_swapcache() is not reliable to exclude
+ * swapcache. Use folio_test_swapbacked() instead, since it remains set
+ * when a folio is added to/removed from swapcache.
+ */
+
+ return folio_test_private(folio) && !folio_test_swapbacked(folio) &&
+ !folio_test_hugetlb(folio);
+}
/**
* folio_has_private - Determine if folio has private stuff
* @folio: The folio to be checked
@@ -1205,7 +1233,7 @@ static __always_inline void __ClearPageAnonExclusive(struct page *page)
*/
static inline int folio_has_private(const struct folio *folio)
{
- return !!(folio->flags.f & PAGE_FLAGS_PRIVATE);
+ return folio_has_attached_private(folio) || folio_test_private_2(folio);
}
#undef PF_ANY
diff --git a/include/linux/page_counter.h b/include/linux/page_counter.h
index d649b6bbbc87..2baf7a2b29b2 100644
--- a/include/linux/page_counter.h
+++ b/include/linux/page_counter.h
@@ -63,11 +63,12 @@ static inline void page_counter_init(struct page_counter *counter,
counter->track_failcnt = false;
}
-static inline unsigned long page_counter_read(struct page_counter *counter)
+static inline unsigned long page_counter_read(const struct page_counter *counter)
{
return atomic_long_read(&counter->usage);
}
+long page_counter_margin(const struct page_counter *counter);
void page_counter_cancel(struct page_counter *counter, unsigned long nr_pages);
void page_counter_charge(struct page_counter *counter, unsigned long nr_pages);
bool page_counter_try_charge(struct page_counter *counter,
diff --git a/include/linux/pagemap.h b/include/linux/pagemap.h
index 0adfa6605653..bcbb0afe1a68 100644
--- a/include/linux/pagemap.h
+++ b/include/linux/pagemap.h
@@ -594,7 +594,6 @@ static inline void folio_attach_private(struct folio *folio, void *data)
{
folio_get(folio);
folio->private = data;
- folio_set_private(folio);
}
/**
@@ -629,9 +628,8 @@ static inline void *folio_detach_private(struct folio *folio)
{
void *data = folio_get_private(folio);
- if (!folio_test_private(folio))
+ if (!data)
return NULL;
- folio_clear_private(folio);
folio->private = NULL;
folio_put(folio);
@@ -1128,8 +1126,7 @@ static inline pgoff_t linear_anon_page_index(const struct vm_area_struct *vma,
const pgoff_t pgoff = __linear_anon_page_index(vma, address);
VM_WARN_ON_ONCE(!vma_is_cow_mapping(vma));
- /* Account for MAP_PRIVATE-/dev/zero which is only semi-anonymous. */
- if (vma_is_anonymous(vma) && !vma->vm_file)
+ if (vma_is_anonymous(vma))
VM_WARN_ON_ONCE(pgoff != linear_page_index(vma, address));
return pgoff;
@@ -1416,6 +1413,7 @@ struct readahead_control {
bool dropbehind;
bool _workingset;
unsigned long _pflags;
+ bool _forward;
};
#define DEFINE_READAHEAD(ractl, f, r, m, i) \
@@ -1480,18 +1478,29 @@ void page_cache_async_readahead(struct address_space *mapping,
page_cache_async_ra(&ractl, folio, req_count);
}
+/*
+ * Adjust readahead_control to ensure next folio comes from
+ * [_index, _index + _nr_pages) afterwards and reset _batch_count.
+ */
+static inline void __readahead_advance(struct readahead_control *rac)
+{
+ if (rac->_forward)
+ rac->_index += rac->_batch_count;
+
+ rac->_nr_pages -= rac->_batch_count;
+ rac->_batch_count = 0;
+}
+
static inline struct folio *__readahead_folio(struct readahead_control *ractl)
{
struct folio *folio;
BUG_ON(ractl->_batch_count > ractl->_nr_pages);
- ractl->_nr_pages -= ractl->_batch_count;
- ractl->_index += ractl->_batch_count;
+ __readahead_advance(ractl);
+ ractl->_forward = true;
- if (!ractl->_nr_pages) {
- ractl->_batch_count = 0;
+ if (!ractl->_nr_pages)
return NULL;
- }
folio = xa_load(&ractl->mapping->i_pages, ractl->_index);
VM_BUG_ON_FOLIO(!folio_test_locked(folio), folio);
@@ -1517,6 +1526,39 @@ static inline struct folio *readahead_folio(struct readahead_control *ractl)
return folio;
}
+/**
+ * readahead_folio_last - Get the next folio to read, from the tail.
+ * @ractl: The current readahead request.
+ *
+ * Like readahead_folio(), but walks the range back-to-front. The folio is
+ * returned locked with its refcount dropped; the caller unlocks it once I/O
+ * completes. Compound folios are returned once, at their head index.
+ *
+ * Context: The folio is locked.
+ * Return: A pointer to the next folio, or %NULL when done.
+ */
+static inline struct folio *readahead_folio_last(struct readahead_control *ractl)
+{
+ struct folio *folio;
+
+ /* Drop the previously returned batch from the remaining range. */
+ __readahead_advance(ractl);
+ ractl->_forward = false;
+
+ if (!ractl->_nr_pages)
+ return NULL;
+
+ /* xa_load() follows sibling entries, so a tail index returns the head */
+ folio = xa_load(&ractl->mapping->i_pages,
+ ractl->_index + ractl->_nr_pages - 1);
+ VM_WARN_ON_ONCE_FOLIO(!folio_test_locked(folio), folio);
+
+ ractl->_batch_count = folio_nr_pages(folio);
+
+ folio_put(folio);
+ return folio;
+}
+
static inline unsigned int __readahead_batch(struct readahead_control *rac,
struct page **array, unsigned int array_sz)
{
@@ -1525,9 +1567,8 @@ static inline unsigned int __readahead_batch(struct readahead_control *rac,
struct folio *folio;
BUG_ON(rac->_batch_count > rac->_nr_pages);
- rac->_nr_pages -= rac->_batch_count;
- rac->_index += rac->_batch_count;
- rac->_batch_count = 0;
+ __readahead_advance(rac);
+ rac->_forward = true;
xas_set(&xas, rac->_index);
rcu_read_lock();
diff --git a/include/linux/panic.h b/include/linux/panic.h
index f1dd417e54b2..8e7250b0e913 100644
--- a/include/linux/panic.h
+++ b/include/linux/panic.h
@@ -88,7 +88,8 @@ static inline void set_arch_panic_timeout(int timeout, int arch_default_timeout)
#define TAINT_RANDSTRUCT 17
#define TAINT_TEST 18
#define TAINT_FWCTL 19
-#define TAINT_FLAGS_COUNT 20
+#define TAINT_FORCED_BIND 20
+#define TAINT_FLAGS_COUNT 21
#define TAINT_FLAGS_MAX ((1UL << TAINT_FLAGS_COUNT) - 1)
struct taint_flag {
diff --git a/include/linux/pci-epf.h b/include/linux/pci-epf.h
index 704e1dc8b30a..226f3e59cf60 100644
--- a/include/linux/pci-epf.h
+++ b/include/linux/pci-epf.h
@@ -163,7 +163,8 @@ enum pci_epf_doorbell_type {
* For MSI-backed doorbells this is the MSI message, while for
* "embedded" doorbells this represents an MMIO write that asserts
* an interrupt on the EP side.
- * @virq: IRQ number of this doorbell message
+ * @virq: IRQ number of this doorbell message. Multiple messages may use the
+ * same IRQ; consumers must request each distinct IRQ only once.
* @irq_flags: Required flags for request_irq()/request_threaded_irq().
* Callers may OR-in additional flags (e.g. IRQF_ONESHOT).
* @type: Doorbell type.
diff --git a/include/linux/pci.h b/include/linux/pci.h
index d31a8d107b1e..ef6327205520 100644
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -467,6 +467,7 @@ struct pci_dev {
unsigned int is_busmaster:1; /* Is busmaster */
unsigned int no_msi:1; /* May not use MSI */
+ unsigned int no_aer_anfe:1; /* Do not unmask ANFE */
unsigned int block_cfg_access:1; /* Config space access blocked */
unsigned int broken_parity_status:1; /* Generates false positive parity */
unsigned int irq_reroute_variant:2; /* Needs IRQ rerouting variant */
@@ -1915,12 +1916,14 @@ static inline int pci_irqd_intx_xlate(struct irq_domain *d,
#ifdef CONFIG_PCIEPORTBUS
extern bool pcie_ports_disabled;
extern bool pcie_ports_native;
+extern bool pcie_ports_dpc_native;
int pcie_set_target_speed(struct pci_dev *port, enum pci_bus_speed speed_req,
bool use_lt);
#else
#define pcie_ports_disabled true
#define pcie_ports_native false
+#define pcie_ports_dpc_native false
static inline int pcie_set_target_speed(struct pci_dev *port,
enum pci_bus_speed speed_req,
diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h
index 63774ae2bf71..030c86dd6d67 100644
--- a/include/linux/pci_ids.h
+++ b/include/linux/pci_ids.h
@@ -889,6 +889,7 @@
#define PCI_DEVICE_ID_TI_XX12 0x8039
#define PCI_DEVICE_ID_TI_XX12_FM 0x803b
#define PCI_DEVICE_ID_TI_XIO2000A 0x8231
+#define PCI_DEVICE_ID_TI_TUSB73X0 0x8241
#define PCI_DEVICE_ID_TI_1130 0xac12
#define PCI_DEVICE_ID_TI_1031 0xac13
#define PCI_DEVICE_ID_TI_1131 0xac15
@@ -2732,6 +2733,7 @@
#define PCI_DEVICE_ID_INTEL_HDA_HSW_3 0x0d0c
#define PCI_DEVICE_ID_INTEL_HDA_BYT 0x0f04
#define PCI_DEVICE_ID_INTEL_SST_BYT 0x0f28
+#define PCI_DEVICE_ID_INTEL_ISP_BYT 0x0f38
#define PCI_DEVICE_ID_INTEL_8257X_SOL 0x1062
#define PCI_DEVICE_ID_INTEL_82573E_SOL 0x1085
#define PCI_DEVICE_ID_INTEL_82573L_SOL 0x108f
@@ -2787,6 +2789,7 @@
#define PCI_DEVICE_ID_INTEL_VMD_201D 0x201d
#define PCI_DEVICE_ID_INTEL_HDA_BSW 0x2284
#define PCI_DEVICE_ID_INTEL_SST_BSW 0x22a8
+#define PCI_DEVICE_ID_INTEL_ISP_BSW 0x22b8
#define PCI_DEVICE_ID_INTEL_DH89XXCC_LPC_MIN 0x2310
#define PCI_DEVICE_ID_INTEL_DH89XXCC_LPC_MAX 0x231f
#define PCI_DEVICE_ID_INTEL_82801AA_0 0x2410
diff --git a/include/linux/pcs/pcs-xpcs-rk.h b/include/linux/pcs/pcs-xpcs-rk.h
new file mode 100644
index 000000000000..e3ca3d51f7c7
--- /dev/null
+++ b/include/linux/pcs/pcs-xpcs-rk.h
@@ -0,0 +1,11 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef __LINUX_PCS_XPCS_ROCKCHIP_H
+#define __LINUX_PCS_XPCS_ROCKCHIP_H
+
+#include <linux/device.h>
+#include <linux/of.h>
+#include <linux/pcs/pcs-xpcs.h>
+
+struct dw_xpcs *xpcs_rk_create(struct device *dev, struct device_node *pcs, int port);
+
+#endif /* __LINUX_PCS_XPCS_ROCKCHIP_H */
diff --git a/include/linux/perf/riscv_pmu.h b/include/linux/perf/riscv_pmu.h
index f82a28040594..ecaa40370830 100644
--- a/include/linux/perf/riscv_pmu.h
+++ b/include/linux/perf/riscv_pmu.h
@@ -55,7 +55,7 @@ struct riscv_pmu {
irqreturn_t (*handle_irq)(int irq_num, void *dev);
- unsigned long cmask;
+ DECLARE_BITMAP(cmask, RISCV_MAX_COUNTERS);
u64 (*ctr_read)(struct perf_event *event);
int (*ctr_get_idx)(struct perf_event *event);
int (*ctr_get_width)(int idx);
diff --git a/include/linux/perf_event.h b/include/linux/perf_event.h
index 5842552294c1..eb3f7bab498c 100644
--- a/include/linux/perf_event.h
+++ b/include/linux/perf_event.h
@@ -306,6 +306,7 @@ struct perf_event_pmu_context;
#define PERF_PMU_CAP_AUX_PAUSE 0x0200
#define PERF_PMU_CAP_AUX_PREFER_LARGE 0x0400
#define PERF_PMU_CAP_MEDIATED_VPMU 0x0800
+#define PERF_PMU_CAP_SIMD_REGS 0x1000
/**
* pmu::scope
@@ -1467,23 +1468,7 @@ static inline u32 perf_sample_data_size(struct perf_sample_data *data,
return size;
}
-/*
- * Clear all bitfields in the perf_branch_entry.
- * The to and from fields are not cleared because they are
- * systematically modified by caller.
- */
-static inline void perf_clear_branch_entry_bitfields(struct perf_branch_entry *br)
-{
- br->mispred = 0;
- br->predicted = 0;
- br->in_tx = 0;
- br->abort = 0;
- br->cycles = 0;
- br->type = 0;
- br->spec = PERF_BR_SPEC_NA;
- br->reserved = 0;
-}
-
+extern u64 perf_update_xregs_size(struct perf_event *event, bool intr);
extern void perf_output_sample(struct perf_output_handle *handle,
struct perf_event_header *header,
struct perf_sample_data *data,
@@ -1523,9 +1508,10 @@ is_default_overflow_handler(struct perf_event *event)
}
extern void
-perf_event_header__init_id(struct perf_event_header *header,
- struct perf_sample_data *data,
- struct perf_event *event);
+perf_event_header__init(struct perf_event_header *header,
+ struct perf_sample_data *data,
+ u32 type, u16 misc, u16 size,
+ struct perf_event *event);
extern void
perf_event__output_id_sample(struct perf_event *event,
struct perf_output_handle *handle,
@@ -1534,6 +1520,27 @@ perf_event__output_id_sample(struct perf_event *event,
extern void
perf_log_lost_samples(struct perf_event *event, u64 lost);
+static inline bool event_has_simd_regs(struct perf_event *event)
+{
+ struct perf_event_attr *attr = &event->attr;
+
+ if (!(event->attr.sample_type &
+ (PERF_SAMPLE_REGS_INTR | PERF_SAMPLE_REGS_USER)))
+ return false;
+
+ return attr->sample_simd_regs_enabled != 0;
+}
+
+static inline bool event_has_extended_regs(struct perf_event *event)
+{
+ struct perf_event_attr *attr = &event->attr;
+
+ return ((attr->sample_type & PERF_SAMPLE_REGS_USER) &&
+ (attr->sample_regs_user & PERF_REG_EXTENDED_MASK)) ||
+ ((attr->sample_type & PERF_SAMPLE_REGS_INTR) &&
+ (attr->sample_regs_intr & PERF_REG_EXTENDED_MASK));
+}
+
static inline bool event_has_any_exclude_flag(struct perf_event *event)
{
struct perf_event_attr *attr = &event->attr;
diff --git a/include/linux/perf_regs.h b/include/linux/perf_regs.h
index f632c5725f16..09dbc2fc3859 100644
--- a/include/linux/perf_regs.h
+++ b/include/linux/perf_regs.h
@@ -9,6 +9,16 @@ struct perf_regs {
struct pt_regs *regs;
};
+u64 perf_reg_value(struct pt_regs *regs, int idx);
+int perf_reg_validate(u64 mask, bool simd_enabled);
+u64 perf_reg_abi(struct task_struct *task);
+void perf_get_regs_user(struct perf_regs *regs_user,
+ struct pt_regs *regs);
+int perf_simd_reg_validate(u16 vec_qwords, u64 vec_mask,
+ u16 pred_qwords, u32 pred_mask);
+u64 perf_simd_reg_value(struct pt_regs *regs, int idx,
+ u16 qwords_idx, bool pred);
+
#ifdef CONFIG_HAVE_PERF_REGS
#include <asm/perf_regs.h>
@@ -16,35 +26,9 @@ struct perf_regs {
#define PERF_REG_EXTENDED_MASK 0
#endif
-u64 perf_reg_value(struct pt_regs *regs, int idx);
-int perf_reg_validate(u64 mask);
-u64 perf_reg_abi(struct task_struct *task);
-void perf_get_regs_user(struct perf_regs *regs_user,
- struct pt_regs *regs);
#else
#define PERF_REG_EXTENDED_MASK 0
-static inline u64 perf_reg_value(struct pt_regs *regs, int idx)
-{
- return 0;
-}
-
-static inline int perf_reg_validate(u64 mask)
-{
- return mask ? -ENOSYS : 0;
-}
-
-static inline u64 perf_reg_abi(struct task_struct *task)
-{
- return PERF_SAMPLE_REGS_ABI_NONE;
-}
-
-static inline void perf_get_regs_user(struct perf_regs *regs_user,
- struct pt_regs *regs)
-{
- regs_user->regs = task_pt_regs(current);
- regs_user->abi = perf_reg_abi(current);
-}
#endif /* CONFIG_HAVE_PERF_REGS */
#endif /* _LINUX_PERF_REGS_H */
diff --git a/include/linux/pgtable.h b/include/linux/pgtable.h
index 8c093c119e5a..780fe849ff8b 100644
--- a/include/linux/pgtable.h
+++ b/include/linux/pgtable.h
@@ -490,35 +490,35 @@ static inline int pudp_set_access_flags(struct vm_area_struct *vma,
#endif
#ifndef ptep_get
-static inline pte_t ptep_get(pte_t *ptep)
+static inline pte_t ptep_get(const pte_t *ptep)
{
return READ_ONCE(*ptep);
}
#endif
#ifndef pmdp_get
-static inline pmd_t pmdp_get(pmd_t *pmdp)
+static inline pmd_t pmdp_get(const pmd_t *pmdp)
{
return READ_ONCE(*pmdp);
}
#endif
#ifndef pudp_get
-static inline pud_t pudp_get(pud_t *pudp)
+static inline pud_t pudp_get(const pud_t *pudp)
{
return READ_ONCE(*pudp);
}
#endif
#ifndef p4dp_get
-static inline p4d_t p4dp_get(p4d_t *p4dp)
+static inline p4d_t p4dp_get(const p4d_t *p4dp)
{
return READ_ONCE(*p4dp);
}
#endif
#ifndef pgdp_get
-static inline pgd_t pgdp_get(pgd_t *pgdp)
+static inline pgd_t pgdp_get(const pgd_t *pgdp)
{
return READ_ONCE(*pgdp);
}
@@ -2313,6 +2313,20 @@ static inline const char *pgtable_level_to_str(enum pgtable_level level)
}
}
+void ptval_bytes_to_hex_str(char *buf, size_t buf_size, const void *entry, size_t entry_size);
+
+#define ptval_to_str(buf, val) \
+ do { \
+ auto __val = (val); \
+ \
+ ptval_bytes_to_hex_str((buf), sizeof(buf), &__val, sizeof(__val)); \
+ } while (0)
+
+#if defined(__SIZEOF_INT128__)
+#define PTVAL_STR_MAX (32 + 1) /* Max 128-bit value in hex + NUL */
+#else
+#define PTVAL_STR_MAX (16 + 1) /* Max 64-bit value in hex + NUL */
+#endif
#endif /* !__ASSEMBLER__ */
#if !defined(MAX_POSSIBLE_PHYSMEM_BITS) && !defined(CONFIG_64BIT)
diff --git a/include/linux/phy.h b/include/linux/phy.h
index 5f8d65868e0f..21afc2082b17 100644
--- a/include/linux/phy.h
+++ b/include/linux/phy.h
@@ -376,6 +376,24 @@ struct mii_bus {
int regnum, u16 val);
/** @reset: Perform a reset of the bus */
int (*reset)(struct mii_bus *bus);
+ /**
+ * @notify_phy_attach: Perform post-attach handling for MDIO bus
+ * drivers. Optional and independent of @notify_phy_detach. Called
+ * in phy_attach_direct() right before phy_resume(). Runs in process
+ * context, may sleep and may be called with RTNL held. Must not
+ * acquire or rely on RTNL. Returns 0 on success or negative errno
+ * on failure. Must unwind its own state on error as attachment is
+ * aborted.
+ */
+ int (*notify_phy_attach)(struct phy_device *phydev);
+ /**
+ * @notify_phy_detach: Perform pre-detach handling for MDIO bus
+ * drivers. Optional and independent of @notify_phy_attach. Called
+ * in phy_detach() right after phy_suspend(). Runs in process context,
+ * may sleep and may be called with RTNL held. Must not acquire or
+ * rely on RTNL.
+ */
+ void (*notify_phy_detach)(struct phy_device *phydev);
/** @stats: Statistic counters per device on the bus */
struct mdio_bus_stats stats[PHY_MAX_ADDR];
@@ -560,6 +578,7 @@ struct phy_oatc14_sqi_capability {
*
* @mdio: MDIO bus this PHY is on
* @drv: Pointer to the driver for this PHY instance
+ * @drv_owner: Driver module phy_attach_direct() took a reference on
* @devlink: Create a link between phy dev and mac dev, if the external phy
* used by current mac interface is managed by another mac interface.
* @phyindex: Unique id across the phy's parent tree of phys to address the PHY
@@ -593,7 +612,11 @@ struct phy_oatc14_sqi_capability {
* @irq: IRQ number of the PHY's interrupt (-1 if none)
* @phylink: Pointer to phylink instance for this PHY
* @sfp_bus_attached: Flag indicating whether the SFP bus has been attached
+ * @has_sfp_mod_phy: Set true if downstream SFP bus's module contains a PHY
* @sfp_bus: SFP bus attached to this PHY's fiber port
+ * @sfp_cage_port: The phy_port connected to the downstream SFP cage
+ * @mod_port: phy_port representing the SFP module, if it is phy-less
+ * @upstream_port: phy_port this PHY's MII attaches to, if any
* @attached_dev: The attached enet driver's device instance ptr
* @adjust_link: Callback for the enet controller to respond to changes: in the
* link state.
@@ -671,6 +694,7 @@ struct phy_device {
/* Information about the PHY type */
/* And management functions */
const struct phy_driver *drv;
+ struct module *drv_owner;
struct device_link *devlink;
@@ -784,7 +808,11 @@ struct phy_device {
/* This may be modified under the rtnl lock */
bool sfp_bus_attached;
+ bool has_sfp_mod_phy;
struct sfp_bus *sfp_bus;
+ struct phy_port *sfp_cage_port;
+ struct phy_port *mod_port;
+ struct phy_port *upstream_port;
struct phylink *phylink;
struct net_device *attached_dev;
struct mii_timestamper *mii_ts;
@@ -1697,7 +1725,7 @@ static inline bool phy_can_wakeup(struct phy_device *phydev)
* phy_may_wakeup() - indicate whether PHY has wakeup enabled
* @phydev: The phy_device struct
*
- * Returns: true/false depending on the PHY driver's device_set_wakeup_enabled()
+ * Returns: true/false depending on the PHY driver's device_set_wakeup_enable()
* setting if using the driver model, otherwise the legacy determination.
*/
bool phy_may_wakeup(struct phy_device *phydev);
@@ -2422,10 +2450,10 @@ int phy_get_mac_termination(struct phy_device *phydev, struct device *dev,
void phy_resolve_pause(unsigned long *local_adv, unsigned long *partner_adv,
bool *tx_pause, bool *rx_pause);
-int phy_register_fixup_for_id(const char *bus_id,
- int (*run)(struct phy_device *));
-int phy_register_fixup_for_uid(u32 phy_uid, u32 phy_uid_mask,
- int (*run)(struct phy_device *));
+void __init phy_register_fixup_for_id(const char *bus_id,
+ int (*run)(struct phy_device *));
+void __init phy_register_fixup_for_uid(u32 phy_uid, u32 phy_uid_mask,
+ int (*run)(struct phy_device *));
int phy_eee_tx_clock_stop_capable(struct phy_device *phydev);
int phy_eee_rx_clock_stop(struct phy_device *phydev, bool clk_stop_enable);
@@ -2469,6 +2497,8 @@ int __phy_hwtstamp_set(struct phy_device *phydev,
struct phy_port *phy_get_sfp_port(struct phy_device *phydev);
+void phy_set_upstream_port(struct phy_device *phydev, struct phy_port *port);
+
/**
* phy_module_driver() - Helper macro for registering PHY drivers
* @__phy_drivers: array of PHY drivers to register
diff --git a/include/linux/phy/phy.h b/include/linux/phy/phy.h
index ea47975e288a..14b924a88411 100644
--- a/include/linux/phy/phy.h
+++ b/include/linux/phy/phy.h
@@ -284,6 +284,8 @@ struct phy *devm_of_phy_optional_get(struct device *dev, struct device_node *np,
const char *con_id);
struct phy *devm_of_phy_get_by_index(struct device *dev, struct device_node *np,
int index);
+struct phy *phy_get_by_of_node(struct device_node *np);
+struct phy *devm_phy_get_by_of_node(struct device *dev, struct device_node *np);
void of_phy_put(struct phy *phy);
void phy_put(struct device *dev, struct phy *phy);
void devm_phy_put(struct device *dev, struct phy *phy);
@@ -493,6 +495,17 @@ static inline struct phy *devm_of_phy_get_by_index(struct device *dev,
return ERR_PTR(-ENOSYS);
}
+static inline struct phy *phy_get_by_of_node(struct device_node *np)
+{
+ return ERR_PTR(-ENOSYS);
+}
+
+static inline struct phy *devm_phy_get_by_of_node(struct device *dev,
+ struct device_node *np)
+{
+ return ERR_PTR(-ENOSYS);
+}
+
static inline void of_phy_put(struct phy *phy)
{
}
diff --git a/include/linux/phy_link_topology.h b/include/linux/phy_link_topology.h
index 95575f68d5bc..f2e493c433ff 100644
--- a/include/linux/phy_link_topology.h
+++ b/include/linux/phy_link_topology.h
@@ -13,14 +13,19 @@
#include <linux/ethtool.h>
#include <linux/netdevice.h>
+#include <linux/rtnetlink.h>
struct xarray;
struct phy_device;
+struct phy_port;
struct sfp_bus;
struct phy_link_topology {
struct xarray phys;
u32 next_phy_index;
+
+ struct xarray ports;
+ u32 next_port_index;
};
struct phy_device_node {
@@ -48,6 +53,9 @@ int phy_link_topo_add_phy(struct net_device *dev,
void phy_link_topo_del_phy(struct net_device *dev, struct phy_device *phy);
+int phy_link_topo_add_port(struct net_device *dev, struct phy_port *port);
+void phy_link_topo_del_port(struct net_device *dev, struct phy_port *port);
+
static inline struct phy_device *
phy_link_topo_get_phy(struct net_device *dev, u32 phyindex)
{
@@ -64,6 +72,24 @@ phy_link_topo_get_phy(struct net_device *dev, u32 phyindex)
return NULL;
}
+static inline struct phy_port *
+phy_link_topo_get_port(struct net_device *dev, u32 port_id)
+{
+ struct phy_link_topology *topo = dev->link_topo;
+
+ if (!topo)
+ return NULL;
+
+ /* ports in the topo are RTNL protected, but may be accessed under
+ * netdev_lock for ops-locked devices. For now keep them under rtnl
+ * protection, as no ops-locked devices have phy_port capabilities
+ * yet.
+ */
+ ASSERT_RTNL();
+
+ return xa_load(&topo->ports, port_id);
+}
+
#else
static inline int phy_link_topo_add_phy(struct net_device *dev,
struct phy_device *phy,
@@ -77,11 +103,28 @@ static inline void phy_link_topo_del_phy(struct net_device *dev,
{
}
+static inline int phy_link_topo_add_port(struct net_device *dev,
+ struct phy_port *port)
+{
+ return 0;
+}
+
+static inline void phy_link_topo_del_port(struct net_device *dev,
+ struct phy_port *port)
+{
+}
+
static inline struct phy_device *
phy_link_topo_get_phy(struct net_device *dev, u32 phyindex)
{
return NULL;
}
+
+static inline struct phy_port *
+phy_link_topo_get_port(struct net_device *dev, u32 port_id)
+{
+ return NULL;
+}
#endif
#endif /* __PHY_LINK_TOPOLOGY_H */
diff --git a/include/linux/phy_port.h b/include/linux/phy_port.h
index 0ef0f5ce4709..8f45c031cbc1 100644
--- a/include/linux/phy_port.h
+++ b/include/linux/phy_port.h
@@ -36,9 +36,12 @@ struct phy_port_ops {
/**
* struct phy_port - A representation of a network device physical interface
*
+ * @id: Unique identifier for the port within the topology
* @head: Used by the port's parent to list ports
* @parent_type: The type of device this port is directly connected to
* @phy: If the parent is PHY_PORT_PHYDEV, the PHY controlling that port
+ * @upstream_port: Indicates the MII port that feeds this port, if any,
+ * e.g. the SFP cage port for a SFP module port.
* @ops: Callback ops implemented by the port controller
* @pairs: The number of pairs this port has, 0 if not applicable
* @mediums: Bitmask of the physical mediums this port provides access to
@@ -52,11 +55,13 @@ struct phy_port_ops {
* @is_sfp: Indicates if this port drives an SFP cage.
*/
struct phy_port {
+ u32 id;
struct list_head head;
enum phy_port_parent parent_type;
union {
struct phy_device *phy;
};
+ struct phy_port *upstream_port;
const struct phy_port_ops *ops;
diff --git a/include/linux/phylink.h b/include/linux/phylink.h
index 1dda5c7ed5f1..3a88a69882a6 100644
--- a/include/linux/phylink.h
+++ b/include/linux/phylink.h
@@ -843,4 +843,6 @@ void phylink_replay_link_begin(struct phylink *pl);
void phylink_replay_link_end(struct phylink *pl);
+void phylink_update_mac_pause_capabilities(struct phylink *pl, unsigned long mac_pause);
+
#endif
diff --git a/include/linux/pid.h b/include/linux/pid.h
index ddaef0bbc8ba..185bf0cde2d1 100644
--- a/include/linux/pid.h
+++ b/include/linux/pid.h
@@ -2,6 +2,9 @@
#ifndef _LINUX_PID_H
#define _LINUX_PID_H
+#include <linux/array_size.h>
+#include <linux/build_bug.h>
+#include <linux/minmax.h>
#include <linux/pid_types.h>
#include <linux/rculist.h>
#include <linux/rcupdate.h>
@@ -92,6 +95,56 @@ static inline struct pid *get_pid(struct pid *pid)
}
extern void put_pid(struct pid *pid);
+
+/*
+ * Helpers for arrays of struct pid indexed by pid type declared with
+ * DECLARE_PIDS(). The array covers PIDTYPE_PID up to the pid type it
+ * was declared with and the helpers take that bound from the array.
+ */
+static inline void __get_pids(struct pid **dst, struct pid *const *src,
+ enum pid_type last)
+{
+ for (enum pid_type type = PIDTYPE_PID; type <= last; type++)
+ dst[type] = get_pid(src[type]);
+}
+
+static inline void __put_pids(struct pid **pids, enum pid_type last)
+{
+ for (enum pid_type type = PIDTYPE_PID; type <= last; type++) {
+ put_pid(pids[type]);
+ pids[type] = NULL;
+ }
+}
+
+static inline void __swap_pids(struct pid **a, struct pid **b,
+ enum pid_type last)
+{
+ for (enum pid_type type = PIDTYPE_PID; type <= last; type++)
+ swap(a[type], b[type]);
+}
+
+static inline bool __pids_equal(struct pid *const *a, struct pid *const *b,
+ enum pid_type last)
+{
+ for (enum pid_type type = PIDTYPE_PID; type <= last; type++)
+ if (a[type] != b[type])
+ return false;
+ return true;
+}
+
+/* The last pid type an array declared with DECLARE_PIDS() covers. */
+#define pids_last(pids) \
+ ((enum pid_type)(ARRAY_SIZE(pids) - 1 + \
+ BUILD_BUG_ON_ZERO(ARRAY_SIZE(pids) > PIDTYPE_MAX)))
+
+#define __pids_last2(a, b) \
+ (pids_last(a) + BUILD_BUG_ON_ZERO(ARRAY_SIZE(a) != ARRAY_SIZE(b)))
+
+#define get_pids(dst, src) __get_pids(dst, src, __pids_last2(dst, src))
+#define put_pids(pids) __put_pids(pids, pids_last(pids))
+#define swap_pids(a, b) __swap_pids(a, b, __pids_last2(a, b))
+#define pids_equal(a, b) __pids_equal(a, b, __pids_last2(a, b))
+
extern struct task_struct *pid_task(struct pid *pid, enum pid_type);
static inline bool pid_has_task(struct pid *pid, enum pid_type type)
{
@@ -187,6 +240,15 @@ static inline pid_t pid_nr(struct pid *pid)
pid_t pid_nr_ns(struct pid *pid, struct pid_namespace *ns);
pid_t pid_vnr(struct pid *pid);
+/*
+ * Needs tasklist_lock if type > PIDTYPE_TGID. A lockless reader can:
+ *
+ * - race with a change_pid() that moves the task to another hlist,
+ * and continue to scan the wrong list.
+ *
+ * - race with a copy_process() that adds a new task to the start of hlist,
+ * and miss the new child.
+ */
#define do_each_pid_task(pid, type, task) \
do { \
if ((pid) != NULL) \
@@ -264,7 +326,7 @@ static inline pid_t task_tgid_nr(struct task_struct *tsk)
*/
static inline int pid_alive(const struct task_struct *p)
{
- return p->thread_pid != NULL;
+ return READ_ONCE(p->thread_pid) != NULL;
}
static inline pid_t task_pgrp_nr_ns(struct task_struct *tsk, struct pid_namespace *ns)
diff --git a/include/linux/pid_types.h b/include/linux/pid_types.h
index c2aee1d91dcf..3302690a2a28 100644
--- a/include/linux/pid_types.h
+++ b/include/linux/pid_types.h
@@ -2,6 +2,8 @@
#ifndef _LINUX_PID_TYPES_H
#define _LINUX_PID_TYPES_H
+#include <linux/build_bug.h>
+
enum pid_type {
PIDTYPE_PID,
PIDTYPE_TGID,
@@ -10,6 +12,12 @@ enum pid_type {
PIDTYPE_MAX,
};
+struct pid;
+
+/* An array of struct pid indexed by pid type, PIDTYPE_PID up to @last. */
+#define DECLARE_PIDS(name, last) \
+ struct pid *name[(last) + 1 + BUILD_BUG_ON_ZERO((last) >= PIDTYPE_MAX)]
+
struct pid_namespace;
extern struct pid_namespace init_pid_ns;
diff --git a/include/linux/pidfs.h b/include/linux/pidfs.h
index 0abf7da9ab23..3c1e82f1a369 100644
--- a/include/linux/pidfs.h
+++ b/include/linux/pidfs.h
@@ -3,6 +3,7 @@
#define _LINUX_PID_FS_H
#include <linux/gfp_types.h>
+#include <linux/pid.h>
struct coredump_params;
@@ -32,5 +33,9 @@ static inline int pidfs_register_pid(struct pid *pid)
}
void pidfs_free_pid(struct pid *pid);
+int __pidfs_register_pids(struct pid *const *pids, enum pid_type last);
+
+/* Register the pids of an array declared with DECLARE_PIDS(). */
+#define pidfs_register_pids(pids) __pidfs_register_pids(pids, pids_last(pids))
#endif /* _LINUX_PID_FS_H */
diff --git a/include/linux/pinctrl/consumer.h b/include/linux/pinctrl/consumer.h
index 11b8f0b8da0c..81e7866bd2e3 100644
--- a/include/linux/pinctrl/consumer.h
+++ b/include/linux/pinctrl/consumer.h
@@ -12,6 +12,7 @@
#define __LINUX_PINCTRL_CONSUMER_H
#include <linux/err.h>
+#include <linux/errno.h>
#include <linux/types.h>
#include <linux/pinctrl/pinctrl-state.h>
@@ -107,14 +108,14 @@ static inline int
pinctrl_gpio_get_config(struct gpio_chip *gc, unsigned int offset,
unsigned long *config)
{
- return 0;
+ return -ENOTSUPP;
}
static inline int
pinctrl_gpio_set_config(struct gpio_chip *gc, unsigned int offset,
unsigned long config)
{
- return 0;
+ return -ENOTSUPP;
}
static inline struct pinctrl * __must_check pinctrl_get(struct device *dev)
diff --git a/include/linux/pinctrl/pinconf-generic.h b/include/linux/pinctrl/pinconf-generic.h
index a5d4b2d8633a..1df63c732b99 100644
--- a/include/linux/pinctrl/pinconf-generic.h
+++ b/include/linux/pinctrl/pinconf-generic.h
@@ -71,6 +71,10 @@ struct pinctrl_map;
* which means it will wait for signals to settle when reading inputs. The
* argument gives the debounce time in usecs. Setting the
* argument to zero turns debouncing off.
+ * @PIN_CONFIG_INPUT_DEBOUNCE_NS: this will configure the pin to debounce mode,
+ * which means it will wait for signals to settle when reading inputs. The
+ * argument gives the debounce time in nsecs. Setting the
+ * argument to zero turns debouncing off.
* @PIN_CONFIG_INPUT_ENABLE: enable the pin's input. Note that this does not
* affect the pin's ability to drive output. 1 enables input, 0 disables
* input.
@@ -143,6 +147,7 @@ enum pin_config_param {
PIN_CONFIG_DRIVE_STRENGTH,
PIN_CONFIG_DRIVE_STRENGTH_UA,
PIN_CONFIG_INPUT_DEBOUNCE,
+ PIN_CONFIG_INPUT_DEBOUNCE_NS,
PIN_CONFIG_INPUT_ENABLE,
PIN_CONFIG_INPUT_SCHMITT,
PIN_CONFIG_INPUT_SCHMITT_ENABLE,
diff --git a/include/linux/platform_data/cros_ec_commands.h b/include/linux/platform_data/cros_ec_commands.h
index 749d985e9da2..a7bd69d83522 100644
--- a/include/linux/platform_data/cros_ec_commands.h
+++ b/include/linux/platform_data/cros_ec_commands.h
@@ -1344,6 +1344,26 @@ enum ec_feature_code {
* The EC supports UCSI PPM.
*/
EC_FEATURE_UCSI_PPM = 54,
+ /*
+ * The EC supports Strauss keyboard.
+ */
+ EC_FEATURE_STRAUSS = 55,
+ /*
+ * The EC supports PoE.
+ */
+ EC_FEATURE_POE = 56,
+ /*
+ * The EC supports a hybrid boost charger
+ */
+ EC_FEATURE_CHARGER_HYBRID_POWER_BOOST = 57,
+ /*
+ * Support signaling new console logs via host event
+ */
+ EC_FEATURE_CONSOLE_LOG_EVENT = 58,
+ /*
+ * The EC supports power monitoring
+ */
+ EC_FEATURE_PWRMON = 59,
};
#define EC_FEATURE_MASK_0(event_code) BIT(event_code % 32)
@@ -3516,6 +3536,9 @@ enum ec_mkbp_event {
/* Peripheral device charger event */
EC_MKBP_EVENT_PCHG = 12,
+ /* Power monitor telemetry event */
+ EC_MKBP_EVENT_PWRMON = 13,
+
/* Number of MKBP events */
EC_MKBP_EVENT_COUNT,
};
@@ -3599,6 +3622,12 @@ union __ec_align_offset1 ec_response_get_next_data_v3 {
uint32_t cec_events;
uint8_t cec_message[16];
+
+ struct __ec_todo_packed {
+ int64_t value;
+ uint32_t samples;
+ uint8_t channel_id;
+ } pwrmon_data;
};
BUILD_ASSERT(sizeof(union ec_response_get_next_data_v3) == 18);
@@ -6589,6 +6618,49 @@ struct ec_params_usb_pd_mux_ack {
uint8_t port; /* USB-C port number */
} __ec_align1;
+/**
+ * Power monitoring. Used to read power consumptions on rails
+ */
+#define EC_CMD_PWRMON 0x0608
+
+enum ec_pwrmon_cmd {
+ EC_PWRMON_GET_CHANNEL_COUNT = 0,
+ EC_PWRMON_DUMP_INFO = 1,
+ EC_PWRMON_SET_RATE = 2,
+ EC_PWRMON_GET_RATE = 3,
+ EC_PWRMON_START = 4,
+ EC_PWRMON_STOP = 5,
+ EC_PWRMON_LATCH = 6,
+};
+
+struct ec_params_pwrmon {
+ uint8_t cmd;
+ union {
+ uint16_t set_rate;
+ uint8_t channel_id;
+ } __ec_align2;
+
+ /*
+ * The following commands have no args:
+ *
+ * start, stop, latch
+ *
+ */
+} __ec_align4;
+
+struct pwrmon_dump_info {
+ uint8_t channel_id;
+ char channel_name[32];
+} __ec_align4;
+
+struct ec_response_pwrmon {
+ union {
+ uint16_t sample_rate;
+ uint8_t channel_count;
+ struct pwrmon_dump_info dump_info;
+ } __ec_align4;
+} __ec_align4;
+
/*****************************************************************************/
/*
* Reserve a range of host commands for board-specific, experimental, or
diff --git a/include/linux/platform_data/dmtimer-omap.h b/include/linux/platform_data/dmtimer-omap.h
index 726d89143842..b78ee4676b98 100644
--- a/include/linux/platform_data/dmtimer-omap.h
+++ b/include/linux/platform_data/dmtimer-omap.h
@@ -57,6 +57,8 @@ struct dmtimer_platform_data {
u32 timer_errata;
int (*get_context_loss_count)(struct device *);
const struct omap_dm_timer_ops *timer_ops;
+ /* always-on timers can be used for clocksource/clockevent */
+ bool system_timer_capable;
};
#endif /* __PLATFORM_DATA_DMTIMER_OMAP_H__ */
diff --git a/include/linux/platform_data/microchip-ksz.h b/include/linux/platform_data/microchip-ksz.h
index 028781ad4059..411d5e164383 100644
--- a/include/linux/platform_data/microchip-ksz.h
+++ b/include/linux/platform_data/microchip-ksz.h
@@ -31,9 +31,11 @@ enum ksz_chip_id {
KSZ88X3_CHIP_ID = 0x8830,
KSZ8864_CHIP_ID = 0x8864,
KSZ8895_CHIP_ID = 0x8895,
+ KSZ8995XA_CHIP_ID = 0x8995,
KSZ9477_CHIP_ID = 0x00947700,
KSZ9896_CHIP_ID = 0x00989600,
KSZ9897_CHIP_ID = 0x00989700,
+ KSZ9897S_CHIP_ID = 0x00989701,
KSZ9893_CHIP_ID = 0x00989300,
KSZ9563_CHIP_ID = 0x00956300,
KSZ8567_CHIP_ID = 0x00856700,
diff --git a/include/linux/platform_data/x86/int3472.h b/include/linux/platform_data/x86/int3472.h
index a73841dfae27..b1040e36deb8 100644
--- a/include/linux/platform_data/x86/int3472.h
+++ b/include/linux/platform_data/x86/int3472.h
@@ -25,6 +25,8 @@
#define INT3472_GPIO_TYPE_RESET 0x00
#define INT3472_GPIO_TYPE_POWERDOWN 0x01
#define INT3472_GPIO_TYPE_STROBE 0x02
+#define INT3472_GPIO_TYPE_POWER0 0x07
+#define INT3472_GPIO_TYPE_POWER1 0x08
#define INT3472_GPIO_TYPE_POWER_ENABLE 0x0b
#define INT3472_GPIO_TYPE_CLK_ENABLE 0x0c
#define INT3472_GPIO_TYPE_PRIVACY_LED 0x0d
diff --git a/include/linux/pm.h b/include/linux/pm.h
index afcaaa37a812..ef3f1310e749 100644
--- a/include/linux/pm.h
+++ b/include/linux/pm.h
@@ -663,6 +663,99 @@ struct pm_subsys_data {
#define DPM_FLAG_SMART_SUSPEND BIT(2)
#define DPM_FLAG_MAY_SKIP_RESUME BIT(3)
+/**
+ * struct dev_pm_info - Device power management information.
+ *
+ * @power_state: Legacy power state (mostly unused in modern kernels).
+ * @can_wakeup: Device is capable of generating wakeup signals.
+ * @async_suspend: Device can be suspended and resumed asynchronously.
+ * @in_dpm_list: Device is on the dpm_list.
+ * @is_prepared: Device's ->prepare() callback has run successfully.
+ * @is_suspended: Device is suspended during a system sleep transition.
+ * @is_noirq_suspended: Device's noirq suspend callback has run successfully.
+ * @is_late_suspended: Device's late suspend callback has run successfully.
+ * @no_pm: Device does not participate in power management transitions.
+ * @early_init: Device was initialized before standard PM initialization.
+ * @direct_complete: Device can skip suspend/resume callbacks and remain
+ * runtime-suspended during system sleep.
+ * @driver_flags: Driver flags (e.g. %DPM_FLAG_SMART_SUSPEND) set at probe time.
+ * @lock: Spinlock used for synchronizing PM state transitions and runtime PM
+ * operations.
+ * @entry: List head for device power management lists.
+ * @completion: Completion for synchronization during asynchronous system
+ * suspend/resume.
+ * @wakeup: Wakeup source object associated with the device.
+ * @work_in_progress: Asynchronous PM operation in progress.
+ * @wakeup_path: Device is in the wakeup path or can wake the system up.
+ * @syscore: Device participates in syscore power management operations.
+ * @no_pm_callbacks: Device has no PM callbacks; handled by parent or subsystem.
+ * @smart_suspend: Driver requested smart-suspend behavior.
+ * @must_resume: Device must be resumed during system resume.
+ * @may_skip_resume: Set by subsystems to indicate driver resume callbacks may
+ * be skipped.
+ * @out_band_wakeup: Out-of-band wakeup is supported.
+ * @strict_midlayer: Middle layer code does not want callbacks invoked via
+ * pm_runtime_force_suspend() / pm_runtime_force_resume().
+ * @should_wakeup: Wakeup flag when system sleep is not enabled.
+ * @suspend_timer: High-resolution timer used for scheduling delayed runtime
+ * suspend and autosuspend requests.
+ * @timer_expires: Timer expiration time in nanoseconds monotonic time
+ * (runtime PM).
+ * @work: Work structure used for queuing up requests into pm_wq (runtime PM).
+ * @wait_queue: Wait queue used if any helper functions need to wait for another
+ * state change to complete (runtime PM).
+ * @wakeirq: Dedicated wakeup interrupt for the device.
+ * @usage_count: Device runtime PM usage counter.
+ * @child_count: Count of active children of the device (runtime PM).
+ * @disable_depth: Disable counter for runtime PM (runtime PM is enabled when
+ * this is 0; initial value is 1).
+ * @idle_notification: Set if ->runtime_idle() is being executed.
+ * @request_pending: Set if a work item is queued into pm_wq (runtime PM).
+ * @deferred_resume: Set if ->runtime_resume() should run as soon as
+ * ->runtime_suspend() completes.
+ * @needs_force_resume: Indicates the device was forced into suspend by
+ * pm_runtime_force_suspend() and must be resumed by
+ * pm_runtime_force_resume().
+ * @runtime_auto: User space has allowed the driver to power manage the device
+ * at runtime via sysfs control attribute; also can be set by
+ * pm_runtime_allow() or pm_runtime_forbid().
+ * @ignore_children: If set, the value of child_count is ignored for runtime
+ * suspend and idle decisions.
+ * @no_callbacks: Indicates the device does not use runtime PM callbacks.
+ * @irq_safe: Indicates runtime PM callbacks will be invoked with the spinlock
+ * held and interrupts disabled.
+ * @use_autosuspend: Indicates the device driver supports delayed runtime
+ * autosuspend.
+ * @timer_autosuspends: Indicates the runtime PM core should attempt an
+ * autosuspend rather than a normal suspend when the timer expires.
+ * @memalloc_noio: Indicates memory allocation during runtime PM transitions
+ * must avoid I/O (GFP_NOIO).
+ * @links_count: Number of device links that require runtime PM coordination.
+ * @request: Type of pending runtime PM request (valid if request_pending is
+ * set).
+ * @runtime_status: Runtime PM status of the device.
+ * @last_status: Last status captured before disabling runtime PM, or
+ * %RPM_BLOCKED / %RPM_INVALID.
+ * @runtime_error: Fatal error code returned by a failing callback, blocking
+ * helpers until cleared.
+ * @autosuspend_delay: Delay time in milliseconds to be used for runtime
+ * autosuspend.
+ * @last_busy: Timestamp in nanoseconds when pm_runtime_mark_last_busy() was
+ * last called. Used in calculating inactivity periods for autosuspend.
+ * @active_time: Accumulated time in nanoseconds spent in %RPM_ACTIVE state.
+ * @suspended_time: Accumulated time in nanoseconds spent in %RPM_SUSPENDED
+ * state.
+ * @accounting_timestamp: Timestamp in nanoseconds of the last runtime PM state
+ * accounting update.
+ * @subsys_data: Subsystem-specific power management data.
+ * @set_latency_tolerance: Callback for setting latency tolerance.
+ * @qos: Per-device PM Quality of Service (QoS) constraints.
+ * @detach_power_off: Indicates device should be detached from PM domain on
+ * power off.
+ *
+ * Device power management information stored in the "power" member of struct
+ * device.
+ */
struct dev_pm_info {
pm_message_t power_state;
bool can_wakeup:1;
diff --git a/include/linux/pm_domain.h b/include/linux/pm_domain.h
index f925614aebdb..14e0e346c610 100644
--- a/include/linux/pm_domain.h
+++ b/include/linux/pm_domain.h
@@ -121,6 +121,14 @@ struct dev_pm_domain_list {
* powered-off until the ->sync_state() callback is
* invoked. This flag informs genpd to allow a
* power-off without waiting for ->sync_state().
+ *
+ * GENPD_FLAG_POWER_UNKNOWN: Use this flag to inform genpd that its initial
+ * status for the PM domain is set to powered off,
+ * which may not correctly reflect the state of the
+ * HW, as it's unknown. If the PM domain becomes
+ * powered on during boot, genpd will prevent it
+ * from being powered off until the ->sync_state
+ * callback is invoked for it.
*/
#define GENPD_FLAG_PM_CLK (1U << 0)
#define GENPD_FLAG_IRQ_SAFE (1U << 1)
@@ -133,6 +141,7 @@ struct dev_pm_domain_list {
#define GENPD_FLAG_DEV_NAME_FW (1U << 8)
#define GENPD_FLAG_NO_SYNC_STATE (1U << 9)
#define GENPD_FLAG_NO_STAY_ON (1U << 10)
+#define GENPD_FLAG_POWER_UNKNOWN (1U << 11)
enum gpd_status {
GENPD_STATE_ON = 0, /* PM domain is on */
diff --git a/include/linux/pm_qos.h b/include/linux/pm_qos.h
index 6cea4455f867..439a9e779d81 100644
--- a/include/linux/pm_qos.h
+++ b/include/linux/pm_qos.h
@@ -37,6 +37,8 @@ enum pm_qos_flags_status {
#define PM_QOS_LATENCY_TOLERANCE_NO_CONSTRAINT (-1)
#define PM_QOS_FLAG_NO_POWER_OFF (1 << 0)
+/* latency value applies to system-wide suspend/s2idle */
+#define PM_QOS_FLAG_LATENCY_SYS (2 << 0)
enum pm_qos_type {
PM_QOS_UNITIALIZED,
@@ -217,6 +219,12 @@ static inline s32 dev_pm_qos_raw_resume_latency(struct device *dev)
PM_QOS_RESUME_LATENCY_NO_CONSTRAINT :
pm_qos_read_value(&dev->power.qos->resume_latency);
}
+
+static inline s32 dev_pm_qos_raw_flags(struct device *dev)
+{
+ return IS_ERR_OR_NULL(dev->power.qos) ?
+ 0 : READ_ONCE(dev->power.qos->flags.effective_flags);
+}
#else
static inline enum pm_qos_flags_status __dev_pm_qos_flags(struct device *dev,
s32 mask)
@@ -298,6 +306,7 @@ static inline s32 dev_pm_qos_raw_resume_latency(struct device *dev)
{
return PM_QOS_RESUME_LATENCY_NO_CONSTRAINT;
}
+static inline s32 dev_pm_qos_raw_flags(struct device *dev) { return 0; }
#endif
static inline int freq_qos_request_active(struct freq_qos_request *req)
diff --git a/include/linux/pm_runtime.h b/include/linux/pm_runtime.h
index 64921b10ac74..322e3b17f987 100644
--- a/include/linux/pm_runtime.h
+++ b/include/linux/pm_runtime.h
@@ -137,13 +137,14 @@ static inline void pm_runtime_put_noidle(struct device *dev)
* pm_runtime_suspended - Check whether or not a device is runtime-suspended.
* @dev: Target device.
*
- * Return %true if runtime PM is enabled for @dev and its runtime PM status is
- * %RPM_SUSPENDED, or %false otherwise.
- *
* Note that the return value of this function can only be trusted if it is
* called under the runtime PM lock of @dev or under conditions in which
* runtime PM cannot be either disabled or enabled for @dev and its runtime PM
* status cannot change.
+ *
+ * Return:
+ * * %true: @dev has runtime PM enabled and its status is %RPM_SUSPENDED.
+ * * %false: Otherwise.
*/
static inline bool pm_runtime_suspended(struct device *dev)
{
@@ -155,13 +156,14 @@ static inline bool pm_runtime_suspended(struct device *dev)
* pm_runtime_active - Check whether or not a device is runtime-active.
* @dev: Target device.
*
- * Return %true if runtime PM is disabled for @dev or its runtime PM status is
- * %RPM_ACTIVE, or %false otherwise.
- *
* Note that the return value of this function can only be trusted if it is
* called under the runtime PM lock of @dev or under conditions in which
* runtime PM cannot be either disabled or enabled for @dev and its runtime PM
* status cannot change.
+ *
+ * Return:
+ * * %true: Runtime PM is disabled for @dev or its status is %RPM_ACTIVE.
+ * * %false: Otherwise.
*/
static inline bool pm_runtime_active(struct device *dev)
{
@@ -173,12 +175,13 @@ static inline bool pm_runtime_active(struct device *dev)
* pm_runtime_status_suspended - Check if runtime PM status is "suspended".
* @dev: Target device.
*
- * Return %true if the runtime PM status of @dev is %RPM_SUSPENDED, or %false
- * otherwise, regardless of whether or not runtime PM has been enabled for @dev.
- *
* Note that the return value of this function can only be trusted if it is
* called under the runtime PM lock of @dev or under conditions in which the
* runtime PM status of @dev cannot change.
+ *
+ * Return:
+ * * %true: Runtime PM status of @dev is %RPM_SUSPENDED.
+ * * %false: Otherwise.
*/
static inline bool pm_runtime_status_suspended(struct device *dev)
{
@@ -189,11 +192,13 @@ static inline bool pm_runtime_status_suspended(struct device *dev)
* pm_runtime_enabled - Check if runtime PM is enabled.
* @dev: Target device.
*
- * Return %true if runtime PM is enabled for @dev or %false otherwise.
- *
* Note that the return value of this function can only be trusted if it is
* called under the runtime PM lock of @dev or under conditions in which
* runtime PM cannot be either disabled or enabled for @dev.
+ *
+ * Return:
+ * * %true: Runtime PM is enabled for @dev.
+ * * %false: Otherwise.
*/
static inline bool pm_runtime_enabled(struct device *dev)
{
@@ -205,6 +210,10 @@ static inline bool pm_runtime_enabled(struct device *dev)
* @dev: Target device.
*
* Do not call this function outside system suspend/resume code paths.
+ *
+ * Return:
+ * * %true: Runtime PM enabling is blocked for @dev.
+ * * %false: Otherwise.
*/
static inline bool pm_runtime_blocked(struct device *dev)
{
@@ -215,8 +224,9 @@ static inline bool pm_runtime_blocked(struct device *dev)
* pm_runtime_has_no_callbacks - Check if runtime PM callbacks may be present.
* @dev: Target device.
*
- * Return %true if @dev is a special device without runtime PM callbacks or
- * %false otherwise.
+ * Return:
+ * * %true: @dev is marked as having no runtime PM callbacks.
+ * * %false: Otherwise.
*/
static inline bool pm_runtime_has_no_callbacks(struct device *dev)
{
@@ -239,9 +249,11 @@ static inline void pm_runtime_mark_last_busy(struct device *dev)
* pm_runtime_is_irq_safe - Check if runtime PM can work in interrupt context.
* @dev: Target device.
*
- * Return %true if @dev has been marked as an "IRQ-safe" device (with respect
- * to runtime PM), in which case its runtime PM callabcks can be expected to
- * work correctly when invoked from interrupt handlers.
+ * Return:
+ * * %true: @dev has been marked as an "IRQ-safe" device, in which case its
+ * runtime PM callbacks can be expected to work correctly from interrupt
+ * handlers.
+ * * %false: Otherwise.
*/
static inline bool pm_runtime_is_irq_safe(struct device *dev)
{
@@ -340,25 +352,25 @@ static inline int pm_runtime_force_resume(struct device *dev) { return -ENXIO; }
#endif /* CONFIG_PM_SLEEP */
/**
- * pm_runtime_idle - Conditionally set up autosuspend of a device or suspend it.
+ * pm_runtime_idle - Conditionally initiate autosuspend of a device or suspend it.
* @dev: Target device.
*
* Invoke the "idle check" callback of @dev and, depending on its return value,
- * set up autosuspend of @dev or suspend it (depending on whether or not
+ * initiate autosuspend of @dev or suspend it (depending on whether or not
* autosuspend has been enabled for it).
*
* Return:
- * * 0: Success.
- * * -EINVAL: Runtime PM error.
- * * -EACCES: Runtime PM disabled.
- * * -EAGAIN: Runtime PM usage counter non-zero, Runtime PM status change
- * ongoing or device not in %RPM_ACTIVE state.
- * * -EBUSY: Runtime PM child_count non-zero.
- * * -EPERM: Device PM QoS resume latency 0.
- * * -EINPROGRESS: Suspend already in progress.
- * * -ENOSYS: CONFIG_PM not enabled.
- * Other values and conditions for the above values are possible as returned by
- * Runtime PM idle and suspend callbacks.
+ * * %0: Success.
+ * * %-EINVAL: Runtime PM error.
+ * * %-EACCES: Runtime PM disabled.
+ * * %-EAGAIN: Runtime PM usage counter non-zero, Runtime PM status change
+ * ongoing or device not in %RPM_ACTIVE state.
+ * * %-EBUSY: Runtime PM child_count non-zero.
+ * * %-EPERM: Device PM QoS resume latency 0.
+ * * %-EINPROGRESS: Suspend already in progress.
+ * * %-ENOSYS: %CONFIG_PM not enabled.
+ * * Other values and conditions for the above values are possible as returned
+ * by Runtime PM idle and suspend callbacks.
*/
static inline int pm_runtime_idle(struct device *dev)
{
@@ -370,17 +382,17 @@ static inline int pm_runtime_idle(struct device *dev)
* @dev: Target device.
*
* Return:
- * * 1: Success; device was already suspended.
- * * 0: Success.
- * * -EINVAL: Runtime PM error.
- * * -EACCES: Runtime PM disabled.
- * * -EAGAIN: Runtime PM usage counter non-zero or Runtime PM status change
- * ongoing.
- * * -EBUSY: Runtime PM child_count non-zero.
- * * -EPERM: Device PM QoS resume latency 0.
- * * -ENOSYS: CONFIG_PM not enabled.
- * Other values and conditions for the above values are possible as returned by
- * Runtime PM suspend callbacks.
+ * * %1: Success; device was already suspended.
+ * * %0: Success.
+ * * %-EINVAL: Runtime PM error.
+ * * %-EACCES: Runtime PM disabled.
+ * * %-EAGAIN: Runtime PM usage counter non-zero or Runtime PM status change
+ * ongoing.
+ * * %-EBUSY: Runtime PM child_count non-zero.
+ * * %-EPERM: Device PM QoS resume latency 0.
+ * * %-ENOSYS: %CONFIG_PM not enabled.
+ * * Other values and conditions for the above values are possible as returned
+ * by Runtime PM suspend callbacks.
*/
static inline int pm_runtime_suspend(struct device *dev)
{
@@ -388,26 +400,26 @@ static inline int pm_runtime_suspend(struct device *dev)
}
/**
- * pm_runtime_autosuspend - Update the last access time and set up autosuspend
+ * pm_runtime_autosuspend - Update the last access time and initiate autosuspend
* of a device.
* @dev: Target device.
*
- * First update the last access time, then set up autosuspend of @dev or suspend
- * it (depending on whether or not autosuspend is enabled for it) without
- * engaging its "idle check" callback.
+ * First update the last access time, then initiate autosuspend of @dev or
+ * suspend it (depending on whether or not autosuspend is enabled for it)
+ * without engaging its "idle check" callback.
*
* Return:
- * * 1: Success; device was already suspended.
- * * 0: Success.
- * * -EINVAL: Runtime PM error.
- * * -EACCES: Runtime PM disabled.
- * * -EAGAIN: Runtime PM usage counter non-zero or Runtime PM status change
- * ongoing.
- * * -EBUSY: Runtime PM child_count non-zero.
- * * -EPERM: Device PM QoS resume latency 0.
- * * -ENOSYS: CONFIG_PM not enabled.
- * Other values and conditions for the above values are possible as returned by
- * Runtime PM suspend callbacks.
+ * * %1: Success; device was already suspended.
+ * * %0: Success.
+ * * %-EINVAL: Runtime PM error.
+ * * %-EACCES: Runtime PM disabled.
+ * * %-EAGAIN: Runtime PM usage counter non-zero or Runtime PM status change
+ * ongoing.
+ * * %-EBUSY: Runtime PM child_count non-zero.
+ * * %-EPERM: Device PM QoS resume latency 0.
+ * * %-ENOSYS: %CONFIG_PM not enabled.
+ * * Other values and conditions for the above values are possible as returned
+ * by Runtime PM suspend callbacks.
*/
static inline int pm_runtime_autosuspend(struct device *dev)
{
@@ -418,6 +430,11 @@ static inline int pm_runtime_autosuspend(struct device *dev)
/**
* pm_runtime_resume - Resume a device synchronously.
* @dev: Target device.
+ *
+ * Return:
+ * * %1: Success; @dev is already %RPM_ACTIVE.
+ * * %0: Success.
+ * * Error code on failure.
*/
static inline int pm_runtime_resume(struct device *dev)
{
@@ -425,22 +442,22 @@ static inline int pm_runtime_resume(struct device *dev)
}
/**
- * pm_request_idle - Queue up "idle check" execution for a device.
+ * pm_request_idle - Request an asynchronous idle check for a device.
* @dev: Target device.
*
- * Queue up a work item to run an equivalent of pm_runtime_idle() for @dev
- * asynchronously.
+ * Asynchronously request the PM core to evaluate whether @dev can be idled
+ * or suspended, invoking its ->runtime_idle() callback if provided.
*
* Return:
- * * 0: Success.
- * * -EINVAL: Runtime PM error.
- * * -EACCES: Runtime PM disabled.
- * * -EAGAIN: Runtime PM usage counter non-zero, Runtime PM status change
- * ongoing or device not in %RPM_ACTIVE state.
- * * -EBUSY: Runtime PM child_count non-zero.
- * * -EPERM: Device PM QoS resume latency 0.
- * * -EINPROGRESS: Suspend already in progress.
- * * -ENOSYS: CONFIG_PM not enabled.
+ * * %0: Success.
+ * * %-EINVAL: Runtime PM error.
+ * * %-EACCES: Runtime PM disabled.
+ * * %-EAGAIN: Runtime PM usage counter non-zero, Runtime PM status change
+ * ongoing or device not in %RPM_ACTIVE state.
+ * * %-EBUSY: Runtime PM child_count non-zero.
+ * * %-EPERM: Device PM QoS resume latency 0.
+ * * %-EINPROGRESS: Suspend already in progress.
+ * * %-ENOSYS: %CONFIG_PM not enabled.
*/
static inline int pm_request_idle(struct device *dev)
{
@@ -448,8 +465,16 @@ static inline int pm_request_idle(struct device *dev)
}
/**
- * pm_request_resume - Queue up runtime-resume of a device.
+ * pm_request_resume - Request an asynchronous runtime resume for a device.
* @dev: Target device.
+ *
+ * Asynchronously request the PM core to resume @dev to %RPM_ACTIVE state
+ * without modifying its usage counter.
+ *
+ * Return:
+ * * %1: Success; @dev is already %RPM_ACTIVE.
+ * * %0: Success.
+ * * Error code on failure.
*/
static inline int pm_request_resume(struct device *dev)
{
@@ -457,24 +482,23 @@ static inline int pm_request_resume(struct device *dev)
}
/**
- * pm_request_autosuspend - Update the last access time and queue up autosuspend
- * of a device.
+ * pm_request_autosuspend - Update access time and request delayed suspension.
* @dev: Target device.
*
- * Update the last access time of a device and queue up a work item to run an
- * equivalent pm_runtime_autosuspend() for @dev asynchronously.
+ * Update the last access time of @dev and asynchronously request the PM core
+ * to suspend it after the autosuspend delay has elapsed.
*
* Return:
- * * 1: Success; device was already suspended.
- * * 0: Success.
- * * -EINVAL: Runtime PM error.
- * * -EACCES: Runtime PM disabled.
- * * -EAGAIN: Runtime PM usage counter non-zero or Runtime PM status change
- * ongoing.
- * * -EBUSY: Runtime PM child_count non-zero.
- * * -EPERM: Device PM QoS resume latency 0.
- * * -EINPROGRESS: Suspend already in progress.
- * * -ENOSYS: CONFIG_PM not enabled.
+ * * %1: Success; device was already suspended.
+ * * %0: Success.
+ * * %-EINVAL: Runtime PM error.
+ * * %-EACCES: Runtime PM disabled.
+ * * %-EAGAIN: Runtime PM usage counter non-zero or Runtime PM status change
+ * ongoing.
+ * * %-EBUSY: Runtime PM child_count non-zero.
+ * * %-EPERM: Device PM QoS resume latency 0.
+ * * %-EINPROGRESS: Suspend already in progress.
+ * * %-ENOSYS: %CONFIG_PM not enabled.
*/
static inline int pm_request_autosuspend(struct device *dev)
{
@@ -483,11 +507,16 @@ static inline int pm_request_autosuspend(struct device *dev)
}
/**
- * pm_runtime_get - Bump up usage counter and queue up resume of a device.
+ * pm_runtime_get - Increment usage counter and request asynchronous resume.
* @dev: Target device.
*
- * Bump up the runtime PM usage counter of @dev and queue up a work item to
- * carry out runtime-resume of it.
+ * Increment the runtime PM usage counter of @dev and, if the device is
+ * currently suspended, asynchronously request the PM core to resume it.
+ *
+ * Return:
+ * * %1: Success; @dev is already %RPM_ACTIVE.
+ * * %0: Success; runtime-resume was queued.
+ * * Error code on failure.
*/
static inline int pm_runtime_get(struct device *dev)
{
@@ -501,12 +530,15 @@ static inline int pm_runtime_get(struct device *dev)
* Bump up the runtime PM usage counter of @dev and carry out runtime-resume of
* it synchronously.
*
- * The possible return values of this function are the same as for
- * pm_runtime_resume() and the runtime PM usage counter of @dev remains
- * incremented in all cases, even if it returns an error code.
- * Consider using pm_runtime_resume_and_get() instead of it, especially
- * if its return value is checked by the caller, as this is likely to result
- * in cleaner code.
+ * Note that the runtime PM usage counter of @dev remains incremented in all
+ * cases, even if it returns an error code. Consider using
+ * pm_runtime_resume_and_get() instead, especially if the return value is
+ * checked by the caller, as this is likely to result in cleaner code.
+ *
+ * Return:
+ * * %1: Success; @dev is already %RPM_ACTIVE.
+ * * %0: Success.
+ * * Error code on failure.
*/
static inline int pm_runtime_get_sync(struct device *dev)
{
@@ -531,8 +563,11 @@ static inline int pm_runtime_get_active(struct device *dev, int rpmflags)
* @dev: Target device.
*
* Resume @dev synchronously and if that is successful, increment its runtime
- * PM usage counter. Return 0 if the runtime PM usage counter of @dev has been
- * incremented or a negative error code otherwise.
+ * PM usage counter.
+ *
+ * Return:
+ * * %0: Success; @dev is active and its usage counter has been incremented.
+ * * Negative error code on failure; usage counter is unchanged.
*/
static inline int pm_runtime_resume_and_get(struct device *dev)
{
@@ -540,11 +575,12 @@ static inline int pm_runtime_resume_and_get(struct device *dev)
}
/**
- * pm_runtime_put - Drop device usage counter and queue up "idle check" if 0.
+ * pm_runtime_put - Drop device usage counter and request asynchronous idle check.
* @dev: Target device.
*
- * Decrement the runtime PM usage counter of @dev and if it turns out to be
- * equal to 0, queue up a work item for @dev like in pm_request_idle().
+ * Decrement the runtime PM usage counter of @dev. If the counter reaches zero
+ * and the device has no active child dependencies, asynchronously request the
+ * PM core to idle or suspend the device.
*/
static inline void pm_runtime_put(struct device *dev)
{
@@ -559,16 +595,16 @@ static inline void pm_runtime_put(struct device *dev)
* equal to 0, queue up a work item for @dev like in pm_request_autosuspend().
*
* Return:
- * * 1: Success. Usage counter dropped to zero, but device was already suspended.
- * * 0: Success.
- * * -EINVAL: Runtime PM error.
- * * -EACCES: Runtime PM disabled.
- * * -EAGAIN: Runtime PM usage counter became non-zero or Runtime PM status
- * change ongoing.
- * * -EBUSY: Runtime PM child_count non-zero.
- * * -EPERM: Device PM QoS resume latency 0.
- * * -EINPROGRESS: Suspend already in progress.
- * * -ENOSYS: CONFIG_PM not enabled.
+ * * %1: Success. Usage counter dropped to zero, but device was already suspended.
+ * * %0: Success.
+ * * %-EINVAL: Runtime PM error.
+ * * %-EACCES: Runtime PM disabled.
+ * * %-EAGAIN: Runtime PM usage counter became non-zero or Runtime PM status
+ * change ongoing.
+ * * %-EBUSY: Runtime PM child_count non-zero.
+ * * %-EPERM: Device PM QoS resume latency 0.
+ * * %-EINPROGRESS: Suspend already in progress.
+ * * %-ENOSYS: %CONFIG_PM not enabled.
*/
static inline int __pm_runtime_put_autosuspend(struct device *dev)
{
@@ -576,25 +612,25 @@ static inline int __pm_runtime_put_autosuspend(struct device *dev)
}
/**
- * pm_runtime_put_autosuspend - Update the last access time of a device, drop
- * its usage counter and queue autosuspend if the usage counter becomes 0.
+ * pm_runtime_put_autosuspend - Update the last access time, drop usage counter
+ * and request autosuspend.
* @dev: Target device.
*
- * Update the last access time of @dev, decrement runtime PM usage counter of
- * @dev and if it turns out to be equal to 0, queue up a work item for @dev like
- * in pm_request_autosuspend().
+ * Update the last access time of @dev and decrement its runtime PM usage
+ * counter. If the counter drops to zero, asynchronously request the PM core to
+ * suspend the device once its autosuspend delay has elapsed.
*
* Return:
- * * 1: Success. Usage counter dropped to zero, but device was already suspended.
- * * 0: Success.
- * * -EINVAL: Runtime PM error.
- * * -EACCES: Runtime PM disabled.
- * * -EAGAIN: Runtime PM usage counter became non-zero or Runtime PM status
- * change ongoing.
- * * -EBUSY: Runtime PM child_count non-zero.
- * * -EPERM: Device PM QoS resume latency 0.
- * * -EINPROGRESS: Suspend already in progress.
- * * -ENOSYS: CONFIG_PM not enabled.
+ * * %1: Success. Usage counter dropped to zero, but device was already suspended.
+ * * %0: Success.
+ * * %-EINVAL: Runtime PM error.
+ * * %-EACCES: Runtime PM disabled.
+ * * %-EAGAIN: Runtime PM usage counter became non-zero or Runtime PM status
+ * change ongoing.
+ * * %-EBUSY: Runtime PM child_count non-zero.
+ * * %-EPERM: Device PM QoS resume latency 0.
+ * * %-EINPROGRESS: Suspend already in progress.
+ * * %-ENOSYS: %CONFIG_PM not enabled.
*/
static inline int pm_runtime_put_autosuspend(struct device *dev)
{
@@ -653,26 +689,28 @@ DEFINE_GUARD_COND(pm_runtime_active_auto, _try_enabled,
* pm_runtime_put_sync - Drop device usage counter and run "idle check" if 0.
* @dev: Target device.
*
- * Decrement the runtime PM usage counter of @dev and if it turns out to be
- * equal to 0, invoke the "idle check" callback of @dev and, depending on its
- * return value, set up autosuspend of @dev or suspend it (depending on whether
- * or not autosuspend has been enabled for it).
+ * Decrement the runtime PM usage counter of @dev. If the counter drops to zero,
+ * synchronously evaluate and trigger idle/suspend handling.
+ *
+ * Note that this does not update the last access time, but it does respect
+ * existing autosuspend timers. If @dev uses autosuspend, consider using
+ * pm_runtime_put_sync_autosuspend() or pm_runtime_put_sync_suspend() instead.
*
* The runtime PM usage counter of @dev remains decremented in all cases, even
* if it returns an error code.
*
* Return:
- * * 1: Success. Usage counter dropped to zero, but device was already suspended.
- * * 0: Success.
- * * -EINVAL: Runtime PM error.
- * * -EACCES: Runtime PM disabled.
- * * -EAGAIN: Runtime PM usage counter became non-zero or Runtime PM status
- * change ongoing.
- * * -EBUSY: Runtime PM child_count non-zero.
- * * -EPERM: Device PM QoS resume latency 0.
- * * -ENOSYS: CONFIG_PM not enabled.
- * Other values and conditions for the above values are possible as returned by
- * Runtime PM suspend callbacks.
+ * * %1: Success. Usage counter dropped to zero, but device was already suspended.
+ * * %0: Success.
+ * * %-EINVAL: Runtime PM error.
+ * * %-EACCES: Runtime PM disabled.
+ * * %-EAGAIN: Runtime PM usage counter became non-zero or Runtime PM status
+ * change ongoing.
+ * * %-EBUSY: Runtime PM child_count non-zero.
+ * * %-EPERM: Device PM QoS resume latency 0.
+ * * %-ENOSYS: %CONFIG_PM not enabled.
+ * * Other values and conditions for the above values are possible as returned
+ * by Runtime PM suspend callbacks.
*/
static inline int pm_runtime_put_sync(struct device *dev)
{
@@ -683,24 +721,28 @@ static inline int pm_runtime_put_sync(struct device *dev)
* pm_runtime_put_sync_suspend - Drop device usage counter and suspend if 0.
* @dev: Target device.
*
- * Decrement the runtime PM usage counter of @dev and if it turns out to be
- * equal to 0, carry out runtime-suspend of @dev synchronously.
+ * Decrement the runtime PM usage counter of @dev. If the counter drops to zero,
+ * suspend the device synchronously.
+ *
+ * This API differs from pm_runtime_put_sync() and
+ * pm_runtime_put_sync_autosuspend() in that it ignores any outstanding
+ * autosuspend delays.
*
* The runtime PM usage counter of @dev remains decremented in all cases, even
* if it returns an error code.
*
* Return:
- * * 1: Success. Usage counter dropped to zero, but device was already suspended.
- * * 0: Success.
- * * -EINVAL: Runtime PM error.
- * * -EACCES: Runtime PM disabled.
- * * -EAGAIN: Runtime PM usage counter became non-zero or Runtime PM status
- * change ongoing.
- * * -EBUSY: Runtime PM child_count non-zero.
- * * -EPERM: Device PM QoS resume latency 0.
- * * -ENOSYS: CONFIG_PM not enabled.
- * Other values and conditions for the above values are possible as returned by
- * Runtime PM suspend callbacks.
+ * * %1: Success. Usage counter dropped to zero, but device was already suspended.
+ * * %0: Success.
+ * * %-EINVAL: Runtime PM error.
+ * * %-EACCES: Runtime PM disabled.
+ * * %-EAGAIN: Runtime PM usage counter became non-zero or Runtime PM status
+ * change ongoing.
+ * * %-EBUSY: Runtime PM child_count non-zero.
+ * * %-EPERM: Device PM QoS resume latency 0.
+ * * %-ENOSYS: %CONFIG_PM not enabled.
+ * * Other values and conditions for the above values are possible as returned
+ * by Runtime PM suspend callbacks.
*/
static inline int pm_runtime_put_sync_suspend(struct device *dev)
{
@@ -712,27 +754,28 @@ static inline int pm_runtime_put_sync_suspend(struct device *dev)
* drop device usage counter and autosuspend if 0.
* @dev: Target device.
*
- * Update the last access time of @dev, decrement the runtime PM usage counter
- * of @dev and if it turns out to be equal to 0, set up autosuspend of @dev or
- * suspend it synchronously (depending on whether or not autosuspend has been
- * enabled for it).
+ * Update the last access time of @dev and decrement its runtime PM usage
+ * counter. If the counter drops to zero, synchronously suspend the device (or
+ * schedule autosuspend if the delay has not elapsed).
+ *
+ * Prefer this API over pm_runtime_put_sync() for devices that use autosuspend.
*
* The runtime PM usage counter of @dev remains decremented in all cases, even
* if it returns an error code.
*
* Return:
- * * 1: Success. Usage counter dropped to zero, but device was already suspended.
- * * 0: Success.
- * * -EINVAL: Runtime PM error.
- * * -EACCES: Runtime PM disabled.
- * * -EAGAIN: Runtime PM usage counter became non-zero or Runtime PM status
- * change ongoing.
- * * -EBUSY: Runtime PM child_count non-zero.
- * * -EPERM: Device PM QoS resume latency 0.
- * * -EINPROGRESS: Suspend already in progress.
- * * -ENOSYS: CONFIG_PM not enabled.
- * Other values and conditions for the above values are possible as returned by
- * Runtime PM suspend callbacks.
+ * * %1: Success. Usage counter dropped to zero, but device was already suspended.
+ * * %0: Success.
+ * * %-EINVAL: Runtime PM error.
+ * * %-EACCES: Runtime PM disabled.
+ * * %-EAGAIN: Runtime PM usage counter became non-zero or Runtime PM status
+ * change ongoing.
+ * * %-EBUSY: Runtime PM child_count non-zero.
+ * * %-EPERM: Device PM QoS resume latency 0.
+ * * %-EINPROGRESS: Suspend already in progress.
+ * * %-ENOSYS: %CONFIG_PM not enabled.
+ * * Other values and conditions for the above values are possible as returned
+ * by Runtime PM suspend callbacks.
*/
static inline int pm_runtime_put_sync_autosuspend(struct device *dev)
{
@@ -741,13 +784,22 @@ static inline int pm_runtime_put_sync_autosuspend(struct device *dev)
}
/**
- * pm_runtime_set_active - Set runtime PM status to "active".
+ * pm_runtime_set_active - Set runtime PM status to "active" and clear errors.
* @dev: Target device.
*
- * Set the runtime PM status of @dev to %RPM_ACTIVE and ensure that dependencies
- * of it will be taken into account.
+ * Set the runtime PM status of @dev to %RPM_ACTIVE and ensure that its
+ * dependencies will be taken into account. Also clear the device's error
+ * status (@dev->power.runtime_error).
+ *
+ * It is only valid to call this function if runtime PM is disabled or if
+ * @dev->power.runtime_error is set.
*
- * It is not valid to call this function for devices with runtime PM enabled.
+ * This will fail if suppliers cannot be resumed, or if the parent is not in
+ * the correct state.
+ *
+ * Return:
+ * * %0: Success.
+ * * Error code on failure.
*/
static inline int pm_runtime_set_active(struct device *dev)
{
@@ -755,13 +807,19 @@ static inline int pm_runtime_set_active(struct device *dev)
}
/**
- * pm_runtime_set_suspended - Set runtime PM status to "suspended".
+ * pm_runtime_set_suspended - Set runtime PM status to "suspended" and clear errors.
* @dev: Target device.
*
- * Set the runtime PM status of @dev to %RPM_SUSPENDED and ensure that
- * dependencies of it will be taken into account.
+ * Set the runtime PM status of @dev to %RPM_SUSPENDED and ensure that its
+ * dependencies will be taken into account. Also clear the device's error
+ * status (@dev->power.runtime_error).
*
- * It is not valid to call this function for devices with runtime PM enabled.
+ * It is only valid to call this function if runtime PM is disabled or if
+ * @dev->power.runtime_error is set.
+ *
+ * Return:
+ * * %0: Success.
+ * * Error code on failure.
*/
static inline int pm_runtime_set_suspended(struct device *dev)
{
@@ -777,9 +835,8 @@ static inline int pm_runtime_set_suspended(struct device *dev)
*
* If the counter is zero when this function runs and there is a pending runtime
* resume request for @dev, it will be resumed. If the counter is still zero at
- * that point, all of the pending runtime PM requests for @dev will be canceled
- * and all runtime PM operations in progress involving it will be waited for to
- * complete.
+ * that point, this function cancels all pending runtime PM requests for @dev
+ * and waits for its runtime PM operations to complete (if any).
*
* For each invocation of this function for @dev, there must be a matching
* pm_runtime_enable() call, so that runtime PM is eventually enabled for it
diff --git a/include/linux/posix-timers.h b/include/linux/posix-timers.h
index 9a1a0c61361c..00767acbc111 100644
--- a/include/linux/posix-timers.h
+++ b/include/linux/posix-timers.h
@@ -66,38 +66,6 @@ struct cpu_timer {
struct task_struct __rcu *handling;
};
-static inline bool cpu_timer_enqueue(struct timerqueue_head *head,
- struct cpu_timer *ctmr)
-{
- ctmr->head = head;
- return timerqueue_add(head, &ctmr->node);
-}
-
-static inline bool cpu_timer_queued(struct cpu_timer *ctmr)
-{
- return !!ctmr->head;
-}
-
-static inline bool cpu_timer_dequeue(struct cpu_timer *ctmr)
-{
- if (cpu_timer_queued(ctmr)) {
- timerqueue_del(ctmr->head, &ctmr->node);
- ctmr->head = NULL;
- return true;
- }
- return false;
-}
-
-static inline u64 cpu_timer_getexpires(struct cpu_timer *ctmr)
-{
- return ctmr->node.expires;
-}
-
-static inline void cpu_timer_setexpires(struct cpu_timer *ctmr, u64 exp)
-{
- ctmr->node.expires = exp;
-}
-
static inline void posix_cputimers_init(struct posix_cputimers *pct)
{
memset(pct, 0, sizeof(*pct));
@@ -224,14 +192,15 @@ struct k_itimer {
} ____cacheline_aligned_in_smp;
void run_posix_cpu_timers(void);
-void posix_cpu_timers_exit(struct task_struct *task);
-void posix_cpu_timers_exit_group(struct task_struct *task);
void set_process_cpu_timer(struct task_struct *task, unsigned int clock_idx,
u64 *newval, u64 *oldval);
int update_rlimit_cpu(struct task_struct *task, unsigned long rlim_new);
#ifdef CONFIG_POSIX_TIMERS
+void posixtimer_exec(void);
+void posixtimer_exit(bool group_dead);
+
static inline void posixtimer_putref(struct k_itimer *tmr)
{
if (rcuref_put(&tmr->rcuref))
@@ -259,6 +228,8 @@ static inline bool posixtimer_valid(const struct k_itimer *timer)
return !(val & 0x1UL);
}
#else /* CONFIG_POSIX_TIMERS */
+static inline void posixtimer_exec(void) { }
+static inline void posixtimer_exit(bool group_dead) { }
static inline void posixtimer_sigqueue_getref(struct sigqueue *q) { }
static inline void posixtimer_sigqueue_putref(struct sigqueue *q) { }
#endif /* !CONFIG_POSIX_TIMERS */
diff --git a/include/linux/posix_acl.h b/include/linux/posix_acl.h
index 62d497763e25..caf500bed993 100644
--- a/include/linux/posix_acl.h
+++ b/include/linux/posix_acl.h
@@ -74,20 +74,20 @@ extern int __posix_acl_create(struct posix_acl **, gfp_t, umode_t *);
extern int __posix_acl_chmod(struct posix_acl **, gfp_t, umode_t);
extern struct posix_acl *get_posix_acl(struct inode *, int);
-int set_posix_acl(struct mnt_idmap *, struct dentry *, int,
+int set_posix_acl(const struct mnt_idmap *, struct dentry *, int,
struct posix_acl *);
struct posix_acl *get_cached_acl_rcu(struct inode *inode, int type);
struct posix_acl *posix_acl_clone(const struct posix_acl *acl, gfp_t flags);
#ifdef CONFIG_FS_POSIX_ACL
-int posix_acl_chmod(struct mnt_idmap *, struct dentry *, umode_t);
+int posix_acl_chmod(const struct mnt_idmap *, struct dentry *, umode_t);
extern int posix_acl_create(struct inode *, umode_t *, struct posix_acl **,
struct posix_acl **);
-int posix_acl_update_mode(struct mnt_idmap *, struct inode *, umode_t *,
+int posix_acl_update_mode(const struct mnt_idmap *, struct inode *, umode_t *,
struct posix_acl **);
-int simple_set_acl(struct mnt_idmap *, struct dentry *,
+int simple_set_acl(const struct mnt_idmap *, struct dentry *,
struct posix_acl *, int);
extern int simple_acl_create(struct inode *, struct inode *);
@@ -96,7 +96,7 @@ void set_cached_acl(struct inode *inode, int type, struct posix_acl *acl);
void forget_cached_acl(struct inode *inode, int type);
void forget_all_cached_acls(struct inode *inode);
int posix_acl_valid(struct user_namespace *, const struct posix_acl *);
-int posix_acl_permission(struct mnt_idmap *, struct inode *,
+int posix_acl_permission(const struct mnt_idmap *, struct inode *,
const struct posix_acl *, int);
static inline void cache_no_acl(struct inode *inode)
@@ -105,16 +105,16 @@ static inline void cache_no_acl(struct inode *inode)
inode->i_default_acl = NULL;
}
-int vfs_set_acl(struct mnt_idmap *idmap, struct dentry *dentry,
+int vfs_set_acl(const struct mnt_idmap *idmap, struct dentry *dentry,
const char *acl_name, struct posix_acl *kacl);
-struct posix_acl *vfs_get_acl(struct mnt_idmap *idmap,
+struct posix_acl *vfs_get_acl(const struct mnt_idmap *idmap,
struct dentry *dentry, const char *acl_name);
-int vfs_remove_acl(struct mnt_idmap *idmap, struct dentry *dentry,
+int vfs_remove_acl(const struct mnt_idmap *idmap, struct dentry *dentry,
const char *acl_name);
int posix_acl_listxattr(struct inode *inode, char **buffer,
ssize_t *remaining_size);
#else
-static inline int posix_acl_chmod(struct mnt_idmap *idmap,
+static inline int posix_acl_chmod(const struct mnt_idmap *idmap,
struct dentry *dentry, umode_t mode)
{
return 0;
@@ -141,21 +141,21 @@ static inline void forget_all_cached_acls(struct inode *inode)
{
}
-static inline int vfs_set_acl(struct mnt_idmap *idmap,
+static inline int vfs_set_acl(const struct mnt_idmap *idmap,
struct dentry *dentry, const char *name,
struct posix_acl *acl)
{
return -EOPNOTSUPP;
}
-static inline struct posix_acl *vfs_get_acl(struct mnt_idmap *idmap,
+static inline struct posix_acl *vfs_get_acl(const struct mnt_idmap *idmap,
struct dentry *dentry,
const char *acl_name)
{
return ERR_PTR(-EOPNOTSUPP);
}
-static inline int vfs_remove_acl(struct mnt_idmap *idmap,
+static inline int vfs_remove_acl(const struct mnt_idmap *idmap,
struct dentry *dentry, const char *acl_name)
{
return -EOPNOTSUPP;
diff --git a/include/linux/power_supply.h b/include/linux/power_supply.h
index e749d2189335..0a4ea490d5ea 100644
--- a/include/linux/power_supply.h
+++ b/include/linux/power_supply.h
@@ -351,6 +351,16 @@ struct power_supply {
bool removing;
atomic_t use_cnt;
struct power_supply_battery_info *battery_info;
+ /*
+ * Held for read while ->external_power_changed() runs, and for write by
+ * power_supply_unregister() when it publishes @removing, so that it
+ * waits for an in-flight callback to finish. Without this a driver's
+ * data, typically devm-allocated on its own device, can be freed while
+ * the callback is still using it.
+ * Must not be shared with extensions_sem: callbacks may read their own
+ * properties, which takes that one for read.
+ */
+ struct rw_semaphore epc_sem;
struct rw_semaphore extensions_sem; /* protects "extensions" */
struct list_head extensions;
#ifdef CONFIG_THERMAL
@@ -414,9 +424,9 @@ struct power_supply_vbat_ri_table {
* @charge_voltage_max_uv: maintenance charging voltage that is usually a bit
* lower than the constant_charge_voltage_max_uv. We can apply this settings
* charge_current_max_ua until we get back up to this voltage.
- * @safety_timer_minutes: maintenance charging safety timer, with an expiry
- * time in minutes. We will only use maintenance charging in this setting
- * for a certain amount of time, then we will first move to the next
+ * @charge_safety_timer_minutes: maintenance charging safety timer, with an
+ * expiry time in minutes. We will only use maintenance charging in this
+ * setting for a certain amount of time, then we will first move to the next
* maintenance charge current and voltage pair in respective array and wait
* for the next safety timer timeout, or, if we reached the last maintencance
* charging setting, disable charging until we reach
diff --git a/include/linux/pps_gen_kernel.h b/include/linux/pps_gen_kernel.h
index 6214c8aa2e02..c4d22b1af118 100644
--- a/include/linux/pps_gen_kernel.h
+++ b/include/linux/pps_gen_kernel.h
@@ -11,6 +11,7 @@
#include <linux/pps_gen.h>
#include <linux/cdev.h>
#include <linux/device.h>
+#include <linux/mutex.h>
/*
* Global defines
@@ -44,6 +45,7 @@ struct pps_gen_source_info {
/* The main struct */
struct pps_gen_device {
const struct pps_gen_source_info *info; /* PSS generator info */
+ struct mutex info_lock; /* protects info */
bool enabled; /* PSS generator status */
unsigned int event;
@@ -54,7 +56,7 @@ struct pps_gen_device {
unsigned int id; /* PPS generator unique ID */
struct cdev cdev;
- struct device *dev;
+ struct device dev;
struct fasync_struct *async_queue; /* fasync method */
spinlock_t lock;
};
diff --git a/include/linux/preempt.h b/include/linux/preempt.h
index 2e689de7b29a..06ff44a4b8b6 100644
--- a/include/linux/preempt.h
+++ b/include/linux/preempt.h
@@ -498,21 +498,11 @@ DEFINE_LOCK_GUARD_0(preempt_notrace, preempt_disable_notrace(), preempt_enable_n
#ifdef CONFIG_PREEMPT_DYNAMIC
-extern bool preempt_model_none(void);
-extern bool preempt_model_voluntary(void);
extern bool preempt_model_full(void);
extern bool preempt_model_lazy(void);
#else
-static inline bool preempt_model_none(void)
-{
- return IS_ENABLED(CONFIG_PREEMPT_NONE);
-}
-static inline bool preempt_model_voluntary(void)
-{
- return IS_ENABLED(CONFIG_PREEMPT_VOLUNTARY);
-}
static inline bool preempt_model_full(void)
{
return IS_ENABLED(CONFIG_PREEMPT);
@@ -525,6 +515,16 @@ static inline bool preempt_model_lazy(void)
#endif
+static inline bool preempt_model_none(void)
+{
+ return IS_ENABLED(CONFIG_PREEMPT_NONE);
+}
+
+static inline bool preempt_model_voluntary(void)
+{
+ return IS_ENABLED(CONFIG_PREEMPT_VOLUNTARY);
+}
+
static inline bool preempt_model_rt(void)
{
return IS_ENABLED(CONFIG_PREEMPT_RT);
diff --git a/include/linux/property.h b/include/linux/property.h
index 907c790a3f01..9143fe4f5c05 100644
--- a/include/linux/property.h
+++ b/include/linux/property.h
@@ -547,6 +547,11 @@ unsigned int fwnode_graph_get_endpoint_count(const struct fwnode_handle *fwnode,
for (child = fwnode_graph_get_next_endpoint(fwnode, NULL); child; \
child = fwnode_graph_get_next_endpoint(fwnode, child))
+#define fwnode_graph_for_each_endpoint_scoped(fwnode, child) \
+ for (struct fwnode_handle *child __free(fwnode_handle) = \
+ fwnode_graph_get_next_endpoint(fwnode, NULL); \
+ child; child = fwnode_graph_get_next_endpoint(fwnode, child))
+
int fwnode_graph_parse_endpoint(const struct fwnode_handle *fwnode,
struct fwnode_endpoint *endpoint);
diff --git a/include/linux/psp-sev.h b/include/linux/psp-sev.h
index 03a79786df1d..fab62228f981 100644
--- a/include/linux/psp-sev.h
+++ b/include/linux/psp-sev.h
@@ -49,7 +49,7 @@
#define SEV_FW_BLOB_MAX_SIZE 0x4000 /* 16KB */
-/**
+/*
* SEV platform state
*/
enum sev_state {
@@ -60,7 +60,7 @@ enum sev_state {
SEV_STATE_MAX
};
-/**
+/*
* SEV platform and guest management commands
*/
enum sev_cmd {
@@ -157,6 +157,7 @@ enum sev_cmd {
* struct sev_data_init - INIT command parameters
*
* @flags: processing flags
+ * @reserved: reserved
* @tmr_address: system physical address used for SEV-ES
* @tmr_len: len of tmr_address
*/
@@ -174,6 +175,7 @@ struct sev_data_init {
* @flags: processing flags
* @tmr_address: system physical address used for SEV-ES
* @tmr_len: len of tmr_address
+ * @reserved: reserved
* @nv_address: system physical address used for PSP NV storage
* @nv_len: len of nv_address
*/
@@ -201,12 +203,13 @@ struct sev_data_pek_csr {
} __packed;
/**
- * struct sev_data_cert_import - PEK_CERT_IMPORT command parameters
+ * struct sev_data_pek_cert_import - PEK_CERT_IMPORT command parameters
*
- * @pek_address: PEK certificate chain
- * @pek_len: len of PEK certificate
- * @oca_address: OCA certificate chain
- * @oca_len: len of OCA certificate
+ * @pek_cert_address: PEK certificate chain
+ * @pek_cert_len: len of PEK certificate
+ * @reserved: reserved
+ * @oca_cert_address: OCA certificate chain
+ * @oca_cert_len: len of OCA certificate
*/
struct sev_data_pek_cert_import {
u64 pek_cert_address; /* In */
@@ -240,8 +243,9 @@ struct sev_data_get_id {
/**
* struct sev_data_pdh_cert_export - PDH_CERT_EXPORT command parameters
*
- * @pdh_address: PDH certificate address
- * @pdh_len: len of PDH certificate
+ * @pdh_cert_address: PDH certificate address
+ * @pdh_cert_len: len of PDH certificate
+ * @reserved: reserved
* @cert_chain_address: PDH certificate chain
* @cert_chain_len: len of PDH certificate chain
*/
@@ -304,6 +308,7 @@ struct sev_data_guest_status {
* @policy: guest launch policy
* @dh_cert_address: physical address of DH certificate blob
* @dh_cert_len: len of DH certificate blob
+ * @reserved: reserved
* @session_address: physical address of session parameters
* @session_len: len of session parameters
*/
@@ -321,6 +326,7 @@ struct sev_data_launch_start {
* struct sev_data_launch_update_data - LAUNCH_UPDATE_DATA command parameter
*
* @handle: handle of the VM to update
+ * @reserved: reserved
* @len: len of memory to be encrypted
* @address: physical address of memory region to encrypt
*/
@@ -335,6 +341,7 @@ struct sev_data_launch_update_data {
* struct sev_data_launch_update_vmsa - LAUNCH_UPDATE_VMSA command
*
* @handle: handle of the VM
+ * @reserved: reserved
* @address: physical address of memory region to encrypt
* @len: len of memory region to encrypt
*/
@@ -349,6 +356,7 @@ struct sev_data_launch_update_vmsa {
* struct sev_data_launch_measure - LAUNCH_MEASURE command parameters
*
* @handle: handle of the VM to process
+ * @reserved: reserved
* @address: physical address containing the measurement blob
* @len: len of measurement blob
*/
@@ -363,10 +371,13 @@ struct sev_data_launch_measure {
* struct sev_data_launch_secret - LAUNCH_SECRET command parameters
*
* @handle: handle of the VM to process
+ * @reserved1: reserved
* @hdr_address: physical address containing the packet header
* @hdr_len: len of packet header
+ * @reserved2: reserved
* @guest_address: system physical address of guest memory region
* @guest_len: len of guest_paddr
+ * @reserved3: reserved
* @trans_address: physical address of transport memory buffer
* @trans_len: len of transport memory buffer
*/
@@ -399,10 +410,13 @@ struct sev_data_launch_finish {
* @policy: policy information for the VM
* @pdh_cert_address: physical address containing PDH certificate
* @pdh_cert_len: len of PDH certificate
+ * @reserved1: reserved
* @plat_certs_address: physical address containing platform certificate
* @plat_certs_len: len of platform certificate
+ * @reserved2: reserved
* @amd_certs_address: physical address containing AMD certificate
* @amd_certs_len: len of AMD certificate
+ * @reserved3: reserved
* @session_address: physical address containing Session data
* @session_len: len of session data
*/
@@ -423,13 +437,16 @@ struct sev_data_send_start {
} __packed;
/**
- * struct sev_data_send_update - SEND_UPDATE_DATA command
+ * struct sev_data_send_update_data - SEND_UPDATE_DATA command
*
* @handle: handle of the VM to process
+ * @reserved1: reserved
* @hdr_address: physical address containing packet header
* @hdr_len: len of packet header
+ * @reserved2: reserved
* @guest_address: physical address of guest memory region to send
* @guest_len: len of guest memory region to send
+ * @reserved3: reserved
* @trans_address: physical address of host memory region
* @trans_len: len of host memory region
*/
@@ -447,13 +464,15 @@ struct sev_data_send_update_data {
} __packed;
/**
- * struct sev_data_send_update - SEND_UPDATE_VMSA command
+ * struct sev_data_send_update_vmsa - SEND_UPDATE_VMSA command
*
* @handle: handle of the VM to process
* @hdr_address: physical address containing packet header
* @hdr_len: len of packet header
+ * @reserved2: reserved
* @guest_address: physical address of guest memory region to send
* @guest_len: len of guest memory region to send
+ * @reserved3: reserved
* @trans_address: physical address of host memory region
* @trans_len: len of host memory region
*/
@@ -491,8 +510,10 @@ struct sev_data_send_cancel {
* struct sev_data_receive_start - RECEIVE_START command parameters
*
* @handle: handle of the VM to perform receive operation
+ * @policy: policy information for the VM
* @pdh_cert_address: system physical address containing PDH certificate blob
* @pdh_cert_len: len of PDH certificate blob
+ * @reserved1: reserved
* @session_address: system physical address containing session blob
* @session_len: len of session blob
*/
@@ -510,10 +531,13 @@ struct sev_data_receive_start {
* struct sev_data_receive_update_data - RECEIVE_UPDATE_DATA command parameters
*
* @handle: handle of the VM to update
+ * @reserved1: reserved
* @hdr_address: physical address containing packet header blob
* @hdr_len: len of packet header
+ * @reserved2: reserved
* @guest_address: system physical address of guest memory region
* @guest_len: len of guest memory region
+ * @reserved3: reserved
* @trans_address: system physical address of transport buffer
* @trans_len: len of transport buffer
*/
@@ -534,10 +558,13 @@ struct sev_data_receive_update_data {
* struct sev_data_receive_update_vmsa - RECEIVE_UPDATE_VMSA command parameters
*
* @handle: handle of the VM to update
+ * @reserved1: reserved
* @hdr_address: physical address containing packet header blob
* @hdr_len: len of packet header
+ * @reserved2: reserved
* @guest_address: system physical address of guest memory region
* @guest_len: len of guest memory region
+ * @reserved3: reserved
* @trans_address: system physical address of transport buffer
* @trans_len: len of transport buffer
*/
@@ -567,6 +594,7 @@ struct sev_data_receive_finish {
* struct sev_data_dbg - DBG_ENCRYPT/DBG_DECRYPT command parameters
*
* @handle: handle of the VM to perform debug operation
+ * @reserved: reserved
* @src_addr: source address of data to operate on
* @dst_addr: destination address of data to operate on
* @len: len of data to operate on
@@ -583,6 +611,7 @@ struct sev_data_dbg {
* struct sev_data_attestation_report - SEV_ATTESTATION_REPORT command parameters
*
* @handle: handle of the VM
+ * @reserved: reserved
* @mnonce: a random nonce that will be included in the report.
* @address: physical address where the report will be copied.
* @len: length of the physical buffer.
@@ -781,9 +810,14 @@ struct sev_data_snp_guest_request {
*
* @init_rmp: indicate that the RMP should be initialized.
* @list_paddr_en: indicate that list_paddr is valid
+ * @rapl_dis: whether RAPL is disabled
+ * @ciphertext_hiding_en: whether ciphertext hiding is enabled
+ * @tio_en: Indicates that SNP_INIT_EX initialized the RMP for SEV-TIO
* @rsvd: reserved
* @rsvd1: reserved
* @list_paddr: system physical address of range list
+ * @max_snp_asid: When non-zero, enable ciphertext hiding and specify the
+ * maximum ASID that can be used for an SEV-SNP guest.
* @rsvd2: reserved
*/
struct sev_data_snp_init_ex {
@@ -841,7 +875,7 @@ struct sev_data_snp_shutdown_ex {
} __packed;
/**
- * struct sev_platform_init_args
+ * struct sev_platform_init_args - parameters for sev_platform_init()
*
* @error: SEV firmware error code
* @probe: True if this is being called as part of CCP module probe, which
@@ -879,12 +913,12 @@ struct sev_data_snp_feature_info {
} __packed;
/**
- * struct feature_info - FEATURE_INFO structure
+ * struct snp_feature_info - FEATURE_INFO structure
*
* @eax: output of SNP_FEATURE_INFO command
* @ebx: output of SNP_FEATURE_INFO command
* @ecx: output of SNP_FEATURE_INFO command
- * #edx: output of SNP_FEATURE_INFO command
+ * @edx: output of SNP_FEATURE_INFO command
*/
struct snp_feature_info {
u32 eax;
@@ -954,7 +988,7 @@ struct sev_data_snp_verify_mitigation_dst {
} __packed;
/**
- * struct sev_snp_tcb_version_genoa_milan
+ * struct sev_snp_tcb_version_genoa_milan - v1 SVN payload
*
* @boot_loader: SVN of PSP bootloader
* @tee: SVN of PSP operating system
@@ -971,7 +1005,7 @@ struct sev_snp_tcb_version_genoa_milan {
};
/**
- * struct sev_snp_tcb_version_turin
+ * struct sev_snp_tcb_version_turin - v2 SVN payload
*
* @fmc: SVN of FMC firmware
* @boot_loader: SVN of PSP bootloader
@@ -1037,9 +1071,9 @@ int sev_platform_status(struct sev_user_data_status *status, int *error);
* behalf of userspace. The caller must pass a valid SEV file descriptor
* so that we know that it has access to SEV device.
*
- * @filep - SEV device file pointer
- * @cmd - command to issue
- * @data - command buffer
+ * @filep: SEV device file pointer
+ * @id: command to issue
+ * @data: command buffer
* @error: SEV command return code
*
* Returns:
@@ -1056,8 +1090,8 @@ int sev_issue_cmd_external_user(struct file *filep, unsigned int id,
/**
* sev_guest_deactivate - perform SEV DEACTIVATE command
*
- * @deactivate: sev_data_deactivate structure to be processed
- * @sev_ret: sev command return code
+ * @data: sev_data_deactivate structure to be processed
+ * @error: sev command return code
*
* Returns:
* 0 if the sev successfully processed the command
@@ -1071,8 +1105,8 @@ int sev_guest_deactivate(struct sev_data_deactivate *data, int *error);
/**
* sev_guest_activate - perform SEV ACTIVATE command
*
- * @activate: sev_data_activate structure to be processed
- * @sev_ret: sev command return code
+ * @data: sev_data_activate structure to be processed
+ * @error: sev command return code
*
* Returns:
* 0 if the sev successfully processed the command
@@ -1086,7 +1120,7 @@ int sev_guest_activate(struct sev_data_activate *data, int *error);
/**
* sev_guest_df_flush - perform SEV DF_FLUSH command
*
- * @sev_ret: sev command return code
+ * @error: sev command return code
*
* Returns:
* 0 if the sev successfully processed the command
@@ -1100,8 +1134,8 @@ int sev_guest_df_flush(int *error);
/**
* sev_guest_decommission - perform SEV DECOMMISSION command
*
- * @decommission: sev_data_decommission structure to be processed
- * @sev_ret: sev command return code
+ * @data: sev_data_decommission structure to be processed
+ * @error: sev command return code
*
* Returns:
* 0 if the sev successfully processed the command
diff --git a/include/linux/pwrseq/consumer.h b/include/linux/pwrseq/consumer.h
index 16fad5f3e3ab..b69117ad3fa7 100644
--- a/include/linux/pwrseq/consumer.h
+++ b/include/linux/pwrseq/consumer.h
@@ -25,6 +25,8 @@ int pwrseq_disable(struct pwrseq_desc *desc);
struct device *pwrseq_to_device(struct pwrseq_desc *desc);
+bool pwrseq_is_controllable(struct pwrseq_desc *desc);
+
#else /* CONFIG_POWER_SEQUENCING */
static inline struct pwrseq_desc * __must_check
@@ -58,6 +60,11 @@ static inline struct device *pwrseq_to_device(struct pwrseq_desc *desc)
return NULL;
}
+static inline bool pwrseq_is_controllable(struct pwrseq_desc *desc)
+{
+ return false;
+}
+
#endif /* CONFIG_POWER_SEQUENCING */
#endif /* __POWER_SEQUENCING_CONSUMER_H__ */
diff --git a/include/linux/pwrseq/provider.h b/include/linux/pwrseq/provider.h
index 33b3d2c2e39d..7285ad94a221 100644
--- a/include/linux/pwrseq/provider.h
+++ b/include/linux/pwrseq/provider.h
@@ -6,12 +6,15 @@
#ifndef __POWER_SEQUENCING_PROVIDER_H__
#define __POWER_SEQUENCING_PROVIDER_H__
+#include <linux/types.h>
+
struct device;
struct module;
struct pwrseq_device;
typedef int (*pwrseq_power_state_func)(struct pwrseq_device *);
typedef int (*pwrseq_match_func)(struct pwrseq_device *, struct device *);
+typedef bool (*pwrseq_is_controllable_func)(struct pwrseq_device *);
#define PWRSEQ_NO_MATCH 0
#define PWRSEQ_MATCH_OK 1
@@ -43,11 +46,16 @@ struct pwrseq_unit_data {
* the state lock has been released. It's useful for implementing
* boot-up delays without blocking other users from powering up
* using the same power sequencer.
+ * @is_controllable: Optional callback checking whether enabling/disabling this
+ * target actually controls power (for example when the
+ * controlling GPIO is wired up). If not provided, the
+ * target's power is assumed to be always controllable.
*/
struct pwrseq_target_data {
const char *name;
const struct pwrseq_unit_data *unit;
pwrseq_power_state_func post_enable;
+ pwrseq_is_controllable_func is_controllable;
};
/**
diff --git a/include/linux/quotaops.h b/include/linux/quotaops.h
index f9c0f9d7c9d9..0c64ca674e77 100644
--- a/include/linux/quotaops.h
+++ b/include/linux/quotaops.h
@@ -20,7 +20,7 @@ static inline struct quota_info *sb_dqopt(struct super_block *sb)
}
/* i_rwsem must being held */
-static inline bool is_quota_modification(struct mnt_idmap *idmap,
+static inline bool is_quota_modification(const struct mnt_idmap *idmap,
struct inode *inode, struct iattr *ia)
{
return ((ia->ia_valid & ATTR_SIZE) ||
@@ -109,7 +109,7 @@ int dquot_set_dqblk(struct super_block *sb, struct kqid id,
struct qc_dqblk *di);
int __dquot_transfer(struct inode *inode, struct dquot **transfer_to);
-int dquot_transfer(struct mnt_idmap *idmap, struct inode *inode,
+int dquot_transfer(const struct mnt_idmap *idmap, struct inode *inode,
struct iattr *iattr);
static inline struct mem_dqinfo *sb_dqinfo(struct super_block *sb, int type)
@@ -229,7 +229,7 @@ static inline void dquot_free_inode(struct inode *inode)
{
}
-static inline int dquot_transfer(struct mnt_idmap *idmap,
+static inline int dquot_transfer(const struct mnt_idmap *idmap,
struct inode *inode, struct iattr *iattr)
{
return 0;
diff --git a/include/linux/rbtree_augmented.h b/include/linux/rbtree_augmented.h
index 6dbc5a1bf6a8..b9fc1be86ae3 100644
--- a/include/linux/rbtree_augmented.h
+++ b/include/linux/rbtree_augmented.h
@@ -15,6 +15,8 @@
#include <linux/compiler.h>
#include <linux/rbtree.h>
#include <linux/rcupdate.h>
+#include <linux/args.h>
+#include <linux/minmax.h>
/*
* Please note - only struct rb_augment_callbacks and the prototypes for
@@ -28,6 +30,7 @@ struct rb_augment_callbacks {
void (*propagate)(struct rb_node *node, struct rb_node *stop);
void (*copy)(struct rb_node *old, struct rb_node *new);
void (*rotate)(struct rb_node *old, struct rb_node *new);
+ void (*merge)(struct rb_node *node, struct rb_node *new);
};
extern void __rb_insert_augmented(struct rb_node *node, struct rb_root *root,
@@ -60,6 +63,12 @@ rb_insert_augmented_cached(struct rb_node *node,
rb_insert_augmented(node, &root->rb_root, augment);
}
+/*
+ * Insert @node into the leftmost cached augmented tree @tree.
+ *
+ * The augmented data of @node must already describe @node alone; it is
+ * merged into every ancestor on the way down through augment->merge().
+ */
static __always_inline struct rb_node *
rb_add_augmented_cached(struct rb_node *node, struct rb_root_cached *tree,
bool (*less)(struct rb_node *, const struct rb_node *),
@@ -71,6 +80,7 @@ rb_add_augmented_cached(struct rb_node *node, struct rb_root_cached *tree,
while (*link) {
parent = *link;
+ augment->merge(parent, node);
if (less(node, parent)) {
link = &parent->rb_left;
} else {
@@ -80,31 +90,138 @@ rb_add_augmented_cached(struct rb_node *node, struct rb_root_cached *tree,
}
rb_link_node(node, parent, link);
- augment->propagate(parent, NULL); /* suboptimal */
rb_insert_augmented_cached(node, tree, leftmost, augment);
return leftmost ? node : NULL;
}
+#define RB_FOR_EACH_1(what, RBNAME, RBSTRUCT, RBFIELD, x) \
+ what(1, RBNAME, RBSTRUCT, RBFIELD, x)
+
+#define RB_FOR_EACH_2(what, RBNAME, RBSTRUCT, RBFIELD, x, ...) \
+ what(2, RBNAME, RBSTRUCT, RBFIELD, x) \
+ RB_FOR_EACH_1(what, RBNAME, RBSTRUCT, RBFIELD, __VA_ARGS__)
+
+#define RB_FOR_EACH_3(what, RBNAME, RBSTRUCT, RBFIELD, x, ...) \
+ what(3, RBNAME, RBSTRUCT, RBFIELD, x) \
+ RB_FOR_EACH_2(what, RBNAME, RBSTRUCT, RBFIELD, __VA_ARGS__)
+
+#define RB_FOR_EACH_4(what, RBNAME, RBSTRUCT, RBFIELD, x, ...) \
+ what(4, RBNAME, RBSTRUCT, RBFIELD, x) \
+ RB_FOR_EACH_3(what, RBNAME, RBSTRUCT, RBFIELD, __VA_ARGS__)
+
+#define RB_FOR_EACH_5(what, RBNAME, RBSTRUCT, RBFIELD, x, ...) \
+ what(5, RBNAME, RBSTRUCT, RBFIELD, x) \
+ RB_FOR_EACH_4(what, RBNAME, RBSTRUCT, RBFIELD, __VA_ARGS__)
+
+#define RB_FOR_EACH_6(what, RBNAME, RBSTRUCT, RBFIELD, x, ...) \
+ what(6, RBNAME, RBSTRUCT, RBFIELD, x) \
+ RB_FOR_EACH_5(what, RBNAME, RBSTRUCT, RBFIELD, __VA_ARGS__)
+
+#define RB_FOR_EACH_7(what, RBNAME, RBSTRUCT, RBFIELD, x, ...) \
+ what(7, RBNAME, RBSTRUCT, RBFIELD, x) \
+ RB_FOR_EACH_6(what, RBNAME, RBSTRUCT, RBFIELD, __VA_ARGS__)
+
+#define RB_FOR_EACH_8(what, RBNAME, RBSTRUCT, RBFIELD, x, ...) \
+ what(8, RBNAME, RBSTRUCT, RBFIELD, x) \
+ RB_FOR_EACH_7(what, RBNAME, RBSTRUCT, RBFIELD, __VA_ARGS__)
+
+#define RB_FOR_EACH(action, RBNAME, RBSTRUCT, RBFIELD, ...) \
+ CONCATENATE(RB_FOR_EACH_, COUNT_ARGS(__VA_ARGS__)) \
+ (action, RBNAME, RBSTRUCT, RBFIELD, __VA_ARGS__)
+
/*
- * Template for declaring augmented rbtree callbacks (generic case)
+ * One augmented field: @val is the node's own contribution (a member for
+ * RB_AUG(), a function of the node for RB_AUG_FUNC()), @aug the member
+ * holding the aggregate over the subtree, and @fold(a, b) combines two
+ * aggregates: min, max, a sum, ... It must be commutative and associative.
+ */
+#define RB_AUG_FUNC(val, aug, fold) (val(s), aug, fold)
+#define RB_AUG(val, aug, fold) (s->val, aug, fold)
+#define RB_UNPACK(...) __VA_ARGS__
+
+#define __RB_INST(n, RBNAME, RBSTRUCT, RBFIELD, val, aug, fold) \
+static inline void \
+RBNAME ## _copy_ ## n(RBSTRUCT *old, RBSTRUCT *new) \
+{ \
+ new->aug = old->aug; \
+} \
+static inline bool \
+RBNAME ## _compute_ ## n(RBSTRUCT *s, bool exit) \
+{ \
+ TYPEOF_UNQUAL(s->aug) _old_aug = s->aug; \
+ TYPEOF_UNQUAL(s->aug) _val = val; \
+ struct rb_node *_node = &s->RBFIELD; \
+ if (_node->rb_right) { \
+ RBSTRUCT *_c = container_of(_node->rb_right, typeof(*s), RBFIELD); \
+ _val = fold(_val, _c->aug); \
+ } \
+ if (_node->rb_left) { \
+ RBSTRUCT *_c = container_of(_node->rb_left, typeof(*s), RBFIELD); \
+ _val = fold(_val, _c->aug); \
+ } \
+ if (exit && _old_aug == _val) \
+ return true; \
+ s->aug = _val; \
+ return false; \
+}
+#define _RB_INST(n, RBNAME, RBSTRUCT, RBFIELD, args) \
+ __RB_INST(n, RBNAME, RBSTRUCT, RBFIELD, args)
+#define RB_INST(n, RBNAME, RBSTRUCT, RBFIELD, x) \
+ _RB_INST(n, RBNAME, RBSTRUCT, RBFIELD, RB_UNPACK x)
+
+#define __RB_COPY(n, RBNAME, RBSTRUCT, RBFIELD, val, aug, fold) \
+ RBNAME ## _copy_ ## n(old, new);
+#define _RB_COPY(n, RBNAME, RBSTRUCT, RBFIELD, args) \
+ __RB_COPY(n, RBNAME, RBSTRUCT, RBFIELD, args)
+#define RB_COPY(n, RBNAME, RBSTRUCT, RBFIELD, x) \
+ _RB_COPY(n, RBNAME, RBSTRUCT, RBFIELD, RB_UNPACK x)
+
+#define __RB_COMPUTE(n, RBNAME, RBSTRUCT, RBFIELD, val, aug, fold) \
+ ret &= RBNAME ## _compute_ ## n(node, exit);
+#define _RB_COMPUTE(n, RBNAME, RBSTRUCT, RBFIELD, args) \
+ __RB_COMPUTE(n, RBNAME, RBSTRUCT, RBFIELD, args)
+#define RB_COMPUTE(n, RBNAME, RBSTRUCT, RBFIELD, x) \
+ _RB_COMPUTE(n, RBNAME, RBSTRUCT, RBFIELD, RB_UNPACK x)
+
+/* fold @new, about to become a descendant of @node, into @node */
+#define __RB_MERGE(n, RBNAME, RBSTRUCT, RBFIELD, val, aug, fold) \
+ node->aug = fold(node->aug, new->aug);
+#define _RB_MERGE(n, RBNAME, RBSTRUCT, RBFIELD, args) \
+ __RB_MERGE(n, RBNAME, RBSTRUCT, RBFIELD, args)
+#define RB_MERGE(n, RBNAME, RBSTRUCT, RBFIELD, x) \
+ _RB_MERGE(n, RBNAME, RBSTRUCT, RBFIELD, RB_UNPACK x)
+
+/*
+ * Template for declaring augmented rbtree callbacks (generic multi fields)
*
* RBSTATIC: 'static' or empty
* RBNAME: name of the rb_augment_callbacks structure
* RBSTRUCT: struct type of the tree nodes
* RBFIELD: name of struct rb_node field within RBSTRUCT
- * RBAUGMENTED: name of field within RBSTRUCT holding data for subtree
- * RBCOMPUTE: name of function that recomputes the RBAUGMENTED data
+ * RBAUG...: list of RB_AUG() describing the augmented data
*/
-
#define RB_DECLARE_CALLBACKS(RBSTATIC, RBNAME, \
- RBSTRUCT, RBFIELD, RBAUGMENTED, RBCOMPUTE) \
+ RBSTRUCT, RBFIELD, RBAUG...) \
+RB_FOR_EACH(RB_INST, RBNAME, RBSTRUCT, RBFIELD, RBAUG) \
+static inline void \
+RBNAME ## __copy(RBSTRUCT *old, RBSTRUCT *new) \
+{ \
+ RB_FOR_EACH(RB_COPY, RBNAME, RBSTRUCT, RBFIELD, RBAUG); \
+} \
+static inline bool \
+RBNAME ## __compute(RBSTRUCT *node, bool exit) \
+{ \
+ bool ret = true; \
+ RB_FOR_EACH(RB_COMPUTE, RBNAME, RBSTRUCT, RBFIELD, RBAUG); \
+ return ret; \
+} \
static inline void \
RBNAME ## _propagate(struct rb_node *rb, struct rb_node *stop) \
{ \
while (rb != stop) { \
RBSTRUCT *node = rb_entry(rb, RBSTRUCT, RBFIELD); \
- if (RBCOMPUTE(node, true)) \
+ if (RBNAME ## __compute(node, true)) \
break; \
rb = rb_parent(&node->RBFIELD); \
} \
@@ -114,20 +231,28 @@ RBNAME ## _copy(struct rb_node *rb_old, struct rb_node *rb_new) \
{ \
RBSTRUCT *old = rb_entry(rb_old, RBSTRUCT, RBFIELD); \
RBSTRUCT *new = rb_entry(rb_new, RBSTRUCT, RBFIELD); \
- new->RBAUGMENTED = old->RBAUGMENTED; \
+ RBNAME ## __copy(old, new); \
} \
static void \
RBNAME ## _rotate(struct rb_node *rb_old, struct rb_node *rb_new) \
{ \
RBSTRUCT *old = rb_entry(rb_old, RBSTRUCT, RBFIELD); \
RBSTRUCT *new = rb_entry(rb_new, RBSTRUCT, RBFIELD); \
- new->RBAUGMENTED = old->RBAUGMENTED; \
- RBCOMPUTE(old, false); \
+ RBNAME ## __copy(old, new); \
+ RBNAME ## __compute(old, false); \
+} \
+static inline void \
+RBNAME ## _merge(struct rb_node *rb, struct rb_node *rb_new) \
+{ \
+ RBSTRUCT *node = rb_entry(rb, RBSTRUCT, RBFIELD); \
+ RBSTRUCT *new = rb_entry(rb_new, RBSTRUCT, RBFIELD); \
+ RB_FOR_EACH(RB_MERGE, RBNAME, RBSTRUCT, RBFIELD, RBAUG); \
} \
RBSTATIC const struct rb_augment_callbacks RBNAME = { \
.propagate = RBNAME ## _propagate, \
.copy = RBNAME ## _copy, \
- .rotate = RBNAME ## _rotate \
+ .rotate = RBNAME ## _rotate, \
+ .merge = RBNAME ## _merge \
};
/*
@@ -138,34 +263,15 @@ RBSTATIC const struct rb_augment_callbacks RBNAME = { \
* RBNAME: name of the rb_augment_callbacks structure
* RBSTRUCT: struct type of the tree nodes
* RBFIELD: name of struct rb_node field within RBSTRUCT
- * RBTYPE: type of the RBAUGMENTED field
- * RBAUGMENTED: name of RBTYPE field within RBSTRUCT holding data for subtree
- * RBCOMPUTE: name of function that returns the per-node RBTYPE scalar
+ * RBTYPE: type of the RBAUGMENTED field -- unused, assumed typeof(RBAUGMENTED)
+ * RBAUGMENTED: name of field within RBSTRUCT holding data for subtree
+ * RBVALUE: name of function that returns the per-node RBTYPE scalar
*/
-#define RB_DECLARE_CALLBACKS_MAX(RBSTATIC, RBNAME, RBSTRUCT, RBFIELD, \
- RBTYPE, RBAUGMENTED, RBCOMPUTE) \
-static inline bool RBNAME ## _compute_max(RBSTRUCT *node, bool exit) \
-{ \
- RBSTRUCT *child; \
- RBTYPE max = RBCOMPUTE(node); \
- if (node->RBFIELD.rb_left) { \
- child = rb_entry(node->RBFIELD.rb_left, RBSTRUCT, RBFIELD); \
- if (child->RBAUGMENTED > max) \
- max = child->RBAUGMENTED; \
- } \
- if (node->RBFIELD.rb_right) { \
- child = rb_entry(node->RBFIELD.rb_right, RBSTRUCT, RBFIELD); \
- if (child->RBAUGMENTED > max) \
- max = child->RBAUGMENTED; \
- } \
- if (exit && node->RBAUGMENTED == max) \
- return true; \
- node->RBAUGMENTED = max; \
- return false; \
-} \
-RB_DECLARE_CALLBACKS(RBSTATIC, RBNAME, \
- RBSTRUCT, RBFIELD, RBAUGMENTED, RBNAME ## _compute_max)
+#define RB_DECLARE_CALLBACKS_MAX(RBSTATIC, RBNAME, RBSTRUCT, RBFIELD, \
+ RBTYPE, RBAUGMENTED, RBVALUE) \
+RB_DECLARE_CALLBACKS(RBSTATIC, RBNAME, RBSTRUCT, RBFIELD, \
+ RB_AUG_FUNC(RBVALUE, RBAUGMENTED, max))
#define RB_RED 0
diff --git a/include/linux/rcupdate.h b/include/linux/rcupdate.h
index 44c07a66edff..3f74ae6d6e1f 100644
--- a/include/linux/rcupdate.h
+++ b/include/linux/rcupdate.h
@@ -488,7 +488,7 @@ static __always_inline bool lockdep_assert_rcu_helper(bool c, const struct __ctx
context_unsafe( \
typeof(*p) *local = (typeof(*p) *__force)(p); \
rcu_check_sparse(p, __rcu); \
- ((typeof(*p) __force __kernel *)(local)) \
+ ((TYPEOF_NO_ADDRESS_SPACE(*p) __force __kernel *)(local)) \
)
/**
* unrcu_pointer - mark a pointer as not being RCU protected
@@ -503,7 +503,7 @@ context_unsafe( \
({ \
typeof(*p) *local = (typeof(*p) *__force)READ_ONCE(p); \
rcu_check_sparse(p, space); \
- ((typeof(*p) __force __kernel *)(local)); \
+ ((TYPEOF_NO_ADDRESS_SPACE(*p) __force __kernel *)(local)); \
}) )
#define __rcu_dereference_check(p, local, c, space) \
({ \
@@ -511,19 +511,19 @@ context_unsafe( \
typeof(*p) *local = (typeof(*p) *__force)READ_ONCE(p); \
RCU_LOCKDEP_WARN(!(c), "suspicious rcu_dereference_check() usage"); \
rcu_check_sparse(p, space); \
- ((typeof(*p) __force __kernel *)(local)); \
+ ((TYPEOF_NO_ADDRESS_SPACE(*p) __force __kernel *)(local)); \
})
#define __rcu_dereference_protected(p, local, c, space) \
({ \
RCU_LOCKDEP_WARN(!(c), "suspicious rcu_dereference_protected() usage"); \
rcu_check_sparse(p, space); \
- ((typeof(*p) __force __kernel *)(p)); \
+ ((TYPEOF_NO_ADDRESS_SPACE(*p) __force __kernel *)(p)); \
})
#define __rcu_dereference_raw(p, local) \
({ \
/* Dependency order vs. p above. */ \
typeof(p) local = READ_ONCE(p); \
- ((typeof(*p) __force __kernel *)(local)); \
+ ((TYPEOF_NO_ADDRESS_SPACE(*p) __force __kernel *)(local)); \
})
#define rcu_dereference_raw(p) __rcu_dereference_raw(p, __UNIQUE_ID(rcu))
diff --git a/include/linux/rcuref.h b/include/linux/rcuref.h
index 2fb2af6d9824..01fee161b67c 100644
--- a/include/linux/rcuref.h
+++ b/include/linux/rcuref.h
@@ -34,7 +34,7 @@ static inline void rcuref_init(rcuref_t *ref, unsigned int cnt)
* indicate that it is safe to schedule the object, protected by this reference
* counter, for deconstruction.
* If you want to know if the reference counter has been marked DEAD (as
- * signaled by rcuref_put()) please use rcuread_is_dead().
+ * signaled by rcuref_put()) please use rcuref_is_dead().
*/
static inline unsigned int rcuref_read(rcuref_t *ref)
{
diff --git a/include/linux/rcutree.h b/include/linux/rcutree.h
index 16a04202888b..e6ad4f2a475c 100644
--- a/include/linux/rcutree.h
+++ b/include/linux/rcutree.h
@@ -116,7 +116,7 @@ int rcutree_offline_cpu(unsigned int cpu);
void rcutree_migrate_callbacks(int cpu);
-/* Called from hotplug and also arm64 early secondary boot failure */
+/* Called from hotplug */
void rcutree_report_cpu_dead(void);
#endif /* __LINUX_RCUTREE_H */
diff --git a/include/linux/regulator/driver.h b/include/linux/regulator/driver.h
index cc6ce709ec86..55cc519103ed 100644
--- a/include/linux/regulator/driver.h
+++ b/include/linux/regulator/driver.h
@@ -362,7 +362,7 @@ enum regulator_type {
* @off_on_delay: guard time (in uS), before re-enabling a regulator
*
* @poll_enabled_time: The polling interval (in uS) to use while checking that
- * the regulator was actually enabled. Max upto enable_time.
+ * the regulator was actually enabled. Max up to enable_time.
*
* @of_map_mode: Maps a hardware mode defined in a DeviceTree to a standard mode
*/
diff --git a/include/linux/regulator/lp872x.h b/include/linux/regulator/lp872x.h
deleted file mode 100644
index b62e45aa1dd3..000000000000
--- a/include/linux/regulator/lp872x.h
+++ /dev/null
@@ -1,86 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-only */
-/*
- * Copyright 2012 Texas Instruments
- *
- * Author: Milo(Woogyom) Kim <milo.kim@ti.com>
- */
-
-#ifndef __LP872X_REGULATOR_H__
-#define __LP872X_REGULATOR_H__
-
-#include <linux/regulator/machine.h>
-#include <linux/platform_device.h>
-#include <linux/gpio/consumer.h>
-
-#define LP872X_MAX_REGULATORS 9
-
-#define LP8720_ENABLE_DELAY 200
-#define LP8725_ENABLE_DELAY 30000
-
-enum lp872x_regulator_id {
- LP8720_ID_BASE,
- LP8720_ID_LDO1 = LP8720_ID_BASE,
- LP8720_ID_LDO2,
- LP8720_ID_LDO3,
- LP8720_ID_LDO4,
- LP8720_ID_LDO5,
- LP8720_ID_BUCK,
-
- LP8725_ID_BASE,
- LP8725_ID_LDO1 = LP8725_ID_BASE,
- LP8725_ID_LDO2,
- LP8725_ID_LDO3,
- LP8725_ID_LDO4,
- LP8725_ID_LDO5,
- LP8725_ID_LILO1,
- LP8725_ID_LILO2,
- LP8725_ID_BUCK1,
- LP8725_ID_BUCK2,
-
- LP872X_ID_MAX,
-};
-
-enum lp872x_dvs_sel {
- SEL_V1,
- SEL_V2,
-};
-
-/**
- * lp872x_dvs
- * @gpio : gpio descriptor for dvs control
- * @vsel : dvs selector for buck v1 or buck v2 register
- * @init_state : initial dvs pin state
- */
-struct lp872x_dvs {
- struct gpio_desc *gpio;
- enum lp872x_dvs_sel vsel;
- enum gpiod_flags init_state;
-};
-
-/**
- * lp872x_regdata
- * @id : regulator id
- * @init_data : init data for each regulator
- */
-struct lp872x_regulator_data {
- enum lp872x_regulator_id id;
- struct regulator_init_data *init_data;
-};
-
-/**
- * lp872x_platform_data
- * @general_config : the value of LP872X_GENERAL_CFG register
- * @update_config : if LP872X_GENERAL_CFG register is updated, set true
- * @regulator_data : platform regulator id and init data
- * @dvs : dvs data for buck voltage control
- * @enable_gpio : gpio descriptor for enable control
- */
-struct lp872x_platform_data {
- u8 general_config;
- bool update_config;
- struct lp872x_regulator_data regulator_data[LP872X_MAX_REGULATORS];
- struct lp872x_dvs *dvs;
- struct gpio_desc *enable_gpio;
-};
-
-#endif
diff --git a/include/linux/regulator/pca9450.h b/include/linux/regulator/pca9450.h
index 0df8b3c48082..bf94df5fafe3 100644
--- a/include/linux/regulator/pca9450.h
+++ b/include/linux/regulator/pca9450.h
@@ -210,9 +210,11 @@ enum {
#define LDO5L_EN_MASK 0xC0
#define LDO5LOUT_MASK 0x0F
-#define LDO5H_EN_MASK 0xC0
#define LDO5HOUT_MASK 0x0F
+/* LDO ENMODE value: ON in RUN, OFF while PMIC_STBY_REQ is asserted */
+#define LDO_ENMODE_ONREQ_STBYREQ 0x80
+
/* PCA9450_REG_IRQ bits */
#define IRQ_PWRON 0x80
#define IRQ_WDOGB 0x40
diff --git a/include/linux/remoteproc.h b/include/linux/remoteproc.h
index a44368737b39..ff0ad1e12c01 100644
--- a/include/linux/remoteproc.h
+++ b/include/linux/remoteproc.h
@@ -15,6 +15,7 @@
#include <linux/cdev.h>
#include <linux/completion.h>
#include <linux/idr.h>
+#include <linux/srcu.h>
#include <linux/of.h>
#include <linux/rsc_table.h>
@@ -228,6 +229,7 @@ enum rproc_features {
* @mappings: list of iommu mappings we initiated, needed on shutdown
* @bootaddr: address of first instruction to boot rproc with (optional)
* @rvdevs: list of remote virtio devices
+ * @vq_srcu: SRCU domain for the virtqueue callbacks of @rvdevs
* @subdevs: list of subdevices, to following the running state
* @notifyids: idr for dynamically assigning rproc-wide unique notify ids
* @index: index of this rproc device
@@ -274,6 +276,7 @@ struct rproc {
struct list_head mappings;
u64 bootaddr;
struct list_head rvdevs;
+ struct srcu_struct vq_srcu;
struct list_head subdevs;
struct idr notifyids;
int index;
diff --git a/include/linux/resctrl.h b/include/linux/resctrl.h
index dd09c2ce9a0f..10dfdca7f4bf 100644
--- a/include/linux/resctrl.h
+++ b/include/linux/resctrl.h
@@ -505,6 +505,25 @@ bool resctrl_arch_mbm_cntr_assign_enabled(struct rdt_resource *r);
*/
int resctrl_arch_mbm_cntr_assign_set(struct rdt_resource *r, bool enable);
+/**
+ * resctrl_arch_preconvert_bw() - Prepare bandwidth control value for arch use.
+ * @r: Resource whose schema was written.
+ * @val: Bandwidth control value written to the schemata file by userspace.
+ *
+ * Convert the user provided bandwidth control value to an appropriate form for
+ * consumption by the hardware driver for resource @r. Converted value is stored
+ * in rdt_ctrl_domain::staged_config[] for later consumption by
+ * resctrl_arch_update_domains(). Is not called when MBA software controller is
+ * enabled.
+ *
+ * Architectures for which this pre-conversion hook is not useful should supply
+ * an implementation of this function that just returns @val unmodified.
+ *
+ * Return:
+ * The converted value.
+ */
+u32 resctrl_arch_preconvert_bw(const struct rdt_resource *r, u32 val);
+
/*
* Update the ctrl_val and apply this config right now.
* Must be called on one of the domain's CPUs.
diff --git a/include/linux/resctrl_types.h b/include/linux/resctrl_types.h
index a5f56faa18d2..e2e2cf3d9ff6 100644
--- a/include/linux/resctrl_types.h
+++ b/include/linux/resctrl_types.h
@@ -60,6 +60,8 @@ enum resctrl_event_id {
PMT_EVENT_AUTO_C6_RES,
PMT_EVENT_UNHALTED_REF_CYCLES,
PMT_EVENT_UOPS_RETIRED,
+ PMT_EVENT_INST_RETIRED,
+ PMT_EVENT_PCNT,
/* Must be the last */
QOS_NUM_EVENTS,
diff --git a/include/linux/rhashtable-types.h b/include/linux/rhashtable-types.h
index 57c11ec9dc64..3576b8f08aff 100644
--- a/include/linux/rhashtable-types.h
+++ b/include/linux/rhashtable-types.h
@@ -70,6 +70,12 @@ struct rhashtable_params {
rht_obj_cmpfn_t obj_cmpfn;
};
+struct rhashtable_lockdep_keys {
+ struct lock_class_key lock_key;
+ struct lock_class_key mutex_key;
+ struct lock_class_key bucket_key;
+};
+
/**
* struct rhashtable - Hash table handle
* @tbl: Bucket table
@@ -97,6 +103,9 @@ struct rhashtable {
#ifdef CONFIG_MEM_ALLOC_PROFILING
struct alloc_tag *alloc_tag;
#endif
+#ifdef CONFIG_LOCKDEP
+ struct lock_class_key *lockdep_key;
+#endif
};
/**
@@ -138,24 +147,77 @@ struct rhashtable_iter {
int __rhashtable_init_noprof(struct rhashtable *ht,
const struct rhashtable_params *params,
- struct lock_class_key *key);
+ struct rhashtable_lockdep_keys *keys);
#define rhashtable_init_noprof(ht, params) \
({ \
- static struct lock_class_key __key; \
+ static struct rhashtable_lockdep_keys __keys; \
\
- __rhashtable_init_noprof(ht, params, &__key); \
+ __rhashtable_init_noprof(ht, params, &__keys); \
})
+
+/**
+ * rhashtable_init - initialize a new hash table
+ * @ht: hash table to be initialized
+ * @params: configuration parameters
+ *
+ * Initializes a new hash table based on the provided configuration
+ * parameters. A table can be configured either with a variable or
+ * fixed length key:
+ *
+ * Configuration Example 1: Fixed length keys
+ * struct test_obj {
+ * int key;
+ * void * my_member;
+ * struct rhash_head node;
+ * };
+ *
+ * struct rhashtable_params params = {
+ * .head_offset = offsetof(struct test_obj, node),
+ * .key_offset = offsetof(struct test_obj, key),
+ * .key_len = sizeof(int),
+ * .hashfn = jhash,
+ * };
+ *
+ * Configuration Example 2: Variable length keys
+ * struct test_obj {
+ * [...]
+ * struct rhash_head node;
+ * };
+ *
+ * u32 my_hash_fn(const void *data, u32 len, u32 seed)
+ * {
+ * struct test_obj *obj = data;
+ *
+ * return [... hash ...];
+ * }
+ *
+ * struct rhashtable_params params = {
+ * .head_offset = offsetof(struct test_obj, node),
+ * .hashfn = jhash,
+ * .obj_hashfn = my_hash_fn,
+ * };
+ */
#define rhashtable_init(...) alloc_hooks(rhashtable_init_noprof(__VA_ARGS__))
int __rhltable_init_noprof(struct rhltable *hlt,
const struct rhashtable_params *params,
- struct lock_class_key *key);
+ struct rhashtable_lockdep_keys *keys);
#define rhltable_init_noprof(hlt, params) \
({ \
- static struct lock_class_key __key; \
+ static struct rhashtable_lockdep_keys __keys; \
\
- __rhltable_init_noprof(hlt, params, &__key); \
+ __rhltable_init_noprof(hlt, params, &__keys); \
})
+
+/**
+ * rhltable_init - initialize a new hash list table
+ * @hlt: hash list table to be initialized
+ * @params: configuration parameters
+ *
+ * Initializes a new hash list table.
+ *
+ * See documentation for rhashtable_init.
+ */
#define rhltable_init(...) alloc_hooks(rhltable_init_noprof(__VA_ARGS__))
#endif /* _LINUX_RHASHTABLE_TYPES_H */
diff --git a/include/linux/rhashtable.h b/include/linux/rhashtable.h
index 57a2a29bef0e..70dac9214617 100644
--- a/include/linux/rhashtable.h
+++ b/include/linux/rhashtable.h
@@ -319,18 +319,6 @@ static inline struct rhash_lock_head __rcu **rht_bucket_insert(
* When we write to a bucket without unlocking, we use rht_assign_locked().
*/
-static inline unsigned long rht_lock(struct bucket_table *tbl,
- struct rhash_lock_head __rcu **bkt)
- __acquires(__bitlock(0, bkt))
-{
- unsigned long flags;
-
- local_irq_save(flags);
- bit_spin_lock(0, (unsigned long *)bkt);
- lock_map_acquire(&tbl->dep_map);
- return flags;
-}
-
static inline unsigned long rht_lock_nested(struct bucket_table *tbl,
struct rhash_lock_head __rcu **bucket,
unsigned int subclass)
@@ -344,6 +332,13 @@ static inline unsigned long rht_lock_nested(struct bucket_table *tbl,
return flags;
}
+static inline unsigned long rht_lock(struct bucket_table *tbl,
+ struct rhash_lock_head __rcu **bkt)
+ __acquires(__bitlock(0, bkt))
+{
+ return rht_lock_nested(tbl, bkt, 0);
+}
+
static inline void rht_unlock(struct bucket_table *tbl,
struct rhash_lock_head __rcu **bkt,
unsigned long flags)
@@ -598,13 +593,23 @@ static inline void rht_assign_unlock(struct bucket_table *tbl,
for (pos = list; pos && rht_entry(tpos, pos, member); \
pos = rcu_dereference_all(pos->next))
-static inline int rhashtable_compare(struct rhashtable_compare_arg *arg,
- const void *obj)
+/*
+ * Use constant params from inlined callers to specialize memcmp(). If params
+ * isn't constant, it must be equal to ht->p.
+ */
+static __always_inline int rhashtable_compare(struct rhashtable_compare_arg *arg,
+ const void *obj,
+ const struct rhashtable_params params)
{
struct rhashtable *ht = arg->ht;
const char *ptr = obj;
- return memcmp(ptr + ht->p.key_offset, arg->key, ht->p.key_len);
+ if (!__builtin_constant_p(params.key_len))
+ return memcmp(ptr + ht->p.key_offset, arg->key,
+ ht->p.key_len);
+
+ return memcmp(ptr + params.key_offset, arg->key,
+ params.key_len ? : ht->p.key_len);
}
/* Internal function, do not use. */
@@ -632,7 +637,7 @@ restart:
rht_for_each_rcu_from(he, __rht_ptr_rcu(bkt, freq), tbl, hash) {
if (params.obj_cmpfn ?
params.obj_cmpfn(&arg, rht_obj(ht, he)) :
- rhashtable_compare(&arg, rht_obj(ht, he)))
+ rhashtable_compare(&arg, rht_obj(ht, he), params))
continue;
return he;
}
@@ -797,7 +802,7 @@ slow_path:
if (!key ||
(params.obj_cmpfn ?
params.obj_cmpfn(&arg, rht_obj(ht, head)) :
- rhashtable_compare(&arg, rht_obj(ht, head)))) {
+ rhashtable_compare(&arg, rht_obj(ht, head), params))) {
pprev = &head->next;
continue;
}
diff --git a/include/linux/ring_buffer.h b/include/linux/ring_buffer.h
index afc7daa6ee7d..e4370064273e 100644
--- a/include/linux/ring_buffer.h
+++ b/include/linux/ring_buffer.h
@@ -3,8 +3,9 @@
#define _LINUX_RING_BUFFER_H
#include <linux/mm.h>
-#include <linux/seq_file.h>
#include <linux/poll.h>
+#include <linux/ring_buffer_types.h>
+#include <linux/seq_file.h>
#include <uapi/linux/trace_mmap.h>
@@ -98,6 +99,13 @@ struct trace_buffer *__ring_buffer_alloc_range(unsigned long size, unsigned flag
void *ring_buffer_meta_scratch(struct trace_buffer *buffer, unsigned int *size);
/*
+ * A minimum of 2 pages ensures we can always swap a page out of the ring
+ * buffer. This does not account for the reader page or any other page
+ * containing meta data used by static ring buffers.
+ */
+#define RING_BUFFER_MIN_NR_PAGES 2UL
+
+/*
* Because the ring buffer is generic, if other users of the ring buffer get
* traced by ftrace, it can produce lockdep warnings. We need to keep each
* ring buffer's lock class separate.
@@ -279,11 +287,25 @@ static inline struct ring_buffer_desc *__first_ring_buffer_desc(struct trace_buf
return (struct ring_buffer_desc *)(&desc->__data[0]);
}
+/*
+ * Returns the number of pages for a ring_buffer_desc. The caller must ensure it
+ * does not overflow ring_buffer_desc::nr_page_va.
+ */
+static inline unsigned long __calc_nr_pages_ring_buffer_desc(size_t size)
+{
+ /* Takes into account the reader page */
+ return max(DIV_ROUND_UP(size, PAGE_SIZE - BUF_PAGE_HDR_SIZE), RING_BUFFER_MIN_NR_PAGES) + 1;
+}
+
static inline size_t trace_buffer_desc_size(size_t buffer_size, unsigned int nr_cpus)
{
- unsigned int nr_pages = max(DIV_ROUND_UP(buffer_size, PAGE_SIZE), 2UL) + 1;
+ unsigned long nr_pages = __calc_nr_pages_ring_buffer_desc(buffer_size);
struct ring_buffer_desc *rbdesc;
+ /* Capped by ring_buffer_desc::nr_page_va */
+ if (nr_pages > UINT_MAX)
+ return SIZE_MAX;
+
return size_add(offsetof(struct trace_buffer_desc, __data),
size_mul(nr_cpus, struct_size(rbdesc, page_va, nr_pages)));
}
diff --git a/include/linux/rolling_buffer.h b/include/linux/rolling_buffer.h
index 9e5dad29669c..a97f7cfaacaa 100644
--- a/include/linux/rolling_buffer.h
+++ b/include/linux/rolling_buffer.h
@@ -45,9 +45,9 @@ struct rolling_buffer_snapshot {
int rolling_buffer_init(struct rolling_buffer *roll, unsigned int rreq_id,
unsigned int direction, gfp_t gfp);
int rolling_buffer_make_space(struct rolling_buffer *roll, gfp_t gfp);
-ssize_t rolling_buffer_load_from_ra(struct rolling_buffer *roll,
- struct readahead_control *ractl,
- struct folio_batch *put_batch);
+ssize_t rolling_buffer_bulk_load_from_ra(struct rolling_buffer *roll,
+ struct readahead_control *ractl,
+ unsigned int rreq_id, gfp_t gfp);
ssize_t rolling_buffer_append(struct rolling_buffer *roll, struct folio *folio,
unsigned int flags, gfp_t gfp);
struct folio_queue *rolling_buffer_delete_spent(struct rolling_buffer *roll);
diff --git a/include/linux/rtnetlink.h b/include/linux/rtnetlink.h
index 95729339e7a5..a54ec40d095c 100644
--- a/include/linux/rtnetlink.h
+++ b/include/linux/rtnetlink.h
@@ -186,7 +186,12 @@ void net_dec_ingress_queue(void);
#ifdef CONFIG_NET_EGRESS
void net_inc_egress_queue(void);
void net_dec_egress_queue(void);
-void netdev_xmit_skip_txqueue(bool skip);
+bool netdev_xmit_skip_txqueue(bool skip);
+#else
+static inline bool netdev_xmit_skip_txqueue(bool skip)
+{
+ return false;
+}
#endif
void rtnetlink_init(void);
diff --git a/include/linux/sched.h b/include/linux/sched.h
index 8b3d47a325cc..1c93da75226e 100644
--- a/include/linux/sched.h
+++ b/include/linux/sched.h
@@ -554,6 +554,7 @@ struct sched_statistics {
u64 nr_failed_migrations_running;
u64 nr_failed_migrations_hot;
u64 nr_forced_migrations;
+ u64 nr_migrations_cpu_non_preferred;
u64 nr_wakeups;
u64 nr_wakeups_sync;
@@ -1172,8 +1173,12 @@ struct task_struct {
/* Objective and real subjective task credentials (COW): */
const struct cred __rcu *real_cred;
- /* Effective (overridable) subjective task credentials (COW): */
- const struct cred __rcu *cred;
+ /*
+ * Effective (overridable) subjective task credentials (COW).
+ * Only accessible for the current task and during task creation/freeing.
+ * This pointer is not managed by RCU!
+ */
+ const struct cred *cred;
#ifdef CONFIG_KEYS
/* Cached requested key. */
@@ -1433,6 +1438,7 @@ struct task_struct {
#ifdef CONFIG_SCHED_CACHE
struct callback_head cache_work;
+ struct sched_cache_group __rcu *sched_cache_grp;
int preferred_llc;
/* 1: task was enqueued to its preferred LLC, 0 otherwise */
int pref_llc_queued;
@@ -1787,7 +1793,7 @@ static inline bool is_lazy_mmu_mode_active(void)
}
#endif
-extern struct pid *cad_pid;
+extern struct pid __rcu *cad_pid;
/*
* Per process flags
@@ -1808,15 +1814,15 @@ extern struct pid *cad_pid;
#define PF_USED_MATH 0x00002000 /* If unset the fpu must be initialized before use */
#define PF_USER_WORKER 0x00004000 /* Kernel thread cloned from userspace thread */
#define PF_NOFREEZE 0x00008000 /* This thread should not be frozen */
-#define PF_KCOMPACTD 0x00010000 /* I am kcompactd */
-#define PF_KSWAPD 0x00020000 /* I am kswapd */
+#define PF__HOLE__00010000 0x00010000
+#define PF__HOLE__00020000 0x00020000
#define PF_MEMALLOC_NOFS 0x00040000 /* All allocations inherit GFP_NOFS. See memalloc_nfs_save() */
#define PF_MEMALLOC_NOIO 0x00080000 /* All allocations inherit GFP_NOIO. See memalloc_noio_save() */
#define PF_LOCAL_THROTTLE 0x00100000 /* Throttle writes only against the bdi I write to,
* 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__HOLE__00800000 0x00800000
+#define PF_NO_NOTIFY_SIGNAL 0x00800000 /* see no_notify_signal_save() */
#define PF__HOLE__01000000 0x01000000
#define PF__HOLE__02000000 0x02000000
#define PF_NO_SETAFFINITY 0x04000000 /* Userland is not allowed to meddle with cpus_mask */
@@ -2104,10 +2110,9 @@ static inline int test_tsk_thread_flag(struct task_struct *tsk, int flag)
static inline void set_tsk_need_resched(struct task_struct *tsk)
{
- if (tracepoint_enabled(sched_set_need_resched_tp) &&
- !test_tsk_thread_flag(tsk, TIF_NEED_RESCHED))
+ if (!test_and_set_tsk_thread_flag(tsk, TIF_NEED_RESCHED) &&
+ tracepoint_enabled(sched_set_need_resched_tp))
__trace_set_need_resched(tsk, TIF_NEED_RESCHED);
- set_tsk_thread_flag(tsk,TIF_NEED_RESCHED);
}
static inline void clear_tsk_need_resched(struct task_struct *tsk)
@@ -2134,44 +2139,19 @@ static inline void set_need_resched_current(void)
* value indicates whether a reschedule was done in fact.
* cond_resched_lock() will drop the spinlock before scheduling,
*/
-#if !defined(CONFIG_PREEMPTION) || defined(CONFIG_PREEMPT_DYNAMIC)
+#if !defined(CONFIG_PREEMPTION)
extern int __cond_resched(void);
-#if defined(CONFIG_PREEMPT_DYNAMIC) && defined(CONFIG_HAVE_PREEMPT_DYNAMIC_CALL)
-
-DECLARE_STATIC_CALL(cond_resched, __cond_resched);
-
-static __always_inline int _cond_resched(void)
-{
- return static_call_mod(cond_resched)();
-}
-
-#elif defined(CONFIG_PREEMPT_DYNAMIC) && defined(CONFIG_HAVE_PREEMPT_DYNAMIC_KEY)
-
-extern int dynamic_cond_resched(void);
-
-static __always_inline int _cond_resched(void)
-{
- return dynamic_cond_resched();
-}
-
-#else /* !CONFIG_PREEMPTION */
-
static inline int _cond_resched(void)
{
return __cond_resched();
}
-
-#endif /* PREEMPT_DYNAMIC && CONFIG_HAVE_PREEMPT_DYNAMIC_CALL */
-
-#else /* CONFIG_PREEMPTION && !CONFIG_PREEMPT_DYNAMIC */
-
+#else
static inline int _cond_resched(void)
{
return 0;
}
-
-#endif /* !CONFIG_PREEMPTION || CONFIG_PREEMPT_DYNAMIC */
+#endif
#define cond_resched() ({ \
__might_resched(__FILE__, __LINE__, 0); \
@@ -2405,7 +2385,7 @@ struct sched_cache_time {
unsigned long epoch;
};
-struct sched_cache_stat {
+struct sched_cache_group {
struct sched_cache_time __percpu *pcpu_sched;
raw_spinlock_t lock;
unsigned long epoch;
@@ -2413,11 +2393,26 @@ struct sched_cache_stat {
unsigned long next_scan;
unsigned long footprint;
int cpu;
+ refcount_t refcnt;
+ struct rcu_head rcu;
} ____cacheline_aligned_in_smp;
+struct sched_cache_group *sched_cache_group_get(struct sched_cache_group *grp);
+struct sched_cache_group *task_cache_group_get(struct task_struct *p);
+
+void sched_cache_fork(struct task_struct *p);
+void sched_cache_fork_cleanup(struct task_struct *p);
+void sched_cache_exec_mmap(struct task_struct *p, struct mm_struct *mm);
+void sched_cache_exit_mm(struct task_struct *p);
+
#else
-struct sched_cache_stat { };
+struct sched_cache_group { };
+
+static inline void sched_cache_fork(struct task_struct *p) { }
+static inline void sched_cache_fork_cleanup(struct task_struct *p) { }
+static inline void sched_cache_exec_mmap(struct task_struct *p, struct mm_struct *mm) { }
+static inline void sched_cache_exit_mm(struct task_struct *p) { }
#endif
diff --git a/include/linux/sched/cputime.h b/include/linux/sched/cputime.h
index e90efaf6d26e..694126411dfe 100644
--- a/include/linux/sched/cputime.h
+++ b/include/linux/sched/cputime.h
@@ -182,9 +182,9 @@ extern unsigned long long
task_sched_runtime(struct task_struct *task);
#ifdef CONFIG_PARAVIRT
-struct static_key;
-extern struct static_key paravirt_steal_enabled;
-extern struct static_key paravirt_steal_rq_enabled;
+#include <linux/jump_label.h>
+DECLARE_STATIC_KEY_FALSE(paravirt_steal_enabled);
+DECLARE_STATIC_KEY_FALSE(paravirt_steal_rq_enabled);
#ifdef CONFIG_HAVE_PV_STEAL_CLOCK_GEN
u64 dummy_steal_clock(int cpu);
diff --git a/include/linux/sched/ext.h b/include/linux/sched/ext.h
index 582d7cd4a983..efd635a99309 100644
--- a/include/linux/sched/ext.h
+++ b/include/linux/sched/ext.h
@@ -91,7 +91,7 @@ struct scx_dispatch_q {
struct rhash_head hash_node;
struct llist_node free_node;
struct scx_sched *sched;
- struct scx_dsq_pcpu __percpu *pcpu;
+ struct scx_dsq_pcpu __percpu *pcpu_user;
struct rcu_head rcu;
};
@@ -104,6 +104,7 @@ enum scx_ent_flags {
SCX_TASK_SUB_INIT = 1 << 4, /* task being initialized for a sub sched */
SCX_TASK_IMMED = 1 << 5, /* task is on local DSQ with %SCX_ENQ_IMMED */
SCX_TASK_PROTECTED = 1 << 6, /* slice and DSQ head position protected */
+ SCX_TASK_RUN_TRACKED = 1 << 7, /* task is in an ops.running()/stopping() session */
/*
* Bits 8 to 10 are used to carry task state:
@@ -136,6 +137,7 @@ enum scx_ent_flags {
* IMMED reenqueued due to failed ENQ_IMMED
* PREEMPTED preempted while running
* CAP sub-sched cap miss, see p->scx.reenq_reason_*
+ * PROXY proxy state prevented a remote DSQ transfer
*/
SCX_TASK_REENQ_REASON_SHIFT = 12,
SCX_TASK_REENQ_REASON_BITS = 3,
@@ -146,6 +148,7 @@ enum scx_ent_flags {
SCX_TASK_REENQ_IMMED = 2 << SCX_TASK_REENQ_REASON_SHIFT,
SCX_TASK_REENQ_PREEMPTED = 3 << SCX_TASK_REENQ_REASON_SHIFT,
SCX_TASK_REENQ_CAP = 4 << SCX_TASK_REENQ_REASON_SHIFT,
+ SCX_TASK_REENQ_PROXY = 5 << SCX_TASK_REENQ_REASON_SHIFT,
/* iteration cursor, not a task */
SCX_TASK_CURSOR = 1 << 31,
@@ -154,6 +157,7 @@ enum scx_ent_flags {
/* scx_entity.dsq_flags */
enum scx_ent_dsq_flags {
SCX_TASK_DSQ_ON_PRIQ = 1 << 0, /* task is queued on the priority queue of a dsq */
+ SCX_TASK_DSQ_REENQ = 1 << 1, /* marked by scx_bpf_dsq_reenq_task() */
};
enum scx_dsq_lnode_flags {
@@ -197,9 +201,19 @@ struct sched_ext_entity {
u64 ddsp_slice;
u64 ddsp_vtime;
struct scx_dsq_list_node dsq_list; /* dispatch order */
- struct rb_node dsq_priq; /* p->scx.dsq_vtime order */
u32 dsq_seq;
u32 dsq_flags; /* protected by DSQ lock */
+
+ /*
+ * Used to order tasks when dispatching to the vtime-ordered priority
+ * queue of a dsq. This is usually set through
+ * scx_bpf_dsq_insert_vtime() but can also be modified directly by the
+ * BPF scheduler. Modifying it while a task is queued on a dsq may
+ * mangle the ordering and is not recommended. Kept next to @dsq_priq
+ * as rbtree insertion reads both on every visited node.
+ */
+ u64 dsq_vtime;
+ struct rb_node dsq_priq; /* p->scx.dsq_vtime order */
u32 flags; /* protected by rq lock */
u32 weight;
u32 reenq_cnt; /* reenqueues since last run */
@@ -207,6 +221,7 @@ struct sched_ext_entity {
s32 holding_cpu;
s32 selected_cpu;
s32 runnable_cpu; /* cpu @p is runnable on, -1 if not */
+ u32 ops_qseq; /* protected by rq lock */
struct task_struct *kf_tasks[2]; /* see SCX_CALL_OP_TASK() */
struct list_head runnable_node; /* rq->scx.runnable_list */
@@ -225,7 +240,7 @@ struct sched_ext_entity {
u64 tid;
struct rhash_head tid_hash_node; /* see SCX_OPS_TID_TO_TASK */
- /* BPF scheduler modifiable fields */
+ /* BPF scheduler modifiable fields, along with @dsq_vtime above */
/*
* Runtime budget in nsecs - how long the task may hold its cpu. Owned
@@ -241,15 +256,6 @@ struct sched_ext_entity {
u64 slice;
/*
- * Used to order tasks when dispatching to the vtime-ordered priority
- * queue of a dsq. This is usually set through
- * scx_bpf_dsq_insert_vtime() but can also be modified directly by the
- * BPF scheduler. Modifying it while a task is queued on a dsq may
- * mangle the ordering and is not recommended.
- */
- u64 dsq_vtime;
-
- /*
* Out-of-band slice request from scx_bpf_task_set_slice() when the
* caller does not hold the rq lock, applied under the rq lock at the
* next slice consideration. One atomic64 packs the pending flag, the
@@ -278,6 +284,14 @@ struct sched_ext_entity {
*/
bool disallow; /* reject switching into SCX */
+ /*
+ * If set, depletion of this task's slice at the scheduler tick requests
+ * lazy instead of immediate rescheduling. Initialized from
+ * %SCX_OPS_LAZY_RESCHED immediately before ops.enable() and may be
+ * modified afterwards with scx_bpf_task_set_lazy_resched().
+ */
+ bool lazy_resched;
+
/* cold fields */
#ifdef CONFIG_EXT_GROUP_SCHED
struct cgroup *cgrp_moving_from;
@@ -323,7 +337,7 @@ struct scx_task_group {
u64 bw_period_us;
u64 bw_quota_us;
u64 bw_burst_us;
- bool idle;
+ bool sched_idle;
#endif
};
diff --git a/include/linux/sched/signal.h b/include/linux/sched/signal.h
index 584ae88b435e..0adb51ab1542 100644
--- a/include/linux/sched/signal.h
+++ b/include/linux/sched/signal.h
@@ -2,6 +2,7 @@
#ifndef _LINUX_SCHED_SIGNAL_H
#define _LINUX_SCHED_SIGNAL_H
+#include <linux/cleanup.h>
#include <linux/rculist.h>
#include <linux/signal.h>
#include <linux/sched.h>
@@ -79,9 +80,9 @@ struct core_thread {
};
struct core_state {
- atomic_t nr_threads;
- struct core_thread dumper;
- struct completion startup;
+ /* Threads the dumper still waits for. */
+ atomic_t threads_remaining;
+ struct core_thread *tasks;
};
/*
@@ -130,8 +131,8 @@ struct signal_struct {
* process will inherit a flag if they should look for a
* child_subreaper process at exit.
*/
- unsigned int is_child_subreaper:1;
- unsigned int has_child_subreaper:1;
+ bool is_child_subreaper;
+ bool has_child_subreaper;
unsigned int autoreap:1;
#ifdef CONFIG_POSIX_TIMERS
@@ -384,14 +385,36 @@ static inline int task_sigpending(struct task_struct *p)
return unlikely(test_tsk_thread_flag(p,TIF_SIGPENDING));
}
+/* Prevent TIF_NOTIFY_SIGNAL from interrupting this task. */
+static inline unsigned int no_notify_signal_save(void)
+{
+ unsigned int flags = current->flags;
+
+ current->flags |= PF_NO_NOTIFY_SIGNAL;
+ return flags;
+}
+
+/* Restore the previous PF_NO_NOTIFY_SIGNAL state. */
+static inline void no_notify_signal_restore(unsigned int flags)
+{
+ current_restore_flags(flags, PF_NO_NOTIFY_SIGNAL);
+}
+
+DEFINE_LOCK_GUARD_0(no_notify_signal,
+ _T->flags = no_notify_signal_save(),
+ no_notify_signal_restore(_T->flags),
+ unsigned int flags)
+
static inline int signal_pending(struct task_struct *p)
{
/*
* TIF_NOTIFY_SIGNAL isn't really a signal, but it requires the same
* behavior in terms of ensuring that we break out of wait loops
- * so that notify signal callbacks can be processed.
+ * so that notify signal callbacks can be processed. Not for a task
+ * that asked not to be interrupted by it, see no_notify_signal_save().
*/
- if (unlikely(test_tsk_thread_flag(p, TIF_NOTIFY_SIGNAL)))
+ if (unlikely(test_tsk_thread_flag(p, TIF_NOTIFY_SIGNAL)) &&
+ likely(!(READ_ONCE(p->flags) & PF_NO_NOTIFY_SIGNAL)))
return 1;
return task_sigpending(p);
}
@@ -562,10 +585,7 @@ static inline sigset_t *sigmask_to_save(void)
return res;
}
-static inline int kill_cad_pid(int sig, int priv)
-{
- return kill_pid(cad_pid, sig, priv);
-}
+int kill_cad_pid(int sig, int priv);
/* These can be the second arg to send_sig_info/send_group_sig_info. */
#define SEND_SIG_NOINFO ((struct kernel_siginfo *) 0)
@@ -677,6 +697,24 @@ struct pid *task_pid_type(struct task_struct *task, enum pid_type type)
return pid;
}
+/* Fill @pids with the pid types of @task up to @last, without references. */
+static inline void __task_pids(struct pid **pids, enum pid_type last,
+ struct task_struct *task)
+{
+ for (enum pid_type type = PIDTYPE_PID; type <= last; type++)
+ pids[type] = task_pid_type(task, type);
+}
+
+static inline void __get_task_pids(struct pid **pids, enum pid_type last,
+ struct task_struct *task)
+{
+ for (enum pid_type type = PIDTYPE_PID; type <= last; type++)
+ pids[type] = get_pid(task_pid_type(task, type));
+}
+
+#define task_pids(pids, task) __task_pids(pids, pids_last(pids), task)
+#define get_task_pids(pids, task) __get_task_pids(pids, pids_last(pids), task)
+
static inline struct pid *task_tgid(struct task_struct *task)
{
return task->signal->pids[PIDTYPE_TGID];
diff --git a/include/linux/sched/stat.h b/include/linux/sched/stat.h
index 0108a38bb64d..4810b14d0372 100644
--- a/include/linux/sched/stat.h
+++ b/include/linux/sched/stat.h
@@ -20,7 +20,7 @@ extern int nr_processes(void);
extern unsigned int nr_running(void);
extern bool single_task_running(void);
extern unsigned int nr_iowait(void);
-extern unsigned int nr_iowait_cpu(int cpu);
+extern bool cpu_has_iowait(int cpu);
static inline int sched_info_on(void)
{
diff --git a/include/linux/sched/task.h b/include/linux/sched/task.h
index e0c1ca8c6a18..90ed5bc3c7af 100644
--- a/include/linux/sched/task.h
+++ b/include/linux/sched/task.h
@@ -94,7 +94,6 @@ static inline void exit_thread(struct task_struct *tsk)
extern __noreturn void do_group_exit(int);
extern void exit_files(struct task_struct *);
-extern void exit_itimers(struct task_struct *);
extern pid_t kernel_clone(struct kernel_clone_args *kargs);
struct task_struct *copy_process(struct pid *pid, int trace, int node,
diff --git a/include/linux/sched/topology.h b/include/linux/sched/topology.h
index b5d9d7c2b8ad..f96812d71c51 100644
--- a/include/linux/sched/topology.h
+++ b/include/linux/sched/topology.h
@@ -281,9 +281,9 @@ static inline int task_node(const struct task_struct *p)
}
#ifdef CONFIG_SCHED_CACHE
-extern void sched_update_llc_bytes(unsigned int cpu);
+extern void sched_update_llc_bytes(const struct cpumask *cpus);
#else
-static inline void sched_update_llc_bytes(unsigned int cpu) { }
+static inline void sched_update_llc_bytes(const struct cpumask *cpus) { }
#endif
#endif /* _LINUX_SCHED_TOPOLOGY_H */
diff --git a/include/linux/sched/user.h b/include/linux/sched/user.h
index 8d7e5521f7cd..ec262b605437 100644
--- a/include/linux/sched/user.h
+++ b/include/linux/sched/user.h
@@ -23,11 +23,13 @@ struct user_struct {
struct hlist_node uidhash_node;
kuid_t uid;
-#if defined(CONFIG_PERF_EVENTS) || defined(CONFIG_BPF_SYSCALL) || \
- defined(CONFIG_NET) || defined(CONFIG_IO_URING) || \
+#if defined(CONFIG_NET) || defined(CONFIG_IO_URING) || \
defined(CONFIG_VFIO_PCI_ZDEV_KVM) || IS_ENABLED(CONFIG_IOMMUFD) || \
defined(CONFIG_SECRETMEM)
- atomic_long_t locked_vm;
+ atomic_long_t locked_vm; /* pinned pages charged to RLIMIT_MEMLOCK */
+#endif
+#ifdef CONFIG_PERF_EVENTS
+ atomic_long_t perf_mlock; /* perf buffer pages within perf_event_mlock_kb */
#endif
#ifdef CONFIG_WATCH_QUEUE
atomic_t nr_watches; /* The number of watches this user currently has */
diff --git a/include/linux/scmi_protocol.h b/include/linux/scmi_protocol.h
index 5ab73b1ab9aa..3f7cc35eb861 100644
--- a/include/linux/scmi_protocol.h
+++ b/include/linux/scmi_protocol.h
@@ -9,6 +9,7 @@
#define _LINUX_SCMI_PROTOCOL_H
#include <linux/bitfield.h>
+#include <linux/device-id/scmi.h>
#include <linux/device.h>
#include <linux/notifier.h>
#include <linux/types.h>
@@ -528,22 +529,25 @@ struct scmi_sensor_proto_ops {
u32 sensor_id, u32 sensor_config);
};
+struct scmi_reset_domain_info {
+ char name[SCMI_MAX_STR_SIZE];
+ u32 latency_us;
+};
+
/**
* struct scmi_reset_proto_ops - represents the various operations provided
* by SCMI Reset Protocol
*
* @num_domains_get: get the count of reset domains provided by SCMI
- * @name_get: gets the name of a reset domain
- * @latency_get: gets the reset latency for the specified reset domain
+ * @info_get: gets the information of the specified reset domain
* @reset: resets the specified reset domain
* @assert: explicitly assert reset signal of the specified reset domain
* @deassert: explicitly deassert reset signal of the specified reset domain
*/
struct scmi_reset_proto_ops {
int (*num_domains_get)(const struct scmi_protocol_handle *ph);
- const char *(*name_get)(const struct scmi_protocol_handle *ph,
- u32 domain);
- int (*latency_get)(const struct scmi_protocol_handle *ph, u32 domain);
+ const struct scmi_reset_domain_info __must_check *(*info_get)
+ (const struct scmi_protocol_handle *ph, u32 domain);
int (*reset)(const struct scmi_protocol_handle *ph, u32 domain);
int (*assert)(const struct scmi_protocol_handle *ph, u32 domain);
int (*deassert)(const struct scmi_protocol_handle *ph, u32 domain);
@@ -930,6 +934,7 @@ enum scmi_std_protocol {
SCMI_PROTOCOL_VOLTAGE = 0x17,
SCMI_PROTOCOL_POWERCAP = 0x18,
SCMI_PROTOCOL_PINCTRL = 0x19,
+ SCMI_PROTOCOL_TELEMETRY = 0x1B,
};
enum scmi_system_events {
@@ -951,11 +956,6 @@ struct scmi_device {
#define to_scmi_dev(d) container_of_const(d, struct scmi_device, dev)
-struct scmi_device_id {
- u8 protocol_id;
- const char *name;
-};
-
struct scmi_driver {
const char *name;
int (*probe)(struct scmi_device *sdev);
diff --git a/include/linux/seccomp.h b/include/linux/seccomp.h
index fcb3eb9825e5..3b6cc376fff5 100644
--- a/include/linux/seccomp.h
+++ b/include/linux/seccomp.h
@@ -10,7 +10,8 @@
SECCOMP_FILTER_FLAG_SPEC_ALLOW | \
SECCOMP_FILTER_FLAG_NEW_LISTENER | \
SECCOMP_FILTER_FLAG_TSYNC_ESRCH | \
- SECCOMP_FILTER_FLAG_WAIT_KILLABLE_RECV)
+ SECCOMP_FILTER_FLAG_WAIT_KILLABLE_RECV | \
+ SECCOMP_FILTER_FLAG_RESTART_BEFORE_RECV)
/* sizeof() the first published struct seccomp_notif_addfd */
#define SECCOMP_NOTIFY_ADDFD_SIZE_VER0 24
diff --git a/include/linux/security.h b/include/linux/security.h
index 153e9043058f..40831fab5470 100644
--- a/include/linux/security.h
+++ b/include/linux/security.h
@@ -67,6 +67,7 @@ enum fs_value_type;
struct watch;
struct watch_notification;
struct lsm_ctx;
+struct nsset;
/* Default (no) options for the capable function */
#define CAP_OPT_NONE 0x0
@@ -80,6 +81,7 @@ struct lsm_ctx;
struct ctl_table;
struct audit_krule;
+struct ns_common;
struct user_namespace;
struct timezone;
@@ -185,11 +187,11 @@ extern int cap_capset(struct cred *new, const struct cred *old,
extern int cap_bprm_creds_from_file(struct linux_binprm *bprm, const struct file *file);
int cap_inode_setxattr(struct dentry *dentry, const char *name,
const void *value, size_t size, int flags);
-int cap_inode_removexattr(struct mnt_idmap *idmap,
+int cap_inode_removexattr(const struct mnt_idmap *idmap,
struct dentry *dentry, const char *name);
int cap_inode_need_killpriv(struct dentry *dentry);
-int cap_inode_killpriv(struct mnt_idmap *idmap, struct dentry *dentry);
-int cap_inode_getsecurity(struct mnt_idmap *idmap,
+int cap_inode_killpriv(const struct mnt_idmap *idmap, struct dentry *dentry);
+int cap_inode_getsecurity(const struct mnt_idmap *idmap,
struct inode *inode, const char *name, void **buffer,
bool alloc);
extern int cap_mmap_addr(unsigned long addr);
@@ -404,49 +406,53 @@ int security_inode_init_security(struct inode *inode, struct inode *dir,
int security_inode_init_security_anon(struct inode *inode,
const struct qstr *name,
const struct inode *context_inode);
-int security_inode_create(struct inode *dir, struct dentry *dentry, umode_t mode);
-void security_inode_post_create_tmpfile(struct mnt_idmap *idmap,
+int security_inode_create(const struct mnt_idmap *idmap, struct inode *dir,
+ struct dentry *dentry, umode_t mode);
+void security_inode_post_create_tmpfile(const struct mnt_idmap *idmap,
struct inode *inode);
-int security_inode_link(struct dentry *old_dentry, struct inode *dir,
- struct dentry *new_dentry);
+int security_inode_link(const struct mnt_idmap *idmap, struct dentry *old_dentry,
+ struct inode *dir, struct dentry *new_dentry);
int security_inode_unlink(struct inode *dir, struct dentry *dentry);
-int security_inode_symlink(struct inode *dir, struct dentry *dentry,
- const char *old_name);
-int security_inode_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode);
+int security_inode_symlink(const struct mnt_idmap *idmap, struct inode *dir,
+ struct dentry *dentry, const char *old_name);
+int security_inode_mkdir(const struct mnt_idmap *idmap, struct inode *dir,
+ struct dentry *dentry, umode_t mode);
int security_inode_rmdir(struct inode *dir, struct dentry *dentry);
-int security_inode_mknod(struct inode *dir, struct dentry *dentry, umode_t mode, dev_t dev);
+int security_inode_mknod(const struct mnt_idmap *idmap, struct inode *dir,
+ struct dentry *dentry, umode_t mode, dev_t dev);
int security_inode_rename(struct inode *old_dir, struct dentry *old_dentry,
struct inode *new_dir, struct dentry *new_dentry,
unsigned int flags);
int security_inode_readlink(struct dentry *dentry);
int security_inode_follow_link(struct dentry *dentry, struct inode *inode,
bool rcu);
-int security_inode_permission(struct inode *inode, int mask);
-int security_inode_setattr(struct mnt_idmap *idmap,
+int security_inode_permission(const struct mnt_idmap *idmap,
+ struct inode *inode, int mask);
+int security_inode_setattr(const struct mnt_idmap *idmap,
struct dentry *dentry, struct iattr *attr);
-void security_inode_post_setattr(struct mnt_idmap *idmap, struct dentry *dentry,
+void security_inode_post_setattr(const struct mnt_idmap *idmap, struct dentry *dentry,
int ia_valid);
int security_inode_getattr(const struct path *path);
-int security_inode_setxattr(struct mnt_idmap *idmap,
+int security_inode_setxattr(const struct mnt_idmap *idmap,
struct dentry *dentry, const char *name,
const void *value, size_t size, int flags);
-int security_inode_set_acl(struct mnt_idmap *idmap,
+int security_inode_set_acl(const struct mnt_idmap *idmap,
struct dentry *dentry, const char *acl_name,
struct posix_acl *kacl);
void security_inode_post_set_acl(struct dentry *dentry, const char *acl_name,
struct posix_acl *kacl);
-int security_inode_get_acl(struct mnt_idmap *idmap,
+int security_inode_get_acl(const struct mnt_idmap *idmap,
struct dentry *dentry, const char *acl_name);
-int security_inode_remove_acl(struct mnt_idmap *idmap,
+int security_inode_remove_acl(const struct mnt_idmap *idmap,
struct dentry *dentry, const char *acl_name);
-void security_inode_post_remove_acl(struct mnt_idmap *idmap,
+void security_inode_post_remove_acl(const struct mnt_idmap *idmap,
struct dentry *dentry,
const char *acl_name);
void security_inode_post_setxattr(struct dentry *dentry, const char *name,
const void *value, size_t size, int flags);
int security_inode_getxattr(struct dentry *dentry, const char *name);
int security_inode_listxattr(struct dentry *dentry);
-int security_inode_removexattr(struct mnt_idmap *idmap,
+int security_inode_removexattr(const struct mnt_idmap *idmap,
struct dentry *dentry, const char *name);
void security_inode_post_removexattr(struct dentry *dentry, const char *name);
int security_inode_file_setattr(struct dentry *dentry,
@@ -454,8 +460,8 @@ int security_inode_file_setattr(struct dentry *dentry,
int security_inode_file_getattr(struct dentry *dentry,
struct file_kattr *fa);
int security_inode_need_killpriv(struct dentry *dentry);
-int security_inode_killpriv(struct mnt_idmap *idmap, struct dentry *dentry);
-int security_inode_getsecurity(struct mnt_idmap *idmap,
+int security_inode_killpriv(const struct mnt_idmap *idmap, struct dentry *dentry);
+int security_inode_getsecurity(const struct mnt_idmap *idmap,
struct inode *inode, const char *name,
void **buffer, bool alloc);
int security_inode_setsecurity(struct inode *inode, const char *name, const void *value, size_t size, int flags);
@@ -540,6 +546,9 @@ int security_task_prctl(int option, unsigned long arg2, unsigned long arg3,
unsigned long arg4, unsigned long arg5);
void security_task_to_inode(struct task_struct *p, struct inode *inode);
int security_create_user_ns(const struct cred *cred);
+int security_namespace_init(struct ns_common *ns);
+void security_namespace_free(struct ns_common *ns);
+int security_namespace_install(const struct nsset *nsset, struct ns_common *ns);
int security_ipc_permission(struct kern_ipc_perm *ipcp, short flag);
void security_ipc_getlsmprop(struct kern_ipc_perm *ipcp, struct lsm_prop *prop);
int security_msg_msg_alloc(struct msg_msg *msg);
@@ -902,20 +911,22 @@ static inline int security_inode_init_security_anon(struct inode *inode,
return 0;
}
-static inline int security_inode_create(struct inode *dir,
- struct dentry *dentry,
- umode_t mode)
+static inline int security_inode_create(const struct mnt_idmap *idmap,
+ struct inode *dir,
+ struct dentry *dentry,
+ umode_t mode)
{
return 0;
}
static inline void
-security_inode_post_create_tmpfile(struct mnt_idmap *idmap, struct inode *inode)
+security_inode_post_create_tmpfile(const struct mnt_idmap *idmap, struct inode *inode)
{ }
-static inline int security_inode_link(struct dentry *old_dentry,
- struct inode *dir,
- struct dentry *new_dentry)
+static inline int security_inode_link(const struct mnt_idmap *idmap,
+ struct dentry *old_dentry,
+ struct inode *dir,
+ struct dentry *new_dentry)
{
return 0;
}
@@ -926,16 +937,18 @@ static inline int security_inode_unlink(struct inode *dir,
return 0;
}
-static inline int security_inode_symlink(struct inode *dir,
- struct dentry *dentry,
- const char *old_name)
+static inline int security_inode_symlink(const struct mnt_idmap *idmap,
+ struct inode *dir,
+ struct dentry *dentry,
+ const char *old_name)
{
return 0;
}
-static inline int security_inode_mkdir(struct inode *dir,
- struct dentry *dentry,
- int mode)
+static inline int security_inode_mkdir(const struct mnt_idmap *idmap,
+ struct inode *dir,
+ struct dentry *dentry,
+ int mode)
{
return 0;
}
@@ -946,9 +959,10 @@ static inline int security_inode_rmdir(struct inode *dir,
return 0;
}
-static inline int security_inode_mknod(struct inode *dir,
- struct dentry *dentry,
- int mode, dev_t dev)
+static inline int security_inode_mknod(const struct mnt_idmap *idmap,
+ struct inode *dir,
+ struct dentry *dentry,
+ int mode, dev_t dev)
{
return 0;
}
@@ -974,12 +988,13 @@ static inline int security_inode_follow_link(struct dentry *dentry,
return 0;
}
-static inline int security_inode_permission(struct inode *inode, int mask)
+static inline int security_inode_permission(const struct mnt_idmap *idmap,
+ struct inode *inode, int mask)
{
return 0;
}
-static inline int security_inode_setattr(struct mnt_idmap *idmap,
+static inline int security_inode_setattr(const struct mnt_idmap *idmap,
struct dentry *dentry,
struct iattr *attr)
{
@@ -987,7 +1002,7 @@ static inline int security_inode_setattr(struct mnt_idmap *idmap,
}
static inline void
-security_inode_post_setattr(struct mnt_idmap *idmap, struct dentry *dentry,
+security_inode_post_setattr(const struct mnt_idmap *idmap, struct dentry *dentry,
int ia_valid)
{ }
@@ -996,14 +1011,14 @@ static inline int security_inode_getattr(const struct path *path)
return 0;
}
-static inline int security_inode_setxattr(struct mnt_idmap *idmap,
+static inline int security_inode_setxattr(const struct mnt_idmap *idmap,
struct dentry *dentry, const char *name, const void *value,
size_t size, int flags)
{
return cap_inode_setxattr(dentry, name, value, size, flags);
}
-static inline int security_inode_set_acl(struct mnt_idmap *idmap,
+static inline int security_inode_set_acl(const struct mnt_idmap *idmap,
struct dentry *dentry,
const char *acl_name,
struct posix_acl *kacl)
@@ -1016,21 +1031,21 @@ static inline void security_inode_post_set_acl(struct dentry *dentry,
struct posix_acl *kacl)
{ }
-static inline int security_inode_get_acl(struct mnt_idmap *idmap,
+static inline int security_inode_get_acl(const struct mnt_idmap *idmap,
struct dentry *dentry,
const char *acl_name)
{
return 0;
}
-static inline int security_inode_remove_acl(struct mnt_idmap *idmap,
+static inline int security_inode_remove_acl(const struct mnt_idmap *idmap,
struct dentry *dentry,
const char *acl_name)
{
return 0;
}
-static inline void security_inode_post_remove_acl(struct mnt_idmap *idmap,
+static inline void security_inode_post_remove_acl(const struct mnt_idmap *idmap,
struct dentry *dentry,
const char *acl_name)
{ }
@@ -1050,7 +1065,7 @@ static inline int security_inode_listxattr(struct dentry *dentry)
return 0;
}
-static inline int security_inode_removexattr(struct mnt_idmap *idmap,
+static inline int security_inode_removexattr(const struct mnt_idmap *idmap,
struct dentry *dentry,
const char *name)
{
@@ -1078,13 +1093,13 @@ static inline int security_inode_need_killpriv(struct dentry *dentry)
return cap_inode_need_killpriv(dentry);
}
-static inline int security_inode_killpriv(struct mnt_idmap *idmap,
+static inline int security_inode_killpriv(const struct mnt_idmap *idmap,
struct dentry *dentry)
{
return cap_inode_killpriv(idmap, dentry);
}
-static inline int security_inode_getsecurity(struct mnt_idmap *idmap,
+static inline int security_inode_getsecurity(const struct mnt_idmap *idmap,
struct inode *inode,
const char *name, void **buffer,
bool alloc)
@@ -1431,6 +1446,21 @@ static inline int security_create_user_ns(const struct cred *cred)
return 0;
}
+static inline int security_namespace_init(struct ns_common *ns)
+{
+ return 0;
+}
+
+static inline void security_namespace_free(struct ns_common *ns)
+{
+}
+
+static inline int security_namespace_install(const struct nsset *nsset,
+ struct ns_common *ns)
+{
+ return 0;
+}
+
static inline int security_ipc_permission(struct kern_ipc_perm *ipcp,
short flag)
{
@@ -2085,7 +2115,7 @@ int security_path_mkdir(const struct path *dir, struct dentry *dentry, umode_t m
int security_path_rmdir(const struct path *dir, struct dentry *dentry);
int security_path_mknod(const struct path *dir, struct dentry *dentry, umode_t mode,
unsigned int dev);
-void security_path_post_mknod(struct mnt_idmap *idmap, struct dentry *dentry);
+void security_path_post_mknod(const struct mnt_idmap *idmap, struct dentry *dentry);
int security_path_truncate(const struct path *path);
int security_path_symlink(const struct path *dir, struct dentry *dentry,
const char *old_name);
@@ -2120,7 +2150,7 @@ static inline int security_path_mknod(const struct path *dir, struct dentry *den
return 0;
}
-static inline void security_path_post_mknod(struct mnt_idmap *idmap,
+static inline void security_path_post_mknod(const struct mnt_idmap *idmap,
struct dentry *dentry)
{ }
diff --git a/include/linux/seq_buf.h b/include/linux/seq_buf.h
index 9f2839e73f8a..f006f2654e4c 100644
--- a/include/linux/seq_buf.h
+++ b/include/linux/seq_buf.h
@@ -5,6 +5,7 @@
#include <linux/bug.h>
#include <linux/minmax.h>
#include <linux/seq_file.h>
+#include <linux/string.h>
#include <linux/types.h>
/*
@@ -30,6 +31,10 @@ struct seq_buf {
.size = SIZE, \
}
+/**
+ * seq_buf_clear - reset the seq_buf to be read / appended from the beginning
+ * @s: the seq_buf handle
+ */
static inline void seq_buf_clear(struct seq_buf *s)
{
s->len = 0;
@@ -37,6 +42,14 @@ static inline void seq_buf_clear(struct seq_buf *s)
s->buffer[0] = '\0';
}
+/**
+ * seq_buf_init - initialize a seq_buf
+ * @s: the seq_buf handle
+ * @buf: pointer to the buffer
+ * @size: total size of @buf
+ *
+ * The contents of the buffer are ignored.
+ */
static inline void
seq_buf_init(struct seq_buf *s, char *buf, unsigned int size)
{
@@ -55,12 +68,46 @@ seq_buf_has_overflowed(struct seq_buf *s)
return s->len > s->size;
}
+/*
+ * Mark @s as overflowed, which discards the length of what it holds. The
+ * bytes up to its last one are the string from then on, as that is where
+ * seq_buf_str() terminates it, so clear whatever was not written: a writer
+ * sets len to how much it filled, and anything past that was never adopted.
+ */
static inline void
seq_buf_set_overflow(struct seq_buf *s)
{
+ if (s->len < s->size)
+ memset(s->buffer + s->len, 0, s->size - s->len);
+
s->len = s->size + 1;
}
+/**
+ * seq_buf_init_append - initialize a seq_buf over a buffer that may
+ * already hold NUL-terminated content
+ * @s: the seq_buf handle
+ * @buf: pointer to the (possibly non-empty) buffer
+ * @size: total size of @buf
+ *
+ * Unlike seq_buf_init(), which always starts @buf at len=0, this
+ * preserves whatever NUL-terminated content @buf already holds and
+ * positions @s to append after it. Useful for converting code that used
+ * to append to an existing buffer with strlcat()/scnprintf() and friends.
+ *
+ * If @buf holds no NUL within @size, @s starts out overflowed, as
+ * strlcat() treats such a buffer as already truncated.
+ */
+static inline void
+seq_buf_init_append(struct seq_buf *s, char *buf, unsigned int size)
+{
+ s->buffer = buf;
+ s->size = size;
+ s->len = strnlen(buf, size);
+ if (s->len == size)
+ seq_buf_set_overflow(s);
+}
+
/*
* How much buffer is left on the seq_buf?
*/
@@ -79,6 +126,27 @@ static inline unsigned int seq_buf_used(struct seq_buf *s)
return min(s->len, s->size);
}
+/*
+ * NUL-terminate the buffer in @s: directly after the data when there is
+ * room for it, otherwise in the last byte of the buffer. @s->size must not
+ * be zero.
+ *
+ * Returns: the offset of the NUL.
+ */
+static inline size_t __seq_buf_terminate(struct seq_buf *s)
+{
+ size_t end;
+
+ if (seq_buf_buffer_left(s))
+ end = s->len;
+ else
+ end = s->size - 1;
+
+ s->buffer[end] = 0;
+
+ return end;
+}
+
/**
* seq_buf_str - get NUL-terminated C string from seq_buf
* @s: the seq_buf handle
@@ -88,7 +156,14 @@ static inline unsigned int seq_buf_used(struct seq_buf *s)
*
* Note, if this is called when the buffer has overflowed, then
* the last byte of the buffer is zeroed, and the len will still
- * point passed it.
+ * point passed it. The same happens when the buffer is exactly
+ * full: the NUL takes the place of the last byte written, which is
+ * lost, though seq_buf_used() still counts it.
+ *
+ * A zero-sized seq_buf has nowhere to put a NUL, so the empty string
+ * is returned instead of writing to @s->buffer. Any other seq_buf
+ * returns @s->buffer, even when it holds an empty string, so callers
+ * always get their own buffer back.
*
* After this function is called, s->buffer is safe to use
* in string operations.
@@ -97,18 +172,68 @@ static inline unsigned int seq_buf_used(struct seq_buf *s)
*/
static inline const char *seq_buf_str(struct seq_buf *s)
{
- if (WARN_ON(s->size == 0))
+ if (s->size == 0)
return "";
- if (seq_buf_buffer_left(s))
- s->buffer[s->len] = 0;
- else
- s->buffer[s->size - 1] = 0;
+ __seq_buf_terminate(s);
return s->buffer;
}
/**
+ * seq_buf_strlen - get the length of the NUL-terminated C string in seq_buf
+ * @s: the seq_buf handle
+ *
+ * This makes sure that the buffer in @s is NUL-terminated, exactly as
+ * seq_buf_str() does, and returns the length of the resulting string
+ * without walking it. Unlike seq_buf_used(), this does not count the byte
+ * given up to the NUL when the buffer is full or has overflowed. When the
+ * buffer is exactly full, that byte is the last one written, and calling
+ * either function loses it.
+ *
+ * A zero-sized seq_buf holds no string, so 0 is returned without writing
+ * to @s->buffer, matching what seq_buf_str() returns for one.
+ *
+ * After this function is called, s->buffer is safe to use
+ * in string operations.
+ *
+ * Returns: the offset of the NUL that terminates @s->buffer. That is the
+ * length of the string unless an earlier NUL is in the way, either one the
+ * data written to @s carried itself, or one seq_buf_set_overflow() left
+ * behind when it cleared what no writer had claimed.
+ */
+static inline size_t seq_buf_strlen(struct seq_buf *s)
+{
+ if (s->size == 0)
+ return 0;
+
+ return __seq_buf_terminate(s);
+}
+
+/**
+ * seq_buf_terminate - NUL-terminate the string in a seq_buf
+ * @s: the seq_buf handle
+ *
+ * Terminate @s->buffer exactly as seq_buf_str() and seq_buf_strlen() do,
+ * for callers that want neither the pointer nor the length and only need
+ * the buffer to be safe to read as a C string. A zero-sized seq_buf has
+ * nowhere to put a NUL and is left untouched.
+ *
+ * Nothing is returned on purpose: a caller that wants the length should
+ * use seq_buf_strlen(), which says so.
+ *
+ * After this function is called, s->buffer is safe to use
+ * in string operations.
+ */
+static inline void seq_buf_terminate(struct seq_buf *s)
+{
+ if (s->size == 0)
+ return;
+
+ __seq_buf_terminate(s);
+}
+
+/**
* seq_buf_get_buf - get buffer to write arbitrary data to
* @s: the seq_buf handle
* @bufp: the beginning of the buffer is stored here
@@ -155,11 +280,11 @@ static inline void seq_buf_commit(struct seq_buf *s, int num)
*
* Removes the last written character to the seq_buf @s.
*
- * Returns the last character or -1 if it is empty.
+ * Returns the last character, or -1 if @s is empty or has overflowed.
*/
static inline int seq_buf_pop(struct seq_buf *s)
{
- if (!s->len)
+ if (!s->len || seq_buf_has_overflowed(s))
return -1;
s->len--;
diff --git a/include/linux/serial_8250.h b/include/linux/serial_8250.h
index eeb868e93e15..d91c0477be9d 100644
--- a/include/linux/serial_8250.h
+++ b/include/linux/serial_8250.h
@@ -186,10 +186,10 @@ static inline struct uart_8250_port *up_to_u8250p(struct uart_port *up)
return container_of(up, struct uart_8250_port, port);
}
-int serial8250_register_8250_port(const struct uart_8250_port *);
-void serial8250_unregister_port(int line);
-void serial8250_suspend_port(int line);
-void serial8250_resume_port(int line);
+struct uart_8250_port *serial8250_register_8250_port(const struct uart_8250_port *);
+void serial8250_unregister_port(struct uart_8250_port *);
+void serial8250_suspend_port(struct uart_8250_port *);
+void serial8250_resume_port(struct uart_8250_port *);
int early_serial_setup(struct uart_port *port);
int early_serial8250_setup(struct earlycon_device *device, const char *options);
diff --git a/include/linux/serial_core.h b/include/linux/serial_core.h
index 904760876ca8..4eeb8253752a 100644
--- a/include/linux/serial_core.h
+++ b/include/linux/serial_core.h
@@ -1140,8 +1140,6 @@ int uart_add_one_port(struct uart_driver *reg, struct uart_port *port);
void uart_remove_one_port(struct uart_driver *reg, struct uart_port *port);
int uart_read_port_properties(struct uart_port *port);
int uart_read_and_validate_port_properties(struct uart_port *port);
-bool uart_match_port(const struct uart_port *port1,
- const struct uart_port *port2);
/*
* Power Management
diff --git a/include/linux/set_memory.h b/include/linux/set_memory.h
index 3030d9245f5a..27c32fbabfec 100644
--- a/include/linux/set_memory.h
+++ b/include/linux/set_memory.h
@@ -5,16 +5,92 @@
#ifndef _LINUX_SET_MEMORY_H_
#define _LINUX_SET_MEMORY_H_
+/**
+ * DOC: Kernel page table permissions
+ *
+ * The set_memory() and set_direct_map() APIs update permissions of existing
+ * kernel mappings.
+ *
+ * The set_memory() functions operate on a range of kernel virtual addresses,
+ * the set_direct_map() functions operate on the direct map.
+ *
+ * The updates are not atomic: when a call fails, an arbitrary prefix of the
+ * range may have been updated already and there is no automatic rollback.
+ * A caller must restore the required permissions before reusing or freeing
+ * the memory.
+ *
+ * When an architecture does not implement these APIs they succeed without
+ * doing anything, so a return value of 0 does not mean that the permissions
+ * were actually changed.
+ *
+ * Callers that depend on the permissions being applied must ensure that the
+ * architecture supports the required operation for the target addresses. The
+ * Kconfig symbols alone do not guarantee this.
+ *
+ * See Documentation/mm/kernel-page-tables.rst for the details and for the
+ * differences between the architecture implementations.
+ */
+
#ifdef CONFIG_ARCH_HAS_SET_MEMORY
#include <asm/set_memory.h>
#else
+/**
+ * set_memory_ro - make a kernel mapping read-only
+ * @addr: page aligned start of the kernel virtual address range
+ * @numpages: number of pages in the range
+ *
+ * Flushes the TLB for the range.
+ *
+ * Return: 0 on success, negative error code on failure.
+ */
static inline int __must_check set_memory_ro(unsigned long addr, int numpages) { return 0; }
+
+/**
+ * set_memory_rw - make a kernel mapping writable
+ * @addr: page aligned start of the kernel virtual address range
+ * @numpages: number of pages in the range
+ *
+ * Flushes the TLB for the range.
+ *
+ * Return: 0 on success, negative error code on failure.
+ */
static inline int __must_check set_memory_rw(unsigned long addr, int numpages) { return 0; }
+
+/**
+ * set_memory_x - make a kernel mapping executable
+ * @addr: page aligned start of the kernel virtual address range
+ * @numpages: number of pages in the range
+ *
+ * Flushes the TLB for the range.
+ *
+ * Return: 0 on success, negative error code on failure.
+ */
static inline int __must_check set_memory_x(unsigned long addr, int numpages) { return 0; }
+
+/**
+ * set_memory_nx - make a kernel mapping non-executable
+ * @addr: page aligned start of the kernel virtual address range
+ * @numpages: number of pages in the range
+ *
+ * Flushes the TLB for the range.
+ *
+ * Return: 0 on success, negative error code on failure.
+ */
static inline int __must_check set_memory_nx(unsigned long addr, int numpages) { return 0; }
#endif
#ifndef set_memory_rox
+/**
+ * set_memory_rox - make a kernel mapping read-only and executable
+ * @addr: page aligned start of the kernel virtual address range
+ * @numpages: number of pages in the range
+ *
+ * A failure may leave the range read-only but not executable.
+ *
+ * Flushes the TLB for the range.
+ *
+ * Return: 0 on success, negative error code on failure.
+ */
static inline int set_memory_rox(unsigned long addr, int numpages)
{
int ret = set_memory_ro(addr, numpages);
@@ -25,17 +101,35 @@ static inline int set_memory_rox(unsigned long addr, int numpages)
#endif
#ifndef CONFIG_ARCH_HAS_SET_DIRECT_MAP
-static inline int set_direct_map_invalid_noflush(struct page *page)
-{
- return 0;
-}
-static inline int set_direct_map_default_noflush(struct page *page)
+/**
+ * set_direct_map_invalid_noflush - remove pages from the direct map
+ * @page: first page to update
+ * @nr: number of pages to update
+ *
+ * Makes the direct mapping of @nr pages starting at @page not present.
+ * The caller is responsible for any required TLB flushing.
+ *
+ * Return: 0 on success, negative error code on failure.
+ */
+static inline int set_direct_map_invalid_noflush(struct page *page,
+ unsigned int nr)
{
return 0;
}
-static inline int set_direct_map_valid_noflush(struct page *page,
- unsigned nr, bool valid)
+/**
+ * set_direct_map_default_noflush - restore the direct map of pages
+ * @page: first page to update
+ * @nr: number of pages to update
+ *
+ * Restores the default kernel permissions of the direct mapping of @nr
+ * pages starting at @page.
+ * The caller is responsible for any required TLB flushing.
+ *
+ * Return: 0 on success, negative error code on failure.
+ */
+static inline int set_direct_map_default_noflush(struct page *page,
+ unsigned int nr)
{
return 0;
}
@@ -50,6 +144,18 @@ static inline bool kernel_page_present(struct page *page)
* boot time. Let them overrive this query.
*/
#ifndef can_set_direct_map
+/**
+ * can_set_direct_map - check if the direct map can be modified
+ *
+ * Available with CONFIG_ARCH_HAS_SET_DIRECT_MAP. Architectures may override
+ * this to report whether direct map updates are enabled at runtime.
+ * Even though the generic implementation returns true this does not guarantee
+ * that every address can be updated.
+ *
+ * See Documentation/mm/kernel-page-tables.rst for the details
+ *
+ * Return: true unless the architecture reports direct map updates disabled.
+ */
static inline bool can_set_direct_map(void)
{
return true;
diff --git a/include/linux/shmem_fs.h b/include/linux/shmem_fs.h
index 5663dff53186..a7c7a96a7cbf 100644
--- a/include/linux/shmem_fs.h
+++ b/include/linux/shmem_fs.h
@@ -11,6 +11,7 @@
#include <linux/fs_parser.h>
#include <linux/userfaultfd_k.h>
#include <linux/bits.h>
+#include <linux/list_lru.h>
/* inode in-kernel data */
@@ -54,6 +55,11 @@ struct shmem_inode_info {
struct dquot __rcu *i_dquot[MAXQUOTAS];
#endif
struct inode vfs_inode;
+
+#ifdef CONFIG_TRANSPARENT_HUGEPAGE
+ struct obj_cgroup *shrinklist_objcg;
+ int shrinklist_nid;
+#endif
};
#define SHMEM_FL_USER_VISIBLE (FS_FL_USER_VISIBLE | FS_CASEFOLD_FL)
@@ -83,9 +89,9 @@ struct shmem_sb_info {
ino_t next_ino; /* The next per-sb inode number to use */
ino_t __percpu *ino_batch; /* The next per-cpu inode number to use */
struct mempolicy *mpol; /* default memory policy for mappings */
- spinlock_t shrinklist_lock; /* Protects shrinklist */
- struct list_head shrinklist; /* List of shinkable inodes */
- unsigned long shrinklist_len; /* Length of shrinklist */
+#ifdef CONFIG_TRANSPARENT_HUGEPAGE
+ struct list_lru shrinklist; /* List of shrinkable inodes */
+#endif
struct shmem_quota_limits qlimits; /* Default quota limits */
struct simple_xattr_cache xa_cache;
};
diff --git a/include/linux/siphash.h b/include/linux/siphash.h
index 9153e77382e1..00c58bbe549a 100644
--- a/include/linux/siphash.h
+++ b/include/linux/siphash.h
@@ -75,8 +75,10 @@ static inline u64 ___siphash_aligned(const __le64 *data, size_t len,
/**
* siphash - compute 64-bit siphash PRF value
* @data: buffer to hash
- * @size: size of @data
+ * @len: size of @data
* @key: the siphash key
+ *
+ * Returns: siphash PRF value
*/
static inline u64 siphash(const void *data, size_t len,
const siphash_key_t *key)
@@ -125,8 +127,10 @@ static inline u32 ___hsiphash_aligned(const __le32 *data, size_t len,
/**
* hsiphash - compute 32-bit hsiphash PRF value
* @data: buffer to hash
- * @size: size of @data
+ * @len: size of @data
* @key: the hsiphash key
+ *
+ * Returns: hsiphash PRF value
*/
static inline u32 hsiphash(const void *data, size_t len,
const hsiphash_key_t *key)
diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h
index 421f6fc45451..6787fcf6ac3e 100644
--- a/include/linux/skbuff.h
+++ b/include/linux/skbuff.h
@@ -358,6 +358,12 @@ struct sk_buff;
*/
#define GSO_BY_FRAGS 0xFFFF
+/* All frags in an skb must either all be struct page-backed or all belong to
+ * the same memory provider instance (e.g. the same devmem binding or io_uring
+ * area). Mixing page and memory-provider frags, or mixing frags from different
+ * memory providers within a single skb (including via coalescing), is not
+ * allowed.
+ */
typedef struct skb_frag {
netmem_ref netmem;
unsigned int len;
@@ -633,9 +639,9 @@ struct skb_shared_info {
*
* Transport layers send out clones of payload skbs they hold for
* retransmissions. To allow lower layers of the stack to prepend their headers
- * we split &skb_shared_info.dataref into two halves.
- * The lower 16 bits count the overall number of references.
- * The higher 16 bits indicate how many of the references are payload-only.
+ * we split &skb_shared_info.dataref into two parts.
+ * The lower 30 bits count the overall number of references.
+ * Bit 30 indicates whether one of the references is payload-only.
* skb_header_cloned() checks if skb is allowed to add / write the headers.
*
* The creator of the skb (e.g. TCP) marks its skb as &sk_buff.nohdr
@@ -655,7 +661,7 @@ struct skb_shared_info {
* Having multiple payload-only skbs with different lengths of hdr_len is not
* possible. The payload-only skbs should never leave their owner.
*/
-#define SKB_DATAREF_SHIFT 16
+#define SKB_DATAREF_SHIFT 30
#define SKB_DATAREF_MASK ((1 << SKB_DATAREF_SHIFT) - 1)
@@ -1020,7 +1026,7 @@ struct sk_buff {
#ifdef CONFIG_NET_REDIRECT
__u8 from_ingress:1;
#endif
-#ifdef CONFIG_NETFILTER_SKIP_EGRESS
+#ifdef CONFIG_NET_EGRESS
__u8 nf_skip_egress:1;
#endif
#ifdef CONFIG_SKB_DECRYPTED
@@ -1036,8 +1042,6 @@ struct sk_buff {
__u16 tc_index; /* traffic control index */
#endif
- u16 alloc_cpu;
-
union {
__wsum csum;
struct {
@@ -1088,6 +1092,8 @@ struct sk_buff {
); /* end headers group */
+ u16 alloc_cpu;
+
/* These elements must be at the end, see alloc_skb() for details. */
sk_buff_data_t tail;
sk_buff_data_t end;
@@ -1834,22 +1840,6 @@ static inline void skb_zcopy_set(struct sk_buff *skb, struct ubuf_info *uarg,
}
}
-static inline void skb_zcopy_set_nouarg(struct sk_buff *skb, void *val)
-{
- skb_shinfo(skb)->destructor_arg = (void *)((uintptr_t) val | 0x1UL);
- skb_shinfo(skb)->flags |= SKBFL_ZEROCOPY_FRAG;
-}
-
-static inline bool skb_zcopy_is_nouarg(struct sk_buff *skb)
-{
- return (uintptr_t) skb_shinfo(skb)->destructor_arg & 0x1UL;
-}
-
-static inline void *skb_zcopy_get_nouarg(struct sk_buff *skb)
-{
- return (void *)((uintptr_t) skb_shinfo(skb)->destructor_arg & ~0x1UL);
-}
-
static inline void net_zcopy_put(struct ubuf_info *uarg)
{
if (uarg)
@@ -1872,8 +1862,7 @@ static inline void skb_zcopy_clear(struct sk_buff *skb, bool zerocopy_success)
struct ubuf_info *uarg = skb_zcopy(skb);
if (uarg) {
- if (!skb_zcopy_is_nouarg(skb))
- uarg->ops->complete(skb, uarg, zerocopy_success);
+ uarg->ops->complete(skb, uarg, zerocopy_success);
skb_shinfo(skb)->flags &= ~SKBFL_ALL_ZEROCOPY;
}
@@ -2142,14 +2131,14 @@ static inline struct sk_buff *skb_share_check(struct sk_buff *skb, gfp_t pri)
}
/*
- * Copy shared buffers into a new sk_buff. We effectively do COW on
+ * Copy cloned buffers into a new sk_buff. We effectively do COW on
* packets to handle cases where we have a local reader and forward
* and a couple of other messy ones. The normal one is tcpdumping
* a packet that's being forwarded.
*/
/**
- * skb_unshare - make a copy of a shared buffer
+ * skb_unclone_full - make a private copy of a cloned buffer
* @skb: buffer to check
* @pri: priority for memory allocation
*
@@ -2159,10 +2148,13 @@ static inline struct sk_buff *skb_share_check(struct sk_buff *skb, gfp_t pri)
* the original buffer is returned. When called with a spinlock held or
* from interrupt state @pri must be %GFP_ATOMIC
*
+ * Unlike skb_unclone(), the paged data is copied as well. A buffer with
+ * skb->users > 1 that is not a clone is returned as is, use
+ * skb_share_check() for that case.
+ *
* %NULL is returned on a memory allocation failure.
*/
-static inline struct sk_buff *skb_unshare(struct sk_buff *skb,
- gfp_t pri)
+static inline struct sk_buff *skb_unclone_full(struct sk_buff *skb, gfp_t pri)
{
might_sleep_if(gfpflags_allow_blocking(pri));
if (skb_cloned(skb)) {
@@ -3833,9 +3825,12 @@ static inline dma_addr_t __skb_frag_dma_map(struct device *dev,
size_t offset, size_t size,
enum dma_data_direction dir)
{
+ dma_addr_t addr;
+
if (skb_frag_is_net_iov(frag)) {
- return netmem_to_net_iov(frag->netmem)->desc.dma_addr +
- offset + frag->offset;
+ addr = netmem_dma_addr_decode(
+ netmem_get_dma_addr(frag->netmem));
+ return addr + offset + frag->offset;
}
return dma_map_page(dev, skb_frag_page(frag),
skb_frag_off(frag) + offset, size, dir);
@@ -4372,7 +4367,10 @@ skb_header_pointer_careful(const struct sk_buff *skb, int offset,
static inline void * __must_check
skb_pointer_if_linear(const struct sk_buff *skb, int offset, int len)
{
- if (likely(skb_headlen(skb) - offset >= len))
+ unsigned int uoffset = (unsigned int)offset;
+
+ if (likely(uoffset <= skb_headlen(skb) &&
+ (unsigned int)len <= skb_headlen(skb) - uoffset))
return skb->data + offset;
return NULL;
}
diff --git a/include/linux/skbuff_ref.h b/include/linux/skbuff_ref.h
index 05c8486bafac..b6f6da556ee9 100644
--- a/include/linux/skbuff_ref.h
+++ b/include/linux/skbuff_ref.h
@@ -9,66 +9,78 @@
#include <linux/skbuff.h>
+bool napi_pp_get_page(netmem_ref netmem);
+
/**
- * __skb_frag_ref - take an addition reference on a paged fragment.
- * @frag: the paged fragment
+ * skb_netmem_ref - acquire a fragment reference on a netmem
+ * @netmem: netmem to reference
+ * @recycle: whether page_pool recycling is enabled (e.g. skb->pp_recycle)
*
- * Takes an additional reference on the paged fragment @frag.
+ * Acquires pp_ref_count via napi_pp_get_page() if @recycle is true and
+ * @netmem belongs to a page_pool; otherwise acquires a non-pp backing
+ * reference via netmem_inc_ref(). Counterpart to skb_netmem_unref().
*/
-static __always_inline void __skb_frag_ref(skb_frag_t *frag)
+static __always_inline void skb_netmem_ref(netmem_ref netmem, bool recycle)
{
- get_netmem(skb_frag_netmem(frag));
+#ifdef CONFIG_PAGE_POOL
+ if (recycle && napi_pp_get_page(netmem))
+ return;
+#endif
+ netmem_inc_ref(netmem);
}
/**
- * skb_frag_ref - take an addition reference on a paged fragment of an skb.
+ * skb_frag_ref - acquire a reference on a paged fragment of an skb
* @skb: the buffer
- * @f: the fragment offset.
+ * @f: the fragment offset
*
- * Takes an additional reference on the @f'th paged fragment of @skb.
+ * Acquires a reference on the @f'th fragment of @skb via skb_netmem_ref()
+ * (pp_ref_count if skb->pp_recycle and page_pool-backed, else non-pp
+ * backing refcount). Counterpart to skb_frag_unref().
*/
static __always_inline void skb_frag_ref(struct sk_buff *skb, int f)
{
- __skb_frag_ref(&skb_shinfo(skb)->frags[f]);
+ skb_netmem_ref(skb_frag_netmem(&skb_shinfo(skb)->frags[f]),
+ skb->pp_recycle);
}
bool napi_pp_put_page(netmem_ref netmem);
-static __always_inline void skb_page_unref(netmem_ref netmem, bool recycle)
+/**
+ * skb_netmem_unref - release a fragment reference on a netmem
+ * @netmem: netmem to unreference
+ * @recycle: whether page_pool recycling is enabled (e.g. skb->pp_recycle)
+ *
+ * Drops pp_ref_count via napi_pp_put_page() if @recycle is true and @netmem
+ * belongs to a page_pool; otherwise drops a non-pp backing reference via
+ * netmem_dec_ref(). Counterpart to skb_netmem_ref().
+ */
+static __always_inline void skb_netmem_unref(netmem_ref netmem, bool recycle)
{
#ifdef CONFIG_PAGE_POOL
if (recycle && napi_pp_put_page(netmem))
return;
#endif
- put_netmem(netmem);
-}
-
-/**
- * __skb_frag_unref - release a reference on a paged fragment.
- * @frag: the paged fragment
- * @recycle: recycle the page if allocated via page_pool
- *
- * Releases a reference on the paged fragment @frag
- * or recycles the page via the page_pool API.
- */
-static __always_inline void __skb_frag_unref(skb_frag_t *frag, bool recycle)
-{
- skb_page_unref(skb_frag_netmem(frag), recycle);
+ netmem_dec_ref(netmem);
}
/**
- * skb_frag_unref - release a reference on a paged fragment of an skb.
+ * skb_frag_unref - release a reference on a paged fragment of an skb
* @skb: the buffer
* @f: the fragment offset
*
- * Releases a reference on the @f'th paged fragment of @skb.
+ * Drops a reference on the @f'th fragment of @skb via skb_netmem_unref()
+ * (pp_ref_count if skb->pp_recycle and page_pool-backed, else non-pp
+ * backing refcount), skipping managed zerocopy fragments. Counterpart to
+ * skb_frag_ref().
*/
static __always_inline void skb_frag_unref(struct sk_buff *skb, int f)
{
struct skb_shared_info *shinfo = skb_shinfo(skb);
if (!skb_zcopy_managed(skb))
- __skb_frag_unref(&shinfo->frags[f], skb->pp_recycle);
+ skb_netmem_unref(skb_frag_netmem(&shinfo->frags[f]),
+ skb->pp_recycle);
}
#endif /* _LINUX_SKBUFF_REF_H */
diff --git a/include/linux/slimbus.h b/include/linux/slimbus.h
index ca6f1da4bdf3..1a2d3aa0e033 100644
--- a/include/linux/slimbus.h
+++ b/include/linux/slimbus.h
@@ -98,7 +98,7 @@ struct slim_driver {
* @start_offset: Specifies starting offset in information/value element map
* @rbuf: buffer to read the values
* @wbuf: buffer to write
- * @num_bytes: upto 16. This ensures that the message will fit the slicesize
+ * @num_bytes: up to 16. This ensures that the message will fit the slicesize
* per SLIMbus spec
* @comp: completion for asynchronous operations, valid only if TID is
* required for transaction, like REQUEST operations.
diff --git a/include/linux/soc/marvell/octeontx2/asm.h b/include/linux/soc/marvell/octeontx2/asm.h
index d683251a0b40..8b572d3d741c 100644
--- a/include/linux/soc/marvell/octeontx2/asm.h
+++ b/include/linux/soc/marvell/octeontx2/asm.h
@@ -17,7 +17,7 @@
#define otx2_lmt_flush(ioaddr) \
({ \
u64 result = 0; \
- __asm__ volatile(".cpu generic+lse\n" \
+ __asm__ volatile(".arch_extension lse\n" \
"ldeor xzr, %x[rf], [%[rs]]" \
: [rf]"=r" (result) \
: [rs]"r" (ioaddr)); \
@@ -30,7 +30,7 @@
*/
#define cn10k_lmt_flush(val, addr) \
({ \
- __asm__ volatile(".cpu generic+lse\n" \
+ __asm__ volatile(".arch_extension lse\n" \
"steorl %x[rf],[%[rs]]" \
: [rf] "+r"(val) \
: [rs] "r"(addr)); \
@@ -40,7 +40,7 @@ static inline u64 otx2_atomic64_fetch_add(u64 incr, u64 *ptr)
{
u64 result;
- asm volatile (".cpu generic+lse\n"
+ asm volatile (".arch_extension lse\n"
"ldadda %x[i], %x[r], [%[b]]"
: [r] "=r" (result), "+m" (*ptr)
: [i] "r" (incr), [b] "r" (ptr)
diff --git a/include/linux/soc/qcom/apr.h b/include/linux/soc/qcom/apr.h
index 909e84f84e0c..2e4231092088 100644
--- a/include/linux/soc/qcom/apr.h
+++ b/include/linux/soc/qcom/apr.h
@@ -5,7 +5,6 @@
#include <linux/spinlock.h>
#include <linux/device.h>
-#include <linux/device-id/apr.h>
#include <dt-bindings/soc/qcom,apr.h>
#include <dt-bindings/soc/qcom,gpr.h>
@@ -135,6 +134,8 @@ struct pkt_router_svc {
typedef struct pkt_router_svc gpr_port_t;
+#define APR_NAME_SIZE 32
+
struct apr_device {
struct device dev;
uint16_t svc_id;
@@ -158,7 +159,6 @@ struct apr_driver {
const struct apr_resp_pkt *d);
gpr_port_cb gpr_callback;
struct device_driver driver;
- const struct apr_device_id *id_table;
};
typedef struct apr_driver gpr_driver_t;
diff --git a/include/linux/soc/qcom/geni-se.h b/include/linux/soc/qcom/geni-se.h
index 29a53bbc0dd4..b3372a3147a0 100644
--- a/include/linux/soc/qcom/geni-se.h
+++ b/include/linux/soc/qcom/geni-se.h
@@ -347,17 +347,18 @@ struct geni_se {
#define QUP_SE_VERSION_2_5 0x20050000
/*
- * Define bandwidth thresholds that cause the underlying Core 2X interconnect
- * clock to run at the named frequency. These baseline values are recommended
- * by the hardware team, and are not dynamically scaled with GENI bandwidth
- * beyond basic on/off.
+ * ICC bandwidth values in Bps for the GENI_TO_CORE ("qup-core") path.
+ * Convert them with Bps_to_icc() before setting avg_bw. The QUP ICC provider
+ * maps each threshold to the Core 2X rate named by the macro suffix.
+ *
+ * These values are core clock votes, not GENI transfer bandwidths.
*/
-#define CORE_2X_19_2_MHZ 960
-#define CORE_2X_50_MHZ 2500
-#define CORE_2X_100_MHZ 5000
-#define CORE_2X_150_MHZ 7500
-#define CORE_2X_200_MHZ 10000
-#define CORE_2X_236_MHZ 16383
+#define CORE_2X_19_2_MHZ 9600000
+#define CORE_2X_50_MHZ 25000000
+#define CORE_2X_100_MHZ 50000000
+#define CORE_2X_150_MHZ 75000000
+#define CORE_2X_200_MHZ 100000000
+#define CORE_2X_236_MHZ 118000000
#define GENI_DEFAULT_BW Bps_to_icc(1000)
@@ -573,7 +574,7 @@ void geni_se_tx_dma_unprep(struct geni_se *se, dma_addr_t iova, size_t len);
void geni_se_rx_dma_unprep(struct geni_se *se, dma_addr_t iova, size_t len);
-int geni_icc_get(struct geni_se *se, const char *icc_ddr);
+int geni_icc_get(struct geni_se *se);
int geni_icc_set_bw(struct geni_se *se);
int geni_icc_set_bw_ab(struct geni_se *se, u32 core_ab, u32 cfg_ab, u32 ddr_ab);
diff --git a/include/linux/soc/qcom/llcc-qcom.h b/include/linux/soc/qcom/llcc-qcom.h
index f3ed63e475ab..713cb0221b14 100644
--- a/include/linux/soc/qcom/llcc-qcom.h
+++ b/include/linux/soc/qcom/llcc-qcom.h
@@ -74,6 +74,7 @@
#define LLCC_CAMSRTIP 73
#define LLCC_CAMRTRF 74
#define LLCC_CAMSRTRF 75
+#define LLCC_GPU_LITTLE 80
#define LLCC_OOBM_NS 81
#define LLCC_OOBM_S 82
#define LLCC_VIDEO_APV 83
@@ -85,7 +86,12 @@
#define LLCC_CAM_OFE_STROV 93
#define LLCC_CPUSS_HEU 94
#define LLCC_PCIE_TCU 97
+#define LLCC_GPUHTW_LITTLE 98
#define LLCC_MDM_PNG_FIXED 100
+#define LLCC_PPE_RXDESC 101
+#define LLCC_PPE_RXFILL 102
+#define LLCC_WLAN_5G 103
+#define LLCC_WLAN_6G 104
/**
* struct llcc_slice_desc - Cache slice descriptor
diff --git a/include/linux/soc/qcom/tc9563.h b/include/linux/soc/qcom/tc9563.h
new file mode 100644
index 000000000000..086f37a40d80
--- /dev/null
+++ b/include/linux/soc/qcom/tc9563.h
@@ -0,0 +1,19 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2026 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Author: Lorenzo Bianconi <lorenzo.bianconi@oss.qualcomm.com>
+ */
+
+#ifndef __QCOM_TC9563_H
+#define __QCOM_TC9563_H
+
+#define TC9563_GPIO_DEV_NAME "tc9563-gpio"
+
+#define TC9563_GPIO_IN0_OFFSET 0x801200
+#define TC9563_GPIO_EN0_OFFSET 0x801208
+#define TC9563_GPIO_OUT0_OFFSET 0x801210
+
+#define TC9563_GPIO_CONFIG TC9563_GPIO_EN0_OFFSET
+#define TC9563_RESET_GPIO TC9563_GPIO_OUT0_OFFSET
+
+#endif /* __QCOM_TC9563_H */
diff --git a/include/linux/soc/qcom/ubwc.h b/include/linux/soc/qcom/ubwc.h
index f3a70360b177..b09ae05cbeae 100644
--- a/include/linux/soc/qcom/ubwc.h
+++ b/include/linux/soc/qcom/ubwc.h
@@ -36,6 +36,7 @@ struct qcom_ubwc_cfg_data {
#define UBWC_4_3 0x40030000
#define UBWC_5_0 0x50000000
#define UBWC_6_0 0x60000000
+#define UBWC_7_0 0x70000000
#if IS_ENABLED(CONFIG_QCOM_UBWC_CONFIG)
const struct qcom_ubwc_cfg_data *qcom_ubwc_config_get_data(void);
@@ -108,6 +109,8 @@ static inline u32 qcom_ubwc_swizzle(const struct qcom_ubwc_cfg_data *cfg)
static inline u32 qcom_ubwc_version_tag(const struct qcom_ubwc_cfg_data *cfg)
{
+ if (cfg->ubwc_enc_version >= UBWC_7_0)
+ return 6;
if (cfg->ubwc_enc_version >= UBWC_6_0)
return 5;
if (cfg->ubwc_enc_version >= UBWC_5_0)
diff --git a/include/linux/soc/ti/k3-ringacc.h b/include/linux/soc/ti/k3-ringacc.h
index 39b022b92598..7b7fc237c08f 100644
--- a/include/linux/soc/ti/k3-ringacc.h
+++ b/include/linux/soc/ti/k3-ringacc.h
@@ -57,13 +57,13 @@ struct k3_ringacc;
struct k3_ring;
/**
- * enum k3_ring_cfg - RA ring configuration structure
+ * struct k3_ring_cfg - RA ring configuration structure
*
* @size: Ring size, number of elements
* @elm_size: Ring element size
* @mode: Ring operational mode
* @flags: Ring configuration flags. Possible values:
- * @K3_RINGACC_RING_SHARED: when set allows to request the same ring
+ * %K3_RINGACC_RING_SHARED: when set allows to request the same ring
* few times. It's usable when the same ring is used as Free Host PD ring
* for different flows, for example.
* Note: Locking should be done by consumer if required
@@ -88,11 +88,10 @@ struct k3_ring_cfg {
/**
* of_k3_ringacc_get_by_phandle - find a RA by phandle property
* @np: device node
- * @propname: property name containing phandle on RA node
+ * @property: property name containing phandle on RA node
*
- * Returns pointer on the RA - struct k3_ringacc
- * or -ENODEV if not found,
- * or -EPROBE_DEFER if not yet registered
+ * Return: Pointer to the RA, or ERR_PTR(-ENODEV) if the phandle cannot
+ * be resolved, or ERR_PTR(-EPROBE_DEFER) if the RA is not yet registered.
*/
struct k3_ringacc *of_k3_ringacc_get_by_phandle(struct device_node *np,
const char *property);
@@ -103,10 +102,8 @@ struct k3_ringacc *of_k3_ringacc_get_by_phandle(struct device_node *np,
* k3_ringacc_request_ring - request ring from ringacc
* @ringacc: pointer on ringacc
* @id: ring id or K3_RINGACC_RING_ID_ANY for any general purpose ring
- * @flags:
- * @K3_RINGACC_RING_USE_PROXY: if set - proxy will be allocated and
- * used to access ring memory. Sopported only for rings in
- * Message/Credentials/Queue mode.
+ * @flags: Set %K3_RINGACC_RING_USE_PROXY to allocate a proxy for
+ * accessing ring memory in Message mode.
*
* Returns pointer on the Ring - struct k3_ring
* or NULL in case of failure.
@@ -126,8 +123,9 @@ int k3_ringacc_request_rings_pair(struct k3_ringacc *ringacc,
*/
void k3_ringacc_ring_reset(struct k3_ring *ring);
/**
- * k3_ringacc_ring_reset - ring reset for DMA rings
+ * k3_ringacc_ring_reset_dma - ring reset for DMA rings
* @ring: pointer on Ring
+ * @occ: occupancy used by the DMA reset quirk, or zero to read it from hardware
*
* Resets ring internal state ((hw)occ, (hw)idx). Should be used for rings
* which are read by K3 UDMA, like TX or Free Host PD rings.
@@ -217,8 +215,8 @@ int k3_ringacc_ring_push(struct k3_ring *ring, void *elem);
* @ring: pointer on ring
* @elem: pointer on ring element buffer
*
- * Push one ring element from the ring head. Size of the ring element is
- * determined by ring configuration &struct k3_ring_cfg elm_size..
+ * Pop one ring element from the ring head. Size of the ring element is
+ * determined by ring configuration &struct k3_ring_cfg elm_size.
*
* Returns 0 on success, errno otherwise.
*/
@@ -242,7 +240,7 @@ int k3_ringacc_ring_push_head(struct k3_ring *ring, void *elem);
* @ring: pointer on ring
* @elem: pointer on ring element buffer
*
- * Push one ring element from the ring tail. Size of the ring element is
+ * Pop one ring element from the ring tail. Size of the ring element is
* determined by ring configuration &struct k3_ring_cfg elm_size.
*
* Returns 0 on success, errno otherwise.
@@ -256,7 +254,10 @@ u32 k3_ringacc_get_tisci_dev_id(struct k3_ring *ring);
struct ti_sci_handle;
/**
- * struct struct k3_ringacc_init_data - Initialization data for DMA rings
+ * struct k3_ringacc_init_data - Initialization data for DMA rings
+ * @tisci: TI SCI firmware handle
+ * @tisci_dev_id: TI SCI device ID of the DMA controller
+ * @num_rings: Total number of available rings
*/
struct k3_ringacc_init_data {
const struct ti_sci_handle *tisci;
diff --git a/include/linux/socket.h b/include/linux/socket.h
index 5a5eb1250103..b17fdb7d38a7 100644
--- a/include/linux/socket.h
+++ b/include/linux/socket.h
@@ -189,10 +189,11 @@ static inline size_t msg_data_left(const struct msghdr *msg)
/* "Socket"-level control message types: */
-#define SCM_RIGHTS 0x01 /* rw: access rights (array of int) */
-#define SCM_CREDENTIALS 0x02 /* rw: struct ucred */
-#define SCM_SECURITY 0x03 /* rw: security label */
-#define SCM_PIDFD 0x04 /* ro: pidfd (int) */
+#define SCM_RIGHTS 0x01 /* rw: access rights (array of int) */
+#define SCM_CREDENTIALS 0x02 /* rw: struct ucred */
+#define SCM_SECURITY 0x03 /* rw: security label */
+#define SCM_PIDFD 0x04 /* ro: pidfd (int) */
+#define SCM_PIDFD_THREAD 0x05 /* ro: thread pidfd (int) */
struct ucred {
__u32 pid;
diff --git a/include/linux/spi/spi.h b/include/linux/spi/spi.h
index 88d17fce02dc..fb4baa0d3398 100644
--- a/include/linux/spi/spi.h
+++ b/include/linux/spi/spi.h
@@ -169,6 +169,12 @@ extern void spi_transfer_cs_change_delay_exec(struct spi_message *msg,
* @cs_inactive: delay to be introduced by the controller after CS is
* deasserted. If @cs_change_delay is used from @spi_transfer, then the
* two delays will be added up.
+ * @rx_sample_delay_ns: Delay in nanoseconds by which the controller should
+ * postpone sampling the incoming data, relative to the sampling point it
+ * uses by default. Describes the board rather than the device, namely the
+ * flight time of the clock and data signals between controller and
+ * device, and comes from the "rx-sample-delay-ns" property. Zero when the
+ * property is absent.
* @chip_select: Array of physical chipselect, spi->chipselect[i] gives
* the corresponding physical CS for logical CS i.
* @num_chipselect: Number of physical chipselects used.
@@ -235,6 +241,9 @@ struct spi_device {
struct spi_delay cs_hold;
struct spi_delay cs_inactive;
+ /* Additional delay before the incoming data is sampled, in ns */
+ u32 rx_sample_delay_ns;
+
u8 chip_select[SPI_DEVICE_CS_CNT_MAX];
u8 num_chipselect;
diff --git a/include/linux/spinlock_types_raw.h b/include/linux/spinlock_types_raw.h
index e5644ab2161f..942c229c90bb 100644
--- a/include/linux/spinlock_types_raw.h
+++ b/include/linux/spinlock_types_raw.h
@@ -11,6 +11,10 @@
#include <linux/lockdep_types.h>
+/*
+ * Keep in sync with rust/kernel/sync/lock/spinlock.rs
+ */
+
context_lock_struct(raw_spinlock) {
arch_spinlock_t raw_lock;
#ifdef CONFIG_DEBUG_SPINLOCK
diff --git a/include/linux/splice.h b/include/linux/splice.h
index 9dec4861d09f..0e6c955dc6ff 100644
--- a/include/linux/splice.h
+++ b/include/linux/splice.h
@@ -79,8 +79,8 @@ ssize_t add_to_pipe(struct pipe_inode_info *pipe, struct pipe_buffer *buf);
ssize_t vfs_splice_read(struct file *in, loff_t *ppos,
struct pipe_inode_info *pipe, size_t len,
unsigned int flags);
-ssize_t splice_direct_to_actor(struct file *file, struct splice_desc *sd,
- splice_direct_actor *actor);
+ssize_t vfs_splice_to_actor(struct file *file, loff_t pos, size_t count,
+ splice_direct_actor *actor, void *private);
ssize_t do_splice(struct file *in, loff_t *off_in, struct file *out,
loff_t *off_out, size_t len, unsigned int flags);
ssize_t do_splice_direct(struct file *in, loff_t *ppos, struct file *out,
diff --git a/include/linux/spmi.h b/include/linux/spmi.h
index 4eb9564a7fb3..4daebc980501 100644
--- a/include/linux/spmi.h
+++ b/include/linux/spmi.h
@@ -70,6 +70,22 @@ int spmi_device_add(struct spmi_device *sdev);
void spmi_device_remove(struct spmi_device *sdev);
/**
+ * struct spmi_subdevice - Basic representation of an SPMI sub-device
+ * @sdev: Sub-device representation of an SPMI device
+ * @devid: Platform Device ID of an SPMI sub-device
+ */
+struct spmi_subdevice {
+ struct spmi_device sdev;
+ unsigned int devid;
+};
+
+struct spmi_subdevice *spmi_subdevice_alloc_and_add(struct spmi_device *sparent);
+void spmi_subdevice_remove(struct spmi_subdevice *sdev);
+
+struct spmi_subdevice *devm_spmi_subdevice_alloc_and_add(struct device *dev,
+ struct spmi_device *sparent);
+
+/**
* struct spmi_controller - interface to the SPMI master controller
* @dev: Driver model representation of the device.
* @nr: board-specific number identifier for this controller/bus
@@ -173,6 +189,7 @@ static inline void spmi_driver_unregister(struct spmi_driver *sdrv)
struct device_node;
struct spmi_device *spmi_find_device_by_of_node(struct device_node *np);
+struct spmi_device *spmi_get_parent_spmi_device(struct device *dev);
int spmi_register_read(struct spmi_device *sdev, u8 addr, u8 *buf);
int spmi_ext_register_read(struct spmi_device *sdev, u8 addr, u8 *buf,
size_t len);
diff --git a/include/linux/srcu.h b/include/linux/srcu.h
index 7d9bc06df98d..1a8a465a5650 100644
--- a/include/linux/srcu.h
+++ b/include/linux/srcu.h
@@ -36,6 +36,8 @@ static inline int __init_srcu_struct(struct srcu_struct *ssp, const char *name,
int __init_srcu_struct_fast(struct srcu_struct *ssp, const char *name, struct lock_class_key *key);
int __init_srcu_struct_fast_updown(struct srcu_struct *ssp, const char *name,
struct lock_class_key *key);
+int __init_srcu_struct_atomic(struct srcu_struct *ssp, const char *name,
+ struct lock_class_key *key);
#endif // #ifndef CONFIG_TINY_SRCU
#define init_srcu_struct_fast(ssp) \
@@ -52,6 +54,13 @@ int __init_srcu_struct_fast_updown(struct srcu_struct *ssp, const char *name,
__init_srcu_struct_fast_updown((ssp), #ssp, &__srcu_key); \
})
+#define init_srcu_struct_atomic(ssp) \
+({ \
+ static struct lock_class_key __srcu_key; \
+ \
+ __init_srcu_struct_atomic((ssp), #ssp, &__srcu_key); \
+})
+
#define __SRCU_DEP_MAP_INIT(srcu_name) .dep_map = { .name = #srcu_name },
#else /* #ifdef CONFIG_DEBUG_LOCK_ALLOC */
@@ -64,6 +73,7 @@ static inline int __init_srcu_struct(struct srcu_struct *ssp, const char *name,
#ifndef CONFIG_TINY_SRCU
int init_srcu_struct_fast(struct srcu_struct *ssp);
int init_srcu_struct_fast_updown(struct srcu_struct *ssp);
+int init_srcu_struct_atomic(struct srcu_struct *ssp);
#endif // #ifndef CONFIG_TINY_SRCU
#define __SRCU_DEP_MAP_INIT(srcu_name)
@@ -77,14 +87,18 @@ int init_srcu_struct_fast_updown(struct srcu_struct *ssp);
})
/* Values for SRCU Tree srcu_data ->srcu_reader_flavor, but also used by rcutorture. */
-#define SRCU_READ_FLAVOR_NORMAL 0x1 // srcu_read_lock().
-#define SRCU_READ_FLAVOR_NMI 0x2 // srcu_read_lock_nmisafe().
-// 0x4 // SRCU-lite is no longer with us.
-#define SRCU_READ_FLAVOR_FAST 0x4 // srcu_read_lock_fast(), also NMI-safe.
-#define SRCU_READ_FLAVOR_FAST_UPDOWN 0x8 // srcu_read_lock_fast_updown().
+#define SRCU_READ_FLAVOR_NORMAL 0x01 // srcu_read_lock().
+#define SRCU_READ_FLAVOR_NMI 0x02 // srcu_read_lock_nmisafe().
+// 0x04 // SRCU-lite is no longer with us.
+#define SRCU_READ_FLAVOR_FAST 0x04 // srcu_read_lock_fast(), also NMI-safe.
+#define SRCU_READ_FLAVOR_FAST_UPDOWN 0x08 // srcu_read_lock_fast_updown().
+#define SRCU_READ_FLAVOR_ATOMIC 0x10 // srcu_read_lock_atomic().
#define SRCU_READ_FLAVOR_ALL (SRCU_READ_FLAVOR_NORMAL | SRCU_READ_FLAVOR_NMI | \
- SRCU_READ_FLAVOR_FAST | SRCU_READ_FLAVOR_FAST_UPDOWN)
+ SRCU_READ_FLAVOR_FAST | SRCU_READ_FLAVOR_FAST_UPDOWN | \
+ SRCU_READ_FLAVOR_ATOMIC)
// All of the above.
+#define SRCU_READ_FLAVOR_PREDEF (SRCU_READ_FLAVOR_FAST | SRCU_READ_FLAVOR_ATOMIC)
+ // Flavors special DEFINE_SRCU() flavors.
#define SRCU_READ_FLAVOR_SLOWGP (SRCU_READ_FLAVOR_FAST | SRCU_READ_FLAVOR_FAST_UPDOWN)
// Flavors requiring synchronize_rcu()
// instead of smp_mb().
@@ -102,6 +116,7 @@ void call_srcu(struct srcu_struct *ssp, struct rcu_head *head,
void (*func)(struct rcu_head *head));
void cleanup_srcu_struct(struct srcu_struct *ssp);
void synchronize_srcu(struct srcu_struct *ssp);
+void synchronize_srcu_atomic(struct srcu_struct *ssp);
#define SRCU_GET_STATE_COMPLETED 0x1
@@ -307,6 +322,45 @@ static inline int srcu_read_lock(struct srcu_struct *ssp)
}
/**
+ * srcu_read_lock_atomic - register a new reader promising an atomic section
+ * @ssp: srcu_struct in which to register the new reader.
+ *
+ * As srcu_read_lock(), but the caller promises that the read-side
+ * critical section never sleeps and never blocks on anything which
+ * may itself depend on memory allocation to make progress. Preemption
+ * is disabled for the duration, which both enforces that promise (any
+ * sleepable call in the section will splat on every configuration)
+ * and bounds the section so that the update side may spin rather
+ * than sleep when waiting for readers: see synchronize_srcu_atomic().
+ *
+ * The lock and matching srcu_read_unlock_atomic() must be invoked on
+ * the same CPU, from the same context; passing the return value to
+ * another task is not permitted for this flavor.
+ */
+static inline int srcu_read_lock_atomic(struct srcu_struct *ssp)
+ __acquires_shared(ssp)
+{
+ int retval;
+
+ preempt_disable();
+ /*
+ * Arm might_sleep() to catch even a *potentially* sleeping call
+ * in the section, not just an actual schedule: the atomic-domain
+ * promise must hold on every path, contended or not. In hardirq,
+ * softirq, or NMI the annotation would land on the interrupted
+ * task, and can also result in data races against that task's
+ * own non_block_start()/non_block_end() invocations; it is also
+ * redundant there, so skip it.
+ */
+ if (in_task())
+ non_block_start();
+ srcu_check_read_flavor(ssp, SRCU_READ_FLAVOR_ATOMIC);
+ retval = __srcu_read_lock(ssp);
+ srcu_lock_acquire(&ssp->dep_map);
+ return retval;
+}
+
+/**
* srcu_read_lock_fast - register a new reader for an SRCU-protected structure.
* @ssp: srcu_struct in which to register the new reader.
*
@@ -499,6 +553,23 @@ static inline void srcu_read_unlock(struct srcu_struct *ssp, int idx)
}
/**
+ * srcu_read_unlock_atomic - unregister an atomic-section reader
+ * @ssp: srcu_struct from which to unregister the old reader.
+ * @idx: return value from corresponding srcu_read_lock_atomic().
+ */
+static inline void srcu_read_unlock_atomic(struct srcu_struct *ssp, int idx)
+ __releases_shared(ssp)
+{
+ WARN_ON_ONCE(idx & ~0x1);
+ srcu_check_read_flavor(ssp, SRCU_READ_FLAVOR_ATOMIC);
+ srcu_lock_release(&ssp->dep_map);
+ __srcu_read_unlock(ssp, idx);
+ if (in_task())
+ non_block_end();
+ preempt_enable();
+}
+
+/**
* srcu_read_unlock_fast - unregister a old reader from an SRCU-protected structure.
* @ssp: srcu_struct in which to unregister the old reader.
* @scp: return value from corresponding srcu_read_lock_fast().
diff --git a/include/linux/srcutiny.h b/include/linux/srcutiny.h
index fbcf13bc12d1..47a368f945e3 100644
--- a/include/linux/srcutiny.h
+++ b/include/linux/srcutiny.h
@@ -12,12 +12,14 @@
#define _LINUX_SRCU_TINY_H
#include <linux/irq_work_types.h>
+#include <linux/llist.h>
#include <linux/swait.h>
struct srcu_struct {
short srcu_lock_nesting[2]; /* srcu_read_lock() nesting depth. */
u8 srcu_gp_running; /* GP workqueue running? */
u8 srcu_gp_waiting; /* GP waiting for readers? */
+ u8 srcu_atomic_gp_flag; /* Serialize atomic GP work.*/
unsigned long srcu_idx; /* Current reader array element in bit 0x2. */
unsigned long srcu_idx_max; /* Furthest future srcu_idx request. */
struct swait_queue_head srcu_wq;
@@ -26,6 +28,8 @@ struct srcu_struct {
struct rcu_head **srcu_cb_tail; /* Pending callbacks: Tail. */
struct work_struct srcu_work; /* For driving grace periods. */
struct irq_work srcu_irq_work; /* Defer schedule_work() to irq work. */
+ struct llist_head defer_cbs; /* Callbacks deferred on re-entry. */
+ struct irq_work defer_iw; /* Re-issues defer_cbs later. */
#ifdef CONFIG_DEBUG_LOCK_ALLOC
struct lockdep_map dep_map;
#endif /* #ifdef CONFIG_DEBUG_LOCK_ALLOC */
@@ -33,6 +37,7 @@ struct srcu_struct {
void srcu_drive_gp(struct work_struct *wp);
void srcu_tiny_irq_work(struct irq_work *irq_work);
+void srcu_defer_drain(struct irq_work *irq_work);
#define __SRCU_STRUCT_INIT(name, __ignored, ___ignored, ____ignored) \
{ \
@@ -40,6 +45,9 @@ void srcu_tiny_irq_work(struct irq_work *irq_work);
.srcu_cb_tail = &name.srcu_cb_head, \
.srcu_work = __WORK_INITIALIZER(name.srcu_work, srcu_drive_gp), \
.srcu_irq_work = { .func = srcu_tiny_irq_work }, \
+ .defer_cbs = LLIST_HEAD_INIT(name.defer_cbs), \
+ .defer_iw = { .node = { .u_flags = IRQ_WORK_HARD_IRQ }, \
+ .func = srcu_defer_drain }, \
__SRCU_DEP_MAP_INIT(name) \
}
@@ -57,15 +65,20 @@ void srcu_tiny_irq_work(struct irq_work *irq_work);
#define DEFINE_SRCU_FAST_UPDOWN(name) DEFINE_SRCU(name)
#define DEFINE_STATIC_SRCU_FAST_UPDOWN(name) \
static struct srcu_struct name = __SRCU_STRUCT_INIT(name, name, name, name)
+#define DEFINE_SRCU_ATOMIC(name) DEFINE_SRCU(name)
+#define DEFINE_STATIC_SRCU_ATOMIC(name) \
+ static struct srcu_struct name = __SRCU_STRUCT_INIT(name, name, name, name)
// Dummy structure for srcu_notifier_head.
struct srcu_usage { };
#define __SRCU_USAGE_INIT(name) { }
#define __init_srcu_struct_fast __init_srcu_struct
#define __init_srcu_struct_fast_updown __init_srcu_struct
+#define __init_srcu_struct_atomic __init_srcu_struct
#ifndef CONFIG_DEBUG_LOCK_ALLOC
#define init_srcu_struct_fast init_srcu_struct
#define init_srcu_struct_fast_updown init_srcu_struct
+#define init_srcu_struct_atomic init_srcu_struct
#endif // #ifndef CONFIG_DEBUG_LOCK_ALLOC
void synchronize_srcu(struct srcu_struct *ssp);
@@ -131,10 +144,7 @@ static inline void synchronize_srcu_expedited(struct srcu_struct *ssp)
synchronize_srcu(ssp);
}
-static inline void srcu_barrier(struct srcu_struct *ssp)
-{
- synchronize_srcu(ssp);
-}
+void srcu_barrier(struct srcu_struct *ssp);
static inline void srcu_expedite_current(struct srcu_struct *ssp) { }
#define srcu_check_read_flavor(ssp, read_flavor) do { } while (0)
diff --git a/include/linux/srcutree.h b/include/linux/srcutree.h
index 75e54e4f963f..93b76e543894 100644
--- a/include/linux/srcutree.h
+++ b/include/linux/srcutree.h
@@ -13,6 +13,8 @@
#include <linux/rcu_node_tree.h>
#include <linux/completion.h>
+#include <linux/irq_work_types.h>
+#include <linux/llist.h>
struct srcu_node;
struct srcu_struct;
@@ -41,6 +43,8 @@ struct srcu_data {
bool srcu_cblist_invoking; /* Invoking these CBs? */
struct timer_list delay_work; /* Delay for CB invoking */
struct work_struct work; /* Context for CB invoking. */
+ struct llist_head defer_cbs; /* Callbacks deferred on re-entry. */
+ struct llist_node defer_link; /* Links onto the per-CPU deferral drain list */
struct rcu_head srcu_barrier_head; /* For srcu_barrier() use. */
struct rcu_head srcu_ec_head; /* For srcu_expedite_current() use. */
int srcu_ec_state; /* State for srcu_expedite_current(). */
@@ -76,6 +80,7 @@ struct srcu_usage {
struct mutex srcu_cb_mutex; /* Serialize CB preparation. */
raw_spinlock_t __private lock; /* Protect counters and size state. */
struct mutex srcu_gp_mutex; /* Serialize GP work. */
+ atomic_t srcu_atomic_gp_flag; /* Serialize atomic GP work. */
unsigned long srcu_gp_seq; /* Grace-period seq #. */
unsigned long srcu_gp_seq_needed; /* Latest gp_seq needed. */
unsigned long srcu_gp_seq_needed_exp; /* Furthest future exp GP. */
@@ -209,6 +214,12 @@ struct srcu_struct {
* instead of smp_mb(), and given that the first (for example)
* srcu_read_lock_fast() might race with the first synchronize_srcu(),
* this different must be specified at initialization time.
+ *
+ * If you use any of the DEFINE_SRCU() functions within a module, the
+ * module-entry code will invoke init_srcu_struct() and the module-exit
+ * code will invoke cleanup_srcu_struct(). This means that if your module
+ * passes the resulting srcu_struct structure to call_srcu(), you will
+ * need to also pass this structure to srcu_barrier() prior to module exit.
*/
#ifdef MODULE
# define __DEFINE_SRCU(name, fast, is_static) \
@@ -225,14 +236,16 @@ struct srcu_struct {
is_static struct srcu_struct name = \
__SRCU_STRUCT_INIT(name, name##_srcu_usage, name##_srcu_data, fast)
#endif
-#define DEFINE_SRCU(name) __DEFINE_SRCU(name, 0, /* not static */)
+#define DEFINE_SRCU(name) __DEFINE_SRCU(name, 0, /* !static */)
#define DEFINE_STATIC_SRCU(name) __DEFINE_SRCU(name, 0, static)
-#define DEFINE_SRCU_FAST(name) __DEFINE_SRCU(name, SRCU_READ_FLAVOR_FAST, /* not static */)
+#define DEFINE_SRCU_FAST(name) __DEFINE_SRCU(name, SRCU_READ_FLAVOR_FAST, /* !static */)
#define DEFINE_STATIC_SRCU_FAST(name) __DEFINE_SRCU(name, SRCU_READ_FLAVOR_FAST, static)
#define DEFINE_SRCU_FAST_UPDOWN(name) __DEFINE_SRCU(name, SRCU_READ_FLAVOR_FAST_UPDOWN, \
- /* not static */)
+ /* !static */)
#define DEFINE_STATIC_SRCU_FAST_UPDOWN(name) \
__DEFINE_SRCU(name, SRCU_READ_FLAVOR_FAST_UPDOWN, static)
+#define DEFINE_SRCU_ATOMIC(name) __DEFINE_SRCU(name, SRCU_READ_FLAVOR_ATOMIC, /* !static */)
+#define DEFINE_STATIC_SRCU_ATOMIC(name) __DEFINE_SRCU(name, SRCU_READ_FLAVOR_ATOMIC, static)
int __srcu_read_lock(struct srcu_struct *ssp) __acquires_shared(ssp);
void synchronize_srcu_expedited(struct srcu_struct *ssp);
diff --git a/include/linux/stmmac.h b/include/linux/stmmac.h
index 4430b967abde..00be2df63d22 100644
--- a/include/linux/stmmac.h
+++ b/include/linux/stmmac.h
@@ -242,6 +242,8 @@ struct plat_stmmacenet_data {
* that phylink uses.
*/
phy_interface_t phy_interface;
+ bool has_internal_tx_delay;
+ bool has_internal_rx_delay;
struct stmmac_mdio_bus_data *mdio_bus_data;
struct device_node *phy_node;
struct device_node *mdio_node;
diff --git a/include/linux/string.h b/include/linux/string.h
index 5702daca4326..6cb5cdd01158 100644
--- a/include/linux/string.h
+++ b/include/linux/string.h
@@ -278,6 +278,19 @@ static inline void memcpy_flushcache(void *dst, const void *src, size_t cnt)
}
#endif
+#ifndef memcpy_nontemporal
+/*
+ * memcpy_nontemporal() requests a non-temporal copy when the
+ * architecture has a suitable backend. Architectures without a
+ * specialized backend fall back to memcpy(). Keep this as a
+ * function-like macro so the compiler can still see the original
+ * memcpy() call site and preserve the usual FORTIFY coverage when
+ * object sizes remain visible there, while keeping the API void.
+ */
+#define memcpy_nontemporal(dst, src, len) \
+ ((void)memcpy(dst, src, len))
+#endif
+
void *memchr_inv(const void *s, int c, size_t n);
char *strreplace(char *str, char old, char new);
diff --git a/include/linux/suspend.h b/include/linux/suspend.h
index b02876f1ae38..a3815027773c 100644
--- a/include/linux/suspend.h
+++ b/include/linux/suspend.h
@@ -401,6 +401,7 @@ int hibernate_quiet_exec(int (*func)(void *data), void *data);
int hibernate_resume_nonboot_cpu_disable(void);
int arch_hibernation_header_save(void *addr, unsigned int max_size);
int arch_hibernation_header_restore(void *addr);
+bool arch_hibernation_available(void);
#else /* CONFIG_HIBERNATION */
static inline void register_nosave_region(unsigned long b, unsigned long e) {}
diff --git a/include/linux/swap.h b/include/linux/swap.h
index 5658a1634b85..cb434cccd653 100644
--- a/include/linux/swap.h
+++ b/include/linux/swap.h
@@ -25,12 +25,6 @@
#define SWAP_FLAGS_VALID (SWAP_FLAG_PRIO_MASK | SWAP_FLAG_PREFER | \
SWAP_FLAG_DISCARD | SWAP_FLAG_DISCARD_ONCE | \
SWAP_FLAG_DISCARD_PAGES)
-
-static inline int current_is_kswapd(void)
-{
- return current->flags & PF_KSWAPD;
-}
-
/*
* MAX_SWAPFILES defines the maximum number of swaptypes: things which can
* be swapped to. The swap type and the offset into that swap type are
@@ -246,7 +240,7 @@ struct swap_info_struct {
struct plist_node list; /* entry in swap_active_head */
signed char type; /* strange name for an index */
unsigned int max; /* size of this swap device */
- struct swap_cluster_info *cluster_info; /* cluster info. Only for SSD */
+ struct swap_cluster_info *cluster_info; /* array, one entry per cluster */
struct list_head free_clusters; /* free clusters list */
struct list_head full_clusters; /* full clusters list */
struct list_head nonfull_clusters[SWAP_NR_ORDERS];
@@ -278,15 +272,39 @@ struct swap_info_struct {
const struct swap_ops *ops;
};
-static inline swp_entry_t page_swap_entry(struct page *page)
+/**
+ * folio_swap_entry - Return the swap entry at a page index within a folio.
+ * @folio: The folio.
+ * @idx: The index of the page within the folio.
+ *
+ * A folio in the swap cache occupies folio_nr_pages() contiguous swap
+ * entries starting at folio->swap. The caller must ensure the folio is
+ * in the swap cache and that @idx is within the folio.
+ */
+static inline
+swp_entry_t folio_swap_entry(const struct folio *folio, unsigned long idx)
{
- struct folio *folio = page_folio(page);
swp_entry_t entry = folio->swap;
- entry.val += folio_page_idx(folio, page);
+ VM_WARN_ON_ONCE_FOLIO(idx >= folio_nr_pages(folio), folio);
+ entry.val += idx;
return entry;
}
+/**
+ * folio_page_swap_entry - Return the swap entry of a page in a folio.
+ * @folio: The folio containing @page.
+ * @page: A page within @folio.
+ *
+ * The caller must ensure the folio is in the swap cache and that @page
+ * is part of @folio.
+ */
+static inline swp_entry_t folio_page_swap_entry(const struct folio *folio,
+ const struct page *page)
+{
+ return folio_swap_entry(folio, folio_page_idx(folio, page));
+}
+
/* linux/mm/page_alloc.c */
extern unsigned long totalreserve_pages;
@@ -318,6 +336,9 @@ static inline bool lru_cache_disabled(void)
extern unsigned long shrink_all_memory(unsigned long nr_pages);
long remove_mapping(struct address_space *mapping, struct folio *folio);
+long remove_mapping_set_shadow(struct address_space *mapping,
+ struct folio *folio,
+ struct mem_cgroup *target_memcg);
#if defined(CONFIG_SYSFS) && defined(CONFIG_NUMA)
extern int reclaim_register_node(struct node *node);
@@ -339,6 +360,7 @@ void check_move_unevictable_folios(struct folio_batch *fbatch);
extern void __meminit kswapd_run(int nid);
extern void __meminit kswapd_stop(int nid);
+bool current_is_kswapd(void);
#ifdef CONFIG_SWAP
int add_swap_extent(struct swap_info_struct *sis, unsigned long start_page,
@@ -402,6 +424,8 @@ void swap_put_entries_direct(swp_entry_t entry, int nr);
*/
bool folio_free_swap(struct folio *folio);
+void swap_writeback_dropbehind_folio(struct folio *folio);
+
/* Allocate / free (hibernation) exclusive entries */
swp_entry_t swap_alloc_hibernation_slot(int type);
void swap_free_hibernation_slot(swp_entry_t entry);
@@ -412,6 +436,7 @@ static inline void put_swap_device(struct swap_info_struct *si)
}
#else /* CONFIG_SWAP */
+static inline void swap_writeback_dropbehind_folio(struct folio *folio) {}
static inline struct swap_info_struct *get_swap_device(swp_entry_t entry)
{
return NULL;
@@ -508,8 +533,9 @@ static inline void mem_cgroup_uncharge_swap(unsigned short id, unsigned int nr_p
__mem_cgroup_uncharge_swap(id, nr_pages);
}
-extern long mem_cgroup_get_nr_swap_pages(struct mem_cgroup *memcg);
-extern bool mem_cgroup_swap_full(struct folio *folio);
+long mem_cgroup_get_folio_swap_margin(const struct folio *folio);
+long mem_cgroup_get_nr_swap_pages(const struct mem_cgroup *memcg);
+bool mem_cgroup_swap_full(const struct folio *folio);
#else
static inline int mem_cgroup_try_charge_swap(struct folio *folio)
{
@@ -521,12 +547,17 @@ static inline void mem_cgroup_uncharge_swap(unsigned short id,
{
}
-static inline long mem_cgroup_get_nr_swap_pages(struct mem_cgroup *memcg)
+static inline long mem_cgroup_get_folio_swap_margin(const struct folio *folio)
+{
+ return PAGE_COUNTER_MAX;
+}
+
+static inline long mem_cgroup_get_nr_swap_pages(const struct mem_cgroup *memcg)
{
return get_nr_swap_pages();
}
-static inline bool mem_cgroup_swap_full(struct folio *folio)
+static inline bool mem_cgroup_swap_full(const struct folio *folio)
{
return vm_swap_full();
}
diff --git a/include/linux/swapops.h b/include/linux/swapops.h
index e7d0d529f3e0..603f9e3f909c 100644
--- a/include/linux/swapops.h
+++ b/include/linux/swapops.h
@@ -261,11 +261,6 @@ static inline swp_entry_t make_hwpoison_entry(struct page *page)
return swp_entry(SWP_HWPOISON, page_to_pfn(page));
}
-static inline int is_hwpoison_entry(swp_entry_t entry)
-{
- return swp_type(entry) == SWP_HWPOISON;
-}
-
#else
static inline swp_entry_t make_hwpoison_entry(struct page *page)
@@ -273,10 +268,6 @@ static inline swp_entry_t make_hwpoison_entry(struct page *page)
return swp_entry(0, 0);
}
-static inline int is_hwpoison_entry(swp_entry_t swp)
-{
- return 0;
-}
#endif
typedef unsigned long pte_marker;
diff --git a/include/linux/swiotlb.h b/include/linux/swiotlb.h
index 2a421241b980..5f24edf47b68 100644
--- a/include/linux/swiotlb.h
+++ b/include/linux/swiotlb.h
@@ -38,7 +38,7 @@ struct scatterlist;
#define IO_TLB_DEFAULT_SIZE (64UL << 20)
#endif
-unsigned long swiotlb_size_or_default(void);
+unsigned long swiotlb_default_pool_size(void);
void __init swiotlb_init_remap(bool addressing_limit, unsigned int flags,
int (*remap)(void *tlb, unsigned long nslabs));
int swiotlb_init_late(size_t size, gfp_t gfp_mask,
diff --git a/include/linux/syscalls.h b/include/linux/syscalls.h
index 8413b624ad47..552d9710a0d5 100644
--- a/include/linux/syscalls.h
+++ b/include/linux/syscalls.h
@@ -92,6 +92,7 @@ struct file_attr;
#include <linux/quota.h>
#include <linux/key.h>
#include <linux/personality.h>
+#include <linux/error-injection.h>
#include <trace/syscall.h>
#ifdef CONFIG_ARCH_HAS_SYSCALL_WRAPPER
diff --git a/include/linux/tcp.h b/include/linux/tcp.h
index 6a8c77719322..d18f7bc1e5d0 100644
--- a/include/linux/tcp.h
+++ b/include/linux/tcp.h
@@ -233,6 +233,13 @@ struct tcp_sock {
is_sack_reneg:1, /* in recovery from loss with SACK reneg? */
is_cwnd_limited:1,/* forward progress limited by snd_cwnd? */
recvmsg_inq : 1;/* Indicate # of bytes in queue upon recvmsg */
+#ifdef CONFIG_BPF
+ u32 bpf_tcp_ops_flags;
+#define BPF_TCP_OPS_TEST_FLAG(TP, ARG) \
+ (READ_ONCE((TP)->bpf_tcp_ops_flags) & BPF_TCP_OPS_FLAG_ ## ARG)
+#else
+#define BPF_TCP_OPS_TEST_FLAG(TP, ARG) (0)
+#endif
__cacheline_group_end(tcp_sock_read_txrx);
/* RX read-mostly hotpath cache lines */
@@ -269,6 +276,9 @@ struct tcp_sock {
*/
u32 snd_sml; /* Last byte of the most recently transmitted small packet */
u8 chrono_type; /* current chronograph type */
+ u8 tcp_nospace; /* mirrors SOCK_NOSPACE, must be set whenever
+ * SOCK_NOSPACE is set.
+ */
u32 chrono_start; /* Start time in jiffies of a TCP chrono */
u32 chrono_stat[3]; /* Time in jiffies for chrono_stat stats */
u32 write_seq; /* Tail(+1) of data held in tcp send buffer */
diff --git a/include/linux/thermal.h b/include/linux/thermal.h
index 083b4f533933..306ad17aed89 100644
--- a/include/linux/thermal.h
+++ b/include/linux/thermal.h
@@ -293,8 +293,9 @@ struct device *thermal_zone_device(struct thermal_zone_device *tzd);
void thermal_zone_device_update(struct thermal_zone_device *,
enum thermal_notify_event);
-struct thermal_cooling_device *thermal_cooling_device_register(const char *,
- void *, const struct thermal_cooling_device_ops *);
+struct thermal_cooling_device *thermal_cooling_device_create(
+ struct device *parent, const char *type, void *devdata,
+ const struct thermal_cooling_device_ops *ops);
struct thermal_cooling_device *
devm_thermal_cooling_device_register(struct device *dev, const char *type, void *devdata,
@@ -340,9 +341,9 @@ static inline void thermal_zone_device_update(struct thermal_zone_device *tz,
enum thermal_notify_event event)
{ }
-static inline struct thermal_cooling_device *
-thermal_cooling_device_register(const char *type, void *devdata,
- const struct thermal_cooling_device_ops *ops)
+static inline struct thermal_cooling_device *thermal_cooling_device_create(
+ struct device *parent, const char *type, void *devdata,
+ const struct thermal_cooling_device_ops *ops)
{ return ERR_PTR(-ENODEV); }
static inline struct thermal_cooling_device *
@@ -391,4 +392,12 @@ static inline void thermal_pm_prepare(void) {}
static inline void thermal_pm_complete(void) {}
#endif /* CONFIG_THERMAL */
+static inline struct thermal_cooling_device *thermal_cooling_device_register(
+ const char *type, void *devdata,
+ const struct thermal_cooling_device_ops *ops)
+{
+ return thermal_cooling_device_create(NULL, type, devdata, ops);
+}
+
+
#endif /* __THERMAL_H__ */
diff --git a/include/linux/thunderbolt.h b/include/linux/thunderbolt.h
index d48623fda79b..57502da29080 100644
--- a/include/linux/thunderbolt.h
+++ b/include/linux/thunderbolt.h
@@ -22,6 +22,7 @@ struct device;
#include <linux/device.h>
#include <linux/idr.h>
#include <linux/list.h>
+#include <linux/lockdep.h>
#include <linux/mutex.h>
#include <linux/device-id/tb.h>
#include <linux/pci.h>
@@ -369,7 +370,7 @@ int tb_xdomain_request(struct tb_xdomain *xd, const void *request,
* @uuid: XDomain messages with this UUID are dispatched to this handler
* @callback: Callback called with the XDomain message. Returning %1
* here tells the XDomain core that the message was handled
- * by this handler and should not be forwared to other
+ * by this handler and should not be forwarded to other
* handlers.
* @data: Data passed with the callback
* @list: Handlers are linked using this
@@ -506,6 +507,7 @@ void tb_service_properties_changed(struct tb_service *svc);
* @iobase: MMIO space of the NHI
* @tx_rings: All Tx rings available on this host controller
* @rx_rings: All Rx rings available on this host controller
+ * @interrupt_mask: Shadow copy of the ring interrupt mask register
* @going_away: The host controller device is about to disappear so when
* this flag is set, avoid touching the hardware anymore.
* @iommu_dma_protection: An IOMMU will isolate external-facing ports.
@@ -527,6 +529,7 @@ struct tb_nhi {
void __iomem *iobase;
struct tb_ring **tx_rings;
struct tb_ring **rx_rings;
+ u32 *interrupt_mask;
bool going_away;
bool iommu_dma_protection;
struct work_struct interrupt_work;
@@ -552,6 +555,8 @@ struct tb_nhi {
* @work: Interrupt work structure
* @is_tx: Is the ring Tx or Rx
* @running: Is the ring running
+ * @notify_pending: Controller has not been notified about the posted
+ * descriptors yet
* @irq: MSI-X irq number if the ring uses MSI-X. %0 otherwise.
* @vector: MSI-X vector number the ring uses (only set if @irq is > 0)
* @flags: Ring specific flags
@@ -565,6 +570,7 @@ struct tb_nhi {
* @interval_nsec: Interval counter if interrupt throttling is to be
* used with this ring (in ns)
* @wait: Used to signal that the ring may be empty now
+ * @lock_key: Lock validator class key per-ring
*/
struct tb_ring {
spinlock_t lock;
@@ -580,6 +586,7 @@ struct tb_ring {
struct work_struct work;
bool is_tx:1;
bool running:1;
+ bool notify_pending:1;
int irq;
u8 vector;
unsigned int flags;
@@ -590,6 +597,7 @@ struct tb_ring {
void *poll_data;
unsigned int interval_nsec;
wait_queue_head_t wait;
+ struct lock_class_key lock_key;
};
/* Leave ring interrupt enabled on suspend */
@@ -669,7 +677,8 @@ bool tb_ring_flush(struct tb_ring *ring, unsigned int timeout_msec);
void tb_ring_stop(struct tb_ring *ring);
void tb_ring_free(struct tb_ring *ring);
-int __tb_ring_enqueue(struct tb_ring *ring, struct ring_frame *frame);
+int __tb_ring_enqueue(struct tb_ring *ring, struct ring_frame *frame, bool more);
+void tb_ring_notify(struct tb_ring *ring);
/**
* tb_ring_rx() - enqueue a frame on an RX ring
@@ -690,7 +699,24 @@ int __tb_ring_enqueue(struct tb_ring *ring, struct ring_frame *frame);
static inline int tb_ring_rx(struct tb_ring *ring, struct ring_frame *frame)
{
WARN_ON(ring->is_tx);
- return __tb_ring_enqueue(ring, frame);
+ return __tb_ring_enqueue(ring, frame, false);
+}
+
+/**
+ * tb_ring_rx_more() - enqueue a frame on an RX ring without notifying
+ * @ring: Ring to enqueue the frame
+ * @frame: Frame to enqueue
+ *
+ * Same as tb_ring_rx() but does not notify the controller about the
+ * enqueued frame. The caller must call tb_ring_notify() once it is done
+ * enqueuing frames.
+ *
+ * Return: %-ESHUTDOWN if tb_ring_stop() has been called, %0 otherwise.
+ */
+static inline int tb_ring_rx_more(struct tb_ring *ring, struct ring_frame *frame)
+{
+ WARN_ON(ring->is_tx);
+ return __tb_ring_enqueue(ring, frame, true);
}
/**
@@ -711,11 +737,27 @@ static inline int tb_ring_rx(struct tb_ring *ring, struct ring_frame *frame)
static inline int tb_ring_tx(struct tb_ring *ring, struct ring_frame *frame)
{
WARN_ON(!ring->is_tx);
- return __tb_ring_enqueue(ring, frame);
+ return __tb_ring_enqueue(ring, frame, false);
+}
+
+/**
+ * tb_ring_tx_more() - enqueue a frame on a TX ring without notifying
+ * @ring: Ring to enqueue the frame
+ * @frame: Frame to enqueue
+ *
+ * Same as tb_ring_rx_more() but for TX ring.
+ *
+ * Return: %-ESHUTDOWN if tb_ring_stop() has been called, %0 otherwise.
+ */
+static inline int tb_ring_tx_more(struct tb_ring *ring, struct ring_frame *frame)
+{
+ WARN_ON(!ring->is_tx);
+ return __tb_ring_enqueue(ring, frame, true);
}
/* Used only when the ring is in polling mode */
struct ring_frame *tb_ring_poll(struct tb_ring *ring);
+bool tb_ring_poll_pending(struct tb_ring *ring);
void tb_ring_poll_complete(struct tb_ring *ring);
int tb_ring_throttling(struct tb_ring *ring, unsigned int interval_nsec);
diff --git a/include/linux/tnum.h b/include/linux/tnum.h
index ca2cfec8de08..16682248f963 100644
--- a/include/linux/tnum.h
+++ b/include/linux/tnum.h
@@ -134,4 +134,6 @@ static inline bool tnum_subreg_is_const(struct tnum a)
/* Returns the smallest member of t larger than z */
u64 tnum_step(struct tnum t, u64 z);
+u32 tnum_alignment(struct tnum a);
+
#endif /* _LINUX_TNUM_H */
diff --git a/include/linux/trace_remote_event.h b/include/linux/trace_remote_event.h
index c8ae1e1f5e72..e4cc2d4497bc 100644
--- a/include/linux/trace_remote_event.h
+++ b/include/linux/trace_remote_event.h
@@ -3,6 +3,8 @@
#ifndef _LINUX_TRACE_REMOTE_EVENTS_H
#define _LINUX_TRACE_REMOTE_EVENTS_H
+#include <linux/types.h>
+
struct trace_remote;
struct trace_event_fields;
struct trace_seq;
diff --git a/include/linux/trace_seq.h b/include/linux/trace_seq.h
index 697d619aafdc..7174ebf3f015 100644
--- a/include/linux/trace_seq.h
+++ b/include/linux/trace_seq.h
@@ -86,7 +86,10 @@ static inline bool trace_seq_has_overflowed(struct trace_seq *s)
*
* Removes the last written character to the trace_seq @s.
*
- * Returns the last character or -1 if it is empty.
+ * Returns the last character, or -1 if the underlying seq_buf is empty or
+ * has overflowed. Note that only that buffer is consulted: a @s marked
+ * full by a write that did not fit, which trace_seq_has_overflowed()
+ * reports as overflowed, still pops the last character written.
*/
static inline int trace_seq_pop(struct trace_seq *s)
{
diff --git a/include/linux/tty.h b/include/linux/tty.h
index 0a46e4054dec..833bb7b97ceb 100644
--- a/include/linux/tty.h
+++ b/include/linux/tty.h
@@ -168,6 +168,7 @@ struct tty_operations;
* @write_wait: concurrent writers are waiting in this queue until they are
* allowed to write
* @read_wait: readers wait for data in this queue
+ * @break_wait: wait queue for timed breaks
* @hangup_work: normally a work to perform a hangup (do_tty_hangup()); while
* freeing the tty, (re)used to release_one_tty()
* @disc_data: pointer to @ldisc's private data (e.g. to &struct n_tty_data)
@@ -230,6 +231,7 @@ struct tty_struct {
struct fasync_struct *fasync;
wait_queue_head_t write_wait;
wait_queue_head_t read_wait;
+ wait_queue_head_t break_wait;
struct work_struct hangup_work;
void *disc_data;
void *driver_data;
diff --git a/include/linux/tty_driver.h b/include/linux/tty_driver.h
index 1f2896e56e77..40ae3bb13e11 100644
--- a/include/linux/tty_driver.h
+++ b/include/linux/tty_driver.h
@@ -73,6 +73,11 @@ struct serial_struct;
* @TTY_DRIVER_NO_WORKQUEUE:
* Do not create workqueue when tty_register_driver(). Whenever set, flip
* buffer workqueue can be set by tty_port_link_wq() for every port.
+ *
+ * @TTY_DRIVER_RESET_SAVED_TERMIOS:
+ * Reset any saved termios settings on device registration when reusing a
+ * minor number. Must only be set by drivers that guarantee that the minor
+ * number is no longer in use.
*/
enum tty_driver_flag {
TTY_DRIVER_INSTALLED = BIT(0),
@@ -84,6 +89,7 @@ enum tty_driver_flag {
TTY_DRIVER_DYNAMIC_ALLOC = BIT(6),
TTY_DRIVER_UNNUMBERED_NODE = BIT(7),
TTY_DRIVER_NO_WORKQUEUE = BIT(8),
+ TTY_DRIVER_RESET_SAVED_TERMIOS = BIT(9),
};
enum tty_driver_type {
diff --git a/include/linux/tty_port.h b/include/linux/tty_port.h
index 23cad403bb8f..8d22c59c6f15 100644
--- a/include/linux/tty_port.h
+++ b/include/linux/tty_port.h
@@ -245,7 +245,8 @@ bool tty_port_carrier_raised(struct tty_port *port);
void tty_port_raise_dtr_rts(struct tty_port *port);
void tty_port_lower_dtr_rts(struct tty_port *port);
void tty_port_hangup(struct tty_port *port);
-void __tty_port_tty_hangup(struct tty_port *port, bool check_clocal, bool async);
+void tty_port_tty_hangup(struct tty_port *port, bool check_clocal);
+void tty_port_tty_vhangup(struct tty_port *port);
void tty_port_tty_wakeup(struct tty_port *port);
int tty_port_block_til_ready(struct tty_port *port, struct tty_struct *tty,
struct file *filp);
@@ -264,25 +265,6 @@ static inline int tty_port_users(struct tty_port *port)
return port->count + port->blocked_open;
}
-/**
- * tty_port_tty_hangup - helper to hang up a tty asynchronously
- * @port: tty port
- * @check_clocal: hang only ttys with %CLOCAL unset?
- */
-static inline void tty_port_tty_hangup(struct tty_port *port, bool check_clocal)
-{
- __tty_port_tty_hangup(port, check_clocal, true);
-}
-
-/**
- * tty_port_tty_vhangup - helper to hang up a tty synchronously
- * @port: tty port
- */
-static inline void tty_port_tty_vhangup(struct tty_port *port)
-{
- __tty_port_tty_hangup(port, false, false);
-}
-
#ifdef CONFIG_TTY
void tty_kref_put(struct tty_struct *tty);
__DEFINE_CLASS_IS_CONDITIONAL(tty_port_tty, true);
diff --git a/include/linux/ucs2_string.h b/include/linux/ucs2_string.h
index c499ae809c7d..74f23ca5a967 100644
--- a/include/linux/ucs2_string.h
+++ b/include/linux/ucs2_string.h
@@ -14,7 +14,16 @@ ssize_t ucs2_strscpy(ucs2_char_t *dst, const ucs2_char_t *src, size_t count);
int ucs2_strncmp(const ucs2_char_t *a, const ucs2_char_t *b, size_t len);
unsigned long ucs2_utf8size(const ucs2_char_t *src);
+unsigned long
+ucs2_as_utf8_l(u8 *dest, const ucs2_char_t *src, unsigned long limit,
+ unsigned long maxlength);
+
+static inline
unsigned long ucs2_as_utf8(u8 *dest, const ucs2_char_t *src,
- unsigned long maxlength);
+ unsigned long maxlength)
+{
+ return ucs2_as_utf8_l(dest, src, ucs2_strnlen(src, maxlength),
+ maxlength);
+}
#endif /* _LINUX_UCS2_STRING_H_ */
diff --git a/include/linux/uidgid.h b/include/linux/uidgid.h
index 2dc767e08f54..02403629b49f 100644
--- a/include/linux/uidgid.h
+++ b/include/linux/uidgid.h
@@ -130,9 +130,9 @@ static inline bool kgid_has_mapping(struct user_namespace *ns, kgid_t gid)
return from_kgid(ns, gid) != (gid_t) -1;
}
-u32 map_id_down(struct uid_gid_map *map, u32 id);
-u32 map_id_up(struct uid_gid_map *map, u32 id);
-u32 map_id_range_up(struct uid_gid_map *map, u32 id, u32 count);
+u32 map_id_down(const struct uid_gid_map *map, u32 id);
+u32 map_id_up(const struct uid_gid_map *map, u32 id);
+u32 map_id_range_up(const struct uid_gid_map *map, u32 id, u32 count);
#else
@@ -182,17 +182,17 @@ static inline bool kgid_has_mapping(struct user_namespace *ns, kgid_t gid)
return gid_valid(gid);
}
-static inline u32 map_id_down(struct uid_gid_map *map, u32 id)
+static inline u32 map_id_down(const struct uid_gid_map *map, u32 id)
{
return id;
}
-static inline u32 map_id_range_up(struct uid_gid_map *map, u32 id, u32 count)
+static inline u32 map_id_range_up(const struct uid_gid_map *map, u32 id, u32 count)
{
return id;
}
-static inline u32 map_id_up(struct uid_gid_map *map, u32 id)
+static inline u32 map_id_up(const struct uid_gid_map *map, u32 id)
{
return id;
}
diff --git a/include/linux/ulpi/driver.h b/include/linux/ulpi/driver.h
index c668d9c8d876..c899197e0aa8 100644
--- a/include/linux/ulpi/driver.h
+++ b/include/linux/ulpi/driver.h
@@ -51,8 +51,8 @@ struct ulpi_driver {
/*
* use a macro to avoid include chaining to get THIS_MODULE
*/
-#define ulpi_register_driver(drv) __ulpi_register_driver(drv, THIS_MODULE)
-int __ulpi_register_driver(struct ulpi_driver *drv, struct module *module);
+#define ulpi_register_driver(drv) __ulpi_register_driver(drv, THIS_MODULE, KBUILD_MODNAME)
+int __ulpi_register_driver(struct ulpi_driver *drv, struct module *module, const char *mod_name);
void ulpi_unregister_driver(struct ulpi_driver *drv);
#define module_ulpi_driver(__ulpi_driver) \
diff --git a/include/linux/unicode.h b/include/linux/unicode.h
index 64fa44fe180c..3a8cb603eb93 100644
--- a/include/linux/unicode.h
+++ b/include/linux/unicode.h
@@ -53,6 +53,7 @@ struct unicode_map {
unsigned int version;
const struct utf8data *ntab[UTF8_NMAX];
const struct utf8data_table *tables;
+ struct rcu_head rcu;
};
int utf8_validate(const struct unicode_map *um, const struct qstr *str);
diff --git a/include/linux/usb.h b/include/linux/usb.h
index 49ab8dbb885f..825f03b29067 100644
--- a/include/linux/usb.h
+++ b/include/linux/usb.h
@@ -1369,8 +1369,10 @@ extern void usb_deregister(struct usb_driver *);
module_driver(__usb_driver, usb_register, \
usb_deregister)
-extern int usb_register_device_driver(struct usb_device_driver *,
- struct module *);
+#define usb_register_device_driver(new_udriver) \
+ __usb_register_device_driver(new_udriver, THIS_MODULE, KBUILD_MODNAME)
+extern int __usb_register_device_driver(struct usb_device_driver *,
+ struct module *, const char *);
extern void usb_deregister_device_driver(struct usb_device_driver *);
extern int usb_register_dev(struct usb_interface *intf,
@@ -1606,7 +1608,12 @@ typedef void (*usb_complete_t)(struct urb *);
*
* Completion Callbacks:
*
- * The completion callback is made in_interrupt(), and one of the first
+ * The completion callback can occur in any context: process, interrupt,
+ * BH, or anything else. Also, interrupts may or may not be disabled on
+ * the local CPU when the callback runs. A completion handler routine
+ * must not depend on any particular properties of its environment.
+ *
+ * One of the first
* things that a completion handler should do is check the status field.
* The status field is provided for all URBs. It is used to report
* unlinked URBs, and status for all non-ISO transfers. It should not
diff --git a/include/linux/usb/rndis_host.h b/include/linux/usb/rndis_host.h
index 489cfb1d00f6..3eaf57a9b282 100644
--- a/include/linux/usb/rndis_host.h
+++ b/include/linux/usb/rndis_host.h
@@ -182,8 +182,9 @@ struct rndis_keepalive_c { /* IN (optionally OUT) */
#define FLAG_RNDIS_PHYM_WIRELESS 0x0002
/* Flags for driver_info::data */
-#define RNDIS_DRIVER_DATA_POLL_STATUS 1 /* poll status before control */
-#define RNDIS_DRIVER_DATA_DST_MAC_FIXUP 2 /* device ignores configured MAC address */
+#define RNDIS_DRIVER_DATA_POLL_STATUS 1 /* poll status before control */
+#define RNDIS_DRIVER_DATA_DST_MAC_FIXUP 2 /* device ignores configured MAC address */
+#define RNDIS_DRIVER_DATA_RX_AGGREGATION 4 /* needs RX limit > 2048 */
extern void rndis_status(struct usbnet *dev, struct urb *urb);
extern int
diff --git a/include/linux/usb/serial.h b/include/linux/usb/serial.h
index 534e6650e2aa..5866f19d3c7b 100644
--- a/include/linux/usb/serial.h
+++ b/include/linux/usb/serial.h
@@ -305,9 +305,17 @@ struct usb_serial_driver {
void (*write_bulk_callback)(struct urb *urb);
/* Called by the generic read bulk callback */
void (*process_read_urb)(struct urb *urb);
+ /*
+ * Called with port->lock held before preparing another write URB.
+ * Drivers returning false must restart the generic write path when
+ * writes may proceed again.
+ */
+ bool (*write_ready)(struct usb_serial_port *port);
/* Called by the generic write implementation */
int (*prepare_write_buffer)(struct usb_serial_port *port,
void *dest, size_t size);
+ /* Called with port->lock held to roll back a failed write submission */
+ void (*write_rollback)(struct usb_serial_port *port, int count);
};
#define to_usb_serial_driver(d) \
container_of(d, struct usb_serial_driver, driver)
@@ -381,6 +389,7 @@ void usb_serial_handle_dcd_change(struct usb_serial_port *usb_port,
int usb_serial_bus_register(struct usb_serial_driver *device);
void usb_serial_bus_deregister(struct usb_serial_driver *device);
+void usb_serial_bus_remove_new_id(struct usb_serial_driver *driver);
extern const struct bus_type usb_serial_bus_type;
extern struct tty_driver *usb_serial_tty_driver;
diff --git a/include/linux/usb/typec_altmode.h b/include/linux/usb/typec_altmode.h
index ef21ead551be..92309b569c3a 100644
--- a/include/linux/usb/typec_altmode.h
+++ b/include/linux/usb/typec_altmode.h
@@ -227,9 +227,9 @@ struct typec_altmode_driver {
* handle all SVID specific communication.
*/
#define typec_altmode_register_driver(drv) \
- __typec_altmode_register_driver(drv, THIS_MODULE)
+ __typec_altmode_register_driver(drv, THIS_MODULE, KBUILD_MODNAME)
int __typec_altmode_register_driver(struct typec_altmode_driver *drv,
- struct module *module);
+ struct module *module, const char *mod_name);
/**
* typec_altmode_unregister_driver - unregisters a USB Type-C alternate mode
* device driver
diff --git a/include/linux/user_namespace.h b/include/linux/user_namespace.h
index e38d9e60569f..91232053775d 100644
--- a/include/linux/user_namespace.h
+++ b/include/linux/user_namespace.h
@@ -29,8 +29,8 @@ struct uid_gid_map { /* 64 bytes -- 1 cache line */
u32 nr_extents;
};
struct {
- struct uid_gid_extent *forward;
- struct uid_gid_extent *reverse;
+ struct uid_gid_extent *forward __counted_by_ptr(nr_extents);
+ struct uid_gid_extent *reverse __counted_by_ptr(nr_extents);
};
};
};
@@ -207,6 +207,13 @@ extern bool in_userns(const struct user_namespace *ancestor,
const struct user_namespace *child);
extern bool current_in_userns(const struct user_namespace *target_ns);
struct ns_common *ns_get_owner(struct ns_common *ns);
+
+#if IS_ENABLED(CONFIG_KUNIT)
+extern int uid_gid_map_insert_extent(struct uid_gid_map *map,
+ struct uid_gid_extent *extent);
+extern int uid_gid_map_sort(struct uid_gid_map *map);
+#endif /* CONFIG_KUNIT */
+
#else
static inline struct user_namespace *get_user_ns(struct user_namespace *ns)
diff --git a/include/linux/vdso_time.h b/include/linux/vdso_time.h
new file mode 100644
index 000000000000..6d81ee3a3c9c
--- /dev/null
+++ b/include/linux/vdso_time.h
@@ -0,0 +1,8 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef _LINUX_VDSO_TIME_H
+#define _LINUX_VDSO_TIME_H
+
+unsigned long vdso_time_update_begin(void);
+void vdso_time_update_end(unsigned long flags);
+
+#endif /* _LINUX_VDSO_TIME_H */
diff --git a/include/linux/vfio.h b/include/linux/vfio.h
index 45f08986359e..0cc91c6f96d2 100644
--- a/include/linux/vfio.h
+++ b/include/linux/vfio.h
@@ -54,7 +54,7 @@ struct vfio_device {
struct list_head dev_set_list;
unsigned int migration_flags;
u8 precopy_info_v2;
- struct kvm *kvm;
+ struct file *kvm;
/* Members below here are private, not for driver use */
unsigned int index;
@@ -66,7 +66,6 @@ struct vfio_device {
unsigned int open_count;
struct completion comp;
struct iommufd_access *iommufd_access;
- void (*put_kvm)(struct kvm *kvm);
struct inode *inode;
#if IS_ENABLED(CONFIG_IOMMUFD)
struct iommufd_device *iommufd_device;
@@ -378,7 +377,7 @@ static inline bool vfio_file_has_dev(struct file *file, struct vfio_device *devi
#endif
bool vfio_file_is_valid(struct file *file);
bool vfio_file_enforced_coherent(struct file *file);
-void vfio_file_set_kvm(struct file *file, struct kvm *kvm);
+void vfio_file_set_kvm(struct file *vfio_file, struct file *kvm);
#define VFIO_PIN_PAGES_MAX_ENTRIES (PAGE_SIZE/sizeof(unsigned long))
diff --git a/include/linux/vfio_pci_core.h b/include/linux/vfio_pci_core.h
index 9a1674c152aa..2f3fa2787737 100644
--- a/include/linux/vfio_pci_core.h
+++ b/include/linux/vfio_pci_core.h
@@ -8,6 +8,7 @@
* Author: Tom Lyon, pugs@cisco.com
*/
+#include <linux/device.h>
#include <linux/mutex.h>
#include <linux/pci.h>
#include <linux/vfio.h>
@@ -16,6 +17,7 @@
#include <linux/types.h>
#include <linux/uuid.h>
#include <linux/notifier.h>
+#include <linux/pm.h>
#ifndef VFIO_PCI_CORE_H
#define VFIO_PCI_CORE_H
@@ -168,7 +170,6 @@ int vfio_pci_core_init_dev(struct vfio_device *core_vdev);
void vfio_pci_core_release_dev(struct vfio_device *core_vdev);
int vfio_pci_core_register_device(struct vfio_pci_core_device *vdev);
void vfio_pci_core_unregister_device(struct vfio_pci_core_device *vdev);
-extern const struct pci_error_handlers vfio_pci_core_err_handlers;
int vfio_pci_core_sriov_configure(struct vfio_pci_core_device *vdev,
int nr_virtfn);
long vfio_pci_core_ioctl(struct vfio_device *core_vdev, unsigned int cmd,
@@ -193,8 +194,6 @@ int vfio_pci_core_match_token_uuid(struct vfio_device *core_vdev,
int vfio_pci_core_enable(struct vfio_pci_core_device *vdev);
void vfio_pci_core_disable(struct vfio_pci_core_device *vdev);
void vfio_pci_core_finish_enable(struct vfio_pci_core_device *vdev);
-pci_ers_result_t vfio_pci_core_aer_err_detected(struct pci_dev *pdev,
- pci_channel_state_t state);
ssize_t vfio_pci_core_do_io_rw(struct vfio_pci_core_device *vdev, bool test_mem,
void __iomem *io, char __user *buf,
loff_t off, size_t count, size_t x_start,
@@ -260,4 +259,40 @@ vfio_pci_core_get_iomap(struct vfio_pci_core_device *vdev, unsigned int bar)
int vfio_pci_dma_buf_iommufd_map(struct dma_buf_attachment *attachment,
struct phys_vec *phys);
+int vfio_pci_core_runtime_suspend(struct vfio_pci_core_device *vdev);
+int vfio_pci_core_runtime_resume(struct vfio_pci_core_device *vdev);
+pci_ers_result_t vfio_pci_core_aer_err_detected(struct vfio_pci_core_device *vdev);
+
+/*
+ * Per-driver PM/AER trampolines. driver_data points to the driver's private
+ * structure, which embeds a struct vfio_pci_core_device.
+ *
+ * @name: prefix for <name>_pm_ops and <name>_aer_err_detected
+ * @drv_type: type of the driver's private structure, including struct
+ * @member: member containing the struct vfio_pci_core_device
+ */
+#define VFIO_PCI_CORE_DEFINE_CALLBACKS(name, drv_type, member) \
+static int __maybe_unused name##_pm_suspend(struct device *dev) \
+{ \
+ drv_type *drvdata = dev_get_drvdata(dev); \
+ \
+ return vfio_pci_core_runtime_suspend(&drvdata->member); \
+} \
+static int __maybe_unused name##_pm_resume(struct device *dev) \
+{ \
+ drv_type *drvdata = dev_get_drvdata(dev); \
+ \
+ return vfio_pci_core_runtime_resume(&drvdata->member); \
+} \
+static const struct dev_pm_ops name##_pm_ops = { \
+ SET_RUNTIME_PM_OPS(name##_pm_suspend, name##_pm_resume, NULL) \
+}; \
+static pci_ers_result_t name##_aer_err_detected(struct pci_dev *pdev, \
+ pci_channel_state_t state) \
+{ \
+ drv_type *drvdata = pci_get_drvdata(pdev); \
+ \
+ return vfio_pci_core_aer_err_detected(&drvdata->member); \
+}
+
#endif /* VFIO_PCI_CORE_H */
diff --git a/include/linux/vga_switcheroo.h b/include/linux/vga_switcheroo.h
index 7e6ac0114d55..d7eee65664ab 100644
--- a/include/linux/vga_switcheroo.h
+++ b/include/linux/vga_switcheroo.h
@@ -31,8 +31,12 @@
#ifndef _LINUX_VGA_SWITCHEROO_H_
#define _LINUX_VGA_SWITCHEROO_H_
-#include <linux/fb.h>
+#include <linux/errno.h>
+#include <linux/types.h>
+struct device;
+struct dev_pm_domain;
+struct fb_info;
struct pci_dev;
/**
@@ -127,23 +131,28 @@ struct vga_switcheroo_handler {
* @set_gpu_state: do the equivalent of suspend/resume for the card.
* Mandatory. This should not cut power to the discrete GPU,
* which is the job of the handler
- * @reprobe: poll outputs.
- * Optional. This gets called after waking the GPU and switching
- * the outputs to it
* @can_switch: check if the device is in a position to switch now.
* Mandatory. The client should return false if a user space process
* has one of its device files open
+ * @pre_switch: prepare switch
+ * Optional. This gets called before switching the outputs to the
+ * GPU. Allows drivers to prepare for the switch.
+ * @post_switch: completes switch
+ * Optional. This gets called after waking the GPU and switching
+ * the outputs to it. Allows drivers to poll the switched outputs.
* @gpu_bound: notify the client id to audio client when the GPU is bound.
*
* Client callbacks. A client can be either a GPU or an audio device on a GPU.
- * The @set_gpu_state and @can_switch methods are mandatory, @reprobe may be
- * set to NULL. For audio clients, the @reprobe member is bogus.
- * OTOH, @gpu_bound is only for audio clients, and not used for GPU clients.
+ * The @set_gpu_state and @can_switch methods are mandatory, @pre_switch and
+ * @post_switch may be set to NULL. For audio clients, the @pre_switch and
+ * @post_switch members are bogus. OTOH, @gpu_bound is only for audio clients,
+ * and not used for GPU clients.
*/
struct vga_switcheroo_client_ops {
void (*set_gpu_state)(struct pci_dev *dev, enum vga_switcheroo_state);
- void (*reprobe)(struct pci_dev *dev);
bool (*can_switch)(struct pci_dev *dev);
+ void (*pre_switch)(struct pci_dev *dev);
+ void (*post_switch)(struct pci_dev *dev);
void (*gpu_bound)(struct pci_dev *dev, enum vga_switcheroo_client_id);
};
@@ -156,9 +165,6 @@ int vga_switcheroo_register_audio_client(struct pci_dev *pdev,
const struct vga_switcheroo_client_ops *ops,
struct pci_dev *vga_dev);
-void vga_switcheroo_client_fb_set(struct pci_dev *dev,
- struct fb_info *info);
-
int vga_switcheroo_register_handler(const struct vga_switcheroo_handler *handler,
enum vga_switcheroo_handler_flags_t handler_flags);
void vga_switcheroo_unregister_handler(void);
@@ -178,7 +184,6 @@ void vga_switcheroo_fini_domain_pm_ops(struct device *dev);
static inline void vga_switcheroo_unregister_client(struct pci_dev *dev) {}
static inline int vga_switcheroo_register_client(struct pci_dev *dev,
const struct vga_switcheroo_client_ops *ops, bool driver_power_control) { return 0; }
-static inline void vga_switcheroo_client_fb_set(struct pci_dev *dev, struct fb_info *info) {}
static inline int vga_switcheroo_register_handler(const struct vga_switcheroo_handler *handler,
enum vga_switcheroo_handler_flags_t handler_flags) { return 0; }
static inline int vga_switcheroo_register_audio_client(struct pci_dev *pdev,
diff --git a/include/linux/vgaarb.h b/include/linux/vgaarb.h
index 97129a1bbb7d..71a364669eaf 100644
--- a/include/linux/vgaarb.h
+++ b/include/linux/vgaarb.h
@@ -33,7 +33,8 @@ struct pci_dev *vga_default_device(void);
void vga_set_default_device(struct pci_dev *pdev);
int vga_remove_vgacon(struct pci_dev *pdev);
int vga_client_register(struct pci_dev *pdev,
- unsigned int (*set_decode)(struct pci_dev *pdev, bool state));
+ unsigned int (*set_decode)(void *data, bool state),
+ void *data);
#else /* CONFIG_VGA_ARB */
static inline void vga_set_legacy_decoding(struct pci_dev *pdev,
unsigned int decodes)
@@ -59,7 +60,8 @@ static inline int vga_remove_vgacon(struct pci_dev *pdev)
return 0;
}
static inline int vga_client_register(struct pci_dev *pdev,
- unsigned int (*set_decode)(struct pci_dev *pdev, bool state))
+ unsigned int (*set_decode)(void *data, bool state),
+ void *data)
{
return 0;
}
@@ -97,7 +99,7 @@ static inline int vga_get_uninterruptible(struct pci_dev *pdev,
static inline void vga_client_unregister(struct pci_dev *pdev)
{
- vga_client_register(pdev, NULL);
+ vga_client_register(pdev, NULL, NULL);
}
#endif /* LINUX_VGA_H */
diff --git a/include/linux/virtio_net.h b/include/linux/virtio_net.h
index c381b916c1b5..d6466f96cdd0 100644
--- a/include/linux/virtio_net.h
+++ b/include/linux/virtio_net.h
@@ -111,48 +111,38 @@ static inline int __virtio_net_hdr_to_skb(struct sk_buff *skb,
p_off = nh_min_len + thlen;
if (!pskb_may_pull(skb, p_off))
return -EINVAL;
- } else {
+ } else if (gso_type) {
/* gso packets without NEEDS_CSUM do not set transport_offset.
* probe and drop if does not match one of the above types.
*/
- if (gso_type && skb->network_header) {
- struct flow_keys_basic keys;
-
- if (!skb->protocol) {
- __be16 protocol = dev_parse_header_protocol(skb);
-
- if (!protocol)
- virtio_net_hdr_set_proto(skb, hdr);
- else if (!virtio_net_hdr_match_proto(protocol,
- hdr_gso_type))
- return -EINVAL;
- else
- skb->protocol = protocol;
- }
+ struct flow_keys_basic keys;
+
+ if (!skb->protocol) {
+ skb->protocol = dev_parse_header_protocol(skb);
+ if (!skb->protocol)
+ virtio_net_hdr_set_proto(skb, hdr);
+ }
retry:
- if (!skb_flow_dissect_flow_keys_basic(NULL, skb, &keys,
- NULL, 0, 0, 0,
- 0)) {
- /* UFO does not specify ipv4 or 6: try both */
- if (gso_type & SKB_GSO_UDP &&
- skb->protocol == htons(ETH_P_IP)) {
- skb->protocol = htons(ETH_P_IPV6);
- goto retry;
- }
- return -EINVAL;
+ if (!skb_flow_dissect_flow_keys_basic(NULL, skb, &keys,
+ NULL, 0, 0, 0,
+ 0)) {
+ /* UFO does not specify ipv4 or 6: try both */
+ if (gso_type & SKB_GSO_UDP &&
+ skb->protocol == htons(ETH_P_IP)) {
+ skb->protocol = htons(ETH_P_IPV6);
+ goto retry;
}
+ return -EINVAL;
+ }
- p_off = keys.control.thoff + thlen;
- if (!pskb_may_pull(skb, p_off) ||
- keys.basic.ip_proto != ip_proto)
- return -EINVAL;
+ p_off = keys.control.thoff + thlen;
+ if (!pskb_may_pull(skb, p_off) ||
+ keys.basic.ip_proto != ip_proto ||
+ !virtio_net_hdr_match_proto(keys.basic.n_proto,
+ hdr_gso_type))
+ return -EINVAL;
- skb_set_transport_header(skb, keys.control.thoff);
- } else if (gso_type) {
- p_off = nh_min_len + thlen;
- if (!pskb_may_pull(skb, p_off))
- return -EINVAL;
- }
+ skb_set_transport_header(skb, keys.control.thoff);
}
if (hdr_gso_type != VIRTIO_NET_HDR_GSO_NONE) {
diff --git a/include/linux/vmalloc.h b/include/linux/vmalloc.h
index aed121d729b0..034a693777ca 100644
--- a/include/linux/vmalloc.h
+++ b/include/linux/vmalloc.h
@@ -3,6 +3,7 @@
#define _LINUX_VMALLOC_H
#include <linux/alloc_tag.h>
+#include <linux/cleanup.h>
#include <linux/sched.h>
#include <linux/spinlock.h>
#include <linux/init.h>
@@ -38,6 +39,7 @@ struct iov_iter; /* in uio.h */
#define VM_DEFER_KMEMLEAK 0
#endif
#define VM_SPARSE 0x00001000 /* sparse vm_area. not all pages are present. */
+#define VM_REQUIRE_HUGE_VMAP 0x00002000 /* huge page mapping or nothing */
/* bits [20..32] reserved for arch specific ioremap internals */
@@ -214,6 +216,8 @@ void *__must_check vrealloc_node_align_noprof(const void *p, size_t size,
extern void vfree(const void *addr);
extern void vfree_atomic(const void *addr);
+DEFINE_FREE(vfree, void *, if (!IS_ERR_OR_NULL(_T)) vfree(_T))
+
extern void *vmap(struct page **pages, unsigned int count,
unsigned long flags, pgprot_t prot);
void *vmap_pfn(unsigned long *pfns, unsigned int count, pgprot_t prot);
diff --git a/include/linux/vmemmap-optimization.h b/include/linux/vmemmap-optimization.h
new file mode 100644
index 000000000000..fa9e9abd6656
--- /dev/null
+++ b/include/linux/vmemmap-optimization.h
@@ -0,0 +1,115 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * vmemmap-optimization.h
+ *
+ * Generic vmemmap optimization declarations.
+ *
+ * Author: Muchun Song <songmuchun@bytedance.com>
+ */
+#ifndef _LINUX_VMEMMAP_OPTIMIZATION_H
+#define _LINUX_VMEMMAP_OPTIMIZATION_H
+
+#include <linux/align.h>
+#include <linux/log2.h>
+#include <linux/mmdebug.h>
+#include <linux/mmzone.h>
+
+/*
+ * HugeTLB Vmemmap Optimization (HVO) requires struct pages of the head page to
+ * be naturally aligned with regard to the folio size.
+ *
+ * HVO which is only active if the size of struct page is a power of 2.
+ */
+#define MAX_FOLIO_VMEMMAP_ALIGN \
+ (IS_ENABLED(CONFIG_VMEMMAP_OPTIMIZATION) && \
+ is_power_of_2(sizeof(struct page)) ? \
+ MAX_FOLIO_NR_PAGES * sizeof(struct page) : 0)
+
+/* The number of retained vmemmap pages with HVO enabled. */
+#define VMEMMAP_OPTIMIZATION_PAGES 1
+#define VMEMMAP_OPTIMIZATION_NR_STRUCT_PAGES \
+ (VMEMMAP_OPTIMIZATION_PAGES * PAGE_SIZE / sizeof(struct page))
+#define VMEMMAP_OPTIMIZATION_MIN_ORDER (ilog2(VMEMMAP_OPTIMIZATION_NR_STRUCT_PAGES) + 1)
+
+#ifdef CONFIG_VMEMMAP_OPTIMIZATION
+static inline unsigned int section_compound_order(const struct mem_section *section)
+{
+ return section->compound_page_order;
+}
+
+static inline void section_set_compound_order(struct mem_section *section,
+ unsigned int order)
+{
+ VM_WARN_ON(section_compound_order(section) && order &&
+ section_compound_order(section) != order);
+ section->compound_page_order = order;
+}
+
+static inline void section_set_compound_order_range(unsigned long pfn,
+ unsigned long nr_pages, unsigned int order)
+{
+ unsigned long section_nr = pfn_to_section_nr(pfn);
+
+ if (!IS_ALIGNED(pfn | nr_pages, PAGES_PER_SECTION))
+ return;
+
+ for (unsigned long i = 0; i < nr_pages / PAGES_PER_SECTION; i++)
+ section_set_compound_order(__nr_to_section(section_nr + i), order);
+}
+
+static inline unsigned int pfn_to_section_compound_order(unsigned long pfn)
+{
+ return section_compound_order(__pfn_to_section(pfn));
+}
+
+struct page *vmemmap_shared_tail_page(unsigned int order, struct zone *zone);
+#else
+static inline unsigned int section_compound_order(const struct mem_section *section)
+{
+ return 0;
+}
+
+static inline void section_set_compound_order(struct mem_section *section,
+ unsigned int order)
+{
+}
+
+static inline void section_set_compound_order_range(unsigned long pfn,
+ unsigned long nr_pages, unsigned int order)
+{
+}
+
+static inline unsigned int pfn_to_section_compound_order(unsigned long pfn)
+{
+ return 0;
+}
+
+static inline struct page *vmemmap_shared_tail_page(unsigned int order,
+ struct zone *zone)
+{
+ return NULL;
+}
+#endif /* CONFIG_VMEMMAP_OPTIMIZATION */
+
+static inline bool vmemmap_optimizable_pfn(unsigned long pfn)
+{
+ const unsigned int order = pfn_to_section_compound_order(pfn);
+ const unsigned long nr_pages = 1UL << order;
+
+ if (!is_power_of_2(sizeof(struct page)))
+ return false;
+
+ return (pfn & (nr_pages - 1)) >= VMEMMAP_OPTIMIZATION_NR_STRUCT_PAGES;
+}
+
+static inline bool vmemmap_optimizable_order(unsigned int order)
+{
+ if (!IS_ENABLED(CONFIG_VMEMMAP_OPTIMIZATION))
+ return false;
+
+ if (!is_power_of_2(sizeof(struct page)))
+ return false;
+
+ return order >= VMEMMAP_OPTIMIZATION_MIN_ORDER;
+}
+#endif /* _LINUX_VMEMMAP_OPTIMIZATION_H */
diff --git a/include/linux/wait.h b/include/linux/wait.h
index 7e215330199c..c2af98b0074d 100644
--- a/include/linux/wait.h
+++ b/include/linux/wait.h
@@ -556,7 +556,7 @@ do { \
} \
\
__ret = ___wait_event(wq_head, condition, state, 0, 0, \
- if (!__t.task) { \
+ if (!hrtimer_sleeper_task_get(&__t)) { \
__ret = -ETIME; \
break; \
} \
diff --git a/include/linux/wait_bit.h b/include/linux/wait_bit.h
index 553d7b23e3ad..af077ed4caf6 100644
--- a/include/linux/wait_bit.h
+++ b/include/linux/wait_bit.h
@@ -433,6 +433,32 @@ do { \
})
/**
+ * wait_var_event_state - wait for a variable to be updated and notified
+ * @var: the address of variable being waited on
+ * @condition: the condition to wait for
+ * @state: the task state to sleep in, %TASK_UNINTERRUPTIBLE etc.
+ *
+ * Wait for a @condition to be true, only re-checking when a wake up is
+ * received for the given @var (an arbitrary kernel address which need
+ * not be directly related to the given condition, but usually is).
+ *
+ * Returns 0 if the condition became true, or %-ERESTARTSYS if a signal
+ * arrived which @state allows to interrupt.
+ *
+ * The condition should normally use smp_load_acquire() or a similarly
+ * ordered access to ensure that any changes to memory made before the
+ * condition became true will be visible after the wait completes.
+ */
+#define wait_var_event_state(var, condition, state) \
+({ \
+ int __ret = 0; \
+ might_sleep(); \
+ if (!(condition)) \
+ __ret = ___wait_var_event(var, condition, (state), 0, 0, schedule()); \
+ __ret; \
+})
+
+/**
* wait_var_event_any_lock - wait for a variable to be updated under a lock
* @var: the address of the variable being waited on
* @condition: condition to wait for
diff --git a/include/linux/wwan.h b/include/linux/wwan.h
index 1e0e2cb53579..23a8a8ee473d 100644
--- a/include/linux/wwan.h
+++ b/include/linux/wwan.h
@@ -57,6 +57,14 @@ struct wwan_port;
* @tx_blocking: Optional blocking routine that sends WWAN port protocol data
* to the device.
* @tx_poll: Optional routine that sets additional TX poll flags.
+ * @dtr_rts: Optional routine that updates the modem control lines to match
+ * @mdmbits, the TIOCM_* output bits (DTR, RTS, OUT1, OUT2, LOOP)
+ * currently set for the port. Called when the port is first opened
+ * and ->start() has succeeded, on last close if HUPCL is set, when
+ * the port is removed while still open, and when TIOCMSET, TIOCMBIS
+ * or TIOCMBIC changes DTR or RTS. Only called for WWAN_PORT_AT ports,
+ * as only the AT (DUN) port carries the modem's virtual RS-232
+ * control signals.
*
* The wwan_port_ops structure contains a list of low-level operations
* that control a WWAN port device. All functions are mandatory unless specified.
@@ -70,6 +78,7 @@ struct wwan_port_ops {
int (*tx_blocking)(struct wwan_port *port, struct sk_buff *skb);
__poll_t (*tx_poll)(struct wwan_port *port, struct file *filp,
poll_table *wait);
+ void (*dtr_rts)(struct wwan_port *port, unsigned int mdmbits);
};
/** struct wwan_port_caps - The WWAN port capbilities
diff --git a/include/linux/xattr.h b/include/linux/xattr.h
index 54ac3cbc133f..4cc4257de084 100644
--- a/include/linux/xattr.h
+++ b/include/linux/xattr.h
@@ -47,7 +47,7 @@ struct xattr_handler {
struct inode *inode, const char *name, void *buffer,
size_t size);
int (*set)(const struct xattr_handler *,
- struct mnt_idmap *idmap, struct dentry *dentry,
+ const struct mnt_idmap *idmap, struct dentry *dentry,
struct inode *inode, const char *name, const void *buffer,
size_t size, int flags);
};
@@ -77,25 +77,25 @@ struct xattr {
};
ssize_t __vfs_getxattr(struct dentry *, struct inode *, const char *, void *, size_t);
-ssize_t vfs_getxattr(struct mnt_idmap *, struct dentry *, const char *,
+ssize_t vfs_getxattr(const struct mnt_idmap *, struct dentry *, const char *,
void *, size_t);
ssize_t vfs_listxattr(struct dentry *d, char *list, size_t size);
-int __vfs_setxattr(struct mnt_idmap *, struct dentry *, struct inode *,
+int __vfs_setxattr(const struct mnt_idmap *, struct dentry *, struct inode *,
const char *, const void *, size_t, int);
-int __vfs_setxattr_noperm(struct mnt_idmap *, struct dentry *,
+int __vfs_setxattr_noperm(const struct mnt_idmap *, struct dentry *,
const char *, const void *, size_t, int);
-int __vfs_setxattr_locked(struct mnt_idmap *, struct dentry *,
+int __vfs_setxattr_locked(const struct mnt_idmap *, struct dentry *,
const char *, const void *, size_t, int,
struct delegated_inode *);
-int vfs_setxattr(struct mnt_idmap *, struct dentry *, const char *,
+int vfs_setxattr(const struct mnt_idmap *, struct dentry *, const char *,
const void *, size_t, int);
-int __vfs_removexattr(struct mnt_idmap *, struct dentry *, const char *);
-int __vfs_removexattr_locked(struct mnt_idmap *, struct dentry *,
+int __vfs_removexattr(const struct mnt_idmap *, struct dentry *, const char *);
+int __vfs_removexattr_locked(const struct mnt_idmap *, struct dentry *,
const char *, struct delegated_inode *);
-int vfs_removexattr(struct mnt_idmap *, struct dentry *, const char *);
+int vfs_removexattr(const struct mnt_idmap *, struct dentry *, const char *);
ssize_t generic_listxattr(struct dentry *dentry, char *buffer, size_t buffer_size);
-int vfs_getxattr_alloc(struct mnt_idmap *idmap,
+int vfs_getxattr_alloc(const struct mnt_idmap *idmap,
struct dentry *dentry, const char *name,
char **xattr_value, size_t size, gfp_t flags);
diff --git a/include/linux/zsmalloc.h b/include/linux/zsmalloc.h
index 478410c880b1..5b7298a5026b 100644
--- a/include/linux/zsmalloc.h
+++ b/include/linux/zsmalloc.h
@@ -40,10 +40,6 @@ unsigned int zs_lookup_class_index(struct zs_pool *pool, unsigned int size);
void zs_pool_stats(struct zs_pool *pool, struct zs_pool_stats *stats);
-void *zs_obj_read_begin(struct zs_pool *pool, unsigned long handle,
- size_t mem_len, void *local_copy);
-void zs_obj_read_end(struct zs_pool *pool, unsigned long handle,
- size_t mem_len, void *handle_mem);
void zs_obj_read_sg_begin(struct zs_pool *pool, unsigned long handle,
struct scatterlist *sg, size_t mem_len);
void zs_obj_read_sg_end(struct zs_pool *pool, unsigned long handle);
diff --git a/include/linux/zswap.h b/include/linux/zswap.h
index 30c193a1207e..df6cafbe95dc 100644
--- a/include/linux/zswap.h
+++ b/include/linux/zswap.h
@@ -27,7 +27,7 @@ struct zswap_lruvec_state {
unsigned long zswap_total_pages(void);
bool zswap_store(struct folio *folio);
int zswap_load(struct folio *folio);
-void zswap_invalidate(swp_entry_t swp);
+void zswap_invalidate(int type, pgoff_t offset, unsigned long nr_entries);
int zswap_swapon(int type, unsigned long nr_pages);
void zswap_swapoff(int type);
void zswap_memcg_offline_cleanup(struct mem_cgroup *memcg);
@@ -49,7 +49,11 @@ static inline int zswap_load(struct folio *folio)
return -ENOENT;
}
-static inline void zswap_invalidate(swp_entry_t swp) {}
+static inline void zswap_invalidate(int type, pgoff_t offset,
+ unsigned long nr_entries)
+{
+}
+
static inline int zswap_swapon(int type, unsigned long nr_pages)
{
return 0;
diff --git a/include/math-emu/op-common.h b/include/math-emu/op-common.h
index 8ce066c035cf..1d1ce5c08efc 100644
--- a/include/math-emu/op-common.h
+++ b/include/math-emu/op-common.h
@@ -135,6 +135,24 @@ do { \
else \
{ \
/* we've got a denormalized number */ \
+ int _FP_PACK_CANONICAL_is_tiny = 1; \
+ if (_FP_TININESS_AFTER_ROUNDING && X##_e == 0) \
+ { \
+ /* Architectures that detect tininess after rounding \
+ only signal underflow if the result is still \
+ subnormal once rounded as if the exponent range \
+ were unbounded. Round a copy to find out. */ \
+ FP_DECL_##fs(_FP_PACK_CANONICAL_T); \
+ /* The class field is not used by the rounding below, \
+ and is unused entirely where this block is dead. */ \
+ (void)_FP_PACK_CANONICAL_T##_c; \
+ _FP_FRAC_COPY_##wc(_FP_PACK_CANONICAL_T, X); \
+ _FP_PACK_CANONICAL_T##_s = X##_s; \
+ _FP_PACK_CANONICAL_T##_e = X##_e; \
+ _FP_ROUND(wc, _FP_PACK_CANONICAL_T); \
+ if (_FP_FRAC_OVERP_##wc(fs, _FP_PACK_CANONICAL_T)) \
+ _FP_PACK_CANONICAL_is_tiny = 0; \
+ } \
X##_e = -X##_e + 1; \
if (X##_e <= _FP_WFRACBITS_##fs) \
{ \
@@ -161,8 +179,9 @@ do { \
_FP_FRAC_SRL_##wc(X, _FP_WORKBITS); \
} \
} \
- if ((FP_CUR_EXCEPTIONS & FP_EX_INEXACT) || \
- (FP_TRAPPING_EXCEPTIONS & FP_EX_UNDERFLOW)) \
+ if (_FP_PACK_CANONICAL_is_tiny \
+ && ((FP_CUR_EXCEPTIONS & FP_EX_INEXACT) || \
+ (FP_TRAPPING_EXCEPTIONS & FP_EX_UNDERFLOW))) \
FP_SET_EXCEPTION(FP_EX_UNDERFLOW); \
} \
else \
diff --git a/include/math-emu/soft-fp.h b/include/math-emu/soft-fp.h
index 5650c1628383..02ada0a9fca1 100644
--- a/include/math-emu/soft-fp.h
+++ b/include/math-emu/soft-fp.h
@@ -31,6 +31,14 @@
#include <endian.h>
#endif
+/* Whether the architecture determines tininess of a floating-point
+ result after rounding rather than before it. IEEE 754 permits either
+ but requires the same choice for every operation, so this has to agree
+ with what the hardware does for the results it produces itself. */
+#ifndef _FP_TININESS_AFTER_ROUNDING
+#define _FP_TININESS_AFTER_ROUNDING 0
+#endif
+
#define _FP_WORKBITS 3
#define _FP_WORK_LSB ((_FP_W_TYPE)1 << 3)
#define _FP_WORK_ROUND ((_FP_W_TYPE)1 << 2)
diff --git a/include/media/ipu-bridge.h b/include/media/ipu-bridge.h
index 16fac765456e..3ef94c2b7678 100644
--- a/include/media/ipu-bridge.h
+++ b/include/media/ipu-bridge.h
@@ -17,13 +17,28 @@
#define IPU_SENSOR_ROTATION_NORMAL 0
#define IPU_SENSOR_ROTATION_INVERTED 1
-#define IPU_SENSOR_CONFIG(_HID, _NR, ...) \
- (const struct ipu_sensor_config) { \
- .hid = _HID, \
- .nr_link_freqs = _NR, \
- .link_freqs = { __VA_ARGS__ } \
+/* Flags for struct ipu_sensor_config */
+/* The sensor's CSI-2 transmitter needs a non-continuous clock */
+#define IPU_BR_FL_CSI2_CLK_NONCONTINUOUS BIT(0)
+
+/*
+ * Sensor config specific to one or more IPUs, identified by their PCI product
+ * IDs, with flags describing what the sensor needs there. Entries for one HID
+ * must be adjacent in ipu_supported_sensors[], with the IPU-specific ones
+ * before the generic one.
+ */
+#define IPU_SENSOR_CONFIG_MATCH_FL(_HID, _IDS, _FLAGS, _NR, ...) \
+ (const struct ipu_sensor_config) { \
+ .hid = _HID, \
+ .pci_ids = _IDS, \
+ .flags = _FLAGS, \
+ .nr_link_freqs = _NR, \
+ .link_freqs = { __VA_ARGS__ } \
}
+#define IPU_SENSOR_CONFIG(_HID, _NR, ...) \
+ IPU_SENSOR_CONFIG_MATCH_FL(_HID, NULL, 0, _NR, __VA_ARGS__)
+
#define NODE_SENSOR(_HID, _PROPS) \
(const struct software_node) { \
.name = _HID, \
@@ -64,6 +79,24 @@ enum ipu_sensor_swnodes {
SWNODE_COUNT
};
+enum ipu_bridge_ep_props {
+ IPU_BRIDGE_EP_BUS_TYPE,
+ IPU_BRIDGE_EP_DATA_LANES,
+ IPU_BRIDGE_EP_REMOTE_EP,
+ IPU_BRIDGE_EP_LINK_FREQUENCIES,
+ IPU_BRIDGE_EP_CLOCK_NONCONTINUOUS,
+ IPU_BRIDGE_EP_NUM_OF,
+ IPU_BRIDGE_EP_NUM_ENTRIES
+};
+
+/*
+ * Get the index of the next property in a property array, with a given maximum
+ * value.
+ */
+#define IPU_BRIDGE_NEXT_PROPERTY(index, max) \
+ (WARN_ON((index) > IPU_BRIDGE_##max) ? \
+ IPU_BRIDGE_##max : (index)++)
+
/* Data representation as it is in ACPI SSDB buffer */
struct ipu_sensor_ssdb {
u8 version;
@@ -102,6 +135,7 @@ struct ipu_property_names {
char data_lanes[11];
char remote_endpoint[16];
char link_frequencies[17];
+ char clock_noncontinuous[20];
};
struct ipu_node_names {
@@ -115,6 +149,9 @@ struct ipu_node_names {
struct ipu_sensor_config {
const char *hid;
+ /* Zero-terminated list of IPU PCI product IDs, NULL for any IPU */
+ const u16 *pci_ids;
+ const u32 flags;
const u8 nr_link_freqs;
const u64 link_freqs[MAX_NUM_LINK_FREQS];
};
@@ -141,7 +178,7 @@ struct ipu_sensor {
const char *vcm_type;
struct ipu_property_names prop_names;
- struct property_entry ep_properties[5];
+ struct property_entry ep_properties[IPU_BRIDGE_EP_NUM_ENTRIES];
struct property_entry dev_properties[5];
struct property_entry ipu_properties[3];
struct property_entry ivsc_properties[1];
@@ -160,6 +197,8 @@ typedef int (*ipu_parse_sensor_fwnode_t)(struct acpi_device *adev,
struct ipu_bridge {
struct device *dev;
+ /* PCI product ID of the IPU, 0 if it is not a PCI device */
+ u16 pci_id;
ipu_parse_sensor_fwnode_t parse_sensor_fwnode;
char ipu_node_name[ACPI_ID_LEN];
struct software_node ipu_hid_node;
@@ -169,11 +208,13 @@ struct ipu_bridge {
};
#if IS_ENABLED(CONFIG_IPU_BRIDGE)
+struct pci_dev *ipu_bridge_get_ipu6(void);
int ipu_bridge_init(struct device *dev,
ipu_parse_sensor_fwnode_t parse_sensor_fwnode);
int ipu_bridge_parse_ssdb(struct acpi_device *adev, struct ipu_sensor *sensor);
int ipu_bridge_instantiate_vcm(struct device *sensor);
#else
+static inline struct pci_dev *ipu_bridge_get_ipu6(void) { return NULL; }
/* Use a define to avoid the @parse_sensor_fwnode argument getting evaluated */
#define ipu_bridge_init(dev, parse_sensor_fwnode) (0)
static inline int ipu_bridge_instantiate_vcm(struct device *s) { return 0; }
diff --git a/include/media/ipu6-pci-table.h b/include/media/ipu6-pci-table.h
index 0899d9d2f978..4c7e724ea15e 100644
--- a/include/media/ipu6-pci-table.h
+++ b/include/media/ipu6-pci-table.h
@@ -14,6 +14,9 @@
#define PCI_DEVICE_ID_INTEL_IPU6EP_ADLN 0x462e
#define PCI_DEVICE_ID_INTEL_IPU6EP_RPLP 0xa75d
#define PCI_DEVICE_ID_INTEL_IPU6EP_MTL 0x7d19
+#define PCI_DEVICE_ID_INTEL_IPU7 0x645d
+#define PCI_DEVICE_ID_INTEL_IPU7P5 0xb05d
+#define PCI_DEVICE_ID_INTEL_IPU8 0xd719
static const struct pci_device_id ipu6_pci_tbl[] = {
{ PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_IPU6) },
@@ -22,6 +25,9 @@ static const struct pci_device_id ipu6_pci_tbl[] = {
{ PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_IPU6EP_ADLN) },
{ PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_IPU6EP_RPLP) },
{ PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_IPU6EP_MTL) },
+ { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_IPU7) },
+ { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_IPU7P5) },
+ { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_IPU8) },
{ }
};
diff --git a/include/media/rc-map.h b/include/media/rc-map.h
index d95ed3e96de2..f167c37179c8 100644
--- a/include/media/rc-map.h
+++ b/include/media/rc-map.h
@@ -148,7 +148,6 @@ struct rc_map_table {
* @scan: pointer to struct &rc_map_table
* @size: Max number of entries
* @len: Number of entries that are in use
- * @alloc: size of \*scan, in bytes
* @rc_proto: type of the remote controller protocol, as defined at
* enum &rc_proto
* @name: name of the key map table
@@ -158,7 +157,6 @@ struct rc_map {
struct rc_map_table *scan;
unsigned int size;
unsigned int len;
- unsigned int alloc;
enum rc_proto rc_proto;
const char *name;
spinlock_t lock;
diff --git a/include/media/v4l2-common.h b/include/media/v4l2-common.h
index edd416178c33..33f5713734cb 100644
--- a/include/media/v4l2-common.h
+++ b/include/media/v4l2-common.h
@@ -554,15 +554,80 @@ static inline bool v4l2_is_format_bayer(const struct v4l2_format_info *f)
const struct v4l2_format_info *v4l2_format_info(u32 format);
void v4l2_apply_frmsize_constraints(u32 *width, u32 *height,
const struct v4l2_frmsize_stepwise *frmsize);
-int v4l2_fill_pixfmt(struct v4l2_pix_format *pixfmt, u32 pixelformat,
- u32 width, u32 height);
-int v4l2_fill_pixfmt_mp(struct v4l2_pix_format_mplane *pixfmt, u32 pixelformat,
- u32 width, u32 height);
-/* @stride_alignment is a power of 2 value in bytes */
+
+/**
+ * v4l2_fill_pixfmt_aligned - Fill in a &struct v4l2_pix_format with stride
+ * alignment requirements
+ *
+ * @pixfmt: pointer to the &struct v4l2_pix_format to be filled
+ * @pixelformat: the V4L2 pixel format (V4L2_PIX_FMT_*)
+ * @width: image width in pixels
+ * @height: image height in pixels
+ * @stride_alignment: stride alignment in bytes, must be a power of 2
+ *
+ * Fills all fields of @pixfmt for the given pixel format, dimensions, and
+ * stride alignment. Only formats stored in a single memory plane are
+ * supported; returns -EINVAL for multi-memory-plane formats.
+ *
+ * @pixfmt->bytesperline is set to the stride of the primary (plane 0) plane,
+ * rounded up to a multiple of @stride_alignment. For formats that store
+ * multiple component planes in a single memory buffer (e.g. YUV420), the
+ * alignment applied to each component plane's stride is scaled relative to
+ * @stride_alignment so that the chroma stride remains consistently derivable
+ * from the luma stride. @pixfmt->bytesperline therefore reflects only the
+ * primary plane stride.
+ *
+ * @pixfmt->sizeimage is set to the total size in bytes of all planes.
+ *
+ * Return: 0 on success, -EINVAL if @pixelformat is unknown or uses multiple
+ * memory planes.
+ */
+int v4l2_fill_pixfmt_aligned(struct v4l2_pix_format *pixfmt, u32 pixelformat,
+ u32 width, u32 height, u8 stride_alignment);
+
+static inline int v4l2_fill_pixfmt(struct v4l2_pix_format *pixfmt,
+ u32 pixelformat, u32 width, u32 height)
+{
+ return v4l2_fill_pixfmt_aligned(pixfmt, pixelformat, width, height, 1);
+}
+
+/**
+ * v4l2_fill_pixfmt_mp_aligned - Fill in a &struct v4l2_pix_format_mplane with
+ * stride alignment requirements.
+ *
+ * @pixfmt: pointer to the &struct v4l2_pix_format_mplane to be filled
+ * @pixelformat: the V4L2 pixel format (V4L2_PIX_FMT_*)
+ * @width: image width in pixels
+ * @height: image height in pixels
+ * @stride_alignment: stride alignment in bytes; must be a power of 2
+ *
+ * Fills all fields of @pixfmt for the given pixel format, dimensions, and
+ * stride alignment.
+ *
+ * For formats stored in a single memory plane (mem_planes == 1), the
+ * behaviour matches v4l2_fill_pixfmt_aligned(): plane_fmt[0].bytesperline
+ * is set to the primary plane stride. The strides of all components are
+ * aligned to the @stride_alignment. To keep the chroma strides consistently
+ * derivable from the luma stride, strides may be aligned to a multiple of
+ * the @stride_alignment instead. plane_fmt[0].sizeimage covers all
+ * component planes.
+ *
+ * For formats with multiple memory planes (mem_planes > 1), each plane's
+ * bytesperline is independently rounded up to @stride_alignment, and each
+ * plane's sizeimage is set to bytesperline multiplied by the plane height.
+ *
+ * Return: 0 on success, -EINVAL if @pixelformat is unknown.
+ */
int v4l2_fill_pixfmt_mp_aligned(struct v4l2_pix_format_mplane *pixfmt,
u32 pixelformat, u32 width, u32 height,
u8 stride_alignment);
+static inline int v4l2_fill_pixfmt_mp(struct v4l2_pix_format_mplane *pixfmt,
+ u32 pixelformat, u32 width, u32 height)
+{
+ return v4l2_fill_pixfmt_mp_aligned(pixfmt, pixelformat, width, height, 1);
+}
+
/**
* v4l2_get_link_freq - Get link rate from transmitter
*
diff --git a/include/media/v4l2-ctrls.h b/include/media/v4l2-ctrls.h
index 327976b14d50..cec9217d97ac 100644
--- a/include/media/v4l2-ctrls.h
+++ b/include/media/v4l2-ctrls.h
@@ -834,6 +834,9 @@ bool v4l2_ctrl_radio_filter(const struct v4l2_ctrl *ctrl);
*
* @ncontrols: The number of controls in this cluster.
* @controls: The cluster control array of size @ncontrols.
+ *
+ * If controls[0] is NULL, then this function does nothing and just
+ * returns.
*/
void v4l2_ctrl_cluster(unsigned int ncontrols, struct v4l2_ctrl **controls);
@@ -845,6 +848,9 @@ void v4l2_ctrl_cluster(unsigned int ncontrols, struct v4l2_ctrl **controls);
* @ncontrols: The number of controls in this cluster.
* @controls: The cluster control array of size @ncontrols. The first control
* must be the 'auto' control (e.g. autogain, autoexposure, etc.)
+ *
+ * If controls[0] is NULL, then this function does nothing and just
+ * returns.
* @manual_val: The value for the first control in the cluster that equals the
* manual setting.
* @set_volatile: If true, then all controls except the first auto control will
diff --git a/include/media/v4l2-dv-timings.h b/include/media/v4l2-dv-timings.h
index 2b42e5d81f9e..de5ef825a6c6 100644
--- a/include/media/v4l2-dv-timings.h
+++ b/include/media/v4l2-dv-timings.h
@@ -252,6 +252,20 @@ v4l2_hdmi_rx_colorimetry(const struct hdmi_avi_infoframe *avi,
const struct hdmi_vendor_infoframe *hdmi,
unsigned int height);
+/*
+ * The time in milliseconds that the HPD should be pulled low when writing
+ * a new EDID. This will tell the HDMI source that the EDID was changed and
+ * that it has to be re-read.
+ *
+ * The source is supposed to re-read the EDID if the HPD is low for more than
+ * 100 ms, but in practice the sink should pull it low for a bit longer due
+ * to clock differences and imprecise video source implementations.
+ *
+ * Practice has shown that setting the delay to HZ / 7 (approx 143 ms) works
+ * well.
+ */
+#define V4L2_SET_EDID_HPD_LOW_JIFFIES (HZ / 7)
+
unsigned int v4l2_num_edid_blocks(const u8 *edid, unsigned int max_blocks);
u16 v4l2_get_edid_phys_addr(const u8 *edid, unsigned int size,
unsigned int *offset);
diff --git a/include/media/v4l2-hevc.h b/include/media/v4l2-hevc.h
new file mode 100644
index 000000000000..973c96be16be
--- /dev/null
+++ b/include/media/v4l2-hevc.h
@@ -0,0 +1,41 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * Helper functions for HEVC stateless codecs.
+ */
+
+#ifndef _MEDIA_V4L2_HEVC_H
+#define _MEDIA_V4L2_HEVC_H
+
+#include <linux/minmax.h>
+#include <media/v4l2-ctrls.h>
+
+/**
+ * v4l2_hevc_pps_num_tile_columns - number of HEVC tile columns, bounded
+ * @pps: the V4L2 HEVC PPS control
+ *
+ * Return the number of tile columns (num_tile_columns_minus1 + 1) clamped to
+ * the capacity of column_width_minus1[]. The control validation already
+ * rejects out-of-range counts; this keeps the consuming drivers bounded too.
+ */
+static inline unsigned int
+v4l2_hevc_pps_num_tile_columns(const struct v4l2_ctrl_hevc_pps *pps)
+{
+ return min_t(unsigned int, pps->num_tile_columns_minus1 + 1,
+ ARRAY_SIZE(pps->column_width_minus1));
+}
+
+/**
+ * v4l2_hevc_pps_num_tile_rows - number of HEVC tile rows, bounded
+ * @pps: the V4L2 HEVC PPS control
+ *
+ * Return the number of tile rows (num_tile_rows_minus1 + 1) clamped to the
+ * capacity of row_height_minus1[].
+ */
+static inline unsigned int
+v4l2_hevc_pps_num_tile_rows(const struct v4l2_ctrl_hevc_pps *pps)
+{
+ return min_t(unsigned int, pps->num_tile_rows_minus1 + 1,
+ ARRAY_SIZE(pps->row_height_minus1));
+}
+
+#endif /* _MEDIA_V4L2_HEVC_H */
diff --git a/include/media/v4l2-subdev.h b/include/media/v4l2-subdev.h
index d256b7ec8f84..5796e52678b9 100644
--- a/include/media/v4l2-subdev.h
+++ b/include/media/v4l2-subdev.h
@@ -735,6 +735,14 @@ struct v4l2_subdev_state {
};
/**
+ * struct v4l2_subdev_client_info - Sub-device client information
+ * @caps: bitmask of ``V4L2_SUBDEV_CLIENT_CAP_*``
+ */
+struct v4l2_subdev_client_info {
+ u64 caps;
+};
+
+/**
* struct v4l2_subdev_pad_ops - v4l2-subdev pad level operations
*
* @enum_mbus_code: callback for VIDIOC_SUBDEV_ENUM_MBUS_CODE() ioctl handler
@@ -747,11 +755,14 @@ struct v4l2_subdev_state {
*
* @get_fmt: callback for VIDIOC_SUBDEV_G_FMT() ioctl handler code.
*
- * @set_fmt: callback for VIDIOC_SUBDEV_S_FMT() ioctl handler code.
+ * @set_fmt: callback for VIDIOC_SUBDEV_S_FMT() ioctl handler code. The ci
+ * pointer may be NULL for in-kernel calls.
*
* @get_selection: callback for VIDIOC_SUBDEV_G_SELECTION() ioctl handler code.
+ * The ci pointer may be NULL for in-kernel calls.
*
* @set_selection: callback for VIDIOC_SUBDEV_S_SELECTION() ioctl handler code.
+ * The ci pointer may be NULL for in-kernel calls.
*
* @get_frame_interval: callback for VIDIOC_SUBDEV_G_FRAME_INTERVAL()
* ioctl handler code.
@@ -814,6 +825,11 @@ struct v4l2_subdev_state {
* V4L2_SUBDEV_CAP_STREAMS sub-device capability flag can ignore the mask
* argument.
*
+ * Due to device constraints, starting the requested streams may result in
+ * additional streams also being started by the driver. Streams that are
+ * started and stopped together due to the nature of the hardware are
+ * called a stream group.
+ *
* @disable_streams: Disable the streams defined in streams_mask on the given
* source pad. Subdevs that implement this operation must use the active
* state management provided by the subdev core (enabled through a call to
@@ -823,6 +839,9 @@ struct v4l2_subdev_state {
* Drivers that support only a single stream without setting the
* V4L2_SUBDEV_CAP_STREAMS sub-device capability flag can ignore the mask
* argument.
+ *
+ * When the requested stream are part of a stream group, they will be
+ * stopped once all streams in the group are stopped.
*/
struct v4l2_subdev_pad_ops {
int (*enum_mbus_code)(struct v4l2_subdev *sd,
@@ -838,12 +857,15 @@ struct v4l2_subdev_pad_ops {
struct v4l2_subdev_state *state,
struct v4l2_subdev_format *format);
int (*set_fmt)(struct v4l2_subdev *sd,
+ const struct v4l2_subdev_client_info *ci,
struct v4l2_subdev_state *state,
struct v4l2_subdev_format *format);
int (*get_selection)(struct v4l2_subdev *sd,
+ const struct v4l2_subdev_client_info *ci,
struct v4l2_subdev_state *state,
struct v4l2_subdev_selection *sel);
int (*set_selection)(struct v4l2_subdev *sd,
+ const struct v4l2_subdev_client_info *ci,
struct v4l2_subdev_state *state,
struct v4l2_subdev_selection *sel);
int (*get_frame_interval)(struct v4l2_subdev *sd,
@@ -1122,14 +1144,14 @@ struct v4l2_subdev {
* @vfh: pointer to &struct v4l2_fh
* @state: pointer to &struct v4l2_subdev_state
* @owner: module pointer to the owner of this file handle
- * @client_caps: bitmask of ``V4L2_SUBDEV_CLIENT_CAP_*``
+ * @ci: sub-device client info related to this file handle
*/
struct v4l2_subdev_fh {
struct v4l2_fh vfh;
struct module *owner;
#if defined(CONFIG_VIDEO_V4L2_SUBDEV_API)
struct v4l2_subdev_state *state;
- u64 client_caps;
+ struct v4l2_subdev_client_info ci;
#endif
};
@@ -1935,14 +1957,16 @@ extern const struct v4l2_subdev_ops v4l2_subdev_call_wrappers;
int __result; \
if (!__sd) \
__result = -ENODEV; \
- else if (!(__sd->ops->o && __sd->ops->o->f)) \
+ else if (!__sd->ops->o) \
__result = -ENOIOCTLCMD; \
else if (v4l2_subdev_call_wrappers.o && \
v4l2_subdev_call_wrappers.o->f) \
__result = v4l2_subdev_call_wrappers.o->f( \
__sd, ##args); \
- else \
+ else if (__sd->ops->o->f) \
__result = __sd->ops->o->f(__sd, ##args); \
+ else \
+ __result = -ENOIOCTLCMD; \
__result; \
})
diff --git a/include/net/addrconf.h b/include/net/addrconf.h
index e6764245995f..6818057cf727 100644
--- a/include/net/addrconf.h
+++ b/include/net/addrconf.h
@@ -81,6 +81,9 @@ struct ifa6_config {
u8 ifa_proto;
const struct in6_addr *peer_pfx;
+ struct inet6_ifaddr *ifpub;
+ unsigned long cstamp;
+ unsigned long tstamp;
u32 rt_priority;
u32 ifa_flags;
diff --git a/include/net/af_rxrpc.h b/include/net/af_rxrpc.h
index 0fb4c41c9bbf..f3980348ed34 100644
--- a/include/net/af_rxrpc.h
+++ b/include/net/af_rxrpc.h
@@ -64,9 +64,8 @@ struct rxrpc_call *rxrpc_kernel_begin_call(struct socket *sock,
bool upgrade,
enum rxrpc_interruptibility interruptibility,
unsigned int debug_id);
-int rxrpc_kernel_send_data(struct socket *, struct rxrpc_call *,
- struct msghdr *, size_t,
- rxrpc_notify_end_tx_t);
+int rxrpc_kernel_send_data(struct socket *sock, struct rxrpc_call *call,
+ struct msghdr *msg, rxrpc_notify_end_tx_t notify_end_tx);
int rxrpc_kernel_recv_data(struct socket *, struct rxrpc_call *,
struct iov_iter *, size_t *, bool, u32 *, u16 *);
bool rxrpc_kernel_abort_call(struct socket *, struct rxrpc_call *,
diff --git a/include/net/af_vsock.h b/include/net/af_vsock.h
index 5549298c1ec6..e8481f12312e 100644
--- a/include/net/af_vsock.h
+++ b/include/net/af_vsock.h
@@ -68,6 +68,7 @@ struct vsock_sock {
u64 buffer_size;
u64 buffer_min_size;
u64 buffer_max_size;
+ bool recvmsg_inq;
/* Private to transport. */
void *trans;
diff --git a/include/net/amt.h b/include/net/amt.h
index a0255491f5b0..2846dde0cadc 100644
--- a/include/net/amt.h
+++ b/include/net/amt.h
@@ -231,10 +231,6 @@ struct amt_relay_headers {
};
} __packed;
-struct amt_skb_cb {
- struct amt_tunnel_list *tunnel;
-};
-
struct amt_tunnel_list {
struct list_head list;
/* Protect All resources under an amt_tunne_list */
diff --git a/include/net/arp.h b/include/net/arp.h
index e8747e0713c7..329a5456987a 100644
--- a/include/net/arp.h
+++ b/include/net/arp.h
@@ -7,8 +7,10 @@
#include <linux/hash.h>
#include <net/neighbour.h>
-
-extern struct neigh_table arp_tbl;
+static inline struct neigh_table *arp_table(struct net *net)
+{
+ return net->neigh_tables[NEIGH_ARP_TABLE];
+}
static inline u32 arp_hashfn(const void *pkey, const struct net_device *dev, u32 *hash_rnd)
{
@@ -21,10 +23,12 @@ static inline u32 arp_hashfn(const void *pkey, const struct net_device *dev, u32
#ifdef CONFIG_INET
static inline struct neighbour *__ipv4_neigh_lookup_noref(struct net_device *dev, u32 key)
{
+ struct neigh_table *tbl = arp_table(dev_net(dev));
+
if (dev->flags & (IFF_LOOPBACK | IFF_POINTOPOINT))
key = INADDR_ANY;
- return ___neigh_lookup_noref(&arp_tbl, neigh_key_eq32, arp_hashfn, &key, dev);
+ return ___neigh_lookup_noref(tbl, neigh_key_eq32, arp_hashfn, &key, dev);
}
#else
static inline
@@ -47,6 +51,22 @@ static inline struct neighbour *__ipv4_neigh_lookup(struct net_device *dev, u32
return n;
}
+static inline struct neighbour *ipv4_neigh_lookup(struct net_device *dev,
+ const void *pkey)
+{
+ struct neigh_table *tbl = arp_table(dev_net(dev));
+
+ return neigh_lookup(tbl, pkey, dev);
+}
+
+static inline struct neighbour *ipv4_neigh_create(struct net_device *dev,
+ const void *pkey)
+{
+ struct neigh_table *tbl = arp_table(dev_net(dev));
+
+ return neigh_create(tbl, pkey, dev);
+}
+
static inline void __ipv4_confirm_neigh(struct net_device *dev, u32 key)
{
struct neighbour *n;
diff --git a/include/net/bluetooth/bluetooth.h b/include/net/bluetooth/bluetooth.h
index b624da5026f5..cd9189244566 100644
--- a/include/net/bluetooth/bluetooth.h
+++ b/include/net/bluetooth/bluetooth.h
@@ -296,9 +296,9 @@ void bt_err_ratelimited(const char *fmt, ...);
BT_DBG("%s: " fmt, bt_dev_name(hdev), ##__VA_ARGS__)
#define bt_dev_warn_ratelimited(hdev, fmt, ...) \
- bt_warn_ratelimited("%s: " fmt, bt_dev_name(hdev), ##__VA_ARGS__)
+ bt_warn_ratelimited("%s: " fmt "\n", bt_dev_name(hdev), ##__VA_ARGS__)
#define bt_dev_err_ratelimited(hdev, fmt, ...) \
- bt_err_ratelimited("%s: " fmt, bt_dev_name(hdev), ##__VA_ARGS__)
+ bt_err_ratelimited("%s: " fmt "\n", bt_dev_name(hdev), ##__VA_ARGS__)
/* Connection and socket states */
enum bt_sock_state {
diff --git a/include/net/bluetooth/coredump.h b/include/net/bluetooth/coredump.h
index 1f071ab55416..acc1849f66c0 100644
--- a/include/net/bluetooth/coredump.h
+++ b/include/net/bluetooth/coredump.h
@@ -70,6 +70,7 @@ struct hci_devcoredump {
const char *hci_devcd_state_name(enum devcoredump_state state);
void hci_devcd_reset(struct hci_dev *hdev);
+void hci_devcd_shutdown(struct hci_dev *hdev);
void hci_devcd_rx(struct work_struct *work);
void hci_devcd_timeout(struct work_struct *work);
@@ -89,6 +90,7 @@ static inline const char *hci_devcd_state_name(enum devcoredump_state state)
}
static inline void hci_devcd_reset(struct hci_dev *hdev) {}
+static inline void hci_devcd_shutdown(struct hci_dev *hdev) {}
static inline void hci_devcd_rx(struct work_struct *work) {}
static inline void hci_devcd_timeout(struct work_struct *work) {}
diff --git a/include/net/bluetooth/hci.h b/include/net/bluetooth/hci.h
index 1641d879dbda..9dc714d9145e 100644
--- a/include/net/bluetooth/hci.h
+++ b/include/net/bluetooth/hci.h
@@ -2527,6 +2527,7 @@ struct hci_le_conn_interval_group {
struct hci_rp_le_read_conn_interval {
__u8 status;
+ __u8 min;
__u8 num_grps;
struct hci_le_conn_interval_group grps[];
} __packed;
diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
index 4105c446ca98..aa04dec45153 100644
--- a/include/net/bluetooth/hci_core.h
+++ b/include/net/bluetooth/hci_core.h
@@ -28,6 +28,7 @@
#include <linux/rculist.h>
#include <linux/spinlock.h>
#include <linux/srcu.h>
+#include <linux/uio.h>
#include <net/bluetooth/hci.h>
#include <net/bluetooth/hci_drv.h>
@@ -62,7 +63,7 @@ struct inquiry_entry {
NAME_PENDING,
NAME_KNOWN,
} name_state;
- __u32 timestamp;
+ unsigned long timestamp;
struct inquiry_data data;
};
@@ -78,7 +79,7 @@ struct discovery_state {
struct list_head all; /* All devices found during inquiry */
struct list_head unknown; /* Name state not known */
struct list_head resolve; /* Name needs to be resolved */
- __u32 timestamp;
+ unsigned long timestamp;
bdaddr_t last_adv_addr;
u8 last_adv_addr_type;
s8 last_adv_rssi;
@@ -562,6 +563,7 @@ struct hci_dev {
struct list_head link_keys;
struct list_head long_term_keys;
struct list_head identity_resolving_keys;
+ struct mutex remote_oob_lock;
struct list_head remote_oob_data;
struct list_head le_accept_list;
struct list_head le_resolv_list;
@@ -599,7 +601,7 @@ struct hci_dev {
struct list_head adv_instances;
unsigned int adv_instance_cnt;
__u8 cur_adv_instance;
- __u16 adv_instance_timeout;
+ bool adv_instance_timeout;
struct delayed_work adv_instance_expire;
struct idr adv_monitors_idr;
@@ -646,6 +648,8 @@ struct hci_dev {
int (*setup)(struct hci_dev *hdev);
int (*shutdown)(struct hci_dev *hdev);
int (*send)(struct hci_dev *hdev, struct sk_buff *skb);
+ /* Receive HCI_VENDOR_PKT */
+ void (*recv_vendor_pkt)(struct hci_dev *hdev, struct sk_buff *skb);
/* Handle HCI_EV_VENDOR; return true if handled, false otherwise */
bool (*handle_ev_vendor)(struct hci_dev *hdev, struct sk_buff *skb);
void (*notify)(struct hci_dev *hdev, unsigned int evt);
@@ -1030,6 +1034,9 @@ static inline bool hci_conn_sc_enabled(struct hci_conn *conn)
static inline void hci_conn_hash_add(struct hci_dev *hdev, struct hci_conn *c)
{
struct hci_conn_hash *h = &hdev->conn_hash;
+
+ lockdep_assert_held(&hdev->lock);
+
list_add_tail_rcu(&c->list, &h->list);
switch (c->type) {
case ACL_LINK:
@@ -1060,6 +1067,8 @@ static inline void hci_conn_hash_del(struct hci_dev *hdev, struct hci_conn *c)
{
struct hci_conn_hash *h = &hdev->conn_hash;
+ lockdep_assert_held(&hdev->lock);
+
list_del_rcu(&c->list);
synchronize_rcu();
@@ -1088,6 +1097,15 @@ static inline void hci_conn_hash_del(struct hci_dev *hdev, struct hci_conn *c)
}
}
+#ifdef CONFIG_PROVE_RCU
+#define HCI_CONN_HASH_LOCKDEP_CHECK(hdev) \
+ RCU_LOCKDEP_WARN(!lockdep_is_held(&(hdev)->lock) && \
+ !rcu_read_lock_held(), \
+ "suspicious hci_conn locking")
+#else
+#define HCI_CONN_HASH_LOCKDEP_CHECK(hdev) do { } while (0 && (hdev))
+#endif
+
static inline unsigned int hci_conn_num(struct hci_dev *hdev, __u8 type)
{
struct hci_conn_hash *h = &hdev->conn_hash;
@@ -1169,6 +1187,8 @@ static inline struct hci_conn *hci_conn_hash_lookup_bis(struct hci_dev *hdev,
struct hci_conn_hash *h = &hdev->conn_hash;
struct hci_conn *c;
+ HCI_CONN_HASH_LOCKDEP_CHECK(hdev);
+
rcu_read_lock();
list_for_each_entry_rcu(c, &h->list, list) {
@@ -1191,6 +1211,8 @@ hci_conn_hash_lookup_create_pa_sync(struct hci_dev *hdev)
struct hci_conn_hash *h = &hdev->conn_hash;
struct hci_conn *c;
+ HCI_CONN_HASH_LOCKDEP_CHECK(hdev);
+
rcu_read_lock();
list_for_each_entry_rcu(c, &h->list, list) {
@@ -1217,6 +1239,8 @@ hci_conn_hash_lookup_per_adv_bis(struct hci_dev *hdev,
struct hci_conn_hash *h = &hdev->conn_hash;
struct hci_conn *c;
+ HCI_CONN_HASH_LOCKDEP_CHECK(hdev);
+
rcu_read_lock();
list_for_each_entry_rcu(c, &h->list, list) {
@@ -1241,6 +1265,8 @@ static inline struct hci_conn *hci_conn_hash_lookup_handle(struct hci_dev *hdev,
struct hci_conn_hash *h = &hdev->conn_hash;
struct hci_conn *c;
+ HCI_CONN_HASH_LOCKDEP_CHECK(hdev);
+
rcu_read_lock();
list_for_each_entry_rcu(c, &h->list, list) {
@@ -1260,6 +1286,8 @@ static inline struct hci_conn *hci_conn_hash_lookup_ba(struct hci_dev *hdev,
struct hci_conn_hash *h = &hdev->conn_hash;
struct hci_conn *c;
+ HCI_CONN_HASH_LOCKDEP_CHECK(hdev);
+
rcu_read_lock();
list_for_each_entry_rcu(c, &h->list, list) {
@@ -1281,6 +1309,8 @@ static inline struct hci_conn *hci_conn_hash_lookup_role(struct hci_dev *hdev,
struct hci_conn_hash *h = &hdev->conn_hash;
struct hci_conn *c;
+ HCI_CONN_HASH_LOCKDEP_CHECK(hdev);
+
rcu_read_lock();
list_for_each_entry_rcu(c, &h->list, list) {
@@ -1302,6 +1332,8 @@ static inline struct hci_conn *hci_conn_hash_lookup_le(struct hci_dev *hdev,
struct hci_conn_hash *h = &hdev->conn_hash;
struct hci_conn *c;
+ HCI_CONN_HASH_LOCKDEP_CHECK(hdev);
+
rcu_read_lock();
list_for_each_entry_rcu(c, &h->list, list) {
@@ -1328,6 +1360,8 @@ static inline struct hci_conn *hci_conn_hash_lookup_cis(struct hci_dev *hdev,
struct hci_conn_hash *h = &hdev->conn_hash;
struct hci_conn *c;
+ HCI_CONN_HASH_LOCKDEP_CHECK(hdev);
+
rcu_read_lock();
list_for_each_entry_rcu(c, &h->list, list) {
@@ -1360,6 +1394,8 @@ static inline struct hci_conn *hci_conn_hash_lookup_cig(struct hci_dev *hdev,
struct hci_conn_hash *h = &hdev->conn_hash;
struct hci_conn *c;
+ HCI_CONN_HASH_LOCKDEP_CHECK(hdev);
+
rcu_read_lock();
list_for_each_entry_rcu(c, &h->list, list) {
@@ -1383,6 +1419,8 @@ static inline struct hci_conn *hci_conn_hash_lookup_big(struct hci_dev *hdev,
struct hci_conn_hash *h = &hdev->conn_hash;
struct hci_conn *c;
+ HCI_CONN_HASH_LOCKDEP_CHECK(hdev);
+
rcu_read_lock();
list_for_each_entry_rcu(c, &h->list, list) {
@@ -1407,6 +1445,8 @@ hci_conn_hash_lookup_big_sync_pend(struct hci_dev *hdev,
struct hci_conn_hash *h = &hdev->conn_hash;
struct hci_conn *c;
+ HCI_CONN_HASH_LOCKDEP_CHECK(hdev);
+
rcu_read_lock();
list_for_each_entry_rcu(c, &h->list, list) {
@@ -1431,6 +1471,8 @@ hci_conn_hash_lookup_big_state(struct hci_dev *hdev, __u8 handle, __u16 state,
struct hci_conn_hash *h = &hdev->conn_hash;
struct hci_conn *c;
+ HCI_CONN_HASH_LOCKDEP_CHECK(hdev);
+
rcu_read_lock();
list_for_each_entry_rcu(c, &h->list, list) {
@@ -1454,6 +1496,8 @@ hci_conn_hash_lookup_pa_sync_big_handle(struct hci_dev *hdev, __u8 big)
struct hci_conn_hash *h = &hdev->conn_hash;
struct hci_conn *c;
+ HCI_CONN_HASH_LOCKDEP_CHECK(hdev);
+
rcu_read_lock();
list_for_each_entry_rcu(c, &h->list, list) {
@@ -1477,6 +1521,8 @@ hci_conn_hash_lookup_pa_sync_handle(struct hci_dev *hdev, __u16 sync_handle)
struct hci_conn_hash *h = &hdev->conn_hash;
struct hci_conn *c;
+ HCI_CONN_HASH_LOCKDEP_CHECK(hdev);
+
rcu_read_lock();
list_for_each_entry_rcu(c, &h->list, list) {
@@ -1546,6 +1592,8 @@ static inline struct hci_conn *hci_lookup_le_connect(struct hci_dev *hdev)
struct hci_conn_hash *h = &hdev->conn_hash;
struct hci_conn *c;
+ HCI_CONN_HASH_LOCKDEP_CHECK(hdev);
+
rcu_read_lock();
list_for_each_entry_rcu(c, &h->list, list) {
@@ -2207,6 +2255,8 @@ static inline void hci_auth_cfm(struct hci_conn *conn, __u8 status)
conn->security_cfm_cb(conn, status);
}
+void mgmt_security_level_changed(struct hci_conn *conn);
+
static inline void hci_encrypt_cfm(struct hci_conn *conn, __u8 status)
{
struct hci_cb *cb;
@@ -2229,11 +2279,19 @@ static inline void hci_encrypt_cfm(struct hci_conn *conn, __u8 status)
encrypt = 0x01;
if (!status) {
- if (conn->sec_level == BT_SECURITY_SDP)
+ /* Callers either set conn->sec_level = conn->pending_sec_level
+ * unconditionally before calling this function, or never
+ * reach here with status == 0 (e.g. conn->state == BT_CONFIG
+ * returns early above, or status is actually an error). So
+ * conn->pending_sec_level is never greater than
+ * conn->sec_level at this point; only the initial
+ * BT_SECURITY_SDP -> BT_SECURITY_LOW bump can still happen
+ * here.
+ */
+ if (conn->sec_level == BT_SECURITY_SDP) {
conn->sec_level = BT_SECURITY_LOW;
-
- if (conn->pending_sec_level > conn->sec_level)
- conn->sec_level = conn->pending_sec_level;
+ mgmt_security_level_changed(conn);
+ }
}
mutex_lock(&hci_cb_list_lock);
@@ -2356,6 +2414,8 @@ static inline int hci_check_conn_params(u16 min, u16 max, u16 latency,
int hci_register_cb(struct hci_cb *hcb);
int hci_unregister_cb(struct hci_cb *hcb);
+int hci_send_vendor_frame(struct hci_dev *hdev, struct iov_iter *iter);
+
int __hci_cmd_send(struct hci_dev *hdev, u16 opcode, u32 plen,
const void *param);
diff --git a/include/net/bluetooth/hci_h4.h b/include/net/bluetooth/hci_h4.h
new file mode 100644
index 000000000000..a37e7df8c9ce
--- /dev/null
+++ b/include/net/bluetooth/hci_h4.h
@@ -0,0 +1,60 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * Bluetooth HCI H:4 packet reassembly
+ *
+ * Copyright (C) 2000-2001 Qualcomm Incorporated
+ * Copyright (C) 2002-2003 Maxim Krasnyansky <maxk@qualcomm.com>
+ * Copyright (C) 2004-2005 Marcel Holtmann <marcel@holtmann.org>
+ */
+
+#ifndef __HCI_H4_H
+#define __HCI_H4_H
+
+#include <linux/skbuff.h>
+#include <linux/types.h>
+
+struct hci_dev;
+
+struct h4_recv_pkt {
+ u8 type; /* Packet type */
+ u8 hlen; /* Header length */
+ u8 loff; /* Data length offset in header */
+ u8 lsize; /* Data length field size */
+ u16 maxlen; /* Max overall packet length */
+ int (*recv)(struct hci_dev *hdev, struct sk_buff *skb);
+};
+
+#define H4_RECV_ACL \
+ .type = HCI_ACLDATA_PKT, \
+ .hlen = HCI_ACL_HDR_SIZE, \
+ .loff = 2, \
+ .lsize = 2, \
+ .maxlen = HCI_MAX_FRAME_SIZE \
+
+#define H4_RECV_SCO \
+ .type = HCI_SCODATA_PKT, \
+ .hlen = HCI_SCO_HDR_SIZE, \
+ .loff = 2, \
+ .lsize = 1, \
+ .maxlen = HCI_MAX_SCO_SIZE
+
+#define H4_RECV_EVENT \
+ .type = HCI_EVENT_PKT, \
+ .hlen = HCI_EVENT_HDR_SIZE, \
+ .loff = 1, \
+ .lsize = 1, \
+ .maxlen = HCI_MAX_EVENT_SIZE
+
+#define H4_RECV_ISO \
+ .type = HCI_ISODATA_PKT, \
+ .hlen = HCI_ISO_HDR_SIZE, \
+ .loff = 2, \
+ .lsize = 2, \
+ .maxlen = HCI_MAX_FRAME_SIZE \
+
+struct sk_buff *h4_recv_skb(struct hci_dev *hdev, u8 *alignment, u8 *padding,
+ struct sk_buff *skb, const unsigned char *buffer,
+ int count, const struct h4_recv_pkt *pkts,
+ int pkts_count);
+
+#endif /* __HCI_H4_H */
diff --git a/include/net/bluetooth/hci_mon.h b/include/net/bluetooth/hci_mon.h
index 4b2a0af4ed58..7710688c0d30 100644
--- a/include/net/bluetooth/hci_mon.h
+++ b/include/net/bluetooth/hci_mon.h
@@ -50,6 +50,8 @@ struct hci_mon_hdr {
#define HCI_MON_ISO_RX_PKT 19
#define HCI_MON_DRV_TX_PKT 20
#define HCI_MON_DRV_RX_PKT 21
+#define HCI_MON_VENDOR_TX_PKT 22
+#define HCI_MON_VENDOR_RX_PKT 23
struct hci_mon_new_index {
__u8 type;
diff --git a/include/net/bluetooth/hci_sync.h b/include/net/bluetooth/hci_sync.h
index a6579a868678..59cb918d1405 100644
--- a/include/net/bluetooth/hci_sync.h
+++ b/include/net/bluetooth/hci_sync.h
@@ -122,6 +122,7 @@ int hci_disable_per_advertising_sync(struct hci_dev *hdev, u8 instance);
int hci_remove_advertising_sync(struct hci_dev *hdev, struct sock *sk,
u8 instance, bool force);
int hci_disable_advertising_sync(struct hci_dev *hdev);
+int hci_disable_ext_adv_legacy_instance_sync(struct hci_dev *hdev);
int hci_clear_adv_instance_sync(struct hci_dev *hdev, struct sock *sk,
u8 instance, bool force);
int hci_update_passive_scan_sync(struct hci_dev *hdev);
diff --git a/include/net/bluetooth/l2cap.h b/include/net/bluetooth/l2cap.h
index 3d9a32094347..54eddcdd341f 100644
--- a/include/net/bluetooth/l2cap.h
+++ b/include/net/bluetooth/l2cap.h
@@ -614,31 +614,6 @@ struct l2cap_chan {
struct mutex lock;
};
-struct l2cap_ops {
- char *name;
-
- int (*new_connection)(struct l2cap_chan *chan,
- struct l2cap_chan *new_chan);
- int (*recv) (struct l2cap_chan * chan,
- struct sk_buff *skb);
- void (*teardown) (struct l2cap_chan *chan, int err);
- void (*close) (struct l2cap_chan *chan);
- void (*state_change) (struct l2cap_chan *chan,
- int state, int err);
- void (*ready) (struct l2cap_chan *chan);
- void (*defer) (struct l2cap_chan *chan);
- void (*resume) (struct l2cap_chan *chan);
- void (*suspend) (struct l2cap_chan *chan);
- void (*set_shutdown) (struct l2cap_chan *chan);
- long (*get_sndtimeo) (struct l2cap_chan *chan);
- struct pid *(*get_peer_pid) (struct l2cap_chan *chan);
- struct sk_buff *(*alloc_skb) (struct l2cap_chan *chan,
- unsigned long hdr_len,
- unsigned long len, int nb);
- int (*filter) (struct l2cap_chan * chan,
- struct sk_buff *skb);
-};
-
struct l2cap_conn {
struct hci_conn *hcon;
struct hci_chan *hchan;
@@ -668,12 +643,45 @@ struct l2cap_conn {
struct l2cap_chan *smp;
- struct list_head chan_l;
+ struct list_head chan_l __guarded_by(&lock);
struct mutex lock;
struct kref ref;
struct list_head users;
};
+struct l2cap_ops {
+ char *name;
+
+ int (*new_connection)(struct l2cap_chan *chan,
+ struct l2cap_chan *new_chan)
+ __must_hold(&chan->lock)
+ __must_hold(&new_chan->lock);
+ int (*recv) (struct l2cap_chan * chan,
+ struct sk_buff *skb);
+ void (*teardown) (struct l2cap_chan *chan, int err)
+ __must_hold(&chan->lock);
+ void (*close) (struct l2cap_chan *chan)
+ __must_hold(&chan->lock);
+ void (*state_change) (struct l2cap_chan *chan,
+ int state, int err);
+ void (*ready) (struct l2cap_chan *chan)
+ __must_hold(&chan->lock)
+ __must_hold(&chan->conn->lock);
+ void (*defer) (struct l2cap_chan *chan);
+ void (*resume) (struct l2cap_chan *chan)
+ __must_hold(&chan->lock);
+ void (*suspend) (struct l2cap_chan *chan);
+ void (*set_shutdown) (struct l2cap_chan *chan)
+ __must_hold(&chan->lock);
+ long (*get_sndtimeo) (struct l2cap_chan *chan);
+ struct pid *(*get_peer_pid) (struct l2cap_chan *chan);
+ struct sk_buff *(*alloc_skb) (struct l2cap_chan *chan,
+ unsigned long hdr_len,
+ unsigned long len, int nb);
+ int (*filter) (struct l2cap_chan * chan,
+ struct sk_buff *skb);
+};
+
struct l2cap_user {
struct list_head list;
int (*probe) (struct l2cap_conn *conn, struct l2cap_user *user);
@@ -717,7 +725,6 @@ enum {
CONF_CONNECT_PEND,
CONF_RECV_NO_FCS,
CONF_STATE2_DEVICE,
- CONF_EWS_RECV,
CONF_LOC_CONF_PEND,
CONF_REM_CONF_PEND,
CONF_NOT_COMPLETE,
@@ -758,6 +765,10 @@ enum {
* otherwise considers all channels equal and will e.g. complain about a
* connection oriented channel triggering SMP procedures or a listening
* channel creating and locking a child channel.
+ *
+ * Lock nesting of channels at the same nesting level is allowed if the channels
+ * have the same l2cap_chan::conn and l2cap_chan::conn.lock is taken before the
+ * nested locks. l2cap_chan_try_sibling_lock() must be used.
*/
enum {
L2CAP_NESTING_SMP,
@@ -830,11 +841,13 @@ struct l2cap_chan *l2cap_chan_hold_unless_zero(struct l2cap_chan *c);
void l2cap_chan_put(struct l2cap_chan *c);
static inline void l2cap_chan_lock(struct l2cap_chan *chan)
+ __acquires(&chan->lock)
{
mutex_lock_nested(&chan->lock, atomic_read(&chan->nesting));
}
static inline void l2cap_chan_unlock(struct l2cap_chan *chan)
+ __releases(&chan->lock)
{
mutex_unlock(&chan->lock);
}
@@ -845,12 +858,11 @@ static inline void l2cap_set_timer(struct l2cap_chan *chan,
BT_DBG("chan %p state %s timeout %ld", chan,
state_to_string(chan->state), timeout);
- /* If delayed work cancelled do not hold(chan)
- since it is already done with previous set_timer */
- if (!cancel_delayed_work(work))
- l2cap_chan_hold(chan);
+ l2cap_chan_hold(chan);
- schedule_delayed_work(work, timeout);
+ /* put(chan) if timer was already queued so it already has a ref */
+ if (mod_delayed_work(system_percpu_wq, work, timeout))
+ l2cap_chan_put(chan);
}
static inline bool l2cap_clear_timer(struct l2cap_chan *chan,
@@ -952,14 +964,16 @@ void l2cap_cleanup_sockets(void);
bool l2cap_is_socket(struct socket *sock);
void __l2cap_le_connect_rsp_defer(struct l2cap_chan *chan);
-void __l2cap_ecred_conn_rsp_defer(struct l2cap_chan *chan);
+void __l2cap_ecred_conn_rsp_defer(struct l2cap_chan *chan)
+ __must_hold(&chan->lock) __must_hold(&chan->conn->lock);
void __l2cap_connect_rsp_defer(struct l2cap_chan *chan);
int l2cap_add_psm(struct l2cap_chan *chan, bdaddr_t *src, __le16 psm);
int l2cap_add_scid(struct l2cap_chan *chan, __u16 scid);
struct l2cap_chan *l2cap_chan_create(void);
-void l2cap_chan_close(struct l2cap_chan *chan, int reason);
+void l2cap_chan_close_unlocked(struct l2cap_chan *chan, int reason)
+ __must_not_hold(&chan->lock);
int l2cap_chan_connect(struct l2cap_chan *chan, __le16 psm, u16 cid,
bdaddr_t *dst, u8 dst_type, u16 timeout);
int l2cap_chan_reconfigure(struct l2cap_chan *chan, __u16 mtu);
@@ -971,11 +985,13 @@ int l2cap_chan_check_security(struct l2cap_chan *chan, bool initiator);
void l2cap_chan_set_defaults(struct l2cap_chan *chan, struct l2cap_chan *pchan);
int l2cap_ertm_init(struct l2cap_chan *chan);
void l2cap_chan_add(struct l2cap_conn *conn, struct l2cap_chan *chan);
-void __l2cap_chan_add(struct l2cap_conn *conn, struct l2cap_chan *chan);
+void __l2cap_chan_add(struct l2cap_conn *conn, struct l2cap_chan *chan)
+ __must_hold(&conn->lock) __must_hold(&chan->lock);
typedef void (*l2cap_chan_func_t)(struct l2cap_chan *chan, void *data);
void l2cap_chan_list(struct l2cap_conn *conn, l2cap_chan_func_t func,
void *data);
-void l2cap_chan_del(struct l2cap_chan *chan, int err);
+void l2cap_chan_del(struct l2cap_chan *chan, int err)
+ __must_hold(&chan->lock) __must_hold(&chan->conn->lock);
void l2cap_send_conn_req(struct l2cap_chan *chan);
struct l2cap_conn *l2cap_conn_get(struct l2cap_conn *conn);
@@ -985,4 +1001,19 @@ void l2cap_conn_put(struct l2cap_conn *conn);
int l2cap_register_user(struct l2cap_conn *conn, struct l2cap_user *user);
void l2cap_unregister_user(struct l2cap_conn *conn, struct l2cap_user *user);
+bool l2cap_chan_lock_conn(struct l2cap_chan *chan)
+ __acquires(&chan->lock) __cond_acquires(true, &chan->conn->lock);
+
+/* Release macro for l2cap_chan_lock_conn, so context analysis understands it */
+#define l2cap_chan_unlock_conn(chan, conn_locked) \
+ ({ \
+ struct l2cap_chan *__chan = (chan); \
+ struct l2cap_conn *__conn = __chan->conn; \
+ l2cap_chan_unlock(__chan); \
+ if (conn_locked) { \
+ mutex_unlock(&__conn->lock); \
+ l2cap_conn_put(__conn); \
+ } \
+ })
+
#endif /* __L2CAP_H */
diff --git a/include/net/bluetooth/mgmt.h b/include/net/bluetooth/mgmt.h
index 1e22eab1081c..b02e915bb44c 100644
--- a/include/net/bluetooth/mgmt.h
+++ b/include/net/bluetooth/mgmt.h
@@ -1221,3 +1221,17 @@ struct mgmt_ev_conn_subrate {
__le16 cont_num;
__le16 supv_timeout;
} __packed;
+
+#define MGMT_CONN_SEC_ENCRYPT_NONE 0x00
+#define MGMT_CONN_SEC_ENCRYPT_E0 0x01
+#define MGMT_CONN_SEC_ENCRYPT_AES_CCM 0x02
+
+#define MGMT_SEC_LEVEL_CHANGED_PARAM_LEVEL 0x0000
+#define MGMT_SEC_LEVEL_CHANGED_PARAM_ENC_TYPE 0x0001
+
+#define MGMT_EV_SECURITY_LEVEL_CHANGED 0x0034
+struct mgmt_ev_security_level_changed {
+ struct mgmt_addr_info addr;
+ __u8 tlv_length;
+ __u8 tlv_data[] __counted_by(tlv_length);
+} __packed;
diff --git a/include/net/bluetooth/rfcomm.h b/include/net/bluetooth/rfcomm.h
index 102c278e3584..9dc5fd4cb8c8 100644
--- a/include/net/bluetooth/rfcomm.h
+++ b/include/net/bluetooth/rfcomm.h
@@ -207,6 +207,7 @@ struct rfcomm_dlc {
#define RFCOMM_AUTH_REJECT 7
#define RFCOMM_DEFER_SETUP 8
#define RFCOMM_ENC_DROP 9
+#define RFCOMM_CLOSED 10
/* Scheduling flags and events */
#define RFCOMM_SCHED_WAKEUP 31
diff --git a/include/net/bond_3ad.h b/include/net/bond_3ad.h
index ef667dff2972..9e548d3dca21 100644
--- a/include/net/bond_3ad.h
+++ b/include/net/bond_3ad.h
@@ -60,12 +60,6 @@ typedef enum {
AD_MUX_COLLECTING_DISTRIBUTING /* mux machine */
} mux_states_t;
-/* tx machine states(43.4.15 in the 802.3ad standard) */
-typedef enum {
- AD_TX_DUMMY,
- AD_TRANSMIT /* tx Machine */
-} tx_states_t;
-
/* churn machine states(43.4.17 in the 802.3ad standard) */
typedef enum {
AD_CHURN_MONITOR, /* monitoring for churn */
@@ -231,7 +225,6 @@ typedef struct port {
u16 sm_periodic_timer_counter; /* state machine periodic timer counter */
mux_states_t sm_mux_state; /* state machine mux state */
u16 sm_mux_timer_counter; /* state machine mux timer counter */
- tx_states_t sm_tx_state; /* state machine tx state */
u16 sm_tx_timer_counter; /* state machine tx timer counter
* (always on - enter to transmit
* state 3 time per second)
diff --git a/include/net/bond_alb.h b/include/net/bond_alb.h
index e5945427f38d..32f1981033e4 100644
--- a/include/net/bond_alb.h
+++ b/include/net/bond_alb.h
@@ -57,12 +57,12 @@ struct tlb_client_info {
* packets to a Client that the Hash function
* gave this entry index.
*/
- u32 tx_bytes; /* Each Client accumulates the BytesTx that
+ u64 tx_bytes; /* Each Client accumulates the BytesTx that
* were transmitted to it, and after each
* CallBack the LoadHistory is divided
* by the balance interval
*/
- u32 load_history; /* This field contains the amount of Bytes
+ u64 load_history; /* This field contains the amount of Bytes
* that were transmitted to this client by
* the server on the previous balance
* interval in Bps.
@@ -118,14 +118,20 @@ struct tlb_slave_info {
* are the entries that were assigned to use this
* slave for transmit.
*/
- u32 load; /* Each slave sums the loadHistory of all clients
+ u64 load; /* Each slave sums the loadHistory of all clients
* assigned to it
*/
};
+struct unbalanced_load_stats {
+ u64_stats_t tx_bytes;
+ struct u64_stats_sync syncp;
+};
+
struct alb_bond_info {
struct tlb_client_info *tx_hashtbl; /* Dynamically allocated */
- u32 unbalanced_load;
+ struct unbalanced_load_stats __percpu *unbalanced_load;
+ u64 prev_total_unbalanced;
atomic_t tx_rebalance_counter;
int lp_counter;
/* -------- rlb parameters -------- */
diff --git a/include/net/can.h b/include/net/can.h
index 6db9e826f0e0..2b8af2598732 100644
--- a/include/net/can.h
+++ b/include/net/can.h
@@ -17,12 +17,14 @@
* @can_framelen: cached echo CAN frame length for bql
* @can_gw_hops: can-gw CAN frame time-to-live counter
* @can_ext_flags: CAN skb extensions flags
+ * @can_skb_uid: CAN skb UID for raw_rcv and isotp echo handling
*/
struct can_skb_ext {
int can_iif;
u16 can_framelen;
u8 can_gw_hops;
u8 can_ext_flags;
+ u32 can_skb_uid;
};
#endif /* _NET_CAN_H */
diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index 97c16d4ff127..f773856c1818 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -21,6 +21,7 @@
#include <linux/nl80211.h>
#include <linux/if_ether.h>
#include <linux/ieee80211.h>
+#include <linux/refcount.h>
#include <linux/net.h>
#include <linux/rfkill.h>
#include <net/regulatory.h>
@@ -576,7 +577,6 @@ struct ieee80211_sta_s1g_cap {
* @vht_cap: VHT capabilities in this band
* @s1g_cap: S1G capabilities in this band
* @edmg_cap: EDMG capabilities in this band
- * @s1g_cap: S1G capabilities in this band (S1G band only, of course)
* @n_iftype_data: number of iftype data entries
* @iftype_data: interface type data entries. Note that the bits in
* @types_mask inside this structure cannot overlap (i.e. only
@@ -901,6 +901,7 @@ struct cfg80211_bitrate_mask {
enum nl80211_eht_gi eht_gi;
enum nl80211_he_ltf he_ltf;
enum nl80211_eht_ltf eht_ltf;
+ bool nonht_dup_6ghz;
} control[NUM_NL80211_BANDS];
};
@@ -1410,7 +1411,7 @@ struct cfg80211_mbssid_config {
/**
* struct cfg80211_mbssid_elems - Multiple BSSID elements
*
- * @cnt: Number of elements in array %elems.
+ * @cnt: Number of elements in array @elem.
*
* @elem: Array of multiple BSSID element(s) to be added into Beacon frames.
* @elem.data: Data for multiple BSSID elements.
@@ -1427,7 +1428,7 @@ struct cfg80211_mbssid_elems {
/**
* struct cfg80211_rnr_elems - Reduced neighbor report (RNR) elements
*
- * @cnt: Number of elements in array %elems.
+ * @cnt: Number of elements in array @elem.
*
* @elem: Array of RNR element(s) to be added into Beacon frames.
* @elem.data: Data for RNR elements.
@@ -1821,6 +1822,8 @@ struct sta_txpwr {
* @s1g_capa: S1G capabilities of station
* @uhr_capa: UHR capabilities of the station
* @uhr_capa_len: the length of the UHR capabilities
+ * @cip_cap_set: If CIP capabilities are present, required for CIP stations
+ * @cip_cap: CIP capabilities of station
*/
struct link_station_parameters {
const u8 *mld_mac;
@@ -1842,6 +1845,8 @@ struct link_station_parameters {
const struct ieee80211_s1g_cap *s1g_capa;
const struct ieee80211_uhr_cap *uhr_capa;
u8 uhr_capa_len;
+ bool cip_cap_set;
+ u8 cip_cap;
};
/**
@@ -2904,7 +2909,7 @@ struct cfg80211_ssid {
* @scan_start_tsf: scan start time in terms of the TSF of the BSS that the
* wireless device that requested the scan is connected to. If this
* information is not available, this field is left zero.
- * @tsf_bssid: the BSSID according to which %scan_start_tsf is set.
+ * @tsf_bssid: the BSSID according to which @scan_start_tsf is set.
* @aborted: set to true if the scan was aborted for any reason,
* userspace will be notified of that
*/
@@ -3164,8 +3169,8 @@ enum cfg80211_signal_type {
* ktime_get_boottime_ns() is likely appropriate.
* @parent_tsf: the time at the start of reception of the first octet of the
* timestamp field of the frame. The time is the TSF of the BSS specified
- * by %parent_bssid.
- * @parent_bssid: the BSS according to which %parent_tsf is set. This is set to
+ * by @parent_bssid.
+ * @parent_bssid: the BSS according to which @parent_tsf is set. This is set to
* the BSS that requested the scan in which the beacon/probe was received.
* @chains: bitmask for filled values in @chain_signal.
* @chain_signal: per-chain signal strength of last received BSS in dBm.
@@ -3402,6 +3407,8 @@ struct cfg80211_ml_reconf_req {
* flag is not set.
* @ASSOC_REQ_SPP_AMSDU: SPP A-MSDUs will be used on this connection (if any)
* @ASSOC_REQ_DISABLE_UHR: Disable UHR
+ * @ASSOC_REQ_CIP: Enable Control Integrity Protocol
+ * @ASSOC_REQ_PROTECTED_TWT: Enable protected TWT
*/
enum cfg80211_assoc_req_flags {
ASSOC_REQ_DISABLE_HT = BIT(0),
@@ -3413,6 +3420,8 @@ enum cfg80211_assoc_req_flags {
CONNECT_REQ_MLO_SUPPORT = BIT(6),
ASSOC_REQ_SPP_AMSDU = BIT(7),
ASSOC_REQ_DISABLE_UHR = BIT(8),
+ ASSOC_REQ_CIP = BIT(9),
+ ASSOC_REQ_PROTECTED_TWT = BIT(10),
};
/**
@@ -4009,6 +4018,7 @@ struct cfg80211_update_ft_ies_params {
* @link_id: for MLO, the link ID to transmit on, -1 if not given; note
* that the link ID isn't validated (much), it's in range but the
* link might not exist (or be used by the receiver STA)
+ * @no_sta: set if the frame should not be transmitted using an existing STA
*/
struct cfg80211_mgmt_tx_params {
struct ieee80211_channel *chan;
@@ -4021,6 +4031,7 @@ struct cfg80211_mgmt_tx_params {
int n_csa_offsets;
const u16 *csa_offsets;
int link_id;
+ bool no_sta;
};
/**
@@ -4183,9 +4194,12 @@ struct cfg80211_nan_band_config {
* that can take a value from 50-6F-9A-01-00-00 to 50-6F-9A-01-FF-FF.
* @scan_period: period (in seconds) between NAN scans.
* @scan_dwell_time: dwell time (in milliseconds) for NAN scans.
- * @discovery_beacon_interval: interval (in TUs) for discovery beacons.
+ * @discovery_beacon_interval: interval (in TUs) for discovery beacons. Must be
+ * greater than 0 when @instant_comm is true.
* @enable_dw_notification: flag to enable/disable discovery window
* notifications.
+ * @instant_comm: if true, start Instant Communication (IC) as defined in
+ * Chapter 13 of the Wi-Fi Aware Specification v4.0.
* @band_cfgs: array of band specific configurations, indexed by
* &enum nl80211_band values.
* @extra_nan_attrs: pointer to additional NAN attributes.
@@ -4201,6 +4215,7 @@ struct cfg80211_nan_conf {
u16 scan_dwell_time;
u8 discovery_beacon_interval;
bool enable_dw_notification;
+ bool instant_comm;
struct cfg80211_nan_band_config band_cfgs[NUM_NL80211_BANDS];
const u8 *extra_nan_attrs;
u16 extra_nan_attrs_len;
@@ -4232,9 +4247,9 @@ struct cfg80211_nan_channel {
*
* This struct defines NAN local schedule parameters
*
- * @schedule: a mapping of time slots to chandef indexes in %nan_channels.
+ * @schedule: a mapping of time slots to chandef indexes in @nan_channels.
* An unscheduled slot will be set to %NL80211_NAN_SCHED_NOT_AVAIL_SLOT.
- * @n_channels: number of channel definitions in %nan_channels.
+ * @n_channels: number of channel definitions in @nan_channels.
* @nan_avail_blob: pointer to NAN Availability attribute blob.
* See %NL80211_ATTR_NAN_AVAIL_BLOB for more details.
* @nan_avail_blob_len: length of the @nan_avail_blob in bytes.
@@ -4257,6 +4272,21 @@ struct cfg80211_nan_local_sched {
};
/**
+ * struct cfg80211_nan_non_evac_channels - NAN non-evacuable channels
+ *
+ * This struct defines the set of NAN local schedule channels that must not
+ * be evacuated for concurrent operations.
+ *
+ * @n_channels: number of channel definitions in @chandefs.
+ * @chandefs: array of channel definitions that must not be evacuated. Each
+ * must match a channel of the current local schedule.
+ */
+struct cfg80211_nan_non_evac_channels {
+ u8 n_channels;
+ struct cfg80211_chan_def chandefs[] __counted_by(n_channels);
+};
+
+/**
* struct cfg80211_nan_peer_map - NAN peer schedule map
*
* This struct defines a single NAN peer schedule map
@@ -4920,6 +4950,9 @@ struct mgmt_frame_regs {
* @start_ap: Start acting in AP mode defined by the parameters.
* @change_beacon: Change the beacon parameters for an access point mode
* interface. This should reject the call when AP mode wasn't started.
+ * @update_beacon: Update the beacon and other templates like @change_beacon,
+ * but called without the wiphy mutex held. May return -EAGAIN to have
+ * it fall back to @change_beacon with the wiphy mutex held.
* @stop_ap: Stop being an AP, including stopping beaconing.
*
* @add_station: Add a new station.
@@ -4930,7 +4963,13 @@ struct mgmt_frame_regs {
* them, also against the existing state! Drivers must call
* cfg80211_check_station_change() to validate the information.
* @get_station: get station information for the station identified by @mac
+ * @get_station_unlocked: Like @get_station, but called without the wiphy
+ * mutex. Return -EAGAIN to get @get_station called with the wiphy mutex
+ * held instead.
* @dump_station: dump station callback -- resume dump at index @idx
+ * @dump_station_unlocked: Like @dump_station, but called without the wiphy
+ * mutex. Return -EAGAIN to get @dump_station called with the wiphy mutex
+ * held instead.
*
* @add_mpath: add a fixed mesh path
* @del_mpath: delete a given mesh path
@@ -5054,6 +5093,13 @@ struct mgmt_frame_regs {
* This allows the operation to be terminated prior to timeout based on
* the duration value.
* @mgmt_tx: Transmit a management frame.
+ * @mgmt_tx_unlocked: Like @mgmt_tx, but called without the wiphy mutex,
+ * currently limited to AP/GO/NAN. The driver may -EAGAIN to get
+ * @mgmt_tx with the wiphy mutex held for the same operation,
+ * although if the device is removed concurrently that might not
+ * happen and userspace sees -ENODEV.
+ * Note this cannot acquire the wiphy mutex or RTNL, that would
+ * deadlock against unregistering the wdev.
* @mgmt_tx_cancel_wait: Cancel the wait time from transmitting a management
* frame on another channel
*
@@ -5109,7 +5155,10 @@ struct mgmt_frame_regs {
*
* @probe_peer: probe a connected peer (AP: STA MAC required; STA: no MAC),
* must use the @cookie as provided which is later passed to
- * cfg80211_probe_status().
+ * cfg80211_probe_status(). Called without the wiphy mutex, so the
+ * interface type may have changed/be changing and the MAC may be
+ * %NULL even in AP mode (if runtime type changes are supported),
+ * drivers must check for that.
*
* @set_noack_map: Set the NoAck Map for the TIDs.
*
@@ -5204,6 +5253,12 @@ struct mgmt_frame_regs {
* schedule, the full new schedule is provided - partial updates are not
* supported, and the new schedule completely replaces the previous one.
*
+ * @nan_set_non_evac_channels: set the list of local schedule channels that
+ * must not be evacuated for concurrent operations. The provided list
+ * replaces the previous set; channels of the current schedule that are
+ * not included become evacuable again. All provided channels are
+ * guaranteed by cfg80211 to belong to the current local schedule.
+ *
* @set_multicast_to_unicast: configure multicast to unicast conversion for BSS
*
* @get_txq_stats: Get TXQ stats for interface or phy. If wdev is %NULL, this
@@ -5222,6 +5277,7 @@ struct mgmt_frame_regs {
* @tx_control_port: TX a control port frame (EAPoL). The noencrypt parameter
* tells the driver that the frame should not be encrypted. A @cookie
* value of 0 means the caller does not want TX status reporting.
+ * Called without the wiphy mutex.
*
* @get_ftm_responder_stats: Retrieve FTM responder statistics, if available.
* Statistics should be cumulative, currently no way to reset is provided.
@@ -5302,14 +5358,17 @@ struct cfg80211_ops {
unsigned int link_id);
int (*add_key)(struct wiphy *wiphy, struct wireless_dev *wdev,
- int link_id, u8 key_index, bool pairwise,
+ int link_id, u8 key_index,
+ enum nl80211_key_type type,
const u8 *mac_addr, struct key_params *params);
int (*get_key)(struct wiphy *wiphy, struct wireless_dev *wdev,
- int link_id, u8 key_index, bool pairwise,
+ int link_id, u8 key_index,
+ enum nl80211_key_type type,
const u8 *mac_addr, void *cookie,
void (*callback)(void *cookie, struct key_params*));
int (*del_key)(struct wiphy *wiphy, struct wireless_dev *wdev,
- int link_id, u8 key_index, bool pairwise,
+ int link_id, u8 key_index,
+ enum nl80211_key_type type,
const u8 *mac_addr);
int (*set_default_key)(struct wiphy *wiphy,
struct net_device *netdev, int link_id,
@@ -5326,6 +5385,8 @@ struct cfg80211_ops {
struct cfg80211_ap_settings *settings);
int (*change_beacon)(struct wiphy *wiphy, struct net_device *dev,
struct cfg80211_ap_update *info);
+ int (*update_beacon)(struct wiphy *wiphy, struct net_device *dev,
+ struct cfg80211_ap_update *info);
int (*stop_ap)(struct wiphy *wiphy, struct net_device *dev,
unsigned int link_id);
@@ -5340,8 +5401,16 @@ struct cfg80211_ops {
struct station_parameters *params);
int (*get_station)(struct wiphy *wiphy, struct wireless_dev *wdev,
const u8 *mac, struct station_info *sinfo);
+ int (*get_station_unlocked)(struct wiphy *wiphy,
+ struct wireless_dev *wdev,
+ const u8 *mac,
+ struct station_info *sinfo);
int (*dump_station)(struct wiphy *wiphy, struct wireless_dev *wdev,
int idx, u8 *mac, struct station_info *sinfo);
+ int (*dump_station_unlocked)(struct wiphy *wiphy,
+ struct wireless_dev *wdev,
+ int idx, u8 *mac,
+ struct station_info *sinfo);
int (*add_mpath)(struct wiphy *wiphy, struct net_device *dev,
const u8 *dst, const u8 *next_hop);
@@ -5466,6 +5535,10 @@ struct cfg80211_ops {
int (*mgmt_tx)(struct wiphy *wiphy, struct wireless_dev *wdev,
struct cfg80211_mgmt_tx_params *params,
u64 cookie);
+ int (*mgmt_tx_unlocked)(struct wiphy *wiphy,
+ struct wireless_dev *wdev,
+ struct cfg80211_mgmt_tx_params *params,
+ u64 cookie);
int (*mgmt_tx_cancel_wait)(struct wiphy *wiphy,
struct wireless_dev *wdev,
u64 cookie);
@@ -5590,6 +5663,9 @@ struct cfg80211_ops {
int (*nan_set_peer_sched)(struct wiphy *wiphy,
struct wireless_dev *wdev,
struct cfg80211_nan_peer_sched *sched);
+ int (*nan_set_non_evac_channels)(struct wiphy *wiphy,
+ struct wireless_dev *wdev,
+ struct cfg80211_nan_non_evac_channels *channels);
int (*set_multicast_to_unicast)(struct wiphy *wiphy,
struct net_device *dev,
const bool enabled);
@@ -6043,6 +6119,8 @@ struct wiphy_vendor_command {
* @eml_capabilities: EML capabilities (for MLO)
* @mld_capa_and_ops: MLD capabilities and operations (for MLO)
* @ext_mld_capa_and_ops: Extended MLD capabilities and operations (for MLO)
+ * @cip_supported: CIP is supported and the capabilities are valid
+ * @cip_capabilities: CIP Capabilities element containing the MIC padding delay
*/
struct wiphy_iftype_ext_capab {
enum nl80211_iftype iftype;
@@ -6052,6 +6130,8 @@ struct wiphy_iftype_ext_capab {
u16 eml_capabilities;
u16 mld_capa_and_ops;
u16 ext_mld_capa_and_ops;
+ bool cip_supported;
+ u8 cip_capabilities;
};
/**
@@ -6266,10 +6346,13 @@ struct wiphy_radio {
* @WIPHY_NAN_FLAGS_CONFIGURABLE_SYNC: Device supports NAN configurable
* synchronization.
* @WIPHY_NAN_FLAGS_USERSPACE_DE: Device doesn't support DE offload.
+ * @WIPHY_NAN_FLAGS_INSTANT_COMM: Device can switch to Instant Communication
+ * (IC) mode. Can only be set along with %WIPHY_NAN_FLAGS_CONFIGURABLE_SYNC.
*/
enum wiphy_nan_flags {
WIPHY_NAN_FLAGS_CONFIGURABLE_SYNC = BIT(0),
WIPHY_NAN_FLAGS_USERSPACE_DE = BIT(1),
+ WIPHY_NAN_FLAGS_INSTANT_COMM = BIT(2),
};
/**
@@ -6314,7 +6397,8 @@ struct wiphy_nan_capa {
* @mtx: mutex for the data (structures) of this device
* @reg_notifier: the driver's regulatory notification callback,
* note that if your driver uses wiphy_apply_custom_regulatory()
- * the reg_notifier's request can be passed as NULL
+ * the reg_notifier's request can be passed as NULL.
+ * This is called under wiphy mutex.
* @regd: the driver's regulatory domain, if one was requested via
* the regulatory_hint() API. This can be used by the driver
* on the reg_notifier() if it chooses to ignore future
@@ -7172,6 +7256,9 @@ enum ieee80211_ap_reg_power {
* @netdev: (private) Used to reference back to the netdev, may be %NULL
* @identifier: (private) Identifier used in nl80211 to identify this
* wireless device if it has no netdev
+ * @refcnt: (private) references held by nl80211 if there's no netdev,
+ * to ensure cfg80211_unregister_wdev() cannot return while
+ * unlocked ops are running
* @u: union containing data specific to @iftype
* @connected: indicates if connected or not (STA mode)
* @wext: (private) Used by the internal wireless extensions compat code
@@ -7194,8 +7281,9 @@ enum ieee80211_ap_reg_power {
* @mgmt_registrations_need_update: mgmt registrations were updated,
* need to propagate the update to the driver
* @address: The address for this device, valid only if @netdev is %NULL
- * @is_running: true if this is a non-netdev device that has been started, e.g.
- * the P2P Device.
+ * @is_running: true if the device has been started, e.g. the P2P Device;
+ * for netdevs, tracked under the wiphy mutex from NETDEV_UP until
+ * NETDEV_GOING_DOWN
* @ps: powersave mode is enabled
* @ps_timeout: dynamic powersave timeout
* @unexpected_nlportid: (private) netlink port ID of application
@@ -7236,6 +7324,7 @@ struct wireless_dev {
struct net_device *netdev;
u32 identifier;
+ refcount_t refcnt;
struct list_head mgmt_registrations;
u8 mgmt_registrations_need_update:1;
@@ -7332,6 +7421,8 @@ struct wireless_dev {
union {
struct {
unsigned int beacon_interval;
+ enum ieee80211_ap_reg_power reg_power;
+ enum ieee80211_ap_reg_power csa_reg_power;
struct cfg80211_chan_def chandef;
} ap;
struct {
@@ -7357,8 +7448,6 @@ static inline const u8 *wdev_address(struct wireless_dev *wdev)
static inline bool wdev_running(struct wireless_dev *wdev)
{
- if (wdev->netdev)
- return netif_running(wdev->netdev);
return wdev->is_running;
}
@@ -7817,7 +7906,8 @@ unsigned int cfg80211_classify8021d(struct sk_buff *skb,
* byte array to match.
*/
const struct element *
-cfg80211_find_elem_match(u8 eid, const u8 *ies, unsigned int len,
+cfg80211_find_elem_match(enum ieee80211_eid eid,
+ const u8 *ies, unsigned int len,
const u8 *match, unsigned int match_len,
unsigned int match_offset);
@@ -7846,7 +7936,7 @@ cfg80211_find_elem_match(u8 eid, const u8 *ies, unsigned int len,
* byte array to match.
*/
static inline const u8 *
-cfg80211_find_ie_match(u8 eid, const u8 *ies, unsigned int len,
+cfg80211_find_ie_match(enum ieee80211_eid eid, const u8 *ies, unsigned int len,
const u8 *match, unsigned int match_len,
unsigned int match_offset)
{
@@ -7879,7 +7969,7 @@ cfg80211_find_ie_match(u8 eid, const u8 *ies, unsigned int len,
* having to fit into the given data.
*/
static inline const struct element *
-cfg80211_find_elem(u8 eid, const u8 *ies, int len)
+cfg80211_find_elem(enum ieee80211_eid eid, const u8 *ies, int len)
{
return cfg80211_find_elem_match(eid, ies, len, NULL, 0, 0);
}
@@ -7899,7 +7989,8 @@ cfg80211_find_elem(u8 eid, const u8 *ies, int len)
* Note: There are no checks on the element length other than
* having to fit into the given data.
*/
-static inline const u8 *cfg80211_find_ie(u8 eid, const u8 *ies, int len)
+static inline const u8 *cfg80211_find_ie(enum ieee80211_eid eid,
+ const u8 *ies, int len)
{
return cfg80211_find_ie_match(eid, ies, len, NULL, 0, 0);
}
@@ -7920,10 +8011,13 @@ static inline const u8 *cfg80211_find_ie(u8 eid, const u8 *ies, int len)
* having to fit into the given data.
*/
static inline const struct element *
-cfg80211_find_ext_elem(u8 ext_eid, const u8 *ies, int len)
+cfg80211_find_ext_elem(enum ieee80211_eid_ext ext_eid,
+ const u8 *ies, int len)
{
+ u8 _ext_eid = ext_eid;
+
return cfg80211_find_elem_match(WLAN_EID_EXTENSION, ies, len,
- &ext_eid, 1, 0);
+ &_ext_eid, 1, 0);
}
/**
@@ -8106,9 +8200,9 @@ int regulatory_set_wiphy_regd(struct wiphy *wiphy,
* @wiphy: the wireless device we want to process the regulatory domain on
* @rd: the regulatory domain information to use for this wiphy
*
- * This functions requires the RTNL and the wiphy mutex to be held and
- * applies the new regdomain synchronously to this wiphy. For more details
- * see regulatory_set_wiphy_regd().
+ * This functions requires the wiphy mutex to be held and applies the new
+ * regdomain synchronously to this wiphy. For more details see
+ * regulatory_set_wiphy_regd().
*
* Return: 0 on success. -EINVAL, -EPERM
*/
@@ -8143,6 +8237,8 @@ void wiphy_apply_custom_regulatory(struct wiphy *wiphy,
* it wants to follow we respect that unless a country IE has been received
* and processed already.
*
+ * Must be called within an RCU read-side critical section.
+ *
* Return: A valid pointer, or, when an error occurs, for example if no rule
* can be found, the return value is encoded using ERR_PTR(). Use IS_ERR() to
* check and PTR_ERR() to obtain the numeric return value. The numeric return
@@ -8181,20 +8277,20 @@ bool regulatory_pre_cac_allowed(struct wiphy *wiphy);
*/
/**
- * reg_query_regdb_wmm - Query internal regulatory db for wmm rule
- * Regulatory self-managed driver can use it to proactively
- *
+ * reg_query_regdb_wmm - Query internal regulatory db for WMM rules
* @alpha2: the ISO/IEC 3166 alpha2 wmm rule to be queried.
* @freq: the frequency (in MHz) to be queried.
- * @rule: pointer to store the wmm rule from the regulatory db.
+ * @rule: pointer to store the WMM rule from the regulatory db.
*
- * Self-managed wireless drivers can use this function to query
+ * Self-managed wireless drivers can use this function to query
* the internal regulatory database to check whether the given
- * ISO/IEC 3166 alpha2 country and freq have wmm rule limitations.
+ * ISO/IEC 3166 alpha2 country and freq have WMM rule limitations.
*
* Drivers should check the return value, its possible you can get
* an -ENODATA.
*
+ * This uses RCU internally so can be called in just about any context.
+ *
* Return: 0 on success. -ENODATA.
*/
int reg_query_regdb_wmm(char *alpha2, int freq,
@@ -9501,6 +9597,7 @@ void cfg80211_conn_failed(struct net_device *dev, const u8 *mac_addr,
* @flags: flags, as defined in &enum nl80211_rxmgmt_flags
* @rx_tstamp: Hardware timestamp of frame RX in nanoseconds
* @ack_tstamp: Hardware timestamp of ack TX in nanoseconds
+ * @no_sta: set if no station is known for the frame (relevant for MLD)
*/
struct cfg80211_rx_info {
int freq;
@@ -9512,6 +9609,7 @@ struct cfg80211_rx_info {
u32 flags;
u64 rx_tstamp;
u64 ack_tstamp;
+ bool no_sta;
};
/**
@@ -9752,6 +9850,7 @@ void cfg80211_cqm_beacon_loss_notify(struct net_device *dev, gfp_t gfp);
* @gfp: context flags
*
* This function is called when a radar is detected on the current chanenl.
+ * Must be called with the wiphy mutex held.
*/
void __cfg80211_radar_event(struct wiphy *wiphy,
struct cfg80211_chan_def *chandef,
@@ -9797,7 +9896,7 @@ void cfg80211_sta_opmode_change_notify(struct net_device *dev, const u8 *mac,
*
* This function is called when a Channel availability check (CAC) is finished
* or aborted. This must be called to notify the completion of a CAC process,
- * also by full-MAC drivers.
+ * also by full-MAC drivers. Must be called with the wiphy mutex held.
*/
void cfg80211_cac_event(struct net_device *netdev,
const struct cfg80211_chan_def *chandef,
@@ -10109,6 +10208,9 @@ u32 cfg80211_calculate_bitrate(struct rate_info *rate);
* when the driver wishes to unregister the wdev, e.g. when the hardware device
* is unbound from the driver.
*
+ * Note that unlocked operations can run concurrently until this returns, so be
+ * careful about ordering.
+ *
* Context: Requires the RTNL and wiphy mutex to be held.
*/
void cfg80211_unregister_wdev(struct wireless_dev *wdev);
diff --git a/include/net/cfg802154.h b/include/net/cfg802154.h
index 76d2cd2e2b30..2c5dcf6a106f 100644
--- a/include/net/cfg802154.h
+++ b/include/net/cfg802154.h
@@ -376,6 +376,7 @@ struct cfg802154_mac_pkt {
struct list_head node;
struct sk_buff *skb;
struct ieee802154_sub_if_data *sdata;
+ netdevice_tracker dev_tracker;
u8 page;
u8 channel;
};
@@ -457,15 +458,16 @@ struct ieee802154_llsec_device_key {
u32 frame_counter;
};
-struct wpan_dev_header_ops {
+struct wpan_dev_ops {
/* TODO create callback currently assumes ieee802154_mac_cb inside
* skb->cb. This should be changed to give these information as
* parameter.
*/
- int (*create)(struct sk_buff *skb, struct net_device *dev,
+ int (*header_create)(struct sk_buff *skb, struct net_device *dev,
const struct ieee802154_addr *daddr,
const struct ieee802154_addr *saddr,
unsigned int len);
+ int (*ioctl)(struct net_device *dev, struct ifreq *ifr, int cmd);
};
struct wpan_dev {
@@ -476,7 +478,7 @@ struct wpan_dev {
struct list_head list;
struct net_device *netdev;
- const struct wpan_dev_header_ops *header_ops;
+ const struct wpan_dev_ops *ops;
/* lowpan interface, set when the wpan_dev belongs to one lowpan_dev */
struct net_device *lowpan_dev;
@@ -522,7 +524,7 @@ wpan_dev_hard_header(struct sk_buff *skb, struct net_device *dev,
{
struct wpan_dev *wpan_dev = dev->ieee802154_ptr;
- return wpan_dev->header_ops->create(skb, dev, daddr, saddr, len);
+ return wpan_dev->ops->header_create(skb, dev, daddr, saddr, len);
}
#endif
diff --git a/include/net/codel.h b/include/net/codel.h
index aa80f744826c..183d43c2bd43 100644
--- a/include/net/codel.h
+++ b/include/net/codel.h
@@ -140,6 +140,11 @@ struct codel_vars {
/* needed shift to get a Q0.32 number from rec_inv_sqrt */
#define REC_INV_SQRT_SHIFT (32 - REC_INV_SQRT_BITS)
+/* Cap on drops per codel_dequeue() call: the loop's work depends on the
+ * idle gap and backlog, both outside our control; resync when exceeded.
+ */
+#define CODEL_MAX_DROPS_PER_DEQUEUE 256
+
/**
* struct codel_stats - contains codel shared variables and stats
* @maxpacket: largest packet we've seen so far
diff --git a/include/net/codel_impl.h b/include/net/codel_impl.h
index 2c1f0ec309e9..8f26132d45b7 100644
--- a/include/net/codel_impl.h
+++ b/include/net/codel_impl.h
@@ -93,12 +93,17 @@ static void codel_Newton_step(struct codel_vars *vars)
* CoDel control_law is t + interval/sqrt(count)
* We maintain in rec_inv_sqrt the reciprocal value of sqrt(count) to avoid
* both sqrt() and divide operation.
+ *
+ * Clamp the increment to at least 1 tick: a very small interval (or a
+ * large count) can truncate it to zero, stalling the dropping loop.
*/
static codel_time_t codel_control_law(codel_time_t t,
codel_time_t interval,
u32 rec_inv_sqrt)
{
- return t + reciprocal_scale(interval, rec_inv_sqrt << REC_INV_SQRT_SHIFT);
+ return t + max_t(u32, 1,
+ reciprocal_scale(interval,
+ rec_inv_sqrt << REC_INV_SQRT_SHIFT));
}
static bool codel_should_drop(const struct sk_buff *skb,
@@ -154,6 +159,7 @@ static struct sk_buff *codel_dequeue(void *ctx,
codel_skb_dequeue_t dequeue_func)
{
struct sk_buff *skb = dequeue_func(vars, ctx);
+ unsigned int drops = 0;
codel_time_t now;
bool drop;
@@ -180,6 +186,14 @@ static struct sk_buff *codel_dequeue(void *ctx,
*/
while (vars->dropping &&
codel_time_after_eq(now, vars->drop_next)) {
+ if (++drops > CODEL_MAX_DROPS_PER_DEQUEUE) {
+ /* fell far behind the schedule */
+ WRITE_ONCE(vars->drop_next,
+ codel_control_law(now,
+ params->interval,
+ vars->rec_inv_sqrt));
+ break;
+ }
/* dont care of possible wrap
* since there is no more divide.
*/
diff --git a/include/net/dropreason-core.h b/include/net/dropreason-core.h
index 2f312d1f67d6..fa2fe8990557 100644
--- a/include/net/dropreason-core.h
+++ b/include/net/dropreason-core.h
@@ -82,7 +82,6 @@
FN(DEV_READY) \
FN(FULL_RING) \
FN(NOMEM) \
- FN(HDR_TRUNC) \
FN(TAP_FILTER) \
FN(TAP_TXFILTER) \
FN(ICMP_CSUM) \
@@ -93,6 +92,7 @@
FN(IP_INVALID_SOURCE) \
FN(IP_LOCALNET) \
FN(IP_INVALID_DEST) \
+ FN(IP_TTL_EXCEEDED) \
FN(PKT_TOO_BIG) \
FN(DUP_FRAG) \
FN(FRAG_REASM_TIMEOUT) \
@@ -110,8 +110,8 @@
FN(PACKET_SOCK_ERROR) \
FN(TC_CHAIN_NOTFOUND) \
FN(TC_RECLASSIFY_LOOP) \
- FN(VXLAN_INVALID_HDR) \
- FN(VXLAN_VNI_NOT_FOUND) \
+ FN(TUNNEL_INVALID_HDR) \
+ FN(TUNNEL_NOT_FOUND) \
FN(MAC_INVALID_SOURCE) \
FN(VXLAN_ENTRY_EXISTS) \
FN(NO_TX_TARGET) \
@@ -427,12 +427,6 @@ enum skb_drop_reason {
/** @SKB_DROP_REASON_NOMEM: error due to OOM */
SKB_DROP_REASON_NOMEM,
/**
- * @SKB_DROP_REASON_HDR_TRUNC: failed to trunc/extract the header from
- * networking data, e.g., failed to pull the protocol header from
- * frags via pskb_may_pull()
- */
- SKB_DROP_REASON_HDR_TRUNC,
- /**
* @SKB_DROP_REASON_TAP_FILTER: dropped by (ebpf) filter directly attached
* to tun/tap, e.g., via TUNSETFILTEREBPF
*/
@@ -475,6 +469,11 @@ enum skb_drop_reason {
*/
SKB_DROP_REASON_IP_INVALID_DEST,
/**
+ * @SKB_DROP_REASON_IP_TTL_EXCEEDED: IPv4 TTL or IPv6 hop limit <= 1
+ * (see IPSTATS_MIB_INHDRERRORS)
+ */
+ SKB_DROP_REASON_IP_TTL_EXCEEDED,
+ /**
* @SKB_DROP_REASON_PKT_TOO_BIG: packet size is too big (maybe exceed the
* MTU)
*/
@@ -533,13 +532,16 @@ enum skb_drop_reason {
*/
SKB_DROP_REASON_TC_RECLASSIFY_LOOP,
/**
- * @SKB_DROP_REASON_VXLAN_INVALID_HDR: VXLAN header is invalid. E.g.:
- * 1) reserved fields are not zero
- * 2) "I" flag is not set
+ * @SKB_DROP_REASON_TUNNEL_INVALID_HDR: tunnel header is invalid. E.g.:
+ * 1) VXLAN reserved fields are not zero
+ * 2) VXLAN "I" flag is not set
*/
- SKB_DROP_REASON_VXLAN_INVALID_HDR,
- /** @SKB_DROP_REASON_VXLAN_VNI_NOT_FOUND: no VXLAN device found for VNI */
- SKB_DROP_REASON_VXLAN_VNI_NOT_FOUND,
+ SKB_DROP_REASON_TUNNEL_INVALID_HDR,
+ /**
+ * @SKB_DROP_REASON_TUNNEL_NOT_FOUND: no tunnel device found for the
+ * packet, e.g. no VXLAN device for its VNI
+ */
+ SKB_DROP_REASON_TUNNEL_NOT_FOUND,
/** @SKB_DROP_REASON_MAC_INVALID_SOURCE: source mac is invalid */
SKB_DROP_REASON_MAC_INVALID_SOURCE,
/**
@@ -604,7 +606,11 @@ enum skb_drop_reason {
SKB_DROP_REASON_PSP_INPUT,
/** @SKB_DROP_REASON_PSP_OUTPUT: PSP output checks failed */
SKB_DROP_REASON_PSP_OUTPUT,
- /** @SKB_DROP_REASON_RECURSION_LIMIT: Dead loop on virtual device. */
+ /**
+ * @SKB_DROP_REASON_RECURSION_LIMIT: Dead loop on virtual device, e.g. a
+ * tunnel whose route to its remote end goes out of the tunnel device
+ * itself.
+ */
SKB_DROP_REASON_RECURSION_LIMIT,
/**
* @SKB_DROP_REASON_MAX: the maximum of core drop reasons, which
diff --git a/include/net/dsa.h b/include/net/dsa.h
index 7507d632e7c6..5d12191b6f6f 100644
--- a/include/net/dsa.h
+++ b/include/net/dsa.h
@@ -61,6 +61,7 @@ struct tc_action;
#define DSA_TAG_PROTO_NETC_VALUE 33
#define DSA_TAG_PROTO_KSZ8463_VALUE 34
#define DSA_TAG_PROTO_MT7628_VALUE 35
+#define DSA_TAG_PROTO_KS8995_VALUE 36
enum dsa_tag_protocol {
DSA_TAG_PROTO_NONE = DSA_TAG_PROTO_NONE_VALUE,
@@ -99,6 +100,7 @@ enum dsa_tag_protocol {
DSA_TAG_PROTO_NETC = DSA_TAG_PROTO_NETC_VALUE,
DSA_TAG_PROTO_KSZ8463 = DSA_TAG_PROTO_KSZ8463_VALUE,
DSA_TAG_PROTO_MT7628 = DSA_TAG_PROTO_MT7628_VALUE,
+ DSA_TAG_PROTO_KS8995 = DSA_TAG_PROTO_KS8995_VALUE,
};
struct dsa_switch;
diff --git a/include/net/dst.h b/include/net/dst.h
index 307073eae7f8..dbedfe72e1fd 100644
--- a/include/net/dst.h
+++ b/include/net/dst.h
@@ -455,7 +455,8 @@ static inline unsigned int dst_dev_overhead(struct dst_entry *dst,
struct sk_buff *skb)
{
if (likely(dst))
- return LL_RESERVED_SPACE(dst->dev);
+ return max_t(unsigned int, skb->mac_len,
+ LL_RESERVED_SPACE(dst->dev));
return skb->mac_len;
}
diff --git a/include/net/gso.h b/include/net/gso.h
index 29975440cad5..fe3260b381d4 100644
--- a/include/net/gso.h
+++ b/include/net/gso.h
@@ -19,10 +19,20 @@ struct skb_gso_cb {
int encap_level;
__wsum csum;
__u16 csum_start;
+ /* Number of IPv4/IPv6 GSO handler entries for this packet. */
+ u8 recursion_counter;
+ /* Max MSS segs per output skb, 0 = no limit */
+ u8 max_segs;
};
#define SKB_GSO_CB_OFFSET 32
#define SKB_GSO_CB(skb) ((struct skb_gso_cb *)((skb)->cb + SKB_GSO_CB_OFFSET))
+static inline bool gso_recursion_inc_test(struct sk_buff *skb,
+ unsigned int limit)
+{
+ return ++SKB_GSO_CB(skb)->recursion_counter > limit;
+}
+
static inline int skb_tnl_header_len(const struct sk_buff *inner_skb)
{
return (skb_mac_header(inner_skb) - inner_skb->head) -
@@ -75,12 +85,13 @@ static inline __sum16 gso_make_checksum(struct sk_buff *skb, __wsum res)
}
struct sk_buff *__skb_gso_segment(struct sk_buff *skb,
- netdev_features_t features, bool tx_path);
+ netdev_features_t features, bool tx_path,
+ unsigned int max_segs);
static inline struct sk_buff *skb_gso_segment(struct sk_buff *skb,
netdev_features_t features)
{
- return __skb_gso_segment(skb, features, true);
+ return __skb_gso_segment(skb, features, true, 0);
}
struct sk_buff *skb_eth_gso_segment(struct sk_buff *skb,
diff --git a/include/net/gue.h b/include/net/gue.h
index caefd6da8693..d377155fd0b3 100644
--- a/include/net/gue.h
+++ b/include/net/gue.h
@@ -84,8 +84,9 @@ static inline size_t guehdr_priv_flags_len(__be32 flags)
}
/* Validate standard and private flags. Returns non-zero (meaning invalid)
- * if there is an unknown standard or private flags, or the options length for
- * the flags exceeds the options length specific in hlen of the GUE header.
+ * if there is an unknown standard or private flags, if the options length for
+ * the flags exceeds the options length specified in hlen of the GUE header, or
+ * if a private option contains invalid data.
*/
static inline int validate_gue_flags(struct guehdr *guehdr, size_t optlen)
{
@@ -103,8 +104,8 @@ static inline int validate_gue_flags(struct guehdr *guehdr, size_t optlen)
/* Private flags are last four bytes accounted in
* guehdr_flags_len
*/
- __be32 pflags = *(__be32 *)((void *)&guehdr[1] +
- len - GUE_LEN_PRIV);
+ void *data = (void *)&guehdr[1] + len;
+ __be32 pflags = *(__be32 *)(data - GUE_LEN_PRIV);
if (pflags & ~GUE_PFLAGS_ALL)
return 1;
@@ -112,6 +113,16 @@ static inline int validate_gue_flags(struct guehdr *guehdr, size_t optlen)
len += guehdr_priv_flags_len(pflags);
if (len > optlen)
return 1;
+
+ if (pflags & GUE_PFLAG_REMCSUM) {
+ __be16 *pd = data;
+
+ /* The field offset pd[1] must not be less
+ * than the start pd[0].
+ */
+ if (ntohs(pd[1]) < ntohs(pd[0]))
+ return 1;
+ }
}
return 0;
diff --git a/include/net/ieee80211_radiotap.h b/include/net/ieee80211_radiotap.h
index 8bbaf77da7cf..782c3dcd8b52 100644
--- a/include/net/ieee80211_radiotap.h
+++ b/include/net/ieee80211_radiotap.h
@@ -1,6 +1,6 @@
/*
* Copyright (c) 2017 Intel Deutschland GmbH
- * Copyright (c) 2018-2019, 2021-2022, 2025 Intel Corporation
+ * Copyright (c) 2018-2019, 2021-2022, 2025-2026 Intel Corporation
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@@ -93,6 +93,7 @@ enum ieee80211_radiotap_presence {
IEEE80211_RADIOTAP_RADIOTAP_NAMESPACE = 29,
IEEE80211_RADIOTAP_VENDOR_NAMESPACE = 30,
IEEE80211_RADIOTAP_EXT = 31,
+ IEEE80211_RADIOTAP_S1G = 32,
IEEE80211_RADIOTAP_EHT_USIG = 33,
IEEE80211_RADIOTAP_EHT = 34,
IEEE80211_RADIOTAP_UHR_ELR = 37,
@@ -112,6 +113,9 @@ enum ieee80211_radiotap_flags {
/* for IEEE80211_RADIOTAP_CHANNEL */
enum ieee80211_radiotap_channel_flags {
+ IEEE80211_CHAN_700MHZ = 0x0001,
+ IEEE80211_CHAN_800MHZ = 0x0002,
+ IEEE80211_CHAN_900MHZ = 0x0004,
IEEE80211_CHAN_CCK = 0x0020,
IEEE80211_CHAN_OFDM = 0x0040,
IEEE80211_CHAN_2GHZ = 0x0080,
@@ -592,7 +596,7 @@ enum ieee80211_radiotap_eht_usig_mu {
enum ieee80211_radiotap_eht_usig_tb {
/* TB-USIG-1 */
- IEEE80211_RADIOTAP_EHT_USIG1_TB_B20_B25_DISREGARD = 0x0000001f,
+ IEEE80211_RADIOTAP_EHT_USIG1_TB_B20_B25_DISREGARD = 0x0000003f,
/* TB-USIG-2 */
IEEE80211_RADIOTAP_EHT_USIG2_TB_B0_B1_PPDU_TYPE = 0x000000c0,
@@ -604,6 +608,49 @@ enum ieee80211_radiotap_eht_usig_tb {
IEEE80211_RADIOTAP_EHT_USIG2_TB_B20_B25_TAIL = 0xfc000000,
};
+enum ieee80211_radiotap_uhr_usig_mu {
+ /* USIG-1 */
+ IEEE80211_RADIOTAP_UHR_USIG1_MU_BSS_COLOR_2 = 0x0000003f,
+ IEEE80211_RADIOTAP_UHR_USIG1_MU_B20_B24_DISREGARD = 0x0000001f,
+ IEEE80211_RADIOTAP_UHR_USIG1_MU_B25_VALIDATE = 0x00000020,
+ /* USIG-2 */
+ IEEE80211_RADIOTAP_UHR_USIG2_MU_B0_B1_PPDU_TYPE = 0x000000c0,
+ IEEE80211_RADIOTAP_UHR_USIG2_MU_B2_COBF_COSR = 0x00000100,
+ IEEE80211_RADIOTAP_UHR_USIG2_MU_B3_B7_PUNCTURED_INFO = 0x00003e00,
+ IEEE80211_RADIOTAP_UHR_USIG2_MU_B8_VALIDATE = 0x00004000,
+ IEEE80211_RADIOTAP_UHR_USIG2_MU_B9_B10_SIG_MCS = 0x00018000,
+ IEEE80211_RADIOTAP_UHR_USIG2_MU_B11_B15_UHR_SIG_SYMBOLS = 0x003e0000,
+ IEEE80211_RADIOTAP_UHR_USIG2_MU_B16_B19_CRC = 0x03c00000,
+ IEEE80211_RADIOTAP_UHR_USIG2_MU_B20_B25_TAIL = 0xfc000000,
+};
+
+enum ieee80211_radiotap_uhr_usig_tb {
+ /* USIG-1 */
+ IEEE80211_RADIOTAP_UHR_USIG1_TB_B20_B25_DISREGARD = 0x0000003f,
+
+ /* USIG-2 */
+ IEEE80211_RADIOTAP_UHR_USIG2_TB_B0_B1_PPDU_TYPE = 0x000000c0,
+ IEEE80211_RADIOTAP_UHR_USIG2_TB_B2_VALIDATE = 0x00000100,
+ IEEE80211_RADIOTAP_UHR_USIG2_TB_B3_B6_SPATIAL_REUSE_1 = 0x00001e00,
+ IEEE80211_RADIOTAP_UHR_USIG2_TB_B7_B10_SPATIAL_REUSE_2 = 0x0001e000,
+ IEEE80211_RADIOTAP_UHR_USIG2_TB_B11_B15_DISREGARD = 0x003e0000,
+ IEEE80211_RADIOTAP_UHR_USIG2_TB_B16_B19_CRC = 0x03c00000,
+ IEEE80211_RADIOTAP_UHR_USIG2_TB_B20_B25_TAIL = 0xfc000000,
+};
+
+enum ieee80211_radiotap_uhr_usig_elr {
+ /* USIG-1 */
+ IEEE80211_RADIOTAP_UHR_USIG1_ELR_B20_B24_DISREGARD = 0x0000001f,
+ IEEE80211_RADIOTAP_UHR_USIG1_ELR_B25_VALIDATE = 0x00000020,
+
+ /* USIG-2 */
+ IEEE80211_RADIOTAP_UHR_USIG2_ELR_B0_B1_PPDU_TYPE = 0x000000c0,
+ IEEE80211_RADIOTAP_UHR_USIG2_ELR_B2_B12_STA_ID = 0x0007ff00,
+ IEEE80211_RADIOTAP_UHR_USIG2_ELR_B13_B15_VALIDATE = 0x00380000,
+ IEEE80211_RADIOTAP_UHR_USIG2_ELR_B16_B19_CRC = 0x03c00000,
+ IEEE80211_RADIOTAP_UHR_USIG2_ELR_B20_B25_TAIL = 0xfc000000,
+};
+
/*
* ieee80211_radiotap_uhr_elr - content of UHR-ELR TLV (type 37)
* see https://www.radiotap.org/fields/UHR-ELR for details
@@ -792,6 +839,68 @@ enum ieee80211_radiotap_uhr_user_info {
IEEE80211_RADIOTAP_UHR_USER_INFO_2X_LDPC = 0x02000000,
};
+/*
+ * ieee80211_radiotap_s1g - content of S1G TLV (type 32)
+ * see www.radiotap.org/fields/S1G.html for details
+ */
+struct ieee80211_radiotap_s1g {
+ __le16 known;
+ __le16 data1;
+ __le16 data2;
+} __packed;
+
+enum ieee80211_radiotap_s1g_known {
+ IEEE80211_RADIOTAP_S1G_KNOWN_PPDU_FORMAT = 0x0001,
+ IEEE80211_RADIOTAP_S1G_KNOWN_RESPONSE_IND = 0x0002,
+ IEEE80211_RADIOTAP_S1G_KNOWN_GI = 0x0004,
+ IEEE80211_RADIOTAP_S1G_KNOWN_NSS = 0x0008,
+ IEEE80211_RADIOTAP_S1G_KNOWN_BW = 0x0010,
+ IEEE80211_RADIOTAP_S1G_KNOWN_MCS = 0x0020,
+ IEEE80211_RADIOTAP_S1G_KNOWN_COLOR = 0x0040,
+ IEEE80211_RADIOTAP_S1G_KNOWN_UPLINK_IND = 0x0080,
+};
+
+enum ieee80211_radiotap_s1g_data1 {
+ IEEE80211_RADIOTAP_S1G_DATA1_PPDU_FORMAT = 0x0003,
+ IEEE80211_RADIOTAP_S1G_DATA1_RESPONSE_IND = 0x000c,
+ IEEE80211_RADIOTAP_S1G_DATA1_GI = 0x0020,
+ IEEE80211_RADIOTAP_S1G_DATA1_NSS = 0x00c0,
+ IEEE80211_RADIOTAP_S1G_DATA1_BW = 0x0f00,
+ IEEE80211_RADIOTAP_S1G_DATA1_MCS = 0xf000,
+};
+
+enum ieee80211_radiotap_s1g_data2 {
+ IEEE80211_RADIOTAP_S1G_DATA2_COLOR = 0x0007,
+ IEEE80211_RADIOTAP_S1G_DATA2_UPLINK_IND = 0x0008,
+ IEEE80211_RADIOTAP_S1G_DATA2_RSSI = 0xff00,
+};
+
+enum ieee80211_radiotap_s1g_ppdu_format {
+ IEEE80211_RADIOTAP_S1G_PPDU_FORMAT_1M = 0,
+ IEEE80211_RADIOTAP_S1G_PPDU_FORMAT_SHORT = 1,
+ IEEE80211_RADIOTAP_S1G_PPDU_FORMAT_LONG = 2,
+};
+
+enum ieee80211_radiotap_s1g_response_ind {
+ IEEE80211_RADIOTAP_S1G_RESPONSE_IND_NONE = 0,
+ IEEE80211_RADIOTAP_S1G_RESPONSE_IND_NDP = 1,
+ IEEE80211_RADIOTAP_S1G_RESPONSE_IND_NORMAL = 2,
+ IEEE80211_RADIOTAP_S1G_RESPONSE_IND_LONG = 3,
+};
+
+enum ieee80211_radiotap_s1g_gi {
+ IEEE80211_RADIOTAP_S1G_GI_LONG = 0,
+ IEEE80211_RADIOTAP_S1G_GI_SHORT = 1,
+};
+
+enum ieee80211_radiotap_s1g_bw {
+ IEEE80211_RADIOTAP_S1G_BW_1MHZ = 0,
+ IEEE80211_RADIOTAP_S1G_BW_2MHZ = 1,
+ IEEE80211_RADIOTAP_S1G_BW_4MHZ = 2,
+ IEEE80211_RADIOTAP_S1G_BW_8MHZ = 3,
+ IEEE80211_RADIOTAP_S1G_BW_16MHZ = 4,
+};
+
/**
* ieee80211_get_radiotap_len - get radiotap header length
* @data: pointer to the header
diff --git a/include/net/inet_connection_sock.h b/include/net/inet_connection_sock.h
index 433c2df23076..903499581db7 100644
--- a/include/net/inet_connection_sock.h
+++ b/include/net/inet_connection_sock.h
@@ -94,6 +94,7 @@ struct inet_connection_sock {
u32 icsk_rto_max;
__u32 icsk_delack_max;
__u32 icsk_pmtu_cookie;
+ unsigned char unhashed_state;
const struct tcp_congestion_ops *icsk_ca_ops;
const struct inet_connection_sock_af_ops *icsk_af_ops;
const struct tcp_ulp_ops *icsk_ulp_ops;
diff --git a/include/net/inet_sock.h b/include/net/inet_sock.h
index 7cdcbed3e5cb..24cbabc24582 100644
--- a/include/net/inet_sock.h
+++ b/include/net/inet_sock.h
@@ -207,7 +207,7 @@ struct rtable;
* @inet_saddr - Sending source
* @uc_ttl - Unicast TTL
* @inet_sport - Source port
- * @inet_id - ID counter for DF pkts
+ * @inet_id - ID counter for non atomic pkts
* @tos - TOS
* @mc_ttl - Multicasting TTL
* @uc_index - Unicast outgoing device index
diff --git a/include/net/ip.h b/include/net/ip.h
index 6f602df72ee6..618b9806c10b 100644
--- a/include/net/ip.h
+++ b/include/net/ip.h
@@ -74,6 +74,13 @@ static inline unsigned int ip_hdrlen(const struct sk_buff *skb)
return ip_hdr(skb)->ihl * 4;
}
+static inline int ip_check_csum_start(const struct sk_buff *skb)
+{
+ if (unlikely(skb->csum_start < skb->network_header + ip_hdrlen(skb)))
+ return -EINVAL;
+ return 0;
+}
+
struct ipcm_cookie {
struct sockcm_cookie sockc;
__be32 addr;
@@ -584,6 +591,13 @@ static inline void ip_select_ident_segs(struct net *net, struct sk_buff *skb,
{
struct iphdr *iph = ip_hdr(skb);
+ /* RFC 6864: the IPv4 ID of atomic datagrams has no meaning.
+ * DF packets without ignore_df can not be fragmented.
+ */
+ if ((iph->frag_off & htons(IP_DF)) && !skb->ignore_df) {
+ iph->id = 0;
+ return;
+ }
/* We had many attacks based on IPID, use the private
* generator as much as we can.
*/
@@ -598,17 +612,13 @@ static inline void ip_select_ident_segs(struct net *net, struct sk_buff *skb,
val = atomic_read(&inet_sk(sk)->inet_id);
atomic_set(&inet_sk(sk)->inet_id, val + segs);
} else {
- val = atomic_add_return(segs, &inet_sk(sk)->inet_id);
+ val = atomic_fetch_add(segs, &inet_sk(sk)->inet_id);
}
iph->id = htons(val);
return;
}
- if ((iph->frag_off & htons(IP_DF)) && !skb->ignore_df) {
- iph->id = 0;
- } else {
- /* Unfortunately we need the big hammer to get a suitable IPID */
- __ip_select_ident(net, iph, segs);
- }
+ /* Unfortunately we need the big hammer to get a suitable IPID */
+ __ip_select_ident(net, iph, segs);
}
static inline void ip_select_ident(struct net *net, struct sk_buff *skb,
diff --git a/include/net/ip6_route.h b/include/net/ip6_route.h
index c69f1c871922..5f47cef0be46 100644
--- a/include/net/ip6_route.h
+++ b/include/net/ip6_route.h
@@ -101,12 +101,12 @@ static inline struct dst_entry *ip6_route_output(struct net *net,
}
/* Only conditionally release dst if flags indicates
- * !RT6_LOOKUP_F_DST_NOREF or dst is in uncached_list.
+ * !RT6_LOOKUP_F_DST_NOREF or dst is uncached.
*/
static inline void ip6_rt_put_flags(struct rt6_info *rt, int flags)
{
if (!(flags & RT6_LOOKUP_F_DST_NOREF) ||
- !list_empty(&rt->dst.rt_uncached))
+ rt->dst.rt_uncached_list)
ip6_rt_put(rt);
}
@@ -231,6 +231,13 @@ void rt6_multipath_rebalance(struct fib6_info *f6i);
void rt6_uncached_list_add(struct rt6_info *rt);
void rt6_uncached_list_del(struct rt6_info *rt);
+#ifdef CONFIG_IPV6
+void rt6_uncached_list_flush_dev(struct net_device *dev);
+#else
+static inline void rt6_uncached_list_flush_dev(struct net_device *dev)
+{
+}
+#endif
static inline const struct rt6_info *skb_rt6_info(const struct sk_buff *skb)
{
@@ -384,6 +391,8 @@ static inline unsigned int ip6_dst_mtu_maybe_forward(const struct dst_entry *dst
rcu_read_unlock();
out:
+ mtu = min_t(unsigned int, mtu, IP6_MAX_MTU);
+
return mtu - lwtunnel_headroom(dst->lwtstate, mtu);
}
@@ -428,7 +437,7 @@ u32 ip6_mtu_from_fib6(const struct fib6_result *res,
const struct in6_addr *daddr,
const struct in6_addr *saddr);
-struct neighbour *ip6_neigh_lookup(const struct in6_addr *gw,
- struct net_device *dev, struct sk_buff *skb,
- const void *daddr);
+struct neighbour *__ip6_dst_neigh_lookup(const struct in6_addr *gw,
+ struct net_device *dev, struct sk_buff *skb,
+ const void *daddr);
#endif
diff --git a/include/net/ip6_tunnel.h b/include/net/ip6_tunnel.h
index b99805ee2fd1..d1f0a427e9c8 100644
--- a/include/net/ip6_tunnel.h
+++ b/include/net/ip6_tunnel.h
@@ -45,6 +45,7 @@ struct __ip6_tnl_parm {
/* IPv6 tunnel */
struct ip6_tnl {
struct ip6_tnl __rcu *next; /* next tunnel in list */
+ struct hlist_node hash_node;
struct net_device *dev; /* virtual device associated with tunnel */
netdevice_tracker dev_tracker;
struct net *net; /* netns for packet i/o */
diff --git a/include/net/ip_fib.h b/include/net/ip_fib.h
index 0a35355fb0f3..92f4eb8b86d7 100644
--- a/include/net/ip_fib.h
+++ b/include/net/ip_fib.h
@@ -258,6 +258,7 @@ struct fib_table {
struct hlist_node tb_hlist;
u32 tb_id;
int tb_num_default;
+ struct net *tb_net;
struct rcu_head rcu;
unsigned long *tb_data;
unsigned long __data[];
@@ -591,7 +592,8 @@ void fib_nh_common_release(struct fib_nh_common *nhc);
/* Exported by fib_trie.c */
void fib_alias_hw_flags_set(struct net *net, const struct fib_rt_info *fri);
void fib_trie_init(void);
-struct fib_table *fib_trie_table(u32 id, struct fib_table *alias);
+struct fib_table *fib_trie_table(struct net *net, u32 id,
+ struct fib_table *alias);
bool fib_lookup_good_nhc(const struct fib_nh_common *nhc, int fib_flags,
const struct flowi4 *flp);
diff --git a/include/net/ip_tunnels.h b/include/net/ip_tunnels.h
index 7c9aadfe8fe3..5cccf4c0e691 100644
--- a/include/net/ip_tunnels.h
+++ b/include/net/ip_tunnels.h
@@ -127,6 +127,7 @@ struct ip_tunnel_6rd_parm {
__be32 relay_prefix;
u16 prefixlen;
u16 relay_prefixlen;
+ struct rcu_head rcu;
};
#endif
@@ -148,6 +149,7 @@ struct ip_tunnel_parm_kern {
__be32 o_key;
int link;
struct iphdr iph;
+ struct rcu_head rcu;
};
struct ip_tunnel {
@@ -185,10 +187,11 @@ struct ip_tunnel {
/* for SIT */
#ifdef CONFIG_IPV6_SIT_6RD
- struct ip_tunnel_6rd_parm ip6rd;
+ struct ip_tunnel_6rd_parm __rcu *ip6rd;
#endif
struct ip_tunnel_prl_entry __rcu *prl; /* potential router list */
unsigned int prl_count; /* # of entries in PRL */
+ struct ip_tunnel_parm_kern __rcu *sit_parms;
unsigned int ip_tnl_net_id;
struct gro_cells gro_cells;
__u32 fwmark;
@@ -215,6 +218,7 @@ struct ip_tunnel_net {
struct net_device *fb_tunnel_dev;
struct rtnl_link_ops *rtnl_link_ops;
struct hlist_head tunnels[IP_TNL_HASH_SIZE];
+ struct mutex tunnels_lock;
struct ip_tunnel __rcu *collect_md_tun;
int type;
};
@@ -398,7 +402,6 @@ int ip_tunnel_get_iflink(const struct net_device *dev);
int ip_tunnel_init_net(struct net *net, unsigned int ip_tnl_net_id,
struct rtnl_link_ops *ops, char *devname);
void ip_tunnel_delete_net(struct net *net, unsigned int id,
- struct rtnl_link_ops *ops,
struct list_head *dev_to_kill);
void ip_tunnel_xmit(struct sk_buff *skb, struct net_device *dev,
@@ -611,11 +614,13 @@ static inline u8 ip_tunnel_ecn_encap(u8 tos, const struct iphdr *iph,
return INET_ECN_encapsulate(tos, inner);
}
-int __iptunnel_pull_header(struct sk_buff *skb, int hdr_len,
- __be16 inner_proto, bool raw_proto, bool xnet);
+enum skb_drop_reason
+__iptunnel_pull_header(struct sk_buff *skb, int hdr_len,
+ __be16 inner_proto, bool raw_proto, bool xnet);
-static inline int iptunnel_pull_header(struct sk_buff *skb, int hdr_len,
- __be16 inner_proto, bool xnet)
+static inline enum skb_drop_reason
+iptunnel_pull_header(struct sk_buff *skb, int hdr_len,
+ __be16 inner_proto, bool xnet)
{
return __iptunnel_pull_header(skb, hdr_len, inner_proto, false, xnet);
}
diff --git a/include/net/ip_vs.h b/include/net/ip_vs.h
index 32fde731bceb..9a83bff32569 100644
--- a/include/net/ip_vs.h
+++ b/include/net/ip_vs.h
@@ -36,9 +36,6 @@
#define IP_VS_HDR_INVERSE 1
#define IP_VS_HDR_ICMP 2
-/* Destination Server Flags */
-#define IP_VS_DEST_F_OVERLOAD 0x0002 /* server is overloaded */
-
/* Destination Server Config Flags */
#define IP_VS_DEST_CF_AVAILABLE 0x0001 /* server is available */
@@ -973,32 +970,43 @@ struct ip_vs_dest_dst {
* and so on.
*/
struct ip_vs_dest {
+ /* Cacheline for hash table nodes - read-mostly */
+
struct list_head n_list; /* for the dests in the service */
struct hlist_node d_list; /* for table with all the dests */
- u16 af; /* address family */
- __be16 port; /* port number of the server */
- union nf_inet_addr addr; /* IP address of the server */
- volatile unsigned int flags; /* dest status flags */
- atomic_t conn_flags; /* flags to copy to conn */
atomic_t weight; /* server weight */
- unsigned long cflags; /* config flags */
atomic_t last_weight; /* server latest weight */
+
+ /* connection thresholds */
+ u32 l_threshold_val;/* used lower threshold */
+ u32 u_threshold_val;/* used upper threshold */
+ /* 32/48 */
+ u32 l_threshold; /* lower threshold */
+ u32 u_threshold; /* upper threshold */
+
+ unsigned long cflags; /* config flags */
+
+ /* 44/64 */
+ atomic_t conn_flags; /* flags to copy to conn */
+
__u16 tun_type; /* tunnel type */
__be16 tun_port; /* tunnel port */
__u16 tun_flags; /* tunnel flags */
- refcount_t refcnt; /* reference counter */
- struct ip_vs_stats stats; /* statistics */
- unsigned long idle_start; /* start time, jiffies */
+ u16 af; /* address family */
+ __be16 port; /* port number of the server */
+ /* 60/80 */
+ union nf_inet_addr addr; /* IP address of the server */
- /* connection counters and thresholds */
- atomic_t activeconns; /* active connections */
+ /* connection counters */
atomic_t totalconns; /* total connections */
+ atomic_t activeconns; /* active connections */
atomic_t persistconns; /* persistent connections */
- __u32 u_threshold; /* upper threshold */
- __u32 l_threshold; /* lower threshold */
- __u32 l_threshold_val;/* used lower threshold */
+
+ refcount_t refcnt; /* reference counter */
+ struct ip_vs_stats stats; /* statistics */
+ unsigned long idle_start; /* start time, jiffies */
/* for destination cache */
spinlock_t dst_lock; /* lock of dst_cache */
@@ -1915,7 +1923,13 @@ static inline void ip_vs_dest_put_and_free(struct ip_vs_dest *dest)
kfree(dest);
}
-void ip_vs_dest_update_overload(struct ip_vs_dest *dest, int mode);
+void ip_vs_dest_update_overload(struct ip_vs_dest *dest, bool overload);
+
+/* Check if dest is in overloaded state */
+static inline bool ip_vs_dest_is_overloaded(const struct ip_vs_dest *dest)
+{
+ return READ_ONCE(dest->l_threshold_val);
+}
/* IPVS sync daemon data and function prototypes
* (from ip_vs_sync.c)
diff --git a/include/net/llc.h b/include/net/llc.h
index 029ba8a22319..ce7db08e8355 100644
--- a/include/net/llc.h
+++ b/include/net/llc.h
@@ -6,112 +6,44 @@
* 2001-2003 by Arnaldo Carvalho de Melo <acme@conectiva.com.br>
*/
-#include <linux/if.h>
-#include <linux/if_ether.h>
#include <linux/list.h>
-#include <linux/spinlock.h>
-#include <linux/rculist_nulls.h>
-#include <linux/hash.h>
-#include <linux/jhash.h>
-
-#include <linux/atomic.h>
+#include <linux/refcount.h>
struct net_device;
struct packet_type;
struct sk_buff;
-struct llc_addr {
- unsigned char lsap;
- unsigned char mac[IFHWADDRLEN];
-};
-
-#define LLC_SAP_STATE_INACTIVE 1
-#define LLC_SAP_STATE_ACTIVE 2
-
-#define LLC_SK_DEV_HASH_BITS 6
-#define LLC_SK_DEV_HASH_ENTRIES (1<<LLC_SK_DEV_HASH_BITS)
-
-#define LLC_SK_LADDR_HASH_BITS 6
-#define LLC_SK_LADDR_HASH_ENTRIES (1<<LLC_SK_LADDR_HASH_BITS)
-
/**
* struct llc_sap - Defines the SAP component
*
- * @station - station this sap belongs to
- * @state - sap state
- * @p_bit - only lowest-order bit used
- * @f_bit - only lowest-order bit used
- * @laddr - SAP value in this 'lsap'
- * @node - entry in station sap_list
- * @sk_list - LLC sockets this one manages
+ * @refcnt: reference count
+ * @lsap: SAP number
+ * @rcv_func: handler for the PDUs addressed to this SAP
+ * @node: entry in the SAP list
+ * @rcu: for deferred freeing
*/
struct llc_sap {
- unsigned char state;
- unsigned char p_bit;
- unsigned char f_bit;
refcount_t refcnt;
+ unsigned char lsap;
int (*rcv_func)(struct sk_buff *skb,
struct net_device *dev,
struct packet_type *pt,
struct net_device *orig_dev);
- struct llc_addr laddr;
struct list_head node;
- spinlock_t sk_lock;
- int sk_count;
- struct hlist_nulls_head sk_laddr_hash[LLC_SK_LADDR_HASH_ENTRIES];
- struct hlist_head sk_dev_hash[LLC_SK_DEV_HASH_ENTRIES];
struct rcu_head rcu;
};
-static inline
-struct hlist_head *llc_sk_dev_hash(struct llc_sap *sap, int ifindex)
-{
- u32 bucket = hash_32(ifindex, LLC_SK_DEV_HASH_BITS);
-
- return &sap->sk_dev_hash[bucket];
-}
-
-static inline
-u32 llc_sk_laddr_hashfn(struct llc_sap *sap, const struct llc_addr *laddr)
-{
- return hash_32(jhash(laddr->mac, sizeof(laddr->mac), 0),
- LLC_SK_LADDR_HASH_BITS);
-}
-
-static inline
-struct hlist_nulls_head *llc_sk_laddr_hash(struct llc_sap *sap,
- const struct llc_addr *laddr)
-{
- return &sap->sk_laddr_hash[llc_sk_laddr_hashfn(sap, laddr)];
-}
-
-#define LLC_DEST_INVALID 0 /* Invalid LLC PDU type */
-#define LLC_DEST_SAP 1 /* Type 1 goes here */
-#define LLC_DEST_CONN 2 /* Type 2 goes here */
-
-extern struct list_head llc_sap_list;
-
int llc_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt,
struct net_device *orig_dev);
int llc_mac_hdr_init(struct sk_buff *skb, const unsigned char *sa,
const unsigned char *da);
-void llc_add_pack(int type,
- void (*handler)(struct llc_sap *sap, struct sk_buff *skb));
-void llc_remove_pack(int type);
-
-void llc_set_station_handler(void (*handler)(struct sk_buff *skb));
-
struct llc_sap *llc_sap_open(unsigned char lsap,
int (*rcv)(struct sk_buff *skb,
struct net_device *dev,
struct packet_type *pt,
struct net_device *orig_dev));
-static inline void llc_sap_hold(struct llc_sap *sap)
-{
- refcount_inc(&sap->refcnt);
-}
static inline bool llc_sap_hold_safe(struct llc_sap *sap)
{
@@ -130,30 +62,4 @@ struct llc_sap *llc_sap_find(unsigned char sap_value);
int llc_build_and_send_ui_pkt(struct llc_sap *sap, struct sk_buff *skb,
const unsigned char *dmac, unsigned char dsap);
-
-void llc_sap_handler(struct llc_sap *sap, struct sk_buff *skb);
-void llc_conn_handler(struct llc_sap *sap, struct sk_buff *skb);
-
-void llc_station_init(void);
-void llc_station_exit(void);
-
-#ifdef CONFIG_PROC_FS
-int llc_proc_init(void);
-void llc_proc_exit(void);
-#else
-#define llc_proc_init() (0)
-#define llc_proc_exit() do { } while(0)
-#endif /* CONFIG_PROC_FS */
-#ifdef CONFIG_SYSCTL
-int llc_sysctl_init(void);
-void llc_sysctl_exit(void);
-
-extern int sysctl_llc2_ack_timeout;
-extern int sysctl_llc2_busy_timeout;
-extern int sysctl_llc2_p_timeout;
-extern int sysctl_llc2_rej_timeout;
-#else
-#define llc_sysctl_init() (0)
-#define llc_sysctl_exit() do { } while(0)
-#endif /* CONFIG_SYSCTL */
#endif /* LLC_H */
diff --git a/include/net/llc_c_ac.h b/include/net/llc_c_ac.h
deleted file mode 100644
index af31a49bebb0..000000000000
--- a/include/net/llc_c_ac.h
+++ /dev/null
@@ -1,180 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-#ifndef LLC_C_AC_H
-#define LLC_C_AC_H
-/*
- * Copyright (c) 1997 by Procom Technology,Inc.
- * 2001 by Arnaldo Carvalho de Melo <acme@conectiva.com.br>
- */
-/* Connection component state transition actions */
-/*
- * Connection state transition actions
- * (Fb = F bit; Pb = P bit; Xb = X bit)
- */
-
-#include <linux/types.h>
-
-struct sk_buff;
-struct sock;
-struct timer_list;
-
-#define LLC_CONN_AC_CLR_REMOTE_BUSY 1
-#define LLC_CONN_AC_CONN_IND 2
-#define LLC_CONN_AC_CONN_CONFIRM 3
-#define LLC_CONN_AC_DATA_IND 4
-#define LLC_CONN_AC_DISC_IND 5
-#define LLC_CONN_AC_RESET_IND 6
-#define LLC_CONN_AC_RESET_CONFIRM 7
-#define LLC_CONN_AC_REPORT_STATUS 8
-#define LLC_CONN_AC_CLR_REMOTE_BUSY_IF_Fb_EQ_1 9
-#define LLC_CONN_AC_STOP_REJ_TMR_IF_DATA_FLAG_EQ_2 10
-#define LLC_CONN_AC_SEND_DISC_CMD_Pb_SET_X 11
-#define LLC_CONN_AC_SEND_DM_RSP_Fb_SET_Pb 12
-#define LLC_CONN_AC_SEND_DM_RSP_Fb_SET_1 13
-#define LLC_CONN_AC_SEND_DM_RSP_Fb_SET_F_FLAG 14
-#define LLC_CONN_AC_SEND_FRMR_RSP_Fb_SET_X 15
-#define LLC_CONN_AC_RESEND_FRMR_RSP_Fb_SET_0 16
-#define LLC_CONN_AC_RESEND_FRMR_RSP_Fb_SET_Pb 17
-#define LLC_CONN_AC_SEND_I_CMD_Pb_SET_1 18
-#define LLC_CONN_AC_RESEND_I_CMD_Pb_SET_1 19
-#define LLC_CONN_AC_RESEND_I_CMD_Pb_SET_1_OR_SEND_RR 20
-#define LLC_CONN_AC_SEND_I_XXX_Xb_SET_0 21
-#define LLC_CONN_AC_RESEND_I_XXX_Xb_SET_0 22
-#define LLC_CONN_AC_RESEND_I_XXX_Xb_SET_0_OR_SEND_RR 23
-#define LLC_CONN_AC_RESEND_I_RSP_Fb_SET_1 24
-#define LLC_CONN_AC_SEND_REJ_CMD_Pb_SET_1 25
-#define LLC_CONN_AC_SEND_REJ_RSP_Fb_SET_1 26
-#define LLC_CONN_AC_SEND_REJ_XXX_Xb_SET_0 27
-#define LLC_CONN_AC_SEND_RNR_CMD_Pb_SET_1 28
-#define LLC_CONN_AC_SEND_RNR_RSP_Fb_SET_1 29
-#define LLC_CONN_AC_SEND_RNR_XXX_Xb_SET_0 30
-#define LLC_CONN_AC_SET_REMOTE_BUSY 31
-#define LLC_CONN_AC_OPTIONAL_SEND_RNR_XXX_Xb_SET_0 32
-#define LLC_CONN_AC_SEND_RR_CMD_Pb_SET_1 33
-#define LLC_CONN_AC_SEND_ACK_CMD_Pb_SET_1 34
-#define LLC_CONN_AC_SEND_RR_RSP_Fb_SET_1 35
-#define LLC_CONN_AC_SEND_ACK_RSP_Fb_SET_1 36
-#define LLC_CONN_AC_SEND_RR_XXX_Xb_SET_0 37
-#define LLC_CONN_AC_SEND_ACK_XXX_Xb_SET_0 38
-#define LLC_CONN_AC_SEND_SABME_CMD_Pb_SET_X 39
-#define LLC_CONN_AC_SEND_UA_RSP_Fb_SET_Pb 40
-#define LLC_CONN_AC_SEND_UA_RSP_Fb_SET_F_FLAG 41
-#define LLC_CONN_AC_S_FLAG_SET_0 42
-#define LLC_CONN_AC_S_FLAG_SET_1 43
-#define LLC_CONN_AC_START_P_TMR 44
-#define LLC_CONN_AC_START_ACK_TMR 45
-#define LLC_CONN_AC_START_REJ_TMR 46
-#define LLC_CONN_AC_START_ACK_TMR_IF_NOT_RUNNING 47
-#define LLC_CONN_AC_STOP_ACK_TMR 48
-#define LLC_CONN_AC_STOP_P_TMR 49
-#define LLC_CONN_AC_STOP_REJ_TMR 50
-#define LLC_CONN_AC_STOP_ALL_TMRS 51
-#define LLC_CONN_AC_STOP_OTHER_TMRS 52
-#define LLC_CONN_AC_UPDATE_Nr_RECEIVED 53
-#define LLC_CONN_AC_UPDATE_P_FLAG 54
-#define LLC_CONN_AC_DATA_FLAG_SET_2 55
-#define LLC_CONN_AC_DATA_FLAG_SET_0 56
-#define LLC_CONN_AC_DATA_FLAG_SET_1 57
-#define LLC_CONN_AC_DATA_FLAG_SET_1_IF_DATA_FLAG_EQ_0 58
-#define LLC_CONN_AC_P_FLAG_SET_0 59
-#define LLC_CONN_AC_P_FLAG_SET_P 60
-#define LLC_CONN_AC_REMOTE_BUSY_SET_0 61
-#define LLC_CONN_AC_RETRY_CNT_SET_0 62
-#define LLC_CONN_AC_RETRY_CNT_INC_BY_1 63
-#define LLC_CONN_AC_Vr_SET_0 64
-#define LLC_CONN_AC_Vr_INC_BY_1 65
-#define LLC_CONN_AC_Vs_SET_0 66
-#define LLC_CONN_AC_Vs_SET_Nr 67
-#define LLC_CONN_AC_F_FLAG_SET_P 68
-#define LLC_CONN_AC_STOP_SENDACK_TMR 70
-#define LLC_CONN_AC_START_SENDACK_TMR_IF_NOT_RUNNING 71
-
-typedef int (*llc_conn_action_t)(struct sock *sk, struct sk_buff *skb);
-
-int llc_conn_ac_clear_remote_busy(struct sock *sk, struct sk_buff *skb);
-int llc_conn_ac_conn_ind(struct sock *sk, struct sk_buff *skb);
-int llc_conn_ac_conn_confirm(struct sock *sk, struct sk_buff *skb);
-int llc_conn_ac_data_ind(struct sock *sk, struct sk_buff *skb);
-int llc_conn_ac_disc_ind(struct sock *sk, struct sk_buff *skb);
-int llc_conn_ac_rst_ind(struct sock *sk, struct sk_buff *skb);
-int llc_conn_ac_rst_confirm(struct sock *sk, struct sk_buff *skb);
-int llc_conn_ac_clear_remote_busy_if_f_eq_1(struct sock *sk,
- struct sk_buff *skb);
-int llc_conn_ac_stop_rej_tmr_if_data_flag_eq_2(struct sock *sk,
- struct sk_buff *skb);
-int llc_conn_ac_send_disc_cmd_p_set_x(struct sock *sk, struct sk_buff *skb);
-int llc_conn_ac_send_dm_rsp_f_set_p(struct sock *sk, struct sk_buff *skb);
-int llc_conn_ac_send_dm_rsp_f_set_1(struct sock *sk, struct sk_buff *skb);
-int llc_conn_ac_send_frmr_rsp_f_set_x(struct sock *sk, struct sk_buff *skb);
-int llc_conn_ac_resend_frmr_rsp_f_set_0(struct sock *sk, struct sk_buff *skb);
-int llc_conn_ac_resend_frmr_rsp_f_set_p(struct sock *sk, struct sk_buff *skb);
-int llc_conn_ac_send_i_cmd_p_set_1(struct sock *sk, struct sk_buff *skb);
-int llc_conn_ac_send_i_xxx_x_set_0(struct sock *sk, struct sk_buff *skb);
-int llc_conn_ac_resend_i_xxx_x_set_0(struct sock *sk, struct sk_buff *skb);
-int llc_conn_ac_resend_i_xxx_x_set_0_or_send_rr(struct sock *sk,
- struct sk_buff *skb);
-int llc_conn_ac_resend_i_rsp_f_set_1(struct sock *sk, struct sk_buff *skb);
-int llc_conn_ac_send_rej_cmd_p_set_1(struct sock *sk, struct sk_buff *skb);
-int llc_conn_ac_send_rej_rsp_f_set_1(struct sock *sk, struct sk_buff *skb);
-int llc_conn_ac_send_rej_xxx_x_set_0(struct sock *sk, struct sk_buff *skb);
-int llc_conn_ac_send_rnr_cmd_p_set_1(struct sock *sk, struct sk_buff *skb);
-int llc_conn_ac_send_rnr_rsp_f_set_1(struct sock *sk, struct sk_buff *skb);
-int llc_conn_ac_send_rnr_xxx_x_set_0(struct sock *sk, struct sk_buff *skb);
-int llc_conn_ac_set_remote_busy(struct sock *sk, struct sk_buff *skb);
-int llc_conn_ac_opt_send_rnr_xxx_x_set_0(struct sock *sk, struct sk_buff *skb);
-int llc_conn_ac_send_rr_cmd_p_set_1(struct sock *sk, struct sk_buff *skb);
-int llc_conn_ac_send_rr_rsp_f_set_1(struct sock *sk, struct sk_buff *skb);
-int llc_conn_ac_send_ack_rsp_f_set_1(struct sock *sk, struct sk_buff *skb);
-int llc_conn_ac_send_rr_xxx_x_set_0(struct sock *sk, struct sk_buff *skb);
-int llc_conn_ac_send_ack_xxx_x_set_0(struct sock *sk, struct sk_buff *skb);
-int llc_conn_ac_send_sabme_cmd_p_set_x(struct sock *sk, struct sk_buff *skb);
-int llc_conn_ac_send_ua_rsp_f_set_p(struct sock *sk, struct sk_buff *skb);
-int llc_conn_ac_set_s_flag_0(struct sock *sk, struct sk_buff *skb);
-int llc_conn_ac_set_s_flag_1(struct sock *sk, struct sk_buff *skb);
-int llc_conn_ac_start_p_timer(struct sock *sk, struct sk_buff *skb);
-int llc_conn_ac_start_ack_timer(struct sock *sk, struct sk_buff *skb);
-int llc_conn_ac_start_rej_timer(struct sock *sk, struct sk_buff *skb);
-int llc_conn_ac_start_ack_tmr_if_not_running(struct sock *sk,
- struct sk_buff *skb);
-int llc_conn_ac_stop_ack_timer(struct sock *sk, struct sk_buff *skb);
-int llc_conn_ac_stop_p_timer(struct sock *sk, struct sk_buff *skb);
-int llc_conn_ac_stop_rej_timer(struct sock *sk, struct sk_buff *skb);
-int llc_conn_ac_stop_all_timers(struct sock *sk, struct sk_buff *skb);
-int llc_conn_ac_stop_other_timers(struct sock *sk, struct sk_buff *skb);
-int llc_conn_ac_upd_nr_received(struct sock *sk, struct sk_buff *skb);
-int llc_conn_ac_inc_tx_win_size(struct sock *sk, struct sk_buff *skb);
-int llc_conn_ac_dec_tx_win_size(struct sock *sk, struct sk_buff *skb);
-int llc_conn_ac_upd_p_flag(struct sock *sk, struct sk_buff *skb);
-int llc_conn_ac_set_data_flag_2(struct sock *sk, struct sk_buff *skb);
-int llc_conn_ac_set_data_flag_0(struct sock *sk, struct sk_buff *skb);
-int llc_conn_ac_set_data_flag_1(struct sock *sk, struct sk_buff *skb);
-int llc_conn_ac_set_data_flag_1_if_data_flag_eq_0(struct sock *sk,
- struct sk_buff *skb);
-int llc_conn_ac_set_p_flag_0(struct sock *sk, struct sk_buff *skb);
-int llc_conn_ac_set_remote_busy_0(struct sock *sk, struct sk_buff *skb);
-int llc_conn_ac_set_retry_cnt_0(struct sock *sk, struct sk_buff *skb);
-int llc_conn_ac_set_cause_flag_0(struct sock *sk, struct sk_buff *skb);
-int llc_conn_ac_set_cause_flag_1(struct sock *sk, struct sk_buff *skb);
-int llc_conn_ac_inc_retry_cnt_by_1(struct sock *sk, struct sk_buff *skb);
-int llc_conn_ac_set_vr_0(struct sock *sk, struct sk_buff *skb);
-int llc_conn_ac_inc_vr_by_1(struct sock *sk, struct sk_buff *skb);
-int llc_conn_ac_set_vs_0(struct sock *sk, struct sk_buff *skb);
-int llc_conn_ac_set_vs_nr(struct sock *sk, struct sk_buff *skb);
-int llc_conn_ac_rst_vs(struct sock *sk, struct sk_buff *skb);
-int llc_conn_ac_upd_vs(struct sock *sk, struct sk_buff *skb);
-int llc_conn_disc(struct sock *sk, struct sk_buff *skb);
-int llc_conn_reset(struct sock *sk, struct sk_buff *skb);
-int llc_conn_ac_disc_confirm(struct sock *sk, struct sk_buff *skb);
-u8 llc_circular_between(u8 a, u8 b, u8 c);
-int llc_conn_ac_send_ack_if_needed(struct sock *sk, struct sk_buff *skb);
-int llc_conn_ac_adjust_npta_by_rr(struct sock *sk, struct sk_buff *skb);
-int llc_conn_ac_adjust_npta_by_rnr(struct sock *sk, struct sk_buff *skb);
-int llc_conn_ac_rst_sendack_flag(struct sock *sk, struct sk_buff *skb);
-int llc_conn_ac_send_i_as_ack(struct sock *sk, struct sk_buff *skb);
-
-void llc_conn_busy_tmr_cb(struct timer_list *t);
-void llc_conn_pf_cycle_tmr_cb(struct timer_list *t);
-void llc_conn_ack_tmr_cb(struct timer_list *t);
-void llc_conn_rej_tmr_cb(struct timer_list *t);
-
-void llc_conn_set_p_flag(struct sock *sk, u8 value);
-#endif /* LLC_C_AC_H */
diff --git a/include/net/llc_c_ev.h b/include/net/llc_c_ev.h
deleted file mode 100644
index d45140d4289a..000000000000
--- a/include/net/llc_c_ev.h
+++ /dev/null
@@ -1,217 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-#ifndef LLC_C_EV_H
-#define LLC_C_EV_H
-/*
- * Copyright (c) 1997 by Procom Technology,Inc.
- * 2001 by Arnaldo Carvalho de Melo <acme@conectiva.com.br>
- */
-
-#include <net/sock.h>
-
-/* Connection component state transition event qualifiers */
-/* Types of events (possible values in 'ev->type') */
-#define LLC_CONN_EV_TYPE_SIMPLE 1
-#define LLC_CONN_EV_TYPE_CONDITION 2
-#define LLC_CONN_EV_TYPE_PRIM 3
-#define LLC_CONN_EV_TYPE_PDU 4 /* command/response PDU */
-#define LLC_CONN_EV_TYPE_ACK_TMR 5
-#define LLC_CONN_EV_TYPE_P_TMR 6
-#define LLC_CONN_EV_TYPE_REJ_TMR 7
-#define LLC_CONN_EV_TYPE_BUSY_TMR 8
-#define LLC_CONN_EV_TYPE_RPT_STATUS 9
-#define LLC_CONN_EV_TYPE_SENDACK_TMR 10
-
-#define NBR_CONN_EV 5
-/* Connection events which cause state transitions when fully qualified */
-
-#define LLC_CONN_EV_CONN_REQ 1
-#define LLC_CONN_EV_CONN_RESP 2
-#define LLC_CONN_EV_DATA_REQ 3
-#define LLC_CONN_EV_DISC_REQ 4
-#define LLC_CONN_EV_RESET_REQ 5
-#define LLC_CONN_EV_RESET_RESP 6
-#define LLC_CONN_EV_LOCAL_BUSY_DETECTED 7
-#define LLC_CONN_EV_LOCAL_BUSY_CLEARED 8
-#define LLC_CONN_EV_RX_BAD_PDU 9
-#define LLC_CONN_EV_RX_DISC_CMD_Pbit_SET_X 10
-#define LLC_CONN_EV_RX_DM_RSP_Fbit_SET_X 11
-#define LLC_CONN_EV_RX_FRMR_RSP_Fbit_SET_X 12
-#define LLC_CONN_EV_RX_I_CMD_Pbit_SET_X 13
-#define LLC_CONN_EV_RX_I_CMD_Pbit_SET_X_UNEXPD_Ns 14
-#define LLC_CONN_EV_RX_I_CMD_Pbit_SET_X_INVAL_Ns 15
-#define LLC_CONN_EV_RX_I_RSP_Fbit_SET_X 16
-#define LLC_CONN_EV_RX_I_RSP_Fbit_SET_X_UNEXPD_Ns 17
-#define LLC_CONN_EV_RX_I_RSP_Fbit_SET_X_INVAL_Ns 18
-#define LLC_CONN_EV_RX_REJ_CMD_Pbit_SET_X 19
-#define LLC_CONN_EV_RX_REJ_RSP_Fbit_SET_X 20
-#define LLC_CONN_EV_RX_RNR_CMD_Pbit_SET_X 21
-#define LLC_CONN_EV_RX_RNR_RSP_Fbit_SET_X 22
-#define LLC_CONN_EV_RX_RR_CMD_Pbit_SET_X 23
-#define LLC_CONN_EV_RX_RR_RSP_Fbit_SET_X 24
-#define LLC_CONN_EV_RX_SABME_CMD_Pbit_SET_X 25
-#define LLC_CONN_EV_RX_UA_RSP_Fbit_SET_X 26
-#define LLC_CONN_EV_RX_XXX_CMD_Pbit_SET_X 27
-#define LLC_CONN_EV_RX_XXX_RSP_Fbit_SET_X 28
-#define LLC_CONN_EV_RX_XXX_YYY 29
-#define LLC_CONN_EV_RX_ZZZ_CMD_Pbit_SET_X_INVAL_Nr 30
-#define LLC_CONN_EV_RX_ZZZ_RSP_Fbit_SET_X_INVAL_Nr 31
-#define LLC_CONN_EV_P_TMR_EXP 32
-#define LLC_CONN_EV_ACK_TMR_EXP 33
-#define LLC_CONN_EV_REJ_TMR_EXP 34
-#define LLC_CONN_EV_BUSY_TMR_EXP 35
-#define LLC_CONN_EV_RX_XXX_CMD_Pbit_SET_1 36
-#define LLC_CONN_EV_RX_XXX_CMD_Pbit_SET_0 37
-#define LLC_CONN_EV_RX_I_CMD_Pbit_SET_0_UNEXPD_Ns 38
-#define LLC_CONN_EV_RX_I_RSP_Fbit_SET_0_UNEXPD_Ns 39
-#define LLC_CONN_EV_RX_I_RSP_Fbit_SET_1_UNEXPD_Ns 40
-#define LLC_CONN_EV_RX_I_CMD_Pbit_SET_1_UNEXPD_Ns 41
-#define LLC_CONN_EV_RX_I_CMD_Pbit_SET_0 42
-#define LLC_CONN_EV_RX_I_RSP_Fbit_SET_0 43
-#define LLC_CONN_EV_RX_I_CMD_Pbit_SET_1 44
-#define LLC_CONN_EV_RX_RR_CMD_Pbit_SET_0 45
-#define LLC_CONN_EV_RX_RR_RSP_Fbit_SET_0 46
-#define LLC_CONN_EV_RX_RR_RSP_Fbit_SET_1 47
-#define LLC_CONN_EV_RX_RR_CMD_Pbit_SET_1 48
-#define LLC_CONN_EV_RX_RNR_CMD_Pbit_SET_0 49
-#define LLC_CONN_EV_RX_RNR_RSP_Fbit_SET_0 50
-#define LLC_CONN_EV_RX_RNR_RSP_Fbit_SET_1 51
-#define LLC_CONN_EV_RX_RNR_CMD_Pbit_SET_1 52
-#define LLC_CONN_EV_RX_REJ_CMD_Pbit_SET_0 53
-#define LLC_CONN_EV_RX_REJ_RSP_Fbit_SET_0 54
-#define LLC_CONN_EV_RX_REJ_CMD_Pbit_SET_1 55
-#define LLC_CONN_EV_RX_I_RSP_Fbit_SET_1 56
-#define LLC_CONN_EV_RX_REJ_RSP_Fbit_SET_1 57
-#define LLC_CONN_EV_RX_XXX_RSP_Fbit_SET_1 58
-#define LLC_CONN_EV_TX_BUFF_FULL 59
-
-#define LLC_CONN_EV_INIT_P_F_CYCLE 100
-/*
- * Connection event qualifiers; for some events a certain combination of
- * these qualifiers must be TRUE before event recognized valid for state;
- * these constants act as indexes into the Event Qualifier function
- * table
- */
-#define LLC_CONN_EV_QFY_DATA_FLAG_EQ_1 1
-#define LLC_CONN_EV_QFY_DATA_FLAG_EQ_0 2
-#define LLC_CONN_EV_QFY_DATA_FLAG_EQ_2 3
-#define LLC_CONN_EV_QFY_P_FLAG_EQ_1 4
-#define LLC_CONN_EV_QFY_P_FLAG_EQ_0 5
-#define LLC_CONN_EV_QFY_P_FLAG_EQ_Fbit 6
-#define LLC_CONN_EV_QFY_REMOTE_BUSY_EQ_0 7
-#define LLC_CONN_EV_QFY_RETRY_CNT_LT_N2 8
-#define LLC_CONN_EV_QFY_RETRY_CNT_GTE_N2 9
-#define LLC_CONN_EV_QFY_S_FLAG_EQ_1 10
-#define LLC_CONN_EV_QFY_S_FLAG_EQ_0 11
-#define LLC_CONN_EV_QFY_INIT_P_F_CYCLE 12
-
-struct llc_conn_state_ev {
- u8 type;
- u8 prim;
- u8 prim_type;
- u8 reason;
- u8 status;
- u8 ind_prim;
- u8 cfm_prim;
-};
-
-static __inline__ struct llc_conn_state_ev *llc_conn_ev(struct sk_buff *skb)
-{
- return (struct llc_conn_state_ev *)skb->cb;
-}
-
-typedef int (*llc_conn_ev_t)(struct sock *sk, struct sk_buff *skb);
-typedef int (*llc_conn_ev_qfyr_t)(struct sock *sk, struct sk_buff *skb);
-
-int llc_conn_ev_conn_req(struct sock *sk, struct sk_buff *skb);
-int llc_conn_ev_data_req(struct sock *sk, struct sk_buff *skb);
-int llc_conn_ev_disc_req(struct sock *sk, struct sk_buff *skb);
-int llc_conn_ev_rst_req(struct sock *sk, struct sk_buff *skb);
-int llc_conn_ev_local_busy_detected(struct sock *sk, struct sk_buff *skb);
-int llc_conn_ev_local_busy_cleared(struct sock *sk, struct sk_buff *skb);
-int llc_conn_ev_rx_bad_pdu(struct sock *sk, struct sk_buff *skb);
-int llc_conn_ev_rx_disc_cmd_pbit_set_x(struct sock *sk, struct sk_buff *skb);
-int llc_conn_ev_rx_dm_rsp_fbit_set_x(struct sock *sk, struct sk_buff *skb);
-int llc_conn_ev_rx_frmr_rsp_fbit_set_x(struct sock *sk, struct sk_buff *skb);
-int llc_conn_ev_rx_i_cmd_pbit_set_x_inval_ns(struct sock *sk,
- struct sk_buff *skb);
-int llc_conn_ev_rx_i_rsp_fbit_set_x(struct sock *sk, struct sk_buff *skb);
-int llc_conn_ev_rx_i_rsp_fbit_set_x_unexpd_ns(struct sock *sk,
- struct sk_buff *skb);
-int llc_conn_ev_rx_i_rsp_fbit_set_x_inval_ns(struct sock *sk,
- struct sk_buff *skb);
-int llc_conn_ev_rx_rej_rsp_fbit_set_x(struct sock *sk, struct sk_buff *skb);
-int llc_conn_ev_rx_sabme_cmd_pbit_set_x(struct sock *sk, struct sk_buff *skb);
-int llc_conn_ev_rx_ua_rsp_fbit_set_x(struct sock *sk, struct sk_buff *skb);
-int llc_conn_ev_rx_xxx_cmd_pbit_set_x(struct sock *sk, struct sk_buff *skb);
-int llc_conn_ev_rx_xxx_rsp_fbit_set_x(struct sock *sk, struct sk_buff *skb);
-int llc_conn_ev_rx_zzz_cmd_pbit_set_x_inval_nr(struct sock *sk,
- struct sk_buff *skb);
-int llc_conn_ev_rx_zzz_rsp_fbit_set_x_inval_nr(struct sock *sk,
- struct sk_buff *skb);
-int llc_conn_ev_p_tmr_exp(struct sock *sk, struct sk_buff *skb);
-int llc_conn_ev_ack_tmr_exp(struct sock *sk, struct sk_buff *skb);
-int llc_conn_ev_rej_tmr_exp(struct sock *sk, struct sk_buff *skb);
-int llc_conn_ev_busy_tmr_exp(struct sock *sk, struct sk_buff *skb);
-/* NOT_USED functions and their variations */
-int llc_conn_ev_rx_xxx_cmd_pbit_set_1(struct sock *sk, struct sk_buff *skb);
-int llc_conn_ev_rx_xxx_rsp_fbit_set_1(struct sock *sk, struct sk_buff *skb);
-int llc_conn_ev_rx_i_cmd_pbit_set_0_unexpd_ns(struct sock *sk,
- struct sk_buff *skb);
-int llc_conn_ev_rx_i_cmd_pbit_set_1_unexpd_ns(struct sock *sk,
- struct sk_buff *skb);
-int llc_conn_ev_rx_i_cmd_pbit_set_0(struct sock *sk, struct sk_buff *skb);
-int llc_conn_ev_rx_i_cmd_pbit_set_1(struct sock *sk, struct sk_buff *skb);
-int llc_conn_ev_rx_i_rsp_fbit_set_0_unexpd_ns(struct sock *sk,
- struct sk_buff *skb);
-int llc_conn_ev_rx_i_rsp_fbit_set_1_unexpd_ns(struct sock *sk,
- struct sk_buff *skb);
-int llc_conn_ev_rx_i_rsp_fbit_set_0(struct sock *sk, struct sk_buff *skb);
-int llc_conn_ev_rx_i_rsp_fbit_set_1(struct sock *sk, struct sk_buff *skb);
-int llc_conn_ev_rx_rr_cmd_pbit_set_0(struct sock *sk, struct sk_buff *skb);
-int llc_conn_ev_rx_rr_cmd_pbit_set_1(struct sock *sk, struct sk_buff *skb);
-int llc_conn_ev_rx_rr_rsp_fbit_set_0(struct sock *sk, struct sk_buff *skb);
-int llc_conn_ev_rx_rr_rsp_fbit_set_1(struct sock *sk, struct sk_buff *skb);
-int llc_conn_ev_rx_rnr_cmd_pbit_set_0(struct sock *sk, struct sk_buff *skb);
-int llc_conn_ev_rx_rnr_cmd_pbit_set_1(struct sock *sk, struct sk_buff *skb);
-int llc_conn_ev_rx_rnr_rsp_fbit_set_0(struct sock *sk, struct sk_buff *skb);
-int llc_conn_ev_rx_rnr_rsp_fbit_set_1(struct sock *sk, struct sk_buff *skb);
-int llc_conn_ev_rx_rej_cmd_pbit_set_0(struct sock *sk, struct sk_buff *skb);
-int llc_conn_ev_rx_rej_cmd_pbit_set_1(struct sock *sk, struct sk_buff *skb);
-int llc_conn_ev_rx_rej_rsp_fbit_set_0(struct sock *sk, struct sk_buff *skb);
-int llc_conn_ev_rx_rej_rsp_fbit_set_1(struct sock *sk, struct sk_buff *skb);
-int llc_conn_ev_rx_any_frame(struct sock *sk, struct sk_buff *skb);
-int llc_conn_ev_tx_buffer_full(struct sock *sk, struct sk_buff *skb);
-int llc_conn_ev_init_p_f_cycle(struct sock *sk, struct sk_buff *skb);
-
-/* Available connection action qualifiers */
-int llc_conn_ev_qlfy_data_flag_eq_1(struct sock *sk, struct sk_buff *skb);
-int llc_conn_ev_qlfy_data_flag_eq_0(struct sock *sk, struct sk_buff *skb);
-int llc_conn_ev_qlfy_data_flag_eq_2(struct sock *sk, struct sk_buff *skb);
-int llc_conn_ev_qlfy_p_flag_eq_1(struct sock *sk, struct sk_buff *skb);
-int llc_conn_ev_qlfy_last_frame_eq_1(struct sock *sk, struct sk_buff *skb);
-int llc_conn_ev_qlfy_last_frame_eq_0(struct sock *sk, struct sk_buff *skb);
-int llc_conn_ev_qlfy_p_flag_eq_0(struct sock *sk, struct sk_buff *skb);
-int llc_conn_ev_qlfy_p_flag_eq_f(struct sock *sk, struct sk_buff *skb);
-int llc_conn_ev_qlfy_remote_busy_eq_0(struct sock *sk, struct sk_buff *skb);
-int llc_conn_ev_qlfy_remote_busy_eq_1(struct sock *sk, struct sk_buff *skb);
-int llc_conn_ev_qlfy_retry_cnt_lt_n2(struct sock *sk, struct sk_buff *skb);
-int llc_conn_ev_qlfy_retry_cnt_gte_n2(struct sock *sk, struct sk_buff *skb);
-int llc_conn_ev_qlfy_s_flag_eq_1(struct sock *sk, struct sk_buff *skb);
-int llc_conn_ev_qlfy_s_flag_eq_0(struct sock *sk, struct sk_buff *skb);
-int llc_conn_ev_qlfy_cause_flag_eq_1(struct sock *sk, struct sk_buff *skb);
-int llc_conn_ev_qlfy_cause_flag_eq_0(struct sock *sk, struct sk_buff *skb);
-int llc_conn_ev_qlfy_set_status_conn(struct sock *sk, struct sk_buff *skb);
-int llc_conn_ev_qlfy_set_status_disc(struct sock *sk, struct sk_buff *skb);
-int llc_conn_ev_qlfy_set_status_failed(struct sock *sk, struct sk_buff *skb);
-int llc_conn_ev_qlfy_set_status_remote_busy(struct sock *sk,
- struct sk_buff *skb);
-int llc_conn_ev_qlfy_set_status_refuse(struct sock *sk, struct sk_buff *skb);
-int llc_conn_ev_qlfy_set_status_conflict(struct sock *sk, struct sk_buff *skb);
-int llc_conn_ev_qlfy_set_status_rst_done(struct sock *sk, struct sk_buff *skb);
-
-static __inline__ int llc_conn_space(struct sock *sk, struct sk_buff *skb)
-{
- return atomic_read(&sk->sk_rmem_alloc) + skb->truesize <
- (unsigned int)sk->sk_rcvbuf;
-}
-#endif /* LLC_C_EV_H */
diff --git a/include/net/llc_c_st.h b/include/net/llc_c_st.h
deleted file mode 100644
index f52a4cc4880d..000000000000
--- a/include/net/llc_c_st.h
+++ /dev/null
@@ -1,46 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-#ifndef LLC_C_ST_H
-#define LLC_C_ST_H
-/*
- * Copyright (c) 1997 by Procom Technology,Inc.
- * 2001 by Arnaldo Carvalho de Melo <acme@conectiva.com.br>
- */
-
-#include <net/llc_c_ac.h>
-#include <net/llc_c_ev.h>
-
-/* Connection component state management */
-/* connection states */
-#define LLC_CONN_OUT_OF_SVC 0 /* prior to allocation */
-
-#define LLC_CONN_STATE_ADM 1 /* disc, initial state */
-#define LLC_CONN_STATE_SETUP 2 /* disconnected state */
-#define LLC_CONN_STATE_NORMAL 3 /* connected state */
-#define LLC_CONN_STATE_BUSY 4 /* connected state */
-#define LLC_CONN_STATE_REJ 5 /* connected state */
-#define LLC_CONN_STATE_AWAIT 6 /* connected state */
-#define LLC_CONN_STATE_AWAIT_BUSY 7 /* connected state */
-#define LLC_CONN_STATE_AWAIT_REJ 8 /* connected state */
-#define LLC_CONN_STATE_D_CONN 9 /* disconnected state */
-#define LLC_CONN_STATE_RESET 10 /* disconnected state */
-#define LLC_CONN_STATE_ERROR 11 /* disconnected state */
-#define LLC_CONN_STATE_TEMP 12 /* disconnected state */
-
-#define NBR_CONN_STATES 12 /* size of state table */
-#define NO_STATE_CHANGE 100
-
-/* Connection state table structure */
-struct llc_conn_state_trans {
- llc_conn_ev_t ev;
- u8 next_state;
- const llc_conn_ev_qfyr_t *ev_qualifiers;
- const llc_conn_action_t *ev_actions;
-};
-
-struct llc_conn_state {
- u8 current_state;
- const struct llc_conn_state_trans **transitions;
-};
-
-extern struct llc_conn_state llc_conn_state_table[];
-#endif /* LLC_C_ST_H */
diff --git a/include/net/llc_conn.h b/include/net/llc_conn.h
deleted file mode 100644
index e1a302696723..000000000000
--- a/include/net/llc_conn.h
+++ /dev/null
@@ -1,114 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-#ifndef LLC_CONN_H
-#define LLC_CONN_H
-/*
- * Copyright (c) 1997 by Procom Technology, Inc.
- * 2001, 2002 by Arnaldo Carvalho de Melo <acme@conectiva.com.br>
- */
-#include <linux/timer.h>
-#include <net/llc_if.h>
-#include <net/sock.h>
-#include <linux/llc.h>
-
-#define LLC_EVENT 1
-#define LLC_PACKET 2
-
-#define LLC2_P_TIME 2
-#define LLC2_ACK_TIME 1
-#define LLC2_REJ_TIME 3
-#define LLC2_BUSY_TIME 3
-
-struct llc_timer {
- struct timer_list timer;
- unsigned long expire; /* timer expire time */
-};
-
-struct llc_sock {
- /* struct sock must be the first member of llc_sock */
- struct sock sk;
- struct sockaddr_llc addr; /* address sock is bound to */
- u8 state; /* state of connection */
- struct llc_sap *sap; /* pointer to parent SAP */
- struct llc_addr laddr; /* lsap/mac pair */
- struct llc_addr daddr; /* dsap/mac pair */
- struct net_device *dev; /* device to send to remote */
- netdevice_tracker dev_tracker;
- u32 copied_seq; /* head of yet unread data */
- u8 retry_count; /* number of retries */
- u8 ack_must_be_send;
- u8 first_pdu_Ns;
- u8 npta;
- struct llc_timer ack_timer;
- struct llc_timer pf_cycle_timer;
- struct llc_timer rej_sent_timer;
- struct llc_timer busy_state_timer; /* ind busy clr at remote LLC */
- u8 vS; /* seq# next in-seq I-PDU tx'd*/
- u8 vR; /* seq# next in-seq I-PDU rx'd*/
- u32 n2; /* max nbr re-tx's for timeout*/
- u32 n1; /* max nbr octets in I PDU */
- u8 k; /* tx window size; max = 127 */
- u8 rw; /* rx window size; max = 127 */
- u8 p_flag; /* state flags */
- u8 f_flag;
- u8 s_flag;
- u8 data_flag;
- u8 remote_busy_flag;
- u8 cause_flag;
- struct sk_buff_head pdu_unack_q; /* PUDs sent/waiting ack */
- u16 link; /* network layer link number */
- u8 X; /* a temporary variable */
- u8 ack_pf; /* this flag indicates what is
- the P-bit of acknowledge */
- u8 failed_data_req; /* recognize that already exist a
- failed llc_data_req_handler
- (tx_buffer_full or unacceptable
- state */
- u8 dec_step;
- u8 inc_cntr;
- u8 dec_cntr;
- u8 connect_step;
- u8 last_nr; /* NR of last pdu received */
- u32 rx_pdu_hdr; /* used for saving header of last pdu
- received and caused sending FRMR.
- Used for resending FRMR */
- u32 cmsg_flags;
- struct hlist_node dev_hash_node;
-};
-
-static inline struct llc_sock *llc_sk(const struct sock *sk)
-{
- return (struct llc_sock *)sk;
-}
-
-static __inline__ void llc_set_backlog_type(struct sk_buff *skb, char type)
-{
- skb->cb[sizeof(skb->cb) - 1] = type;
-}
-
-static __inline__ char llc_backlog_type(struct sk_buff *skb)
-{
- return skb->cb[sizeof(skb->cb) - 1];
-}
-
-struct sock *llc_sk_alloc(struct net *net, int family, gfp_t priority,
- struct proto *prot, int kern);
-void llc_sk_stop_all_timers(struct sock *sk, bool sync);
-void llc_sk_free(struct sock *sk);
-
-void llc_sk_reset(struct sock *sk);
-
-/* Access to a connection */
-int llc_conn_state_process(struct sock *sk, struct sk_buff *skb);
-void llc_conn_send_pdu(struct sock *sk, struct sk_buff *skb);
-void llc_conn_rtn_pdu(struct sock *sk, struct sk_buff *skb);
-void llc_conn_resend_i_pdu_as_cmd(struct sock *sk, u8 nr, u8 first_p_bit);
-void llc_conn_resend_i_pdu_as_rsp(struct sock *sk, u8 nr, u8 first_f_bit);
-int llc_conn_remove_acked_pdus(struct sock *conn, u8 nr, u16 *how_many_unacked);
-struct sock *llc_lookup_established(struct llc_sap *sap, struct llc_addr *daddr,
- struct llc_addr *laddr, const struct net *net);
-void llc_sap_add_socket(struct llc_sap *sap, struct sock *sk);
-void llc_sap_remove_socket(struct llc_sap *sap, struct sock *sk);
-
-u8 llc_data_accept_state(u8 state);
-void llc_build_offset_table(void);
-#endif /* LLC_CONN_H */
diff --git a/include/net/llc_if.h b/include/net/llc_if.h
deleted file mode 100644
index a333259613ab..000000000000
--- a/include/net/llc_if.h
+++ /dev/null
@@ -1,63 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-#ifndef LLC_IF_H
-#define LLC_IF_H
-/*
- * Copyright (c) 1997 by Procom Technology,Inc.
- * 2001 by Arnaldo Carvalho de Melo <acme@conectiva.com.br>
- */
-/* Defines LLC interface to network layer */
-/* Available primitives */
-#include <linux/if.h>
-#include <linux/if_arp.h>
-#include <linux/llc.h>
-#include <linux/etherdevice.h>
-#include <net/llc.h>
-
-#define LLC_DATAUNIT_PRIM 1
-#define LLC_CONN_PRIM 2
-#define LLC_DATA_PRIM 3
-#define LLC_DISC_PRIM 4
-#define LLC_RESET_PRIM 5
-#define LLC_FLOWCONTROL_PRIM 6 /* Not supported at this time */
-#define LLC_DISABLE_PRIM 7
-#define LLC_XID_PRIM 8
-#define LLC_TEST_PRIM 9
-#define LLC_SAP_ACTIVATION 10
-#define LLC_SAP_DEACTIVATION 11
-
-#define LLC_NBR_PRIMITIVES 11
-
-#define LLC_IND 1
-#define LLC_CONFIRM 2
-
-/* Primitive type */
-#define LLC_PRIM_TYPE_REQ 1
-#define LLC_PRIM_TYPE_IND 2
-#define LLC_PRIM_TYPE_RESP 3
-#define LLC_PRIM_TYPE_CONFIRM 4
-
-/* Reset reasons, remote entity or local LLC */
-#define LLC_RESET_REASON_REMOTE 1
-#define LLC_RESET_REASON_LOCAL 2
-
-/* Disconnect reasons */
-#define LLC_DISC_REASON_RX_DM_RSP_PDU 0
-#define LLC_DISC_REASON_RX_DISC_CMD_PDU 1
-#define LLC_DISC_REASON_ACK_TMR_EXP 2
-
-/* Confirm reasons */
-#define LLC_STATUS_CONN 0 /* connect confirm & reset confirm */
-#define LLC_STATUS_DISC 1 /* connect confirm & reset confirm */
-#define LLC_STATUS_FAILED 2 /* connect confirm & reset confirm */
-#define LLC_STATUS_IMPOSSIBLE 3 /* connect confirm */
-#define LLC_STATUS_RECEIVED 4 /* data conn */
-#define LLC_STATUS_REMOTE_BUSY 5 /* data conn */
-#define LLC_STATUS_REFUSE 6 /* data conn */
-#define LLC_STATUS_CONFLICT 7 /* disconnect conn */
-#define LLC_STATUS_RESET_DONE 8 /* */
-
-int llc_establish_connection(struct sock *sk, const u8 *lmac, u8 *dmac,
- u8 dsap);
-int llc_build_and_send_pkt(struct sock *sk, struct sk_buff *skb);
-int llc_send_disc(struct sock *sk);
-#endif /* LLC_IF_H */
diff --git a/include/net/llc_pdu.h b/include/net/llc_pdu.h
index f165237a3723..14c76b0d9832 100644
--- a/include/net/llc_pdu.h
+++ b/include/net/llc_pdu.h
@@ -6,201 +6,17 @@
* 2001-2003 by Arnaldo Carvalho de Melo <acme@conectiva.com.br>
*/
-#include <linux/if_ether.h>
-
-/* Lengths of frame formats */
-#define LLC_PDU_LEN_I 4 /* header and 2 control bytes */
-#define LLC_PDU_LEN_S 4
-#define LLC_PDU_LEN_U 3 /* header and 1 control byte */
-/* header and 1 control byte and XID info */
-#define LLC_PDU_LEN_U_XID (LLC_PDU_LEN_U + sizeof(struct llc_xid_info))
-/* Known SAP addresses */
-#define LLC_GLOBAL_SAP 0xFF
-#define LLC_NULL_SAP 0x00 /* not network-layer visible */
-#define LLC_MGMT_INDIV 0x02 /* station LLC mgmt indiv addr */
-#define LLC_MGMT_GRP 0x03 /* station LLC mgmt group addr */
-#define LLC_RDE_SAP 0xA6 /* route ... */
-
-/* SAP field bit masks */
-#define LLC_ISO_RESERVED_SAP 0x02
-#define LLC_SAP_GROUP_DSAP 0x01
-#define LLC_SAP_RESP_SSAP 0x01
-
-/* Group/individual DSAP indicator is DSAP field */
-#define LLC_PDU_GROUP_DSAP_MASK 0x01
-#define LLC_PDU_IS_GROUP_DSAP(pdu) \
- ((pdu->dsap & LLC_PDU_GROUP_DSAP_MASK) ? 0 : 1)
-#define LLC_PDU_IS_INDIV_DSAP(pdu) \
- (!(pdu->dsap & LLC_PDU_GROUP_DSAP_MASK) ? 0 : 1)
+#include <linux/skbuff.h>
/* Command/response PDU indicator in SSAP field */
-#define LLC_PDU_CMD_RSP_MASK 0x01
#define LLC_PDU_CMD 0
#define LLC_PDU_RSP 1
-#define LLC_PDU_IS_CMD(pdu) ((pdu->ssap & LLC_PDU_RSP) ? 0 : 1)
-#define LLC_PDU_IS_RSP(pdu) ((pdu->ssap & LLC_PDU_RSP) ? 1 : 0)
/* Get PDU type from 2 lowest-order bits of control field first byte */
-#define LLC_PDU_TYPE_I_MASK 0x01 /* 16-bit control field */
-#define LLC_PDU_TYPE_S_MASK 0x03
-#define LLC_PDU_TYPE_U_MASK 0x03 /* 8-bit control field */
#define LLC_PDU_TYPE_MASK 0x03
-
-#define LLC_PDU_TYPE_I 0 /* first bit */
-#define LLC_PDU_TYPE_S 1 /* first two bits */
#define LLC_PDU_TYPE_U 3 /* first two bits */
-#define LLC_PDU_TYPE_U_XID 4 /* private type for detecting XID commands */
-
-#define LLC_PDU_TYPE_IS_I(pdu) \
- ((!(pdu->ctrl_1 & LLC_PDU_TYPE_I_MASK)) ? 1 : 0)
-
-#define LLC_PDU_TYPE_IS_U(pdu) \
- (((pdu->ctrl_1 & LLC_PDU_TYPE_U_MASK) == LLC_PDU_TYPE_U) ? 1 : 0)
-
-#define LLC_PDU_TYPE_IS_S(pdu) \
- (((pdu->ctrl_1 & LLC_PDU_TYPE_S_MASK) == LLC_PDU_TYPE_S) ? 1 : 0)
-
-/* U-format PDU control field masks */
-#define LLC_U_PF_BIT_MASK 0x10 /* P/F bit mask */
-#define LLC_U_PF_IS_1(pdu) ((pdu->ctrl_1 & LLC_U_PF_BIT_MASK) ? 1 : 0)
-#define LLC_U_PF_IS_0(pdu) ((!(pdu->ctrl_1 & LLC_U_PF_BIT_MASK)) ? 1 : 0)
-
-#define LLC_U_PDU_CMD_MASK 0xEC /* cmd/rsp mask */
-#define LLC_U_PDU_CMD(pdu) (pdu->ctrl_1 & LLC_U_PDU_CMD_MASK)
-#define LLC_U_PDU_RSP(pdu) (pdu->ctrl_1 & LLC_U_PDU_CMD_MASK)
#define LLC_1_PDU_CMD_UI 0x00 /* Type 1 cmds/rsps */
-#define LLC_1_PDU_CMD_XID 0xAC
-#define LLC_1_PDU_CMD_TEST 0xE0
-
-#define LLC_2_PDU_CMD_SABME 0x6C /* Type 2 cmds/rsps */
-#define LLC_2_PDU_CMD_DISC 0x40
-#define LLC_2_PDU_RSP_UA 0x60
-#define LLC_2_PDU_RSP_DM 0x0C
-#define LLC_2_PDU_RSP_FRMR 0x84
-
-/* Type 1 operations */
-
-/* XID information field bit masks */
-
-/* LLC format identifier (byte 1) */
-#define LLC_XID_FMT_ID 0x81 /* first byte must be this */
-
-/* LLC types/classes identifier (byte 2) */
-#define LLC_XID_CLASS_ZEROS_MASK 0xE0 /* these must be zeros */
-#define LLC_XID_CLASS_MASK 0x1F /* AND with byte to get below */
-
-#define LLC_XID_NULL_CLASS_1 0x01 /* if NULL LSAP...use these */
-#define LLC_XID_NULL_CLASS_2 0x03
-#define LLC_XID_NULL_CLASS_3 0x05
-#define LLC_XID_NULL_CLASS_4 0x07
-
-#define LLC_XID_NNULL_TYPE_1 0x01 /* if non-NULL LSAP...use these */
-#define LLC_XID_NNULL_TYPE_2 0x02
-#define LLC_XID_NNULL_TYPE_3 0x04
-#define LLC_XID_NNULL_TYPE_1_2 0x03
-#define LLC_XID_NNULL_TYPE_1_3 0x05
-#define LLC_XID_NNULL_TYPE_2_3 0x06
-#define LLC_XID_NNULL_ALL 0x07
-
-/* Sender Receive Window (byte 3) */
-#define LLC_XID_RW_MASK 0xFE /* AND with value to get below */
-
-#define LLC_XID_MIN_RW 0x02 /* lowest-order bit always zero */
-
-/* Type 2 operations */
-
-#define LLC_2_SEQ_NBR_MODULO ((u8) 128)
-
-/* I-PDU masks ('ctrl' is I-PDU control word) */
-#define LLC_I_GET_NS(pdu) (u8)((pdu->ctrl_1 & 0xFE) >> 1)
-#define LLC_I_GET_NR(pdu) (u8)((pdu->ctrl_2 & 0xFE) >> 1)
-
-#define LLC_I_PF_BIT_MASK 0x01
-
-#define LLC_I_PF_IS_0(pdu) ((!(pdu->ctrl_2 & LLC_I_PF_BIT_MASK)) ? 1 : 0)
-#define LLC_I_PF_IS_1(pdu) ((pdu->ctrl_2 & LLC_I_PF_BIT_MASK) ? 1 : 0)
-
-/* S-PDU supervisory commands and responses */
-
-#define LLC_S_PDU_CMD_MASK 0x0C
-#define LLC_S_PDU_CMD(pdu) (pdu->ctrl_1 & LLC_S_PDU_CMD_MASK)
-#define LLC_S_PDU_RSP(pdu) (pdu->ctrl_1 & LLC_S_PDU_CMD_MASK)
-
-#define LLC_2_PDU_CMD_RR 0x00 /* rx ready cmd */
-#define LLC_2_PDU_RSP_RR 0x00 /* rx ready rsp */
-#define LLC_2_PDU_CMD_REJ 0x08 /* reject PDU cmd */
-#define LLC_2_PDU_RSP_REJ 0x08 /* reject PDU rsp */
-#define LLC_2_PDU_CMD_RNR 0x04 /* rx not ready cmd */
-#define LLC_2_PDU_RSP_RNR 0x04 /* rx not ready rsp */
-
-#define LLC_S_PF_BIT_MASK 0x01
-#define LLC_S_PF_IS_0(pdu) ((!(pdu->ctrl_2 & LLC_S_PF_BIT_MASK)) ? 1 : 0)
-#define LLC_S_PF_IS_1(pdu) ((pdu->ctrl_2 & LLC_S_PF_BIT_MASK) ? 1 : 0)
-
-#define PDU_SUPV_GET_Nr(pdu) ((pdu->ctrl_2 & 0xFE) >> 1)
-#define PDU_GET_NEXT_Vr(sn) (((sn) + 1) & ~LLC_2_SEQ_NBR_MODULO)
-
-/* FRMR information field macros */
-
-#define FRMR_INFO_LENGTH 5 /* 5 bytes of information */
-
-/*
- * info is pointer to FRMR info field structure; 'rej_ctrl' is byte pointer
- * (if U-PDU) or word pointer to rejected PDU control field
- */
-#define FRMR_INFO_SET_REJ_CNTRL(info,rej_ctrl) \
- info->rej_pdu_ctrl = ((*((u8 *) rej_ctrl) & \
- LLC_PDU_TYPE_U) != LLC_PDU_TYPE_U ? \
- (u16)*((u16 *) rej_ctrl) : \
- (((u16) *((u8 *) rej_ctrl)) & 0x00FF))
-
-/*
- * Info is pointer to FRMR info field structure; 'vs' is a byte containing
- * send state variable value in low-order 7 bits (insure the lowest-order
- * bit remains zero (0))
- */
-#define FRMR_INFO_SET_Vs(info,vs) (info->curr_ssv = (((u8) vs) << 1))
-#define FRMR_INFO_SET_Vr(info,vr) (info->curr_rsv = (((u8) vr) << 1))
-
-/*
- * Info is pointer to FRMR info field structure; 'cr' is a byte containing
- * the C/R bit value in the low-order bit
- */
-#define FRMR_INFO_SET_C_R_BIT(info, cr) (info->curr_rsv |= (((u8) cr) & 0x01))
-
-/*
- * In the remaining five macros, 'info' is pointer to FRMR info field
- * structure; 'ind' is a byte containing the bit value to set in the
- * lowest-order bit)
- */
-#define FRMR_INFO_SET_INVALID_PDU_CTRL_IND(info, ind) \
- (info->ind_bits = ((info->ind_bits & 0xFE) | (((u8) ind) & 0x01)))
-
-#define FRMR_INFO_SET_INVALID_PDU_INFO_IND(info, ind) \
- (info->ind_bits = ( (info->ind_bits & 0xFD) | (((u8) ind) & 0x02)))
-
-#define FRMR_INFO_SET_PDU_INFO_2LONG_IND(info, ind) \
- (info->ind_bits = ( (info->ind_bits & 0xFB) | (((u8) ind) & 0x04)))
-
-#define FRMR_INFO_SET_PDU_INVALID_Nr_IND(info, ind) \
- (info->ind_bits = ( (info->ind_bits & 0xF7) | (((u8) ind) & 0x08)))
-
-#define FRMR_INFO_SET_PDU_INVALID_Ns_IND(info, ind) \
- (info->ind_bits = ( (info->ind_bits & 0xEF) | (((u8) ind) & 0x10)))
-
-/* Sequence-numbered PDU format (4 bytes in length) */
-struct llc_pdu_sn {
- u8 dsap;
- u8 ssap;
- u8 ctrl_1;
- u8 ctrl_2;
-} __packed;
-
-static inline struct llc_pdu_sn *llc_pdu_sn_hdr(struct sk_buff *skb)
-{
- return (struct llc_pdu_sn *)skb_network_header(skb);
-}
/* Un-numbered PDU format (3 bytes in length) */
struct llc_pdu_un {
@@ -217,29 +33,18 @@ static inline struct llc_pdu_un *llc_pdu_un_hdr(struct sk_buff *skb)
/**
* llc_pdu_header_init - initializes pdu header
* @skb: input skb that header must be set into it.
- * @type: type of PDU (U, I or S).
* @ssap: source sap.
* @dsap: destination sap.
- * @cr: command/response bit (0 or 1).
+ * @cr: command/response bit (%LLC_PDU_CMD or %LLC_PDU_RSP).
*
* This function sets DSAP, SSAP and command/Response bit in LLC header.
*/
-static inline void llc_pdu_header_init(struct sk_buff *skb, u8 type,
- u8 ssap, u8 dsap, u8 cr)
+static inline void llc_pdu_header_init(struct sk_buff *skb, u8 ssap, u8 dsap,
+ u8 cr)
{
- int hlen = 4; /* default value for I and S types */
struct llc_pdu_un *pdu;
- switch (type) {
- case LLC_PDU_TYPE_U:
- hlen = 3;
- break;
- case LLC_PDU_TYPE_U_XID:
- hlen = 6;
- break;
- }
-
- skb_push(skb, hlen);
+ skb_push(skb, sizeof(*pdu));
skb_reset_network_header(skb);
pdu = llc_pdu_un_hdr(skb);
pdu->dsap = dsap;
@@ -248,56 +53,6 @@ static inline void llc_pdu_header_init(struct sk_buff *skb, u8 type,
}
/**
- * llc_pdu_decode_sa - extracts, source address (MAC) of input frame
- * @skb: input skb that source address must be extracted from it.
- * @sa: pointer to source address (6 byte array).
- *
- * This function extracts source address(MAC) of input frame.
- */
-static inline void llc_pdu_decode_sa(struct sk_buff *skb, u8 *sa)
-{
- memcpy(sa, eth_hdr(skb)->h_source, ETH_ALEN);
-}
-
-/**
- * llc_pdu_decode_da - extracts dest address of input frame
- * @skb: input skb that destination address must be extracted from it
- * @da: pointer to destination address (6 byte array).
- *
- * This function extracts destination address(MAC) of input frame.
- */
-static inline void llc_pdu_decode_da(struct sk_buff *skb, u8 *da)
-{
- memcpy(da, eth_hdr(skb)->h_dest, ETH_ALEN);
-}
-
-/**
- * llc_pdu_decode_ssap - extracts source SAP of input frame
- * @skb: input skb that source SAP must be extracted from it.
- * @ssap: source SAP (output argument).
- *
- * This function extracts source SAP of input frame. Right bit of SSAP is
- * command/response bit.
- */
-static inline void llc_pdu_decode_ssap(struct sk_buff *skb, u8 *ssap)
-{
- *ssap = llc_pdu_un_hdr(skb)->ssap & 0xFE;
-}
-
-/**
- * llc_pdu_decode_dsap - extracts dest SAP of input frame
- * @skb: input skb that destination SAP must be extracted from it.
- * @dsap: destination SAP (output argument).
- *
- * This function extracts destination SAP of input frame. right bit of
- * DSAP designates individual/group SAP.
- */
-static inline void llc_pdu_decode_dsap(struct sk_buff *skb, u8 *dsap)
-{
- *dsap = llc_pdu_un_hdr(skb)->dsap & 0xFE;
-}
-
-/**
* llc_pdu_init_as_ui_cmd - sets LLC header as UI PDU
* @skb: input skb that header must be set into it.
*
@@ -311,128 +66,4 @@ static inline void llc_pdu_init_as_ui_cmd(struct sk_buff *skb)
pdu->ctrl_1 |= LLC_1_PDU_CMD_UI;
}
-/**
- * llc_pdu_init_as_test_cmd - sets PDU as TEST
- * @skb: Address of the skb to build
- *
- * Sets a PDU as TEST
- */
-static inline void llc_pdu_init_as_test_cmd(struct sk_buff *skb)
-{
- struct llc_pdu_un *pdu = llc_pdu_un_hdr(skb);
-
- pdu->ctrl_1 = LLC_PDU_TYPE_U;
- pdu->ctrl_1 |= LLC_1_PDU_CMD_TEST;
- pdu->ctrl_1 |= LLC_U_PF_BIT_MASK;
-}
-
-/**
- * llc_pdu_init_as_test_rsp - build TEST response PDU
- * @skb: Address of the skb to build
- * @ev_skb: The received TEST command PDU frame
- *
- * Builds a pdu frame as a TEST response.
- */
-static inline void llc_pdu_init_as_test_rsp(struct sk_buff *skb,
- struct sk_buff *ev_skb)
-{
- struct llc_pdu_un *pdu = llc_pdu_un_hdr(skb);
-
- pdu->ctrl_1 = LLC_PDU_TYPE_U;
- pdu->ctrl_1 |= LLC_1_PDU_CMD_TEST;
- pdu->ctrl_1 |= LLC_U_PF_BIT_MASK;
- if (ev_skb->protocol == htons(ETH_P_802_2)) {
- struct llc_pdu_un *ev_pdu = llc_pdu_un_hdr(ev_skb);
- int dsize;
-
- dsize = ntohs(eth_hdr(ev_skb)->h_proto) - 3;
- memcpy(((u8 *)pdu) + 3, ((u8 *)ev_pdu) + 3, dsize);
- skb_put(skb, dsize);
- }
-}
-
-/* LLC Type 1 XID command/response information fields format */
-struct llc_xid_info {
- u8 fmt_id; /* always 0x81 for LLC */
- u8 type; /* different if NULL/non-NULL LSAP */
- u8 rw; /* sender receive window */
-} __packed;
-
-/**
- * llc_pdu_init_as_xid_cmd - sets bytes 3, 4 & 5 of LLC header as XID
- * @skb: input skb that header must be set into it.
- * @svcs_supported: The class of the LLC (I or II)
- * @rx_window: The size of the receive window of the LLC
- *
- * This function sets third,fourth,fifth and sixth bytes of LLC header as
- * a XID PDU.
- */
-static inline void llc_pdu_init_as_xid_cmd(struct sk_buff *skb,
- u8 svcs_supported, u8 rx_window)
-{
- struct llc_xid_info *xid_info;
- struct llc_pdu_un *pdu = llc_pdu_un_hdr(skb);
-
- pdu->ctrl_1 = LLC_PDU_TYPE_U;
- pdu->ctrl_1 |= LLC_1_PDU_CMD_XID;
- pdu->ctrl_1 |= LLC_U_PF_BIT_MASK;
- xid_info = (struct llc_xid_info *)(((u8 *)&pdu->ctrl_1) + 1);
- xid_info->fmt_id = LLC_XID_FMT_ID; /* 0x81 */
- xid_info->type = svcs_supported;
- xid_info->rw = rx_window << 1; /* size of receive window */
-
- /* no need to push/put since llc_pdu_header_init() has already
- * pushed 3 + 3 bytes
- */
-}
-
-/**
- * llc_pdu_init_as_xid_rsp - builds XID response PDU
- * @skb: Address of the skb to build
- * @svcs_supported: The class of the LLC (I or II)
- * @rx_window: The size of the receive window of the LLC
- *
- * Builds a pdu frame as an XID response.
- */
-static inline void llc_pdu_init_as_xid_rsp(struct sk_buff *skb,
- u8 svcs_supported, u8 rx_window)
-{
- struct llc_xid_info *xid_info;
- struct llc_pdu_un *pdu = llc_pdu_un_hdr(skb);
-
- pdu->ctrl_1 = LLC_PDU_TYPE_U;
- pdu->ctrl_1 |= LLC_1_PDU_CMD_XID;
- pdu->ctrl_1 |= LLC_U_PF_BIT_MASK;
-
- xid_info = (struct llc_xid_info *)(((u8 *)&pdu->ctrl_1) + 1);
- xid_info->fmt_id = LLC_XID_FMT_ID;
- xid_info->type = svcs_supported;
- xid_info->rw = rx_window << 1;
- skb_put(skb, sizeof(struct llc_xid_info));
-}
-
-/* LLC Type 2 FRMR response information field format */
-struct llc_frmr_info {
- u16 rej_pdu_ctrl; /* bits 1-8 if U-PDU */
- u8 curr_ssv; /* current send state variable val */
- u8 curr_rsv; /* current receive state variable */
- u8 ind_bits; /* indicator bits set with macro */
-} __packed;
-
-void llc_pdu_set_cmd_rsp(struct sk_buff *skb, u8 type);
-void llc_pdu_set_pf_bit(struct sk_buff *skb, u8 bit_value);
-void llc_pdu_decode_pf_bit(struct sk_buff *skb, u8 *pf_bit);
-void llc_pdu_init_as_disc_cmd(struct sk_buff *skb, u8 p_bit);
-void llc_pdu_init_as_i_cmd(struct sk_buff *skb, u8 p_bit, u8 ns, u8 nr);
-void llc_pdu_init_as_rej_cmd(struct sk_buff *skb, u8 p_bit, u8 nr);
-void llc_pdu_init_as_rnr_cmd(struct sk_buff *skb, u8 p_bit, u8 nr);
-void llc_pdu_init_as_rr_cmd(struct sk_buff *skb, u8 p_bit, u8 nr);
-void llc_pdu_init_as_sabme_cmd(struct sk_buff *skb, u8 p_bit);
-void llc_pdu_init_as_dm_rsp(struct sk_buff *skb, u8 f_bit);
-void llc_pdu_init_as_frmr_rsp(struct sk_buff *skb, struct llc_pdu_sn *prev_pdu,
- u8 f_bit, u8 vs, u8 vr, u8 vzyxw);
-void llc_pdu_init_as_rr_rsp(struct sk_buff *skb, u8 f_bit, u8 nr);
-void llc_pdu_init_as_rej_rsp(struct sk_buff *skb, u8 f_bit, u8 nr);
-void llc_pdu_init_as_rnr_rsp(struct sk_buff *skb, u8 f_bit, u8 nr);
-void llc_pdu_init_as_ua_rsp(struct sk_buff *skb, u8 f_bit);
#endif /* LLC_PDU_H */
diff --git a/include/net/llc_s_ac.h b/include/net/llc_s_ac.h
deleted file mode 100644
index 076adc5217fd..000000000000
--- a/include/net/llc_s_ac.h
+++ /dev/null
@@ -1,35 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-#ifndef LLC_S_AC_H
-#define LLC_S_AC_H
-/*
- * Copyright (c) 1997 by Procom Technology,Inc.
- * 2001 by Arnaldo Carvalho de Melo <acme@conectiva.com.br>
- */
-
-struct llc_sap;
-struct sk_buff;
-
-/* SAP component actions */
-#define SAP_ACT_UNITDATA_IND 1
-#define SAP_ACT_SEND_UI 2
-#define SAP_ACT_SEND_XID_C 3
-#define SAP_ACT_SEND_XID_R 4
-#define SAP_ACT_SEND_TEST_C 5
-#define SAP_ACT_SEND_TEST_R 6
-#define SAP_ACT_REPORT_STATUS 7
-#define SAP_ACT_XID_IND 8
-#define SAP_ACT_TEST_IND 9
-
-/* All action functions must look like this */
-typedef int (*llc_sap_action_t)(struct llc_sap *sap, struct sk_buff *skb);
-
-int llc_sap_action_unitdata_ind(struct llc_sap *sap, struct sk_buff *skb);
-int llc_sap_action_send_ui(struct llc_sap *sap, struct sk_buff *skb);
-int llc_sap_action_send_xid_c(struct llc_sap *sap, struct sk_buff *skb);
-int llc_sap_action_send_xid_r(struct llc_sap *sap, struct sk_buff *skb);
-int llc_sap_action_send_test_c(struct llc_sap *sap, struct sk_buff *skb);
-int llc_sap_action_send_test_r(struct llc_sap *sap, struct sk_buff *skb);
-int llc_sap_action_report_status(struct llc_sap *sap, struct sk_buff *skb);
-int llc_sap_action_xid_ind(struct llc_sap *sap, struct sk_buff *skb);
-int llc_sap_action_test_ind(struct llc_sap *sap, struct sk_buff *skb);
-#endif /* LLC_S_AC_H */
diff --git a/include/net/llc_s_ev.h b/include/net/llc_s_ev.h
deleted file mode 100644
index 7b9c94093336..000000000000
--- a/include/net/llc_s_ev.h
+++ /dev/null
@@ -1,61 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-#ifndef LLC_S_EV_H
-#define LLC_S_EV_H
-/*
- * Copyright (c) 1997 by Procom Technology,Inc.
- * 2001 by Arnaldo Carvalho de Melo <acme@conectiva.com.br>
- */
-
-#include <linux/skbuff.h>
-#include <net/llc.h>
-
-/* Defines SAP component events */
-/* Types of events (possible values in 'ev->type') */
-#define LLC_SAP_EV_TYPE_SIMPLE 1
-#define LLC_SAP_EV_TYPE_CONDITION 2
-#define LLC_SAP_EV_TYPE_PRIM 3
-#define LLC_SAP_EV_TYPE_PDU 4 /* command/response PDU */
-#define LLC_SAP_EV_TYPE_ACK_TMR 5
-#define LLC_SAP_EV_TYPE_RPT_STATUS 6
-
-#define LLC_SAP_EV_ACTIVATION_REQ 1
-#define LLC_SAP_EV_RX_UI 2
-#define LLC_SAP_EV_UNITDATA_REQ 3
-#define LLC_SAP_EV_XID_REQ 4
-#define LLC_SAP_EV_RX_XID_C 5
-#define LLC_SAP_EV_RX_XID_R 6
-#define LLC_SAP_EV_TEST_REQ 7
-#define LLC_SAP_EV_RX_TEST_C 8
-#define LLC_SAP_EV_RX_TEST_R 9
-#define LLC_SAP_EV_DEACTIVATION_REQ 10
-
-struct llc_sap_state_ev {
- u8 prim;
- u8 prim_type;
- u8 type;
- u8 reason;
- u8 ind_cfm_flag;
- struct llc_addr saddr;
- struct llc_addr daddr;
-};
-
-static __inline__ struct llc_sap_state_ev *llc_sap_ev(struct sk_buff *skb)
-{
- return (struct llc_sap_state_ev *)skb->cb;
-}
-
-struct llc_sap;
-
-typedef int (*llc_sap_ev_t)(struct llc_sap *sap, struct sk_buff *skb);
-
-int llc_sap_ev_activation_req(struct llc_sap *sap, struct sk_buff *skb);
-int llc_sap_ev_rx_ui(struct llc_sap *sap, struct sk_buff *skb);
-int llc_sap_ev_unitdata_req(struct llc_sap *sap, struct sk_buff *skb);
-int llc_sap_ev_xid_req(struct llc_sap *sap, struct sk_buff *skb);
-int llc_sap_ev_rx_xid_c(struct llc_sap *sap, struct sk_buff *skb);
-int llc_sap_ev_rx_xid_r(struct llc_sap *sap, struct sk_buff *skb);
-int llc_sap_ev_test_req(struct llc_sap *sap, struct sk_buff *skb);
-int llc_sap_ev_rx_test_c(struct llc_sap *sap, struct sk_buff *skb);
-int llc_sap_ev_rx_test_r(struct llc_sap *sap, struct sk_buff *skb);
-int llc_sap_ev_deactivation_req(struct llc_sap *sap, struct sk_buff *skb);
-#endif /* LLC_S_EV_H */
diff --git a/include/net/llc_s_st.h b/include/net/llc_s_st.h
deleted file mode 100644
index 85ce230fd946..000000000000
--- a/include/net/llc_s_st.h
+++ /dev/null
@@ -1,32 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-#ifndef LLC_S_ST_H
-#define LLC_S_ST_H
-/*
- * Copyright (c) 1997 by Procom Technology,Inc.
- * 2001 by Arnaldo Carvalho de Melo <acme@conectiva.com.br>
- */
-
-#include <linux/types.h>
-#include <net/llc_s_ac.h>
-#include <net/llc_s_ev.h>
-
-struct llc_sap_state_trans;
-
-#define LLC_NR_SAP_STATES 2 /* size of state table */
-
-/* structures and types */
-/* SAP state table structure */
-struct llc_sap_state_trans {
- llc_sap_ev_t ev;
- u8 next_state;
- const llc_sap_action_t *ev_actions;
-};
-
-struct llc_sap_state {
- u8 curr_state;
- const struct llc_sap_state_trans **transitions;
-};
-
-/* only access to SAP state table */
-extern struct llc_sap_state llc_sap_state_table[LLC_NR_SAP_STATES];
-#endif /* LLC_S_ST_H */
diff --git a/include/net/llc_sap.h b/include/net/llc_sap.h
deleted file mode 100644
index b259f5993c46..000000000000
--- a/include/net/llc_sap.h
+++ /dev/null
@@ -1,26 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-#ifndef LLC_SAP_H
-#define LLC_SAP_H
-
-#include <asm/types.h>
-
-/*
- * Copyright (c) 1997 by Procom Technology,Inc.
- * 2001-2003 by Arnaldo Carvalho de Melo <acme@conectiva.com.br>
- */
-struct llc_sap;
-struct net_device;
-struct sk_buff;
-struct sock;
-
-void llc_sap_rtn_pdu(struct llc_sap *sap, struct sk_buff *skb);
-void llc_save_primitive(struct sock *sk, struct sk_buff *skb,
- unsigned char prim);
-struct sk_buff *llc_alloc_frame(struct sock *sk, struct net_device *dev,
- u8 type, u32 data_size);
-
-void llc_build_and_send_test_pkt(struct llc_sap *sap, struct sk_buff *skb,
- unsigned char *dmac, unsigned char dsap);
-void llc_build_and_send_xid_pkt(struct llc_sap *sap, struct sk_buff *skb,
- unsigned char *dmac, unsigned char dsap);
-#endif /* LLC_SAP_H */
diff --git a/include/net/mac80211.h b/include/net/mac80211.h
index 9d1fac6e8082..a1a6409b44c1 100644
--- a/include/net/mac80211.h
+++ b/include/net/mac80211.h
@@ -640,7 +640,6 @@ struct ieee80211_bss_npca_params {
* mode only, set if the AP advertises TWT responder role)
* @twt_responder: does this BSS support TWT requester (relevant for managed
* mode only, set if the AP advertises TWT responder role)
- * @twt_protected: does this BSS support protected TWT frames
* @twt_broadcast: does this BSS support broadcast TWT
* @use_cts_prot: use CTS protection
* @use_short_preamble: use 802.11b short preamble
@@ -812,7 +811,6 @@ struct ieee80211_bss_conf {
bool he_support;
bool twt_requester;
bool twt_responder;
- bool twt_protected;
bool twt_broadcast;
/* erp related data */
bool use_cts_prot;
@@ -923,12 +921,14 @@ struct ieee80211_bss_conf {
* @channel_entry: the Channel Entry blob as defined in Wi-Fi Aware
* (TM) 4.0 specification Table 100 (Channel Entry format for the NAN
* Availability attribute).
+ * @no_evacuate: if set, this channel must not be evacuated
*/
struct ieee80211_nan_channel {
struct ieee80211_chan_req chanreq;
u8 needed_rx_chains;
struct ieee80211_chanctx_conf *chanctx_conf;
u8 channel_entry[6];
+ bool no_evacuate;
};
/**
@@ -1770,10 +1770,9 @@ enum mac80211_rx_encoding {
* @ampdu_reference: A-MPDU reference number, must be a different value for
* each A-MPDU but the same for each subframe within one A-MPDU
* @zero_length_psdu_type: radiotap type of the 0-length PSDU
- * @link_valid: if the link which is identified by @link_id is valid. This flag
- * is set only when connection is MLO.
- * @link_id: id of the link used to receive the packet. This is used along with
- * @link_valid.
+ * @link_id: id of the link used to receive the packet. Set and used by
+ * mac80211 internally, it uses @freq set by the driver to identify the
+ * correct link per vif.
*/
struct ieee80211_rx_status {
u64 mactime;
@@ -1813,7 +1812,7 @@ struct ieee80211_rx_status {
u8 chains;
s8 chain_signal[IEEE80211_MAX_CHAINS];
u8 zero_length_psdu_type;
- u8 link_valid:1, link_id:4;
+ u8 link_id:4;
};
static_assert(sizeof(struct ieee80211_rx_status) <= sizeof_field(struct sk_buff, cb));
@@ -2396,6 +2395,8 @@ static inline bool lockdep_vif_wiphy_mutex_held(struct ieee80211_vif *vif)
* number generation only
* @IEEE80211_KEY_FLAG_SPP_AMSDU: SPP A-MSDUs can be used with this key
* (set by mac80211 from the sta->spp_amsdu flag)
+ * @IEEE80211_KEY_FLAG_CIP: This key is used for the Control Integrity
+ * Protocol, and is either a pairwise key or a CIGTK.
*/
enum ieee80211_key_flags {
IEEE80211_KEY_FLAG_GENERATE_IV_MGMT = BIT(0),
@@ -2410,6 +2411,7 @@ enum ieee80211_key_flags {
IEEE80211_KEY_FLAG_NO_AUTO_TX = BIT(9),
IEEE80211_KEY_FLAG_GENERATE_MMIE = BIT(10),
IEEE80211_KEY_FLAG_SPP_AMSDU = BIT(11),
+ IEEE80211_KEY_FLAG_CIP = BIT(12),
};
/**
@@ -2630,6 +2632,7 @@ struct ieee80211_sta_aggregates {
* @eht_cap: EHT capabilities of this STA
* @uhr_cap: UHR capabilities of this STA
* @s1g_cap: S1G capabilities of this STA
+ * @cip_cap: the CIP capabilities of this STA (or zero)
* @agg: per-link data for multi-link aggregation
* @bandwidth: current bandwidth the station can receive with.
* This is the minimum between the peer's capabilities and our own
@@ -2658,6 +2661,7 @@ struct ieee80211_link_sta {
struct ieee80211_sta_eht_cap eht_cap;
struct ieee80211_sta_uhr_cap uhr_cap;
struct ieee80211_sta_s1g_cap s1g_cap;
+ u8 cip_cap;
struct ieee80211_sta_aggregates agg;
@@ -2721,6 +2725,8 @@ struct ieee80211_link_sta {
* @valid_links: bitmap of valid links, or 0 for non-MLO
* @spp_amsdu: indicates whether the STA uses SPP A-MSDU or not.
* @epp_peer: indicates that the peer is an EPP peer.
+ * @cip: indicates whether the STA uses control frame protection or not.
+ * @twt_protected: does this STA support protected TWT frames
* @nmi: For NDI stations, pointer to the NMI station of the peer.
* @nan_sched: NAN peer schedule for this station. Valid only for NMI stations.
* @ext_mld_capa_ops: the MLD's extended MLD capabilities and operations
@@ -2742,6 +2748,9 @@ struct ieee80211_sta {
u8 max_amsdu_subframes;
u16 eml_cap;
+ bool cip;
+ bool twt_protected;
+
struct ieee80211_sta_aggregates *cur;
bool support_p2p_ps;
@@ -2919,8 +2928,8 @@ struct ieee80211_txq {
* autonomously manages the PS status of connected stations. When
* this flag is set mac80211 will not trigger PS mode for connected
* stations based on the PM bit of incoming frames.
- * Use ieee80211_start_ps()/ieee8021_end_ps() to manually configure
- * the PS mode of connected stations.
+ * Use ieee80211_sta_ps_transition() to manually toggle the PS mode
+ * of connected stations.
*
* @IEEE80211_HW_TX_AMPDU_SETUP_IN_HW: The device handles TX A-MPDU session
* setup strictly in HW. mac80211 should not attempt to do this in
@@ -4360,6 +4369,13 @@ struct ieee80211_prep_tx_info {
* Statistics that the driver doesn't fill will be filled by mac80211.
* The callback can sleep.
*
+ * @sta_statistics_atomic: Like @sta_statistics, but called under RCU, so it
+ * must be atomic. This is called instead of @sta_statistics if available,
+ * but may return -EAGAIN to fall back to @sta_statistics with the wiphy
+ * mutex held.
+ * Note that it's not guaranteed this will always be called first, some
+ * (internal) calls may call @sta_statistics directly.
+ *
* @link_sta_statistics: Get link statistics for this station. For example with
* beacon filtering, the statistics kept by mac80211 might not be
* accurate, so let the driver pre-fill the statistics. The driver can
@@ -4369,6 +4385,9 @@ struct ieee80211_prep_tx_info {
* Statistics that the driver doesn't fill will be filled by mac80211.
* The callback can sleep.
*
+ * @link_sta_statistics_atomic: Like @link_sta_statistics, with the same
+ * locking/retry semantics as @sta_statistics_atomic. Must be atomic.
+ *
* @conf_tx: Configure TX queue parameters (EDCF (aifs, cw_min, cw_max),
* bursting) for a hardware TX queue.
* Returns a negative error code on failure.
@@ -4577,6 +4596,9 @@ struct ieee80211_prep_tx_info {
* just "paused" for scanning/ROC, which is indicated by the beacon being
* disabled/enabled via @bss_info_changed.
* @stop_ap: Stop operation on the AP interface.
+ * @update_beacon: Update the templates indicated by @changed (beacon, probe
+ * response, FILS discovery and/or unsolicitated bcast probe response)
+ * without the wiphy mutex held. This callback must not sleep.
*
* @reconfig_complete: Called after a call to ieee80211_restart_hw() and
* during resume, when the reconfiguration has completed.
@@ -4774,6 +4796,10 @@ struct ieee80211_ops {
struct ieee80211_bss_conf *link_conf);
void (*stop_ap)(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
struct ieee80211_bss_conf *link_conf);
+ void (*update_beacon)(struct ieee80211_hw *hw,
+ struct ieee80211_vif *vif,
+ struct ieee80211_bss_conf *link_conf,
+ u64 changed);
u64 (*prepare_multicast)(struct ieee80211_hw *hw,
struct netdev_hw_addr_list *mc_list);
@@ -4867,6 +4893,10 @@ struct ieee80211_ops {
struct ieee80211_vif *vif,
struct ieee80211_sta *sta,
struct station_info *sinfo);
+ int (*sta_statistics_atomic)(struct ieee80211_hw *hw,
+ struct ieee80211_vif *vif,
+ struct ieee80211_sta *sta,
+ struct station_info *sinfo);
int (*conf_tx)(struct ieee80211_hw *hw,
struct ieee80211_vif *vif,
unsigned int link_id, u16 ac,
@@ -4882,6 +4912,10 @@ struct ieee80211_ops {
struct ieee80211_vif *vif,
struct ieee80211_link_sta *link_sta,
struct link_station_info *link_sinfo);
+ int (*link_sta_statistics_atomic)(struct ieee80211_hw *hw,
+ struct ieee80211_vif *vif,
+ struct ieee80211_link_sta *link_sta,
+ struct link_station_info *link_sinfo);
/**
* @ampdu_action:
@@ -5389,14 +5423,18 @@ void ieee80211_restart_hw(struct ieee80211_hw *hw);
* mixed for a single hardware. Must not run concurrently with
* ieee80211_tx_status_skb() or ieee80211_tx_status_ni().
*
+ * For data frames, when hardware has done address translation, a link station
+ * has to be provided and the frequency information may be skipped.
+ *
* This function must be called with BHs disabled and RCU read lock
*
* @hw: the hardware this frame came in on
- * @sta: the station the frame was received from, or %NULL
+ * @link_sta: the link station the data frame was received from, or %NULL
* @skb: the buffer to receive, owned by mac80211 after this call
* @list: the destination list
*/
-void ieee80211_rx_list(struct ieee80211_hw *hw, struct ieee80211_sta *sta,
+void ieee80211_rx_list(struct ieee80211_hw *hw,
+ struct ieee80211_link_sta *link_sta,
struct sk_buff *skb, struct list_head *list);
/**
@@ -5414,14 +5452,18 @@ void ieee80211_rx_list(struct ieee80211_hw *hw, struct ieee80211_sta *sta,
* mixed for a single hardware. Must not run concurrently with
* ieee80211_tx_status_skb() or ieee80211_tx_status_ni().
*
+ * For data frames, when hardware has done address translation, a link station
+ * has to be provided and the frequency information may be skipped.
+ *
* This function must be called with BHs disabled.
*
* @hw: the hardware this frame came in on
- * @sta: the station the frame was received from, or %NULL
+ * @link_sta: the link station the data frame was received from, or %NULL
* @skb: the buffer to receive, owned by mac80211 after this call
* @napi: the NAPI context
*/
-void ieee80211_rx_napi(struct ieee80211_hw *hw, struct ieee80211_sta *sta,
+void ieee80211_rx_napi(struct ieee80211_hw *hw,
+ struct ieee80211_link_sta *link_sta,
struct sk_buff *skb, struct napi_struct *napi);
/**
@@ -5499,10 +5541,8 @@ static inline void ieee80211_rx_ni(struct ieee80211_hw *hw,
*
* @sta: currently connected sta
* @start: start or stop PS
- *
- * Return: 0 on success. -EINVAL when the requested PS mode is already set.
*/
-int ieee80211_sta_ps_transition(struct ieee80211_sta *sta, bool start);
+void ieee80211_sta_ps_transition(struct ieee80211_sta *sta, bool start);
/**
* ieee80211_sta_ps_transition_ni - PS transition for connected sta
@@ -5514,19 +5554,13 @@ int ieee80211_sta_ps_transition(struct ieee80211_sta *sta, bool start);
*
* @sta: currently connected sta
* @start: start or stop PS
- *
- * Return: Like ieee80211_sta_ps_transition().
*/
-static inline int ieee80211_sta_ps_transition_ni(struct ieee80211_sta *sta,
+static inline void ieee80211_sta_ps_transition_ni(struct ieee80211_sta *sta,
bool start)
{
- int ret;
-
local_bh_disable();
- ret = ieee80211_sta_ps_transition(sta, start);
+ ieee80211_sta_ps_transition(sta, start);
local_bh_enable();
-
- return ret;
}
/**
@@ -6279,6 +6313,7 @@ void ieee80211_set_key_rx_seq(struct ieee80211_key_conf *keyconf,
* @key_len: the key data. Might be bigger than the actual key length,
* but not smaller (for the driver convinence)
* @link_id: the link id of the key or -1 for non-MLO
+ * @cigtk: whether this is a CIGTK
*
* When GTK rekeying was done while the system was suspended, (a) new
* key(s) will be available. These will be needed by mac80211 for proper
@@ -6305,7 +6340,7 @@ void ieee80211_set_key_rx_seq(struct ieee80211_key_conf *keyconf,
struct ieee80211_key_conf *
ieee80211_gtk_rekey_add(struct ieee80211_vif *vif,
u8 idx, u8 *key_data, u8 key_len,
- int link_id);
+ int link_id, bool cigtk);
/**
* ieee80211_gtk_rekey_notify - notify userspace supplicant of rekeying
@@ -7638,11 +7673,16 @@ bool ieee80211_tx_prepare_skb(struct ieee80211_hw *hw,
*
* @skb: packet injected by userspace
* @dev: the &struct device of this 802.11 device
+ * @chandef: the channel definition the frame will be transmitted on, or
+ * %NULL to skip the bandwidth checks
+ * @trim_fcs: trim the FCS trailer when present; validate it otherwise
*
* Return: %true if the radiotap header was parsed, %false otherwise
*/
bool ieee80211_parse_tx_radiotap(struct sk_buff *skb,
- struct net_device *dev);
+ struct net_device *dev,
+ const struct cfg80211_chan_def *chandef,
+ bool trim_fcs);
/**
* struct ieee80211_noa_data - holds temporary data for tracking P2P NoA state
@@ -8059,25 +8099,6 @@ ieee80211_obss_color_collision_notify(struct ieee80211_vif *vif,
u64 color_bitmap, u8 link_id);
/**
- * ieee80211_is_tx_data - check if frame is a data frame
- *
- * The function is used to check if a frame is a data frame. Frames with
- * hardware encapsulation enabled are data frames.
- *
- * @skb: the frame to be transmitted.
- *
- * Return: %true if @skb is a data frame, %false otherwise
- */
-static inline bool ieee80211_is_tx_data(struct sk_buff *skb)
-{
- struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
- struct ieee80211_hdr *hdr = (void *) skb->data;
-
- return info->flags & IEEE80211_TX_CTL_HW_80211_ENCAP ||
- ieee80211_is_data(hdr->frame_control);
-}
-
-/**
* ieee80211_set_active_links - set active links in client mode
* @vif: interface to set active links on
* @active_links: the new active links bitmap
diff --git a/include/net/mana/gdma.h b/include/net/mana/gdma.h
index 308950f9b54b..0b52582118e8 100644
--- a/include/net/mana/gdma.h
+++ b/include/net/mana/gdma.h
@@ -6,6 +6,7 @@
#include <linux/dma-mapping.h>
#include <linux/netdevice.h>
+#include <rdma/ib_verbs.h>
#include "shm_channel.h"
@@ -54,6 +55,7 @@ enum gdma_work_request_flags {
GDMA_WR_NONE = 0,
GDMA_WR_OOB_IN_SGL = BIT(0),
GDMA_WR_PAD_BY_SGE0 = BIT(1),
+ GDMA_WR_IB_SGL = BIT(2),
};
enum gdma_eqe_type {
@@ -212,7 +214,10 @@ struct gdma_sge {
}; /* HW DATA */
struct gdma_wqe_request {
- struct gdma_sge *sgl;
+ union {
+ struct gdma_sge *sgl;
+ struct ib_sge *ib_sgl;
+ };
u32 num_sge;
u32 inline_oob_size;
@@ -422,14 +427,74 @@ enum gdma_context_flags {
GC_IN_SERVICE = 1,
};
+struct gdma_context;
+
+/**
+ * struct gdma_bus_ops - transport-specific operations
+ *
+ * Lets the bus-agnostic GDMA core drive PCI and CDX devices without
+ * testing configuration symbols. Each bus driver installs its own
+ * instance in gdma_context.bus_ops at probe time.
+ *
+ * @bus_name: Bus token used to build the per-vector IRQ names.
+ * @adev_prefix: Prefix used for auxiliary-device match names.
+ * @msix_can_alloc_dyn: True if the bus can allocate MSI-X vectors after
+ * probe time. Buses that size their vector pool at probe and cannot
+ * grow it later leave this NULL.
+ * @msix_virq: Return the Linux IRQ number backing an MSI vector, or
+ * -EINVAL if the vector has not been allocated yet.
+ * @msix_alloc_at: Allocate an MSI vector on demand and return its IRQ
+ * number, updating @msi with the index actually assigned. Buses that
+ * allocate their whole pool up front leave this NULL.
+ * @msix_free: Release a vector obtained from @msix_alloc_at. Only needed
+ * by buses that implement @msix_alloc_at.
+ * @msix_vec_count: Return the number of entries in the device MSI-X table,
+ * used to clamp the vector count the core asks for. Buses that cannot
+ * report a table size leave this NULL and the clamp is skipped.
+ * @setup_hwc_irqs: Set up the interrupts the hardware channel needs before
+ * it is created.
+ * @setup_remaining_irqs: Set up the remaining interrupts once the device
+ * resource limits are known.
+ * @remove_irqs: Release the interrupts set up by @setup_hwc_irqs and
+ * @setup_remaining_irqs.
+ * @dev_reset: Reset the device using the bus-level reset mechanism.
+ * @schedule_serv_work: Queue device servicing or recovery. Buses without
+ * a servicing path leave this NULL.
+ * @drv_cap_flags1: Extra capability bits this transport can honour, OR'ed
+ * into GDMA_DRV_CAP_FLAGS1 when the driver version is negotiated.
+ */
+struct gdma_bus_ops {
+ const char *bus_name;
+ const char *adev_prefix;
+ bool (*msix_can_alloc_dyn)(struct gdma_context *gc);
+ int (*msix_virq)(struct gdma_context *gc, int msi);
+ int (*msix_alloc_at)(struct gdma_context *gc, int *msi);
+ void (*msix_free)(struct gdma_context *gc, int msi, int irq);
+ int (*msix_vec_count)(struct gdma_context *gc);
+ int (*setup_hwc_irqs)(struct gdma_context *gc);
+ int (*setup_remaining_irqs)(struct gdma_context *gc);
+ void (*remove_irqs)(struct gdma_context *gc);
+ int (*dev_reset)(struct gdma_context *gc);
+ int (*schedule_serv_work)(struct gdma_context *gc,
+ enum gdma_eqe_type type);
+ u64 drv_cap_flags1;
+};
+
struct gdma_context {
struct device *dev;
struct dentry *mana_pci_debugfs;
+ /* Transport-specific operations, installed by the bus driver */
+ const struct gdma_bus_ops *bus_ops;
+
/* Hardware max number of queues */
unsigned int max_num_queues;
/* Per-vPort max number of queues */
unsigned int max_num_queues_vport;
+ /* Number of vPorts reported by the device, capped at
+ * MAX_PORTS_IN_MANA_DEV
+ */
+ u16 num_ports;
unsigned int max_num_msix;
unsigned int num_msix_usable;
struct xarray irq_contexts;
@@ -529,6 +594,10 @@ ssize_t mana_gd_read_ring(struct gdma_queue *q, char __user *buf,
int mana_schedule_serv_work(struct gdma_context *gc, enum gdma_eqe_type type);
+int mana_gd_alloc_service_wq(struct gdma_context *gc);
+
+void mana_gd_free_service_wq(struct gdma_context *gc);
+
void mana_gd_ring_dim(struct gdma_queue *cq, u32 mod_usec, bool mod_usec_vld,
u32 mod_comps, bool mod_comps_vld);
@@ -552,6 +621,7 @@ struct gdma_wqe {
#define INLINE_OOB_SMALL_SIZE 8
#define INLINE_OOB_LARGE_SIZE 24
+#define INLINE_OOB_EXTRA_LARGE_SIZE 32
#define MANA_MAX_TX_WQE_SGL_ENTRIES 30
@@ -622,8 +692,12 @@ struct gdma_eqe {
#define MANA_PF2_DEVICE_ID 0x00C1
#define MANA_VF_DEVICE_ID 0x00BA
+#define MANA_CDX_DEVICE_ID 0x00C2
+
struct gdma_posted_wqe_info {
u32 wqe_size_in_bu;
+ /* Unmasked WQE start offset in GDMA basic units. */
+ u32 wqe_offset;
};
/* GDMA_GENERATE_TEST_EQE */
@@ -686,21 +760,28 @@ enum {
/* Driver supports non-contiguous queue buffers */
#define GDMA_DRV_CAP_FLAG_1_NON_CONTIGUOUS_BUFFERS BIT(30)
+/* Capabilities in the PCI-only group below rely on dynamic MSI-X allocation
+ * and on the servicing and reset paths reached through
+ * mana_schedule_serv_work(). Transports that provide neither leave
+ * gdma_bus_ops.drv_cap_flags1 unset so the group is not advertised.
+ */
+#define GDMA_DRV_CAP_FLAGS1_PCI \
+ (GDMA_DRV_CAP_FLAG_1_DYNAMIC_IRQ_ALLOC_SUPPORT | \
+ GDMA_DRV_CAP_FLAG_1_SELF_RESET_ON_EQE | \
+ GDMA_DRV_CAP_FLAG_1_HANDLE_RECONFIG_EQE | \
+ GDMA_DRV_CAP_FLAG_1_PROBE_RECOVERY | \
+ GDMA_DRV_CAP_FLAG_1_HWC_TIMEOUT_RECOVERY)
+
#define GDMA_DRV_CAP_FLAGS1 \
(GDMA_DRV_CAP_FLAG_1_EQ_SHARING_MULTI_VPORT | \
GDMA_DRV_CAP_FLAG_1_NAPI_WKDONE_FIX | \
GDMA_DRV_CAP_FLAG_1_HWC_TIMEOUT_RECONFIG | \
GDMA_DRV_CAP_FLAG_1_VARIABLE_INDIRECTION_TABLE_SUPPORT | \
GDMA_DRV_CAP_FLAG_1_DEV_LIST_HOLES_SUP | \
- GDMA_DRV_CAP_FLAG_1_DYNAMIC_IRQ_ALLOC_SUPPORT | \
- GDMA_DRV_CAP_FLAG_1_SELF_RESET_ON_EQE | \
- GDMA_DRV_CAP_FLAG_1_HANDLE_RECONFIG_EQE | \
GDMA_DRV_CAP_FLAG_1_HW_VPORT_LINK_AWARE | \
GDMA_DRV_CAP_FLAG_1_PERIODIC_STATS_QUERY | \
GDMA_DRV_CAP_FLAG_1_SKB_LINEARIZE | \
- GDMA_DRV_CAP_FLAG_1_PROBE_RECOVERY | \
GDMA_DRV_CAP_FLAG_1_HANDLE_STALL_SQ_RECOVERY | \
- GDMA_DRV_CAP_FLAG_1_HWC_TIMEOUT_RECOVERY | \
GDMA_DRV_CAP_FLAG_1_EQ_MSI_UNSHARE_MULTI_VPORT | \
GDMA_DRV_CAP_FLAG_1_DYN_INTERRUPT_MODERATION | \
GDMA_DRV_CAP_FLAG_1_NON_CONTIGUOUS_BUFFERS)
@@ -1044,7 +1125,24 @@ struct gdma_destroy_dm_resp {
struct gdma_resp_hdr hdr;
}; /* HW Data */
-int mana_gd_verify_vf_version(struct pci_dev *pdev);
+int mana_gd_verify_vf_version(struct gdma_context *gc);
+int mana_gd_query_max_resources(struct gdma_context *gc);
+int mana_gd_setup(struct gdma_context *gc);
+void mana_gd_cleanup(struct gdma_context *gc);
+int mana_gd_detect_devices(struct gdma_context *gc);
+int mana_gd_init_registers(struct gdma_context *gc);
+irqreturn_t mana_gd_intr(int irq, void *arg);
+void mana_gd_process_eq_events(void *arg);
+
+static inline u32 mana_gd_r32(struct gdma_context *g, u64 offset)
+{
+ return readl(g->bar0_va + offset);
+}
+
+static inline u64 mana_gd_r64(struct gdma_context *g, u64 offset)
+{
+ return readq(g->bar0_va + offset);
+}
int mana_gd_register_device(struct gdma_dev *gd);
int mana_gd_deregister_device(struct gdma_dev *gd);
@@ -1062,6 +1160,8 @@ void mana_gd_free_res_map(struct gdma_resource *r);
void mana_gd_wq_ring_doorbell(struct gdma_context *gc,
struct gdma_queue *queue);
+void mana_gd_wq_ring_doorbell_ext(struct gdma_context *gc, struct gdma_queue *queue,
+ u32 tail_ptr, u8 wqe_cnt, u8 client_offset);
int mana_gd_alloc_memory(struct gdma_context *gc, unsigned int length,
struct gdma_mem_info *gmi, bool allow_scatter);
@@ -1077,8 +1177,6 @@ void mana_unregister_debugfs(void);
int mana_rdma_service_event(struct gdma_context *gc, enum gdma_service_type event);
-int mana_gd_suspend(struct pci_dev *pdev, pm_message_t state);
-int mana_gd_resume(struct pci_dev *pdev);
bool mana_need_log(struct gdma_context *gc, int err);
@@ -1089,4 +1187,6 @@ void mana_gd_put_gic(struct gdma_context *gc, bool use_msi_bitmap, int msi);
int mana_gd_query_device_cfg(struct gdma_context *gc, u32 proto_major_ver,
u32 proto_minor_ver, u32 proto_micro_ver,
u16 *max_num_vports, u8 *bm_hostmode);
+int mana_gd_dev_reset(struct gdma_context *gc);
+
#endif /* _GDMA_H */
diff --git a/include/net/mana/hw_channel.h b/include/net/mana/hw_channel.h
index 16feb39616c1..1ab2d66c891e 100644
--- a/include/net/mana/hw_channel.h
+++ b/include/net/mana/hw_channel.h
@@ -20,8 +20,8 @@
#define HWC_INIT_DATA_MAX_NUM_CQS 7
#define HWC_INIT_DATA_PDID 8
#define HWC_INIT_DATA_GPA_MKEY 9
-#define HWC_INIT_DATA_PF_DEST_RQ_ID 10
-#define HWC_INIT_DATA_PF_DEST_CQ_ID 11
+#define HWC_INIT_DATA_DEST_RQ_ID 10
+#define HWC_INIT_DATA_DEST_CQ_ID 11
#define HWC_DATA_CFG_HWC_TIMEOUT 1
#define HWC_DATA_HW_LINK_CONNECT 2
@@ -195,8 +195,8 @@ struct hw_channel_context {
struct semaphore sema;
struct gdma_resource inflight_msg_res;
- u32 pf_dest_vrq_id;
- u32 pf_dest_vrcq_id;
+ u32 dest_vrq_id;
+ u32 dest_vrcq_id;
u32 hwc_timeout;
struct hwc_caller_ctx *caller_ctx;
diff --git a/include/net/mana/mana.h b/include/net/mana/mana.h
index 83b7eff4646e..71d726b1f784 100644
--- a/include/net/mana/mana.h
+++ b/include/net/mana/mana.h
@@ -47,8 +47,8 @@ enum mana_priv_flag_bits {
#define COMP_ENTRY_SIZE 64
/* This Max value for RX buffers is derived from __alloc_page()'s max page
- * allocation calculation. It allows maximum 2^(MAX_ORDER -1) pages. RX buffer
- * size beyond this value gets rejected by __alloc_page() call.
+ * allocation calculation. It allows maximum 2^MAX_PAGE_ORDER pages. RX
+ * buffer size beyond this value gets rejected by __alloc_page() call.
*/
#define MAX_RX_BUFFERS_PER_QUEUE 8192
#define DEF_RX_BUFFERS_PER_QUEUE 1024
@@ -377,7 +377,18 @@ struct mana_recv_buf_oob {
#define MANA_RXBUF_PAD (SKB_DATA_ALIGN(sizeof(struct skb_shared_info)) \
+ ETH_HLEN)
-#define MANA_XDP_MTU_MAX (PAGE_SIZE - MANA_RXBUF_PAD - XDP_PACKET_HEADROOM)
+/* Headroom an RX buffer has to reserve while XDP is attached: the XDP program
+ * needs XDP_PACKET_HEADROOM, and the TX path needs LL_RESERVED_SPACE() (see
+ * mana_get_rxbuf_headroom()). LL_RESERVED_SPACE() grows with MAX_SKB_FRAGS and
+ * exceeds XDP_PACKET_HEADROOM once CONFIG_MAX_SKB_FRAGS is 19 or more.
+ */
+static inline u32 mana_xdp_headroom(struct net_device *ndev)
+{
+ return max_t(u32, LL_RESERVED_SPACE(ndev), XDP_PACKET_HEADROOM);
+}
+
+#define MANA_XDP_MTU_MAX(ndev) \
+ (PAGE_SIZE - MANA_RXBUF_PAD - mana_xdp_headroom(ndev))
struct mana_rxq {
struct gdma_queue *gdma_rq;
@@ -661,6 +672,8 @@ struct mana_port_context {
u32 steer_cqe_coalescing;
};
+netdev_tx_t __mana_start_xmit(struct sk_buff *skb, struct net_device *ndev,
+ bool xdp);
netdev_tx_t mana_start_xmit(struct sk_buff *skb, struct net_device *ndev);
int mana_config_rss(struct mana_port_context *ac, enum TRI_STATE rx,
bool update_hash, bool update_tab);
@@ -691,6 +704,7 @@ int mana_query_link_cfg(struct mana_port_context *apc);
int mana_set_bw_clamp(struct mana_port_context *apc, u32 speed,
int enable_clamping);
void mana_query_phy_stats(struct mana_port_context *apc);
+bool mana_single_rxbuf_per_page_forced(struct mana_port_context *apc, u32 mtu);
int mana_pre_alloc_rxbufs(struct mana_port_context *apc, int mtu, int num_queues);
void mana_pre_dealloc_rxbufs(struct mana_port_context *apc);
void mana_unmap_skb(struct sk_buff *skb, struct mana_port_context *apc);
diff --git a/include/net/mptcp.h b/include/net/mptcp.h
index 485d55b66ea6..ad7005b574bb 100644
--- a/include/net/mptcp.h
+++ b/include/net/mptcp.h
@@ -219,6 +219,9 @@ int mptcp_subflow_init_cookie_req(struct request_sock *req,
struct request_sock *mptcp_subflow_reqsk_alloc(const struct request_sock_ops *ops,
struct sock *sk_listener,
bool attach_listener);
+/* Caller must hold an RCU read-side lock. */
+void mptcp_subflow_reqsk_clone(struct request_sock *req,
+ struct request_sock *new_req);
__be32 mptcp_get_reset_option(const struct sk_buff *skb);
@@ -305,6 +308,12 @@ static inline struct request_sock *mptcp_subflow_reqsk_alloc(const struct reques
return NULL;
}
+/* Caller must hold an RCU read-side lock. */
+static inline void mptcp_subflow_reqsk_clone(struct request_sock *req,
+ struct request_sock *new_req)
+{
+}
+
static inline __be32 mptcp_reset_option(const struct sk_buff *skb) { return htonl(0u); }
static inline void mptcp_active_detect_blackhole(struct sock *sk, bool expired) { }
diff --git a/include/net/ndisc.h b/include/net/ndisc.h
index 9e5379ad2d8e..91898a2475e7 100644
--- a/include/net/ndisc.h
+++ b/include/net/ndisc.h
@@ -67,6 +67,15 @@ struct prefix_info;
extern struct neigh_table nd_tbl;
+static inline struct neigh_table *nd_table(struct net *net)
+{
+#if IS_ENABLED(CONFIG_IPV6)
+ if (disable_ipv6_mod)
+ return &nd_tbl;
+#endif
+ return net->neigh_tables[NEIGH_ND_TABLE];
+}
+
struct nd_msg {
struct icmp6hdr icmph;
struct in6_addr target;
@@ -354,7 +363,9 @@ static inline u32 ndisc_hashfn(const void *pkey, const struct net_device *dev, _
static inline struct neighbour *__ipv6_neigh_lookup_noref(struct net_device *dev, const void *pkey)
{
- return ___neigh_lookup_noref(&nd_tbl, neigh_key_eq128, ndisc_hashfn, pkey, dev);
+ struct neigh_table *tbl = nd_table(dev_net(dev));
+
+ return ___neigh_lookup_noref(tbl, neigh_key_eq128, ndisc_hashfn, pkey, dev);
}
static inline struct neighbour *__ipv6_neigh_lookup(struct net_device *dev, const void *pkey)
@@ -370,6 +381,30 @@ static inline struct neighbour *__ipv6_neigh_lookup(struct net_device *dev, cons
return n;
}
+static inline struct neighbour *ipv6_neigh_lookup(struct net_device *dev,
+ const void *pkey)
+{
+ struct neigh_table *tbl = nd_table(dev_net(dev));
+
+ return neigh_lookup(tbl, pkey, dev);
+}
+
+static inline struct neighbour *ipv6_neigh_create(struct net_device *dev,
+ const void *pkey)
+{
+ struct neigh_table *tbl = nd_table(dev_net(dev));
+
+ return neigh_create(tbl, pkey, dev);
+}
+
+static inline struct neighbour *ipv6_neigh_create_noref(struct net_device *dev,
+ const void *pkey)
+{
+ struct neigh_table *tbl = nd_table(dev_net(dev));
+
+ return __neigh_create(tbl, pkey, dev, false);
+}
+
static inline void __ipv6_confirm_neigh(struct net_device *dev,
const void *pkey)
{
@@ -389,7 +424,7 @@ static inline struct neighbour *ip_neigh_gw6(struct net_device *dev,
neigh = __ipv6_neigh_lookup_noref(dev, addr);
if (unlikely(!neigh))
- neigh = __neigh_create(&nd_tbl, addr, dev, false);
+ neigh = ipv6_neigh_create_noref(dev, addr);
return neigh;
#else
diff --git a/include/net/neighbour.h b/include/net/neighbour.h
index 8860cc2175fc..79a5a548a129 100644
--- a/include/net/neighbour.h
+++ b/include/net/neighbour.h
@@ -31,6 +31,8 @@
#include <net/rtnetlink.h>
#include <net/neighbour_tables.h>
+extern int sysctl_neigh_inherit_init_net;
+
/*
* NUD stands for "neighbor unreachability detection"
*/
@@ -179,7 +181,6 @@ struct neigh_ops {
struct pneigh_entry {
struct pneigh_entry __rcu *next;
- possible_net_t net;
struct net_device *dev;
netdevice_tracker dev_tracker;
union {
@@ -234,7 +235,7 @@ struct neigh_table {
struct delayed_work managed_work;
struct timer_list proxy_timer;
struct sk_buff_head proxy_queue;
- atomic_t entries;
+ refcount_t entries;
atomic_t gc_entries;
struct list_head gc_list;
struct list_head managed_list;
@@ -339,8 +340,8 @@ static inline void neigh_confirm(struct neighbour *n)
}
}
-void neigh_table_init(int index, struct neigh_table *tbl);
-int neigh_table_clear(int index, struct neigh_table *tbl);
+int neigh_table_register(struct net *net, struct neigh_table *tbl, int index);
+void neigh_table_unregister(struct net *net, int index);
struct neighbour *neigh_lookup(struct neigh_table *tbl, const void *pkey,
struct net_device *dev);
struct neighbour *__neigh_create(struct neigh_table *tbl, const void *pkey,
@@ -389,24 +390,17 @@ static inline void neigh_set_reach_time(struct neigh_parms *p)
void pneigh_enqueue(struct neigh_table *tbl, struct neigh_parms *p,
struct sk_buff *skb);
-struct pneigh_entry *pneigh_lookup(struct neigh_table *tbl, struct net *net,
+struct pneigh_entry *pneigh_lookup(struct neigh_table *tbl,
const void *key, struct net_device *dev);
-int pneigh_create(struct neigh_table *tbl, struct net *net, const void *key,
+int pneigh_create(struct neigh_table *tbl, const void *key,
struct net_device *dev, u32 flags, u8 protocol,
bool permanent);
-int pneigh_delete(struct neigh_table *tbl, struct net *net, const void *key,
+int pneigh_delete(struct neigh_table *tbl, const void *key,
struct net_device *dev);
-static inline struct net *pneigh_net(const struct pneigh_entry *pneigh)
-{
- return read_pnet(&pneigh->net);
-}
-
void neigh_app_ns(struct neighbour *n);
void neigh_for_each(struct neigh_table *tbl,
void (*cb)(struct neighbour *, void *), void *cookie);
-void __neigh_for_each_release(struct neigh_table *tbl,
- int (*cb)(struct neighbour *));
int neigh_xmit(int fam, struct net_device *, const void *, struct sk_buff *);
struct neigh_seq_state {
@@ -560,30 +554,6 @@ static inline int neigh_output(struct neighbour *n, struct sk_buff *skb,
return READ_ONCE(n->output)(n, skb);
}
-static inline struct neighbour *
-__neigh_lookup(struct neigh_table *tbl, const void *pkey, struct net_device *dev, int creat)
-{
- struct neighbour *n = neigh_lookup(tbl, pkey, dev);
-
- if (n || !creat)
- return n;
-
- n = neigh_create(tbl, pkey, dev);
- return IS_ERR(n) ? NULL : n;
-}
-
-static inline struct neighbour *
-__neigh_lookup_errno(struct neigh_table *tbl, const void *pkey,
- struct net_device *dev)
-{
- struct neighbour *n = neigh_lookup(tbl, pkey, dev);
-
- if (n)
- return n;
-
- return neigh_create(tbl, pkey, dev);
-}
-
struct neighbour_cb {
unsigned long sched_next;
unsigned int flags;
diff --git a/include/net/net_namespace.h b/include/net/net_namespace.h
index e5ee673b9fcf..c29a22ca178f 100644
--- a/include/net/net_namespace.h
+++ b/include/net/net_namespace.h
@@ -39,6 +39,7 @@
#include <net/netns/mctp.h>
#include <net/netns/vsock.h>
#include <net/net_trackers.h>
+#include <net/neighbour_tables.h>
#include <linux/ns_common.h>
#include <linux/idr.h>
#include <linux/skbuff.h>
@@ -47,6 +48,7 @@
struct user_namespace;
struct proc_dir_entry;
+struct neigh_table;
struct net_device;
struct sock;
struct ctl_table_header;
@@ -69,6 +71,7 @@ struct net {
spinlock_t rules_mod_lock;
unsigned int dev_base_seq; /* protected by rtnl_mutex */
+ atomic_t dev_mc_genid; /* dev->mc membership changes */
u32 ifindex;
spinlock_t nsid_lock;
@@ -103,6 +106,8 @@ struct net {
struct proc_dir_entry *proc_net;
struct proc_dir_entry *proc_net_stat;
+ struct neigh_table *neigh_tables[NEIGH_NR_TABLES];
+
#ifdef CONFIG_SYSCTL
struct ctl_table_set sysctls;
#endif
diff --git a/include/net/netdev_lock.h b/include/net/netdev_lock.h
index 9fb3e93857c3..edd8cc2e2b36 100644
--- a/include/net/netdev_lock.h
+++ b/include/net/netdev_lock.h
@@ -110,34 +110,20 @@ static inline int netdev_is_locked_ops_compat(const struct net_device *dev)
return lockdep_rtnl_is_held();
}
-static inline int netdev_lock_cmp_fn(const struct lockdep_map *a,
- const struct lockdep_map *b)
-{
- if (a == b)
- return 0;
-
- /* Allow locking multiple devices only under rtnl_lock,
- * the exact order doesn't matter.
- * Note that upper devices don't lock their ops, so nesting
- * mostly happens in batched device removal for now.
- */
- return lockdep_rtnl_is_held() ? -1 : 1;
-}
+void netdev_set_instance_lock_class(struct net_device *dev);
#define netdev_lockdep_set_classes(dev) \
{ \
static struct lock_class_key qdisc_tx_busylock_key; \
static struct lock_class_key qdisc_xmit_lock_key; \
static struct lock_class_key dev_addr_list_lock_key; \
- static struct lock_class_key dev_instance_lock_key; \
unsigned int i; \
\
(dev)->qdisc_tx_busylock = &qdisc_tx_busylock_key; \
lockdep_set_class(&(dev)->addr_list_lock, \
&dev_addr_list_lock_key); \
- lockdep_set_class(&(dev)->lock, \
- &dev_instance_lock_key); \
- lock_set_cmp_fn(&dev->lock, netdev_lock_cmp_fn, NULL); \
+ if (IS_ENABLED(CONFIG_PROVE_LOCKING)) \
+ netdev_set_instance_lock_class(dev); \
for (i = 0; i < (dev)->num_tx_queues; i++) \
lockdep_set_class(&(dev)->_tx[i]._xmit_lock, \
&qdisc_xmit_lock_key); \
diff --git a/include/net/netdev_queues.h b/include/net/netdev_queues.h
index 70c9fe9e83cc..c5335e935b7d 100644
--- a/include/net/netdev_queues.h
+++ b/include/net/netdev_queues.h
@@ -5,17 +5,55 @@
#include <linux/netdevice.h>
/**
+ * struct netdev_ring_config - accepted RX ring depth configuration
+ * @rx_pending: Size of the regular RX ring.
+ * @rx_mini_pending: Size of the RX mini ring.
+ * @rx_jumbo_pending: Size of the RX jumbo ring.
+ *
+ * This stores only persistent configuration values. Capability fields,
+ * such as max ring sizes, are reported by drivers but are not part of the
+ * accepted configuration.
+ *
+ * These values are only used for queue-configuration validation today.
+ * Drivers which normalize ring sizes must update the struct ethtool_ringparam
+ * passed to set_ringparam() with the applied sizes.
+ */
+struct netdev_ring_config {
+ u32 rx_pending;
+ u32 rx_mini_pending;
+ u32 rx_jumbo_pending;
+};
+
+/**
* struct netdev_config - queue-related configuration for a netdev
* @hds_thresh: HDS Threshold value.
* @hds_config: HDS value from userspace.
+ * @rings: Accepted RX ring depths.
+ *
+ * Direct values, such as @hds_thresh and @rings, hold the accepted
+ * configuration and always override callback-provided defaults, including
+ * when zero. Drivers which use @rings for queue rendering must initialize
+ * every RX ring depth before registering the netdev.
*/
struct netdev_config {
u32 hds_thresh;
u8 hds_config;
+
+ struct netdev_ring_config rings;
};
+/**
+ * struct netdev_queue_config - rendered configuration for an RX queue
+ * @rx_page_size: Size of one RX page-pool allocation.
+ * @rx_ring_size: Configured size of the regular RX ring.
+ * @rx_mini_ring_size: Configured size of the RX mini ring.
+ * @rx_jumbo_ring_size: Configured size of the RX jumbo ring.
+ */
struct netdev_queue_config {
u32 rx_page_size;
+ u32 rx_ring_size;
+ u32 rx_mini_ring_size;
+ u32 rx_jumbo_ring_size;
};
/* See the netdev.yaml spec for definition of each statistic */
@@ -139,16 +177,20 @@ enum {
* @ndo_queue_get_dma_dev: Get dma device for zero-copy operations to be used
* for this queue. Return NULL on error.
*
- * @ndo_default_qcfg: (Optional) Populate queue config struct with defaults.
- * Queue config structs are passed to this helper before
- * the user-requested settings are applied.
+ * @ndo_default_qcfg: (Optional) Populate queue config with defaults. Queue
+ * config structs are passed to this helper before the
+ * user-requested settings are applied. Ring depths from
+ * dev->cfg override these defaults. Drivers which consume
+ * them must initialize dev->cfg->rings before registering
+ * the netdev.
*
* @ndo_validate_qcfg: (Optional) Check if queue config is supported.
* Called when configuration affecting a queue may be
- * changing, either due to NIC-wide config, or config
- * scoped to the queue at a specified index.
- * When NIC-wide config is changed the callback will
- * be invoked for all queues.
+ * changing. When NIC-wide config is changed the
+ * callback will be invoked for the defaults and all
+ * queue overrides. Drivers which normalize device-wide
+ * values when applying them must use the same
+ * normalization during validation.
*
* @ndo_queue_create: Create a new RX queue on a virtual device that will
* be paired with a physical device's queue via leasing.
diff --git a/include/net/netfilter/nf_conntrack.h b/include/net/netfilter/nf_conntrack.h
index bc42dd0e10e6..c39425e54d87 100644
--- a/include/net/netfilter/nf_conntrack.h
+++ b/include/net/netfilter/nf_conntrack.h
@@ -185,6 +185,11 @@ static inline void nf_ct_put(struct nf_conn *ct)
nf_ct_destroy(&ct->ct_general);
}
+static inline bool nf_ct_shared(const struct nf_conn *ct)
+{
+ return refcount_read(&ct->ct_general.use) > 1;
+}
+
/* load module; enable/disable conntrack in this namespace */
int nf_ct_netns_get(struct net *net, u8 nfproto);
void nf_ct_netns_put(struct net *net, u8 nfproto);
diff --git a/include/net/netfilter/nf_conntrack_seqadj.h b/include/net/netfilter/nf_conntrack_seqadj.h
index 883c414b768e..0f5bbb14a25a 100644
--- a/include/net/netfilter/nf_conntrack_seqadj.h
+++ b/include/net/netfilter/nf_conntrack_seqadj.h
@@ -33,6 +33,7 @@ static inline struct nf_conn_seqadj *nfct_seqadj_ext_add(struct nf_conn *ct)
int nf_ct_seqadj_init(struct nf_conn *ct, enum ip_conntrack_info ctinfo,
s32 off);
+void nf_ct_seqadj_reset(struct nf_conn *ct, enum ip_conntrack_info ctinfo);
int nf_ct_seqadj_set(struct nf_conn *ct, enum ip_conntrack_info ctinfo,
__be32 seq, s32 off);
void nf_ct_tcp_seqadj_set(struct sk_buff *skb, struct nf_conn *ct,
diff --git a/include/net/netfilter/nf_flow_table.h b/include/net/netfilter/nf_flow_table.h
index f2e2771f188f..5b22d31cb140 100644
--- a/include/net/netfilter/nf_flow_table.h
+++ b/include/net/netfilter/nf_flow_table.h
@@ -118,6 +118,7 @@ struct flow_offload_tunnel {
};
u8 inner_proto;
+ u8 encap_proto;
};
struct flow_offload_tuple {
@@ -183,10 +184,10 @@ enum nf_flow_flags {
NF_FLOW_DNAT,
NF_FLOW_CLOSING,
NF_FLOW_TEARDOWN,
+ NF_FLOW_PENDING,
NF_FLOW_HW,
NF_FLOW_HW_DYING,
NF_FLOW_HW_DEAD,
- NF_FLOW_HW_PENDING,
NF_FLOW_HW_BIDIRECTIONAL,
NF_FLOW_HW_ESTABLISHED,
};
diff --git a/include/net/netfilter/nf_queue.h b/include/net/netfilter/nf_queue.h
index fc3e81c07364..86021c55ba3c 100644
--- a/include/net/netfilter/nf_queue.h
+++ b/include/net/netfilter/nf_queue.h
@@ -35,7 +35,8 @@ struct nf_queue_entry {
struct nf_queue_handler {
int (*outfn)(struct nf_queue_entry *entry,
unsigned int queuenum);
- void (*nf_hook_drop)(struct net *net);
+ void (*nf_hook_drop)(struct net *net,
+ const struct nf_hook_ops *ops);
};
void nf_register_queue_handler(const struct nf_queue_handler *qh);
diff --git a/include/net/netmem.h b/include/net/netmem.h
index bccacd21b6c3..fb693bc1702a 100644
--- a/include/net/netmem.h
+++ b/include/net/netmem.h
@@ -70,16 +70,18 @@ enum net_iov_type {
NET_IOV_IOURING,
};
-/* A memory descriptor representing abstract networking I/O vectors,
- * generally for non-pages memory that doesn't have its corresponding
- * struct page and needs to be explicitly allocated through slab.
+/* A memory descriptor representing abstract networking I/O vectors.
*
* net_iovs are allocated and used by networking code, and the size of
* the chunk is PAGE_SIZE.
*
- * This memory can be any form of non-struct paged memory. Examples
- * include imported dmabuf memory and imported io_uring memory. See
- * net_iov_type for all the supported types.
+ * Examples include imported dmabuf memory and imported io_uring memory. See
+ * net_iov_type for all the supported types. While current net_iov types are
+ * unreadable by the CPU, net_iov has no inherent restrictions and may be
+ * CPU-readable or unreadable. New code must not assume net_iov implies
+ * unreadable memory (check readability via netmem_address() or
+ * skb_frags_readable() instead) and should, as much as possible, generalize
+ * existing limitations to match the design principles.
*
* @pp_magic: pp field, similar to the one in struct page/struct
* netmem_desc.
@@ -102,9 +104,6 @@ struct net_iov_area {
/* Array of net_iovs for this area. */
struct net_iov *niovs;
size_t num_niovs;
-
- /* Offset into the dma-buf where this chunk starts. */
- unsigned long base_virtual;
};
static inline struct net_iov_area *net_iov_owner(const struct net_iov *niov)
@@ -134,8 +133,17 @@ static inline void net_iov_init(struct net_iov *niov,
* network memory.
*
* A netmem_ref can be a struct page* or a struct net_iov* underneath.
+ * Memory providers (or the default page_pool allocator) allocate struct
+ * net_iov or struct page, cast them to netmem_ref, and hand them to
+ * page_pool.
*
- * Use the supplied helpers to obtain the underlying memory pointer and fields.
+ * The page_pool, drivers, and core networking stack should operate on
+ * netmem_ref rather than struct page or struct net_iov. Downcasting
+ * netmem_ref via netmem_to_page() or netmem_to_net_iov() in callers is
+ * not allowed unless a code path strictly requires a specific backing
+ * type (e.g., kmap_local_page()). In such cases, add a netmem helper here
+ * that handles both page and net_iov cases and returns an error if the
+ * underlying type cannot support the operation.
*/
typedef unsigned long __bitwise netmem_ref;
@@ -300,9 +308,8 @@ static inline atomic_long_t *netmem_get_pp_ref_count_ref(netmem_ref netmem)
static inline bool netmem_is_pref_nid(netmem_ref netmem, int pref_nid)
{
- /* NUMA node preference only makes sense if we're allocating
- * system memory. Memory providers (which give us net_iovs)
- * choose for us.
+ /* NUMA node preference only applies to struct page; net_iovs are
+ * managed by their memory provider.
*/
if (netmem_is_net_iov(netmem))
return true;
@@ -358,6 +365,33 @@ static inline bool netmem_is_pfmemalloc(netmem_ref netmem)
return page_is_pfmemalloc(netmem_to_page(netmem));
}
+#define NETMEM_32BIT_ARCH_WITH_64BIT_DMA \
+ (sizeof(dma_addr_t) > sizeof(unsigned long))
+
+static inline unsigned long netmem_dma_addr_encode(dma_addr_t addr)
+{
+ if (NETMEM_32BIT_ARCH_WITH_64BIT_DMA)
+ addr >>= PAGE_SHIFT;
+
+ return addr;
+}
+
+static inline dma_addr_t netmem_dma_addr_decode(unsigned long addr)
+{
+ if (NETMEM_32BIT_ARCH_WITH_64BIT_DMA)
+ return (dma_addr_t)addr << PAGE_SHIFT;
+
+ return addr;
+}
+
+static inline bool netmem_dma_addr_fits(dma_addr_t addr)
+{
+ /* We assume page alignment to shave off bottom bits,
+ * if this "compression" doesn't work we need to drop.
+ */
+ return addr == netmem_dma_addr_decode(netmem_dma_addr_encode(addr));
+}
+
static inline unsigned long netmem_get_dma_addr(netmem_ref netmem)
{
return netmem_to_nmdesc(netmem)->dma_addr;
@@ -375,21 +409,37 @@ static inline bool net_is_devmem_iov(const struct net_iov *niov)
}
#endif
-void __get_netmem(netmem_ref netmem);
-void __put_netmem(netmem_ref netmem);
+void net_iov_inc_ref(struct net_iov *niov);
+void net_iov_dec_ref(struct net_iov *niov);
-static __always_inline void get_netmem(netmem_ref netmem)
+/**
+ * netmem_inc_ref - acquire a non-page_pool reference on a netmem
+ * @netmem: netmem to reference
+ *
+ * Acquires a non-pp backing reference (page._refcount via get_page() or
+ * binding->ref via net_iov_inc_ref()) regardless of page_pool membership.
+ * Counterpart to netmem_dec_ref().
+ */
+static __always_inline void netmem_inc_ref(netmem_ref netmem)
{
if (netmem_is_net_iov(netmem))
- __get_netmem(netmem);
+ net_iov_inc_ref(netmem_to_net_iov(netmem));
else
get_page(netmem_to_page(netmem));
}
-static __always_inline void put_netmem(netmem_ref netmem)
+/**
+ * netmem_dec_ref - release a non-page_pool reference on a netmem
+ * @netmem: netmem to unreference
+ *
+ * Drops a non-pp backing reference (page._refcount via put_page() or
+ * binding->ref via net_iov_dec_ref()) regardless of page_pool membership.
+ * Counterpart to netmem_inc_ref().
+ */
+static __always_inline void netmem_dec_ref(netmem_ref netmem)
{
if (netmem_is_net_iov(netmem))
- __put_netmem(netmem);
+ net_iov_dec_ref(netmem_to_net_iov(netmem));
else
put_page(netmem_to_page(netmem));
}
diff --git a/include/net/netns/netfilter.h b/include/net/netns/netfilter.h
index a6a0bf4a247e..7fd78394d1e7 100644
--- a/include/net/netns/netfilter.h
+++ b/include/net/netns/netfilter.h
@@ -33,5 +33,7 @@ struct netns_nf {
#if IS_ENABLED(CONFIG_NF_DEFRAG_IPV6)
unsigned int defrag_ipv6_users;
#endif
+ unsigned int hook_base_seq;
+ unsigned int nat_hook_base_seq;
};
#endif
diff --git a/include/net/nfc/hci.h b/include/net/nfc/hci.h
index 756c11084f65..86ed63e5d533 100644
--- a/include/net/nfc/hci.h
+++ b/include/net/nfc/hci.h
@@ -144,7 +144,7 @@ struct nfc_hci_dev {
data_exchange_cb_t async_cb;
void *async_cb_context;
- u8 *gb;
+ u8 gb[NFC_MAX_GT_LEN];
size_t gb_len;
unsigned long quirks;
diff --git a/include/net/nfc/nfc.h b/include/net/nfc/nfc.h
index c54df042db6b..bcafab5c53e5 100644
--- a/include/net/nfc/nfc.h
+++ b/include/net/nfc/nfc.h
@@ -273,7 +273,8 @@ struct sk_buff *nfc_alloc_recv_skb(unsigned int size, gfp_t gfp);
int nfc_set_remote_general_bytes(struct nfc_dev *dev,
const u8 *gt, u8 gt_len);
-u8 *nfc_get_local_general_bytes(struct nfc_dev *dev, size_t *gb_len);
+u8 *nfc_get_local_general_bytes(struct nfc_dev *dev, u8 *out_gb,
+ size_t gb_max_len, size_t *gb_len);
int nfc_fw_download_done(struct nfc_dev *dev, const char *firmware_name,
u32 result);
diff --git a/include/net/page_pool/helpers.h b/include/net/page_pool/helpers.h
index e2730dd273b2..28635ce9454e 100644
--- a/include/net/page_pool/helpers.h
+++ b/include/net/page_pool/helpers.h
@@ -8,12 +8,20 @@
/**
* DOC: page_pool allocator
*
- * The page_pool allocator is optimized for recycling page or page fragment used
- * by skb packet and xdp frame.
+ * The page_pool allocator is optimized for recycling network memory
+ * (netmem_ref) or fragments used by skb packets and xdp frames.
*
- * Basic use involves replacing any alloc_pages() calls with page_pool_alloc(),
- * which allocate memory with or without page splitting depending on the
- * requested memory size.
+ * page_pool natively operates on netmem_ref, which abstracts the underlying
+ * memory type (struct page or struct net_iov) supplied by the page allocator
+ * or a memory provider. Drivers and core networking code should use the
+ * netmem-based APIs (e.g. page_pool_alloc_netmem(), page_pool_put_netmem()).
+ * The struct page-based APIs (e.g. page_pool_alloc(), page_pool_alloc_pages(),
+ * page_pool_put_page()) are legacy compatibility wrappers for drivers not yet
+ * converted to netmem.
+ *
+ * Basic use involves replacing any alloc_pages() calls with
+ * page_pool_alloc_netmem() (or legacy page_pool_alloc()), which allocate memory
+ * with or without splitting depending on the requested memory size.
*
* If the driver knows that it always requires full pages or its allocations are
* always smaller than half a page, it can use one of the more specific API
@@ -408,16 +416,13 @@ static inline void page_pool_recycle_direct_netmem(struct page_pool *pool,
page_pool_put_full_netmem(pool, netmem, true);
}
-#define PAGE_POOL_32BIT_ARCH_WITH_64BIT_DMA \
- (sizeof(dma_addr_t) > sizeof(unsigned long))
-
/**
* page_pool_free_va() - free a va into the page_pool
* @pool: pool from which va was allocated
* @va: va to be freed
* @allow_direct: freed by the consumer, allow lockless caching
*
- * Free a va allocated from page_pool_allo_va().
+ * Free a va allocated from page_pool_alloc_va().
*/
static inline void page_pool_free_va(struct page_pool *pool, void *va,
bool allow_direct)
@@ -427,12 +432,7 @@ static inline void page_pool_free_va(struct page_pool *pool, void *va,
static inline dma_addr_t page_pool_get_dma_addr_netmem(netmem_ref netmem)
{
- dma_addr_t ret = netmem_get_dma_addr(netmem);
-
- if (PAGE_POOL_32BIT_ARCH_WITH_64BIT_DMA)
- ret <<= PAGE_SHIFT;
-
- return ret;
+ return netmem_dma_addr_decode(netmem_get_dma_addr(netmem));
}
/**
diff --git a/include/net/page_pool/memory_provider.h b/include/net/page_pool/memory_provider.h
index 255ce4cfd975..137cfc50833a 100644
--- a/include/net/page_pool/memory_provider.h
+++ b/include/net/page_pool/memory_provider.h
@@ -9,6 +9,16 @@ struct netdev_rx_queue;
struct netlink_ext_ack;
struct sk_buff;
+/* Memory providers allocate underlying memory (struct net_iov or struct page),
+ * cast it to netmem_ref, and supply it to page_pool. While current memory
+ * providers only return struct net_iov, they are not architecturally limited to
+ * net_iov; a provider returning page-backed netmems is allowed. New code must
+ * not assume a memory provider implies net_iov and should, as much as possible,
+ * generalize existing limitations to match the design principles.
+ *
+ * Per-provider custom logic must be delegated to memory_provider_ops rather
+ * than handled directly in page_pool core code.
+ */
struct memory_provider_ops {
netmem_ref (*alloc_netmems)(struct page_pool *pool, gfp_t gfp);
bool (*release_netmem)(struct page_pool *pool, netmem_ref netmem);
diff --git a/include/net/page_pool/types.h b/include/net/page_pool/types.h
index 03da138722f5..6d543076a0c0 100644
--- a/include/net/page_pool/types.h
+++ b/include/net/page_pool/types.h
@@ -22,9 +22,9 @@
*/
#define PP_FLAG_SYSTEM_POOL BIT(2) /* Global system page_pool */
-/* Allow unreadable (net_iov backed) netmem in this page_pool. Drivers setting
- * this must be able to support unreadable netmem, where netmem_address() would
- * return NULL. This flag should not be set for header page_pools.
+/* Allow unreadable netmem in this page_pool. Drivers setting this must be able
+ * to support unreadable netmem, where netmem_address() returns NULL. This flag
+ * should not be set for header page_pools.
*
* If the driver sets PP_FLAG_ALLOW_UNREADABLE_NETMEM, it should also set
* page_pool_params.slow.queue_idx.
diff --git a/include/net/phy/realtek_phy.h b/include/net/phy/realtek_phy.h
deleted file mode 100644
index d683bc1b0659..000000000000
--- a/include/net/phy/realtek_phy.h
+++ /dev/null
@@ -1,7 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-#ifndef _REALTEK_PHY_H
-#define _REALTEK_PHY_H
-
-#define PHY_ID_RTL_DUMMY_SFP 0x001ccbff
-
-#endif /* _REALTEK_PHY_H */
diff --git a/include/net/pkt_cls.h b/include/net/pkt_cls.h
index 5f5cb36439fe..9382405b2bab 100644
--- a/include/net/pkt_cls.h
+++ b/include/net/pkt_cls.h
@@ -316,10 +316,8 @@ tcf_exts_hw_stats_update(const struct tcf_exts *exts,
continue;
}
- preempt_disable();
tcf_action_stats_update(a, stats->bytes, stats->pkts, stats->drops,
stats->lastused, true);
- preempt_enable();
a->used_hw_stats = stats->used_hw_stats;
a->used_hw_stats_valid = stats->used_hw_stats_valid;
diff --git a/include/net/psp/functions.h b/include/net/psp/functions.h
index c5c23a54774e..b23c30898389 100644
--- a/include/net/psp/functions.h
+++ b/include/net/psp/functions.h
@@ -24,11 +24,6 @@ int psp_dev_rcv(struct sk_buff *skb, u16 dev_id, u8 generation, bool strip_icv);
/* Kernel-facing API */
void psp_assoc_put(struct psp_assoc *pas);
-static inline void *psp_assoc_drv_data(struct psp_assoc *pas)
-{
- return pas->drv_data;
-}
-
#if IS_ENABLED(CONFIG_INET_PSP)
unsigned int psp_key_size(u32 version);
void psp_sk_assoc_free(struct sock *sk);
diff --git a/include/net/psp/types.h b/include/net/psp/types.h
index 87991a1ea02d..b8905efbd604 100644
--- a/include/net/psp/types.h
+++ b/include/net/psp/types.h
@@ -219,12 +219,16 @@ struct psp_dev_ops {
* @tx_key_add: add a Tx key to the device
* Install an association in the device. Core will allocate space
* for the driver to use at drv_data.
+ * Can be left NULL if device does not store Tx keys and @tx_key_del
+ * is also NULL.
*/
int (*tx_key_add)(struct psp_dev *psd, struct psp_assoc *pas,
struct netlink_ext_ack *extack);
/**
* @tx_key_del: remove a Tx key from the device
* Remove an association from the device.
+ * Can be left NULL if device does not store Tx keys and @tx_key_add
+ * is also NULL.
*/
void (*tx_key_del)(struct psp_dev *psd, struct psp_assoc *pas);
diff --git a/include/net/route.h b/include/net/route.h
index 45290177a33c..3fccd31eb74d 100644
--- a/include/net/route.h
+++ b/include/net/route.h
@@ -129,7 +129,13 @@ struct in_device;
int ip_rt_init(void);
void rt_cache_flush(struct net *net);
+#ifdef CONFIG_INET
void rt_flush_dev(struct net_device *dev);
+#else
+static inline void rt_flush_dev(struct net_device *dev)
+{
+}
+#endif
static inline void inet_sk_init_flowi4(const struct inet_sock *inet,
struct flowi4 *fl4)
@@ -405,8 +411,11 @@ static inline struct neighbour *ip_neigh_gw4(struct net_device *dev,
struct neighbour *neigh;
neigh = __ipv4_neigh_lookup_noref(dev, (__force u32)daddr);
- if (unlikely(!neigh))
- neigh = __neigh_create(&arp_tbl, &daddr, dev, false);
+ if (unlikely(!neigh)) {
+ struct neigh_table *tbl = arp_table(dev_net(dev));
+
+ neigh = __neigh_create(tbl, &daddr, dev, false);
+ }
return neigh;
}
diff --git a/include/net/sch_generic.h b/include/net/sch_generic.h
index cbc248776511..1acaadb3e2cf 100644
--- a/include/net/sch_generic.h
+++ b/include/net/sch_generic.h
@@ -793,7 +793,7 @@ void qdisc_offload_query_caps(struct net_device *dev,
struct Qdisc *qdisc_alloc(struct netdev_queue *dev_queue,
const struct Qdisc_ops *ops,
struct netlink_ext_ack *extack);
-void qdisc_free(struct Qdisc *qdisc);
+void qdisc_free_rcu(struct Qdisc *qdisc);
struct Qdisc *qdisc_create_dflt(struct netdev_queue *dev_queue,
const struct Qdisc_ops *ops, u32 parentid,
struct netlink_ext_ack *extack);
@@ -810,6 +810,15 @@ static inline bool skb_at_tc_ingress(const struct sk_buff *skb)
#endif
}
+static inline bool skb_at_tc_egress(const struct sk_buff *skb)
+{
+#ifdef CONFIG_NET_EGRESS
+ return skb->nf_skip_egress && !skb_at_tc_ingress(skb);
+#else
+ return false;
+#endif
+}
+
static inline bool skb_skip_tc_classify(struct sk_buff *skb)
{
#ifdef CONFIG_NET_CLS_ACT
diff --git a/include/net/scm.h b/include/net/scm.h
index 86ae6bc109ec..b68a143f42de 100644
--- a/include/net/scm.h
+++ b/include/net/scm.h
@@ -42,7 +42,7 @@ struct scm_fp_list {
};
struct scm_cookie {
- struct pid *pid; /* Skb credentials */
+ DECLARE_PIDS(pid, PIDTYPE_TGID); /* Skb credentials by pid type */
struct scm_fp_list *fp; /* Passed files */
struct scm_creds creds; /* Skb credentials */
#ifdef CONFIG_SECURITY_NETWORK
@@ -69,7 +69,6 @@ static __inline__ void unix_get_peersec_dgram(struct socket *sock, struct scm_co
static __inline__ void scm_set_cred(struct scm_cookie *scm,
struct pid *pid, kuid_t uid, kgid_t gid)
{
- scm->pid = get_pid(pid);
scm->creds.pid = pid_vnr(pid);
scm->creds.uid = uid;
scm->creds.gid = gid;
@@ -77,8 +76,7 @@ static __inline__ void scm_set_cred(struct scm_cookie *scm,
static __inline__ void scm_destroy_cred(struct scm_cookie *scm)
{
- put_pid(scm->pid);
- scm->pid = NULL;
+ put_pids(scm->pid);
}
static __inline__ void scm_destroy(struct scm_cookie *scm)
@@ -94,8 +92,10 @@ static __inline__ int scm_send(struct socket *sock, struct msghdr *msg,
memset(scm, 0, sizeof(*scm));
scm->creds.uid = INVALID_UID;
scm->creds.gid = INVALID_GID;
- if (forcecreds)
+ if (forcecreds) {
+ scm->pid[PIDTYPE_TGID] = get_pid(task_tgid(current));
scm_set_cred(scm, task_tgid(current), current_uid(), current_gid());
+ }
unix_get_peersec_dgram(sock, scm);
if (msg->msg_controllen <= 0)
return 0;
diff --git a/include/net/sctp/sm.h b/include/net/sctp/sm.h
index 3bfd261a53cc..76605d1ee839 100644
--- a/include/net/sctp/sm.h
+++ b/include/net/sctp/sm.h
@@ -252,6 +252,7 @@ struct sctp_chunk *sctp_make_fwdtsn(const struct sctp_association *asoc,
struct sctp_fwdtsn_skip *skiplist);
struct sctp_chunk *sctp_make_auth(const struct sctp_association *asoc,
__u16 key_id);
+void sctp_control_set_owner_w(struct sctp_chunk *chunk);
struct sctp_chunk *sctp_make_strreset_req(const struct sctp_association *asoc,
__u16 stream_num, __be16 *stream_list,
bool out, bool in);
diff --git a/include/net/seg6_hmac.h b/include/net/seg6_hmac.h
index e9f41725933e..3161a8104b89 100644
--- a/include/net/seg6_hmac.h
+++ b/include/net/seg6_hmac.h
@@ -48,7 +48,8 @@ extern int seg6_hmac_info_add(struct net *net, u32 key,
extern int seg6_hmac_info_del(struct net *net, u32 key);
extern int seg6_push_hmac(struct net *net, struct in6_addr *saddr,
struct ipv6_sr_hdr *srh);
-extern bool seg6_hmac_validate_skb(struct sk_buff *skb);
+extern bool seg6_hmac_validate_skb(struct sk_buff *skb,
+ struct ipv6_sr_hdr *srh);
#ifdef CONFIG_IPV6_SEG6_HMAC
extern int seg6_hmac_net_init(struct net *net);
extern void seg6_hmac_net_exit(struct net *net);
diff --git a/include/net/sock.h b/include/net/sock.h
index 51185222aac2..173b37b2b8bb 100644
--- a/include/net/sock.h
+++ b/include/net/sock.h
@@ -301,7 +301,7 @@ struct sk_filter;
* @sk_type: socket type (%SOCK_STREAM, etc)
* @sk_protocol: which protocol this socket belongs in this network family
* @sk_peer_lock: lock protecting @sk_peer_pid and @sk_peer_cred
- * @sk_peer_pid: &struct pid for this socket's peer
+ * @sk_peer_pid: &struct pid for this socket's peer, by pid type
* @sk_peer_cred: %SO_PEERCRED setting
* @sk_rcvlowat: %SO_RCVLOWAT setting
* @sk_rcvtimeo: %SO_RCVTIMEO setting
@@ -356,6 +356,7 @@ struct sk_filter;
* @sk_scm_security: flagged by SO_PASSSEC to recv SCM_SECURITY
* @sk_scm_pidfd: flagged by SO_PASSPIDFD to recv SCM_PIDFD
* @sk_scm_rights: flagged by SO_PASSRIGHTS to recv SCM_RIGHTS
+ * @sk_scm_pidfd_thread: flagged by SO_PASSPIDFD_THREAD to recv a thread SCM_PIDFD
* @sk_scm_unused: unused flags for scm_recv()
* @ns_tracker: tracker for netns reference
* @sk_user_frags: xarray of pages the user is holding a reference on.
@@ -545,7 +546,7 @@ struct sock {
u64 sk_ino;
spinlock_t sk_peer_lock;
int sk_bind_phc;
- struct pid *sk_peer_pid;
+ DECLARE_PIDS(sk_peer_pid, PIDTYPE_TGID);
const struct cred *sk_peer_cred;
ktime_t sk_stamp;
@@ -562,7 +563,8 @@ struct sock {
sk_scm_security : 1,
sk_scm_pidfd : 1,
sk_scm_rights : 1,
- sk_scm_unused : 4;
+ sk_scm_pidfd_thread : 1,
+ sk_scm_unused : 3;
};
};
u8 sk_clockid;
@@ -1129,6 +1131,8 @@ static inline void sk_forward_alloc_add(struct sock *sk, int val)
}
void sk_stream_write_space(struct sock *sk);
+void sk_set_nospace(struct sock *sk);
+void sk_clear_nospace(struct sock *sk);
/* OOB backlog add */
static inline void __sk_add_backlog(struct sock *sk, struct sk_buff *skb)
@@ -2312,6 +2316,8 @@ static inline void sk_gso_disable(struct sock *sk)
sk->sk_route_caps &= ~NETIF_F_GSO_MASK;
}
+bool sk_has_decrypt_user(const struct sock *sk);
+
static inline int skb_do_copy_data_nocache(struct sock *sk, struct sk_buff *skb,
struct iov_iter *from, char *to,
int copy, int offset)
diff --git a/include/net/strparser.h b/include/net/strparser.h
index 0ed73e364faa..c2938eda3e79 100644
--- a/include/net/strparser.h
+++ b/include/net/strparser.h
@@ -32,7 +32,6 @@ struct strp_aggr_stats {
unsigned int msg_too_big;
unsigned int msg_timeouts;
unsigned int bad_hdr_len;
- unsigned int aborts;
unsigned int interrupted;
unsigned int unrecov_intr;
};
@@ -46,9 +45,6 @@ struct strp_callbacks {
int (*read_sock)(struct strparser *strp, read_descriptor_t *desc,
sk_read_actor_t recv_actor);
int (*read_sock_done)(struct strparser *strp, int err);
- void (*abort_parser)(struct strparser *strp, int err);
- void (*lock)(struct strparser *strp);
- void (*unlock)(struct strparser *strp);
};
struct strp_msg {
@@ -91,11 +87,10 @@ static inline struct strp_msg *strp_msg(struct sk_buff *skb)
struct strparser {
struct sock *sk;
- u32 stopped : 1;
- u32 paused : 1;
- u32 aborted : 1;
- u32 interrupted : 1;
- u32 unrecov_intr : 1;
+ u8 stopped;
+ u8 paused;
+ u8 interrupted;
+ u8 unrecov_intr;
struct sk_buff **skb_nextp;
struct sk_buff *skb_head;
@@ -131,8 +126,6 @@ static inline void save_strp_stats(struct strparser *strp,
SAVE_PSOCK_STATS(bad_hdr_len);
#undef SAVE_PSOCK_STATS
- if (strp->aborted)
- agg_stats->aborts++;
if (strp->interrupted)
agg_stats->interrupted++;
if (strp->unrecov_intr)
@@ -150,7 +143,6 @@ static inline void aggregate_strp_stats(struct strp_aggr_stats *stats,
SAVE_PSOCK_STATS(msg_too_big);
SAVE_PSOCK_STATS(msg_timeouts);
SAVE_PSOCK_STATS(bad_hdr_len);
- SAVE_PSOCK_STATS(aborts);
SAVE_PSOCK_STATS(interrupted);
SAVE_PSOCK_STATS(unrecov_intr);
#undef SAVE_PSOCK_STATS
@@ -163,8 +155,5 @@ void strp_check_rcv(struct strparser *strp);
int strp_init(struct strparser *strp, struct sock *sk,
const struct strp_callbacks *cb);
void strp_data_ready(struct strparser *strp);
-int strp_process(struct strparser *strp, struct sk_buff *orig_skb,
- unsigned int orig_offset, size_t orig_len,
- size_t max_msg_size, long timeo);
#endif /* __NET_STRPARSER_H_ */
diff --git a/include/net/tcp.h b/include/net/tcp.h
index 436495ff2271..3560adddf821 100644
--- a/include/net/tcp.h
+++ b/include/net/tcp.h
@@ -512,6 +512,7 @@ void tcp_set_keepalive(struct sock *sk, int val);
void tcp_syn_ack_timeout(const struct request_sock *req);
int tcp_recvmsg(struct sock *sk, struct msghdr *msg, size_t len,
int flags);
+int __tcp_set_rcvlowat(struct sock *sk, int val, bool wakeup);
int tcp_set_rcvlowat(struct sock *sk, int val);
void tcp_set_rcvbuf(struct sock *sk, int val);
int tcp_set_window_clamp(struct sock *sk, int val);
@@ -783,14 +784,42 @@ void tcp_done_with_error(struct sock *sk, int err);
void tcp_reset(struct sock *sk, struct sk_buff *skb);
void tcp_fin(struct sock *sk);
void __tcp_check_space(struct sock *sk);
+
+/* Mirror of SOCK_NOSPACE in tcp_sock, maintained by sk_set_nospace()
+ * and sk_clear_nospace().
+ *
+ * MPTCP subflows share the parent socket, and thus its SOCK_NOSPACE bit.
+ * Keep their mirror always set (see subflow_ulp_init()) so that they
+ * always reach __tcp_check_space() and behave as before.
+ */
+static inline void tcp_set_nospace(struct sock *sk)
+{
+ if (sk_is_tcp(sk)) {
+ /* pairs with smp_mb__before_atomic() in tcp_clear_nospace() */
+ smp_mb__after_atomic();
+ /* pairs with smp_mb() in tcp_check_space() */
+ smp_store_mb(tcp_sk(sk)->tcp_nospace, 1);
+ }
+}
+
+static inline void tcp_clear_nospace(struct sock *sk)
+{
+ if (sk_is_tcp(sk) && !sk_is_mptcp(sk)) {
+ WRITE_ONCE(tcp_sk(sk)->tcp_nospace, 0);
+ /* pairs with smp_mb__after_atomic() in tcp_set_nospace() */
+ smp_mb__before_atomic();
+ }
+}
+
static inline void tcp_check_space(struct sock *sk)
{
/* pairs with tcp_poll() */
smp_mb();
- if (sk->sk_socket && test_bit(SOCK_NOSPACE, &sk->sk_socket->flags))
+ if (unlikely(READ_ONCE(tcp_sk(sk)->tcp_nospace)))
__tcp_check_space(sk);
}
+
void tcp_sack_compress_send_ack(struct sock *sk);
static inline void tcp_cleanup_skb(struct sk_buff *skb)
@@ -823,6 +852,9 @@ unsigned int tcp_sync_mss(struct sock *sk, u32 pmtu);
unsigned int tcp_current_mss(struct sock *sk);
u32 tcp_clamp_probe0_to_user_timeout(const struct sock *sk, u32 when);
+u32 tcp_tso_autosize(const struct sock *sk, unsigned int mss_now,
+ int min_tso_segs);
+
/* Bound MSS / TSO packet size with the half of the window */
static inline int tcp_bound_to_half_wnd(struct tcp_sock *tp, int pktsize)
{
@@ -1232,9 +1264,9 @@ static inline bool tcp_skb_can_collapse_to(const struct sk_buff *skb)
static inline bool tcp_skb_can_collapse(const struct sk_buff *to,
const struct sk_buff *from)
{
- /* skb_cmp_decrypted() not needed, use tcp_write_collapse_fence() */
return likely(tcp_skb_can_collapse_to(to) &&
mptcp_skb_can_collapse(to, from) &&
+ !skb_cmp_decrypted(to, from) &&
skb_pure_zcopy_same(to, from) &&
skb_frags_readable(to) == skb_frags_readable(from));
}
@@ -1360,8 +1392,16 @@ struct tcp_congestion_ops {
/* hook for packet ack accounting (optional) */
void (*pkts_acked)(struct sock *sk, const struct ack_sample *sample);
- /* override sysctl_tcp_min_tso_segs (optional) */
- u32 (*min_tso_segs)(struct sock *sk);
+ /* Override tcp_tso_autosize() (optional)
+ *
+ * If provided, this callback supplies the TSO segment target count
+ * instead of using tcp_tso_autosize(). The returned value is
+ * subsequently clamped to [1, sk->sk_gso_max_segs] by the caller.
+ *
+ * For the kernel callback path, mss_now originates from
+ * tcp_current_mss() and should never be zero.
+ */
+ u32 (*tso_segs)(struct sock *sk, u32 mss_now);
/* new value of cwnd after loss (required) */
u32 (*undo_cwnd)(struct sock *sk);
@@ -2327,7 +2367,7 @@ static inline void tcp_rtx_queue_unlink_and_free(struct sk_buff *skb, struct soc
static inline void tcp_write_collapse_fence(struct sock *sk)
{
- struct sk_buff *skb = tcp_write_queue_tail(sk);
+ struct sk_buff *skb = tcp_write_queue_tail(sk) ?: tcp_rtx_queue_tail(sk);
if (skb)
TCP_SKB_CB(skb)->eor = 1;
@@ -2891,7 +2931,7 @@ static inline void bpf_skops_init_skb(struct bpf_sock_ops_kern *skops,
* program loaded).
*/
#ifdef CONFIG_BPF
-static inline int tcp_call_bpf(struct sock *sk, int op, u32 nargs, u32 *args)
+static inline int __tcp_call_bpf(struct sock *sk, int op, u32 nargs, u32 *args)
{
struct bpf_sock_ops_kern sock_ops;
int ret;
@@ -2908,7 +2948,7 @@ static inline int tcp_call_bpf(struct sock *sk, int op, u32 nargs, u32 *args)
if (nargs > 0)
memcpy(sock_ops.args, args, nargs * sizeof(*args));
- ret = BPF_CGROUP_RUN_PROG_SOCK_OPS(&sock_ops);
+ ret = __BPF_CGROUP_RUN_PROG_SOCK_OPS(&sock_ops);
if (ret == 0)
ret = sock_ops.reply;
else
@@ -2916,42 +2956,37 @@ static inline int tcp_call_bpf(struct sock *sk, int op, u32 nargs, u32 *args)
return ret;
}
-static inline int tcp_call_bpf_2arg(struct sock *sk, int op, u32 arg1, u32 arg2)
-{
- u32 args[2] = {arg1, arg2};
-
- return tcp_call_bpf(sk, op, 2, args);
-}
-
-static inline int tcp_call_bpf_3arg(struct sock *sk, int op, u32 arg1, u32 arg2,
- u32 arg3)
-{
- u32 args[3] = {arg1, arg2, arg3};
-
- return tcp_call_bpf(sk, op, 3, args);
-}
+#define tcp_call_bpf(sk, op) \
+({ \
+ int __ret = 0; \
+ if (cgroup_bpf_enabled(CGROUP_SOCK_OPS)) { \
+ __ret = __tcp_call_bpf(sk, op, 0, NULL); \
+ } \
+ __ret; \
+})
+
+#define tcp_call_bpf_flag(sk, op, ...) \
+do { \
+ if (cgroup_bpf_enabled(CGROUP_SOCK_OPS) && \
+ BPF_SOCK_OPS_TEST_FLAG(tcp_sk(sk), op ## _FLAG)) { \
+ u32 __args[] = { __VA_ARGS__ }; \
+ __tcp_call_bpf(sk, op, ARRAY_SIZE(__args), __args); \
+ } \
+} while (0)
static inline void tcp_clear_sock_ops_cb_flags(struct sock *sk)
{
tcp_sk(sk)->bpf_sock_ops_cb_flags = 0;
+ WRITE_ONCE(tcp_sk(sk)->bpf_tcp_ops_flags, 0);
}
#else
-static inline int tcp_call_bpf(struct sock *sk, int op, u32 nargs, u32 *args)
+static inline int tcp_call_bpf(struct sock *sk, int op)
{
return -EPERM;
}
-static inline int tcp_call_bpf_2arg(struct sock *sk, int op, u32 arg1, u32 arg2)
-{
- return -EPERM;
-}
-
-static inline int tcp_call_bpf_3arg(struct sock *sk, int op, u32 arg1, u32 arg2,
- u32 arg3)
-{
- return -EPERM;
-}
+#define tcp_call_bpf_flag(sk, op, ...) do { } while (0)
static inline void tcp_clear_sock_ops_cb_flags(struct sock *sk)
{
@@ -2959,12 +2994,196 @@ static inline void tcp_clear_sock_ops_cb_flags(struct sock *sk)
#endif
+#if defined(CONFIG_BPF_JIT) && defined(CONFIG_CGROUP_BPF)
+
+struct bpf_tcp_ops {
+ /* Should return the initial SYN (active open) or SYN-ACK (passive open)
+ * retransmission timeout. Return the timeout in jiffies, or <= 0 for
+ * the kernel default.
+ *
+ * @req: request_sock on the passive (synack) path; NULL otherwise.
+ */
+ int (*timeout_init)(struct sock *sk, struct request_sock *req);
+
+ /* Should return the initial advertised receive window, in packets,
+ * or < 0 for the kernel default. @req as in timeout_init().
+ */
+ int (*rwnd_init)(struct sock *sk, struct request_sock *req);
+
+ /* Called when an active connection becomes established.
+ * @skb is the SYNACK that completed the 3WHS, or NULL for a
+ * TCP_REPAIR socket (tcp_finish_connect() with no skb).
+ */
+ void (*active_established)(struct sock *sk, struct sk_buff *skb__nullable);
+
+ /* Called when a passive connection becomes established.
+ * @skb is the ACK that completed the 3WHS.
+ */
+ void (*passive_established)(struct sock *sk, struct sk_buff *skb);
+
+ /* Called when the retransmission timer fires. */
+ void (*rto)(struct sock *sk);
+
+ /* Called on every RTT sample if BPF_TCP_OPS_FLAG_RTT is enabled.
+ * @mrtt: the measured RTT, in microseconds.
+ * @srtt: the updated smoothed RTT.
+ */
+ void (*rtt)(struct sock *sk, long mrtt, u32 srtt);
+
+ /* Called when the connection changes TCP state.
+ * @state: the new state (one of the TCP_* states).
+ */
+ void (*set_state)(struct sock *sk, int state);
+
+ /* Called when an skb is retransmitted.
+ * @skb: the retransmitted skb.
+ * @err: tcp_transmit_skb() return value (0 on success).
+ */
+ void (*retrans)(struct sock *sk, struct sk_buff *skb, int err);
+
+ /* Called right before an active connection is initialized. */
+ void (*connect)(struct sock *sk);
+
+ /* Called on listen(2), right after the socket enters TCP_LISTEN. */
+ void (*listen)(struct sock *sk);
+
+ /*
+ * Parse the TCP header options of an incoming skb received on an
+ * established connection. Use bpf_dynptr_from_skb()/bpf_skb_load_bytes()
+ * to access the options.
+ *
+ * Called if BPF_TCP_OPS_FLAG_PARSE_HDR_OPT_ALL is enabled, or if
+ * BPF_TCP_OPS_FLAG_PARSE_HDR_OPT_UNKNOWN is enabled and an unknown
+ * option is received.
+ */
+ void (*parse_hdr)(struct sock *sk, struct sk_buff *skb);
+
+ /*
+ * Reserve space in the outgoing TCP header for options to be written
+ * later by write_hdr_opt(). Call bpf_reserve_hdr_opt() to reserve bytes.
+ *
+ * Called if BPF_TCP_OPS_FLAG_WRITE_HDR_OPT is enabled.
+ *
+ * @skb: outgoing packet. NULL when called from tcp_current_mss()
+ * (MSS sizing).
+ * @req: request_sock on the synack path; NULL otherwise.
+ * @syn_skb: incoming SYN on the synack path; NULL otherwise.
+ * @synack_type: TCP_SYNACK_COOKIE indicates a stateless syncookie.
+ * @remaining: pointer to the size of space still available; cast it
+ * using bpf_rdonly_cast() before dereferencing.
+ */
+ void (*hdr_opt_len)(struct sock *sk, struct sk_buff *skb,
+ struct request_sock *req, struct sk_buff *syn_skb,
+ enum tcp_synack_type synack_type,
+ unsigned int *remaining);
+
+ /*
+ * Write header options into the space reserved earlier by hdr_opt_len().
+ * Use bpf_store_hdr_opt() to write; it appends within the reserved window
+ * shared with legacy SOCKOPS.
+ *
+ * Called if BPF_TCP_OPS_FLAG_WRITE_HDR_OPT is enabled.
+ *
+ * @skb: outgoing packet.
+ * @req: request_sock on the synack path; NULL otherwise.
+ * @syn_skb: incoming SYN on the synack path; NULL otherwise.
+ * @synack_type: TCP_SYNACK_COOKIE indicates a stateless syncookie.
+ * @opt_off: offset in the outgoing @skb's TCP header where the
+ * bpf_tcp_ops portion of the reserved window begins, i.e. after
+ * the kernel and legacy options.
+ */
+ void (*write_hdr_opt)(struct sock *sk, struct sk_buff *skb,
+ struct request_sock *req, struct sk_buff *syn_skb,
+ enum tcp_synack_type synack_type,
+ u32 opt_off);
+
+ /*
+ * Called when an incoming skb is enqueued to sk->sk_receive_queue
+ * if BPF_TCP_OPS_FLAG_RCVQ is enabled.
+ */
+ void (*enqueue_rcvq)(struct sock *sk, struct sk_buff *skb);
+
+ /*
+ * Called after data is dequeued from sk->sk_receive_queue
+ * if BPF_TCP_OPS_FLAG_RCVQ is enabled.
+ */
+ void (*dequeue_rcvq)(struct sock *sk);
+};
+
+#define __bpf_tcp_ops_call(op, sk, ...) \
+do { \
+ const struct bpf_prog_array_item *item; \
+ const struct bpf_tcp_ops *tcp_ops; \
+ struct cgroup *cgrp; \
+ \
+ cgrp = sock_cgroup_ptr(&sk->sk_cgrp_data); \
+ rcu_read_lock_dont_migrate(); \
+ bpf_cgroup_struct_ops_foreach(tcp_ops, item, cgrp, \
+ CGROUP_TCP_SOCK_OPS) { \
+ if (tcp_ops->op) \
+ tcp_ops->op(sk, ##__VA_ARGS__); \
+ } \
+ rcu_read_unlock_migrate(); \
+} while (0)
+
+#define bpf_tcp_ops_call(op, sk, ...) \
+do { \
+ if (cgroup_bpf_enabled(CGROUP_TCP_SOCK_OPS)) \
+ __bpf_tcp_ops_call(op, sk, ##__VA_ARGS__); \
+} while (0)
+
+#define bpf_tcp_ops_call_flag(op, flag, sk, ...) \
+do { \
+ if (cgroup_bpf_enabled(CGROUP_TCP_SOCK_OPS) && \
+ BPF_TCP_OPS_TEST_FLAG(tcp_sk(sk), flag)) \
+ __bpf_tcp_ops_call(op, sk, ##__VA_ARGS__); \
+} while (0)
+
+#define bpf_tcp_ops_call_int(op, init_retval, sk, ...) \
+({ \
+ int __retval = (init_retval); \
+ if (cgroup_bpf_enabled(CGROUP_TCP_SOCK_OPS)) { \
+ const struct bpf_prog_array_item *item; \
+ const struct bpf_tcp_ops *tcp_ops; \
+ struct bpf_tramp_run_ctx run_ctx; \
+ struct bpf_run_ctx *old_run_ctx; \
+ struct sock *__sk = sk_to_full_sk(sk); \
+ struct request_sock *req = NULL; \
+ struct cgroup *cgrp; \
+ \
+ if (__sk) { \
+ run_ctx.retval = (init_retval); \
+ cgrp = sock_cgroup_ptr(&__sk->sk_cgrp_data); \
+ if (!sk_fullsock(sk)) \
+ req = (struct request_sock *)sk; \
+ rcu_read_lock_dont_migrate(); \
+ old_run_ctx = bpf_set_run_ctx(&run_ctx.run_ctx);\
+ bpf_cgroup_struct_ops_foreach(tcp_ops, item, cgrp, \
+ CGROUP_TCP_SOCK_OPS) { \
+ if (tcp_ops->op) \
+ run_ctx.retval = tcp_ops->op(__sk, req, ##__VA_ARGS__); \
+ } \
+ bpf_reset_run_ctx(old_run_ctx); \
+ rcu_read_unlock_migrate(); \
+ __retval = run_ctx.retval; \
+ } \
+ } \
+ __retval; \
+})
+
+#else
+#define __bpf_tcp_ops_call(op, sk, ...) do { } while (0)
+#define bpf_tcp_ops_call(op, sk, ...) do { } while (0)
+#define bpf_tcp_ops_call_flag(op, flag, sk, ...) do { } while (0)
+#define bpf_tcp_ops_call_int(op, init_retval, sk, ...) (init_retval)
+#endif
+
static inline u32 tcp_timeout_init(struct sock *sk)
{
int timeout;
- timeout = tcp_call_bpf(sk, BPF_SOCK_OPS_TIMEOUT_INIT, 0, NULL);
-
+ timeout = tcp_call_bpf(sk, BPF_SOCK_OPS_TIMEOUT_INIT);
+ timeout = bpf_tcp_ops_call_int(timeout_init, timeout, sk);
if (timeout <= 0)
timeout = TCP_TIMEOUT_INIT;
return min_t(int, timeout, TCP_RTO_MAX);
@@ -2974,8 +3193,8 @@ static inline u32 tcp_rwnd_init_bpf(struct sock *sk)
{
int rwnd;
- rwnd = tcp_call_bpf(sk, BPF_SOCK_OPS_RWND_INIT, 0, NULL);
-
+ rwnd = tcp_call_bpf(sk, BPF_SOCK_OPS_RWND_INIT);
+ rwnd = bpf_tcp_ops_call_int(rwnd_init, rwnd, sk);
if (rwnd < 0)
rwnd = 0;
return rwnd;
@@ -2983,13 +3202,13 @@ static inline u32 tcp_rwnd_init_bpf(struct sock *sk)
static inline bool tcp_bpf_ca_needs_ecn(struct sock *sk)
{
- return (tcp_call_bpf(sk, BPF_SOCK_OPS_NEEDS_ECN, 0, NULL) == 1);
+ return (tcp_call_bpf(sk, BPF_SOCK_OPS_NEEDS_ECN) == 1);
}
static inline void tcp_bpf_rtt(struct sock *sk, long mrtt, u32 srtt)
{
- if (BPF_SOCK_OPS_TEST_FLAG(tcp_sk(sk), BPF_SOCK_OPS_RTT_CB_FLAG))
- tcp_call_bpf_2arg(sk, BPF_SOCK_OPS_RTT_CB, mrtt, srtt);
+ tcp_call_bpf_flag(sk, BPF_SOCK_OPS_RTT_CB, mrtt, srtt);
+ bpf_tcp_ops_call_flag(rtt, RTT, sk, mrtt, srtt);
}
#if IS_ENABLED(CONFIG_SMC)
@@ -3082,7 +3301,7 @@ enum skb_drop_reason tcp_inbound_hash(struct sock *sk,
static inline int tcp_recv_should_stop(struct sock *sk)
{
- return sk->sk_err ||
+ return READ_ONCE(sk->sk_err) ||
sk->sk_state == TCP_CLOSE ||
(sk->sk_shutdown & RCV_SHUTDOWN) ||
signal_pending(current);
diff --git a/include/net/udp.h b/include/net/udp.h
index 1fee17274745..5bc25dcf25fb 100644
--- a/include/net/udp.h
+++ b/include/net/udp.h
@@ -613,7 +613,7 @@ static inline struct sk_buff *udp_rcv_segment(struct sock *sk,
/* the GSO CB lays after the UDP one, no need to save and restore any
* CB fragment
*/
- segs = __skb_gso_segment(skb, features, false);
+ segs = __skb_gso_segment(skb, features, false, 0);
if (IS_ERR_OR_NULL(segs)) {
drop_count = skb_shinfo(skb)->gso_segs;
goto drop;
diff --git a/include/net/vxlan.h b/include/net/vxlan.h
index 7b8207505523..c3c9f2ccc3d1 100644
--- a/include/net/vxlan.h
+++ b/include/net/vxlan.h
@@ -204,7 +204,6 @@ struct vxlan_rdst {
u8 offloaded:1;
__be32 remote_vni;
u32 remote_ifindex;
- struct net_device *remote_dev;
struct list_head list;
struct rcu_head rcu;
struct dst_cache dst_cache;
@@ -229,6 +228,7 @@ struct vxlan_config {
bool no_share;
enum ifla_vxlan_df df;
struct vxlanhdr reserved_bits;
+ struct rcu_head rcu;
};
enum {
@@ -294,14 +294,15 @@ struct vxlan_dev {
#endif
struct net_device *dev;
struct net *net; /* netns for packet i/o */
- struct vxlan_rdst default_dst; /* default destination */
+ struct net_device *lowerdev;
struct timer_list age_timer;
spinlock_t hash_lock;
unsigned int addrcnt;
struct gro_cells gro_cells;
+ unsigned long flags;
- struct vxlan_config cfg;
+ struct vxlan_config __rcu *cfg;
struct vxlan_vni_group __rcu *vnigrp;
@@ -313,6 +314,10 @@ struct vxlan_dev {
unsigned int mdb_seq;
};
+enum vxlan_dev_flags {
+ VXLAN_DEV_F_MDB,
+};
+
#define VXLAN_F_LEARN 0x01
#define VXLAN_F_PROXY 0x02
#define VXLAN_F_RSC 0x04
@@ -331,7 +336,6 @@ struct vxlan_dev {
#define VXLAN_F_IPV6_LINKLOCAL 0x8000
#define VXLAN_F_TTL_INHERIT 0x10000
#define VXLAN_F_VNIFILTER 0x20000
-#define VXLAN_F_MDB 0x40000
#define VXLAN_F_LOCALBYPASS 0x80000
#define VXLAN_F_MC_ROUTE 0x100000
diff --git a/include/net/xdp.h b/include/net/xdp.h
index aa742f413c35..07231adfb5f8 100644
--- a/include/net/xdp.h
+++ b/include/net/xdp.h
@@ -106,6 +106,11 @@ struct xdp_buff {
};
};
+static __always_inline void xdp_reinit_buff(struct xdp_buff *xdp)
+{
+ xdp->flags = 0;
+}
+
static __always_inline bool xdp_buff_has_frags(const struct xdp_buff *xdp)
{
return !!(xdp->flags & XDP_FLAGS_HAS_FRAGS);
diff --git a/include/net/xsk_buff_pool.h b/include/net/xsk_buff_pool.h
index a7df573784fd..02e89350faf9 100644
--- a/include/net/xsk_buff_pool.h
+++ b/include/net/xsk_buff_pool.h
@@ -48,6 +48,8 @@ struct xsk_buff_pool {
struct device *dev;
struct net_device *netdev;
struct list_head xsk_tx_list;
+ /* Assigned pools, including deferred releases; ops protected. */
+ struct hlist_node dev_node;
/* Protects modifications to the xsk_tx_list */
spinlock_t xsk_tx_list_lock;
refcount_t users;
@@ -119,6 +121,7 @@ bool xp_put_pool(struct xsk_buff_pool *pool);
void xp_clear_dev(struct xsk_buff_pool *pool);
void xp_add_xsk(struct xsk_buff_pool *pool, struct xdp_sock *xs);
void xp_del_xsk(struct xsk_buff_pool *pool, struct xdp_sock *xs);
+void xp_clear_dev_all(struct net_device *dev);
/* AF_XDP, and XDP core. */
void xp_free(struct xdp_buff_xsk *xskb);
diff --git a/include/rdma/ib_umem.h b/include/rdma/ib_umem.h
index 1fe87fd1d769..dcb645419692 100644
--- a/include/rdma/ib_umem.h
+++ b/include/rdma/ib_umem.h
@@ -7,6 +7,7 @@
#ifndef IB_UMEM_H
#define IB_UMEM_H
+#include <linux/dma-direction.h>
#include <linux/scatterlist.h>
struct ib_device;
@@ -19,6 +20,7 @@ struct ib_umem {
size_t length;
unsigned long address;
unsigned long dma_attrs;
+ enum dma_data_direction dma_dir;
u32 writable : 1;
u32 is_odp : 1;
u32 is_dmabuf : 1;
diff --git a/include/rdma/ib_verbs.h b/include/rdma/ib_verbs.h
index cb3b6163961b..d6eaa3fee66e 100644
--- a/include/rdma/ib_verbs.h
+++ b/include/rdma/ib_verbs.h
@@ -3532,7 +3532,7 @@ static inline bool rdma_cap_ib_cm(const struct ib_device *device, u32 port_num)
* @port_num: Port number to check
*
* Similar to above, but specific to iWARP connections which have a different
- * managment protocol than InfiniBand.
+ * management protocol than InfiniBand.
*
* Return: true if the port supports an iWARP CM (this does not guarantee that
* a CM is actually running however).
@@ -3577,7 +3577,7 @@ static inline bool rdma_cap_ib_sa(const struct ib_device *device, u32 port_num)
* to this group. And it should leave the group only after all queue pairs
* attached to the group have been detached.
*
- * Return: true if the port must undertake the additional adminstrative
+ * Return: true if the port must undertake the additional administrative
* overhead of registering/unregistering with the SM and tracking of the
* total number of queue pairs attached to the multicast group.
*/
diff --git a/include/rdma/uverbs_ioctl.h b/include/rdma/uverbs_ioctl.h
index 80f3ba6663d0..1aaaadb8daf6 100644
--- a/include/rdma/uverbs_ioctl.h
+++ b/include/rdma/uverbs_ioctl.h
@@ -1142,7 +1142,7 @@ static inline int ib_is_udata_in_empty(struct ib_udata *udata)
* @_udata: The system calls ib_udata struct
*
* Used when there is no driver response data to return. Provides forward
- * compatability by zeroing any buffer the user may have provided.
+ * compatibility by zeroing any buffer the user may have provided.
*/
static inline int ib_respond_empty_udata(struct ib_udata *udata)
{
diff --git a/include/rdma/uverbs_types.h b/include/rdma/uverbs_types.h
index 5a07f9a6dcd1..6f3622892c0c 100644
--- a/include/rdma/uverbs_types.h
+++ b/include/rdma/uverbs_types.h
@@ -180,8 +180,6 @@ struct ib_uverbs_file {
struct page *disassociate_page;
struct xarray idr;
-
- struct mutex disassociation_lock;
};
extern const struct uverbs_obj_type_class uverbs_idr_class;
diff --git a/include/scsi/scsi_cmnd.h b/include/scsi/scsi_cmnd.h
index 8ecfb94049db..2f2364c96457 100644
--- a/include/scsi/scsi_cmnd.h
+++ b/include/scsi/scsi_cmnd.h
@@ -391,8 +391,7 @@ static inline unsigned scsi_transfer_length(struct scsi_cmnd *scmd)
return xfer_len;
}
-extern void scsi_build_sense(struct scsi_cmnd *scmd, int desc,
- u8 key, u8 asc, u8 ascq);
+void scsi_set_sense(struct scsi_cmnd *scmd, int desc, u8 key, u16 code);
struct request *scsi_alloc_request(struct request_queue *q, blk_opf_t opf,
blk_mq_req_flags_t flags);
diff --git a/include/scsi/scsi_common.h b/include/scsi/scsi_common.h
index 00c8a16d3cd2..88a076c1a137 100644
--- a/include/scsi/scsi_common.h
+++ b/include/scsi/scsi_common.h
@@ -71,8 +71,7 @@ extern u64 scsilun_to_int(struct scsi_lun *);
struct scsi_sense_hdr { /* See SPC-3 section 4.5 */
u8 response_code; /* permit: 0x0, 0x70, 0x71, 0x72, 0x73 */
u8 sense_key;
- u8 asc;
- u8 ascq;
+ u16 sense_code;
u8 byte4;
u8 byte5;
u8 byte6;
@@ -87,10 +86,21 @@ static inline bool scsi_sense_valid(const struct scsi_sense_hdr *sshdr)
return (sshdr->response_code & 0x70) == 0x70;
}
+static inline u8 scsi_sense_asc(const struct scsi_sense_hdr *sshdr)
+{
+ return scsi_sense_code_asc(sshdr->sense_code);
+}
+
+static inline u8 scsi_sense_ascq(const struct scsi_sense_hdr *sshdr)
+{
+ return scsi_sense_code_ascq(sshdr->sense_code);
+}
+
extern bool scsi_normalize_sense(const u8 *sense_buffer, int sb_len,
struct scsi_sense_hdr *sshdr);
-extern void scsi_build_sense_buffer(int desc, u8 *buf, u8 key, u8 asc, u8 ascq);
+void scsi_set_sense_buffer(int desc, u8 *buf, u8 key, u16 code);
+
int scsi_set_sense_information(u8 *buf, int buf_len, u64 info);
int scsi_set_sense_field_pointer(u8 *buf, int buf_len, u16 fp, u8 bp, bool cd);
extern const u8 * scsi_sense_desc_find(const u8 * sense_buffer, int sb_len,
diff --git a/include/scsi/scsi_dbg.h b/include/scsi/scsi_dbg.h
index efcdc78530d5..f21a5e3caca9 100644
--- a/include/scsi/scsi_dbg.h
+++ b/include/scsi/scsi_dbg.h
@@ -20,8 +20,8 @@ extern void scsi_print_result(struct scsi_cmnd *, const char *, int);
#ifdef CONFIG_SCSI_CONSTANTS
extern bool scsi_opcode_sa_name(int, int, const char **, const char **);
extern const char *scsi_sense_key_string(unsigned char);
-extern const char *scsi_extd_sense_format(unsigned char, unsigned char,
- const char **);
+extern const char *scsi_extd_sense_format(const struct scsi_sense_hdr *sshdr,
+ const char **fmt);
extern const char *scsi_mlreturn_string(int);
extern const char *scsi_hostbyte_string(int);
#else
@@ -57,7 +57,7 @@ scsi_sense_key_string(unsigned char key)
}
static inline const char *
-scsi_extd_sense_format(unsigned char asc, unsigned char ascq, const char **fmt)
+scsi_extd_sense_format(const struct scsi_sense_hdr *sshdr, const char **fmt)
{
*fmt = NULL;
return NULL;
diff --git a/include/scsi/scsi_device.h b/include/scsi/scsi_device.h
index 8694eeadd753..e6fd6bc30644 100644
--- a/include/scsi/scsi_device.h
+++ b/include/scsi/scsi_device.h
@@ -514,20 +514,20 @@ extern void scsi_sanitize_inquiry_string(unsigned char *s, int len);
*/
#define SCMD_FAILURE_STAT_ANY 0xff
/*
- * The following can be set to the scsi_failure sense, asc and ascq fields to
- * match on any sense, ASC, or ASCQ value.
+ * The following can be set to the scsi_failure sense key, asc and ascq fields
+ * to match any sense key, ASC, and ASCQ value.
*/
-#define SCMD_FAILURE_SENSE_ANY 0xff
-#define SCMD_FAILURE_ASC_ANY 0xff
-#define SCMD_FAILURE_ASCQ_ANY 0xff
+#define SCMD_FAILURE_SENSE_KEY_ANY 0xff
+#define SCMD_FAILURE_SENSE_CODE_ANY 0xffff
+#define SCMD_FAILURE_ASC_ANY 0xff
+#define SCMD_FAILURE_ASCQ_ANY 0xff
/* Always retry a matching failure. */
#define SCMD_FAILURE_NO_LIMIT -1
struct scsi_failure {
int result;
- u8 sense;
- u8 asc;
- u8 ascq;
+ u8 sense_key;
+ u16 sense_code;
/*
* Number of times scsi_execute_cmd will retry the failure. It does
* not count for the total_allowed.
@@ -537,6 +537,16 @@ struct scsi_failure {
s8 retries;
};
+static inline u8 scsi_failure_asc(const struct scsi_failure *failure)
+{
+ return scsi_sense_code_asc(failure->sense_code);
+}
+
+static inline u8 scsi_failure_ascq(const struct scsi_failure *failure)
+{
+ return scsi_sense_code_ascq(failure->sense_code);
+}
+
struct scsi_failures {
/*
* If a scsi_failure does not have a retry limit setup this limit will
diff --git a/include/scsi/scsi_host.h b/include/scsi/scsi_host.h
index 16243ec376cd..daaf1247673f 100644
--- a/include/scsi/scsi_host.h
+++ b/include/scsi/scsi_host.h
@@ -534,9 +534,9 @@ struct scsi_host_template {
unsigned long irq_flags; \
enum scsi_qc_status rc; \
\
- spin_lock_irqsave(shost->host_lock, irq_flags); \
+ spin_lock_irqsave(&shost->host_lock, irq_flags); \
rc = func_name##_lck(cmd); \
- spin_unlock_irqrestore(shost->host_lock, irq_flags); \
+ spin_unlock_irqrestore(&shost->host_lock, irq_flags); \
return rc; \
}
@@ -570,8 +570,7 @@ struct Scsi_Host {
struct list_head starved_list;
- spinlock_t default_lock;
- spinlock_t *host_lock;
+ spinlock_t host_lock;
struct mutex scan_mutex;/* serialize scanning activity */
@@ -953,6 +952,6 @@ static inline unsigned char scsi_host_get_guard(struct Scsi_Host *shost)
}
int scsi_host_set_state(struct Scsi_Host *shost, enum scsi_host_state state)
- __must_hold(shost->host_lock);
+ __must_hold(&shost->host_lock);
#endif /* _SCSI_SCSI_HOST_H */
diff --git a/include/scsi/scsi_proto.h b/include/scsi/scsi_proto.h
index c6b4a4dc8d9c..9c7d31aa6bae 100644
--- a/include/scsi/scsi_proto.h
+++ b/include/scsi/scsi_proto.h
@@ -12,6 +12,7 @@
#include <linux/build_bug.h>
#include <linux/types.h>
+#include <scsi/scsi_sense.h>
/*
* SCSI opcodes
@@ -219,76 +220,6 @@ enum sam_status {
#define STATUS_MASK 0xfe
/*
- * SENSE KEYS
- */
-#define NO_SENSE 0x00
-#define RECOVERED_ERROR 0x01
-#define NOT_READY 0x02
-#define MEDIUM_ERROR 0x03
-#define HARDWARE_ERROR 0x04
-#define ILLEGAL_REQUEST 0x05
-#define UNIT_ATTENTION 0x06
-#define DATA_PROTECT 0x07
-#define BLANK_CHECK 0x08
-#define VENDOR_SPECIFIC 0x09
-#define COPY_ABORTED 0x0a
-#define ABORTED_COMMAND 0x0b
-#define VOLUME_OVERFLOW 0x0d
-#define MISCOMPARE 0x0e
-#define COMPLETED 0x0f
-
-/*
- * Additional Sense Codes (ASC).
- */
-#define NO_ADDITIONAL_SENSE 0x00
-#define OVERLAP_ATOMIC_COMMAND_ASC 0x00
-#define LOGICAL_UNIT_NOT_READY 0x04
-#define LOGICAL_UNIT_COMMUNICATION_FAILURE 0x8
-#define WRITE_ERROR_ASC 0x0c
-#define UNRECOVERED_READ_ERR 0x11
-#define PARAMETER_LIST_LENGTH_ERR 0x1a
-#define MISCOMPARE_VERIFY_ASC 0x1d
-#define INVALID_OPCODE 0x20
-#define LBA_OUT_OF_RANGE 0x21
-#define INVALID_FIELD_IN_CDB 0x24
-#define INVALID_FIELD_IN_PARAM_LIST 0x26
-#define WRITE_PROTECTED 0x27
-#define UA_READY_ASC 0x28
-#define UA_RESET_ASC 0x29
-#define UA_CHANGED_ASC 0x2a
-#define TOO_MANY_IN_PARTITION_ASC 0x3b
-#define TARGET_CHANGED_ASC 0x3f
-#define SAVING_PARAMS_UNSUP 0x39
-#define TRANSPORT_PROBLEM 0x4b
-#define INSUFF_RES_ASC 0x55
-#define LOW_POWER_COND_ON 0x5e
-#define THRESHOLD_EXCEEDED 0x5d
-
-/*
- * Additional Sense Code Qualifiers (ASCQ).
- */
-#define POWER_ON_RESET_ASCQ 0x00
-#define MODE_CHANGED_ASCQ 0x01 /* mode parameters changed */
-#define FILEMARK_DETECTED_ASCQ 0x01
-#define POWER_ON_OCCURRED_ASCQ 0x01
-#define MICROCODE_CHANGED_ASCQ 0x01 /* with TARGET_CHANGED_ASC */
-#define BUS_RESET_ASCQ 0x02 /* scsi bus reset occurred */
-#define EOP_EOM_DETECTED_ASCQ 0x02
-#define INSUFF_RES_ASCQ 0x03
-#define BEGINNING_OF_P_M_DETECTED_ASCQ 0x04
-#define UNALIGNED_WRITE_ASCQ 0x04
-#define EOD_DETECTED_ASCQ 0x05
-#define WRITE_BOUNDARY_ASCQ 0x05
-#define READ_INVDATA_ASCQ 0x06
-#define READ_BOUNDARY_ASCQ 0x07
-#define CAPACITY_CHANGED_ASCQ 0x09
-#define ATTEMPT_ACCESS_GAP 0x09
-#define LUNS_CHANGED_ASCQ 0x0e
-#define INSUFF_ZONE_ASCQ 0x0e
-#define MICROCODE_CHANGED_WO_RESET_ASCQ 0x16
-#define OVERLAP_ATOMIC_COMMAND_ASCQ 0x23
-
-/*
* DEVICE TYPES
* Please keep them in 0x%02x format for $MODALIAS to work
*/
diff --git a/include/scsi/scsi_sense.h b/include/scsi/scsi_sense.h
new file mode 100644
index 000000000000..6e010a72482e
--- /dev/null
+++ b/include/scsi/scsi_sense.h
@@ -0,0 +1,950 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Definitions of SCSI sense keys, additional sense codes and additional sense
+ * code qualifiers.
+ */
+#ifndef _SCSI_SENSE_H_
+#define _SCSI_SENSE_H_
+
+#include <linux/types.h>
+
+/*
+ * Sense keys.
+ * See: https://www.t10.org/lists/2sensekey.htm
+ */
+enum scsi_sense_key {
+ NO_SENSE = 0x00,
+ RECOVERED_ERROR = 0x01,
+ NOT_READY = 0x02,
+ MEDIUM_ERROR = 0x03,
+ HARDWARE_ERROR = 0x04,
+ ILLEGAL_REQUEST = 0x05,
+ UNIT_ATTENTION = 0x06,
+ DATA_PROTECT = 0x07,
+ BLANK_CHECK = 0x08,
+ VENDOR_SPECIFIC = 0x09,
+ COPY_ABORTED = 0x0a,
+ ABORTED_COMMAND = 0x0b,
+ VOLUME_OVERFLOW = 0x0d,
+ MISCOMPARE = 0x0e,
+ COMPLETED = 0x0f,
+};
+
+#define SCSI_ASC_DEF(name) ASC_##name
+#define SCSI_ASC(name, code) \
+ SCSI_ASC_DEF(name) = (code), \
+ name = ((code) << 8) | 0x00
+
+/*
+ * SCSI additional sense codes and sense codes qualifiers.
+ * See: https://www.t10.org/lists/asc-num.txt
+ * Additional sense codes and their qualifiers are combined as a single value
+ * equal to (ASC << 8) | ASCQ.
+ *
+ * The definitions are sorted in increasing sense code value order with a naming
+ * following as close as possible the exact naming used in T10. To avoid
+ * excessively long code lines when using these macros, some long ASC/ASCQ
+ * combination names are shortened (E.g. LOGICAL_UNIT_xxx -> LU_xxx).
+ * Very generic ASC names that potentially may clash with other macros elsewhere
+ * are prefixed with "SSC_" (e.g. WARNING and WRITE_ERROR).
+ */
+enum scsi_sense_code {
+ SCSI_ASC(NO_ADDITIONAL_SENSE_INFORMATION, 0x00),
+ FILEMARK_DETECTED = 0x0001,
+ END_OF_PARTITION_MEDIUM_DETECTED = 0x0002,
+ SETMARK_DETECTED = 0x0003,
+ BEGINNING_OF_PARTITION_MEDIUM_DETECTED = 0x0004,
+ END_OF_DATA_DETECTED = 0x0005,
+ IO_PROCESS_TERMINATED = 0x0006,
+ PROGRAMMABLE_EARLY_WARNING_DETECTED = 0x0007,
+ AUDIO_PLAY_OP_IN_PROGRESS = 0x0011,
+ AUDIO_PLAY_OP_PAUSED = 0x0012,
+ AUDIO_PLAY_OP_SUCCESSFULLY_COMPLETED = 0x0013,
+ AUDIO_PLAY_OP_STOPPED_DUE_TO_ERROR = 0x0014,
+ NO_CURRENT_AUDIO_STATUS_TO_RETURN = 0x0015,
+ OP_IN_PROGRESS = 0x0016,
+ CLEANING_REQUESTED = 0x0017,
+ ERASE_OP_IN_PROGRESS = 0x0018,
+ LOCATE_OP_IN_PROGRESS = 0x0019,
+ REWIND_OP_IN_PROGRESS = 0x001A,
+ SET_CAPACITY_OP_IN_PROGRESS = 0x001B,
+ VERIFY_OP_IN_PROGRESS = 0x001C,
+ ATA_PASS_THROUGH_INFORMATION_AVAILABLE = 0x001D,
+ CONFLICTING_SA_CREATION_REQUEST = 0x001E,
+ LU_TRANSITIONING_TO_ANOTHER_POWER_CONDITION = 0x001F,
+ EXTENDED_COPY_INFORMATION_AVAILABLE = 0x0020,
+ ATOMIC_COMMAND_ABORTED_DUE_TO_ACA = 0x0021,
+ DEFERRED_MICROCODE_IS_PENDING = 0x0022,
+ OVERLAPPING_ATOMIC_COMMAND_IN_PROGRESS = 0x0023,
+
+ SCSI_ASC(NO_INDEX_SECTOR_SIGNAL, 0x01),
+
+ SCSI_ASC(NO_SEEK_COMPLETE, 0x02),
+
+ SCSI_ASC(PERIPHERAL_DEVICE_WRITE_FAULT, 0x03),
+ NO_WRITE_CURRENT = 0x0301,
+ EXCESSIVE_WRITE_ERRORS = 0x0302,
+
+ SCSI_ASC(LU_NOT_READY, 0x04),
+ LU_IS_IN_PROCESS_OF_BECOMING_READY = 0x0401,
+ LU_NOT_READY_INITIALIZING_COMMAND_REQUIRED = 0x0402,
+ LU_NOT_READY_MANUAL_INTERVENTION_REQUIRED = 0x0403,
+ LU_NOT_READY_FORMAT_IN_PROGRESS = 0x0404,
+ LU_NOT_READY_REBUILD_IN_PROGRESS = 0x0405,
+ LU_NOT_READY_RECALCULATION_IN_PROGRESS = 0x0406,
+ LU_NOT_READY_OP_IN_PROGRESS = 0x0407,
+ LU_NOT_READY_LONG_WRITE_IN_PROGRESS = 0x0408,
+ LU_NOT_READY_SELFTEST_IN_PROGRESS = 0x0409,
+ LU_NOT_ACCESSIBLE_ASYMMETRIC_ACCESS_STATE_TRANSITION = 0x040A,
+ LU_NOT_ACCESSIBLE_TARGET_PORT_IN_STANDBY_STATE = 0x040B,
+ LU_NOT_ACCESSIBLE_TARGET_PORT_IN_UNAVAILABLE_STATE = 0x040C,
+ LU_NOT_READY_STRUCTURE_CHECK_REQUIRED = 0x040D,
+ LU_NOT_READY_SECURITY_SESSION_IN_PROGRESS = 0x040E,
+ LU_NOT_READY_AUXILIARY_MEMORY_NOT_ACCESSIBLE = 0x0410,
+ LU_NOT_READY_NOTIFY_REQUIRED = 0x0411,
+ LU_NOT_READY_OFFLINE = 0x0412,
+ LU_NOT_READY_SA_CREATION_IN_PROGRESS = 0x0413,
+ LU_NOT_READY_SPACE_ALLOCATION_IN_PROGRESS = 0x0414,
+ LU_NOT_READY_ROBOTICS_DISABLED = 0x0415,
+ LU_NOT_READY_CONFIG_REQUIRED = 0x0416,
+ LU_NOT_READY_CALIBRATION_REQUIRED = 0x0417,
+ LU_NOT_READY_A_DOOR_IS_OPEN = 0x0418,
+ LU_NOT_READY_OPERATING_IN_SEQUENTIAL_MODE = 0x0419,
+ LU_NOT_READY_START_STOP_UNIT_COMMAND_IN_PROGRESS = 0x041A,
+ LU_NOT_READY_SANITIZE_IN_PROGRESS = 0x041B,
+ LU_NOT_READY_ADDITIONAL_POWER_USE_NOT_YET_GRANTED = 0x041C,
+ LU_NOT_READY_CONFIG_IN_PROGRESS = 0x041D,
+ LU_NOT_READY_MICROCODE_ACTIVATION_REQUIRED = 0x041E,
+ LU_NOT_READY_MICROCODE_DOWNLOAD_REQUIRED = 0x041F,
+ LU_NOT_READY_LU_RESET_REQUIRED = 0x0420,
+ LU_NOT_READY_HARD_RESET_REQUIRED = 0x0421,
+ LU_NOT_READY_POWER_CYCLE_REQUIRED = 0x0422,
+ LU_NOT_READY_AFFILIATION_REQUIRED = 0x0423,
+ DEPOPULATION_IN_PROGRESS = 0x0424,
+ DEPOPULATION_RESTORATION_IN_PROGRESS = 0x0425,
+
+ SCSI_ASC(LU_DOES_NOT_RESPOND_TO_SELECTION, 0x05),
+
+ SCSI_ASC(NO_REFERENCE_POSITION_FOUND, 0x06),
+
+ SCSI_ASC(MULTIPLE_PERIPHERAL_DEVICES_SELECTED, 0x07),
+
+ SCSI_ASC(LU_COMMUNICATION_FAILURE, 0x08),
+ LU_COMMUNICATION_TIMEOUT = 0x0801,
+ LU_COMMUNICATION_PARITY_ERROR = 0x0802,
+ LU_COMMUNICATION_CRC_ERROR = 0x0803,
+ UNREACHABLE_COPY_TARGET = 0x0804,
+
+ SCSI_ASC(TRACK_FOLLOWING_ERROR, 0x09),
+ TRACKING_SERVO_FAILURE = 0x0901,
+ FOCUS_SERVO_FAILURE = 0x0902,
+ SPINDLE_SERVO_FAILURE = 0x0903,
+ HEAD_SELECT_FAULT = 0x0904,
+ VIBRATION_INDUCED_TRACKING_ERROR = 0x0905,
+
+ SCSI_ASC(ERROR_LOG_OVERFLOW, 0x0A),
+
+ SCSI_ASC(SSC_WARNING, 0x0B),
+ WARNING_SPECIFIED_TEMPERATURE_EXCEEDED = 0x0B01,
+ WARNING_ENCLOSURE_DEGRADED = 0x0B02,
+ WARNING_BACKGROUND_SELFTEST_FAILED = 0x0B03,
+ WARNING_BACKGROUND_PRESCAN_DETECTED_MEDIUM_ERROR = 0x0B04,
+ WARNING_BACKGROUND_MEDIUM_SCAN_DETECTED_MEDIUM_ERROR = 0x0B05,
+ WARNING_NONVOLATILE_CACHE_NOW_VOLATILE = 0x0B06,
+ WARNING_DEGRADED_POWER_TO_NONVOLATILE_CACHE = 0x0B07,
+ WARNING_POWER_LOSS_EXPECTED = 0x0B08,
+ WARNING_DEVICE_STATISTICS_NOTIFICATION_ACTIVE = 0x0B09,
+ WARNING_HIGH_CRITICAL_TEMPERATURE_LIMIT_EXCEEDED = 0x0B0A,
+ WARNING_LOW_CRITICAL_TEMPERATURE_LIMIT_EXCEEDED = 0x0B0B,
+ WARNING_HIGH_OPERATING_TEMPERATURE_LIMIT_EXCEEDED = 0x0B0C,
+ WARNING_LOW_OPERATING_TEMPERATURE_LIMIT_EXCEEDED = 0x0B0D,
+ WARNING_HIGH_CRITICAL_HUMIDITY_LIMIT_EXCEEDED = 0x0B0E,
+ WARNING_LOW_CRITICAL_HUMIDITY_LIMIT_EXCEEDED = 0x0B0F,
+ WARNING_HIGH_OPERATING_HUMIDITY_LIMIT_EXCEEDED = 0x0B10,
+ WARNING_LOW_OPERATING_HUMIDITY_LIMIT_EXCEEDED = 0x0B11,
+ WARNING_MICROCODE_SECURITY_AT_RISK = 0x0B12,
+ WARNING_MICROCODE_DIGITAL_SIGNATURE_VALIDATION_FAILURE = 0x0B13,
+ WARNING_PHYSICAL_ELEMENT_STATUS_CHANGE = 0x0B14,
+
+ /* Defined as "WRITE ERROR" in T10. */
+ SCSI_ASC(SSC_WRITE_ERROR, 0x0C),
+ WRITE_ERROR_RECOVERED_WITH_AUTO_REALLOCATION = 0x0C01,
+ WRITE_ERROR_AUTO_REALLOCATION_FAILED = 0x0C02,
+ WRITE_ERROR_RECOMMEND_REASSIGNMENT = 0x0C03,
+ COMPRESSION_CHECK_MISCOMPARE_ERROR = 0x0C04,
+ DATA_EXPANSION_OCCURRED_DURING_COMPRESSION = 0x0C05,
+ BLOCK_NOT_COMPRESSIBLE = 0x0C06,
+ WRITE_ERROR_RECOVERY_NEEDED = 0x0C07,
+ WRITE_ERROR_RECOVERY_FAILED = 0x0C08,
+ WRITE_ERROR_LOSS_OF_STREAMING = 0x0C09,
+ WRITE_ERROR_PADDING_BLOCKS_ADDED = 0x0C0A,
+ AUXILIARY_MEMORY_WRITE_ERROR = 0x0C0B,
+ WRITE_ERROR_UNEXPECTED_UNSOLICITED_DATA = 0x0C0C,
+ WRITE_ERROR_NOT_ENOUGH_UNSOLICITED_DATA = 0x0C0D,
+ MULTIPLE_WRITE_ERRORS = 0x0C0E,
+ DEFECTS_IN_ERROR_WINDOW = 0x0C0F,
+ INCOMPLETE_MULTIPLE_ATOMIC_WRITE_OPERATIONS = 0x0C10,
+ WRITE_ERROR_RECOVERY_SCAN_NEEDED = 0x0C11,
+ WRITE_ERROR_INSUFFICIENT_ZONE_RESOURCES = 0x0C12,
+
+ SCSI_ASC(ERROR_DETECTED_BY_THIRD_PARTY_TEMPORARY_INITIATOR, 0x0D),
+ THIRD_PARTY_DEVICE_FAILURE = 0x0D01,
+ COPY_TARGET_DEVICE_NOT_REACHABLE = 0x0D02,
+ INCORRECT_COPY_TARGET_DEVICE_TYPE = 0x0D03,
+ COPY_TARGET_DEVICE_DATA_UNDERRUN = 0x0D04,
+ COPY_TARGET_DEVICE_DATA_OVERRUN = 0x0D05,
+
+ SCSI_ASC(INVALID_INFORMATION_UNIT, 0x0E),
+ INFORMATION_UNIT_TOO_SHORT = 0x0E01,
+ INFORMATION_UNIT_TOO_LONG = 0x0E02,
+ INVALID_FIELD_IN_COMMAND_INFORMATION_UNIT = 0x0E03,
+
+ SCSI_ASC(ID_CRC_OR_ECC_ERROR, 0x10),
+ LOGICAL_BLOCK_GUARD_CHECK_FAILED = 0x1001,
+ LOGICAL_BLOCK_APPLICATION_TAG_CHECK_FAILED = 0x1002,
+ LOGICAL_BLOCK_REFERENCE_TAG_CHECK_FAILED = 0x1003,
+ LOGICAL_BLOCK_PROTECTION_ERROR_ON_RECOVER_BUFFERED_DATA = 0x1004,
+ LOGICAL_BLOCK_PROTECTION_METHOD_ERROR = 0x1005,
+
+ SCSI_ASC(UNRECOVERED_READ_ERROR, 0x11),
+ READ_RETRIES_EXHAUSTED = 0x1101,
+ ERROR_TOO_LONG_TO_CORRECT = 0x1102,
+ MULTIPLE_READ_ERRORS = 0x1103,
+ UNRECOVERED_READ_ERROR_AUTO_REALLOCATE_FAILED = 0x1104,
+ LEC_UNCORRECTABLE_ERROR = 0x1105,
+ CIRC_UNRECOVERED_ERROR = 0x1106,
+ DATA_RESYNCHRONIZATION_ERROR = 0x1107,
+ INCOMPLETE_BLOCK_READ = 0x1108,
+ NO_GAP_FOUND = 0x1109,
+ MISCORRECTED_ERROR = 0x110A,
+ UNRECOVERED_READ_ERROR_RECOMMEND_REASSIGNMENT = 0x110B,
+ UNRECOVERED_READ_ERROR_RECOMMEND_REWRITE_THE_DATA = 0x110C,
+ DECOMPRESSION_CRC_ERROR = 0x110D,
+ CANNOT_DECOMPRESS_USING_DECLARED_ALGORITHM = 0x110E,
+ ERROR_READING_UPC_EAN_NUMBER = 0x110F,
+ ERROR_READING_ISRC_NUMBER = 0x1110,
+ READ_ERROR_LOSS_OF_STREAMING = 0x1111,
+ AUXILIARY_MEMORY_READ_ERROR = 0x1112,
+ READ_ERROR_FAILED_RETRANSMISSION_REQUEST = 0x1113,
+ READ_ERROR_LBA_MARKED_BAD_BY_APPLICATION_CLIENT = 0x1114,
+ WRITE_AFTER_SANITIZE_REQUIRED = 0x1115,
+
+ SCSI_ASC(ADDRESS_MARK_NOT_FOUND_FOR_ID_FIELD, 0x12),
+
+ SCSI_ASC(ADDRESS_MARK_NOT_FOUND_FOR_DATA_FIELD, 0x13),
+
+ SCSI_ASC(RECORDED_ENTITY_NOT_FOUND, 0x14),
+ RECORD_NOT_FOUND = 0x1401,
+ FILEMARK_OR_SETMARK_NOT_FOUND = 0x1402,
+ END_OF_DATA_NOT_FOUND = 0x1403,
+ BLOCK_SEQUENCE_ERROR = 0x1404,
+ RECORD_NOT_FOUND_RECOMMEND_REASSIGNMENT = 0x1405,
+ RECORD_NOT_FOUND_DATA_AUTO_REALLOCATED = 0x1406,
+ LOCATE_OPERATION_FAILURE = 0x1407,
+
+ SCSI_ASC(RANDOM_POSITIONING_ERROR, 0x15),
+ MECHANICAL_POSITIONING_ERROR = 0x1501,
+ POSITIONING_ERROR_DETECTED_BY_READ_OF_MEDIUM = 0x1502,
+
+ SCSI_ASC(DATA_SYNCHRONIZATION_MARK_ERROR, 0x16),
+ DATA_SYNC_ERROR_DATA_REWRITTEN = 0x1601,
+ DATA_SYNC_ERROR_RECOMMEND_REWRITE = 0x1602,
+ DATA_SYNC_ERROR_DATA_AUTO_REALLOCATED = 0x1603,
+ DATA_SYNC_ERROR_RECOMMEND_REASSIGNMENT = 0x1604,
+
+ SCSI_ASC(RECOVERED_DATA_WITH_NO_ERROR_CORRECTION_APPLIED, 0x17),
+ RECOVERED_DATA_WITH_RETRIES = 0x1701,
+ RECOVERED_DATA_WITH_POSITIVE_HEAD_OFFSET = 0x1702,
+ RECOVERED_DATA_WITH_NEGATIVE_HEAD_OFFSET = 0x1703,
+ RECOVERED_DATA_WITH_RETRIES_AND_OR_CIRC_APPLIED = 0x1704,
+ RECOVERED_DATA_USING_PREVIOUS_SECTOR_ID = 0x1705,
+ RECOVERED_DATA_WITHOUT_ECC_DATA_AUTO_REALLOCATED = 0x1706,
+ RECOVERED_DATA_WITHOUT_ECC_RECOMMEND_REASSIGNMENT = 0x1707,
+ RECOVERED_DATA_WITHOUT_ECC_RECOMMEND_REWRITE = 0x1708,
+ RECOVERED_DATA_WITHOUT_ECC_DATA_REWRITTEN = 0x1709,
+
+ SCSI_ASC(RECOVERED_DATA_WITH_ERROR_CORRECTION_APPLIED, 0x18),
+ RECOVERED_DATA_WITH_ERROR_CORRECTION_RETRIES_APPLIED = 0x1801,
+ RECOVERED_DATA_DATA_AUTO_REALLOCATED = 0x1802,
+ RECOVERED_DATA_WITH_CIRC = 0x1803,
+ RECOVERED_DATA_WITH_LEC = 0x1804,
+ RECOVERED_DATA_RECOMMEND_REASSIGNMENT = 0x1805,
+ RECOVERED_DATA_RECOMMEND_REWRITE = 0x1806,
+ RECOVERED_DATA_WITH_ECC_DATA_REWRITTEN = 0x1807,
+ RECOVERED_DATA_WITH_LINKING = 0x1808,
+
+ SCSI_ASC(DEFECT_LIST_ERROR, 0x19),
+ DEFECT_LIST_NOT_AVAILABLE = 0x1901,
+ DEFECT_LIST_ERROR_IN_PRIMARY_LIST = 0x1902,
+ DEFECT_LIST_ERROR_IN_GROWN_LIST = 0x1903,
+
+ SCSI_ASC(PARAMETER_LIST_LENGTH_ERROR, 0x1A),
+
+ SCSI_ASC(SYNCHRONOUS_DATA_TRANSFER_ERROR, 0x1B),
+
+ SCSI_ASC(DEFECT_LIST_NOT_FOUND, 0x1C),
+ PRIMARY_DEFECT_LIST_NOT_FOUND = 0x1C01,
+ GROWN_DEFECT_LIST_NOT_FOUND = 0x1C02,
+
+ SCSI_ASC(MISCOMPARE_DURING_VERIFY_OPERATION, 0x1D),
+ MISCOMPARE_VERIFY_OF_UNMAPPED_LBA = 0x1D01,
+
+ SCSI_ASC(RECOVERED_ID_WITH_ECC_CORRECTION, 0x1E),
+
+ SCSI_ASC(PARTIAL_DEFECT_LIST_TRANSFER, 0x1F),
+
+ SCSI_ASC(INVALID_COMMAND_OP_CODE, 0x20),
+ ACCESS_DENIED_INITIATOR_PENDING_ENROLLED = 0x2001,
+ ACCESS_DENIED_NO_ACCESS_RIGHTS = 0x2002,
+ ACCESS_DENIED_INVALID_MGMT_ID_KEY = 0x2003,
+ ILLEGAL_COMMAND_WHILE_IN_WRITE_CAPABLE_STATE = 0x2004,
+ ILLEGAL_COMMAND_WHILE_IN_EXPLICIT_ADDRESS_MODE = 0x2006,
+ ILLEGAL_COMMAND_WHILE_IN_IMPLICIT_ADDRESS_MODE = 0x2007,
+ ACCESS_DENIED_ENROLLMENT_CONFLICT = 0x2008,
+ ACCESS_DENIED_INVALID_LU_IDENTIFIER = 0x2009,
+ ACCESS_DENIED_INVALID_PROXY_TOKEN = 0x200A,
+ ACCESS_DENIED_ACL_LUN_CONFLICT = 0x200B,
+ ILLEGAL_COMMAND_WHEN_NOT_IN_APPEND_ONLY_MODE = 0x200C,
+ NOT_AN_ADMINISTRATIVE_LOGICAL_UNIT = 0x200D,
+ NOT_A_SUBSIDIARY_LOGICAL_UNIT = 0x200E,
+ NOT_A_CONGLOMERATE_LOGICAL_UNIT = 0x200F,
+
+ SCSI_ASC(LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE, 0x21),
+ INVALID_ELEMENT_ADDRESS = 0x2101,
+ INVALID_ADDRESS_FOR_WRITE = 0x2102,
+ INVALID_WRITE_CROSSING_LAYER_JUMP = 0x2103,
+ UNALIGNED_WRITE_COMMAND = 0x2104,
+ WRITE_BOUNDARY_VIOLATION = 0x2105,
+ ATTEMPT_TO_READ_INVALID_DATA = 0x2106,
+ READ_BOUNDARY_VIOLATION = 0x2107,
+ MISALIGNED_WRITE_COMMAND = 0x2108,
+ ATTEMPT_TO_ACCESS_GAP_ZONE = 0x2109,
+
+ SCSI_ASC(ILLEGAL_FUNCTION, 0x22),
+
+ SCSI_ASC(INVALID_TOKEN_OP, 0x23),
+ INVALID_TOKEN_OP_UNSUPPORTED_TOKEN_TYPE = 0x2301,
+ INVALID_TOKEN_OP_REMOTE_TOKEN_USAGE_NOT_SUPPORTED = 0x2302,
+ INVALID_TOKEN_OP_REMOTE_ROD_TOKEN_CREATION_NOT_SUPPORTED = 0x2303,
+ INVALID_TOKEN_OP_TOKEN_UNKNOWN = 0x2304,
+ INVALID_TOKEN_OP_TOKEN_CORRUPT = 0x2305,
+ INVALID_TOKEN_OP_TOKEN_REVOKED = 0x2306,
+ INVALID_TOKEN_OP_TOKEN_EXPIRED = 0x2307,
+ INVALID_TOKEN_OP_TOKEN_CANCELLED = 0x2308,
+ INVALID_TOKEN_OP_TOKEN_DELETED = 0x2309,
+ INVALID_TOKEN_OP_INVALID_TOKEN_LENGTH = 0x230A,
+
+ SCSI_ASC(INVALID_FIELD_IN_CDB, 0x24),
+ CDB_DECRYPTION_ERROR = 0x2401,
+ SECURITY_AUDIT_VALUE_FROZEN = 0x2404,
+ SECURITY_WORKING_KEY_FROZEN = 0x2405,
+ NONCE_NOT_UNIQUE = 0x2406,
+ NONCE_TIMESTAMP_OUT_OF_RANGE = 0x2407,
+ INVALID_XCDB = 0x2408,
+ INVALID_FAST_FORMAT = 0x2409,
+
+ SCSI_ASC(LU_NOT_SUPPORTED, 0x25),
+
+ SCSI_ASC(INVALID_FIELD_IN_PARAMETER_LIST, 0x26),
+ PARAMETER_NOT_SUPPORTED = 0x2601,
+ PARAMETER_VALUE_INVALID = 0x2602,
+ THRESHOLD_PARAMETERS_NOT_SUPPORTED = 0x2603,
+ INVALID_RELEASE_OF_PERSISTENT_RESERVATION = 0x2604,
+ DATA_DECRYPTION_ERROR = 0x2605,
+ TOO_MANY_TARGET_DESCRIPTORS = 0x2606,
+ UNSUPPORTED_TARGET_DESCRIPTOR_TYPE_CODE = 0x2607,
+ TOO_MANY_SEGMENT_DESCRIPTORS = 0x2608,
+ UNSUPPORTED_SEGMENT_DESCRIPTOR_TYPE_CODE = 0x2609,
+ UNEXPECTED_INEXACT_SEGMENT = 0x260A,
+ INLINE_DATA_LENGTH_EXCEEDED = 0x260B,
+ INVALID_OP_FOR_COPY_SOURCE_OR_DESTINATION = 0x260C,
+ COPY_SEGMENT_GRANULARITY_VIOLATION = 0x260D,
+ INVALID_PARAMETER_WHILE_PORT_IS_ENABLED = 0x260E,
+ INVALID_DATA_OUT_BUFFER_INTEGRITY_CHECK_VALUE = 0x260F,
+ DATA_DECRYPTION_KEY_FAIL_LIMIT_REACHED = 0x2610,
+ INCOMPLETE_KEY_ASSOCIATED_DATA_SET = 0x2611,
+ VENDOR_SPECIFIC_KEY_REFERENCE_NOT_FOUND = 0x2612,
+ APPLICATION_TAG_MODE_PAGE_IS_INVALID = 0x2613,
+ TAPE_STREAM_MIRRORING_PREVENTED = 0x2614,
+ COPY_SOURCE_OR_COPY_DESTINATION_NOT_AUTHORIZED = 0x2615,
+ FAST_COPY_NOT_POSSIBLE = 0x2616,
+
+ SCSI_ASC(WRITE_PROTECTED, 0x27),
+ HW_WRITE_PROTECTED = 0x2701,
+ LU_SOFTWARE_WRITE_PROTECTED = 0x2702,
+ ASSOCIATED_WRITE_PROTECT = 0x2703,
+ PERSISTENT_WRITE_PROTECT = 0x2704,
+ PERMANENT_WRITE_PROTECT = 0x2705,
+ CONDITIONAL_WRITE_PROTECT = 0x2706,
+ SPACE_ALLOCATION_FAILED_WRITE_PROTECT = 0x2707,
+ ZONE_IS_READ_ONLY = 0x2708,
+
+ SCSI_ASC(NOT_READY_TO_READY_CHANGE_MEDIUM_MAY_HAVE_CHANGED, 0x28),
+ IMPORT_OR_EXPORT_ELEMENT_ACCESSED = 0x2801,
+ FORMAT_LAYER_MAY_HAVE_CHANGED = 0x2802,
+ IMPORT_EXPORT_ELEMENT_ACCESSED_MEDIUM_CHANGED = 0x2803,
+
+ SCSI_ASC(POWER_ON_RESET_OR_BUS_DEVICE_RESET_OCCURRED, 0x29),
+ POWER_ON_OCCURRED = 0x2901,
+ SCSI_BUS_RESET_OCCURRED = 0x2902,
+ BUS_DEVICE_RESET_FUNCTION_OCCURRED = 0x2903,
+ DEVICE_INTERNAL_RESET = 0x2904,
+ TRANSCEIVER_MODE_CHANGED_TO_SINGLE_ENDED = 0x2905,
+ TRANSCEIVER_MODE_CHANGED_TO_LVD = 0x2906,
+ I_T_NEXUS_LOSS_OCCURRED = 0x2907,
+
+ SCSI_ASC(PARAMETERS_CHANGED, 0x2A),
+ MODE_PARAMETERS_CHANGED = 0x2A01,
+ LOG_PARAMETERS_CHANGED = 0x2A02,
+ RESERVATIONS_PREEMPTED = 0x2A03,
+ RESERVATIONS_RELEASED = 0x2A04,
+ REGISTRATIONS_PREEMPTED = 0x2A05,
+ ASYMMETRIC_ACCESS_STATE_CHANGED = 0x2A06,
+ IMPLICIT_ASYMMETRIC_ACCESS_STATE_TRANSITION_FAILED = 0x2A07,
+ PRIORITY_CHANGED = 0x2A08,
+ CAPACITY_DATA_HAS_CHANGED = 0x2A09,
+ ERROR_HISTORY_I_T_NEXUS_CLEARED = 0x2A0A,
+ ERROR_HISTORY_SNAPSHOT_RELEASED = 0x2A0B,
+ ERROR_RECOVERY_ATTRIBUTES_HAVE_CHANGED = 0x2A0C,
+ DATA_ENCRYPTION_CAPABILITIES_CHANGED = 0x2A0D,
+ TIMESTAMP_CHANGED = 0x2A10,
+ DATA_ENCRYPTION_PARAMS_CHANGED_BY_ANOTHER_I_T_NEXUS = 0x2A11,
+ DATA_ENCRYPTION_PARAMS_CHANGED_BY_VENDOR_SPECIFIC_EVENT = 0x2A12,
+ DATA_ENCRYPTION_KEY_INSTANCE_COUNTER_HAS_CHANGED = 0x2A13,
+ SA_CREATION_CAPABILITIES_DATA_HAS_CHANGED = 0x2A14,
+ MEDIUM_REMOVAL_PREVENTION_PREEMPTED = 0x2A15,
+ ZONE_RESET_WRITE_POINTER_RECOMMENDED = 0x2A16,
+
+ SCSI_ASC(COPY_CANNOT_EXECUTE_SINCE_HOST_CANNOT_DISCONNECT, 0x2B),
+
+ SCSI_ASC(COMMAND_SEQUENCE_ERROR, 0x2C),
+ TOO_MANY_WINDOWS_SPECIFIED = 0x2C01,
+ INVALID_COMBINATION_OF_WINDOWS_SPECIFIED = 0x2C02,
+ CURRENT_PROGRAM_AREA_IS_NOT_EMPTY = 0x2C03,
+ CURRENT_PROGRAM_AREA_IS_EMPTY = 0x2C04,
+ ILLEGAL_POWER_CONDITION_REQUEST = 0x2C05,
+ PERSISTENT_PREVENT_CONFLICT = 0x2C06,
+ PREVIOUS_BUSY_STATUS = 0x2C07,
+ PREVIOUS_TASK_SET_FULL_STATUS = 0x2C08,
+ PREVIOUS_RESERVATION_CONFLICT_STATUS = 0x2C09,
+ PARTITION_OR_COLLECTION_CONTAINS_USER_OBJECTS = 0x2C0A,
+ NOT_RESERVED = 0x2C0B,
+ ORWRITE_GENERATION_DOES_NOT_MATCH = 0x2C0C,
+ RESET_WRITE_POINTER_NOT_ALLOWED = 0x2C0D,
+ ZONE_IS_OFFLINE = 0x2C0E,
+ STREAM_NOT_OPEN = 0x2C0F,
+ UNWRITTEN_DATA_IN_ZONE = 0x2C10,
+ DESCRIPTOR_FORMAT_SENSE_DATA_REQUIRED = 0x2C11,
+ ZONE_IS_INACTIVE = 0x2C12,
+ WELL_KNOWN_LU_ACCESS_REQUIRED = 0x2C13,
+
+ SCSI_ASC(OVERWRITE_ERROR_ON_UPDATE_IN_PLACE, 0x2D),
+
+ SCSI_ASC(INSUFFICIENT_TIME_FOR_OPERATION, 0x2E),
+ COMMAND_TIMEOUT_BEFORE_PROCESSING = 0x2E01,
+ COMMAND_TIMEOUT_DURING_PROCESSING = 0x2E02,
+ COMMAND_TIMEOUT_DURING_PROCESSING_DUE_TO_ERROR_RECOVERY = 0x2E03,
+
+ SCSI_ASC(COMMANDS_CLEARED_BY_ANOTHER_INITIATOR, 0x2F),
+ COMMANDS_CLEARED_BY_POWER_LOSS_NOTIFICATION = 0x2F01,
+ COMMANDS_CLEARED_BY_DEVICE_SERVER = 0x2F02,
+ SOME_COMMANDS_CLEARED_BY_QUEUING_LAYER_EVENT = 0x2F03,
+
+ SCSI_ASC(INCOMPATIBLE_MEDIUM_INSTALLED, 0x30),
+ CANNOT_READ_MEDIUM_UNKNOWN_FORMAT = 0x3001,
+ CANNOT_READ_MEDIUM_INCOMPATIBLE_FORMAT = 0x3002,
+ CLEANING_CARTRIDGE_INSTALLED = 0x3003,
+ CANNOT_WRITE_MEDIUM_UNKNOWN_FORMAT = 0x3004,
+ CANNOT_WRITE_MEDIUM_INCOMPATIBLE_FORMAT = 0x3005,
+ CANNOT_FORMAT_MEDIUM_INCOMPATIBLE_MEDIUM = 0x3006,
+ CLEANING_FAILURE = 0x3007,
+ CANNOT_WRITE_APPLICATION_CODE_MISMATCH = 0x3008,
+ CURRENT_SESSION_NOT_FIXATED_FOR_APPEND = 0x3009,
+ CLEANING_REQUEST_REJECTED = 0x300A,
+ WORM_MEDIUM_OVERWRITE_ATTEMPTED = 0x300C,
+ WORM_MEDIUM_INTEGRITY_CHECK = 0x300D,
+ MEDIUM_NOT_FORMATTED = 0x3010,
+ INCOMPATIBLE_VOLUME_TYPE = 0x3011,
+ INCOMPATIBLE_VOLUME_QUALIFIER = 0x3012,
+ CLEANING_VOLUME_EXPIRED = 0x3013,
+
+ SCSI_ASC(MEDIUM_FORMAT_CORRUPTED, 0x31),
+ FORMAT_COMMAND_FAILED = 0x3101,
+ ZONED_FORMATTING_FAILED_DUE_TO_SPARE_LINKING = 0x3102,
+ SANITIZE_COMMAND_FAILED = 0x3103,
+ DEPOPULATION_FAILED = 0x3104,
+ DEPOPULATION_RESTORATION_FAILED = 0x3105,
+
+ SCSI_ASC(NO_DEFECT_SPARE_LOCATION_AVAILABLE, 0x32),
+ DEFECT_LIST_UPDATE_FAILURE = 0x3201,
+
+ SCSI_ASC(TAPE_LENGTH_ERROR, 0x33),
+
+ SCSI_ASC(ENCLOSURE_FAILURE, 0x34),
+
+ SCSI_ASC(ENCLOSURE_SERVICES_FAILURE, 0x35),
+ UNSUPPORTED_ENCLOSURE_FUNCTION = 0x3501,
+ ENCLOSURE_SERVICES_UNAVAILABLE = 0x3502,
+ ENCLOSURE_SERVICES_TRANSFER_FAILURE = 0x3503,
+ ENCLOSURE_SERVICES_TRANSFER_REFUSED = 0x3504,
+ ENCLOSURE_SERVICES_CHECKSUM_ERROR = 0x3505,
+
+ SCSI_ASC(RIBBON_INK_OR_TONER_FAILURE, 0x36),
+
+ SCSI_ASC(ROUNDED_PARAMETER, 0x37),
+
+ SCSI_ASC(EVENT_STATUS_NOTIFICATION, 0x38),
+ ESN_POWER_MANAGEMENT_CLASS_EVENT = 0x3802,
+ ESN_MEDIA_CLASS_EVENT = 0x3804,
+ ESN_DEVICE_BUSY_CLASS_EVENT = 0x3806,
+ THIN_PROVISIONING_SOFT_THRESHOLD_REACHED = 0x3807,
+ DEPOPULATION_INTERRUPTED = 0x3808,
+ DEPOPULATION_RESTORATION_INTERRUPTED = 0x3809,
+
+ SCSI_ASC(SAVING_PARAMETERS_NOT_SUPPORTED, 0x39),
+
+ SCSI_ASC(MEDIUM_NOT_PRESENT, 0x3A),
+ MEDIUM_NOT_PRESENT_TRAY_CLOSED = 0x3A01,
+ MEDIUM_NOT_PRESENT_TRAY_OPEN = 0x3A02,
+ MEDIUM_NOT_PRESENT_LOADABLE = 0x3A03,
+ MEDIUM_NOT_PRESENT_MEDIUM_AUXILIARY_MEMORY_ACCESSIBLE = 0x3A04,
+
+ SCSI_ASC(SEQUENTIAL_POSITIONING_ERROR, 0x3B),
+ TAPE_POSITION_ERROR_AT_BEGINNING_OF_MEDIUM = 0x3B01,
+ TAPE_POSITION_ERROR_AT_END_OF_MEDIUM = 0x3B02,
+ TAPE_OR_ELECTRONIC_VERTICAL_FORMS_UNIT_NOT_READY = 0x3B03,
+ SLEW_FAILURE = 0x3B04,
+ PAPER_JAM = 0x3B05,
+ FAILED_TO_SENSE_TOP_OF_FORM = 0x3B06,
+ FAILED_TO_SENSE_BOTTOM_OF_FORM = 0x3B07,
+ REPOSITION_ERROR = 0x3B08,
+ READ_PAST_END_OF_MEDIUM = 0x3B09,
+ READ_PAST_BEGINNING_OF_MEDIUM = 0x3B0A,
+ POSITION_PAST_END_OF_MEDIUM = 0x3B0B,
+ POSITION_PAST_BEGINNING_OF_MEDIUM = 0x3B0C,
+ MEDIUM_DESTINATION_ELEMENT_FULL = 0x3B0D,
+ MEDIUM_SOURCE_ELEMENT_EMPTY = 0x3B0E,
+ END_OF_MEDIUM_REACHED = 0x3B0F,
+ MEDIUM_MAGAZINE_NOT_ACCESSIBLE = 0x3B11,
+ MEDIUM_MAGAZINE_REMOVED = 0x3B12,
+ MEDIUM_MAGAZINE_INSERTED = 0x3B13,
+ MEDIUM_MAGAZINE_LOCKED = 0x3B14,
+ MEDIUM_MAGAZINE_UNLOCKED = 0x3B15,
+ MECHANICAL_POSITIONING_OR_CHANGER_ERROR = 0x3B16,
+ READ_PAST_END_OF_USER_OBJECT = 0x3B17,
+ ELEMENT_DISABLED = 0x3B18,
+ ELEMENT_ENABLED = 0x3B19,
+ DATA_TRANSFER_DEVICE_REMOVED = 0x3B1A,
+ DATA_TRANSFER_DEVICE_INSERTED = 0x3B1B,
+ TOO_MANY_LOGICAL_OBJECTS_ON_PARTITION_TO_SUPPORT_OP = 0x3B1C,
+ ELEMENT_STATIC_INFORMATION_CHANGED = 0x3B20,
+
+ SCSI_ASC(INVALID_BITS_IN_IDENTIFY_MESSAGE, 0x3D),
+
+ SCSI_ASC(LU_HAS_NOT_SELF_CONFIGURED_YET, 0x3E),
+ LU_FAILURE = 0x3E01,
+ TIMEOUT_ON_LOGICAL_UNIT = 0x3E02,
+ LU_FAILED_SELF_TEST = 0x3E03,
+ LU_UNABLE_TO_UPDATE_SELFTEST_LOG = 0x3E04,
+
+ SCSI_ASC(TARGET_OPERATING_CONDITIONS_HAVE_CHANGED, 0x3F),
+ MICROCODE_HAS_BEEN_CHANGED = 0x3F01,
+ CHANGED_OPERATING_DEFINITION = 0x3F02,
+ INQUIRY_DATA_HAS_CHANGED = 0x3F03,
+ COMPONENT_DEVICE_ATTACHED = 0x3F04,
+ DEVICE_IDENTIFIER_CHANGED = 0x3F05,
+ REDUNDANCY_GROUP_CREATED_OR_MODIFIED = 0x3F06,
+ REDUNDANCY_GROUP_DELETED = 0x3F07,
+ SPARE_CREATED_OR_MODIFIED = 0x3F08,
+ SPARE_DELETED = 0x3F09,
+ VOLUME_SET_CREATED_OR_MODIFIED = 0x3F0A,
+ VOLUME_SET_DELETED = 0x3F0B,
+ VOLUME_SET_DEASSIGNED = 0x3F0C,
+ VOLUME_SET_REASSIGNED = 0x3F0D,
+ REPORTED_LUNS_DATA_HAS_CHANGED = 0x3F0E,
+ ECHO_BUFFER_OVERWRITTEN = 0x3F0F,
+ MEDIUM_LOADABLE = 0x3F10,
+ MEDIUM_AUXILIARY_MEMORY_ACCESSIBLE = 0x3F11,
+ iSCSI_IP_ADDRESS_ADDED = 0x3F12,
+ iSCSI_IP_ADDRESS_REMOVED = 0x3F13,
+ iSCSI_IP_ADDRESS_CHANGED = 0x3F14,
+ INSPECT_REFERRALS_SENSE_DESCRIPTORS = 0x3F15,
+ MICROCODE_HAS_BEEN_CHANGED_WITHOUT_RESET = 0x3F16,
+ ZONE_TRANSITION_TO_FULL = 0x3F17,
+ BIND_COMPLETED = 0x3F18,
+ BIND_REDIRECTED = 0x3F19,
+ SUBSIDIARY_BINDING_CHANGED = 0x3F1A,
+
+ SCSI_ASC(RAM_FAILURE, 0x40),
+ /* DIAGNOSTIC_FAILURE_ON_COMPONENT_NN = 0x40NN */
+
+ SCSI_ASC(DATA_PATH_FAILURE, 0x41),
+
+ SCSI_ASC(POWER_ON_OR_SELFTEST_FAILURE, 0x42),
+
+ SCSI_ASC(MESSAGE_ERROR, 0x43),
+
+ SCSI_ASC(INTERNAL_TARGET_FAILURE, 0x44),
+ PERSISTENT_RESERVATION_INFORMATION_LOST = 0x4401,
+ ATA_DEVICE_FAILED_SET_FEATURES = 0x4471,
+
+ SCSI_ASC(SELECT_OR_RESELECT_FAILURE, 0x45),
+
+ SCSI_ASC(UNSUCCESSFUL_SOFT_RESET, 0x46),
+
+ SCSI_ASC(SCSI_PARITY_ERROR, 0x47),
+ DATA_PHASE_CRC_ERROR_DETECTED = 0x4701,
+ SCSI_PARITY_ERROR_DETECTED_DURING_ST_DATA_PHASE = 0x4702,
+ INFORMATION_UNIT_iuCRC_ERROR_DETECTED = 0x4703,
+ ASYNCHRONOUS_INFORMATION_PROTECTION_ERROR_DETECTED = 0x4704,
+ PROTOCOL_SERVICE_CRC_ERROR = 0x4705,
+ PHY_TEST_FUNCTION_IN_PROGRESS = 0x4706,
+ SOME_COMMANDS_CLEARED_BY_ISCSI_PROTOCOL_EVENT = 0x477F,
+
+ SCSI_ASC(INITIATOR_DETECTED_ERROR_MESSAGE_RECEIVED, 0x48),
+
+ SCSI_ASC(INVALID_MESSAGE_ERROR, 0x49),
+
+ SCSI_ASC(COMMAND_PHASE_ERROR, 0x4A),
+
+ SCSI_ASC(DATA_PHASE_ERROR, 0x4B),
+ INVALID_TARGET_PORT_TRANSFER_TAG_RECEIVED = 0x4B01,
+ TOO_MUCH_WRITE_DATA = 0x4B02,
+ ACK_NAK_TIMEOUT = 0x4B03,
+ NAK_RECEIVED = 0x4B04,
+ DATA_OFFSET_ERROR = 0x4B05,
+ INITIATOR_RESPONSE_TIMEOUT = 0x4B06,
+ CONNECTION_LOST = 0x4B07,
+ DATA_IN_BUFFER_OVERFLOW_BUFFER_SIZE = 0x4B08,
+ DATA_IN_BUFFER_OVERFLOW_BUFFER_DESCRIPTOR_AREA = 0x4B09,
+ DATA_IN_BUFFER_ERROR = 0x4B0A,
+ DATA_OUT_BUFFER_OVERFLOW_BUFFER_SIZE = 0x4B0B,
+ DATA_OUT_BUFFER_OVERFLOW_BUFFER_DESCRIPTOR_AREA = 0x4B0C,
+ DATA_OUT_BUFFER_ERROR = 0x4B0D,
+ PCIE_FABRIC_ERROR = 0x4B0E,
+ PCIE_COMPLETION_TIMEOUT = 0x4B0F,
+ PCIE_COMPLETER_ABORT = 0x4B10,
+ PCIE_POISONED_TLP_RECEIVED = 0x4B11,
+ PCIE_ECRC_CHECK_FAILED = 0x4B12,
+ PCIE_UNSUPPORTED_REQUEST = 0x4B13,
+ PCIE_ACS_VIOLATION = 0x4B14,
+ PCIE_TLP_PREFIX_BLOCKED = 0x4B15,
+
+ SCSI_ASC(LU_FAILED_SELF_CONFIGURATION, 0x4C),
+
+ SCSI_ASC(TAGGED_OVERLAPPED_COMMANDS, 0x4D),
+
+ SCSI_ASC(OVERLAPPED_COMMANDS_ATTEMPTED, 0x4E),
+
+ SCSI_ASC(WRITE_APPEND_ERROR, 0x50),
+ WRITE_APPEND_POSITION_ERROR = 0x5001,
+ POSITION_ERROR_RELATED_TO_TIMING = 0x5002,
+
+ SCSI_ASC(ERASE_FAILURE, 0x51),
+ ERASE_FAILURE_INCOMPLETE_ERASE_OP_DETECTED = 0x5101,
+
+ SCSI_ASC(CARTRIDGE_FAULT, 0x52),
+
+ SCSI_ASC(MEDIA_LOAD_OR_EJECT_FAILED, 0x53),
+ UNLOAD_TAPE_FAILURE = 0x5301,
+ MEDIUM_REMOVAL_PREVENTED = 0x5302,
+ MEDIUM_REMOVAL_PREVENTED_BY_DATA_TRANSFER_ELEMENT = 0x5303,
+ MEDIUM_THREAD_OR_UNTHREAD_FAILURE = 0x5304,
+ VOLUME_IDENTIFIER_INVALID = 0x5305,
+ VOLUME_IDENTIFIER_MISSING = 0x5306,
+ DUPLICATE_VOLUME_IDENTIFIER = 0x5307,
+ ELEMENT_STATUS_UNKNOWN = 0x5308,
+ DATA_TRANSFER_DEVICE_ERR_LOAD_FAILED = 0x5309,
+ DATA_TRANSFER_DEVICE_ERR_UNLOAD_FAILED = 0x530A,
+ DATA_TRANSFER_DEVICE_ERR_UNLOAD_MISSING = 0x530B,
+ DATA_TRANSFER_DEVICE_ERR_EJECT_FAILED = 0x530C,
+ DATA_TRANSFER_DEVICE_ERR_LIBRARY_COMMUNICATION_FAILED = 0x530D,
+
+ SCSI_ASC(SCSI_TO_HOST_SYSTEM_INTERFACE_FAILURE, 0x54),
+
+ SCSI_ASC(SYSTEM_RESOURCE_FAILURE, 0x55),
+ SYSTEM_BUFFER_FULL = 0x5501,
+ INSUFFICIENT_RESERVATION_RESOURCES = 0x5502,
+ INSUFFICIENT_RESOURCES = 0x5503,
+ INSUFFICIENT_REGISTRATION_RESOURCES = 0x5504,
+ INSUFFICIENT_ACCESS_CONTROL_RESOURCES = 0x5505,
+ AUXILIARY_MEMORY_OUT_OF_SPACE = 0x5506,
+ QUOTA_ERROR = 0x5507,
+ MAXIMUM_NUMBER_OF_SUPPLEMENTAL_DECRYPTION_KEYS_EXCEEDED = 0x5508,
+ MEDIUM_AUXILIARY_MEMORY_NOT_ACCESSIBLE = 0x5509,
+ DATA_CURRENTLY_UNAVAILABLE = 0x550A,
+ INSUFFICIENT_POWER_FOR_OPERATION = 0x550B,
+ INSUFFICIENT_RESOURCES_TO_CREATE_ROD = 0x550C,
+ INSUFFICIENT_RESOURCES_TO_CREATE_ROD_TOKEN = 0x550D,
+ INSUFFICIENT_ZONE_RESOURCES = 0x550E,
+ INSUFFICIENT_ZONE_RESOURCES_TO_COMPLETE_WRITE = 0x550F,
+ MAXIMUM_NUMBER_OF_STREAMS_OPEN = 0x5510,
+ INSUFFICIENT_RESOURCES_TO_BIND = 0x5511,
+
+ SCSI_ASC(UNABLE_TO_RECOVER_TABLE_OF_CONTENTS, 0x57),
+
+ SCSI_ASC(GENERATION_DOES_NOT_EXIST, 0x58),
+
+ SCSI_ASC(UPDATED_BLOCK_READ, 0x59),
+
+ SCSI_ASC(OPERATOR_REQUEST_OR_STATE_CHANGE_INPUT, 0x5A),
+ OPERATOR_MEDIUM_REMOVAL_REQUEST = 0x5A01,
+ OPERATOR_SELECTED_WRITE_PROTECT = 0x5A02,
+ OPERATOR_SELECTED_WRITE_PERMIT = 0x5A03,
+
+ SCSI_ASC(LOG_EXCEPTION, 0x5B),
+ THRESHOLD_CONDITION_MET = 0x5B01,
+ LOG_COUNTER_AT_MAXIMUM = 0x5B02,
+ LOG_LIST_CODES_EXHAUSTED = 0x5B03,
+
+ SCSI_ASC(RPL_STATUS_CHANGE, 0x5C),
+ SPINDLES_SYNCHRONIZED = 0x5C01,
+ SPINDLES_NOT_SYNCHRONIZED = 0x5C02,
+
+ SCSI_ASC(FAILURE_PREDICTION_THRESHOLD_EXCEEDED, 0x5D),
+ MEDIA_FAILURE_PREDICTION_THRESHOLD_EXCEEDED = 0x5D01,
+ LU_FAILURE_PREDICTION_THRESHOLD_EXCEEDED = 0x5D02,
+ SPARE_AREA_EXHAUSTION_PREDICTION_THRESHOLD_EXCEEDED = 0x5D03,
+ HW_IMPENDING_FAILURE_GENERAL_HARD_DRIVE_FAILURE = 0x5D10,
+ HW_IMPENDING_FAILURE_DRIVE_ERROR_RATE_TOO_HIGH = 0x5D11,
+ HW_IMPENDING_FAILURE_DATA_ERROR_RATE_TOO_HIGH = 0x5D12,
+ HW_IMPENDING_FAILURE_SEEK_ERROR_RATE_TOO_HIGH = 0x5D13,
+ HW_IMPENDING_FAILURE_TOO_MANY_BLOCK_REASSIGNS = 0x5D14,
+ HW_IMPENDING_FAILURE_ACCESS_TIMES_TOO_HIGH = 0x5D15,
+ HW_IMPENDING_FAILURE_START_UNIT_TIMES_TOO_HIGH = 0x5D16,
+ HW_IMPENDING_FAILURE_CHANNEL_PARAMETRICS = 0x5D17,
+ HW_IMPENDING_FAILURE_CONTROLLER_DETECTED = 0x5D18,
+ HW_IMPENDING_FAILURE_THROUGHPUT_PERFORMANCE = 0x5D19,
+ HW_IMPENDING_FAILURE_SEEK_TIME_PERFORMANCE = 0x5D1A,
+ HW_IMPENDING_FAILURE_SPINUP_RETRY_COUNT = 0x5D1B,
+ HW_IMPENDING_FAILURE_DRIVE_CALIBRATION_RETRY_COUNT = 0x5D1C,
+ HW_IMPENDING_FAILURE_POWER_LOSS_PROTECTION_CIRCUIT = 0x5D1D,
+ CONTROLLER_IMPENDING_FAILURE_GENERAL_HARD_DRIVE_FAILURE = 0x5D20,
+ CONTROLLER_IMPENDING_FAILURE_DRIVE_ERROR_RATE_TOO_HIGH = 0x5D21,
+ CONTROLLER_IMPENDING_FAILURE_DATA_ERROR_RATE_TOO_HIGH = 0x5D22,
+ CONTROLLER_IMPENDING_FAILURE_SEEK_ERROR_RATE_TOO_HIGH = 0x5D23,
+ CONTROLLER_IMPENDING_FAILURE_TOO_MANY_BLOCK_REASSIGNS = 0x5D24,
+ CONTROLLER_IMPENDING_FAILURE_ACCESS_TIMES_TOO_HIGH = 0x5D25,
+ CONTROLLER_IMPENDING_FAILURE_START_UNIT_TIMES_TOO_HIGH = 0x5D26,
+ CONTROLLER_IMPENDING_FAILURE_CHANNEL_PARAMETRICS = 0x5D27,
+ CONTROLLER_IMPENDING_FAILURE_CONTROLLER_DETECTED = 0x5D28,
+ CONTROLLER_IMPENDING_FAILURE_THROUGHPUT_PERFORMANCE = 0x5D29,
+ CONTROLLER_IMPENDING_FAILURE_SEEK_TIME_PERFORMANCE = 0x5D2A,
+ CONTROLLER_IMPENDING_FAILURE_SPINUP_RETRY_COUNT = 0x5D2B,
+ CONTROLLER_IMPENDING_FAILURE_DRIVE_CALIBRATION_RETRY_COUNT = 0x5D2C,
+ DATA_CHANNEL_IMPENDING_FAILURE_GENERAL_HARD_DRIVE_FAILURE = 0x5D30,
+ DATA_CHANNEL_IMPENDING_FAILURE_DRIVE_ERROR_RATE_TOO_HIGH = 0x5D31,
+ DATA_CHANNEL_IMPENDING_FAILURE_DATA_ERROR_RATE_TOO_HIGH = 0x5D32,
+ DATA_CHANNEL_IMPENDING_FAILURE_SEEK_ERROR_RATE_TOO_HIGH = 0x5D33,
+ DATA_CHANNEL_IMPENDING_FAILURE_TOO_MANY_BLOCK_REASSIGNS = 0x5D34,
+ DATA_CHANNEL_IMPENDING_FAILURE_ACCESS_TIMES_TOO_HIGH = 0x5D35,
+ DATA_CHANNEL_IMPENDING_FAILURE_START_UNIT_TIMES_TOO_HIGH = 0x5D36,
+ DATA_CHANNEL_IMPENDING_FAILURE_CHANNEL_PARAMETRICS = 0x5D37,
+ DATA_CHANNEL_IMPENDING_FAILURE_CONTROLLER_DETECTED = 0x5D38,
+ DATA_CHANNEL_IMPENDING_FAILURE_THROUGHPUT_PERFORMANCE = 0x5D39,
+ DATA_CHANNEL_IMPENDING_FAILURE_SEEK_TIME_PERFORMANCE = 0x5D3A,
+ DATA_CHANNEL_IMPENDING_FAILURE_SPINUP_RETRY_COUNT = 0x5D3B,
+ DATA_CHANNEL_IMPENDING_FAILURE_DRIVE_CALIBRATION_RETRY_COUNT = 0x5D3C,
+ SERVO_IMPENDING_FAILURE_GENERAL_HARD_DRIVE_FAILURE = 0x5D40,
+ SERVO_IMPENDING_FAILURE_DRIVE_ERROR_RATE_TOO_HIGH = 0x5D41,
+ SERVO_IMPENDING_FAILURE_DATA_ERROR_RATE_TOO_HIGH = 0x5D42,
+ SERVO_IMPENDING_FAILURE_SEEK_ERROR_RATE_TOO_HIGH = 0x5D43,
+ SERVO_IMPENDING_FAILURE_TOO_MANY_BLOCK_REASSIGNS = 0x5D44,
+ SERVO_IMPENDING_FAILURE_ACCESS_TIMES_TOO_HIGH = 0x5D45,
+ SERVO_IMPENDING_FAILURE_START_UNIT_TIMES_TOO_HIGH = 0x5D46,
+ SERVO_IMPENDING_FAILURE_CHANNEL_PARAMETRICS = 0x5D47,
+ SERVO_IMPENDING_FAILURE_CONTROLLER_DETECTED = 0x5D48,
+ SERVO_IMPENDING_FAILURE_THROUGHPUT_PERFORMANCE = 0x5D49,
+ SERVO_IMPENDING_FAILURE_SEEK_TIME_PERFORMANCE = 0x5D4A,
+ SERVO_IMPENDING_FAILURE_SPINUP_RETRY_COUNT = 0x5D4B,
+ SERVO_IMPENDING_FAILURE_DRIVE_CALIBRATION_RETRY_COUNT = 0x5D4C,
+ SPINDLE_IMPENDING_FAILURE_GENERAL_HARD_DRIVE_FAILURE = 0x5D50,
+ SPINDLE_IMPENDING_FAILURE_DRIVE_ERROR_RATE_TOO_HIGH = 0x5D51,
+ SPINDLE_IMPENDING_FAILURE_DATA_ERROR_RATE_TOO_HIGH = 0x5D52,
+ SPINDLE_IMPENDING_FAILURE_SEEK_ERROR_RATE_TOO_HIGH = 0x5D53,
+ SPINDLE_IMPENDING_FAILURE_TOO_MANY_BLOCK_REASSIGNS = 0x5D54,
+ SPINDLE_IMPENDING_FAILURE_ACCESS_TIMES_TOO_HIGH = 0x5D55,
+ SPINDLE_IMPENDING_FAILURE_START_UNIT_TIMES_TOO_HIGH = 0x5D56,
+ SPINDLE_IMPENDING_FAILURE_CHANNEL_PARAMETRICS = 0x5D57,
+ SPINDLE_IMPENDING_FAILURE_CONTROLLER_DETECTED = 0x5D58,
+ SPINDLE_IMPENDING_FAILURE_THROUGHPUT_PERFORMANCE = 0x5D59,
+ SPINDLE_IMPENDING_FAILURE_SEEK_TIME_PERFORMANCE = 0x5D5A,
+ SPINDLE_IMPENDING_FAILURE_SPINUP_RETRY_COUNT = 0x5D5B,
+ SPINDLE_IMPENDING_FAILURE_DRIVE_CALIBRATION_RETRY_COUNT = 0x5D5C,
+ FW_IMPENDING_FAILURE_GENERAL_HARD_DRIVE_FAILURE = 0x5D60,
+ FW_IMPENDING_FAILURE_DRIVE_ERROR_RATE_TOO_HIGH = 0x5D61,
+ FW_IMPENDING_FAILURE_DATA_ERROR_RATE_TOO_HIGH = 0x5D62,
+ FW_IMPENDING_FAILURE_SEEK_ERROR_RATE_TOO_HIGH = 0x5D63,
+ FW_IMPENDING_FAILURE_TOO_MANY_BLOCK_REASSIGNS = 0x5D64,
+ FW_IMPENDING_FAILURE_ACCESS_TIMES_TOO_HIGH = 0x5D65,
+ FW_IMPENDING_FAILURE_START_UNIT_TIMES_TOO_HIGH = 0x5D66,
+ FW_IMPENDING_FAILURE_CHANNEL_PARAMETRICS = 0x5D67,
+ FW_IMPENDING_FAILURE_CONTROLLER_DETECTED = 0x5D68,
+ FW_IMPENDING_FAILURE_THROUGHPUT_PERFORMANCE = 0x5D69,
+ FW_IMPENDING_FAILURE_SEEK_TIME_PERFORMANCE = 0x5D6A,
+ FW_IMPENDING_FAILURE_SPINUP_RETRY_COUNT = 0x5D6B,
+ FW_IMPENDING_FAILURE_DRIVE_CALIBRATION_RETRY_COUNT = 0x5D6C,
+ MEDIA_IMPENDING_FAILURE_ENDURANCE_LIMIT_MET = 0x5D73,
+ FAILURE_PREDICTION_THRESHOLD_EXCEEDED_FALSE = 0x5DFF,
+
+ SCSI_ASC(LOW_POWER_CONDITION_ON, 0x5E),
+ IDLE_CONDITION_ACTIVATED_BY_TIMER = 0x5E01,
+ STANDBY_CONDITION_ACTIVATED_BY_TIMER = 0x5E02,
+ IDLE_CONDITION_ACTIVATED_BY_COMMAND = 0x5E03,
+ STANDBY_CONDITION_ACTIVATED_BY_COMMAND = 0x5E04,
+ IDLE_B_CONDITION_ACTIVATED_BY_TIMER = 0x5E05,
+ IDLE_B_CONDITION_ACTIVATED_BY_COMMAND = 0x5E06,
+ IDLE_C_CONDITION_ACTIVATED_BY_TIMER = 0x5E07,
+ IDLE_C_CONDITION_ACTIVATED_BY_COMMAND = 0x5E08,
+ STANDBY_Y_CONDITION_ACTIVATED_BY_TIMER = 0x5E09,
+ STANDBY_Y_CONDITION_ACTIVATED_BY_COMMAND = 0x5E0A,
+ POWER_STATE_CHANGE_TO_ACTIVE = 0x5E41,
+ POWER_STATE_CHANGE_TO_IDLE = 0x5E42,
+ POWER_STATE_CHANGE_TO_STANDBY = 0x5E43,
+ POWER_STATE_CHANGE_TO_SLEEP = 0x5E45,
+ POWER_STATE_CHANGE_TO_DEVICE_CONTROL = 0x5E47,
+
+ SCSI_ASC(LAMP_FAILURE, 0x60),
+
+ SCSI_ASC(VIDEO_ACQUISITION_ERROR, 0x61),
+ UNABLE_TO_ACQUIRE_VIDEO = 0x6101,
+ OUT_OF_FOCUS = 0x6102,
+
+ SCSI_ASC(SCAN_HEAD_POSITIONING_ERROR, 0x62),
+
+ SCSI_ASC(END_OF_USER_AREA_ENCOUNTERED_ON_THIS_TRACK, 0x63),
+ PACKET_DOES_NOT_FIT_IN_AVAILABLE_SPACE = 0x6301,
+
+ SCSI_ASC(ILLEGAL_MODE_FOR_THIS_TRACK, 0x64),
+ INVALID_PACKET_SIZE = 0x6401,
+
+ SCSI_ASC(VOLTAGE_FAULT, 0x65),
+
+ SCSI_ASC(AUTOMATIC_DOCUMENT_FEEDER_COVER_UP, 0x66),
+ AUTOMATIC_DOCUMENT_FEEDER_LIFT_UP = 0x6601,
+ DOCUMENT_JAM_IN_AUTOMATIC_DOCUMENT_FEEDER = 0x6602,
+ DOCUMENT_MISS_FEED_AUTOMATIC_IN_DOCUMENT_FEEDER = 0x6603,
+
+ SCSI_ASC(CONFIG_FAILURE, 0x67),
+ CONFIG_OF_INCAPABLE_LOGICAL_UNITS_FAILED = 0x6701,
+ ADD_LU_FAILED = 0x6702,
+ MODIFICATION_OF_LU_FAILED = 0x6703,
+ EXCHANGE_OF_LU_FAILED = 0x6704,
+ REMOVE_OF_LU_FAILED = 0x6705,
+ ATTACHMENT_OF_LU_FAILED = 0x6706,
+ CREATION_OF_LU_FAILED = 0x6707,
+ ASSIGN_FAILURE_OCCURRED = 0x6708,
+ MULTIPLY_ASSIGNED_LOGICAL_UNIT = 0x6709,
+ SET_TARGET_PORT_GROUPS_COMMAND_FAILED = 0x670A,
+ ATA_DEVICE_FEATURE_NOT_ENABLED = 0x670B,
+ COMMAND_REJECTED = 0x670C,
+ EXPLICIT_BIND_NOT_ALLOWED = 0x670D,
+ FEATURE_NOT_ENABLED = 0x670E,
+
+ SCSI_ASC(LU_NOT_CONFIGURED, 0x68),
+ SUBSIDIARY_LU_NOT_CONFIGURED = 0x6801,
+
+ SCSI_ASC(DATA_LOSS_ON_LOGICAL_UNIT, 0x69),
+ MULTIPLE_LU_FAILURES = 0x6901,
+ PARITY_DATA_MISMATCH = 0x6902,
+
+ SCSI_ASC(INFORMATIONAL_REFER_TO_LOG, 0x6A),
+
+ SCSI_ASC(STATE_CHANGE_HAS_OCCURRED, 0x6B),
+ REDUNDANCY_LEVEL_GOT_BETTER = 0x6B01,
+ REDUNDANCY_LEVEL_GOT_WORSE = 0x6B02,
+
+ SCSI_ASC(REBUILD_FAILURE_OCCURRED, 0x6C),
+
+ SCSI_ASC(RECALCULATE_FAILURE_OCCURRED, 0x6D),
+
+ SCSI_ASC(COMMAND_TO_LU_FAILED, 0x6E),
+
+ SCSI_ASC(COPY_PROTECTION_KEY_EXCHANGE_FAILURE_AUTHENTICATION_FAILURE, 0x6F),
+ COPY_PROTECTION_KEY_EXCHANGE_FAILURE_KEY_NOT_PRESENT = 0x6F01,
+ COPY_PROTECTION_KEY_EXCHANGE_FAILURE_KEY_NOT_ESTABLISHED = 0x6F02,
+ READ_OF_SCRAMBLED_SECTOR_WITHOUT_AUTHENTICATION = 0x6F03,
+ MEDIA_REGION_CODE_IS_MISMATCHED_TO_LU_REGION = 0x6F04,
+ DRIVE_REGION_MUST_BE_PERMANENT_REGION_RESET_COUNT_ERROR = 0x6F05,
+ INSUFFICIENT_BLOCK_COUNT_FOR_BINDING_NONCE_RECORDING = 0x6F06,
+ CONFLICT_IN_BINDING_NONCE_RECORDING = 0x6F07,
+ INSUFFICIENT_PERMISSION = 0x6F08,
+ INVALID_DRIVE_HOST_PAIRING_SERVER = 0x6F09,
+ DRIVE_HOST_PAIRING_SUSPENDED = 0x6F0A,
+
+ SCSI_ASC(DECOMPRESSION_EXCEPTION_SHORT_ALGORITHM_ID, 0x70),
+
+ SCSI_ASC(DECOMPRESSION_EXCEPTION_LONG_ALGORITHM_ID, 0x71),
+
+ SCSI_ASC(SESSION_FIXATION_ERROR, 0x72),
+ SESSION_FIXATION_ERROR_WRITING_LEAD_IN = 0x7201,
+ SESSION_FIXATION_ERROR_WRITING_LEAD_OUT = 0x7202,
+ SESSION_FIXATION_ERROR_INCOMPLETE_TRACK_IN_SESSION = 0x7203,
+ EMPTY_OR_PARTIALLY_WRITTEN_RESERVED_TRACK = 0x7204,
+ NO_MORE_TRACK_RESERVATIONS_ALLOWED = 0x7205,
+ RMZ_EXTENSION_IS_NOT_ALLOWED = 0x7206,
+ NO_MORE_TEST_ZONE_EXTENSIONS_ARE_ALLOWED = 0x7207,
+
+ SCSI_ASC(CD_CONTROL_ERROR, 0x73),
+ POWER_CALIBRATION_AREA_ALMOST_FULL = 0x7301,
+ POWER_CALIBRATION_AREA_IS_FULL = 0x7302,
+ POWER_CALIBRATION_AREA_ERROR = 0x7303,
+ PROGRAM_MEMORY_AREA_UPDATE_FAILURE = 0x7304,
+ PROGRAM_MEMORY_AREA_IS_FULL = 0x7305,
+ RMA_PMA_IS_ALMOST_FULL = 0x7306,
+ CURRENT_POWER_CALIBRATION_AREA_ALMOST_FULL = 0x7310,
+ CURRENT_POWER_CALIBRATION_AREA_IS_FULL = 0x7311,
+ RDZ_IS_FULL = 0x7317,
+
+ SCSI_ASC(SECURITY_ERROR, 0x74),
+ UNABLE_TO_DECRYPT_DATA = 0x7401,
+ UNENCRYPTED_DATA_ENCOUNTERED_WHILE_DECRYPTING = 0x7402,
+ INCORRECT_DATA_ENCRYPTION_KEY = 0x7403,
+ CRYPTOGRAPHIC_INTEGRITY_VALIDATION_FAILED = 0x7404,
+ ERROR_DECRYPTING_DATA = 0x7405,
+ UNKNOWN_SIGNATURE_VERIFICATION_KEY = 0x7406,
+ ENCRYPTION_PARAMS_NOT_USEABLE = 0x7407,
+ DIGITAL_SIGNATURE_VALIDATION_FAILURE = 0x7408,
+ ENCRYPTION_MODE_MISMATCH_ON_READ = 0x7409,
+ ENCRYPTED_BLOCK_NOT_RAW_READ_ENABLED = 0x740A,
+ INCORRECT_ENCRYPTION_PARAMS = 0x740B,
+ UNABLE_TO_DECRYPT_PARAMETER_LIST = 0x740C,
+ ENCRYPTION_ALGORITHM_DISABLED = 0x740D,
+ SA_CREATION_PARAMETER_VALUE_INVALID = 0x7410,
+ SA_CREATION_PARAMETER_VALUE_REJECTED = 0x7411,
+ INVALID_SA_USAGE = 0x7412,
+ DATA_ENCRYPTION_CONFIG_PREVENTED = 0x7421,
+ SA_CREATION_PARAMETER_NOT_SUPPORTED = 0x7430,
+ AUTHENTICATION_FAILED = 0x7440,
+ EXTERNAL_DATA_ENCRYPTION_KEY_MANAGER_ACCESS_ERROR = 0x7461,
+ EXTERNAL_DATA_ENCRYPTION_KEY_MANAGER_ERROR = 0x7462,
+ EXTERNAL_DATA_ENCRYPTION_KEY_NOT_FOUND = 0x7463,
+ EXTERNAL_DATA_ENCRYPTION_REQUEST_NOT_AUTHORIZED = 0x7464,
+ EXTERNAL_DATA_ENCRYPTION_CONTROL_TIMEOUT = 0x746E,
+ EXTERNAL_DATA_ENCRYPTION_CONTROL_ERROR = 0x746F,
+ LU_ACCESS_NOT_AUTHORIZED = 0x7471,
+ SECURITY_CONFLICT_IN_TRANSLATED_DEVICE = 0x7479,
+};
+
+#undef SCSI_ASC_DEF
+#undef SCSI_ASC
+
+/*
+ * Use this to build non-standard sense codes.
+ * Note: this is defined as a macro instead of an inline function so that it can
+ * be used to define SCSI failures array variables (see struct scsi_failure).
+ */
+#define scsi_sense_code(asc, ascq) \
+ ((((asc) & 0xff) << 8) | ((ascq) & 0xff))
+
+static inline u8 scsi_sense_code_asc(u16 code)
+{
+ return (code >> 8) & 0xff;
+}
+
+static inline u8 scsi_sense_code_ascq(u16 code)
+{
+ return code & 0xff;
+}
+
+#endif /* _SCSI_SENSE_H_ */
diff --git a/include/soc/fsl/qe/qe.h b/include/soc/fsl/qe/qe.h
index 8f967d15e479..7f0e4165c3b0 100644
--- a/include/soc/fsl/qe/qe.h
+++ b/include/soc/fsl/qe/qe.h
@@ -24,6 +24,7 @@
#include <linux/types.h>
struct device;
+struct gpio_desc;
#define QE_NUM_OF_SNUM 256 /* There are 256 serial number in QE */
#define QE_NUM_OF_BRGS 16
@@ -193,12 +194,13 @@ static inline int par_io_data_set(u8 port, u8 pin, u8 val) { return -ENOSYS; }
*/
struct qe_pin;
#ifdef CONFIG_QE_GPIO
-extern struct qe_pin *qe_pin_request(struct device *dev, int index);
+extern struct qe_pin *qe_pin_request(struct device *dev, struct gpio_desc *gpiod);
extern void qe_pin_free(struct qe_pin *qe_pin);
extern void qe_pin_set_gpio(struct qe_pin *qe_pin);
extern void qe_pin_set_dedicated(struct qe_pin *pin);
#else
-static inline struct qe_pin *qe_pin_request(struct device *dev, int index)
+static inline struct qe_pin *
+qe_pin_request(struct device *dev, struct gpio_desc *gpiod)
{
return ERR_PTR(-ENOSYS);
}
diff --git a/include/soc/imx/cpu.h b/include/soc/imx/cpu.h
index 0bf610acafd0..8c53150acd76 100644
--- a/include/soc/imx/cpu.h
+++ b/include/soc/imx/cpu.h
@@ -30,7 +30,7 @@
#define MXC_CPU_VF600 0x600
#define MXC_CPU_VF610 (MXC_CPU_VF600 | MXC_CPU_VFx10)
-#ifndef __ASSEMBLY__
+#ifndef __ASSEMBLER__
extern unsigned int __mxc_cpu_type;
#endif
diff --git a/include/soc/tegra/fuse.h b/include/soc/tegra/fuse.h
index c4f7a1b97c54..14822f981fec 100644
--- a/include/soc/tegra/fuse.h
+++ b/include/soc/tegra/fuse.h
@@ -33,6 +33,7 @@ enum tegra_revision {
TEGRA_REVISION_A03,
TEGRA_REVISION_A03p,
TEGRA_REVISION_A04,
+ TEGRA_REVISION_B01,
TEGRA_REVISION_MAX,
};
diff --git a/include/sound/aw88399.h b/include/sound/aw88399.h
index a1e0de6be8ea..d72c491ee866 100644
--- a/include/sound/aw88399.h
+++ b/include/sound/aw88399.h
@@ -449,6 +449,11 @@
#define AW88399_NOISE_GATE_EN_MASK \
(~(((1<<AW88399_NOISE_GATE_EN_BITS_LEN)-1) << AW88399_NOISE_GATE_EN_START_BIT))
+#define AW88399_EPS_EN_START_BIT (2)
+#define AW88399_EPS_EN_BITS_LEN (1)
+#define AW88399_EPS_EN_MASK \
+ (~(((1 << AW88399_EPS_EN_BITS_LEN) - 1) << AW88399_EPS_EN_START_BIT))
+
#define AW88399_WDT_CNT_START_BIT (0)
#define AW88399_WDT_CNT_BITS_LEN (8)
#define AW88399_WDT_CNT_MASK \
@@ -598,7 +603,6 @@ struct aw88399 {
unsigned int crc_init_val;
unsigned int vcalb_init_val;
unsigned int dither_st;
- bool bsts_unreliable;
bool fw_needs_reload;
};
@@ -613,7 +617,7 @@ void aw88399_dev_set_channel(struct aw88399 *aw88399, int channel);
void aw88399_hw_reset(struct aw88399 *aw88399);
int aw88399_init(struct aw88399 *aw88399, struct i2c_client *i2c, struct regmap *regmap);
extern const struct regmap_config aw88399_remap_config;
-int aw88399_request_firmware_file(struct aw88399 *aw88399);
+int aw88399_request_firmware_file(struct aw88399 *aw88399, const char *fw_name);
void aw88399_start(struct aw88399 *aw88399, bool sync_start);
void aw88399_startup_work(struct work_struct *work);
int aw88399_stop(struct aw_device *aw_dev);
diff --git a/include/sound/compress_driver.h b/include/sound/compress_driver.h
index 9e3d801e45ec..84f51edc3f9d 100644
--- a/include/sound/compress_driver.h
+++ b/include/sound/compress_driver.h
@@ -188,6 +188,7 @@ struct snd_compr_ops {
* @card: sound card pointer
* @direction: Playback or capture direction
* @lock: device lock
+ * @open_list: list of open compress files
* @device: device id
* @use_pause_in_draining: allow pause in draining, true when set
*/
@@ -199,6 +200,7 @@ struct snd_compr {
struct snd_card *card;
unsigned int direction;
struct mutex lock;
+ struct list_head open_list;
int device;
bool use_pause_in_draining;
#ifdef CONFIG_SND_VERBOSE_PROCFS
diff --git a/include/sound/control.h b/include/sound/control.h
index 909db0d0485d..8e24b668d796 100644
--- a/include/sound/control.h
+++ b/include/sound/control.h
@@ -244,7 +244,7 @@ int _snd_ctl_add_follower(struct snd_kcontrol *master,
* @follower: follower element to add
*
* Add a virtual follower control to the given master element created via
- * snd_ctl_create_virtual_master() beforehand.
+ * snd_ctl_make_virtual_master() beforehand.
*
* All followers must be the same type (returning the same information
* via info callback). The function doesn't check it, so it's your
@@ -289,7 +289,7 @@ snd_ctl_add_follower_uncached(struct snd_kcontrol *master,
return _snd_ctl_add_follower(master, follower, SND_CTL_FOLLOWER_NEED_UPDATE);
}
-int snd_ctl_add_vmaster_hook(struct snd_kcontrol *kctl,
+int snd_ctl_add_vmaster_hook(struct snd_card *card, struct snd_kcontrol *kctl,
void (*hook)(void *private_data, int),
void *private_data);
void snd_ctl_sync_vmaster(struct snd_kcontrol *kctl, bool hook_only);
diff --git a/include/sound/core.h b/include/sound/core.h
index 2ca24ac7e37f..d6584967fd49 100644
--- a/include/sound/core.h
+++ b/include/sound/core.h
@@ -84,6 +84,7 @@ struct snd_device {
struct snd_refcount {
atomic_t count;
wait_queue_head_t waiter;
+ spinlock_t lock;
};
void snd_refcount_init(struct snd_refcount *ref);
@@ -300,7 +301,8 @@ int snd_card_locked(int card);
#define SND_MIXER_OSS_NOTIFY_REGISTER 0
#define SND_MIXER_OSS_NOTIFY_DISCONNECT 1
#define SND_MIXER_OSS_NOTIFY_FREE 2
-extern int (*snd_mixer_oss_notify_callback)(struct snd_card *card, int cmd);
+void snd_mixer_oss_set_notify(int (*callback)(struct snd_card *card, int cmd));
+void snd_mixer_oss_notify(struct snd_card *card, int cmd);
#endif
int snd_card_new(struct device *parent, int idx, const char *xid,
@@ -314,7 +316,6 @@ void snd_card_disconnect(struct snd_card *card);
void snd_card_disconnect_sync(struct snd_card *card);
void snd_card_free(struct snd_card *card);
void snd_card_free_when_closed(struct snd_card *card);
-int snd_card_free_on_error(struct device *dev, int ret);
void snd_card_set_id(struct snd_card *card, const char *id);
int snd_card_register(struct snd_card *card);
int snd_card_info_init(void);
@@ -340,6 +341,15 @@ static inline void snd_card_unref(struct snd_card *card)
DEFINE_FREE(snd_card_unref, struct snd_card *, if (_T) snd_card_unref(_T))
+/*
+ * For automatic error handling at probe time, assign the card like:
+ * struct snd_card *card __free(snd_card_free) = NULL;
+ * then create and process as usual.
+ * But, don't forget to clear to NULL at successful return for avoiding
+ * the unexpected cleanup!
+ */
+DEFINE_FREE(snd_card_free, struct snd_card *, if (_T) snd_card_free(_T))
+
#define snd_card_set_dev(card, devptr) ((card)->dev = (devptr))
/* device.c */
diff --git a/include/sound/cs35l56.h b/include/sound/cs35l56.h
index 45a5df574aa6..747e10ec1a27 100644
--- a/include/sound/cs35l56.h
+++ b/include/sound/cs35l56.h
@@ -312,6 +312,7 @@ struct snd_ctl_elem_value;
#define CS35L56_SDW1_PLAYBACK_PORT 1
#define CS35L56_SDW1_CAPTURE_PORT 3
+#define CS35L56_OT25_CAPTURE_PORT 4
#define CS35L56_NUM_BULK_SUPPLIES 3
#define CS35L56_NUM_DSP_REGIONS 5
diff --git a/include/sound/emu10k1.h b/include/sound/emu10k1.h
index 4f94565c9d15..6474239a11c1 100644
--- a/include/sound/emu10k1.h
+++ b/include/sound/emu10k1.h
@@ -633,8 +633,8 @@ SUB_REG(PEFE, FILTERAMOUNT, 0x000000ff) /* Filter envlope amount */
#define A_ADCCR_RCHANENABLE 0x00000020
#define A_ADCCR_LCHANENABLE 0x00000010
-#define A_ADCCR_SAMPLERATE_MASK 0x0000000F /* Audigy sample rate convertor output rate */
-#define ADCCR_SAMPLERATE_MASK 0x00000007 /* Sample rate convertor output rate */
+#define A_ADCCR_SAMPLERATE_MASK 0x0000000F /* Audigy sample rate converter output rate */
+#define ADCCR_SAMPLERATE_MASK 0x00000007 /* Sample rate converter output rate */
#define ADCCR_SAMPLERATE_48 0x00000000 /* 48kHz sample rate */
#define ADCCR_SAMPLERATE_44 0x00000001 /* 44.1kHz sample rate */
#define ADCCR_SAMPLERATE_32 0x00000002 /* 32kHz sample rate */
diff --git a/include/sound/emux_legacy.h b/include/sound/emux_legacy.h
index 1127e30d33bb..55a7fbfb9bfa 100644
--- a/include/sound/emux_legacy.h
+++ b/include/sound/emux_legacy.h
@@ -5,7 +5,7 @@
/*
* Copyright (c) 1999-2000 Takashi Iwai <tiwai@suse.de>
*
- * Definitions of OSS compatible headers for Emu8000 device informations
+ * Definitions of OSS compatible headers for Emu8000 device information
*/
#include <sound/seq_oss_legacy.h>
diff --git a/include/sound/hda_codec.h b/include/sound/hda_codec.h
index 1d05f991f2ce..c7f29ad64e02 100644
--- a/include/sound/hda_codec.h
+++ b/include/sound/hda_codec.h
@@ -28,6 +28,7 @@ struct hda_codec;
struct hda_pcm;
struct hda_pcm_stream;
struct hda_codec_ops;
+struct hda_jack_tbl;
/*
* codec bus
@@ -274,7 +275,8 @@ struct hda_codec {
struct hda_codec *codec, hda_nid_t nid);
/* jack detection */
- struct snd_array jacktbl;
+ struct hda_jack_tbl *jacktbl, *jacktbl_last; /* linked list head/tail */
+ int jacktbl_used; /* number of jacktbl elements */
unsigned long jackpoll_interval; /* In jiffies. Zero means no poll, rely on unsol events */
struct delayed_work jackpoll_work;
@@ -519,7 +521,7 @@ void snd_hda_update_power_acct(struct hda_codec *codec);
static inline bool hda_codec_need_resume(struct hda_codec *codec)
{
- return !codec->relaxed_resume && codec->jacktbl.used;
+ return !codec->relaxed_resume && codec->jacktbl_used;
}
/*
diff --git a/include/sound/hdaudio.h b/include/sound/hdaudio.h
index aa994d6e6d35..04fd4794bcee 100644
--- a/include/sound/hdaudio.h
+++ b/include/sound/hdaudio.h
@@ -96,7 +96,8 @@ struct hdac_device {
bool lazy_cache:1; /* don't wake up for writes */
bool caps_overwriting:1; /* caps overwrite being in process */
bool cache_coef:1; /* cache COEF read/write too */
- unsigned int registered:1; /* codec was registered */
+ bool registered; /* codec was registered */
+ bool unsol_disabled; /* unsol events blocked; protected by bus->reg_lock */
};
/* device/driver type used for matching */
@@ -123,6 +124,7 @@ int snd_hdac_device_init(struct hdac_device *dev, struct hdac_bus *bus,
const char *name, unsigned int addr);
void snd_hdac_device_exit(struct hdac_device *dev);
int snd_hdac_device_register(struct hdac_device *codec);
+void snd_hdac_device_disable_unsol(struct hdac_device *codec);
void snd_hdac_device_unregister(struct hdac_device *codec);
int snd_hdac_device_set_chip_name(struct hdac_device *codec, const char *name);
int snd_hdac_codec_modalias(const struct hdac_device *hdac, char *buf, size_t size);
@@ -179,9 +181,9 @@ static inline int snd_hdac_read_parm(struct hdac_device *codec, hda_nid_t nid,
#ifdef CONFIG_PM
int snd_hdac_power_up(struct hdac_device *codec);
-int snd_hdac_power_down(struct hdac_device *codec);
+void snd_hdac_power_down(struct hdac_device *codec);
int snd_hdac_power_up_pm(struct hdac_device *codec);
-int snd_hdac_power_down_pm(struct hdac_device *codec);
+void snd_hdac_power_down_pm(struct hdac_device *codec);
int snd_hdac_keep_power_up(struct hdac_device *codec);
/* call this at entering into suspend/resume callbacks in codec driver */
@@ -207,9 +209,9 @@ static inline bool snd_hdac_is_power_on(struct hdac_device *codec)
}
#else
static inline int snd_hdac_power_up(struct hdac_device *codec) { return 0; }
-static inline int snd_hdac_power_down(struct hdac_device *codec) { return 0; }
+static inline void snd_hdac_power_down(struct hdac_device *codec) {}
static inline int snd_hdac_power_up_pm(struct hdac_device *codec) { return 0; }
-static inline int snd_hdac_power_down_pm(struct hdac_device *codec) { return 0; }
+static inline void snd_hdac_power_down_pm(struct hdac_device *codec) {}
static inline int snd_hdac_keep_power_up(struct hdac_device *codec) { return 0; }
static inline void snd_hdac_enter_pm(struct hdac_device *codec) {}
static inline void snd_hdac_leave_pm(struct hdac_device *codec) {}
diff --git a/include/sound/jack.h b/include/sound/jack.h
index 715b95983188..cf19c333e2eb 100644
--- a/include/sound/jack.h
+++ b/include/sound/jack.h
@@ -62,10 +62,10 @@ struct snd_jack {
struct list_head kctl_list;
struct snd_card *card;
const char *id;
+ bool registered;
#ifdef CONFIG_SND_JACK_INPUT_DEV
struct input_dev *input_dev;
struct mutex input_dev_lock;
- int registered;
int type;
char name[100];
unsigned int key[6]; /* Keep in sync with definitions above */
diff --git a/include/sound/omap-hdmi-audio.h b/include/sound/omap-hdmi-audio.h
index e5f82044a404..8dca92360ee0 100644
--- a/include/sound/omap-hdmi-audio.h
+++ b/include/sound/omap-hdmi-audio.h
@@ -34,6 +34,7 @@ struct omap_hdmi_audio_pdata {
phys_addr_t audio_dma_addr;
const struct omap_hdmi_audio_ops *ops;
+ void (*audio_hpd)(struct device *dev, bool connected);
};
#endif /* __OMAP_HDMI_AUDIO_H__ */
diff --git a/include/sound/pcm.h b/include/sound/pcm.h
index 02d8689354c4..1cf511f8d880 100644
--- a/include/sound/pcm.h
+++ b/include/sound/pcm.h
@@ -8,6 +8,7 @@
* Abramo Bagnara <abramo@alsa-project.org>
*/
+#include <sound/core.h>
#include <sound/asound.h>
#include <sound/memalloc.h>
#include <sound/minors.h>
@@ -414,6 +415,7 @@ struct snd_pcm_runtime {
snd_pcm_uframes_t twake; /* do transfer (!poll) wakeup if non-zero */
wait_queue_head_t sleep; /* poll sleep */
wait_queue_head_t tsleep; /* transfer sleep */
+ struct snd_refcount refcnt; /* refcount for draining, etc */
struct snd_fasync *fasync;
bool stop_operating; /* sync_stop will be called */
struct mutex buffer_mutex; /* protect for buffer changes */
diff --git a/include/sound/pcm_oss.h b/include/sound/pcm_oss.h
index c96f23c7755b..43f765300031 100644
--- a/include/sound/pcm_oss.h
+++ b/include/sound/pcm_oss.h
@@ -70,6 +70,7 @@ struct snd_pcm_oss_stream {
struct snd_pcm_oss {
int reg;
unsigned int reg_mask;
+ bool registered;
};
#endif /* __SOUND_PCM_OSS_H */
diff --git a/include/sound/rawmidi.h b/include/sound/rawmidi.h
index 4154035af414..d812f70725bd 100644
--- a/include/sound/rawmidi.h
+++ b/include/sound/rawmidi.h
@@ -86,6 +86,7 @@ struct snd_rawmidi_substream {
bool opened; /* open flag */
bool append; /* append flag (merge more streams) */
bool active_sensing; /* send active sensing when close */
+ bool disconnected; /* already disconnected */
unsigned int framing; /* whether to frame input data */
unsigned int clock_type; /* clock source to use for input framing */
int use_count; /* use counter (for output) */
diff --git a/include/sound/sdca.h b/include/sound/sdca.h
index 2bdf4e333e04..db2672b3aae2 100644
--- a/include/sound/sdca.h
+++ b/include/sound/sdca.h
@@ -60,20 +60,16 @@ enum sdca_quirk {
SDCA_QUIRKS_SKIP_FUNC_TYPE_PATCHING,
};
-#if IS_ENABLED(CONFIG_ACPI) && IS_ENABLED(CONFIG_SND_SOC_SDCA)
+#if IS_ENABLED(CONFIG_SND_SOC_SDCA)
-void sdca_lookup_functions(struct sdw_slave *slave);
void sdca_lookup_swft(struct sdw_slave *slave);
-void sdca_lookup_interface_revision(struct sdw_slave *slave);
bool sdca_device_quirk_match(struct sdw_slave *slave, enum sdca_quirk quirk);
int sdca_dev_register_functions(struct sdw_slave *slave);
void sdca_dev_unregister_functions(struct sdw_slave *slave);
#else
-static inline void sdca_lookup_functions(struct sdw_slave *slave) {}
static inline void sdca_lookup_swft(struct sdw_slave *slave) {}
-static inline void sdca_lookup_interface_revision(struct sdw_slave *slave) {}
static inline bool sdca_device_quirk_match(struct sdw_slave *slave, enum sdca_quirk quirk)
{
return false;
@@ -88,4 +84,21 @@ static inline void sdca_dev_unregister_functions(struct sdw_slave *slave) {}
#endif
+/*
+ * Called from the SoundWire bus during peripheral enumeration; gated on
+ * ACPI to avoid a soundwire_bus <-> snd_soc_sdca module cycle on DT builds
+ * (where the bodies are stubs anyway).
+ */
+#if IS_ENABLED(CONFIG_ACPI) && IS_ENABLED(CONFIG_SND_SOC_SDCA)
+
+void sdca_lookup_functions(struct sdw_slave *slave);
+void sdca_lookup_interface_revision(struct sdw_slave *slave);
+
+#else
+
+static inline void sdca_lookup_functions(struct sdw_slave *slave) {}
+static inline void sdca_lookup_interface_revision(struct sdw_slave *slave) {}
+
+#endif
+
#endif
diff --git a/include/sound/sdca_class.h b/include/sound/sdca_class.h
new file mode 100644
index 000000000000..794a756472cd
--- /dev/null
+++ b/include/sound/sdca_class.h
@@ -0,0 +1,70 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * The MIPI SDCA specification is available for public downloads at
+ * https://www.mipi.org/mipi-sdca-v1-0-download
+ *
+ * Copyright (C) 2025 Cirrus Logic, Inc. and
+ * Cirrus Logic International Semiconductor Ltd.
+ */
+
+#ifndef __SDCA_CLASS_H__
+#define __SDCA_CLASS_H__
+
+#include <linux/completion.h>
+#include <linux/mutex.h>
+#include <linux/workqueue.h>
+
+struct device;
+struct regmap;
+struct sdw_slave;
+struct sdca_function_data;
+
+/**
+ * struct sdca_class_ops - optional codec-provided class callbacks
+ * @populate_function: fill @function (entities, clusters, init_table, ...)
+ * from static tables in place of sdca_parse_function() on
+ * DT/non-DisCo platforms. Called once per SDCA function with
+ * @dev pointing at that function's device. Pure data source;
+ * performs no bus I/O. Return 0 on success or a negative errno.
+ */
+struct sdca_class_ops {
+ int (*populate_function)(struct device *dev,
+ struct sdca_function_data *function);
+};
+
+struct sdca_class_drv {
+ struct device *dev;
+ struct regmap *dev_regmap;
+ struct sdw_slave *sdw;
+
+ struct sdca_interrupt_info *irq_info;
+
+ const struct sdca_class_ops *ops;
+
+ struct mutex regmap_lock;
+ /* Serialise function initialisations */
+ struct mutex init_lock;
+ struct work_struct boot_work;
+};
+
+/* Library helpers used by codec-specific SDCA SoundWire drivers. */
+int sdca_class_probe(struct sdw_slave *sdw,
+ struct sdca_class_drv *drv,
+ const struct sdca_class_ops *ops);
+void sdca_class_remove(struct sdca_class_drv *drv);
+
+/*
+ * PM helpers. Codec drivers embed sdca_class_drv in their own priv,
+ * own dev_set_drvdata(), and compose these into their own dev_pm_ops:
+ *
+ * static int wcd_runtime_suspend(struct device *dev) {
+ * struct wcd_priv *priv = dev_get_drvdata(dev);
+ * return sdca_class_runtime_suspend(&priv->class);
+ * }
+ */
+int sdca_class_runtime_suspend(struct sdca_class_drv *drv);
+int sdca_class_runtime_resume(struct sdca_class_drv *drv);
+int sdca_class_system_suspend(struct sdca_class_drv *drv);
+int sdca_class_system_resume(struct sdca_class_drv *drv);
+
+#endif /* __SDCA_CLASS_H__ */
diff --git a/include/sound/simple_card_utils.h b/include/sound/simple_card_utils.h
index bd8c3a033577..68faec56970e 100644
--- a/include/sound/simple_card_utils.h
+++ b/include/sound/simple_card_utils.h
@@ -219,12 +219,14 @@ static inline int simple_util_parse_aux_devs(struct simple_util_priv *priv, char
int simple_util_init_jack(struct snd_soc_card *card,
struct simple_util_jack *sjack,
int is_hp, char *prefix, char *pin);
+void simple_util_remove_jack(struct simple_util_jack *sjack);
int simple_util_init_aux_jacks(struct snd_soc_card *card, char *prefix);
int simple_util_init_priv(struct simple_util_priv *priv,
struct link_info *li);
void simple_util_remove(struct platform_device *pdev);
int graph_util_card_probe(struct snd_soc_card *card);
+int graph_util_card_remove(struct snd_soc_card *card);
int graph_util_is_ports0(struct device_node *port);
int graph_util_parse_dai(struct simple_util_priv *priv, struct device_node *ep,
struct snd_soc_dai_link_component *dlc, int *is_single_link);
diff --git a/include/sound/soc-component.h b/include/sound/soc-component.h
index c49b59630101..73d66c976694 100644
--- a/include/sound/soc-component.h
+++ b/include/sound/soc-component.h
@@ -154,6 +154,8 @@ struct snd_soc_component_driver {
struct snd_pcm_substream *substream);
snd_pcm_sframes_t (*delay)(struct snd_soc_component *component,
struct snd_pcm_substream *substream);
+ int (*be_hw_params_fixup)(struct snd_soc_pcm_runtime *rtd,
+ struct snd_pcm_hw_params *params);
const struct snd_compress_ops *compress_ops;
@@ -194,12 +196,13 @@ struct snd_soc_component_driver {
unsigned int endianness:1;
unsigned int legacy_dai_naming:1;
+ /* use DAI link PCM ID as PCM device number */
+ unsigned int use_dai_pcm_id:1;
+
/* this component uses topology and ignore machine driver FEs */
const char *ignore_machine;
const char *topology_name_prefix;
- int (*be_hw_params_fixup)(struct snd_soc_pcm_runtime *rtd,
- struct snd_pcm_hw_params *params);
- bool use_dai_pcm_id; /* use DAI link PCM ID as PCM device number */
+
int be_pcm_base; /* base device ID for all BE PCMs */
const char *debugfs_prefix;
@@ -258,37 +261,24 @@ struct snd_soc_component {
void *priv;
};
-#define for_each_component_dais(component, dai)\
- list_for_each_entry(dai, &(component)->dai_list, list)
-#define for_each_component_dais_safe(component, dai, _dai)\
- list_for_each_entry_safe(dai, _dai, &(component)->dai_list, list)
+#define for_each_component_dais(component, dai) \
+ for (dai = snd_soc_dai_from_list((component)->dai_list.next); \
+ snd_soc_dai_to_list(dai) != &(component)->dai_list; \
+ dai = snd_soc_dai_from_list(snd_soc_dai_to_list(dai)->next))
-/**
- * snd_soc_component_to_dapm() - Returns the DAPM context associated with a
- * component
- * @component: The component for which to get the DAPM context
- */
-static inline struct snd_soc_dapm_context *snd_soc_component_to_dapm(
- struct snd_soc_component *component)
-{
- return component->dapm;
-}
+#define for_each_component_dais_safe(component, dai, _dai) \
+ for (dai = snd_soc_dai_from_list((component)->dai_list.next), \
+ _dai = snd_soc_dai_from_list(snd_soc_dai_to_list(dai)->next); \
+ snd_soc_dai_to_list(dai) != &(component)->dai_list; \
+ dai = _dai, _dai = snd_soc_dai_from_list(snd_soc_dai_to_list(_dai)->next))
-/**
- * snd_soc_component_cache_sync() - Sync the register cache with the hardware
- * @component: COMPONENT to sync
- *
- * Note: This function will call regcache_sync()
- */
-static inline int snd_soc_component_cache_sync(
- struct snd_soc_component *component)
-{
- return regcache_sync(component->regmap);
-}
-
-struct snd_soc_component *snd_soc_component_alloc(struct device *dev);
+struct snd_soc_dapm_context *snd_soc_component_to_dapm(struct snd_soc_component *component);
+struct snd_soc_component *snd_soc_component_new(struct device *dev, const char *name,
+ const struct snd_soc_component_driver *driver);
+int snd_soc_component_register(struct snd_soc_component *component,
+ struct snd_soc_dai_driver *dai_drv,
+ int num_dai);
-void snd_soc_component_set_name(struct snd_soc_component *component, const char *name);
const char *snd_soc_component_name(struct snd_soc_component *component);
void snd_soc_component_set_priv(struct snd_soc_component *component, void *priv);
@@ -299,6 +289,11 @@ void snd_soc_component_set_aux(struct snd_soc_component *component,
int snd_soc_component_init(struct snd_soc_component *component);
int snd_soc_component_is_dummy(struct snd_soc_component *component);
+struct snd_soc_component *snd_soc_component_lookup_nolock(struct device *dev,
+ const char *driver_name);
+struct snd_soc_component *snd_soc_component_lookup(struct device *dev, const char *driver_name);
+struct snd_soc_component *snd_soc_component_lookup_by_name(const char *component_name);
+
/* component IO */
unsigned int snd_soc_component_read(struct snd_soc_component *component,
unsigned int reg);
@@ -310,7 +305,6 @@ int snd_soc_component_update_bits(struct snd_soc_component *component,
int snd_soc_component_update_bits_async(struct snd_soc_component *component,
unsigned int reg, unsigned int mask,
unsigned int val);
-void snd_soc_component_async_complete(struct snd_soc_component *component);
int snd_soc_component_test_bits(struct snd_soc_component *component,
unsigned int reg, unsigned int mask,
unsigned int value);
@@ -340,12 +334,18 @@ int snd_soc_component_set_bias_level(struct snd_soc_component *component,
enum snd_soc_bias_level level);
int snd_soc_component_regmap_val_bytes(struct snd_soc_component *component);
+int snd_soc_component_regmap_cache_sync(struct snd_soc_component *component);
+void snd_soc_component_regmap_async_complete(struct snd_soc_component *component);
#ifdef CONFIG_REGMAP
void snd_soc_component_init_regmap(struct snd_soc_component *component,
struct regmap *regmap);
void snd_soc_component_exit_regmap(struct snd_soc_component *component);
#endif
+int snd_soc_component_fixup_controls(struct snd_soc_component *component);
+int snd_soc_component_add_controls(struct snd_soc_component *component,
+ const struct snd_kcontrol_new *controls, unsigned int num_controls);
+
#define snd_soc_component_module_get_when_probe(component)\
snd_soc_component_module_get(component, NULL, 0)
#define snd_soc_component_module_get_when_open(component, substream) \
@@ -370,11 +370,7 @@ static inline void *snd_soc_component_get_drvdata(struct snd_soc_component *c)
return dev_get_drvdata(c->dev);
}
-static inline unsigned int
-snd_soc_component_active(struct snd_soc_component *component)
-{
- return component->active;
-}
+unsigned int snd_soc_component_active(struct snd_soc_component *component);
/* component controls */
struct snd_kcontrol *snd_soc_component_get_kcontrol(struct snd_soc_component *component,
@@ -391,9 +387,6 @@ int snd_soc_component_close(struct snd_soc_component *component,
void snd_soc_component_suspend(struct snd_soc_component *component);
void snd_soc_component_resume(struct snd_soc_component *component);
int snd_soc_component_is_suspended(struct snd_soc_component *component);
-int snd_soc_component_probe(struct snd_soc_component *component);
-int snd_soc_component_fixup_controls(struct snd_soc_component *component);
-void snd_soc_component_remove(struct snd_soc_component *component);
int snd_soc_component_of_xlate_dai_id(struct snd_soc_component *component,
struct device_node *ep);
int snd_soc_component_of_xlate_dai_name(struct snd_soc_component *component,
@@ -423,7 +416,7 @@ int snd_soc_component_compr_set_metadata(struct snd_compr_stream *cstream,
int snd_soc_component_compr_get_metadata(struct snd_compr_stream *cstream,
struct snd_compr_metadata *metadata);
-int snd_soc_pcm_component_pointer(struct snd_pcm_substream *substream);
+snd_pcm_uframes_t snd_soc_pcm_component_pointer(struct snd_pcm_substream *substream);
int snd_soc_pcm_component_ioctl(struct snd_pcm_substream *substream,
unsigned int cmd, void *arg);
int snd_soc_pcm_component_sync_stop(struct snd_pcm_substream *substream);
@@ -451,4 +444,11 @@ int snd_soc_pcm_component_ack(struct snd_pcm_substream *substream);
void snd_soc_pcm_component_delay(struct snd_pcm_substream *substream,
snd_pcm_sframes_t *cpu_delay, snd_pcm_sframes_t *codec_delay);
+/* REMOVE ME */
+#define snd_soc_component_cache_sync snd_soc_component_regmap_cache_sync
+#define snd_soc_component_async_complete snd_soc_component_regmap_async_complete
+#define snd_soc_lookup_component_nolocked snd_soc_component_lookup_nolock
+#define snd_soc_lookup_component snd_soc_component_lookup
+#define snd_soc_lookup_component_by_name snd_soc_component_lookup_by_name
+
#endif /* __SOC_COMPONENT_H */
diff --git a/include/sound/soc-dai.h b/include/sound/soc-dai.h
index ba3ae56c6b06..c044909ef10d 100644
--- a/include/sound/soc-dai.h
+++ b/include/sound/soc-dai.h
@@ -212,8 +212,11 @@ int snd_soc_dai_get_channel_map(const struct snd_soc_dai *dai,
unsigned int *tx_num, unsigned int *tx_slot,
unsigned int *rx_num, unsigned int *rx_slot);
+struct snd_soc_component *snd_soc_dai_to_component(const struct snd_soc_dai *dai);
+struct snd_soc_dai_driver *snd_soc_dai_to_driver(const struct snd_soc_dai *dai);
int snd_soc_dai_is_dummy(const struct snd_soc_dai *dai);
-
+int snd_soc_dai_add_controls(struct snd_soc_dai *dai,
+ const struct snd_kcontrol_new *controls, int num_controls);
int snd_soc_dai_hw_params(struct snd_soc_dai *dai,
struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *params);
@@ -228,18 +231,7 @@ void snd_soc_dai_suspend(struct snd_soc_dai *dai);
void snd_soc_dai_resume(struct snd_soc_dai *dai);
int snd_soc_dai_compress_new(struct snd_soc_dai *dai, struct snd_soc_pcm_runtime *rtd);
bool snd_soc_dai_stream_valid(const struct snd_soc_dai *dai, int stream);
-void snd_soc_dai_action(struct snd_soc_dai *dai,
- int stream, int action);
-static inline void snd_soc_dai_activate(struct snd_soc_dai *dai,
- int stream)
-{
- snd_soc_dai_action(dai, stream, 1);
-}
-static inline void snd_soc_dai_deactivate(struct snd_soc_dai *dai,
- int stream)
-{
- snd_soc_dai_action(dai, stream, -1);
-}
+
int snd_soc_dai_active(const struct snd_soc_dai *dai);
int snd_soc_pcm_dai_probe(struct snd_soc_pcm_runtime *rtd, int order);
@@ -277,7 +269,12 @@ int snd_soc_dai_compr_get_metadata(struct snd_soc_dai *dai,
struct snd_compr_stream *cstream,
struct snd_compr_metadata *metadata);
-const char *snd_soc_dai_name_get(const struct snd_soc_dai *dai);
+int snd_soc_dai_matches_args(const struct snd_soc_dai *dai,
+ const struct of_phandle_args *args2);
+int snd_soc_dai_matches_dlc(struct snd_soc_dai *dai,
+ const struct snd_soc_dai_link_component *dlc);
+const char *snd_soc_dai_name(const struct snd_soc_dai *dai);
+int snd_soc_dai_id(const struct snd_soc_dai *dai);
struct snd_soc_dai_ops {
/* DAI driver callbacks */
@@ -489,69 +486,51 @@ struct snd_soc_dai {
void *priv;
};
+const struct snd_soc_pcm_stream *
+snd_soc_dai_pcm_stream_get_i(const struct snd_soc_dai *dai, int stream);
static inline const struct snd_soc_pcm_stream *
-snd_soc_dai_get_pcm_stream(const struct snd_soc_dai *dai, int stream)
-{
- return (stream == SNDRV_PCM_STREAM_PLAYBACK) ?
- &dai->driver->playback : &dai->driver->capture;
-}
-
-#define snd_soc_dai_get_widget_playback(dai) snd_soc_dai_get_widget(dai, SNDRV_PCM_STREAM_PLAYBACK)
-#define snd_soc_dai_get_widget_capture(dai) snd_soc_dai_get_widget(dai, SNDRV_PCM_STREAM_CAPTURE)
-static inline
-struct snd_soc_dapm_widget *snd_soc_dai_get_widget(struct snd_soc_dai *dai, int stream)
-{
- return dai->stream[stream].widget;
-}
-
-#define snd_soc_dai_set_widget_playback(dai, widget) snd_soc_dai_set_widget(dai, SNDRV_PCM_STREAM_PLAYBACK, widget)
-#define snd_soc_dai_set_widget_capture(dai, widget) snd_soc_dai_set_widget(dai, SNDRV_PCM_STREAM_CAPTURE, widget)
-static inline
-void snd_soc_dai_set_widget(struct snd_soc_dai *dai, int stream, struct snd_soc_dapm_widget *widget)
-{
- dai->stream[stream].widget = widget;
-}
-
-#define snd_soc_dai_dma_data_get_playback(dai) snd_soc_dai_dma_data_get(dai, SNDRV_PCM_STREAM_PLAYBACK)
-#define snd_soc_dai_dma_data_get_capture(dai) snd_soc_dai_dma_data_get(dai, SNDRV_PCM_STREAM_CAPTURE)
-#define snd_soc_dai_get_dma_data(dai, ss) snd_soc_dai_dma_data_get(dai, ss->stream)
-static inline void *snd_soc_dai_dma_data_get(const struct snd_soc_dai *dai, int stream)
-{
- return dai->stream[stream].dma_data;
-}
-
-#define snd_soc_dai_dma_data_set_playback(dai, data) snd_soc_dai_dma_data_set(dai, SNDRV_PCM_STREAM_PLAYBACK, data)
-#define snd_soc_dai_dma_data_set_capture(dai, data) snd_soc_dai_dma_data_set(dai, SNDRV_PCM_STREAM_CAPTURE, data)
-#define snd_soc_dai_set_dma_data(dai, ss, data) snd_soc_dai_dma_data_set(dai, ss->stream, data)
-static inline void snd_soc_dai_dma_data_set(struct snd_soc_dai *dai, int stream, void *data)
+snd_soc_dai_pcm_stream_get_s(const struct snd_soc_dai *dai, struct snd_pcm_substream *substream)
{
- dai->stream[stream].dma_data = data;
+ return snd_soc_dai_pcm_stream_get_i(dai, substream->stream);
}
-
-static inline void snd_soc_dai_init_dma_data(struct snd_soc_dai *dai, void *playback, void *capture)
+#define snd_soc_dai_pcm_stream_get(dai, x) _Generic((x), \
+ int : snd_soc_dai_pcm_stream_get_i, \
+ struct snd_pcm_substream * : snd_soc_dai_pcm_stream_get_s)(dai, x)
+
+#define snd_soc_dai_stream_widget_get_playback(dai) snd_soc_dai_stream_widget_get(dai, SNDRV_PCM_STREAM_PLAYBACK)
+#define snd_soc_dai_stream_widget_get_capture(dai) snd_soc_dai_stream_widget_get(dai, SNDRV_PCM_STREAM_CAPTURE)
+struct snd_soc_dapm_widget *snd_soc_dai_stream_widget_get(struct snd_soc_dai *dai, int stream);
+
+#define snd_soc_dai_stream_widget_set_playback(dai, widget) snd_soc_dai_stream_widget_set(dai, SNDRV_PCM_STREAM_PLAYBACK, widget)
+#define snd_soc_dai_stream_widget_set_capture(dai, widget) snd_soc_dai_stream_widget_set(dai, SNDRV_PCM_STREAM_CAPTURE, widget)
+void snd_soc_dai_stream_widget_set(struct snd_soc_dai *dai, int stream, struct snd_soc_dapm_widget *widget);
+
+#define snd_soc_dai_stream_dma_data_get_playback(dai) snd_soc_dai_stream_dma_data_get(dai, SNDRV_PCM_STREAM_PLAYBACK)
+#define snd_soc_dai_stream_dma_data_get_capture(dai) snd_soc_dai_stream_dma_data_get(dai, SNDRV_PCM_STREAM_CAPTURE)
+void *snd_soc_dai_stream_dma_data_get_i(const struct snd_soc_dai *dai, int stream);
+static inline void *snd_soc_dai_stream_dma_data_get_s(const struct snd_soc_dai *dai, struct snd_pcm_substream *substream)
{
- snd_soc_dai_dma_data_set_playback(dai, playback);
- snd_soc_dai_dma_data_set_capture(dai, capture);
+ return snd_soc_dai_stream_dma_data_get_i(dai, substream->stream);
}
-
-static inline unsigned int snd_soc_dai_tdm_mask_get(const struct snd_soc_dai *dai,
- int stream)
+#define snd_soc_dai_stream_dma_data_get(dai, x) _Generic((x), \
+ int : snd_soc_dai_stream_dma_data_get_i, \
+ struct snd_pcm_substream * : snd_soc_dai_stream_dma_data_get_s)(dai, x)
+
+#define snd_soc_dai_stream_dma_data_set_playback(dai, data) snd_soc_dai_stream_dma_data_set(dai, SNDRV_PCM_STREAM_PLAYBACK, data)
+#define snd_soc_dai_stream_dma_data_set_capture(dai, data) snd_soc_dai_stream_dma_data_set(dai, SNDRV_PCM_STREAM_CAPTURE, data)
+void snd_soc_dai_stream_dma_data_set_i(struct snd_soc_dai *dai, int stream, void *data);
+static inline void snd_soc_dai_stream_dma_data_set_s(struct snd_soc_dai *dai, struct snd_pcm_substream *substream, void *data)
{
- return dai->stream[stream].tdm_mask;
+ snd_soc_dai_stream_dma_data_set_i(dai, substream->stream, data);
}
+#define snd_soc_dai_stream_dma_data_set(dai, x, data) _Generic((x), \
+ int : snd_soc_dai_stream_dma_data_set_i, \
+ struct snd_pcm_substream * : snd_soc_dai_stream_dma_data_set_s)(dai, x, data)
-static inline void snd_soc_dai_tdm_mask_set(struct snd_soc_dai *dai, int stream,
- unsigned int tdm_mask)
-{
- dai->stream[stream].tdm_mask = tdm_mask;
-}
+unsigned int snd_soc_dai_stream_tdm_mask_get(const struct snd_soc_dai *dai, int stream);
+void snd_soc_dai_stream_tdm_mask_set(struct snd_soc_dai *dai, int stream, unsigned int tdm_mask);
-static inline unsigned int snd_soc_dai_stream_active(const struct snd_soc_dai *dai,
- int stream)
-{
- /* see snd_soc_dai_action() for setup */
- return dai->stream[stream].active;
-}
+unsigned int snd_soc_dai_stream_active(const struct snd_soc_dai *dai, int stream);
static inline void snd_soc_dai_set_drvdata(struct snd_soc_dai *dai,
void *data)
@@ -564,45 +543,43 @@ static inline void *snd_soc_dai_get_drvdata(struct snd_soc_dai *dai)
return dev_get_drvdata(dai->dev);
}
-/**
- * snd_soc_dai_set_stream() - Configures a DAI for stream operation
- * @dai: DAI
- * @stream: STREAM (opaque structure depending on DAI type)
- * @direction: Stream direction(Playback/Capture)
- * Some subsystems, such as SoundWire, don't have a notion of direction and we reuse
- * the ASoC stream direction to configure sink/source ports.
- * Playback maps to source ports and Capture for sink ports.
- *
- * This should be invoked with NULL to clear the stream set previously.
- * Returns 0 on success, a negative error code otherwise.
- */
-static inline int snd_soc_dai_set_stream(struct snd_soc_dai *dai,
- void *stream, int direction)
-{
- if (dai->driver->ops->set_stream)
- return dai->driver->ops->set_stream(dai, stream, direction);
- else
- return -ENOTSUPP;
-}
-
-/**
- * snd_soc_dai_get_stream() - Retrieves stream from DAI
- * @dai: DAI
- * @direction: Stream direction(Playback/Capture)
- *
- * This routine only retrieves that was previously configured
- * with snd_soc_dai_get_stream()
- *
- * Returns pointer to stream or an ERR_PTR value, e.g.
- * ERR_PTR(-ENOTSUPP) if callback is not supported;
- */
-static inline void *snd_soc_dai_get_stream(struct snd_soc_dai *dai,
- int direction)
+int snd_soc_dai_set_stream(struct snd_soc_dai *dai, void *stream, int direction);
+void *snd_soc_dai_get_stream(struct snd_soc_dai *dai, int direction);
+
+struct snd_soc_dai *snd_soc_dai_register(struct snd_soc_component *component,
+ struct snd_soc_dai_driver *dai_drv,
+ bool legacy_dai_naming);
+void snd_soc_dai_unregister(struct snd_soc_dai *dai);
+struct snd_soc_dai *snd_soc_dai_from_list(struct list_head *list);
+struct list_head *snd_soc_dai_to_list(struct snd_soc_dai *dai);
+unsigned int snd_soc_dai_get_symmetric_rate(struct snd_soc_dai *dai);
+unsigned int snd_soc_dai_get_symmetric_channels(struct snd_soc_dai *dai);
+unsigned int snd_soc_dai_get_symmetric_sample_bits(struct snd_soc_dai *dai);
+void snd_soc_dai_set_priv(struct snd_soc_dai *dai, void *priv);
+void *snd_soc_dai_to_priv(struct snd_soc_dai *dai);
+
+/* REMOVE ME */
+#define snd_soc_dai_get_pcm_stream snd_soc_dai_pcm_stream_get
+#define snd_soc_dai_get_widget_playback(dai) snd_soc_dai_stream_widget_get(dai, SNDRV_PCM_STREAM_PLAYBACK)
+#define snd_soc_dai_get_widget_capture(dai) snd_soc_dai_stream_widget_get(dai, SNDRV_PCM_STREAM_CAPTURE)
+#define snd_soc_dai_get_widget snd_soc_dai_stream_widget_get
+#define snd_soc_dai_set_widget_playback(dai, widget) snd_soc_dai_stream_widget_set(dai, SNDRV_PCM_STREAM_PLAYBACK, widget)
+#define snd_soc_dai_set_widget_capture(dai, widget) snd_soc_dai_stream_widget_set(dai, SNDRV_PCM_STREAM_CAPTURE, widget)
+#define snd_soc_dai_set_widget snd_soc_dai_stream_widget_set
+#define snd_soc_dai_dma_data_get_playback(dai) snd_soc_dai_stream_dma_data_get(dai, SNDRV_PCM_STREAM_PLAYBACK)
+#define snd_soc_dai_dma_data_get_capture(dai) snd_soc_dai_stream_dma_data_get(dai, SNDRV_PCM_STREAM_CAPTURE)
+#define snd_soc_dai_get_dma_data snd_soc_dai_stream_dma_data_get
+#define snd_soc_dai_dma_data_get snd_soc_dai_stream_dma_data_get
+#define snd_soc_dai_dma_data_set_playback(dai, data) snd_soc_dai_stream_dma_data_set(dai, SNDRV_PCM_STREAM_PLAYBACK, data)
+#define snd_soc_dai_dma_data_set_capture(dai, data) snd_soc_dai_stream_dma_data_set(dai, SNDRV_PCM_STREAM_CAPTURE, data)
+#define snd_soc_dai_set_dma_data snd_soc_dai_stream_dma_data_set
+#define snd_soc_dai_dma_data_set snd_soc_dai_stream_dma_data_set
+#define snd_soc_dai_tdm_mask_get snd_soc_dai_stream_tdm_mask_get
+#define snd_soc_dai_tdm_mask_set snd_soc_dai_stream_tdm_mask_set
+static inline void snd_soc_dai_init_dma_data(struct snd_soc_dai *dai, void *playback, void *capture)
{
- if (dai->driver->ops->get_stream)
- return dai->driver->ops->get_stream(dai, direction);
- else
- return ERR_PTR(-ENOTSUPP);
+ snd_soc_dai_stream_dma_data_set_playback(dai, playback);
+ snd_soc_dai_stream_dma_data_set_capture(dai, capture);
}
#endif
diff --git a/include/sound/soc.h b/include/sound/soc.h
index f46b2bc2a022..f6b98324f346 100644
--- a/include/sound/soc.h
+++ b/include/sound/soc.h
@@ -447,15 +447,9 @@ static inline int snd_soc_resume(struct device *dev)
}
#endif
int snd_soc_poweroff(struct device *dev);
-int snd_soc_register_component_c(struct snd_soc_component *component,
- const struct snd_soc_component_driver *component_driver,
- struct snd_soc_dai_driver *dai_drv, int num_dai);
-int snd_soc_register_component_d(struct device *dev,
+int snd_soc_register_component(struct device *dev,
const struct snd_soc_component_driver *component_driver,
struct snd_soc_dai_driver *dai_drv, int num_dai);
-#define snd_soc_register_component(x, ...) _Generic((x), \
-struct device * : snd_soc_register_component_d, \
-struct snd_soc_component * : snd_soc_register_component_c)(x, __VA_ARGS__)
int devm_snd_soc_register_component(struct device *dev,
const struct snd_soc_component_driver *component_driver,
@@ -463,11 +457,6 @@ int devm_snd_soc_register_component(struct device *dev,
#define snd_soc_unregister_component(dev) snd_soc_unregister_component_by_driver(dev, NULL)
void snd_soc_unregister_component_by_driver(struct device *dev,
const struct snd_soc_component_driver *component_driver);
-struct snd_soc_component *snd_soc_lookup_component_nolocked(struct device *dev,
- const char *driver_name);
-struct snd_soc_component *snd_soc_lookup_component(struct device *dev,
- const char *driver_name);
-struct snd_soc_component *snd_soc_lookup_component_by_name(const char *component_name);
int soc_new_pcm(struct snd_soc_pcm_runtime *rtd);
#ifdef CONFIG_SND_SOC_COMPRESS
@@ -551,12 +540,8 @@ static inline int snd_soc_set_ac97_ops(struct snd_ac97_bus_ops *ops)
struct snd_kcontrol *snd_soc_cnew(const struct snd_kcontrol_new *_template,
void *data, const char *long_name,
const char *prefix);
-int snd_soc_add_component_controls(struct snd_soc_component *component,
- const struct snd_kcontrol_new *controls, unsigned int num_controls);
int snd_soc_add_card_controls(struct snd_soc_card *soc_card,
const struct snd_kcontrol_new *controls, int num_controls);
-int snd_soc_add_dai_controls(struct snd_soc_dai *dai,
- const struct snd_kcontrol_new *controls, int num_controls);
int snd_soc_info_enum_double(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_info *uinfo);
int snd_soc_get_enum_double(struct snd_kcontrol *kcontrol,
@@ -699,7 +684,8 @@ struct snd_soc_dai_link_component {
struct snd_soc_dai_link_ch_map {
unsigned int cpu;
unsigned int codec;
- unsigned int ch_mask;
+ unsigned int cpu_ch_mask;
+ unsigned int codec_ch_mask;
};
struct snd_soc_dai_link {
@@ -1330,6 +1316,9 @@ int snd_soc_of_parse_tdm_slot(struct device_node *np,
unsigned int *rx_mask,
unsigned int *slots,
unsigned int *slot_width);
+int snd_soc_of_xlate_dai_name(struct snd_soc_component *component,
+ const struct of_phandle_args *args,
+ const char **dai_name);
void snd_soc_of_parse_node_prefix(struct device_node *np,
struct snd_soc_codec_conf *codec_conf,
struct device_node *of_node,
@@ -1388,19 +1377,12 @@ void snd_soc_dlc_use_cpu_as_platform(struct snd_soc_dai_link_component *platform
struct of_phandle_args *snd_soc_copy_dai_args(struct device *dev,
const struct of_phandle_args *args);
struct snd_soc_dai *snd_soc_get_dai_via_args(const struct of_phandle_args *dai_args);
-struct snd_soc_dai *snd_soc_register_dai(struct snd_soc_component *component,
- struct snd_soc_dai_driver *dai_drv,
- bool legacy_dai_naming);
-void snd_soc_unregister_dai(struct snd_soc_dai *dai);
struct snd_soc_dai *snd_soc_find_dai(
const struct snd_soc_dai_link_component *dlc);
struct snd_soc_dai *snd_soc_find_dai_with_mutex(
const struct snd_soc_dai_link_component *dlc);
-void soc_pcm_set_dai_params(struct snd_soc_dai *dai,
- struct snd_pcm_hw_params *params);
-
#include <sound/soc-dai.h>
static inline
@@ -1550,4 +1532,12 @@ static inline void _snd_soc_dpcm_mutex_assert_held_r(struct snd_soc_pcm_runtime
#include <sound/soc-card.h>
#include <sound/soc-jack.h>
+/*
+ * REMOVE ME
+ */
+#define snd_soc_add_dai_controls snd_soc_dai_add_controls
+#define snd_soc_register_dai snd_soc_dai_register
+#define snd_soc_unregister_dai snd_soc_dai_unregister
+#define snd_soc_add_component_controls snd_soc_component_add_controls
+
#endif
diff --git a/include/sound/soc_sdw_utils.h b/include/sound/soc_sdw_utils.h
index 9b28e9aef4f1..418466438ea1 100644
--- a/include/sound/soc_sdw_utils.h
+++ b/include/sound/soc_sdw_utils.h
@@ -250,8 +250,6 @@ int asoc_sdw_cs_amp_init(struct snd_soc_card *card,
struct snd_soc_dai_link *dai_links,
struct asoc_sdw_codec_info *info,
bool playback);
-int asoc_sdw_cs_spk_feedback_rtd_init(struct snd_soc_pcm_runtime *rtd,
- struct snd_soc_dai *dai);
int asoc_sdw_cs35l56_volume_limit(struct snd_soc_card *card, const char *name_prefix);
/* MAXIM codec support */
@@ -294,4 +292,24 @@ int asoc_sdw_es9356_rtd_init(struct snd_soc_pcm_runtime *rtd, struct snd_soc_dai
int asoc_sdw_es9356_spk_rtd_init(struct snd_soc_pcm_runtime *rtd, struct snd_soc_dai *dai);
int asoc_sdw_es9356_dmic_rtd_init(struct snd_soc_pcm_runtime *rtd, struct snd_soc_dai *dai);
+/* Senary SN624x SDCA */
+int asoc_sdw_senary_sdca_jack_init(struct snd_soc_card *card,
+ struct snd_soc_dai_link *dai_links,
+ struct asoc_sdw_codec_info *info,
+ bool playback);
+int asoc_sdw_senary_sdca_jack_exit(struct snd_soc_card *card,
+ struct snd_soc_dai_link *dai_link);
+int asoc_sdw_senary_sdca_jack_rtd_init(struct snd_soc_pcm_runtime *rtd,
+ struct snd_soc_dai *dai);
+int asoc_sdw_senary_amp_init(struct snd_soc_card *card,
+ struct snd_soc_dai_link *dai_links,
+ struct asoc_sdw_codec_info *info,
+ bool playback);
+int asoc_sdw_senary_amp_exit(struct snd_soc_card *card,
+ struct snd_soc_dai_link *dai_link);
+int asoc_sdw_senary_sdca_spk_rtd_init(struct snd_soc_pcm_runtime *rtd,
+ struct snd_soc_dai *dai);
+int asoc_sdw_senary_dmic_rtd_init(struct snd_soc_pcm_runtime *rtd,
+ struct snd_soc_dai *dai);
+
#endif
diff --git a/include/sound/sof/ipc4/header.h b/include/sound/sof/ipc4/header.h
index cea3d9453b84..c0216f4b14c2 100644
--- a/include/sound/sof/ipc4/header.h
+++ b/include/sound/sof/ipc4/header.h
@@ -436,12 +436,10 @@ enum sof_ipc4_fw_config_params {
SOF_IPC4_FW_CFG_RESERVED,
SOF_IPC4_FW_CFG_POWER_GATING_POLICY,
SOF_IPC4_FW_CFG_ASSERT_MODE,
- SOF_IPC4_FW_RESERVED1,
- SOF_IPC4_FW_RESERVED2,
- SOF_IPC4_FW_RESERVED3,
- SOF_IPC4_FW_RESERVED4,
- SOF_IPC4_FW_RESERVED5,
- SOF_IPC4_FW_CONTEXT_SAVE
+ /* Reserved: 24 - 28 */
+ SOF_IPC4_FW_CONTEXT_SAVE = 29,
+ /* Reserved: 30 - 34 */
+ SOF_IPC4_FW_CFG_SOF_INFO = 35,
};
struct sof_ipc4_fw_version {
@@ -451,6 +449,14 @@ struct sof_ipc4_fw_version {
uint16_t build;
} __packed;
+/*
+ * tuple based array for SOF specific information under SOF_IPC4_FW_CFG_SOF_INFO
+ * tuple of fw_config
+ */
+enum ipc4_fw_sof_info_params {
+ SOF_IPC4_SOF_CODEC_INFO,
+};
+
/* Payload data for SOF_IPC4_MOD_SET_DX */
struct sof_ipc4_dx_state_info {
/* core(s) to apply the change */
@@ -641,9 +647,10 @@ struct sof_ipc4_notify_module_data {
* The event_data contains the struct sof_ipc4_control_msg_payload of the control
* which sent the notification.
*/
-#define SOF_IPC4_NOTIFY_MODULE_EVENTID_ALSA_MAGIC_MASK GENMASK(31, 16)
+#define SOF_IPC4_NOTIFY_MODULE_EVENTID_SOF_MAGIC_MASK GENMASK(31, 16)
#define SOF_IPC4_NOTIFY_MODULE_EVENTID_ALSA_MAGIC_VAL 0xA15A0000
#define SOF_IPC4_NOTIFY_MODULE_EVENTID_ALSA_PARAMID_MASK GENMASK(15, 0)
+#define SOF_IPC4_NOTIFY_MODULE_EVENTID_COMPR_MAGIC_VAL 0xC0C00000
/*
* Macros for creating struct sof_ipc4_module_init_ext_init payload
@@ -706,7 +713,8 @@ struct sof_ipc4_module_init_ext_object {
enum sof_ipc4_mod_init_ext_obj_id {
SOF_IPC4_MOD_INIT_DATA_ID_INVALID = 0,
SOF_IPC4_MOD_INIT_DATA_ID_DP_DATA,
- SOF_IPC4_MOD_INIT_DATA_ID_MAX = SOF_IPC4_MOD_INIT_DATA_ID_DP_DATA,
+ SOF_IPC4_MOD_INIT_DATA_ID_MODULE_DATA,
+ SOF_IPC4_MOD_INIT_DATA_ID_MAX = SOF_IPC4_MOD_INIT_DATA_ID_MODULE_DATA,
};
/* DP module memory configuration data object for object array */
diff --git a/include/sound/tas2781-dsp.h b/include/sound/tas2781-dsp.h
index e845687decf9..3380dfd526de 100644
--- a/include/sound/tas2781-dsp.h
+++ b/include/sound/tas2781-dsp.h
@@ -56,6 +56,10 @@ enum tasdevice_dsp_dev_idx {
TASDEVICE_DSP_TAS_2781_QUAD,
TASDEVICE_DSP_TAS_5825_MONO,
TASDEVICE_DSP_TAS_5825_DUAL,
+ TASDEVICE_DSP_TAS_2573_MONO,
+ TASDEVICE_DSP_TAS_2573_DUAL,
+ TASDEVICE_DSP_TAS_2573_21,
+ TASDEVICE_DSP_TAS_2573_QUAD,
TASDEVICE_DSP_TAS_MAX_DEVICE
};
@@ -142,6 +146,7 @@ struct tasdevice_fw {
struct tasdevice_calibration *calibrations;
struct fct_param_address fct_par_addr;
struct device *dev;
+ int calibration_config_id;
};
enum tasdevice_fw_state {
@@ -207,6 +212,14 @@ struct tasdevice_rca {
*/
int capture_profile_id;
/*
+ * Primarily designed for speaker calibration scenarios with special
+ * requirements. For regular use cases, when the default value -1 is
+ * set, calibration will directly reuse the current playback
+ * configuration; non-negative values can be customized for special
+ * calibration demands.
+ */
+ int calibration_profile_id;
+ /*
* Since version 0x105, the keyword 'init' was introduced into the
* profile, which is used for chip initialization, particularly to
* store common settings for other non-initialization profiles.
diff --git a/include/sound/tas2781.h b/include/sound/tas2781.h
index b763da613769..f4275226366d 100644
--- a/include/sound/tas2781.h
+++ b/include/sound/tas2781.h
@@ -49,6 +49,13 @@
#define TASDEVICE_REG(book, page, reg) (((book * 256 * 128) + \
(page * 128)) + reg)
+#define TAS_REG_ERR_LOG(dev, chn, reg, ret) \
+ dev_err((dev), "%s, C%uBx%02xPx%02xRx%02x E=%d\n", \
+ __func__, chn, TASDEVICE_BOOK_ID(reg), \
+ TASDEVICE_PAGE_ID(reg), \
+ TASDEVICE_PAGE_REG(reg), \
+ (ret))
+
/* Software Reset, compatble with new device (TAS5825). */
#define TASDEVICE_REG_SWRESET TASDEVICE_REG(0x0, 0x0, 0x01)
#define TASDEVICE_REG_SWRESET_RESET BIT(0)
@@ -91,6 +98,30 @@
/* prm_TE_1_Beta1 */
#define TAS2563_TE_DT_REG TASDEVICE_REG(0x00, 0x0f, 0x70)
+#define TAS2573_FCT_INT_LATCH TASDEVICE_REG(0x00, 0x00, 0x67)
+/* YM57 */
+#define TAS2573_FCT_OUTPUT_R0 TASDEVICE_REG(0x00, 0x65, 0x74)
+/* YM58 */
+#define TAS2573_FCT_OUTPUT_R0_LOW TASDEVICE_REG(0x00, 0x65, 0x78)
+/* YM59 */
+#define TAS2573_FCT_OUTPUT_INV_R0 TASDEVICE_REG(0x00, 0x65, 0x7C)
+/* YM61 */
+#define TAS2573_FCT_OUTPUT_POWERTOT TASDEVICE_REG(0x00, 0x66, 0x0C)
+/* YM64 */
+#define TAS2573_FCT_OUTPUT_F0 TASDEVICE_REG(0x00, 0x65, 0x18)
+/* YM147 */
+#define TAS2573_FCT_STATUS_CTRL TASDEVICE_REG(0x00, 0x68, 0x74)
+/* YM148 */
+#define TAS2573_FCT_STATUS_BINNING TASDEVICE_REG(0x00, 0x68, 0x78)
+/* YM664 */
+#define TAS2573_RE_OUT TASDEVICE_REG(0x00, 0x7A, 0x18)
+/* YM952 */
+#define TAS2573_SILENCE_DETECTED TASDEVICE_REG(0x00, 0x83, 0x60)
+/* YM954 */
+#define TAS2573_OPEN_CIRCUIT TASDEVICE_REG(0x00, 0x83, 0x68)
+/* YM955 */
+#define TAS2573_SHORTCKT TASDEVICE_REG(0x00, 0x83, 0x6C)
+
#define TAS2781_PRM_INT_MASK_REG TASDEVICE_REG(0x00, 0x00, 0x3b)
#define TAS2781_PRM_CLK_CFG_REG TASDEVICE_REG(0x00, 0x00, 0x5c)
#define TAS2781_PRM_RSVD_REG TASDEVICE_REG(0x00, 0x01, 0x19)
diff --git a/include/trace/define_remote_events.h b/include/trace/define_remote_events.h
index 676e803dc144..78346ac77585 100644
--- a/include/trace/define_remote_events.h
+++ b/include/trace/define_remote_events.h
@@ -35,17 +35,26 @@ do { \
#define RE_PRINTK(__args...) __args
-#define REMOTE_EVENT(__name, __id, __struct, __printk) \
- REMOTE_EVENT_FORMAT(__name, __struct); \
+#define REMOTE_EVENT_PRINT_FUNC(__name, __printk) \
static void remote_event_print_##__name(void *evt, struct trace_seq *seq) \
{ \
struct remote_event_format_##__name __maybe_unused *__entry = evt; \
trace_seq_puts(seq, #__name); \
- remote_printk(__printk); \
+ __printk; \
}
+
+#define REMOTE_EVENT(__name, __id, __struct, __printk) \
+ REMOTE_EVENT_FORMAT(__name, __struct); \
+ REMOTE_EVENT_PRINT_FUNC(__name, remote_printk(__printk))
+
+#define REMOTE_EVENT_CUSTOM_PRINTK(__name, __id, __struct, __printk) \
+ REMOTE_EVENT_FORMAT(__name, __struct); \
+ REMOTE_EVENT_PRINT_FUNC(__name, __printk)
+
#include REMOTE_EVENT_INCLUDE(REMOTE_EVENT_INCLUDE_FILE)
#undef REMOTE_EVENT
+#undef REMOTE_EVENT_CUSTOM_PRINTK
#undef RE_PRINTK
#undef re_field
#define re_field(__type, __field) \
@@ -70,4 +79,8 @@ do { \
.print_fmt = remote_event_print_fmt_##__name, \
.print = remote_event_print_##__name, \
}
+
+#define REMOTE_EVENT_CUSTOM_PRINTK(__name, __id, __struct, __printk) \
+ REMOTE_EVENT(__name, __id, RE_STRUCT(__struct), "\"Unknown\"")
+
#include REMOTE_EVENT_INCLUDE(REMOTE_EVENT_INCLUDE_FILE)
diff --git a/include/trace/events/bridge.h b/include/trace/events/bridge.h
index 3fe4725c83ff..f676516b33fa 100644
--- a/include/trace/events/bridge.h
+++ b/include/trace/events/bridge.h
@@ -68,13 +68,14 @@ TRACE_EVENT(br_fdb_external_learn_add,
TRACE_EVENT(fdb_delete,
- TP_PROTO(struct net_bridge *br, struct net_bridge_fdb_entry *f),
+ TP_PROTO(struct net_bridge *br, struct net_bridge_fdb_entry *f,
+ const struct net_bridge_port *dst),
- TP_ARGS(br, f),
+ TP_ARGS(br, f, dst),
TP_STRUCT__entry(
__string(br_dev, br->dev->name)
- __string(dev, f->dst ? f->dst->dev->name : "null")
+ __string(dev, dst ? dst->dev->name : "null")
__array(unsigned char, addr, ETH_ALEN)
__field(u16, vid)
),
diff --git a/include/trace/events/cachefiles.h b/include/trace/events/cachefiles.h
index 9259bc71049e..a19233e8ae78 100644
--- a/include/trace/events/cachefiles.h
+++ b/include/trace/events/cachefiles.h
@@ -52,6 +52,8 @@ enum cachefiles_coherency_trace {
cachefiles_coherency_check_ok,
cachefiles_coherency_check_type,
cachefiles_coherency_check_xattr,
+ cachefiles_coherency_discontiguous,
+ cachefiles_coherency_remove,
cachefiles_coherency_set_fail,
cachefiles_coherency_set_ok,
cachefiles_coherency_vol_check_cmp,
@@ -63,9 +65,11 @@ enum cachefiles_coherency_trace {
};
enum cachefiles_trunc_trace {
+ cachefiles_trunc_clear_padding,
cachefiles_trunc_dio_adjust,
cachefiles_trunc_expand_tmpfile,
cachefiles_trunc_shrink,
+ cachefiles_trunc_zap,
};
enum cachefiles_prepare_read_trace {
@@ -80,11 +84,14 @@ enum cachefiles_prepare_read_trace {
};
enum cachefiles_error_trace {
+ cachefiles_trace_alignment_error,
+ cachefiles_trace_create_nospace,
cachefiles_trace_fallocate_error,
cachefiles_trace_getxattr_error,
cachefiles_trace_link_error,
cachefiles_trace_lookup_error,
cachefiles_trace_mkdir_error,
+ cachefiles_trace_mkdir_nospace,
cachefiles_trace_notify_change_error,
cachefiles_trace_open_error,
cachefiles_trace_read_error,
@@ -97,6 +104,8 @@ enum cachefiles_error_trace {
cachefiles_trace_trunc_error,
cachefiles_trace_unlink_error,
cachefiles_trace_write_error,
+ cachefiles_trace_write_nospace,
+ cachefiles_trace_write_nospace_2,
};
#endif
@@ -136,6 +145,8 @@ enum cachefiles_error_trace {
EM(cachefiles_coherency_check_ok, "OK ") \
EM(cachefiles_coherency_check_type, "BAD type") \
EM(cachefiles_coherency_check_xattr, "BAD xatt") \
+ EM(cachefiles_coherency_discontiguous, "--- gap ") \
+ EM(cachefiles_coherency_remove, "REMOVE ") \
EM(cachefiles_coherency_set_fail, "SET fail") \
EM(cachefiles_coherency_set_ok, "SET ok ") \
EM(cachefiles_coherency_vol_check_cmp, "VOL BAD cmp ") \
@@ -146,9 +157,11 @@ enum cachefiles_error_trace {
E_(cachefiles_coherency_vol_set_ok, "VOL SET ok ")
#define cachefiles_trunc_traces \
+ EM(cachefiles_trunc_clear_padding, "CLRPAD") \
EM(cachefiles_trunc_dio_adjust, "DIOADJ") \
EM(cachefiles_trunc_expand_tmpfile, "EXPTMP") \
- E_(cachefiles_trunc_shrink, "SHRINK")
+ EM(cachefiles_trunc_shrink, "SHRINK") \
+ E_(cachefiles_trunc_zap, "ZAP ")
#define cachefiles_prepare_read_traces \
EM(cachefiles_trace_read_after_eof, "after-eof ") \
@@ -161,11 +174,14 @@ enum cachefiles_error_trace {
E_(cachefiles_trace_read_seek_nxio, "seek-enxio")
#define cachefiles_error_traces \
+ EM(cachefiles_trace_alignment_error, "align") \
+ EM(cachefiles_trace_create_nospace, "create-nospace") \
EM(cachefiles_trace_fallocate_error, "fallocate") \
EM(cachefiles_trace_getxattr_error, "getxattr") \
EM(cachefiles_trace_link_error, "link") \
EM(cachefiles_trace_lookup_error, "lookup") \
EM(cachefiles_trace_mkdir_error, "mkdir") \
+ EM(cachefiles_trace_mkdir_nospace, "mkdir-nospace") \
EM(cachefiles_trace_notify_change_error, "notify_change") \
EM(cachefiles_trace_open_error, "open") \
EM(cachefiles_trace_read_error, "read") \
@@ -177,7 +193,9 @@ enum cachefiles_error_trace {
EM(cachefiles_trace_tmpfile_error, "tmpfile") \
EM(cachefiles_trace_trunc_error, "trunc") \
EM(cachefiles_trace_unlink_error, "unlink") \
- E_(cachefiles_trace_write_error, "write")
+ EM(cachefiles_trace_write_error, "write") \
+ EM(cachefiles_trace_write_nospace, "write-nospace") \
+ E_(cachefiles_trace_write_nospace_2, "write-nospace-2")
/*
@@ -371,12 +389,12 @@ TRACE_EVENT(cachefiles_rename,
TRACE_EVENT(cachefiles_coherency,
TP_PROTO(struct cachefiles_object *obj,
- ino_t ino,
- u64 disk_aux,
+ ino_t ino, uoff_t obj_size,
+ const void *disk_aux,
enum cachefiles_content content,
enum cachefiles_coherency_trace why),
- TP_ARGS(obj, ino, disk_aux, content, why),
+ TP_ARGS(obj, ino, obj_size, disk_aux, content, why),
/* Note that obj may be NULL */
TP_STRUCT__entry(
@@ -384,23 +402,41 @@ TRACE_EVENT(cachefiles_coherency,
__field(enum cachefiles_coherency_trace, why)
__field(enum cachefiles_content, content)
__field(u64, ino)
+ __field(u64, obj_size)
__field(u64, aux)
__field(u64, disk_aux)
),
TP_fast_assign(
+ union {
+ __be16 s[4];
+ __be64 ll;
+ } x;
+
__entry->obj = obj->debug_id;
__entry->why = why;
__entry->content = content;
__entry->ino = ino;
+ __entry->obj_size = obj_size;
__entry->aux = be64_to_cpup((__be64 *)obj->cookie->inline_aux);
- __entry->disk_aux = disk_aux;
+
+ /* cachefiles_xattr::data is 2-byte aligned but not 8-byte aligned. */
+ if (disk_aux) {
+ x.s[0] = ((__be16 *)disk_aux)[0];
+ x.s[1] = ((__be16 *)disk_aux)[1];
+ x.s[2] = ((__be16 *)disk_aux)[2];
+ x.s[3] = ((__be16 *)disk_aux)[3];
+ __entry->disk_aux = be64_to_cpu(x.ll);
+ } else {
+ __entry->disk_aux = 0;
+ }
),
- TP_printk("o=%08x %s B=%llx c=%u aux=%llx dsk=%llx",
+ TP_printk("o=%08x %s B=%llx oz=%llx c=%u aux=%llx dsk=%llx",
__entry->obj,
__print_symbolic(__entry->why, cachefiles_coherency_traces),
__entry->ino,
+ __entry->obj_size,
__entry->content,
__entry->aux,
__entry->disk_aux)
@@ -434,7 +470,7 @@ TRACE_EVENT(cachefiles_vol_coherency,
TRACE_EVENT(cachefiles_prep_read,
TP_PROTO(struct cachefiles_object *obj,
- loff_t start,
+ uoff_t start,
size_t len,
unsigned short flags,
enum netfs_io_source source,
@@ -449,7 +485,7 @@ TRACE_EVENT(cachefiles_prep_read,
__field(enum netfs_io_source, source)
__field(enum cachefiles_prepare_read_trace, why)
__field(size_t, len)
- __field(loff_t, start)
+ __field(uoff_t, start)
__field(unsigned int, netfs_inode)
__field(unsigned int, cache_inode)
),
@@ -477,16 +513,16 @@ TRACE_EVENT(cachefiles_prep_read,
TRACE_EVENT(cachefiles_read,
TP_PROTO(struct cachefiles_object *obj,
struct inode *backer,
- loff_t start,
+ uoff_t start,
size_t len),
TP_ARGS(obj, backer, start, len),
TP_STRUCT__entry(
- __field(unsigned int, obj)
- __field(unsigned int, backer)
- __field(size_t, len)
- __field(loff_t, start)
+ __field(unsigned int, obj)
+ __field(unsigned int, backer)
+ __field(size_t, len)
+ __field(uoff_t, start)
),
TP_fast_assign(
@@ -506,16 +542,16 @@ TRACE_EVENT(cachefiles_read,
TRACE_EVENT(cachefiles_write,
TP_PROTO(struct cachefiles_object *obj,
struct inode *backer,
- loff_t start,
+ uoff_t start,
size_t len),
TP_ARGS(obj, backer, start, len),
TP_STRUCT__entry(
- __field(unsigned int, obj)
- __field(unsigned int, backer)
- __field(size_t, len)
- __field(loff_t, start)
+ __field(unsigned int, obj)
+ __field(unsigned int, backer)
+ __field(size_t, len)
+ __field(uoff_t, start)
),
TP_fast_assign(
@@ -534,7 +570,7 @@ TRACE_EVENT(cachefiles_write,
TRACE_EVENT(cachefiles_trunc,
TP_PROTO(struct cachefiles_object *obj, struct inode *backer,
- loff_t from, loff_t to, enum cachefiles_trunc_trace why),
+ uoff_t from, uoff_t to, enum cachefiles_trunc_trace why),
TP_ARGS(obj, backer, from, to, why),
@@ -542,8 +578,8 @@ TRACE_EVENT(cachefiles_trunc,
__field(unsigned int, obj)
__field(unsigned int, backer)
__field(enum cachefiles_trunc_trace, why)
- __field(loff_t, from)
- __field(loff_t, to)
+ __field(uoff_t, from)
+ __field(uoff_t, to)
),
TP_fast_assign(
@@ -679,6 +715,26 @@ TRACE_EVENT(cachefiles_io_error,
__entry->error)
);
+TRACE_EVENT(cachefiles_no_space,
+ TP_PROTO(struct cachefiles_object *obj, enum cachefiles_error_trace trace),
+
+ TP_ARGS(obj, trace),
+
+ TP_STRUCT__entry(
+ __field(unsigned int, obj)
+ __field(enum cachefiles_error_trace, trace)
+ ),
+
+ TP_fast_assign(
+ __entry->obj = obj ? obj->debug_id : 0;
+ __entry->trace = trace;
+ ),
+
+ TP_printk("o=%08x %s",
+ __entry->obj,
+ __print_symbolic(__entry->trace, cachefiles_error_traces))
+ );
+
#endif /* _TRACE_CACHEFILES_H */
/* This part must be outside protection */
diff --git a/include/trace/events/dma.h b/include/trace/events/dma.h
index 9df02c1511de..b06d8f99922d 100644
--- a/include/trace/events/dma.h
+++ b/include/trace/events/dma.h
@@ -134,7 +134,7 @@ DECLARE_EVENT_CLASS(dma_alloc_class,
TP_fast_assign(
__assign_str(device);
__entry->virt_addr = virt_addr;
- __entry->dma_addr = dma_addr;
+ __entry->dma_addr = virt_addr ? dma_addr : 0;
__entry->size = size;
__entry->flags = flags;
__entry->dir = dir;
diff --git a/include/trace/events/fib.h b/include/trace/events/fib.h
index feb28b359eff..e0ee14d6ca45 100644
--- a/include/trace/events/fib.h
+++ b/include/trace/events/fib.h
@@ -15,9 +15,10 @@
TRACE_EVENT(fib_table_lookup,
TP_PROTO(u32 tb_id, const struct flowi4 *flp,
- const struct fib_nh_common *nhc, int err),
+ const struct fib_nh_common *nhc, int err,
+ const struct net *net),
- TP_ARGS(tb_id, flp, nhc, err),
+ TP_ARGS(tb_id, flp, nhc, err, net),
TP_STRUCT__entry(
__field( u32, tb_id )
@@ -35,6 +36,7 @@ TRACE_EVENT(fib_table_lookup,
__field( u16, sport )
__field( u16, dport )
__array(char, name, IFNAMSIZ )
+ __field( u64, net_cookie )
),
TP_fast_assign(
@@ -90,13 +92,16 @@ TRACE_EVENT(fib_table_lookup,
in6 = (struct in6_addr *)__entry->gw6;
*in6 = in6addr_any;
}
+
+ __entry->net_cookie = net->net_cookie;
),
- TP_printk("table %u oif %d iif %d proto %u %pI4/%u -> %pI4/%u tos %d scope %d flags %x ==> dev %s gw %pI4/%pI6c err %d",
+ TP_printk("table %u oif %d iif %d proto %u %pI4/%u -> %pI4/%u tos %d scope %d flags %x ==> dev %s gw %pI4/%pI6c err %d net_cookie %llu",
__entry->tb_id, __entry->oif, __entry->iif, __entry->proto,
__entry->src, __entry->sport, __entry->dst, __entry->dport,
__entry->tos, __entry->scope, __entry->flags,
- __entry->name, __entry->gw4, __entry->gw6, __entry->err)
+ __entry->name, __entry->gw4, __entry->gw6, __entry->err,
+ __entry->net_cookie)
);
#endif /* _TRACE_FIB_H */
diff --git a/include/trace/events/fib6.h b/include/trace/events/fib6.h
index 8d22b2e98d48..e58facd2d7d4 100644
--- a/include/trace/events/fib6.h
+++ b/include/trace/events/fib6.h
@@ -34,6 +34,7 @@ TRACE_EVENT(fib6_table_lookup,
__field( u8, rt_type )
__array( char, name, IFNAMSIZ )
__array( __u8, gw, 16 )
+ __field( u64, net_cookie )
),
TP_fast_assign(
@@ -76,13 +77,16 @@ TRACE_EVENT(fib6_table_lookup,
in6 = (struct in6_addr *)__entry->gw;
*in6 = res->nh->fib_nh_gw6;
}
+
+ __entry->net_cookie = net->net_cookie;
),
- TP_printk("table %3u oif %d iif %d proto %u %pI6c/%u -> %pI6c/%u flowlabel %#x tos %d scope %d flags %x ==> dev %s gw %pI6c err %d",
+ TP_printk("table %3u oif %d iif %d proto %u %pI6c/%u -> %pI6c/%u flowlabel %#x tos %d scope %d flags %x ==> dev %s gw %pI6c err %d net_cookie %llu",
__entry->tb_id, __entry->oif, __entry->iif, __entry->proto,
__entry->src, __entry->sport, __entry->dst, __entry->dport,
__entry->flowlabel, __entry->tos, __entry->scope,
- __entry->flags, __entry->name, __entry->gw, __entry->err)
+ __entry->flags, __entry->name, __entry->gw, __entry->err,
+ __entry->net_cookie)
);
#endif /* _TRACE_FIB6_H */
diff --git a/include/trace/events/fscache.h b/include/trace/events/fscache.h
index f1a73aa83fbb..8735d428ebd9 100644
--- a/include/trace/events/fscache.h
+++ b/include/trace/events/fscache.h
@@ -460,13 +460,13 @@ TRACE_EVENT(fscache_relinquish,
);
TRACE_EVENT(fscache_invalidate,
- TP_PROTO(struct fscache_cookie *cookie, loff_t new_size),
+ TP_PROTO(struct fscache_cookie *cookie, uoff_t new_size),
TP_ARGS(cookie, new_size),
TP_STRUCT__entry(
__field(unsigned int, cookie )
- __field(loff_t, new_size )
+ __field(uoff_t, new_size )
),
TP_fast_assign(
@@ -479,14 +479,14 @@ TRACE_EVENT(fscache_invalidate,
);
TRACE_EVENT(fscache_resize,
- TP_PROTO(struct fscache_cookie *cookie, loff_t new_size),
+ TP_PROTO(struct fscache_cookie *cookie, uoff_t new_size),
TP_ARGS(cookie, new_size),
TP_STRUCT__entry(
__field(unsigned int, cookie )
- __field(loff_t, old_size )
- __field(loff_t, new_size )
+ __field(uoff_t, old_size )
+ __field(uoff_t, new_size )
),
TP_fast_assign(
diff --git a/include/trace/events/huge_memory.h b/include/trace/events/huge_memory.h
index 5a48c5406cce..5fb4d92cfd84 100644
--- a/include/trace/events/huge_memory.h
+++ b/include/trace/events/huge_memory.h
@@ -55,10 +55,10 @@ SCAN_STATUS
TRACE_EVENT(mm_khugepaged_scan_pmd,
- TP_PROTO(struct mm_struct *mm, struct folio *folio,
+ TP_PROTO(struct mm_struct *mm, unsigned long pfn,
int referenced, int none_or_zero, int status, int unmapped),
- TP_ARGS(mm, folio, referenced, none_or_zero, status, unmapped),
+ TP_ARGS(mm, pfn, referenced, none_or_zero, status, unmapped),
TP_STRUCT__entry(
__field(struct mm_struct *, mm)
@@ -71,7 +71,7 @@ TRACE_EVENT(mm_khugepaged_scan_pmd,
TP_fast_assign(
__entry->mm = mm;
- __entry->pfn = folio ? folio_pfn(folio) : -1;
+ __entry->pfn = pfn;
__entry->referenced = referenced;
__entry->none_or_zero = none_or_zero;
__entry->status = status;
@@ -178,10 +178,10 @@ TRACE_EVENT(mm_collapse_huge_page_swapin,
TRACE_EVENT(mm_khugepaged_scan_file,
- TP_PROTO(struct mm_struct *mm, struct folio *folio, struct file *file,
+ TP_PROTO(struct mm_struct *mm, unsigned long pfn, struct file *file,
int present, int swap, int result),
- TP_ARGS(mm, folio, file, present, swap, result),
+ TP_ARGS(mm, pfn, file, present, swap, result),
TP_STRUCT__entry(
__field(struct mm_struct *, mm)
@@ -194,7 +194,7 @@ TRACE_EVENT(mm_khugepaged_scan_file,
TP_fast_assign(
__entry->mm = mm;
- __entry->pfn = folio ? folio_pfn(folio) : -1;
+ __entry->pfn = pfn;
__assign_str(filename);
__entry->present = present;
__entry->swap = swap;
@@ -211,10 +211,10 @@ 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,
+ TP_PROTO(struct mm_struct *mm, unsigned long new_pfn, pgoff_t index,
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_ARGS(mm, new_pfn, index, addr, is_shmem, file, nr, result),
TP_STRUCT__entry(
__field(struct mm_struct *, mm)
__field(unsigned long, hpfn)
@@ -228,7 +228,7 @@ TRACE_EVENT(mm_khugepaged_collapse_file,
TP_fast_assign(
__entry->mm = mm;
- __entry->hpfn = new_folio ? folio_pfn(new_folio) : -1;
+ __entry->hpfn = new_pfn;
__entry->index = index;
__entry->addr = addr;
__entry->is_shmem = is_shmem;
diff --git a/include/trace/events/kvm.h b/include/trace/events/kvm.h
index b282e3a86769..07013f88e655 100644
--- a/include/trace/events/kvm.h
+++ b/include/trace/events/kvm.h
@@ -4,8 +4,14 @@
#include <linux/tracepoint.h>
+#undef UNPACK_KVM
+#define UNPACK_KVM(name) name
#undef TRACE_SYSTEM
-#define TRACE_SYSTEM kvm
+#define TRACE_SYSTEM UNPACK_KVM(KVM_DEV_NAME)
+#undef TRACE_SYSTEM_VAR
+#define TRACE_SYSTEM_VAR kvm
+#undef TRACE_INCLUDE_FILE
+#define TRACE_INCLUDE_FILE kvm
#define ERSN(x) { KVM_EXIT_##x, "KVM_EXIT_" #x }
@@ -358,13 +364,13 @@ TRACE_EVENT(kvm_dirty_ring_exit,
TP_printk("vcpu %d", __entry->vcpu_id)
);
-#ifdef CONFIG_KVM_GENERIC_MEMORY_ATTRIBUTES
+#ifdef CONFIG_KVM_VM_MEMORY_ATTRIBUTES
/*
* @start: Starting address of guest memory range
* @end: End address of guest memory range
* @attr: The value of the attribute being set.
*/
-TRACE_EVENT(kvm_vm_set_mem_attributes,
+TRACE_EVENT(kvm_set_vm_mem_attributes,
TP_PROTO(gfn_t start, gfn_t end, unsigned long attr),
TP_ARGS(start, end, attr),
@@ -383,7 +389,7 @@ TRACE_EVENT(kvm_vm_set_mem_attributes,
TP_printk("%#016llx -- %#016llx [0x%lx]",
__entry->start, __entry->end, __entry->attr)
);
-#endif /* CONFIG_KVM_GENERIC_MEMORY_ATTRIBUTES */
+#endif /* CONFIG_KVM_VM_MEMORY_ATTRIBUTES */
TRACE_EVENT(kvm_unmap_hva_range,
TP_PROTO(unsigned long start, unsigned long end),
diff --git a/include/trace/events/landlock.h b/include/trace/events/landlock.h
index f82588f6f90e..6d9d9e7c7ca2 100644
--- a/include/trace/events/landlock.h
+++ b/include/trace/events/landlock.h
@@ -10,14 +10,19 @@
#if !defined(_TRACE_LANDLOCK_H) || defined(TRACE_HEADER_MULTI_READ)
#define _TRACE_LANDLOCK_H
+#include <linux/in.h>
+#include <linux/in6.h>
#include <linux/landlock.h>
+#include <linux/socket.h>
#include <linux/string.h>
#include <linux/string_helpers.h>
#include <linux/tracepoint.h>
#include <linux/trace_seq.h>
#include <net/af_unix.h>
+enum landlock_request_type;
struct dentry;
+struct landlock_blockers;
struct landlock_domain;
struct landlock_hierarchy;
struct landlock_rule;
@@ -26,8 +31,26 @@ struct path;
struct sock;
struct task_struct;
+static_assert(sizeof(access_mask_t) <= sizeof(u64));
+
+TRACE_DEFINE_ENUM(LANDLOCK_REQUEST_FS_CHANGE_TOPOLOGY);
+TRACE_DEFINE_ENUM(LANDLOCK_REQUEST_FS_ACCESS);
+TRACE_DEFINE_ENUM(LANDLOCK_REQUEST_NET_ACCESS);
+TRACE_DEFINE_ENUM(LANDLOCK_REQUEST_NAMESPACE);
+TRACE_DEFINE_ENUM(LANDLOCK_REQUEST_CAPABILITY);
+
#ifdef CREATE_TRACE_POINTS
+/* About 6 KiB, leaving about 2 KiB for sibling helpers and fixed fields. */
+#define TRACE_UNTRUSTED_STR_OUTPUT_SIZE \
+ (TRACE_SEQ_BUFFER_SIZE - TRACE_SEQ_BUFFER_SIZE / 4)
+
+/*
+ * A raw UTF-8 ellipsis (…) marks truncation and cannot collide with escaped
+ * input: ESCAPE_NAP renders every non-ASCII input byte in octal.
+ */
+#define TRACE_TRUNCATION_MARKER "\xe2\x80\xa6"
+
/*
* Escapes @len bytes of an untrusted string into the trace sequence @p so it
* cannot inject field separators or control characters into the ftrace text
@@ -37,33 +60,59 @@ struct task_struct;
* NUL-terminated or carries embedded NUL bytes (an abstract socket name) is
* escaped in full instead of being truncated at the first NUL.
*
- * Return: a pointer into @p's buffer, or NULL if @src is NULL or the buffer is
- * exhausted (normal when the trace buffer is full).
+ * Strings that exceed the output limit retain the largest complete escaped
+ * prefix followed by the truncation marker.
+ *
+ * Return: a pointer into @p's buffer, or NULL if @src is NULL or the fixed
+ * output reservation is unavailable.
*/
static inline const char *
__trace_print_untrusted_str(struct trace_seq *p, const char *src, size_t len)
{
+ const unsigned int escape_flags = ESCAPE_SPACE | ESCAPE_SPECIAL |
+ ESCAPE_NAP | ESCAPE_APPEND |
+ ESCAPE_OCTAL;
+ const size_t marker_len = sizeof(TRACE_TRUNCATION_MARKER) - 1;
+ size_t buf_size, prefix_len, prefix_size;
int escaped_size;
char *buf;
- size_t buf_size = seq_buf_get_buf(&p->seq, &buf);
- const char *ret = trace_seq_buffer_ptr(p);
+ const char *ret;
- /* Buffer exhaustion is normal when the trace buffer is full. */
- if (!src || buf_size == 0)
+ buf_size = seq_buf_get_buf(&p->seq, &buf);
+ if (!src || buf_size < TRACE_UNTRUSTED_STR_OUTPUT_SIZE)
return NULL;
- escaped_size =
- string_escape_mem(src, len, buf, buf_size,
- ESCAPE_SPACE | ESCAPE_SPECIAL | ESCAPE_NAP |
- ESCAPE_APPEND | ESCAPE_OCTAL,
- " ='\"\\");
- if (unlikely(escaped_size >= buf_size)) {
- /* We need some room for the final '\0'. */
- seq_buf_set_overflow(&p->seq);
- p->full = 1;
- return NULL;
+ ret = trace_seq_buffer_ptr(p);
+ escaped_size = string_escape_mem(src, len, buf,
+ TRACE_UNTRUSTED_STR_OUTPUT_SIZE,
+ escape_flags, " ='\"\\");
+ if (likely(escaped_size < TRACE_UNTRUSTED_STR_OUTPUT_SIZE)) {
+ seq_buf_commit(&p->seq, escaped_size);
+ trace_seq_putc(p, 0);
+ return ret;
}
- seq_buf_commit(&p->seq, escaped_size);
+
+ prefix_len = 0;
+ prefix_size = 0;
+ while (prefix_len < len) {
+ const char *const src_char = src + prefix_len;
+ int char_size;
+
+ char_size = string_escape_mem(src_char, 1, NULL, 0,
+ escape_flags, " ='\"\\");
+ if (char_size > TRACE_UNTRUSTED_STR_OUTPUT_SIZE - marker_len -
+ 1 - prefix_size)
+ break;
+ prefix_size += char_size;
+ prefix_len++;
+ }
+
+ escaped_size = string_escape_mem(src, prefix_len, buf, prefix_size,
+ escape_flags, " ='\"\\");
+ if (WARN_ON_ONCE(escaped_size != prefix_size))
+ return NULL;
+ memcpy(buf + prefix_size, TRACE_TRUNCATION_MARKER, marker_len);
+ seq_buf_commit(&p->seq, prefix_size + marker_len);
trace_seq_putc(p, 0);
return ret;
}
@@ -72,7 +121,7 @@ __trace_print_untrusted_str(struct trace_seq *p, const char *src, size_t len)
* Fills the dense per-domain-layer array layers (one access mask per layer,
* indexed by level - 1) from rule's sparse layer stack, keeping only the
* requested rights (access_request). Layers with no matching rule entry get
- * a zero mask. Shared by the check_rule_fs and check_rule_net events.
+ * a zero mask. Shared by the check_rule_inode and check_rule_net_port events.
*
* rule->layers is sorted by ascending level, with levels in the domain's
* [1, num_layers] range (see landlock_merge_ruleset()), so every entry maps
@@ -146,6 +195,9 @@ static inline const char *__trace_landlock_print_layers(
/* Maps a shared _LANDLOCK_*_NAMES entry to a __print_flags() pair. */
#define _LANDLOCK_NAME_ENTRY(mask, name) { mask, name }
+#define _LANDLOCK_FS_BLOCKER_TYPE_NAMES \
+ { LANDLOCK_REQUEST_FS_CHANGE_TOPOLOGY, "change_topology" }
+
/**
* DOC: Landlock trace events
*
@@ -156,22 +208,22 @@ static inline const char *__trace_landlock_print_layers(
* Decision context
* ~~~~~~~~~~~~~~~~
*
- * A denial event, together with the lifecycle events, exposes the full
- * set of inputs the verdict consumed, so a consumer that tracked domain
- * creation (landlock_create_ruleset, landlock_create_domain) can verify
- * or reproduce the Landlock decision rather than merely observe it
- * happened. In who/what/why terms: who is the denying domain (the domain
- * field, always the subject that enforced the policy, never the current
- * task), what is the operation and its object, and why is every other
- * input the verdict weighed.
+ * A denial event identifies the domain whose policy denied the request, the
+ * Landlock operation and policy object that were checked, and the blocker or
+ * domain relationship responsible for the denial. When tracing starts with
+ * sandbox construction, ruleset and domain events provide the policy history
+ * needed to interpret these identifiers. The denying domain is the subject
+ * that enforced the policy, not necessarily current. Generic tracepoints can
+ * provide additional operational context.
*
* Lifecycle consistency
* ~~~~~~~~~~~~~~~~~~~~~~
*
- * Lifecycle events are balanced: a creation event always has a matching
- * deallocation event and vice versa, so an eBPF program can model object
- * lifetimes from the trace stream without reconciliation logic. A creation
- * event fires while the object is still private to the calling thread
+ * Lifecycle emission is balanced: a creation event always has a matching
+ * deallocation event and vice versa. A consumer that observes an object's
+ * complete lifetime can model it from this pair; one that attaches late or
+ * loses exported records must reconcile incomplete state. A creation event
+ * fires while the object is still private to the calling thread
* (landlock_create_ruleset fires before the ruleset's file descriptor is
* installed, so it cannot race a concurrent :manpage:`close(2)`); if fd
* installation later fails and the ruleset is freed, free_ruleset still
@@ -207,8 +259,8 @@ static inline const char *__trace_landlock_print_layers(
* Field encoding
* ~~~~~~~~~~~~~~
*
- * Fields that mirror the Landlock UAPI use the same C types and endianness
- * (e.g. network ports are __u64 in host endianness, like
+ * Fields that mirror the Landlock UAPI preserve their widths and endianness
+ * (e.g. network ports are u64 in host endianness, like
* landlock_net_port_attr.port). Per-event details, such as where a value
* is byte-swapped, live in the field's own kdoc.
*
@@ -226,13 +278,14 @@ static inline const char *__trace_landlock_print_layers(
* Every denial event shares three fields. domain is the ID of the
* innermost domain that blocked the access. same_exec tells whether the
* current task is the same executable that entered that domain. logged is
- * the domain's audit-logging decision for this denial (its log_status is
- * enabled and the per-execution flag selected by same_exec is set); a
- * stateless ftrace filter can select the denials the domain submits to
- * audit with logged==1, without reconstructing it from the per-execution
- * log flags. Denial events order their fields as domain, same_exec,
- * logged, then blockers (deny_access events only), then the type-specific
- * object fields, then any variable-length field.
+ * the complete audit-submission selection for this denial: the domain's
+ * log_status and per-execution flag, per-object or per-member quiet rules,
+ * and request-specific no-audit options. This excludes global audit state
+ * and audit-side filters. A stateless ftrace filter can select the denials
+ * the domain submits to audit with logged==1, without reconstructing those
+ * inputs. Denial events order their shared fields as domain, same_exec,
+ * and logged. Access and permission denial events follow these with the
+ * blockers verdict input, type-specific fields, and any variable-length field.
*
* Relational referents
* ~~~~~~~~~~~~~~~~~~~~~
@@ -245,6 +298,16 @@ static inline const char *__trace_landlock_print_layers(
* the two parties without kernel-internal state. The ID is a scalar
* snapshot, not a live domain pointer that could dangle: an optional
* relational referent is a scalar (0 sentinel), not a nullable pointer.
+ * Nonzero IDs are unique within one boot. For ptrace, same_exec instead
+ * describes the tracer, even for
+ * PTRACE_TRACEME, and may differ from the current task.
+ *
+ * Blocker fields
+ * ~~~~~~~~~~~~~~
+ *
+ * Blocker arguments identify the request type and carry its final missing
+ * access subset when applicable. The type determines how to interpret the
+ * access value.
*/
/*
@@ -283,26 +346,31 @@ TRACE_EVENT(landlock_create_ruleset,
TP_ARGS(ruleset),
TP_STRUCT__entry(
- __field( __u64, ruleset_id )
- __field( __u32, ruleset_version )
- __field( access_mask_t, handled_fs )
- __field( access_mask_t, handled_net )
- __field( access_mask_t, scoped )
+ __field( u64, ruleset_id )
+ __field( u64, ruleset_version )
+ __field( access_mask_t, handled_fs )
+ __field( access_mask_t, handled_net )
+ __field( access_mask_t, scoped )
+ __field( access_mask_t, handled_permissions )
),
TP_fast_assign(
__entry->ruleset_id = ruleset->id;
__entry->ruleset_version = ruleset->version;
- __entry->handled_fs = ruleset->handled_masks.fs;
- __entry->handled_net = ruleset->handled_masks.net;
- __entry->scoped = ruleset->handled_masks.scope;
+ __entry->handled_fs = ruleset->layer.handled.fs;
+ __entry->handled_net = ruleset->layer.handled.net;
+ __entry->scoped = ruleset->layer.handled.scope;
+ __entry->handled_permissions =
+ ruleset->layer.handled.permissions;
),
- TP_printk("ruleset=%llx.%u handled_fs=%s handled_net=%s scoped=%s",
+ TP_printk("ruleset=%llx.%llu handled_fs=%s handled_net=%s scoped=%s handled_permissions=%s",
__entry->ruleset_id, __entry->ruleset_version,
__print_flags(__entry->handled_fs, "|", _LANDLOCK_ACCESS_FS_NAMES),
__print_flags(__entry->handled_net, "|", _LANDLOCK_ACCESS_NET_NAMES),
- __print_flags(__entry->scoped, "|", _LANDLOCK_SCOPE_NAMES))
+ __print_flags(__entry->scoped, "|", _LANDLOCK_SCOPE_NAMES),
+ __print_flags(__entry->handled_permissions, "|",
+ _LANDLOCK_PERMISSION_NAMES))
);
/**
@@ -323,8 +391,8 @@ TRACE_EVENT(landlock_free_ruleset,
TP_ARGS(ruleset),
TP_STRUCT__entry(
- __field( __u64, ruleset_id )
- __field( __u32, ruleset_version )
+ __field( u64, ruleset_id )
+ __field( u64, ruleset_version )
),
TP_fast_assign(
@@ -332,17 +400,19 @@ TRACE_EVENT(landlock_free_ruleset,
__entry->ruleset_version = ruleset->version;
),
- TP_printk("ruleset=%llx.%u",
+ TP_printk("ruleset=%llx.%llu",
__entry->ruleset_id, __entry->ruleset_version)
);
/**
- * landlock_add_rule_fs - Filesystem rule added to a ruleset
+ * landlock_add_rule_path_beneath - Path-beneath rule added to a ruleset
*
* @ruleset: Source ruleset (never NULL).
- * @access_rights: Effective access mask stored in the rule, not the raw
- * sys_landlock_add_rule() argument (unhandled rights
- * added).
+ * @flags: Complete validated landlock_add_rule_flags value supplied by this
+ * successful call, not the rule's accumulated quiet state.
+ * @access_rights: Canonical per-call access mask passed to
+ * landlock_insert_rule() after normalization, not the raw
+ * sys_landlock_add_rule() argument or accumulated rule.
* @path: Filesystem path for the rule (never NULL).
* @pathname: Resolved absolute path string (never NULL; error placeholder
* on resolution failure).
@@ -351,17 +421,17 @@ TRACE_EVENT(landlock_free_ruleset,
* the reported ruleset is a stable snapshot that no concurrent writer can
* change.
*/
-TRACE_EVENT(landlock_add_rule_fs,
+TRACE_EVENT(landlock_add_rule_path_beneath,
- TP_PROTO(const struct landlock_ruleset *ruleset,
- access_mask_t access_rights, const struct path *path,
+ TP_PROTO(const struct landlock_ruleset *ruleset, u32 flags,
+ u64 access_rights, const struct path *path,
const char *pathname),
- TP_ARGS(ruleset, access_rights, path, pathname),
+ TP_ARGS(ruleset, flags, access_rights, path, pathname),
TP_STRUCT__entry(
- __field( __u64, ruleset_id )
- __field( __u32, ruleset_version )
+ __field( u64, ruleset_id )
+ __field( u64, ruleset_version )
__field( access_mask_t, access_rights )
__field( dev_t, dev )
__field( ino_t, ino )
@@ -382,7 +452,7 @@ TRACE_EVENT(landlock_add_rule_fs,
__assign_str(pathname);
),
- TP_printk("ruleset=%llx.%u access_rights=%s dev=%u:%u ino=%lu path=%s",
+ TP_printk("ruleset=%llx.%llu access_rights=%s dev=%u:%u ino=%lu path=%s",
__entry->ruleset_id, __entry->ruleset_version,
__print_flags(__entry->access_rights, "|", _LANDLOCK_ACCESS_FS_NAMES),
MAJOR(__entry->dev), MINOR(__entry->dev), __entry->ino,
@@ -391,31 +461,33 @@ TRACE_EVENT(landlock_add_rule_fs,
);
/**
- * landlock_add_rule_net - Network port rule added to a ruleset
+ * landlock_add_rule_net_port - Network-port rule added to a ruleset
*
* @ruleset: Source ruleset (never NULL).
- * @access_rights: Effective access mask stored in the rule, not the raw
- * sys_landlock_add_rule() argument (unhandled rights
- * added).
- * @port: Network port, the landlock_net_port_attr.port UAPI value
- * forwarded directly.
+ * @flags: Complete validated landlock_add_rule_flags value supplied by this
+ * successful call, not the rule's accumulated quiet state.
+ * @access_rights: Canonical per-call access mask passed to
+ * landlock_insert_rule() after normalization, not the raw
+ * sys_landlock_add_rule() argument or accumulated rule.
+ * @port: Network port in host endianness, forwarded directly from
+ * &landlock_net_port_attr.port.
*
* Emitted by sys_landlock_add_rule() under the modified ruleset's lock, so
* the reported ruleset is a stable snapshot that no concurrent writer can
* change.
*/
-TRACE_EVENT(landlock_add_rule_net,
+TRACE_EVENT(landlock_add_rule_net_port,
- TP_PROTO(const struct landlock_ruleset *ruleset,
- access_mask_t access_rights, __u64 port),
+ TP_PROTO(const struct landlock_ruleset *ruleset, u32 flags,
+ u64 access_rights, u64 port),
- TP_ARGS(ruleset, access_rights, port),
+ TP_ARGS(ruleset, flags, access_rights, port),
TP_STRUCT__entry(
- __field( __u64, ruleset_id )
- __field( __u32, ruleset_version )
+ __field( u64, ruleset_id )
+ __field( u64, ruleset_version )
__field( access_mask_t, access_rights )
- __field( __u64, port )
+ __field( u64, port )
),
TP_fast_assign(
@@ -426,13 +498,110 @@ TRACE_EVENT(landlock_add_rule_net,
__entry->port = port;
),
- TP_printk("ruleset=%llx.%u access_rights=%s port=%llu",
+ TP_printk("ruleset=%llx.%llu access_rights=%s port=%llu",
__entry->ruleset_id, __entry->ruleset_version,
__print_flags(__entry->access_rights, "|", _LANDLOCK_ACCESS_NET_NAMES),
__entry->port)
);
/**
+ * landlock_add_rule_namespace - Namespace rule added to a ruleset
+ *
+ * @ruleset: Source ruleset (never NULL).
+ * @flags: Complete validated landlock_add_rule_flags value supplied by this
+ * successful call, not the rule's accumulated quiet state.
+ * @permissions: Validated permission mask from the rule attribute.
+ * @allowed_namespace_types: Effective known namespace types allowed by this
+ * call, using CLONE_NEW* values.
+ * @quiet_namespace_types: Effective known namespace types quieted by this
+ * call, using CLONE_NEW* values.
+ *
+ * Emitted by sys_landlock_add_rule() under the modified ruleset's lock, so
+ * the reported ruleset is a stable snapshot that no concurrent writer can
+ * change.
+ */
+TRACE_EVENT(landlock_add_rule_namespace,
+
+ TP_PROTO(const struct landlock_ruleset *ruleset, u32 flags,
+ u64 permissions, u64 allowed_namespace_types,
+ u64 quiet_namespace_types),
+
+ TP_ARGS(ruleset, flags, permissions, allowed_namespace_types,
+ quiet_namespace_types),
+
+ TP_STRUCT__entry(
+ __field( u64, ruleset_id )
+ __field( u64, ruleset_version )
+ __field( access_mask_t, permissions )
+ __field( u64, allowed_namespace_types )
+ __field( u64, quiet_namespace_types )
+ ),
+
+ TP_fast_assign(
+ lockdep_assert_held(&ruleset->lock);
+ __entry->ruleset_id = ruleset->id;
+ __entry->ruleset_version = ruleset->version;
+ __entry->permissions = permissions;
+ __entry->allowed_namespace_types = allowed_namespace_types;
+ __entry->quiet_namespace_types = quiet_namespace_types;
+ ),
+
+ TP_printk("ruleset=%llx.%llu permissions=%s allowed_namespace_types=0x%llx quiet_namespace_types=0x%llx",
+ __entry->ruleset_id, __entry->ruleset_version,
+ __print_flags(__entry->permissions, "|",
+ _LANDLOCK_PERMISSION_NAMES),
+ __entry->allowed_namespace_types,
+ __entry->quiet_namespace_types)
+);
+
+/**
+ * landlock_add_rule_capability - Capability rule added to a ruleset
+ *
+ * @ruleset: Source ruleset (never NULL).
+ * @flags: Complete validated landlock_add_rule_flags value supplied by this
+ * successful call, not the rule's accumulated quiet state.
+ * @permissions: Validated permission mask from the rule attribute.
+ * @allowed_capabilities: Effective known capabilities allowed by this call.
+ * @quiet_capabilities: Effective known capabilities quieted by this call.
+ *
+ * Emitted by sys_landlock_add_rule() under the modified ruleset's lock, so
+ * the reported ruleset is a stable snapshot that no concurrent writer can
+ * change.
+ */
+TRACE_EVENT(landlock_add_rule_capability,
+
+ TP_PROTO(const struct landlock_ruleset *ruleset, u32 flags,
+ u64 permissions, u64 allowed_capabilities,
+ u64 quiet_capabilities),
+
+ TP_ARGS(ruleset, flags, permissions, allowed_capabilities,
+ quiet_capabilities),
+
+ TP_STRUCT__entry(
+ __field( u64, ruleset_id )
+ __field( u64, ruleset_version )
+ __field( access_mask_t, permissions )
+ __field( u64, allowed_capabilities )
+ __field( u64, quiet_capabilities )
+ ),
+
+ TP_fast_assign(
+ lockdep_assert_held(&ruleset->lock);
+ __entry->ruleset_id = ruleset->id;
+ __entry->ruleset_version = ruleset->version;
+ __entry->permissions = permissions;
+ __entry->allowed_capabilities = allowed_capabilities;
+ __entry->quiet_capabilities = quiet_capabilities;
+ ),
+
+ TP_printk("ruleset=%llx.%llu permissions=%s allowed_capabilities=0x%llx quiet_capabilities=0x%llx",
+ __entry->ruleset_id, __entry->ruleset_version,
+ __print_flags(__entry->permissions, "|",
+ _LANDLOCK_PERMISSION_NAMES),
+ __entry->allowed_capabilities, __entry->quiet_capabilities)
+);
+
+/**
* landlock_create_domain - New domain created
*
* @domain: Newly created domain (never NULL, immutable after creation).
@@ -459,10 +628,10 @@ TRACE_EVENT(landlock_create_domain,
TP_ARGS(domain, ruleset),
TP_STRUCT__entry(
- __field( __u64, domain_id )
- __field( __u64, parent_id )
- __field( __u64, ruleset_id )
- __field( __u32, ruleset_version )
+ __field( u64, domain_id )
+ __field( u64, parent_id )
+ __field( u64, ruleset_id )
+ __field( u64, ruleset_version )
),
TP_fast_assign(
@@ -474,7 +643,7 @@ TRACE_EVENT(landlock_create_domain,
__entry->ruleset_version = ruleset->version;
),
- TP_printk("domain=%llx parent=%llx ruleset=%llx.%u",
+ TP_printk("domain=%llx parent=%llx ruleset=%llx.%llu",
__entry->domain_id, __entry->parent_id,
__entry->ruleset_id, __entry->ruleset_version)
);
@@ -521,7 +690,7 @@ TRACE_EVENT(landlock_enforce_domain,
TP_ARGS(domain, complete, process_wide, no_new_privs),
TP_STRUCT__entry(
- __field( __u64, domain_id )
+ __field( u64, domain_id )
__field( bool, complete )
__field( bool, process_wide )
__field( bool, no_new_privs )
@@ -559,8 +728,8 @@ TRACE_EVENT(landlock_free_domain,
TP_ARGS(hierarchy),
TP_STRUCT__entry(
- __field( __u64, domain_id )
- __field( __u64, denials )
+ __field( u64, domain_id )
+ __field( u64, denials )
),
TP_fast_assign(
@@ -573,7 +742,7 @@ TRACE_EVENT(landlock_free_domain,
);
/**
- * landlock_check_rule_fs - Filesystem rule evaluated during access check
+ * landlock_check_rule_inode - Inode rule evaluated during access check
*
* @domain: Enforcing domain (never NULL).
* @rule: Matching rule with per-layer access masks (never NULL).
@@ -586,16 +755,16 @@ TRACE_EVENT(landlock_free_domain,
* domain layer. See Documentation/trace/events-landlock.rst for how to
* interpret it.
*/
-TRACE_EVENT(landlock_check_rule_fs,
+TRACE_EVENT(landlock_check_rule_inode,
TP_PROTO(const struct landlock_domain *domain,
const struct landlock_rule *rule,
- access_mask_t access_request, const struct dentry *dentry),
+ u64 access_request, const struct dentry *dentry),
TP_ARGS(domain, rule, access_request, dentry),
TP_STRUCT__entry(
- __field( __u64, domain_id )
+ __field( u64, domain_id )
__field( access_mask_t, access_request )
__field( dev_t, dev )
__field( ino_t, ino )
@@ -612,7 +781,8 @@ TRACE_EVENT(landlock_check_rule_fs,
__trace_landlock_fill_layers(__get_dynamic_array(grants),
__get_dynamic_array_len(grants) /
sizeof(access_mask_t),
- rule, access_request);
+ rule,
+ (access_mask_t)access_request);
),
TP_printk("domain=%llx access_request=%s dev=%u:%u ino=%lu grants=%s",
@@ -623,7 +793,7 @@ TRACE_EVENT(landlock_check_rule_fs,
);
/**
- * landlock_check_rule_net - Network port rule evaluated during access check
+ * landlock_check_rule_net_port - Network port rule evaluated
*
* @domain: Enforcing domain (never NULL).
* @rule: Matching rule with per-layer access masks (never NULL).
@@ -635,18 +805,18 @@ TRACE_EVENT(landlock_check_rule_fs,
* layer. See Documentation/trace/events-landlock.rst for how to
* interpret it.
*/
-TRACE_EVENT(landlock_check_rule_net,
+TRACE_EVENT(landlock_check_rule_net_port,
TP_PROTO(const struct landlock_domain *domain,
const struct landlock_rule *rule,
- access_mask_t access_request, __u64 port),
+ u64 access_request, u64 port),
TP_ARGS(domain, rule, access_request, port),
TP_STRUCT__entry(
- __field( __u64, domain_id )
+ __field( u64, domain_id )
__field( access_mask_t, access_request )
- __field( __u64, port )
+ __field( u64, port )
__dynamic_array(access_mask_t, grants,
domain->num_layers)
),
@@ -659,7 +829,8 @@ TRACE_EVENT(landlock_check_rule_net,
__trace_landlock_fill_layers(__get_dynamic_array(grants),
__get_dynamic_array_len(grants) /
sizeof(access_mask_t),
- rule, access_request);
+ rule,
+ (access_mask_t)access_request);
),
TP_printk("domain=%llx access_request=%s port=%llu grants=%s",
@@ -676,8 +847,7 @@ TRACE_EVENT(landlock_check_rule_net,
* domain field.
* @same_exec: Whether the current task entered the denying domain itself.
* @logged: The domain's audit-logging decision for this denial.
- * @blockers: Access mask that was blocked (zero for a mount-topology
- * change, whose only blocker is the operation itself).
+ * @blockers: Request type and final missing access subset (never NULL).
* @path: Filesystem path that was denied (never NULL).
* @pathname: Resolved path string (never NULL; an error placeholder on
* resolution failure).
@@ -687,16 +857,17 @@ TRACE_EVENT(landlock_check_rule_net,
TRACE_EVENT(landlock_deny_access_fs,
TP_PROTO(const struct landlock_hierarchy *hierarchy, bool same_exec,
- bool logged, access_mask_t blockers, const struct path *path,
- const char *pathname),
+ bool logged, const struct landlock_blockers *blockers,
+ const struct path *path, const char *pathname),
TP_ARGS(hierarchy, same_exec, logged, blockers, path, pathname),
TP_STRUCT__entry(
- __field( __u64, domain_id )
+ __field( u64, domain_id )
__field( bool, same_exec )
__field( bool, logged )
- __field( access_mask_t, blockers )
+ __field( enum landlock_request_type, blockers_type )
+ __field( access_mask_t, blockers_access )
__field( dev_t, dev )
__field( ino_t, ino )
__string( pathname, pathname )
@@ -708,7 +879,8 @@ TRACE_EVENT(landlock_deny_access_fs,
__entry->domain_id = hierarchy->id;
__entry->same_exec = same_exec;
__entry->logged = logged;
- __entry->blockers = blockers;
+ __entry->blockers_type = blockers->type;
+ __entry->blockers_access = blockers->access;
__entry->dev = path->dentry->d_sb->s_dev;
/*
* A negative dentry has no backing inode, so mirror the
@@ -720,12 +892,20 @@ TRACE_EVENT(landlock_deny_access_fs,
TP_printk("domain=%llx same_exec=%d logged=%d blockers=%s dev=%u:%u ino=%lu path=%s",
__entry->domain_id, __entry->same_exec, __entry->logged,
- __print_flags(__entry->blockers, "|", _LANDLOCK_ACCESS_FS_NAMES),
+ __entry->blockers_type == LANDLOCK_REQUEST_FS_ACCESS ?
+ __print_flags(__entry->blockers_access, "|", _LANDLOCK_ACCESS_FS_NAMES) :
+ __print_symbolic(__entry->blockers_type,
+ _LANDLOCK_FS_BLOCKER_TYPE_NAMES),
MAJOR(__entry->dev), MINOR(__entry->dev), __entry->ino,
__trace_print_untrusted_str(p, __get_str(pathname),
__get_dynamic_array_len(pathname) - 1))
);
+static_assert(offsetof(struct sockaddr_in, sin_port) ==
+ offsetof(struct sockaddr_in6, sin6_port));
+static_assert(sizeof_field(struct sockaddr_in, sin_port) ==
+ sizeof_field(struct sockaddr_in6, sin6_port));
+
/**
* landlock_deny_access_net - Network access denied
*
@@ -733,67 +913,183 @@ TRACE_EVENT(landlock_deny_access_fs,
* domain field.
* @same_exec: Whether the current task entered the denying domain itself.
* @logged: The domain's audit-logging decision for this denial.
- * @blockers: Access mask that was blocked.
- * @sk: Socket object (never NULL), read without a socket lock, so its
- * fields are a best-effort snapshot. The denied endpoint is not
- * available: the hook runs before :manpage:`bind(2)` /
- * :manpage:`connect(2)` sets the socket addresses.
- * @sport: Source port in host endianness, set for bind denials (zero for
- * an autobind/ephemeral port); zero for connect and send denials.
- * @dport: Destination port in host endianness, set for connect and send
- * denials; zero for bind denials, and also zero for a UDP send to
- * an AF_UNSPEC address on an IPv6 socket (indistinguishable from a
- * real destination port 0). The bind-vs-connect direction is
- * given by @blockers, not by which port is set.
- *
- * Emitted when a Landlock domain denies a network operation.
- *
- * The port fields are converted from the socket's network byte order to
- * host endianness before emitting.
+ * @blockers: Request type and final missing access subset (never NULL).
+ * @sk: Socket object (never NULL), read without a socket lock, so its fields
+ * are a best-effort snapshot.
+ * @socket_family: Socket-family snapshot used by the verdict.
+ * @address: Authoritative address checked by the verdict (never NULL).
+ * The producer copies @addrlen bytes from the checked address and
+ * zeroes the remaining storage before emission. The
+ * &sockaddr_in.sin_port or &sockaddr_in6.sin6_port member, when
+ * present, remains in network endianness.
+ * @addrlen: Validated signed length of @address.
+ *
+ * Emitted when a Landlock domain denies a network operation. The blocker
+ * identifies whether the address is a bind or connect/send policy object.
+ * The flattened port field is converted from the checked address to host
+ * endianness, or is -1 when no port was checked. Zero is a valid checked
+ * port.
*/
TRACE_EVENT(landlock_deny_access_net,
TP_PROTO(const struct landlock_hierarchy *hierarchy, bool same_exec,
- bool logged, access_mask_t blockers, const struct sock *sk,
- __u64 sport, __u64 dport),
+ bool logged, const struct landlock_blockers *blockers,
+ const struct sock *sk, u16 socket_family,
+ const struct sockaddr_storage *address, int addrlen),
+
+ TP_ARGS(hierarchy, same_exec, logged, blockers, sk, socket_family,
+ address, addrlen),
+
+ TP_STRUCT__entry(
+ __field( u64, domain_id )
+ __field( bool, same_exec )
+ __field( bool, logged )
+ __field( enum landlock_request_type, blockers_type )
+ __field( access_mask_t, blockers_access )
+ __field( s64, port )
+ ),
+
+ TP_fast_assign(
+ const struct sockaddr *const addr =
+ (const struct sockaddr *)address;
+ const bool has_port =
+ addrlen >= (int)offsetofend(struct sockaddr_in, sin_port) &&
+ (addr->sa_family == AF_INET ||
+ addr->sa_family == AF_INET6 ||
+ (addr->sa_family == AF_UNSPEC &&
+ socket_family == AF_INET));
+
+ __entry->domain_id = hierarchy->id;
+ __entry->same_exec = same_exec;
+ __entry->logged = logged;
+ __entry->blockers_type = blockers->type;
+ __entry->blockers_access = blockers->access;
+ __entry->port =
+ has_port ?
+ ntohs(((const struct sockaddr_in *)addr)->sin_port) :
+ -1;
+ ),
+
+ TP_printk("domain=%llx same_exec=%d logged=%d blockers=%s port=%lld",
+ __entry->domain_id, __entry->same_exec, __entry->logged,
+ __entry->blockers_type == LANDLOCK_REQUEST_NET_ACCESS ?
+ __print_flags(__entry->blockers_access, "|", _LANDLOCK_ACCESS_NET_NAMES) :
+ "unknown",
+ __entry->port)
+);
+
+/**
+ * landlock_deny_permission_namespace - Namespace use denied
+ *
+ * @hierarchy: Denying domain's hierarchy node (never NULL); its id is the
+ * domain field.
+ * @same_exec: Whether the current task entered the denying domain itself.
+ * @logged: Whether this denial was selected for audit logging.
+ * @blockers: Request type and final missing permission subset (never NULL).
+ * @namespace_type: CLONE_NEW* namespace type that was denied.
+ * @namespace_id: Namespace ID, or 0 when creation was denied.
+ *
+ * Emitted when a Landlock domain denies namespace use.
+ */
+TRACE_EVENT(landlock_deny_permission_namespace,
+
+ TP_PROTO(const struct landlock_hierarchy *hierarchy, bool same_exec,
+ bool logged, const struct landlock_blockers *blockers,
+ u32 namespace_type, u64 namespace_id),
- TP_ARGS(hierarchy, same_exec, logged, blockers, sk, sport, dport),
+ TP_ARGS(hierarchy, same_exec, logged, blockers, namespace_type,
+ namespace_id),
TP_STRUCT__entry(
- __field( __u64, domain_id )
+ __field( u64, domain_id )
__field( bool, same_exec )
__field( bool, logged )
- __field( access_mask_t, blockers )
- __field( __u64, sport )
- __field( __u64, dport )
+ __field( enum landlock_request_type, blockers_type )
+ __field( access_mask_t, blockers_access )
+ __field( u32, namespace_type )
+ __field( u64, namespace_id )
),
TP_fast_assign(
__entry->domain_id = hierarchy->id;
__entry->same_exec = same_exec;
__entry->logged = logged;
- __entry->blockers = blockers;
- __entry->sport = sport;
- __entry->dport = dport;
+ __entry->blockers_type = blockers->type;
+ __entry->blockers_access = blockers->access;
+ __entry->namespace_type = namespace_type;
+ __entry->namespace_id = namespace_id;
),
- TP_printk("domain=%llx same_exec=%d logged=%d blockers=%s sport=%llu dport=%llu",
+ TP_printk("domain=%llx same_exec=%d logged=%d blockers=%s namespace_type=0x%x namespace_id=%llu",
__entry->domain_id, __entry->same_exec, __entry->logged,
- __print_flags(__entry->blockers, "|", _LANDLOCK_ACCESS_NET_NAMES),
- __entry->sport, __entry->dport)
+ __entry->blockers_type == LANDLOCK_REQUEST_NAMESPACE ?
+ __print_flags(__entry->blockers_access, "|",
+ _LANDLOCK_PERMISSION_BLOCKER_NAMES) :
+ "unknown",
+ __entry->namespace_type, __entry->namespace_id)
);
/**
- * landlock_deny_ptrace - Ptrace access denied by a Landlock domain
+ * landlock_deny_permission_capability - Capability use denied
*
* @hierarchy: Denying domain's hierarchy node (never NULL); its id is the
* domain field.
* @same_exec: Whether the current task entered the denying domain itself.
+ * @logged: Whether this denial was selected for audit logging.
+ * @blockers: Request type and final missing permission subset (never NULL).
+ * @capability: CAP_* number that was denied.
+ *
+ * Emitted when a Landlock domain denies capability use, except for checks
+ * made with CAP_OPT_NOAUDIT, which are denied without emitting this event.
+ */
+TRACE_EVENT(landlock_deny_permission_capability,
+
+ TP_PROTO(const struct landlock_hierarchy *hierarchy, bool same_exec,
+ bool logged, const struct landlock_blockers *blockers,
+ int capability),
+
+ TP_ARGS(hierarchy, same_exec, logged, blockers, capability),
+
+ TP_STRUCT__entry(
+ __field( u64, domain_id )
+ __field( bool, same_exec )
+ __field( bool, logged )
+ __field( enum landlock_request_type, blockers_type )
+ __field( access_mask_t, blockers_access )
+ __field( int, capability )
+ ),
+
+ TP_fast_assign(
+ __entry->domain_id = hierarchy->id;
+ __entry->same_exec = same_exec;
+ __entry->logged = logged;
+ __entry->blockers_type = blockers->type;
+ __entry->blockers_access = blockers->access;
+ __entry->capability = capability;
+ ),
+
+ TP_printk("domain=%llx same_exec=%d logged=%d blockers=%s capability=%d",
+ __entry->domain_id, __entry->same_exec, __entry->logged,
+ __entry->blockers_type == LANDLOCK_REQUEST_CAPABILITY ?
+ __print_flags(__entry->blockers_access, "|",
+ _LANDLOCK_PERMISSION_BLOCKER_NAMES) :
+ "unknown",
+ __entry->capability)
+);
+
+/**
+ * landlock_deny_ptrace - Ptrace access denied by a Landlock domain
+ *
+ * @hierarchy: Denying domain's hierarchy node (never NULL); its id is the
+ * domain field.
+ * @same_exec: Whether the tracer entered the denying domain itself.
* @logged: The domain's audit-logging decision for this denial.
* @tracee_domain_id: The tracee's Landlock domain ID, or 0 if the tracee
* is unsandboxed.
* @tracee: The target task ptrace acted on (never NULL). tracee_pid is
* the init-namespace TGID (like audit's opid).
+ * @tracer: The tracer or proposed tracer (never NULL); for PTRACE_TRACEME
+ * this is the parent, not the syscall caller.
*
* Emitted when a Landlock domain denies a ptrace operation.
*/
@@ -801,15 +1097,16 @@ TRACE_EVENT(landlock_deny_ptrace,
TP_PROTO(const struct landlock_hierarchy *hierarchy, bool same_exec,
bool logged, u64 tracee_domain_id,
- const struct task_struct *tracee),
+ const struct task_struct *tracee,
+ const struct task_struct *tracer),
- TP_ARGS(hierarchy, same_exec, logged, tracee_domain_id, tracee),
+ TP_ARGS(hierarchy, same_exec, logged, tracee_domain_id, tracee, tracer),
TP_STRUCT__entry(
- __field( __u64, domain_id )
+ __field( u64, domain_id )
__field( bool, same_exec )
__field( bool, logged )
- __field( __u64, tracee_domain_id)
+ __field( u64, tracee_domain_id)
__field( pid_t, tracee_pid )
__string( tracee_comm, tracee->comm )
),
@@ -836,12 +1133,14 @@ TRACE_EVENT(landlock_deny_ptrace,
*
* @hierarchy: Denying domain's hierarchy node (never NULL); its id is the
* domain field.
- * @same_exec: Whether the current task entered the denying domain itself.
+ * @same_exec: Whether the policy subject entered the denying domain itself.
* @logged: The domain's audit-logging decision for this denial.
* @target_domain_id: The target's Landlock domain ID, or 0 if the target
* is unsandboxed.
* @target: The task the signal was aimed at (never NULL). target_pid is
* the init-namespace TGID (like audit's opid).
+ * @signal: The signal selected by the denied check. Zero is a permission
+ * probe, not an absent value.
*
* Emitted when a Landlock domain denies signal delivery to a scoped-out
* target.
@@ -850,15 +1149,15 @@ TRACE_EVENT(landlock_deny_scope_signal,
TP_PROTO(const struct landlock_hierarchy *hierarchy, bool same_exec,
bool logged, u64 target_domain_id,
- const struct task_struct *target),
+ const struct task_struct *target, int signal),
- TP_ARGS(hierarchy, same_exec, logged, target_domain_id, target),
+ TP_ARGS(hierarchy, same_exec, logged, target_domain_id, target, signal),
TP_STRUCT__entry(
- __field( __u64, domain_id )
+ __field( u64, domain_id )
__field( bool, same_exec )
__field( bool, logged )
- __field( __u64, target_domain_id)
+ __field( u64, target_domain_id)
__field( pid_t, target_pid )
__string( target_comm, target->comm )
),
@@ -904,10 +1203,10 @@ TRACE_EVENT(landlock_deny_scope_abstract_unix_socket,
TP_ARGS(hierarchy, same_exec, logged, peer_domain_id, peer),
TP_STRUCT__entry(
- __field( __u64, domain_id )
+ __field( u64, domain_id )
__field( bool, same_exec )
__field( bool, logged )
- __field( __u64, peer_domain_id )
+ __field( u64, peer_domain_id )
__field( pid_t, peer_pid )
/*
* Abstract socket names are untrusted binary data from
@@ -937,13 +1236,12 @@ TRACE_EVENT(landlock_deny_scope_abstract_unix_socket,
__entry->logged = logged;
__entry->peer_domain_id = peer_domain_id;
/*
- * Best-effort (0 for a datagram peer). sk_peer_pid is
- * canonically guarded by sk->sk_peer_lock, but the target
- * peer's peercred is set once and not updated concurrently in
- * these hooks, so this READ_ONCE() is safe; sun_path is the
- * reliable identifier.
+ * Best-effort (0 for a datagram peer). The caller holds the
+ * peer's AF_UNIX state lock, serializing published peercred
+ * updates. The peer socket keeps a reference to sk_peer_pid
+ * through pid_nr(); sun_path is the reliable identifier.
*/
- peer_pid = READ_ONCE(peer->sk_peer_pid);
+ peer_pid = READ_ONCE(peer->sk_peer_pid[PIDTYPE_TGID]);
__entry->peer_pid = peer_pid ? pid_nr(peer_pid) : 0;
__assign_str(sun_path);
),
@@ -955,6 +1253,7 @@ TRACE_EVENT(landlock_deny_scope_abstract_unix_socket,
__get_dynamic_array_len(sun_path) - 1))
);
+#undef _LANDLOCK_FS_BLOCKER_TYPE_NAMES
#undef _LANDLOCK_NAME_ENTRY
#endif /* _TRACE_LANDLOCK_H */
diff --git a/include/trace/events/mmflags.h b/include/trace/events/mmflags.h
index 935893e5ea53..3c153b3ad845 100644
--- a/include/trace/events/mmflags.h
+++ b/include/trace/events/mmflags.h
@@ -144,7 +144,7 @@ TRACE_DEFINE_ENUM(___GFP_LAST_BIT);
DEF_PAGEFLAG_NAME(owner_2), \
DEF_PAGEFLAG_NAME(arch_1), \
DEF_PAGEFLAG_NAME(reserved), \
- DEF_PAGEFLAG_NAME(private), \
+ DEF_PAGEFLAG_NAME(folio), \
DEF_PAGEFLAG_NAME(private_2), \
DEF_PAGEFLAG_NAME(writeback), \
DEF_PAGEFLAG_NAME(head), \
@@ -168,6 +168,10 @@ IF_HAVE_PG_ARCH_3(arch_3)
#define __VM_ARCH_SPECIFIC_1 {VM_SAO, "sao" }
#elif defined(CONFIG_PARISC)
#define __VM_ARCH_SPECIFIC_1 {VM_GROWSUP, "growsup" }
+#elif defined(CONFIG_SPARC64)
+#define __VM_ARCH_SPECIFIC_1 {VM_SPARC_ADI, "adi" }
+#elif defined(CONFIG_ARM64)
+#define __VM_ARCH_SPECIFIC_1 {VM_ARM64_BTI, "bti" }
#elif !defined(CONFIG_MMU)
#define __VM_ARCH_SPECIFIC_1 {VM_MAPPED_COPY,"mappedcopy" }
#else
@@ -198,6 +202,37 @@ IF_HAVE_PG_ARCH_3(arch_3)
# define IF_HAVE_VM_DROPPABLE(flag, name)
#endif
+#ifdef CONFIG_ARCH_HAS_PKEYS
+# define IF_HAVE_VM_PKEY(flag, name) {flag, name},
+#if CONFIG_ARCH_PKEY_BITS > 3
+# define IF_HAVE_VM_PKEY3(flag, name) {flag, name},
+#else
+# define IF_HAVE_VM_PKEY3(flag, name)
+#endif
+#if CONFIG_ARCH_PKEY_BITS > 4
+# define IF_HAVE_VM_PKEY4(flag, name) {flag, name},
+#else
+# define IF_HAVE_VM_PKEY4(flag, name)
+#endif
+#else
+# define IF_HAVE_VM_PKEY(flag, name)
+# define IF_HAVE_VM_PKEY3(flag, name)
+# define IF_HAVE_VM_PKEY4(flag, name)
+#endif
+
+#ifdef CONFIG_ARM64_MTE
+# define IF_HAVE_VM_MTE(flag, name) {flag, name},
+#else
+# define IF_HAVE_VM_MTE(flag, name)
+#endif
+
+#if defined(CONFIG_X86_USER_SHADOW_STACK) || defined(CONFIG_RISCV_USER_CFI) || \
+ defined(CONFIG_ARM64_GCS)
+# define IF_HAVE_VM_SHADOW_STACK(flag, name) {flag, name},
+#else
+# define IF_HAVE_VM_SHADOW_STACK(flag, name)
+#endif
+
#define __def_vmaflag_names \
{VM_READ, "read" }, \
{VM_WRITE, "write" }, \
@@ -233,6 +268,14 @@ IF_HAVE_VM_SOFTDIRTY(VM_SOFTDIRTY, "softdirty" ) \
{VM_HUGEPAGE, "hugepage" }, \
{VM_NOHUGEPAGE, "nohugepage" }, \
IF_HAVE_VM_DROPPABLE(VM_DROPPABLE, "droppable" ) \
+IF_HAVE_VM_PKEY(VM_PKEY_BIT0, "pkey_bit0") \
+IF_HAVE_VM_PKEY(VM_PKEY_BIT1, "pkey_bit1") \
+IF_HAVE_VM_PKEY(VM_PKEY_BIT2, "pkey_bit2") \
+IF_HAVE_VM_PKEY3(VM_PKEY_BIT3, "pkey_bit3") \
+IF_HAVE_VM_PKEY4(VM_PKEY_BIT4, "pkey_bit4") \
+IF_HAVE_VM_MTE(VM_MTE, "mte") \
+IF_HAVE_VM_MTE(VM_MTE_ALLOWED, "mte_allowed") \
+IF_HAVE_VM_SHADOW_STACK(VM_SHADOW_STACK, "shadow_stack") \
{VM_MERGEABLE, "mergeable" } \
#define show_vma_flags(flags) \
diff --git a/include/trace/events/module.h b/include/trace/events/module.h
index e5a006be9dc6..19df3e39bba4 100644
--- a/include/trace/events/module.h
+++ b/include/trace/events/module.h
@@ -26,7 +26,8 @@ struct module;
{ (1UL << TAINT_OOT_MODULE), "O" }, \
{ (1UL << TAINT_FORCED_MODULE), "F" }, \
{ (1UL << TAINT_CRAP), "C" }, \
- { (1UL << TAINT_UNSIGNED_MODULE), "E" })
+ { (1UL << TAINT_UNSIGNED_MODULE), "E" }, \
+ { (1UL << TAINT_FORCED_BIND), "Y" })
TRACE_EVENT(module_load,
diff --git a/include/trace/events/netfs.h b/include/trace/events/netfs.h
index 082cb03c6131..bf1e1f185b05 100644
--- a/include/trace/events/netfs.h
+++ b/include/trace/events/netfs.h
@@ -30,8 +30,7 @@
EM(netfs_write_trace_dio_write, "DIO-WRITE") \
EM(netfs_write_trace_unbuffered_write, "UNB-WRITE") \
EM(netfs_write_trace_writeback, "WRITEBACK") \
- EM(netfs_write_trace_writeback_single, "WB-SINGLE") \
- E_(netfs_write_trace_writethrough, "WRITETHRU")
+ E_(netfs_write_trace_writeback_single, "WB-SINGLE")
#define netfs_rreq_origins \
EM(NETFS_READAHEAD, "RA") \
@@ -43,13 +42,17 @@
EM(NETFS_DIO_READ, "DR") \
EM(NETFS_WRITEBACK, "WB") \
EM(NETFS_WRITEBACK_SINGLE, "W1") \
- EM(NETFS_WRITETHROUGH, "WT") \
EM(NETFS_UNBUFFERED_WRITE, "UW") \
EM(NETFS_DIO_WRITE, "DW") \
E_(NETFS_PGPRIV2_COPY_TO_CACHE, "2C")
#define netfs_rreq_traces \
+ EM(netfs_rreq_trace_all_queued, "ALL-Q ") \
EM(netfs_rreq_trace_assess, "ASSESS ") \
+ EM(netfs_rreq_trace_cache_cancelled, "CA-CNCL") \
+ EM(netfs_rreq_trace_cache_failed, "CA-FAIL") \
+ EM(netfs_rreq_trace_cache_fail_collect, "CA-F-CO") \
+ EM(netfs_rreq_trace_cache_no_space, "CA-NOSP") \
EM(netfs_rreq_trace_collect, "COLLECT") \
EM(netfs_rreq_trace_complete, "COMPLET") \
EM(netfs_rreq_trace_copy, "COPY ") \
@@ -58,10 +61,14 @@
EM(netfs_rreq_trace_end_copy_to_cache, "END-C2C") \
EM(netfs_rreq_trace_free, "FREE ") \
EM(netfs_rreq_trace_intr, "INTR ") \
+ EM(netfs_rreq_trace_inval_cache, "INVL-CA") \
EM(netfs_rreq_trace_ki_complete, "KI-CMPL") \
+ EM(netfs_rreq_trace_ra_put_ref, "RA-PUT ") \
EM(netfs_rreq_trace_recollect, "RECLLCT") \
EM(netfs_rreq_trace_redirty, "REDIRTY") \
EM(netfs_rreq_trace_resubmit, "RESUBMT") \
+ EM(netfs_rreq_trace_retry_begin, "RETRY-BEGIN") \
+ EM(netfs_rreq_trace_retry_end, "RETRY-END") \
EM(netfs_rreq_trace_set_abandon, "S-ABNDN") \
EM(netfs_rreq_trace_set_pause, "PAUSE ") \
EM(netfs_rreq_trace_unlock, "UNLOCK ") \
@@ -70,9 +77,11 @@
EM(netfs_rreq_trace_unpause, "UNPAUSE") \
EM(netfs_rreq_trace_wait_ip, "WAIT-IP") \
EM(netfs_rreq_trace_wait_pause, "--PAUSED--") \
+ EM(netfs_rreq_trace_wait_put_ra_refs, "WAIT-P-RA") \
EM(netfs_rreq_trace_wait_quiesce, "WAIT-QUIESCE") \
EM(netfs_rreq_trace_waited_ip, "DONE-IP") \
EM(netfs_rreq_trace_waited_pause, "--UNPAUSED--") \
+ EM(netfs_rreq_trace_waited_put_ra_refs, "DONE-P-RA") \
EM(netfs_rreq_trace_waited_quiesce, "DONE-QUIESCE") \
EM(netfs_rreq_trace_wake_ip, "WAKE-IP") \
EM(netfs_rreq_trace_wake_queue, "WAKE-Q ") \
@@ -91,8 +100,10 @@
EM(netfs_sreq_trace_abandoned, "ABNDN") \
EM(netfs_sreq_trace_add_donations, "+DON ") \
EM(netfs_sreq_trace_added, "ADD ") \
+ EM(netfs_sreq_trace_cache_nofile, "CA-!F") \
EM(netfs_sreq_trace_cache_nowrite, "CA-NW") \
EM(netfs_sreq_trace_cache_prepare, "CA-PR") \
+ EM(netfs_sreq_trace_cache_waitfail, "CA-!W") \
EM(netfs_sreq_trace_cache_write, "CA-WR") \
EM(netfs_sreq_trace_cancel, "CANCL") \
EM(netfs_sreq_trace_clear, "CLEAR") \
@@ -131,12 +142,12 @@
#define netfs_failures \
EM(netfs_fail_check_write_begin, "check-write-begin") \
- EM(netfs_fail_copy_to_cache, "copy-to-cache") \
EM(netfs_fail_dio_read_short, "dio-read-short") \
EM(netfs_fail_dio_read_zero, "dio-read-zero") \
EM(netfs_fail_read, "read") \
EM(netfs_fail_short_read, "short-read") \
EM(netfs_fail_prepare_write, "prep-write") \
+ EM(netfs_fail_upload, "upload") \
E_(netfs_fail_write, "write")
#define netfs_rreq_ref_traces \
@@ -191,12 +202,11 @@
EM(netfs_folio_trace_alloc_buffer, "alloc-buf") \
EM(netfs_folio_trace_cancel_copy, "cancel-copy") \
EM(netfs_folio_trace_cancel_store, "cancel-store") \
- EM(netfs_folio_trace_clear, "clear") \
- EM(netfs_folio_trace_clear_cc, "clear-cc") \
- EM(netfs_folio_trace_clear_g, "clear-g") \
- EM(netfs_folio_trace_clear_s, "clear-s") \
- EM(netfs_folio_trace_copy_to_cache, "mark-copy") \
EM(netfs_folio_trace_end_copy, "end-copy") \
+ EM(netfs_folio_trace_endwb, "endwb") \
+ EM(netfs_folio_trace_endwb_cc, "endwb-cc") \
+ EM(netfs_folio_trace_endwb_g, "endwb-g") \
+ EM(netfs_folio_trace_endwb_s, "endwb-s") \
EM(netfs_folio_trace_filled_gaps, "filled-gaps") \
EM(netfs_folio_trace_invalidate_all, "inval-all") \
EM(netfs_folio_trace_invalidate_front, "inval-front") \
@@ -206,21 +216,22 @@
EM(netfs_folio_trace_kill_cc, "kill-cc") \
EM(netfs_folio_trace_kill_g, "kill-g") \
EM(netfs_folio_trace_kill_s, "kill-s") \
+ EM(netfs_folio_trace_mark_copy, "mark-copy") \
EM(netfs_folio_trace_mkwrite, "mkwrite") \
EM(netfs_folio_trace_mkwrite_plus, "mkwrite+") \
- EM(netfs_folio_trace_not_under_wback, "!wback") \
EM(netfs_folio_trace_not_locked, "!locked") \
+ EM(netfs_folio_trace_not_under_wback, "!wback") \
+ EM(netfs_folio_trace_pgpriv2_copy, "pgpriv2-copy") \
EM(netfs_folio_trace_put, "put") \
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_unlock, "read-unlock") \
EM(netfs_folio_trace_redirtied, "redirtied") \
+ EM(netfs_folio_trace_sched_copy, "sched-copy") \
EM(netfs_folio_trace_store, "store") \
EM(netfs_folio_trace_store_copy, "store-copy") \
- EM(netfs_folio_trace_store_plus, "store+") \
- EM(netfs_folio_trace_wthru, "wthru") \
- E_(netfs_folio_trace_wthru_plus, "wthru+")
+ E_(netfs_folio_trace_store_plus, "store+")
#define netfs_collect_contig_traces \
EM(netfs_contig_trace_collect, "Collect") \
@@ -296,7 +307,7 @@ netfs_folioq_traces;
TRACE_EVENT(netfs_read,
TP_PROTO(struct netfs_io_request *rreq,
- loff_t start, size_t len,
+ uoff_t start, size_t len,
enum netfs_read_trace what),
TP_ARGS(rreq, start, len, what),
@@ -304,8 +315,9 @@ TRACE_EVENT(netfs_read,
TP_STRUCT__entry(
__field(unsigned int, rreq)
__field(unsigned int, cookie)
- __field(loff_t, i_size)
- __field(loff_t, start)
+ __field(unsigned int, object)
+ __field(uoff_t, i_size)
+ __field(uoff_t, start)
__field(size_t, len)
__field(enum netfs_read_trace, what)
__field(u64, netfs_inode)
@@ -313,7 +325,8 @@ TRACE_EVENT(netfs_read,
TP_fast_assign(
__entry->rreq = rreq->debug_id;
- __entry->cookie = rreq->cache_resources.debug_id;
+ __entry->cookie = rreq->cache_resources.cookie_id;
+ __entry->object = rreq->cache_resources.object_id;
__entry->i_size = rreq->i_size;
__entry->start = start;
__entry->len = len;
@@ -321,10 +334,10 @@ TRACE_EVENT(netfs_read,
__entry->netfs_inode = rreq->inode->i_ino;
),
- TP_printk("R=%08x %s c=%08x ni=%llx s=%llx l=%zx sz=%llx",
+ TP_printk("R=%08x %s c=%08x o=%08x ni=%llx s=%llx l=%zx sz=%llx",
__entry->rreq,
__print_symbolic(__entry->what, netfs_read_traces),
- __entry->cookie,
+ __entry->cookie, __entry->object,
__entry->netfs_inode,
__entry->start, __entry->len, __entry->i_size)
);
@@ -372,7 +385,7 @@ TRACE_EVENT(netfs_sreq,
__field(u8, slot)
__field(size_t, len)
__field(size_t, transferred)
- __field(loff_t, start)
+ __field(uoff_t, start)
),
TP_fast_assign(
@@ -413,7 +426,7 @@ TRACE_EVENT(netfs_failure,
__field(enum netfs_failure, what)
__field(size_t, len)
__field(size_t, transferred)
- __field(loff_t, start)
+ __field(uoff_t, start)
),
TP_fast_assign(
@@ -496,6 +509,7 @@ TRACE_EVENT(netfs_folio,
TP_STRUCT__entry(
__field(u64, ino)
__field(pgoff_t, index)
+ __field(unsigned long, pfn)
__field(unsigned int, nr)
__field(enum netfs_folio_trace, why)
),
@@ -506,9 +520,11 @@ TRACE_EVENT(netfs_folio,
__entry->why = why;
__entry->index = folio->index;
__entry->nr = folio_nr_pages(folio);
+ __entry->pfn = folio_pfn(folio);
),
- TP_printk("i=%05llx ix=%05lx-%05lx %s",
+ TP_printk("p=%lx i=%05llx ix=%05lx-%05lx %s",
+ __entry->pfn,
__entry->ino, __entry->index, __entry->index + __entry->nr - 1,
__print_symbolic(__entry->why, netfs_folio_traces))
);
@@ -519,10 +535,10 @@ TRACE_EVENT(netfs_write_iter,
TP_ARGS(iocb, from),
TP_STRUCT__entry(
- __field(unsigned long long, start)
- __field(size_t, len)
- __field(unsigned int, flags)
- __field(unsigned int, ino)
+ __field(uoff_t, start)
+ __field(size_t, len)
+ __field(unsigned int, flags)
+ __field(unsigned int, ino)
),
TP_fast_assign(
@@ -545,27 +561,27 @@ TRACE_EVENT(netfs_write,
TP_STRUCT__entry(
__field(unsigned int, wreq)
__field(unsigned int, cookie)
+ __field(unsigned int, object)
__field(unsigned int, ino)
__field(enum netfs_write_trace, what)
- __field(unsigned long long, start)
- __field(unsigned long long, len)
+ __field(uoff_t, start)
+ __field(uoff_t, len)
),
TP_fast_assign(
- struct netfs_inode *__ctx = netfs_inode(wreq->inode);
- struct fscache_cookie *__cookie = netfs_i_cookie(__ctx);
__entry->wreq = wreq->debug_id;
- __entry->cookie = __cookie ? __cookie->debug_id : 0;
+ __entry->cookie = wreq->cache_resources.cookie_id;
+ __entry->object = wreq->cache_resources.object_id;
__entry->ino = wreq->inode->i_ino;
__entry->what = what;
__entry->start = wreq->start;
__entry->len = wreq->len;
),
- TP_printk("R=%08x %s c=%08x i=%x by=%llx-%llx",
+ TP_printk("R=%08x %s c=%08x o=%08x i=%x by=%llx-%llx",
__entry->wreq,
__print_symbolic(__entry->what, netfs_write_traces),
- __entry->cookie,
+ __entry->cookie, __entry->object,
__entry->ino,
__entry->start, __entry->start + __entry->len - 1)
);
@@ -577,25 +593,26 @@ TRACE_EVENT(netfs_copy2cache,
TP_ARGS(rreq, creq),
TP_STRUCT__entry(
- __field(unsigned int, rreq)
- __field(unsigned int, creq)
- __field(unsigned int, cookie)
- __field(unsigned int, ino)
+ __field(unsigned int, rreq)
+ __field(unsigned int, creq)
+ __field(unsigned int, cookie)
+ __field(unsigned int, object)
+ __field(unsigned int, ino)
),
TP_fast_assign(
- struct netfs_inode *__ctx = netfs_inode(rreq->inode);
- struct fscache_cookie *__cookie = netfs_i_cookie(__ctx);
__entry->rreq = rreq->debug_id;
__entry->creq = creq->debug_id;
- __entry->cookie = __cookie ? __cookie->debug_id : 0;
+ __entry->cookie = rreq->cache_resources.cookie_id;
+ __entry->object = rreq->cache_resources.object_id;
__entry->ino = rreq->inode->i_ino;
),
- TP_printk("R=%08x CR=%08x c=%08x i=%x ",
+ TP_printk("R=%08x CR=%08x c=%08x o=%08x i=%x ",
__entry->rreq,
__entry->creq,
__entry->cookie,
+ __entry->object,
__entry->ino)
);
@@ -605,10 +622,10 @@ TRACE_EVENT(netfs_collect,
TP_ARGS(wreq),
TP_STRUCT__entry(
- __field(unsigned int, wreq)
- __field(unsigned int, len)
- __field(unsigned long long, transferred)
- __field(unsigned long long, start)
+ __field(unsigned int, wreq)
+ __field(unsigned int, len)
+ __field(uoff_t, transferred)
+ __field(uoff_t, start)
),
TP_fast_assign(
@@ -631,12 +648,12 @@ TRACE_EVENT(netfs_collect_sreq,
TP_ARGS(wreq, subreq),
TP_STRUCT__entry(
- __field(unsigned int, wreq)
- __field(unsigned int, subreq)
- __field(unsigned int, stream)
- __field(unsigned int, len)
- __field(unsigned int, transferred)
- __field(unsigned long long, start)
+ __field(unsigned int, wreq)
+ __field(unsigned int, subreq)
+ __field(unsigned int, stream)
+ __field(unsigned int, len)
+ __field(unsigned int, transferred)
+ __field(uoff_t, start)
),
TP_fast_assign(
@@ -655,37 +672,30 @@ TRACE_EVENT(netfs_collect_sreq,
TRACE_EVENT(netfs_collect_folio,
TP_PROTO(const struct netfs_io_request *wreq,
- const struct folio *folio,
- unsigned long long fend,
- unsigned long long collected_to),
+ const struct folio *folio),
- TP_ARGS(wreq, folio, fend, collected_to),
+ TP_ARGS(wreq, folio),
TP_STRUCT__entry(
__field(unsigned int, wreq)
__field(unsigned long, index)
- __field(unsigned long long, fend)
- __field(unsigned long long, cleaned_to)
- __field(unsigned long long, collected_to)
+ __field(unsigned int, nr)
),
TP_fast_assign(
__entry->wreq = wreq->debug_id;
__entry->index = folio->index;
- __entry->fend = fend;
- __entry->cleaned_to = wreq->cleaned_to;
- __entry->collected_to = collected_to;
+ __entry->nr = folio_nr_pages(folio);
),
- TP_printk("R=%08x ix=%05lx r=%llx-%llx t=%llx/%llx",
+ TP_printk("R=%08x ix=%05lx-%05lx",
__entry->wreq, __entry->index,
- (unsigned long long)__entry->index * PAGE_SIZE, __entry->fend,
- __entry->cleaned_to, __entry->collected_to)
+ __entry->index + __entry->nr - 1)
);
TRACE_EVENT(netfs_collect_state,
TP_PROTO(const struct netfs_io_request *wreq,
- unsigned long long collected_to,
+ uoff_t collected_to,
unsigned int notes),
TP_ARGS(wreq, collected_to, notes),
@@ -693,8 +703,8 @@ TRACE_EVENT(netfs_collect_state,
TP_STRUCT__entry(
__field(unsigned int, wreq)
__field(unsigned int, notes)
- __field(unsigned long long, collected_to)
- __field(unsigned long long, cleaned_to)
+ __field(uoff_t, collected_to)
+ __field(uoff_t, cleaned_to)
),
TP_fast_assign(
@@ -713,7 +723,7 @@ TRACE_EVENT(netfs_collect_state,
TRACE_EVENT(netfs_collect_gap,
TP_PROTO(const struct netfs_io_request *wreq,
const struct netfs_io_stream *stream,
- unsigned long long jump_to, char type),
+ uoff_t jump_to, char type),
TP_ARGS(wreq, stream, jump_to, type),
@@ -721,8 +731,8 @@ TRACE_EVENT(netfs_collect_gap,
__field(unsigned int, wreq)
__field(unsigned char, stream)
__field(unsigned char, type)
- __field(unsigned long long, from)
- __field(unsigned long long, to)
+ __field(uoff_t, from)
+ __field(uoff_t, to)
),
TP_fast_assign(
@@ -747,8 +757,8 @@ TRACE_EVENT(netfs_collect_stream,
TP_STRUCT__entry(
__field(unsigned int, wreq)
__field(unsigned char, stream)
- __field(unsigned long long, collected_to)
- __field(unsigned long long, issued_to)
+ __field(uoff_t, collected_to)
+ __field(uoff_t, issued_to)
),
TP_fast_assign(
@@ -786,6 +796,27 @@ TRACE_EVENT(netfs_folioq,
__print_symbolic(__entry->trace, netfs_folioq_traces))
);
+TRACE_EVENT(netfs_read_progress_at,
+ TP_PROTO(const struct netfs_io_request *rreq),
+
+ TP_ARGS(rreq),
+
+ TP_STRUCT__entry(
+ __field(unsigned int, rreq)
+ __field(size_t, progress_at)
+ __field(size_t, cleaned_to)
+ ),
+
+ TP_fast_assign(
+ __entry->rreq = rreq->debug_id;
+ __entry->cleaned_to = rreq->cleaned_to - rreq->start;
+ __entry->progress_at = rreq->progress_at;
+ ),
+
+ TP_printk("R=%08x cln=%zx prg=%zx",
+ __entry->rreq, __entry->cleaned_to, __entry->progress_at)
+ );
+
#undef EM
#undef E_
#endif /* _TRACE_NETFS_H */
diff --git a/include/trace/events/pagemap.h b/include/trace/events/pagemap.h
index 36c3a90f0acc..5d47b774633a 100644
--- a/include/trace/events/pagemap.h
+++ b/include/trace/events/pagemap.h
@@ -22,7 +22,7 @@
(folio_test_swapcache(folio) ? PAGEMAP_SWAPCACHE : 0) | \
(folio_test_swapbacked(folio) ? PAGEMAP_SWAPBACKED : 0) | \
(folio_test_mappedtodisk(folio) ? PAGEMAP_MAPPEDDISK : 0) | \
- (folio_test_private(folio) ? PAGEMAP_BUFFERS : 0) \
+ (folio_has_attached_private(folio) ? PAGEMAP_BUFFERS : 0) \
)
TRACE_EVENT(mm_lru_insertion,
diff --git a/include/trace/events/rxrpc.h b/include/trace/events/rxrpc.h
index 704a10de6670..56dc9b614071 100644
--- a/include/trace/events/rxrpc.h
+++ b/include/trace/events/rxrpc.h
@@ -20,16 +20,16 @@
/* AFS errors */ \
EM(afs_abort_general_error, "afs-error") \
EM(afs_abort_interrupted, "afs-intr") \
- EM(afs_abort_oom, "afs-oom") \
EM(afs_abort_op_not_supported, "afs-op-notsupp") \
EM(afs_abort_probeuuid_negative, "afs-probeuuid-neg") \
EM(afs_abort_send_data_error, "afs-send-data") \
+ EM(afs_abort_send_error, "afs-send-error") \
EM(afs_abort_unmarshal_error, "afs-unmarshal") \
EM(afs_abort_unsupported_sec_class, "afs-unsup-sec-class") \
/* rxperf errors */ \
EM(rxperf_abort_general_error, "rxperf-error") \
- EM(rxperf_abort_oom, "rxperf-oom") \
EM(rxperf_abort_op_not_supported, "rxperf-op-notsupp") \
+ EM(rxperf_abort_send_error, "rxperf-send-error") \
EM(rxperf_abort_unmarshal_error, "rxperf-unmarshal") \
/* RxKAD security errors */ \
EM(rxkad_abort_1_short_check, "rxkad1-short-check") \
diff --git a/include/trace/events/scmi.h b/include/trace/events/scmi.h
index 703b7bb68e44..b421c253df00 100644
--- a/include/trace/events/scmi.h
+++ b/include/trace/events/scmi.h
@@ -7,8 +7,6 @@
#include <linux/tracepoint.h>
-#define TRACE_SCMI_MAX_TAG_LEN 6
-
TRACE_EVENT(scmi_fc_call,
TP_PROTO(u8 protocol_id, u8 msg_id, u32 res_id, u32 val1, u32 val2),
TP_ARGS(protocol_id, msg_id, res_id, val1, val2),
@@ -156,7 +154,7 @@ TRACE_EVENT(scmi_msg_dump,
__field(u8, channel_id)
__field(u8, protocol_id)
__field(u8, msg_id)
- __array(char, tag, TRACE_SCMI_MAX_TAG_LEN)
+ __string(tag, tag)
__field(u16, seq)
__field(int, status)
__field(size_t, len)
@@ -168,7 +166,7 @@ TRACE_EVENT(scmi_msg_dump,
__entry->channel_id = channel_id;
__entry->protocol_id = protocol_id;
__entry->msg_id = msg_id;
- strscpy(__entry->tag, tag, TRACE_SCMI_MAX_TAG_LEN);
+ __assign_str(tag);
__entry->seq = seq;
__entry->status = status;
__entry->len = len;
@@ -177,7 +175,7 @@ TRACE_EVENT(scmi_msg_dump,
TP_printk("id=%d ch=%02X pt=%02X t=%s msg_id=%02X seq=%04X s=%d pyld=%s",
__entry->id, __entry->channel_id, __entry->protocol_id,
- __entry->tag, __entry->msg_id, __entry->seq, __entry->status,
+ __get_str(tag), __entry->msg_id, __entry->seq, __entry->status,
__print_hex_str(__get_dynamic_array(cmd), __entry->len))
);
#endif /* _TRACE_SCMI_H */
diff --git a/include/trace/events/scsi.h b/include/trace/events/scsi.h
index c36c72ab7f2b..e8328df587c3 100644
--- a/include/trace/events/scsi.h
+++ b/include/trace/events/scsi.h
@@ -303,8 +303,8 @@ DECLARE_EVENT_CLASS(scsi_cmd_done_timeout_template,
if (cmd->sense_buffer && SCSI_SENSE_VALID(cmd) &&
scsi_command_normalize_sense(cmd, &sshdr)) {
__entry->sense_key = sshdr.sense_key;
- __entry->asc = sshdr.asc;
- __entry->ascq = sshdr.ascq;
+ __entry->asc = scsi_sense_asc(&sshdr);
+ __entry->ascq = scsi_sense_ascq(&sshdr);
} else {
__entry->sense_key = 0;
__entry->asc = 0;
diff --git a/include/trace/events/timer.h b/include/trace/events/timer.h
index ca82fd62dc30..3aa0608c6361 100644
--- a/include/trace/events/timer.h
+++ b/include/trace/events/timer.h
@@ -302,7 +302,7 @@ DECLARE_EVENT_CLASS(hrtimer_class,
* hrtimer_start_expired - Invoked when a expired timer was started
* @hrtimer: pointer to struct hrtimer
*
- * Preceeded by a hrtimer_start tracepoint.
+ * Preceded by a hrtimer_start tracepoint.
*/
DEFINE_EVENT(hrtimer_class, hrtimer_start_expired,
diff --git a/include/trace/events/vmscan.h b/include/trace/events/vmscan.h
index b4bf7b8def1f..8a872990b4be 100644
--- a/include/trace/events/vmscan.h
+++ b/include/trace/events/vmscan.h
@@ -214,13 +214,6 @@ DEFINE_EVENT(mm_vmscan_direct_reclaim_begin_template, mm_vmscan_memcg_reclaim_be
TP_ARGS(gfp_flags, order, memcg)
);
-
-DEFINE_EVENT(mm_vmscan_direct_reclaim_begin_template, mm_vmscan_memcg_softlimit_reclaim_begin,
-
- TP_PROTO(gfp_t gfp_flags, int order, struct mem_cgroup *memcg),
-
- TP_ARGS(gfp_flags, order, memcg)
-);
#endif /* CONFIG_MEMCG */
DECLARE_EVENT_CLASS(mm_vmscan_direct_reclaim_end_template,
@@ -260,13 +253,6 @@ DEFINE_EVENT(mm_vmscan_direct_reclaim_end_template, mm_vmscan_memcg_reclaim_end,
TP_ARGS(nr_reclaimed, memcg)
);
-
-DEFINE_EVENT(mm_vmscan_direct_reclaim_end_template, mm_vmscan_memcg_softlimit_reclaim_end,
-
- TP_PROTO(unsigned long nr_reclaimed, struct mem_cgroup *memcg),
-
- TP_ARGS(nr_reclaimed, memcg)
-);
#endif /* CONFIG_MEMCG */
TRACE_EVENT(mm_shrink_slab_start,
diff --git a/include/trace/events/workqueue.h b/include/trace/events/workqueue.h
index b0de2bc9ed52..5b820ff8f81a 100644
--- a/include/trace/events/workqueue.h
+++ b/include/trace/events/workqueue.h
@@ -9,6 +9,7 @@
#include <linux/workqueue.h>
struct pool_workqueue;
+struct worker_pool;
/**
* workqueue_queue_work - called when a work gets queued
@@ -126,7 +127,152 @@ TRACE_EVENT(workqueue_execute_end,
TP_printk("work struct %p: function %ps", __entry->work, __entry->function)
);
+/**
+ * workqueue_cpu_intensive - called when a work item exceeds cpu_intensive threshold
+ * @pwq: pointer to struct pool_workqueue
+ * @work: pointer to struct work_struct
+ * @function: pointer to worker function
+ * @duration_us: CPU time consumed in microseconds
+ *
+ * This event occurs when a concurrency-managed work item runs for longer
+ * than wq_cpu_intensive_thresh_us without sleeping and is excluded from
+ * concurrency management to prevent stalling other work items.
+ */
+TRACE_EVENT(workqueue_cpu_intensive,
+
+ TP_PROTO(struct pool_workqueue *pwq, struct work_struct *work,
+ work_func_t function, u64 duration_us),
+
+ TP_ARGS(pwq, work, function, duration_us),
+
+ TP_STRUCT__entry(
+ __field( void *, work )
+ __field( void *, function )
+ __string( workqueue, pwq->wq->name )
+ __field( int, cpu )
+ __field( u64, duration_us )
+ ),
+
+ TP_fast_assign(
+ __entry->work = work;
+ __entry->function = function;
+ __assign_str(workqueue);
+ __entry->cpu = pwq->pool->cpu;
+ __entry->duration_us = duration_us;
+ ),
+
+ TP_printk("work struct=%p function=%ps workqueue=%s cpu=%d duration_us=%llu",
+ __entry->work, __entry->function, __get_str(workqueue),
+ __entry->cpu, __entry->duration_us)
+);
+
+/**
+ * workqueue_mayday - called when a pool_workqueue sends mayday to rescuer
+ * @pwq: pointer to struct pool_workqueue
+ *
+ * This event occurs when a worker pool fails to create a new worker and
+ * requests the workqueue's rescuer thread to process pending works.
+ */
+TRACE_EVENT(workqueue_mayday,
+
+ TP_PROTO(struct pool_workqueue *pwq),
+
+ TP_ARGS(pwq),
+
+ TP_STRUCT__entry(
+ __string( workqueue, pwq->wq->name )
+ __field( int, pool_id )
+ __field( int, cpu )
+ __field( int, nr_active )
+ ),
+
+ TP_fast_assign(
+ __assign_str(workqueue);
+ __entry->pool_id = pwq->pool->id;
+ __entry->cpu = pwq->pool->cpu;
+ __entry->nr_active = pwq->nr_active;
+ ),
+
+ TP_printk("workqueue=%s pool_id=%d cpu=%d nr_active=%d",
+ __get_str(workqueue), __entry->pool_id, __entry->cpu,
+ __entry->nr_active)
+);
+
+/**
+ * workqueue_rescued - called when a work item is assigned to a rescuer
+ * @pwq: pointer to struct pool_workqueue
+ * @work: pointer to struct work_struct
+ * @function: pointer to worker function
+ *
+ * This event occurs when a work item is claimed by a rescuer thread
+ * to guarantee forward progress.
+ */
+TRACE_EVENT(workqueue_rescued,
+
+ TP_PROTO(struct pool_workqueue *pwq, struct work_struct *work,
+ work_func_t function),
+
+ TP_ARGS(pwq, work, function),
+
+ TP_STRUCT__entry(
+ __field( void *, work )
+ __field( void *, function )
+ __string( workqueue, pwq->wq->name )
+ __field( int, cpu )
+ ),
+
+ TP_fast_assign(
+ __entry->work = work;
+ __entry->function = function;
+ __assign_str(workqueue);
+ __entry->cpu = pwq->pool->cpu;
+ ),
+
+ TP_printk("work struct=%p function=%ps workqueue=%s cpu=%d",
+ __entry->work, __entry->function, __get_str(workqueue),
+ __entry->cpu)
+);
+
+/**
+ * workqueue_bh_budget_yield - called when a BH worker yields due to budget exhaustion
+ * @pool: pointer to struct worker_pool
+ * @restarts: number of restarts executed
+ * @timeout: whether execution hit the time limit (BH_WORKER_JIFFIES)
+ * @highpri: whether this is a high-priority BH pool
+ *
+ * This event occurs when a bottom-half (BH) worker pool running in softirq
+ * context exhausts its execution time slice or restart limit and must yield
+ * execution.
+ */
+TRACE_EVENT(workqueue_bh_budget_yield,
+
+ TP_PROTO(struct worker_pool *pool, int restarts, bool timeout, bool highpri),
+
+ TP_ARGS(pool, restarts, timeout, highpri),
+
+ TP_STRUCT__entry(
+ __field( int, pool_id )
+ __field( int, cpu )
+ __field( int, restarts )
+ __field( bool, timeout )
+ __field( bool, highpri )
+ ),
+
+ TP_fast_assign(
+ __entry->pool_id = pool->id;
+ __entry->cpu = pool->cpu;
+ __entry->restarts = restarts;
+ __entry->timeout = timeout;
+ __entry->highpri = highpri;
+ ),
+
+ TP_printk("pool_id=%d cpu=%d restarts=%d timeout=%d highpri=%d",
+ __entry->pool_id, __entry->cpu, __entry->restarts,
+ __entry->timeout, __entry->highpri)
+);
+
#endif /* _TRACE_WORKQUEUE_H */
/* This part must be outside protection */
#include <trace/define_trace.h>
+
diff --git a/include/uapi/asm-generic/socket.h b/include/uapi/asm-generic/socket.h
index 84ea7b92936e..56fed7ab27ab 100644
--- a/include/uapi/asm-generic/socket.h
+++ b/include/uapi/asm-generic/socket.h
@@ -152,6 +152,10 @@
#define SO_RIGHTS_NOTRUNC 85
+#define SO_PASSPIDFD_THREAD 86
+
+#define SO_PEERPIDFD_THREAD 87
+
#if !defined(__KERNEL__)
#if __BITS_PER_LONG == 64 || (defined(__x86_64__) && defined(__ILP32__))
diff --git a/include/uapi/drm/amdgpu_drm.h b/include/uapi/drm/amdgpu_drm.h
index 42a5fa8ad6b0..29009f6aabde 100644
--- a/include/uapi/drm/amdgpu_drm.h
+++ b/include/uapi/drm/amdgpu_drm.h
@@ -59,6 +59,7 @@ extern "C" {
#define DRM_AMDGPU_USERQ_WAIT 0x18
#define DRM_AMDGPU_GEM_LIST_HANDLES 0x19
#define DRM_AMDGPU_PROC_OPTIONS 0x1A
+#define DRM_AMDGPU_UALINK_HANDLE 0x1B
#define DRM_IOCTL_AMDGPU_GEM_CREATE DRM_IOWR(DRM_COMMAND_BASE + DRM_AMDGPU_GEM_CREATE, union drm_amdgpu_gem_create)
#define DRM_IOCTL_AMDGPU_GEM_MMAP DRM_IOWR(DRM_COMMAND_BASE + DRM_AMDGPU_GEM_MMAP, union drm_amdgpu_gem_mmap)
@@ -81,6 +82,7 @@ extern "C" {
#define DRM_IOCTL_AMDGPU_USERQ_WAIT DRM_IOWR(DRM_COMMAND_BASE + DRM_AMDGPU_USERQ_WAIT, struct drm_amdgpu_userq_wait)
#define DRM_IOCTL_AMDGPU_GEM_LIST_HANDLES DRM_IOWR(DRM_COMMAND_BASE + DRM_AMDGPU_GEM_LIST_HANDLES, struct drm_amdgpu_gem_list_handles)
#define DRM_IOCTL_AMDGPU_PROC_OPTIONS DRM_IOWR(DRM_COMMAND_BASE + DRM_AMDGPU_PROC_OPTIONS, struct drm_amdgpu_proc_options)
+#define DRM_IOCTL_AMDGPU_UALINK_HANDLE DRM_IOWR(DRM_COMMAND_BASE + DRM_AMDGPU_UALINK_HANDLE, union drm_amdgpu_ualink_handle)
/**
* DOC: memory domains
@@ -115,6 +117,12 @@ extern "C" {
#define AMDGPU_GEM_DOMAIN_GWS 0x10
#define AMDGPU_GEM_DOMAIN_OA 0x20
#define AMDGPU_GEM_DOMAIN_DOORBELL 0x40
+#define AMDGPU_GEM_DOMAIN_MMIO_REMAP 0x80
+#define AMDGPU_GEM_DOMAIN_NPA 0x100
+
+/* User-mode is not allowed to allocate NPA space. As a result,
+ * we don't add AMDGPU_GEM_DOMAIN_NPA in the DOMAIN_MASK below.
+ */
#define AMDGPU_GEM_DOMAIN_MASK (AMDGPU_GEM_DOMAIN_CPU | \
AMDGPU_GEM_DOMAIN_GTT | \
AMDGPU_GEM_DOMAIN_VRAM | \
@@ -504,6 +512,11 @@ struct drm_amdgpu_userq_signal {
* @bo_write_handles.
*/
__u32 num_bo_write_handles;
+ /**
+ * @syncobj_points: The list of syncobj points submitted by the user queue job
+ * for the corresponding @syncobj_handles.
+ */
+ __u64 syncobj_points;
};
struct drm_amdgpu_userq_fence_info {
@@ -1170,6 +1183,8 @@ struct drm_amdgpu_cs_chunk_cp_gfx_shadow {
#define AMDGPU_INFO_FW_IMU 0x1b
/* Subquery id: Query VPE firmware version */
#define AMDGPU_INFO_FW_VPE 0x1c
+ /* Subquery id: Query MP5 firmware version */
+ #define AMDGPU_INFO_FW_MP5 0x1d
/* number of bytes moved for TTM migration */
#define AMDGPU_INFO_NUM_BYTES_MOVED 0x0f
@@ -1694,6 +1709,34 @@ struct drm_amdgpu_proc_options {
} kfd_sigbus_delay;
};
+#define DRM_AMDGPU_UALINK_HANDLE_OP_EXPORT 0
+#define DRM_AMDGPU_UALINK_HANDLE_OP_IMPORT 1
+
+struct drm_amdgpu_ualink_handle_in {
+ /* Export or import */
+ __u32 op;
+ /* For future use, no flags defined so far */
+ __u32 flags;
+ union {
+ /* GEM handle of the BO to export */
+ __u32 gem_handle;
+ /* UALink handle to import */
+ __u64 import_ualink_handle[2];
+ };
+};
+
+union drm_amdgpu_ualink_handle_out {
+ /* Exported UALink handle */
+ __u64 export_ualink_handle[2];
+ /** DMABuf representing the imported UALink handle */
+ __u32 import_dmabuf_handle;
+};
+
+union drm_amdgpu_ualink_handle {
+ struct drm_amdgpu_ualink_handle_in in;
+ union drm_amdgpu_ualink_handle_out out;
+};
+
#if defined(__cplusplus)
}
#endif
diff --git a/include/uapi/drm/drm_fourcc.h b/include/uapi/drm/drm_fourcc.h
index a103fdc0b3a3..0bb049f91524 100644
--- a/include/uapi/drm/drm_fourcc.h
+++ b/include/uapi/drm/drm_fourcc.h
@@ -1627,6 +1627,30 @@ drm_fourcc_canonicalize_nvidia_format_mod(__u64 modifier)
#define DRM_FORMAT_MOD_APPLE_GPU_TILED_COMPRESSED fourcc_mod_code(APPLE, 2)
/*
+ * Apple Interchange layout
+ *
+ * Apple Interchange is a compressed framebuffer format used exclusively for
+ * sharing buffers between hardware blocks (GPU, display controller, video
+ * codecs) on Apple platforms. It is similar to and uses the same compression
+ * scheme as GPU_TILED_COMPRESSED. There is no known uncompressed variant
+ * of Apple Interchange.
+ *
+ * Unlike the GPU layouts, tile size is not dependent on bit depth. RGB
+ * images and the chroma components of YUV images use 16x16 tiles. The
+ * luma component of YUV images uses 32x32 tiles. Compression tiles
+ * are once again 16x16 with 8 bytes of metadata per compression subtile.
+ *
+ * Following the example set by GPU_TILED_{,COMPRESSED}, Interchange images
+ * are treated as a single plane by software and do not have a meaningful
+ * stride.
+ *
+ * AGX has limited support for Apple Interchange. It cannot be used for Z/S
+ * buffers or array images, for example. It is intended for scanout buffer
+ * sharing only.
+ */
+#define DRM_FORMAT_MOD_APPLE_INTERCHANGE fourcc_mod_code(APPLE, 3)
+
+/*
* AMD modifiers
*
* Memory layout:
diff --git a/include/uapi/drm/drm_mode.h b/include/uapi/drm/drm_mode.h
index bd435effdcee..ed1a660a3dfd 100644
--- a/include/uapi/drm/drm_mode.h
+++ b/include/uapi/drm/drm_mode.h
@@ -955,6 +955,18 @@ enum drm_colorop_type {
* color = lut3d[index]
*/
DRM_COLOROP_3D_LUT,
+
+ /**
+ * @DRM_COLOROP_FIXED_MATRIX:
+ *
+ * enum string "Fixed Matrix"
+ *
+ * A Colorop block that performs a pre-defined matrix operation selected
+ * via the FIXED_MATRIX_TYPE enum property. The driver advertises the supported
+ * operations through this property.
+ */
+ DRM_COLOROP_FIXED_MATRIX,
+
};
/**
diff --git a/include/uapi/drm/drm_ras.h b/include/uapi/drm/drm_ras.h
index 218a3ee86805..2f832275ee6e 100644
--- a/include/uapi/drm/drm_ras.h
+++ b/include/uapi/drm/drm_ras.h
@@ -33,18 +33,36 @@ enum {
DRM_RAS_A_ERROR_COUNTER_ATTRS_ERROR_ID,
DRM_RAS_A_ERROR_COUNTER_ATTRS_ERROR_NAME,
DRM_RAS_A_ERROR_COUNTER_ATTRS_ERROR_VALUE,
+ DRM_RAS_A_ERROR_COUNTER_ATTRS_ERROR_THRESHOLD,
__DRM_RAS_A_ERROR_COUNTER_ATTRS_MAX,
DRM_RAS_A_ERROR_COUNTER_ATTRS_MAX = (__DRM_RAS_A_ERROR_COUNTER_ATTRS_MAX - 1)
};
enum {
+ DRM_RAS_A_ERROR_EVENT_ATTRS_DEVICE_NAME = 1,
+ DRM_RAS_A_ERROR_EVENT_ATTRS_NODE_ID,
+ DRM_RAS_A_ERROR_EVENT_ATTRS_NODE_NAME,
+ DRM_RAS_A_ERROR_EVENT_ATTRS_ERROR_ID,
+ DRM_RAS_A_ERROR_EVENT_ATTRS_ERROR_NAME,
+ DRM_RAS_A_ERROR_EVENT_ATTRS_ERROR_VALUE,
+
+ __DRM_RAS_A_ERROR_EVENT_ATTRS_MAX,
+ DRM_RAS_A_ERROR_EVENT_ATTRS_MAX = (__DRM_RAS_A_ERROR_EVENT_ATTRS_MAX - 1)
+};
+
+enum {
DRM_RAS_CMD_LIST_NODES = 1,
DRM_RAS_CMD_GET_ERROR_COUNTER,
DRM_RAS_CMD_CLEAR_ERROR_COUNTER,
+ DRM_RAS_CMD_ERROR_EVENT,
+ DRM_RAS_CMD_GET_ERROR_THRESHOLD,
+ DRM_RAS_CMD_SET_ERROR_THRESHOLD,
__DRM_RAS_CMD_MAX,
DRM_RAS_CMD_MAX = (__DRM_RAS_CMD_MAX - 1)
};
+#define DRM_RAS_MCGRP_ERROR_REPORT "error-report"
+
#endif /* _UAPI_LINUX_DRM_RAS_H */
diff --git a/include/uapi/drm/ivpu_accel.h b/include/uapi/drm/ivpu_accel.h
index 264505d54f93..9ce19d9c3131 100644
--- a/include/uapi/drm/ivpu_accel.h
+++ b/include/uapi/drm/ivpu_accel.h
@@ -1,6 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0-only WITH Linux-syscall-note */
/*
- * Copyright (C) 2020-2025 Intel Corporation
+ * Copyright (C) 2020-2026 Intel Corporation
*/
#ifndef __UAPI_IVPU_DRM_H__
@@ -96,6 +96,7 @@ extern "C" {
#define DRM_IVPU_PARAM_SKU 12
#define DRM_IVPU_PARAM_CAPABILITIES 13
#define DRM_IVPU_PARAM_PREEMPT_BUFFER_SIZE 14
+#define DRM_IVPU_PARAM_CMDQ_PRIORITY 15
#define DRM_IVPU_PLATFORM_TYPE_SILICON 0
@@ -141,6 +142,15 @@ extern "C" {
#define DRM_IVPU_CAP_BO_CREATE_FROM_USERPTR 4
/**
+ * DRM_IVPU_CAP_CMDQ_SET_PRIORITY
+ *
+ * Driver supports DRM_IVPU_PARAM_CMDQ_PRIORITY parameter to get/set command
+ * queue priority.
+ * This allows changing command queue priority after creation.
+ */
+#define DRM_IVPU_CAP_CMDQ_SET_PRIORITY 5
+
+/**
* struct drm_ivpu_param - Get/Set VPU parameters
*/
struct drm_ivpu_param {
@@ -192,6 +202,11 @@ struct drm_ivpu_param {
*
* %DRM_IVPU_PARAM_PREEMPT_BUFFER_SIZE:
* Size of the preemption buffer (read-only)
+ *
+ * %DRM_IVPU_PARAM_CMDQ_PRIORITY:
+ * Get/Set command queue priority (see DRM_IVPU_JOB_PRIORITY_*).
+ * DRM_IVPU_JOB_PRIORITY_DEFAULT is treated as DRM_IVPU_JOB_PRIORITY_NORMAL.
+ * Command queue ID is given via drm_ivpu_param.index.
*/
__u32 param;
diff --git a/include/uapi/drm/nova_drm.h b/include/uapi/drm/nova_drm.h
index 3ca90ed9d2bb..d7017ed17143 100644
--- a/include/uapi/drm/nova_drm.h
+++ b/include/uapi/drm/nova_drm.h
@@ -18,26 +18,56 @@
extern "C" {
#endif
-/*
- * NOVA_GETPARAM_VRAM_BAR_SIZE
- *
- * Query the VRAM BAR size in bytes.
+/**
+ * enum drm_nova_architecture - GPU architecture identifier
*/
-#define NOVA_GETPARAM_VRAM_BAR_SIZE 0x1
+enum drm_nova_architecture {
+ NOVA_DRM_ARCHITECTURE_TURING = 0x16,
+ NOVA_DRM_ARCHITECTURE_AMPERE = 0x17,
+ NOVA_DRM_ARCHITECTURE_HOPPER = 0x18,
+ NOVA_DRM_ARCHITECTURE_ADA = 0x19,
+ NOVA_DRM_ARCHITECTURE_BLACKWELL_GB10X = 0x1a,
+ NOVA_DRM_ARCHITECTURE_BLACKWELL_GB20X = 0x1b,
+};
/**
- * struct drm_nova_getparam - query GPU and driver metadata
+ * enum drm_nova_chipid - opaque GPU chip identifier
+ *
+ * These values identify the chip a GPU is based on. They are otherwise
+ * opaque: userspace must not assume the values carry any particular meaning
+ * or encoding, only that they may be compared against this enum.
*/
-struct drm_nova_getparam {
- /**
- * @param: The identifier of the parameter to query.
- */
- __u64 param;
-
- /**
- * @value: The value for the specified parameter.
- */
- __u64 value;
+enum drm_nova_chipid {
+ /* Turing */
+ NOVA_DRM_CHIPID_TU102 = 0x162,
+ NOVA_DRM_CHIPID_TU104 = 0x164,
+ NOVA_DRM_CHIPID_TU106 = 0x166,
+ NOVA_DRM_CHIPID_TU117 = 0x167,
+ NOVA_DRM_CHIPID_TU116 = 0x168,
+ /* Ampere */
+ NOVA_DRM_CHIPID_GA100 = 0x170,
+ NOVA_DRM_CHIPID_GA102 = 0x172,
+ NOVA_DRM_CHIPID_GA103 = 0x173,
+ NOVA_DRM_CHIPID_GA104 = 0x174,
+ NOVA_DRM_CHIPID_GA106 = 0x176,
+ NOVA_DRM_CHIPID_GA107 = 0x177,
+ /* Hopper */
+ NOVA_DRM_CHIPID_GH100 = 0x180,
+ /* Ada */
+ NOVA_DRM_CHIPID_AD102 = 0x192,
+ NOVA_DRM_CHIPID_AD103 = 0x193,
+ NOVA_DRM_CHIPID_AD104 = 0x194,
+ NOVA_DRM_CHIPID_AD106 = 0x196,
+ NOVA_DRM_CHIPID_AD107 = 0x197,
+ /* Blackwell GB10x */
+ NOVA_DRM_CHIPID_GB100 = 0x1a0,
+ NOVA_DRM_CHIPID_GB102 = 0x1a2,
+ /* Blackwell GB20x */
+ NOVA_DRM_CHIPID_GB202 = 0x1b2,
+ NOVA_DRM_CHIPID_GB203 = 0x1b3,
+ NOVA_DRM_CHIPID_GB205 = 0x1b5,
+ NOVA_DRM_CHIPID_GB206 = 0x1b6,
+ NOVA_DRM_CHIPID_GB207 = 0x1b7,
};
/**
@@ -80,14 +110,92 @@ struct drm_nova_gem_info {
__u64 size;
};
-#define DRM_NOVA_GETPARAM 0x00
+/**
+ * struct drm_nova_info - query device information
+ */
+struct drm_nova_info {
+ /**
+ * @id: The identifier of the information to query.
+ */
+ __u32 id;
+
+ /**
+ * @size: The amount of space allocated by userspace at @data. The kernel
+ * will return the number of bytes it wrote, or the size of the queried
+ * information structure if @data is NULL.
+ */
+ __u32 size;
+
+ /**
+ * @data: Pointer to the userspace buffer into which the queried
+ * information will be written. May be NULL, in which case nothing is
+ * written and @size is set to the size of the information structure so
+ * userspace can allocate a suitably sized buffer.
+ */
+ __u64 data;
+};
+
+/**
+ * DRM_NOVA_INFO_GPU
+ *
+ * Query GPU information. The result is returned in a
+ * &struct drm_nova_info_gpu.
+ */
+#define DRM_NOVA_INFO_GPU 0x00
+
+/**
+ * struct drm_nova_info_gpu - GPU information
+ */
+struct drm_nova_info_gpu {
+ /**
+ * @architecture: GPU architecture identifier.
+ *
+ * See &enum drm_nova_architecture for currently known architectures.
+ */
+ __u32 architecture;
+
+ /**
+ * @chipid: Opaque GPU chip identifier.
+ *
+ * See &enum drm_nova_chipid for currently known chips.
+ */
+ __u32 chipid;
+
+ /**
+ * @vram_size: Amount of usable FB, excluding GSP carveouts and protected
+ * regions.
+ */
+ __u64 vram_size;
+
+ /**
+ * @vram_bar_size: Size of the PCI BAR aperture used to access VRAM, in bytes.
+ */
+ __u64 vram_bar_size;
+
+ /**
+ * @gpu_name: NUL-terminated full GPU name.
+ */
+ __u8 gpu_name[64];
+
+ /**
+ * @gpu_short_name: NUL-terminated short GPU name.
+ */
+ __u8 gpu_short_name[64];
+
+ /**
+ * @gpu_gid: 16-byte SHA-1 GPU identifier supplied by GSP-RM.
+ */
+ __u8 gpu_gid[16];
+};
+
+#define DRM_NOVA_INFO 0x00
#define DRM_NOVA_GEM_CREATE 0x01
#define DRM_NOVA_GEM_INFO 0x02
/* Note: this is an enum so that it can be resolved by Rust bindgen. */
enum {
- DRM_IOCTL_NOVA_GETPARAM = DRM_IOWR(DRM_COMMAND_BASE + DRM_NOVA_GETPARAM,
- struct drm_nova_getparam),
+ DRM_IOCTL_NOVA_INFO = DRM_IOWR(DRM_COMMAND_BASE + DRM_NOVA_INFO,
+ struct drm_nova_info),
DRM_IOCTL_NOVA_GEM_CREATE = DRM_IOWR(DRM_COMMAND_BASE + DRM_NOVA_GEM_CREATE,
struct drm_nova_gem_create),
DRM_IOCTL_NOVA_GEM_INFO = DRM_IOWR(DRM_COMMAND_BASE + DRM_NOVA_GEM_INFO,
diff --git a/include/uapi/drm/panfrost_drm.h b/include/uapi/drm/panfrost_drm.h
index 50d5337f35ef..7831c48c59c0 100644
--- a/include/uapi/drm/panfrost_drm.h
+++ b/include/uapi/drm/panfrost_drm.h
@@ -47,7 +47,7 @@ extern "C" {
* them for anything but debugging purpose.
*/
#define DRM_IOCTL_PANFROST_PERFCNT_ENABLE DRM_IOW(DRM_COMMAND_BASE + DRM_PANFROST_PERFCNT_ENABLE, struct drm_panfrost_perfcnt_enable)
-#define DRM_IOCTL_PANFROST_PERFCNT_DUMP DRM_IOW(DRM_COMMAND_BASE + DRM_PANFROST_PERFCNT_DUMP, struct drm_panfrost_perfcnt_dump)
+#define DRM_IOCTL_PANFROST_PERFCNT_DUMP DRM_IOWR(DRM_COMMAND_BASE + DRM_PANFROST_PERFCNT_DUMP, struct drm_panfrost_perfcnt_dump)
#define PANFROST_JD_REQ_FS (1 << 0)
#define PANFROST_JD_REQ_CYCLE_COUNT (1 << 1)
@@ -270,8 +270,35 @@ struct drm_panfrost_perfcnt_enable {
__u32 counterset;
};
+/*
+ * The next two flags describe the state of a perfcnt dump request
+ * as influenced by a device reset. They are the only values the
+ * perfcnt_dump ioctl state field can take on.
+ * Only certain state and ioctl retval combinations are legitimate.
+ */
+
+/* A new perfcnt_enable ioctl should be issued before requesting
+ * more dumps, because a HW reset failed to recreate perfcnt's
+ * original state. Otherwise further perfcnt_dump's will fail.
+ * This flag being set means ioctl's retval is always -EIO.
+ */
+#define PANFROST_PERFCNT_SESSION_DEAD (1 << 0)
+
+/* A HW reset happened before or during a sample request, and
+ * perfcnt's internal state was successfully restored. There
+ * are two possible outcomes depending on the ioctl's retval:
+ * 0: A reset happened before a dump was requested, but did
+ * nonetheless succeed. Counter values are relative to last reset.
+ * -EAGAIN: A reset happened when a counter values sampling
+ * request was ongoing. Values are undefined so a new dump ioctl
+ * should be issued.
+ */
+#define PANFROST_PERFCNT_SESSION_INTERRUPTED_BY_RESET (1 << 1)
+
struct drm_panfrost_perfcnt_dump {
__u64 buf_ptr;
+ __u32 state;
+ __u32 pad; /* MBZ */
};
/* madvise provides a way to tell the kernel in case a buffers contents
diff --git a/include/uapi/drm/tegra_drm.h b/include/uapi/drm/tegra_drm.h
index 8f21f3a44832..b17472103e91 100644
--- a/include/uapi/drm/tegra_drm.h
+++ b/include/uapi/drm/tegra_drm.h
@@ -986,8 +986,8 @@ struct drm_tegra_channel_submit {
/**
* @syncobj_in: [in]
*
- * Handle for DRM syncobj that will be waited before submission.
- * Ignored if zero.
+ * Handle for DRM syncobj that will be waited for before the job
+ * executes. Ignored if zero.
*/
__u32 syncobj_in;
diff --git a/include/uapi/drm/xe_drm.h b/include/uapi/drm/xe_drm.h
index 509202a7b13e..578f0c1eb43e 100644
--- a/include/uapi/drm/xe_drm.h
+++ b/include/uapi/drm/xe_drm.h
@@ -1294,8 +1294,8 @@ struct xe_vm_fault {
#define FAULT_LEVEL_PML4 3
#define FAULT_LEVEL_PML5 4
__u8 fault_level;
- /** @pad: MBZ */
- __u8 pad;
+ /** @srcid: ID of the faulting hardware unit */
+ __u8 srcid;
/** @reserved: MBZ */
__u64 reserved[4];
};
@@ -1491,6 +1491,12 @@ struct drm_xe_exec_queue_destroy {
*
* The @property can be:
* - %DRM_XE_EXEC_QUEUE_GET_PROPERTY_BAN
+ *
+ * For %DRM_XE_EXEC_QUEUE_GET_PROPERTY_BAN, @value is a bitmask of ban reasons:
+ * - %DRM_XE_EXEC_QUEUE_BAN_REASON_GPU_HANG - banned due to GPU hang/timeout
+ * - %DRM_XE_EXEC_QUEUE_BAN_REASON_PAGE_OFFLINE - banned due to memory page offline
+ *
+ * A @value of 0 means the exec queue is not banned.
*/
struct drm_xe_exec_queue_get_property {
/** @extensions: Pointer to the first extension struct, if any */
@@ -1503,7 +1509,17 @@ struct drm_xe_exec_queue_get_property {
/** @property: property to get */
__u32 property;
- /** @value: property value */
+ /**
+ * @value: property value
+ *
+ * For %DRM_XE_EXEC_QUEUE_GET_PROPERTY_BAN, this is a bitmask of:
+ * - %DRM_XE_EXEC_QUEUE_BAN_REASON_GPU_HANG - banned due to GPU hang/timeout
+ * - %DRM_XE_EXEC_QUEUE_BAN_REASON_PAGE_OFFLINE - banned due to memory page offline
+ *
+ * Value of 0 means the exec queue is not banned.
+ */
+#define DRM_XE_EXEC_QUEUE_BAN_REASON_GPU_HANG (1 << 0)
+#define DRM_XE_EXEC_QUEUE_BAN_REASON_PAGE_OFFLINE (1 << 1)
__u64 value;
/** @reserved: Reserved */
diff --git a/include/uapi/linux/alloc_tag.h b/include/uapi/linux/alloc_tag.h
index e3ad94444864..7d4618bea043 100644
--- a/include/uapi/linux/alloc_tag.h
+++ b/include/uapi/linux/alloc_tag.h
@@ -38,6 +38,7 @@ struct allocinfo_counter {
__u64 bytes;
__u64 calls;
__u8 accurate;
+ __u8 pad[7];
} __attribute__((aligned(8)));
struct allocinfo_tag_data {
diff --git a/include/uapi/linux/android/binder.h b/include/uapi/linux/android/binder.h
index 701cad36de43..96e5b0184a1b 100644
--- a/include/uapi/linux/android/binder.h
+++ b/include/uapi/linux/android/binder.h
@@ -296,6 +296,7 @@ enum transaction_flags {
TF_ACCEPT_FDS = 0x10, /* allow replies with file descriptors */
TF_CLEAR_BUF = 0x20, /* clear buffer on txn complete */
TF_UPDATE_TXN = 0x40, /* update the outdated pending async txn */
+ TF_DEFER_COMPLETE = 0x80, /* defer transaction complete to userspace */
};
struct binder_transaction_data {
diff --git a/include/uapi/linux/atm.h b/include/uapi/linux/atm.h
index 95ebdcf4fe88..7a3789f39f52 100644
--- a/include/uapi/linux/atm.h
+++ b/include/uapi/linux/atm.h
@@ -39,7 +39,7 @@
#define ATM_MAX_VCI 65535 /* maximum VCI */
-/* "protcol" values for the socket system call */
+/* "protocol" values for the socket system call */
#define ATM_NO_AAL 0 /* AAL not specified */
#define ATM_AAL0 13 /* "raw" ATM cells */
#define ATM_AAL1 1 /* AAL1 (CBR) */
diff --git a/include/uapi/linux/audit.h b/include/uapi/linux/audit.h
index e8f5ce677df7..abae0524746e 100644
--- a/include/uapi/linux/audit.h
+++ b/include/uapi/linux/audit.h
@@ -122,6 +122,7 @@
#define AUDIT_OPENAT2 1337 /* Record showing openat2 how args */
#define AUDIT_DM_CTRL 1338 /* Device Mapper target control */
#define AUDIT_DM_EVENT 1339 /* Device Mapper events */
+#define AUDIT_FSOPEN 1340 /* Record showing fsopen fs_name arg */
#define AUDIT_AVC 1400 /* SE Linux avc denial or grant */
#define AUDIT_SELINUX_ERR 1401 /* Internal SE Linux Errors */
diff --git a/include/uapi/linux/bpf.h b/include/uapi/linux/bpf.h
index 732b35cc08d1..f29b0aad440c 100644
--- a/include/uapi/linux/bpf.h
+++ b/include/uapi/linux/bpf.h
@@ -56,6 +56,19 @@
enum bpf_cond_pseudo_jmp {
BPF_MAY_GOTO = 0,
+ /*
+ * Follows a call of a bpf subprog. Taken when the subprog left with
+ * BPF_EXIT that has src_reg == BPF_UNWIND_EXIT.
+ */
+ BPF_UNWIND_GOTO = 1,
+};
+
+enum bpf_pseudo_exit {
+ /*
+ * When bpf_exit->src_reg == BPF_UNWIND_EXIT, it's the same as bpf_exit,
+ * except that BPF_UNWIND_GOTO after the call is taken.
+ */
+ BPF_UNWIND_EXIT = 1,
};
/* Register numbers */
@@ -936,6 +949,33 @@ union bpf_iter_link_info {
* 0 on success or -1 if an error occurred (in which case,
* *errno* is set appropriately).
*
+ * BPF_PROG_STREAM_OPEN
+ * Description
+ * Open a file descriptor for one of the BPF streams associated
+ * with the program identified by *prog_fd*. The stream is selected
+ * by *stream_id*.
+ *
+ * The returned file descriptor supports **read**\ (2) and
+ * **poll**\ (2). Reads block while the stream is empty unless
+ * **BPF_F_STREAM_NONBLOCK** is specified in *flags*. A non-blocking
+ * read of an empty stream fails with **EAGAIN**.
+ *
+ * **poll**\ (2) reports **POLLIN** when data is available and
+ * **POLLHUP** once the program has been freed, that is, after every
+ * reference to it, including links and other file descriptors, has
+ * been dropped. Hangup may lag the final release because program
+ * teardown is deferred. Buffered data remains readable after
+ * **POLLHUP** and a read returns zero after all such data has been
+ * consumed.
+ *
+ * The file descriptor is read-only and has the close-on-exec flag
+ * set. It is not seekable and **lseek**\ (2) fails with **ESPIPE**.
+ * *flags* may only contain **BPF_F_STREAM_NONBLOCK**.
+ *
+ * Return
+ * A new file descriptor (a nonnegative integer), or -1 if an
+ * error occurred (in which case, *errno* is set appropriately).
+ *
* NOTES
* eBPF objects (maps and programs) can be shared between processes.
*
@@ -993,6 +1033,7 @@ enum bpf_cmd {
BPF_TOKEN_CREATE,
BPF_PROG_STREAM_READ_BY_FD,
BPF_PROG_ASSOC_STRUCT_OPS,
+ BPF_PROG_STREAM_OPEN,
__MAX_BPF_CMD,
BPF_COMMON_ATTRS = 1 << 16, /* Indicate carrying syscall common attrs. */
};
@@ -1316,6 +1357,12 @@ enum bpf_perf_event_type {
/* The verifier internal test flag. Behavior is undefined */
#define BPF_F_TEST_REG_INVARIANTS (1U << 7)
+/*
+ * Load and store through a number is an access to the arena of the program
+ * at the low 32 bits of the number. It's for programs written in Rust.
+ */
+#define BPF_F_ARENA_SCALAR (1U << 8)
+
/* link_create.kprobe_multi.flags used in LINK_CREATE command for
* BPF_TRACE_KPROBE_MULTI attach type to create return probe.
*/
@@ -1524,6 +1571,11 @@ enum {
BPF_STREAM_STDERR = 2,
};
+/* flags for BPF_PROG_STREAM_OPEN command */
+enum {
+ BPF_F_STREAM_NONBLOCK = (1U << 0),
+};
+
union bpf_attr {
struct { /* anonymous struct used by BPF_MAP_CREATE command */
__u32 map_type; /* one of enum bpf_map_type */
@@ -1756,7 +1808,7 @@ union bpf_attr {
__u32 prog_cnt;
__u32 count;
};
- __u32 :32;
+ __u32 type_id;
/* output: per-program attach_flags.
* not allowed to be set during effective query.
*/
@@ -1950,6 +2002,12 @@ union bpf_attr {
__u32 flags;
} prog_assoc_struct_ops;
+ struct {
+ __u32 prog_fd;
+ __u32 stream_id;
+ __u32 flags;
+ } prog_stream_open;
+
} __attribute__((aligned(8)));
/* The description below is an attempt at providing documentation to eBPF
@@ -4867,15 +4925,18 @@ union bpf_attr {
* The non-negative copied *buf* length equal to or less than
* *size* on success, or a negative error in case of failure.
*
- * long bpf_load_hdr_opt(struct bpf_sock_ops *skops, void *searchby_res, u32 len, u64 flags)
+ * long bpf_load_hdr_opt(void *ctx, void *searchby_res, u32 len, u64 flags)
* Description
* Load header option. Support reading a particular TCP header
- * option for bpf program (**BPF_PROG_TYPE_SOCK_OPS**).
+ * option for bpf program (**BPF_PROG_TYPE_SOCK_OPS**). For the
+ * **bpf_tcp_ops** struct_ops, this helper can be called from the
+ * **parse_hdr**\ () and **write_hdr_opt**\ () operators.
*
- * If *flags* is 0, it will search the option from the
- * *skops*\ **->skb_data**. The comment in **struct bpf_sock_ops**
- * has details on what skb_data contains under different
- * *skops*\ **->op**.
+ * If *flags* is 0, it will search the option from the packet
+ * associated with the current operation. For
+ * **BPF_PROG_TYPE_SOCK_OPS**, the comment in
+ * **struct bpf_sock_ops** has details on what skb_data
+ * contains under different *op*.
*
* The first byte of the *searchby_res* specifies the
* kind that it wants to search.
@@ -4908,6 +4969,8 @@ union bpf_attr {
*
* * **BPF_LOAD_HDR_OPT_TCP_SYN** to search from the
* saved_syn packet or the just-received syn packet.
+ * Not supported by the **bpf_tcp_ops** struct_ops, which
+ * rejects all flags.
*
* Return
* > 0 when found, the header option is copied to *searchby_res*.
@@ -4928,9 +4991,9 @@ union bpf_attr {
* packet.
*
* **-EPERM** if the helper cannot be used under the current
- * *skops*\ **->op**.
+ * operation.
*
- * long bpf_store_hdr_opt(struct bpf_sock_ops *skops, const void *from, u32 len, u64 flags)
+ * long bpf_store_hdr_opt(void *ctx, const void *from, u32 len, u64 flags)
* Description
* Store header option. The data will be copied
* from buffer *from* with length *len* to the TCP header.
@@ -4946,7 +5009,9 @@ union bpf_attr {
* by searching the same option in the outgoing skb.
*
* This helper can only be called during
- * **BPF_SOCK_OPS_WRITE_HDR_OPT_CB**.
+ * **BPF_SOCK_OPS_WRITE_HDR_OPT_CB**, or from the
+ * **write_hdr_opt**\ () operator of the **bpf_tcp_ops**
+ * struct_ops.
*
* Return
* 0 on success, or negative error in case of failure:
@@ -4961,9 +5026,9 @@ union bpf_attr {
* **-EFAULT** on failure to parse the existing header options.
*
* **-EPERM** if the helper cannot be used under the current
- * *skops*\ **->op**.
+ * operation.
*
- * long bpf_reserve_hdr_opt(struct bpf_sock_ops *skops, u32 len, u64 flags)
+ * long bpf_reserve_hdr_opt(void *ctx, u32 len, u64 flags)
* Description
* Reserve *len* bytes for the bpf header option. The
* space will be used by **bpf_store_hdr_opt**\ () later in
@@ -4973,7 +5038,9 @@ union bpf_attr {
* the total number of bytes will be reserved.
*
* This helper can only be called during
- * **BPF_SOCK_OPS_HDR_OPT_LEN_CB**.
+ * **BPF_SOCK_OPS_HDR_OPT_LEN_CB**, or from the
+ * **hdr_opt_len**\ () operator of the **bpf_tcp_ops**
+ * struct_ops.
*
* Return
* 0 on success, or negative error in case of failure:
@@ -4983,7 +5050,7 @@ union bpf_attr {
* **-ENOSPC** if there is not enough space in the header.
*
* **-EPERM** if the helper cannot be used under the current
- * *skops*\ **->op**.
+ * operation.
*
* void *bpf_inode_storage_get(struct bpf_map *map, void *inode, void *value, u64 flags)
* Description
@@ -6890,6 +6957,8 @@ struct bpf_link_info {
} xdp;
struct {
__u32 map_id;
+ __u32 :32;
+ __u64 cgroup_id;
} struct_ops;
struct {
__u32 pf;
@@ -7284,6 +7353,31 @@ enum {
*/
};
+/*
+ * Most callbacks of struct bpf_tcp_ops are placed in the slow
+ * path (e.g., one-shot connection setup or unlikely events like
+ * timers) and are invoked simply by defining non-NULL callbacks.
+ *
+ * Callbacks in the fast path, however, would incur noticeable
+ * overhead even when set to NULL, so they are disabled by default
+ * and must be explicitly enabled per socket via bpf_tcp_ops_set_flags().
+ *
+ * The flags are per-socket and shared by all effective bpf_tcp_ops
+ * programs.
+ */
+enum {
+ /* .rtt() */
+ BPF_TCP_OPS_FLAG_RTT = (1 << 0),
+ /* .parse_hdr() */
+ BPF_TCP_OPS_FLAG_PARSE_HDR_OPT_ALL = (1 << 1),
+ BPF_TCP_OPS_FLAG_PARSE_HDR_OPT_UNKNOWN = (1 << 2),
+ /* .hdr_opt_len() and .write_hdr_opt() */
+ BPF_TCP_OPS_FLAG_WRITE_HDR_OPT = (1 << 3),
+ /* .enqueue_rcvq() and .dequeue_rcvq() */
+ BPF_TCP_OPS_FLAG_RCVQ = (1 << 4),
+ BPF_TCP_OPS_FLAG_ALL = (1 << 5) - 1,
+};
+
/* List of TCP states. There is a build check in net/ipv4/tcp.c to detect
* changes between the TCP and BPF versions. Ideally this should never happen.
* If it does, we need to add code to convert them before calling
@@ -7600,6 +7694,10 @@ struct bpf_task_work {
__u64 __opaque;
} __attribute__((aligned(8)));
+struct bpf_rcu_head {
+ __u64 __opaque[6];
+} __attribute__((aligned(8)));
+
struct bpf_wq {
__u64 __opaque[2];
} __attribute__((aligned(8)));
diff --git a/include/uapi/linux/btf.h b/include/uapi/linux/btf.h
index 618167cab4e6..11d65871d163 100644
--- a/include/uapi/linux/btf.h
+++ b/include/uapi/linux/btf.h
@@ -54,8 +54,8 @@ struct btf_type {
* decl_tag and type_tag
*/
__u32 info;
- /* "size" is used by INT, ENUM, STRUCT, UNION, DATASEC and ENUM64.
- * "size" tells the size of the type it is describing.
+ /* "size" is used by INT, ENUM, STRUCT, UNION, DATASEC, ENUM64
+ * and LOC_PARAM. "size" tells the size of the type it is describing.
*
* "type" is used by PTR, TYPEDEF, VOLATILE, CONST, RESTRICT,
* FUNC, FUNC_PROTO, VAR, DECL_TAG and TYPE_TAG.
@@ -92,7 +92,9 @@ enum {
BTF_KIND_DECL_TAG = 17, /* Decl Tag */
BTF_KIND_TYPE_TAG = 18, /* Type Tag */
BTF_KIND_ENUM64 = 19, /* Enumeration up to 64-bit values */
-
+ BTF_KIND_LOC_PARAM = 20, /* Location parameter information */
+ BTF_KIND_LOC_PROTO = 21, /* Location prototype for site */
+ BTF_KIND_LOCSEC = 22, /* Location section */
NR_BTF_KINDS,
BTF_KIND_MAX = NR_BTF_KINDS - 1,
};
@@ -212,4 +214,79 @@ struct btf_enum64 {
__u32 val_hi32;
};
+/*
+ * BTF_KIND_LOC_PARAM is followed by a single "struct btf_loc_param"
+ * that contains flags specifying the contents of the vlen-specified
+ * number of 4-byte values that follow.
+ */
+struct btf_loc_param {
+ __u32 flags;
+ __u32 values[];
+};
+
+/*
+ * The combination of size, vlen and flags gives us the means to interpret
+ * the following vlen-specified set of 4-byte values:
+ *
+ * - a BTF_LOC_PARAM_CONST is a constant value; combination
+ * of size, vlen and _SIGNED flag determines it. If the value requires
+ * 64 bits it is stored in {lo,hi} order.
+ * - a BTF_LOC_PARAM_ADDR|BTF_LOC_PARAM_CONST is an address that should be
+ * normalized with respect to kernel/module base address.
+ * - a BTF_LOC_PARAM_REG with vlen 1 is a simple register number;
+ * with vlen 2 it is a multi-register parameter. Register numbers are
+ * numbers derived from DW_OP_reg values, i.e. 0 is DW_OP_reg0; since
+ * DW_OP_fbreg has its own special DW_OP_value and DW_OP_regx can refer
+ * to an arbitrary register number, we reserve BTF_LOC_PARAM_FBREG for
+ * the frame base register to avoid collisions.
+ * - a _REG | OFFSET describes an address without dereferencing it.
+ * - a _REG | DEREF with vlen 1 dereferences the value in the register
+ * number specified.
+ * - a REG | DEREF | OFFSET with vlen > 1 specifies the register number
+ * in the first 4-byte value and the offset in the remainder.
+ * In the case of REG and OFFSET combinations, the OFFSET has the width
+ * of the value words while the type size describes the represented parameter,
+ * so for example a REG | DEREF | OFFSET with size 8 and vlen 2 would be
+ * an 8-byte register dereference with signed 4-byte offset, since the vlen 2
+ * values consist of a register value and the signed value.
+ */
+enum btf_loc_param_flags {
+ BTF_LOC_PARAM_SIGNED = 0x1,
+ BTF_LOC_PARAM_CONST = 0x2,
+ BTF_LOC_PARAM_ADDR = 0x4,
+ BTF_LOC_PARAM_REG = 0x8,
+ BTF_LOC_PARAM_DEREF = 0x10,
+ BTF_LOC_PARAM_OFFSET = 0x20,
+};
+
+enum {
+ BTF_LOC_PARAM_FBREG = 0xffffffff
+};
+
+/*
+ * BTF_KIND_LOC_PROTO specifies location prototypes; i.e. how locations relate
+ * to parameters; a struct btf_type of BTF_KIND_LOC_PROTO is followed by a
+ * vlen-specified number of __u32 BTF type ids which specify the associated
+ * BTF_KIND_LOC_PARAM for each function parameter associated with the
+ * location. The type should either be 0 (no location info) or point at
+ * a BTF_KIND_LOC_PARAM.
+ */
+
+/*
+ * BTF_KIND_LOCSEC consists of vlen-specified number of "struct btf_loc"
+ * containing location site-specific information for a specific ELF section;
+ * for example locations in ".text" are in a LOCSEC named "inline.text".
+ *
+ * - function (func)
+ * - location prototype type id (loc_proto)
+ * - address offset (offset) relative to the runtime base address of the
+ * ELF section associated with the LOCSEC
+ */
+
+struct btf_loc {
+ __u32 func;
+ __u32 loc_proto;
+ __u32 offset;
+};
+
#endif /* _UAPI__LINUX_BTF_H__ */
diff --git a/include/uapi/linux/btrfs_tree.h b/include/uapi/linux/btrfs_tree.h
index cc3b9f7dccaf..47ee52859b45 100644
--- a/include/uapi/linux/btrfs_tree.h
+++ b/include/uapi/linux/btrfs_tree.h
@@ -230,7 +230,7 @@
*
* Stored as an inline ref rather to avoid wasting space on a separate item on
* top of the existing extent item. However, unlike the other inline refs,
- * there is one one owner ref per extent rather than one per extent.
+ * there is one owner ref per extent rather than one per extent.
*
* Because of this, it goes at the front of the list of inline refs, and thus
* must have a lower type value than any other inline ref type (to satisfy the
@@ -243,7 +243,7 @@
#define BTRFS_EXTENT_DATA_REF_KEY 178
/*
- * Obsolete key. Defintion removed in 6.6, value may be reused in the future.
+ * Obsolete key. Definition removed in 6.6, value may be reused in the future.
*
* #define BTRFS_EXTENT_REF_V0_KEY 180
*/
@@ -1255,13 +1255,16 @@ static inline __u16 btrfs_qgroup_level(__u64 qgroupid)
}
/*
- * is subvolume quota turned on?
- */
-#define BTRFS_QGROUP_STATUS_FLAG_ON (1ULL << 0)
-/*
- * RESCAN is set during the initialization phase
+ * The following BTRFS_QGROUP_STATUS_BIT_* are for * btrfs_qgroup_status_item::flags.
+ *
+ * Is subvolume quota turned on?
*/
-#define BTRFS_QGROUP_STATUS_FLAG_RESCAN (1ULL << 1)
+#define BTRFS_QGROUP_STATUS_BIT_ON (0)
+#define BTRFS_QGROUP_STATUS_FLAG_ON (1UL << BTRFS_QGROUP_STATUS_BIT_ON)
+
+/* RESCAN is set during the initialization phase */
+#define BTRFS_QGROUP_STATUS_BIT_RESCAN (1)
+#define BTRFS_QGROUP_STATUS_FLAG_RESCAN (1UL << BTRFS_QGROUP_STATUS_BIT_RESCAN)
/*
* Some qgroup entries are known to be out of date,
* either because the configuration has changed in a way that
@@ -1269,14 +1272,16 @@ static inline __u16 btrfs_qgroup_level(__u64 qgroupid)
* with a non-qgroup-aware version.
* Turning qouta off and on again makes it inconsistent, too.
*/
-#define BTRFS_QGROUP_STATUS_FLAG_INCONSISTENT (1ULL << 2)
+#define BTRFS_QGROUP_STATUS_BIT_INCONSISTENT (2)
+#define BTRFS_QGROUP_STATUS_FLAG_INCONSISTENT (1UL << BTRFS_QGROUP_STATUS_BIT_INCONSISTENT)
/*
* Whether or not this filesystem is using simple quotas. Not exactly the
* incompat bit, because we support using simple quotas, disabling it, then
* going back to full qgroup quotas.
*/
-#define BTRFS_QGROUP_STATUS_FLAG_SIMPLE_MODE (1ULL << 3)
+#define BTRFS_QGROUP_STATUS_BIT_SIMPLE_MODE (3)
+#define BTRFS_QGROUP_STATUS_FLAG_SIMPLE_MODE (1UL << BTRFS_QGROUP_STATUS_BIT_SIMPLE_MODE)
#define BTRFS_QGROUP_STATUS_FLAGS_MASK (BTRFS_QGROUP_STATUS_FLAG_ON | \
BTRFS_QGROUP_STATUS_FLAG_RESCAN | \
diff --git a/include/uapi/linux/close_range.h b/include/uapi/linux/close_range.h
index 2d804281554c..7da9ed95258a 100644
--- a/include/uapi/linux/close_range.h
+++ b/include/uapi/linux/close_range.h
@@ -2,11 +2,34 @@
#ifndef _UAPI_LINUX_CLOSE_RANGE_H
#define _UAPI_LINUX_CLOSE_RANGE_H
-/* Unshare the file descriptor table before closing file descriptors. */
-#define CLOSE_RANGE_UNSHARE (1U << 1)
+/*
+ * A macro of one of these names defined before this header is parsed, by
+ * a libc or by a program's own fallback, would replace the enumerator.
+ */
+#undef CLOSE_RANGE_UNSHARE
+#undef CLOSE_RANGE_CLOEXEC
+#undef CLOSE_RANGE_EXCEPT
+#undef CLOSE_RANGE_CLOEXEC_ONLY
-/* Set the FD_CLOEXEC bit instead of closing the file descriptor. */
-#define CLOSE_RANGE_CLOEXEC (1U << 2)
+enum close_range_flags {
+ /* Unshare the file descriptor table before closing file descriptors. */
+ CLOSE_RANGE_UNSHARE = (1U << 1),
+
+ /* Set the FD_CLOEXEC bit instead of closing the file descriptor. */
+ CLOSE_RANGE_CLOEXEC = (1U << 2),
+
+ /* Act on every file descriptor outside of the given range instead. */
+ CLOSE_RANGE_EXCEPT = (1U << 3),
+
+ /* Only close file descriptors that have the FD_CLOEXEC bit set. */
+ CLOSE_RANGE_CLOEXEC_ONLY = (1U << 4),
+};
+
+/* Keep #ifdef working and let glibc skip its own definitions. */
+#define CLOSE_RANGE_UNSHARE CLOSE_RANGE_UNSHARE
+#define CLOSE_RANGE_CLOEXEC CLOSE_RANGE_CLOEXEC
+#define CLOSE_RANGE_EXCEPT CLOSE_RANGE_EXCEPT
+#define CLOSE_RANGE_CLOEXEC_ONLY CLOSE_RANGE_CLOEXEC_ONLY
#endif /* _UAPI_LINUX_CLOSE_RANGE_H */
diff --git a/include/uapi/linux/coredump.h b/include/uapi/linux/coredump.h
index dc3789b78af0..6d0c53b534ea 100644
--- a/include/uapi/linux/coredump.h
+++ b/include/uapi/linux/coredump.h
@@ -11,12 +11,53 @@
* @COREDUMP_USERSPACE: userspace writes coredump
* @COREDUMP_REJECT: don't generate coredump
* @COREDUMP_WAIT: wait for coredump server
+ * @COREDUMP_RECORDS: send the coredump as a sequence of records instead of
+ * as a plain byte stream, see struct coredump_record_header;
+ * requires COREDUMP_KERNEL
+ * @COREDUMP_SPARSE: describe the holes in the coredump as zero records
+ * instead of transferring them; requires COREDUMP_RECORDS
+ * @COREDUMP_MEMORY_TYPES: dump the memory types in
+ * coredump_ack->memory_types instead of the ones
+ * the task selected; requires COREDUMP_KERNEL
*/
enum {
COREDUMP_KERNEL = (1ULL << 0),
COREDUMP_USERSPACE = (1ULL << 1),
COREDUMP_REJECT = (1ULL << 2),
COREDUMP_WAIT = (1ULL << 3),
+ COREDUMP_RECORDS = (1ULL << 4),
+ COREDUMP_SPARSE = (1ULL << 5),
+ COREDUMP_MEMORY_TYPES = (1ULL << 6),
+};
+
+/**
+ * coredump memory types
+ * @COREDUMP_MEMORY_ANON_PRIVATE: anonymous private memory
+ * @COREDUMP_MEMORY_ANON_SHARED: anonymous shared memory
+ * @COREDUMP_MEMORY_FILE_PRIVATE: file-backed private memory
+ * @COREDUMP_MEMORY_FILE_SHARED: file-backed shared memory
+ * @COREDUMP_MEMORY_ELF_HEADERS: the first page of a file-backed private
+ * mapping that starts an ELF file
+ * @COREDUMP_MEMORY_HUGETLB_PRIVATE: hugetlb private memory
+ * @COREDUMP_MEMORY_HUGETLB_SHARED: hugetlb shared memory
+ * @COREDUMP_MEMORY_DAX_PRIVATE: DAX private memory
+ * @COREDUMP_MEMORY_DAX_SHARED: DAX shared memory
+ *
+ * A bitmask of memory types a coredump may request to be included. New
+ * memory type bits must ensure that they do not steal memory from an
+ * existing one so a coredump server will continue to get the same
+ * coredumps even if a new bit is introduced.
+ */
+enum {
+ COREDUMP_MEMORY_ANON_PRIVATE = (1ULL << 0),
+ COREDUMP_MEMORY_ANON_SHARED = (1ULL << 1),
+ COREDUMP_MEMORY_FILE_PRIVATE = (1ULL << 2),
+ COREDUMP_MEMORY_FILE_SHARED = (1ULL << 3),
+ COREDUMP_MEMORY_ELF_HEADERS = (1ULL << 4),
+ COREDUMP_MEMORY_HUGETLB_PRIVATE = (1ULL << 5),
+ COREDUMP_MEMORY_HUGETLB_SHARED = (1ULL << 6),
+ COREDUMP_MEMORY_DAX_PRIVATE = (1ULL << 7),
+ COREDUMP_MEMORY_DAX_SHARED = (1ULL << 8),
};
/**
@@ -24,17 +65,19 @@ enum {
* @size: size of struct coredump_req
* @size_ack: known size of struct coredump_ack on this kernel
* @mask: supported features
+ * @memory_types: the memory types the task selected
+ * @memory_types_mask: the memory types this kernel knows
*
* When a coredump happens the kernel will connect to the coredump
* socket and send a coredump request to the coredump server. The @size
* member is set to the size of struct coredump_req and provides a hint
* to userspace how much data can be read. Userspace may use MSG_PEEK to
* peek the size of struct coredump_req and then choose to consume it in
- * one go. Userspace may also simply read a COREDUMP_ACK_SIZE_VER0
+ * one go. Userspace may also simply read a COREDUMP_REQ_SIZE_VER0
* request. If the size the kernel sends is larger userspace simply
* discards any remaining data.
*
- * The coredump_req->mask member is set to the currently know features.
+ * The coredump_req->mask member is set to the currently known features.
* Userspace may only set coredump_ack->mask to the bits raised by the
* kernel in coredump_req->mask.
*
@@ -42,15 +85,27 @@ enum {
* struct coredump_ack the kernel knows. Userspace may only send up to
* coredump_req->size_ack bytes to the kernel and must set
* coredump_ack->size accordingly.
+ *
+ * @memory_types is set to the default memory types that are included in
+ * the coredump. This can be overridden by raising bits in
+ * coredump_ack->memory_types.
+ *
+ * @memory_types_mask contains a bitmask of all memory types the kernel
+ * knows about. A coredump server may only raise bits in
+ * coredump_ack->memory_types that are raised in
+ * coredump_req->memory_types_mask.
*/
struct coredump_req {
__u32 size;
__u32 size_ack;
__u64 mask;
+ __u64 memory_types;
+ __u64 memory_types_mask;
};
enum {
COREDUMP_REQ_SIZE_VER0 = 16U, /* size of first published struct */
+ COREDUMP_REQ_SIZE_VER1 = 32U, /* memory_types and memory_types_mask added */
};
/**
@@ -58,6 +113,8 @@ enum {
* @size: size of the struct
* @spare: unused
* @mask: features kernel is supposed to use
+ * @memory_types: memory types to dump, only with COREDUMP_MEMORY_TYPES
+ * in @mask
*
* The @size member must be set to the size of struct coredump_ack. It
* may never exceed what the kernel returned in coredump_req->size_ack
@@ -67,15 +124,30 @@ enum {
* The @mask member must be set to the features the coredump server
* wants the kernel to use. Only bits the kernel returned in
* coredump_req->mask may be set.
+ *
+ * If COREDUMP_MEMORY_TYPES is raised in @mask the kernel dumps the
+ * memory types set in the @memory_types mask. Zero is valid and dumps
+ * no memory apart from the mappings that are always dumped.
+ *
+ * Note that memory a task excluded via MADV_DONTDUMP is always left
+ * out. A coredump server wanting to add or drop memory types instead of
+ * outright replacing it should simply copy coredump_req->memory_types
+ * and then mask off or raise types as needed.
+ *
+ * Note that @memory_types must be zero if COREDUMP_MEMORY_TYPES isn't
+ * raised. COREDUMP_MEMORY_TYPES requires COREDUMP_KERNEL and an ack of
+ * at least COREDUMP_ACK_SIZE_VER1 bytes.
*/
struct coredump_ack {
__u32 size;
__u32 spare;
__u64 mask;
+ __u64 memory_types;
};
enum {
COREDUMP_ACK_SIZE_VER0 = 16U, /* size of first published struct */
+ COREDUMP_ACK_SIZE_VER1 = 24U, /* memory_types added */
};
/**
@@ -83,11 +155,12 @@ enum {
*
* The kernel will place a single byte on the coredump socket. The
* markers notify userspace whether the coredump ack succeeded or
- * failed.
+ * failed. After any marker other than COREDUMP_MARK_REQACK the kernel
+ * closes the connection and no coredump is generated.
*
* @COREDUMP_MARK_MINSIZE: the provided coredump_ack size was too small
* @COREDUMP_MARK_MAXSIZE: the provided coredump_ack size was too big
- * @COREDUMP_MARK_UNSUPPORTED: the provided coredump_ack mask was invalid
+ * @COREDUMP_MARK_UNSUPPORTED: the provided coredump_ack mask or memory types were invalid
* @COREDUMP_MARK_CONFLICTING: the provided coredump_ack mask has conflicting options
* @COREDUMP_MARK_REQACK: the coredump request and ack was successful
* @__COREDUMP_MARK_MAX: the maximum coredump mark value
@@ -101,4 +174,72 @@ enum coredump_mark {
__COREDUMP_MARK_MAX = (1U << 31),
};
+/**
+ * enum coredump_record_type - Type of a coredump record
+ *
+ * @COREDUMP_RECORD_DATA: the header is followed by ->len bytes of data
+ * @COREDUMP_RECORD_END: the coredump ends here, the header is not followed
+ * by any data and no further record is sent
+ * @COREDUMP_RECORD_ZERO: the header stands for ->len zero bytes and is not
+ * followed by any data
+ * @__COREDUMP_RECORD_TYPE_MAX: the maximum coredump record type value
+ */
+enum coredump_record_type {
+ COREDUMP_RECORD_DATA = 0U,
+ COREDUMP_RECORD_END = 1U,
+ COREDUMP_RECORD_ZERO = 2U,
+ __COREDUMP_RECORD_TYPE_MAX = (1U << 31),
+};
+
+/**
+ * struct coredump_record_header - header of a coredump record
+ * @size: size of struct coredump_record_header
+ * @type: one of enum coredump_record_type
+ * @flags: modifiers for this record
+ * @offset: offset in the coredump this record starts at
+ * @len: number of coredump bytes this record accounts for
+ *
+ * If the coredump server raises COREDUMP_RECORDS in coredump_ack->mask
+ * the kernel doesn't send the coredump as a plain byte stream. It sends
+ * a sequence of records instead. A COREDUMP_RECORD_DATA record is
+ * followed by @len bytes of actual coredump data. A
+ * COREDUMP_RECORD_ZERO record is followed by nothing and stands for
+ * @len zero bytes. A server that didn't raise COREDUMP_SPARSE never
+ * sees a zero record. Records arrive in order and leave no gaps. So
+ * @offset is the sum of the @len of all records before it.
+ *
+ * The last record is a COREDUMP_RECORD_END record. It is followed by
+ * nothing. Its @len is zero. Its @offset is the size of the coredump.
+ * The kernel only sends it once it has written the whole coredump. A
+ * server that hits end-of-file without having seen an end record must
+ * treat the coredump as incomplete.
+ *
+ * The @size member is set to the size of struct coredump_record_header
+ * the kernel knows and lets the header grow later. It comes first so it
+ * can be peeked. Userspace must consume @size bytes and discard
+ * anything beyond what it knows. It must refuse a @size smaller than
+ * COREDUMP_RECORD_HEADER_SIZE_VER0. @size covers the header alone.
+ * @offset and @len count coredump bytes.
+ *
+ * The @flags member carries modifiers that change how the record is to
+ * be interpreted. No flag is defined yet. Userspace must refuse a
+ * record carrying a flag or a type it doesn't know. Every new record
+ * type is raised in coredump_req->mask as a feature of its own. A
+ * server only ever sees the types it asked for.
+ *
+ * COREDUMP_RECORDS must be combined with COREDUMP_KERNEL, and
+ * COREDUMP_SPARSE with COREDUMP_RECORDS.
+ */
+struct coredump_record_header {
+ __u32 size;
+ __u32 type;
+ __u64 flags;
+ __u64 offset;
+ __u64 len;
+};
+
+enum {
+ COREDUMP_RECORD_HEADER_SIZE_VER0 = 32U, /* size of first published struct */
+};
+
#endif /* _UAPI_LINUX_COREDUMP_H */
diff --git a/include/uapi/linux/dccp.h b/include/uapi/linux/dccp.h
index 6e1978dbcf7c..4a97d7fd855e 100644
--- a/include/uapi/linux/dccp.h
+++ b/include/uapi/linux/dccp.h
@@ -8,15 +8,19 @@
/**
* struct dccp_hdr - generic part of DCCP packet header
*
- * @dccph_sport - Relevant port on the endpoint that sent this packet
- * @dccph_dport - Relevant port on the other endpoint
- * @dccph_doff - Data Offset from the start of the DCCP header, in 32-bit words
- * @dccph_ccval - Used by the HC-Sender CCID
- * @dccph_cscov - Parts of the packet that are covered by the Checksum field
- * @dccph_checksum - Internet checksum, depends on dccph_cscov
- * @dccph_x - 0 = 24 bit sequence number, 1 = 48
- * @dccph_type - packet type, see DCCP_PKT_ prefixed macros
- * @dccph_seq - sequence number high or low order 24 bits, depends on dccph_x
+ * @dccph_sport: Relevant port on the endpoint that sent this packet
+ * @dccph_dport: Relevant port on the other endpoint
+ * @dccph_doff: Data Offset from the start of the DCCP header, in 32-bit words
+ * @dccph_ccval: Used by the HC-Sender CCID
+ * @dccph_cscov: Parts of the packet that are covered by the Checksum field
+ * @dccph_checksum: Internet checksum, depends on dccph_cscov
+ * @dccph_x: 0 = 24 bit sequence number, 1 = 48
+ * @dccph_type: packet type, see DCCP_PKT_ prefixed macros
+ * @dccph_reserved: reserved bits
+ * @dccph_seq: sequence number high or low order lower 16 bits,
+ * depends on dccph_x
+ * @dccph_seq2: sequence number high or low order upper 8 bits,
+ * depends on dccph_x
*/
struct dccp_hdr {
__be16 dccph_sport,
@@ -50,7 +54,7 @@ struct dccp_hdr {
/**
* struct dccp_hdr_ext - the low bits of a 48 bit seq packet
*
- * @dccph_seq_low - low 24 bits of a 48 bit seq packet
+ * @dccph_seq_low: low 24 bits of a 48 bit seq packet
*/
struct dccp_hdr_ext {
__be32 dccph_seq_low;
@@ -59,7 +63,7 @@ struct dccp_hdr_ext {
/**
* struct dccp_hdr_request - Connection initiation request header
*
- * @dccph_req_service - Service to which the client app wants to connect
+ * @dccph_req_service: Service to which the client app wants to connect
*/
struct dccp_hdr_request {
__be32 dccph_req_service;
@@ -67,8 +71,9 @@ struct dccp_hdr_request {
/**
* struct dccp_hdr_ack_bits - acknowledgment bits common to most packets
*
- * @dccph_resp_ack_nr_high - 48 bit ack number high order bits, contains GSR
- * @dccph_resp_ack_nr_low - 48 bit ack number low order bits, contains GSR
+ * @dccph_reserved1: reserved bits
+ * @dccph_ack_nr_high: 48 bit ack number high order bits, contains GSR
+ * @dccph_ack_nr_low: 48 bit ack number low order bits, contains GSR
*/
struct dccp_hdr_ack_bits {
__be16 dccph_reserved1;
@@ -78,8 +83,8 @@ struct dccp_hdr_ack_bits {
/**
* struct dccp_hdr_response - Connection initiation response header
*
- * @dccph_resp_ack - 48 bit Acknowledgment Number Subheader (5.3)
- * @dccph_resp_service - Echoes the Service Code on a received DCCP-Request
+ * @dccph_resp_ack: 48 bit Acknowledgment Number Subheader (5.3)
+ * @dccph_resp_service: Echoes the Service Code on a received DCCP-Request
*/
struct dccp_hdr_response {
struct dccp_hdr_ack_bits dccph_resp_ack;
@@ -89,9 +94,9 @@ struct dccp_hdr_response {
/**
* struct dccp_hdr_reset - Unconditionally shut down a connection
*
- * @dccph_reset_ack - 48 bit Acknowledgment Number Subheader (5.6)
- * @dccph_reset_code - one of %dccp_reset_codes
- * @dccph_reset_data - the Data 1 ... Data 3 fields from 5.6
+ * @dccph_reset_ack: 48 bit Acknowledgment Number Subheader (5.6)
+ * @dccph_reset_code: one of %dccp_reset_codes
+ * @dccph_reset_data: the Data 1 ... Data 3 fields from 5.6
*/
struct dccp_hdr_reset {
struct dccp_hdr_ack_bits dccph_reset_ack;
diff --git a/include/uapi/linux/dpll.h b/include/uapi/linux/dpll.h
index 85b898b1db5e..8c71fc3f9863 100644
--- a/include/uapi/linux/dpll.h
+++ b/include/uapi/linux/dpll.h
@@ -29,8 +29,7 @@ enum dpll_mode {
/**
* enum dpll_lock_status - provides information of dpll device lock status,
* valid values for DPLL_A_LOCK_STATUS attribute
- * @DPLL_LOCK_STATUS_UNLOCKED: dpll was not yet locked to any valid input (or
- * forced by setting DPLL_A_MODE to DPLL_MODE_DETACHED)
+ * @DPLL_LOCK_STATUS_UNLOCKED: dpll was not yet locked to any valid input
* @DPLL_LOCK_STATUS_LOCKED: dpll is locked to a valid signal, but no holdover
* available
* @DPLL_LOCK_STATUS_LOCKED_HO_ACQ: dpll is locked and holdover acquired
diff --git a/include/uapi/linux/ethtool.h b/include/uapi/linux/ethtool.h
index 986d70caec33..9e60c17b48c8 100644
--- a/include/uapi/linux/ethtool.h
+++ b/include/uapi/linux/ethtool.h
@@ -685,6 +685,7 @@ enum ethtool_link_ext_substate_module {
* @ETH_SS_STATS_RMON: names of RMON statistics
* @ETH_SS_STATS_PHY: names of PHY(dev) statistics
* @ETH_SS_TS_FLAGS: hardware timestamping flags
+ * @ETH_SS_PHY_INTERFACES: names of MAC to PHY interfaces
*
* @ETH_SS_COUNT: number of defined string sets
*/
@@ -712,6 +713,7 @@ enum ethtool_stringset {
ETH_SS_STATS_RMON,
ETH_SS_STATS_PHY,
ETH_SS_TS_FLAGS,
+ ETH_SS_PHY_INTERFACES,
/* add new constants above here */
ETH_SS_COUNT
diff --git a/include/uapi/linux/ethtool_netlink_generated.h b/include/uapi/linux/ethtool_netlink_generated.h
index 8134baf7860f..660e0c08a766 100644
--- a/include/uapi/linux/ethtool_netlink_generated.h
+++ b/include/uapi/linux/ethtool_netlink_generated.h
@@ -78,6 +78,14 @@ enum ethtool_pse_event {
ETHTOOL_PSE_EVENT_SW_PW_CONTROL_ERROR = 64,
};
+/*
+ * type of physical connector
+ */
+enum ethtool_port_type {
+ ETHTOOL_PORT_TYPE_MDI,
+ ETHTOOL_PORT_TYPE_SFP,
+};
+
enum {
ETHTOOL_A_HEADER_UNSPEC,
ETHTOOL_A_HEADER_DEV_INDEX,
@@ -841,6 +849,18 @@ enum {
};
enum {
+ ETHTOOL_A_PORT_HEADER = 1,
+ ETHTOOL_A_PORT_ID,
+ ETHTOOL_A_PORT_SUPPORTED_MODES,
+ ETHTOOL_A_PORT_SUPPORTED_INTERFACES,
+ ETHTOOL_A_PORT_TYPE,
+ ETHTOOL_A_PORT_UPSTREAM_PORT,
+
+ __ETHTOOL_A_PORT_CNT,
+ ETHTOOL_A_PORT_MAX = (__ETHTOOL_A_PORT_CNT - 1)
+};
+
+enum {
ETHTOOL_MSG_USER_NONE = 0,
ETHTOOL_MSG_STRSET_GET = 1,
ETHTOOL_MSG_LINKINFO_GET,
@@ -893,6 +913,7 @@ enum {
ETHTOOL_MSG_RSS_CREATE_ACT,
ETHTOOL_MSG_RSS_DELETE_ACT,
ETHTOOL_MSG_MSE_GET,
+ ETHTOOL_MSG_PORT_GET,
__ETHTOOL_MSG_USER_CNT,
ETHTOOL_MSG_USER_MAX = (__ETHTOOL_MSG_USER_CNT - 1)
@@ -954,6 +975,7 @@ enum {
ETHTOOL_MSG_RSS_CREATE_NTF,
ETHTOOL_MSG_RSS_DELETE_NTF,
ETHTOOL_MSG_MSE_GET_REPLY,
+ ETHTOOL_MSG_PORT_GET_REPLY,
__ETHTOOL_MSG_KERNEL_CNT,
ETHTOOL_MSG_KERNEL_MAX = (__ETHTOOL_MSG_KERNEL_CNT - 1)
diff --git a/include/uapi/linux/firewire-cdev.h b/include/uapi/linux/firewire-cdev.h
index 05e3aa8fa8bc..4f83d6babc92 100644
--- a/include/uapi/linux/firewire-cdev.h
+++ b/include/uapi/linux/firewire-cdev.h
@@ -293,7 +293,7 @@ struct fw_cdev_event_request3 {
/**
* struct fw_cdev_event_iso_interrupt - Sent when an iso packet was completed
* @closure: See &fw_cdev_event_common;
- * set by %FW_CDEV_CREATE_ISO_CONTEXT ioctl
+ * set by %FW_CDEV_IOC_CREATE_ISO_CONTEXT ioctl
* @type: See &fw_cdev_event_common; always %FW_CDEV_EVENT_ISO_INTERRUPT
* @cycle: Cycle counter of the last completed packet
* @header_length: Total length of following headers, in bytes
@@ -353,7 +353,7 @@ struct fw_cdev_event_iso_interrupt {
/**
* struct fw_cdev_event_iso_interrupt_mc - An iso buffer chunk was completed
* @closure: See &fw_cdev_event_common;
- * set by %FW_CDEV_CREATE_ISO_CONTEXT ioctl
+ * set by %FW_CDEV_IOC_CREATE_ISO_CONTEXT ioctl
* @type: %FW_CDEV_EVENT_ISO_INTERRUPT_MULTICHANNEL
* @completed: Offset into the receive buffer; data before this offset is valid
*
diff --git a/include/uapi/linux/fs.h b/include/uapi/linux/fs.h
index 34c6f219462a..a46c33692aa2 100644
--- a/include/uapi/linux/fs.h
+++ b/include/uapi/linux/fs.h
@@ -88,7 +88,7 @@ struct fstrim_range {
* We include a length field because some filesystems (vfat) have an identifier
* that we do want to expose as a UUID, but doesn't have the standard length.
*
- * We use a fixed size buffer beacuse this interface will, by fiat, never
+ * We use a fixed size buffer because this interface will, by fiat, never
* support "UUIDs" longer than 16 bytes; we don't want to force all downstream
* users to have to deal with that.
*/
diff --git a/include/uapi/linux/gpio.h b/include/uapi/linux/gpio.h
index f7cb8ae87df7..5515b718886e 100644
--- a/include/uapi/linux/gpio.h
+++ b/include/uapi/linux/gpio.h
@@ -218,7 +218,7 @@ struct gpio_v2_line_request {
* gpio_v2_line_flag, such as %GPIO_V2_LINE_FLAG_ACTIVE_LOW,
* %GPIO_V2_LINE_FLAG_OUTPUT etc, added together
* @attrs: the configuration attributes associated with the line
- * @padding: reserved for future use
+ * @padding: reserved for future use, must be zero filled
*/
struct gpio_v2_line_info {
char name[GPIO_MAX_NAME_SIZE];
diff --git a/include/uapi/linux/handshake.h b/include/uapi/linux/handshake.h
index d7e40f594888..f907aa082520 100644
--- a/include/uapi/linux/handshake.h
+++ b/include/uapi/linux/handshake.h
@@ -13,7 +13,10 @@
enum handshake_handler_class {
HANDSHAKE_HANDLER_CLASS_NONE,
HANDSHAKE_HANDLER_CLASS_TLSHD,
- HANDSHAKE_HANDLER_CLASS_MAX,
+
+ /* private: */
+ __HANDSHAKE_HANDLER_CLASS_MAX,
+ HANDSHAKE_HANDLER_CLASS_MAX = (__HANDSHAKE_HANDLER_CLASS_MAX - 1)
};
enum handshake_msg_type {
diff --git a/include/uapi/linux/if_addr.h b/include/uapi/linux/if_addr.h
index 7fb630b7fe31..0a1ad9ebb47b 100644
--- a/include/uapi/linux/if_addr.h
+++ b/include/uapi/linux/if_addr.h
@@ -57,6 +57,7 @@ enum {
#define IFA_F_NOPREFIXROUTE 0x200
#define IFA_F_MCAUTOJOIN 0x400
#define IFA_F_STABLE_PRIVACY 0x800
+#define IFA_F_GLOBAL 0x1000
struct ifa_cacheinfo {
__u32 ifa_prefered;
diff --git a/include/uapi/linux/if_link.h b/include/uapi/linux/if_link.h
index 43cecca49f01..245b36204525 100644
--- a/include/uapi/linux/if_link.h
+++ b/include/uapi/linux/if_link.h
@@ -381,6 +381,7 @@ enum {
IFLA_NETNS_IMMUTABLE,
IFLA_HEADROOM,
IFLA_TAILROOM,
+ IFLA_PACING_OFFLOAD,
__IFLA_MAX
};
diff --git a/include/uapi/linux/iio/types.h b/include/uapi/linux/iio/types.h
index d0fb714ca0fd..d602b40f14d0 100644
--- a/include/uapi/linux/iio/types.h
+++ b/include/uapi/linux/iio/types.h
@@ -55,6 +55,7 @@ enum iio_chan_type {
IIO_ALTCURRENT,
IIO_COVERAGE,
IIO_VOLUMEFLOW,
+ IIO_FREQUENCY,
};
enum iio_modifier {
diff --git a/include/uapi/linux/input-event-codes.h b/include/uapi/linux/input-event-codes.h
index 3528168f7c6d..4217950e5d16 100644
--- a/include/uapi/linux/input-event-codes.h
+++ b/include/uapi/linux/input-event-codes.h
@@ -970,6 +970,12 @@
/*
* LEDs
+ *
+ * Do not add any new LED definitions to the input subsystem. The existing
+ * definitions are legacy and grandfathered for backwards compatibility with
+ * userspace (via evdev). Any new LEDs should be implemented using the
+ * LED subsystem (struct led_classdev). The input core provides a bridge to
+ * the LED subsystem in drivers/input/input-leds.c.
*/
#define LED_NUML 0x00
diff --git a/include/uapi/linux/io_uring.h b/include/uapi/linux/io_uring.h
index 909fb7aea638..b42b66b424a7 100644
--- a/include/uapi/linux/io_uring.h
+++ b/include/uapi/linux/io_uring.h
@@ -121,14 +121,15 @@ struct io_uring_sqe {
/* sqe->attr_type_mask flags */
#define IORING_RW_ATTR_FLAG_PI (1U << 0)
-/* PI attribute information */
+
+/* PI attribute information in sqe->attr_ptr for IORING_RW_ATTR_FLAG_PI: */
struct io_uring_attr_pi {
- __u16 flags;
- __u16 app_tag;
- __u32 len;
- __u64 addr;
- __u64 seed;
- __u64 rsvd;
+ __u16 flags;
+ __u16 app_tag;
+ __u32 len;
+ __u64 addr;
+ __u64 seed;
+ __u64 rsvd;
};
/*
diff --git a/include/uapi/linux/iommufd.h b/include/uapi/linux/iommufd.h
index 206fa667c782..010f47f7d3d2 100644
--- a/include/uapi/linux/iommufd.h
+++ b/include/uapi/linux/iommufd.h
@@ -776,7 +776,7 @@ enum iommufd_hw_info_flags {
* @out_data_type: Output the iommu hardware info type as defined in the enum
* iommu_hw_info_type.
* @out_capabilities: Output the generic iommu capability info type as defined
- * in the enum iommu_hw_capabilities.
+ * in the enum iommufd_hw_capabilities.
* @out_max_pasid_log2: Output the width of PASIDs. 0 means no PASID support.
* PCI devices turn to out_capabilities to check if the
* specific capabilities is supported or not.
@@ -871,6 +871,12 @@ enum iommufd_hwpt_get_dirty_bitmap_flags {
* Walk the IOMMU pagetables for a given IOVA range to return a bitmap
* with the dirty IOVAs. In doing so it will also by default clear any
* dirty bit metadata set in the IOPTE.
+ *
+ * The IOVA range given must fully enclose any IOPTE. If the range starts or
+ * ends inside a dirty IOPTE then the ioctl will fail. This avoids partially
+ * reporting a dirty range.
+ *
+ * On failure the dirty state becomes unknown and the userspace must restart.
*/
struct iommu_hwpt_get_dirty_bitmap {
__u32 size;
@@ -948,7 +954,9 @@ struct iommu_hwpt_vtd_s1_invalidate {
* CMDQ_OP_CFGI_CD
* CMDQ_OP_CFGI_CD_ALL
*
- * -EIO will be returned if the command is not supported.
+ * User space must forward only valid commands: the kernel rejects, with
+ * -EIO, any command carrying an unsupported opcode, an unsupported field,
+ * or a field value that the underlying SMMU hardware does not implement.
*/
struct iommu_viommu_arm_smmuv3_invalidate {
__aligned_le64 cmd[2];
diff --git a/include/uapi/linux/it6625.h b/include/uapi/linux/it6625.h
new file mode 100644
index 000000000000..a895658aaf6a
--- /dev/null
+++ b/include/uapi/linux/it6625.h
@@ -0,0 +1,25 @@
+/* SPDX-License-Identifier: GPL-2.0+ WITH Linux-syscall-note */
+/*
+ * Controls header for IT6625/IT6626 driver
+ */
+
+#ifndef _UAPI_LINUX_IT6625_H
+#define _UAPI_LINUX_IT6625_H
+
+#include <linux/v4l2-controls.h>
+
+/*
+ * Currently detected HDMI audio sampling rate, in Hz. Read-only.
+ * 0 means the rate is unavailable/unknown: no audio is currently
+ * present on the input, the hardware reported a sample-rate id this
+ * driver doesn't recognize, or the status read itself failed. Never a
+ * literal 0 Hz sample rate.
+ */
+#define V4L2_CID_IT6625_AUDIO_SAMPLING_RATE (V4L2_CID_USER_IT6625_BASE + 0)
+
+/*
+ * Whether HDMI audio is currently present on the input. Read-only.
+ */
+#define V4L2_CID_IT6625_AUDIO_PRESENT (V4L2_CID_USER_IT6625_BASE + 1)
+
+#endif /* _UAPI_LINUX_IT6625_H */
diff --git a/include/uapi/linux/keyctl.h b/include/uapi/linux/keyctl.h
index 4c8884eea808..fa85b9760391 100644
--- a/include/uapi/linux/keyctl.h
+++ b/include/uapi/linux/keyctl.h
@@ -24,6 +24,7 @@
#define KEY_SPEC_GROUP_KEYRING -6 /* - key ID for GID-specific keyring */
#define KEY_SPEC_REQKEY_AUTH_KEY -7 /* - key ID for assumed request_key auth key */
#define KEY_SPEC_REQUESTOR_KEYRING -8 /* - key ID for request_key() dest keyring */
+#define KEY_SPEC_BPF_KEYRING -9 /* - key ID for the BPF-specific keyring */
/* request-key default keyrings */
#define KEY_REQKEY_DEFL_NO_CHANGE -1
diff --git a/include/uapi/linux/kvm.h b/include/uapi/linux/kvm.h
index ac2d77d14963..8dff2fc1972e 100644
--- a/include/uapi/linux/kvm.h
+++ b/include/uapi/linux/kvm.h
@@ -999,6 +999,7 @@ struct kvm_enable_cap {
#define KVM_CAP_S390_HPAGE_2G 249
#define KVM_CAP_PPC_COMPAT_CAPS 250
#define KVM_CAP_ARM_PMU_V3_STRICT 251
+#define KVM_CAP_GUEST_MEMFD_MEMORY_ATTRIBUTES 252
struct kvm_irq_routing_irqchip {
__u32 irqchip;
@@ -1653,6 +1654,21 @@ struct kvm_memory_attributes {
__u64 flags;
};
+/* Available with KVM_CAP_GUEST_MEMFD_MEMORY_ATTRIBUTES */
+#define KVM_SET_MEMORY_ATTRIBUTES2 _IOWR(KVMIO, 0xd2, struct kvm_memory_attributes2)
+
+struct kvm_memory_attributes2 {
+ union {
+ __u64 address;
+ __u64 offset;
+ };
+ __u64 size;
+ __u64 attributes;
+ __u64 flags;
+ __u64 error_offset;
+ __u64 reserved[11];
+};
+
#define KVM_MEMORY_ATTRIBUTE_PRIVATE (1ULL << 3)
#define KVM_CREATE_GUEST_MEMFD _IOWR(KVMIO, 0xd4, struct kvm_create_guest_memfd)
diff --git a/include/uapi/linux/landlock.h b/include/uapi/linux/landlock.h
index cceda3b3b961..24510e5d8479 100644
--- a/include/uapi/linux/landlock.h
+++ b/include/uapi/linux/landlock.h
@@ -33,14 +33,14 @@
* (and that they have tested with a kernel that supported them all).
*
* @quiet_access_fs and @quiet_access_net are bitmasks of actions for which a
- * denial by this layer will not trigger a log if the corresponding object (or
- * its children, for filesystem rules) is marked with the "quiet" bit via
- * %LANDLOCK_ADD_RULE_QUIET, even if logging would normally take place per
+ * denial by this layer will not trigger an audit record if the corresponding
+ * object (or its children, for filesystem rules) is marked with the "quiet" bit
+ * via %LANDLOCK_ADD_RULE_QUIET, even if logging would normally take place per
* landlock_restrict_self() flags. @quiet_scoped is similar, except that it
* does not require marking any objects as quiet - if the ruleset is created
* with any bits set in @quiet_scoped, then denial of such scoped resources will
- * not trigger any log. These 3 fields are available since Landlock ABI version
- * 10.
+ * not trigger an audit record. These three fields are available since Landlock
+ * ABI version 10.
*
* @quiet_access_fs, @quiet_access_net and @quiet_scoped must be a subset of
* @handled_access_fs, @handled_access_net and @scoped respectively.
@@ -66,18 +66,24 @@ struct landlock_ruleset_attr {
__u64 scoped;
/**
* @quiet_access_fs: Bitmask of filesystem actions which should not be
- * logged if per-object quiet flag is set.
+ * submitted to audit if the per-object quiet flag is set.
*/
__u64 quiet_access_fs;
/**
* @quiet_access_net: Bitmask of network actions which should not be
- * logged if per-object quiet flag is set.
+ * submitted to audit if the per-object quiet flag is set.
*/
__u64 quiet_access_net;
/**
- * @quiet_scoped: Bitmask of scoped actions which should not be logged.
+ * @quiet_scoped: Bitmask of scoped actions which should not be
+ * submitted to audit.
*/
__u64 quiet_scoped;
+ /**
+ * @handled_permissions: Bitmask of handled permissions (cf. `Permission
+ * flags`_).
+ */
+ __u64 handled_permissions;
};
/**
@@ -228,6 +234,15 @@ enum landlock_rule_type {
* landlock_net_port_attr .
*/
LANDLOCK_RULE_NET_PORT,
+ /**
+ * @LANDLOCK_RULE_NAMESPACE: Type of a &struct landlock_namespace_attr .
+ */
+ LANDLOCK_RULE_NAMESPACE,
+ /**
+ * @LANDLOCK_RULE_CAPABILITY: Type of a &struct
+ * landlock_capability_attr .
+ */
+ LANDLOCK_RULE_CAPABILITY,
};
/**
@@ -282,6 +297,77 @@ struct landlock_net_port_attr {
};
/**
+ * struct landlock_namespace_attr - Namespace type definition
+ *
+ * Argument of sys_landlock_add_rule() with %LANDLOCK_RULE_NAMESPACE.
+ */
+struct landlock_namespace_attr {
+ /**
+ * @permissions: Must be set to %LANDLOCK_PERMISSION_NAMESPACE_USE.
+ */
+ __u64 permissions;
+ /**
+ * @allowed_namespace_types: Bitmask of namespace types (``CLONE_NEW*``
+ * flags) to allow under this rule. Unknown bits are silently ignored
+ * for forward compatibility.
+ */
+ __u64 allowed_namespace_types;
+ /**
+ * @quiet_namespace_types: Bitmask of namespace types (``CLONE_NEW*``
+ * flags) whose denial by this layer should not be submitted to audit,
+ * even when landlock_restrict_self() enables audit logging. Only audit
+ * records attributed to this layer are suppressed; denial tracepoints
+ * still fire (see `Permission flags`_). Bits also set in
+ * @allowed_namespace_types have no effect, since an allowed type is
+ * never denied. Unknown bits are silently ignored.
+ *
+ * At least one of @allowed_namespace_types or @quiet_namespace_types
+ * must be non-zero, otherwise the call returns ``-ENOMSG``. The
+ * non-zero check runs on the raw input before unknown-bit masking, so a
+ * rule that sets only bits unknown to the running kernel succeeds but
+ * has no runtime effect. Programs should omit this rule when they
+ * neither allow nor quiet a namespace type.
+ */
+ __u64 quiet_namespace_types;
+};
+
+/**
+ * struct landlock_capability_attr - Capability definition
+ *
+ * Argument of sys_landlock_add_rule() with %LANDLOCK_RULE_CAPABILITY.
+ */
+struct landlock_capability_attr {
+ /**
+ * @permissions: Must be set to %LANDLOCK_PERMISSION_CAPABILITY_USE.
+ */
+ __u64 permissions;
+ /**
+ * @allowed_capabilities: Bitmask of capabilities (``1ULL << CAP_*``) to
+ * allow under this rule. Bits above ``CAP_LAST_CAP`` are silently
+ * ignored for forward compatibility.
+ */
+ __u64 allowed_capabilities;
+ /**
+ * @quiet_capabilities: Bitmask of capabilities (``1ULL << CAP_*``)
+ * whose denial by this layer should not be submitted to audit, even if
+ * audit logging would normally take place per landlock_restrict_self()
+ * flags. Only audit records attributed to this layer are suppressed;
+ * denial tracepoints still fire (see `Permission flags`_). Bits also
+ * set in @allowed_capabilities have no effect, since an allowed
+ * capability is never denied. Bits above ``CAP_LAST_CAP`` are silently
+ * ignored.
+ *
+ * At least one of @allowed_capabilities or @quiet_capabilities must be
+ * non-zero, otherwise the call returns ``-ENOMSG``. The non-zero check
+ * runs on the raw input before unknown-bit masking, so a rule that sets
+ * only bits unknown to the running kernel (above ``CAP_LAST_CAP``)
+ * succeeds but has no runtime effect. Programs should omit this rule
+ * when they neither allow nor quiet a capability.
+ */
+ __u64 quiet_capabilities;
+};
+
+/**
* DOC: fs_access
*
* A set of actions on kernel objects may be defined by an attribute (e.g.
@@ -507,4 +593,41 @@ struct landlock_net_port_attr {
#define LANDLOCK_SCOPE_SIGNAL (1ULL << 1)
/* clang-format on*/
+/**
+ * DOC: permission
+ *
+ * Permission flags
+ * ~~~~~~~~~~~~~~~~
+ *
+ * These flags restrict the use of members of a category, each member being
+ * identified by a constant from another kernel subsystem (e.g. CLONE_NEW*
+ * namespace types, CAP_* capabilities). A flag covers every kernel path that
+ * uses a member of its category, and members that no rule explicitly allows are
+ * denied. Values unknown to the running kernel are silently accepted for
+ * forward compatibility and stay denied by default. See
+ * Documentation/security/landlock.rst for design details.
+ *
+ * When a ruleset handles multiple permissions whose operations overlap (e.g. a
+ * non-user namespace needs both its namespace type and CAP_SYS_ADMIN), the
+ * operation is allowed only if each handled permission independently allows it.
+ * See Documentation/userspace-api/landlock.rst.
+ *
+ * - %LANDLOCK_PERMISSION_NAMESPACE_USE: Restrict the use of specific namespace
+ * types: creation (:manpage:`unshare(2)`, :manpage:`clone(2)`,
+ * :manpage:`clone3(2)`), joining (:manpage:`setns(2)`), and acquiring an fd
+ * reference (:manpage:`open_tree(2)`, :manpage:`fsmount(2)`). A process in a
+ * Landlock domain that handles this permission is denied from using namespace
+ * types that are not explicitly allowed by a %LANDLOCK_RULE_NAMESPACE rule.
+ * Support added in Landlock ABI version 12.
+ * - %LANDLOCK_PERMISSION_CAPABILITY_USE: Restrict the use of specific Linux
+ * capabilities. A process in a Landlock domain that handles this permission
+ * is denied from exercising capabilities that are not explicitly allowed by a
+ * %LANDLOCK_RULE_CAPABILITY rule. This hook is purely restrictive: it can
+ * deny capabilities that the kernel would otherwise grant, but it can never
+ * grant capabilities that the kernel already denied. Support added in
+ * Landlock ABI version 12.
+ */
+#define LANDLOCK_PERMISSION_NAMESPACE_USE (1ULL << 0)
+#define LANDLOCK_PERMISSION_CAPABILITY_USE (1ULL << 1)
+
#endif /* _UAPI_LINUX_LANDLOCK_H */
diff --git a/include/uapi/linux/media.h b/include/uapi/linux/media.h
index 1c80b1d6bbaf..2da6ae4da003 100644
--- a/include/uapi/linux/media.h
+++ b/include/uapi/linux/media.h
@@ -208,6 +208,13 @@ struct media_entity_desc {
#define MEDIA_PAD_FL_SINK (1U << 0)
#define MEDIA_PAD_FL_SOURCE (1U << 1)
#define MEDIA_PAD_FL_MUST_CONNECT (1U << 2)
+#if defined(__KERNEL__)
+/*
+ * Forgo INTERNAL pads until proper documentation and v4l2-compliance testing
+ * are merged.
+ */
+#define MEDIA_PAD_FL_INTERNAL (1U << 3)
+#endif /* __KERNEL__ */
struct media_pad_desc {
__u32 entity; /* entity ID */
diff --git a/include/uapi/linux/media/arm/mali-c55-config.h b/include/uapi/linux/media/arm/mali-c55-config.h
index ef0fe17df96e..3ba416d81cd7 100644
--- a/include/uapi/linux/media/arm/mali-c55-config.h
+++ b/include/uapi/linux/media/arm/mali-c55-config.h
@@ -794,12 +794,14 @@ struct mali_c55_params_mesh_shading_selection {
* Q4.8 format
* @gains: Gains for red, green and blue channels in unsigned Q4.8 format
* @offs: Offsets for red, green and blue channels
+ * @__pad: Reserved bytes
*/
struct mali_c55_params_ccm {
struct v4l2_isp_params_block_header header;
__u16 coeffs[3][3];
__u16 gains[3];
__u16 offs[3];
+ __u16 __pad;
};
/**
diff --git a/include/uapi/linux/media/st/dcmipp_config.h b/include/uapi/linux/media/st/dcmipp_config.h
new file mode 100644
index 000000000000..ad8d146820ea
--- /dev/null
+++ b/include/uapi/linux/media/st/dcmipp_config.h
@@ -0,0 +1,16 @@
+/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
+/*
+ * ST DCMIPP Driver - Userspace API
+ *
+ * Copyright (C) STMicroelectronics SA 2026
+ */
+
+#ifndef __UAPI_DCMIPP_CONFIG_H
+#define __UAPI_DCMIPP_CONFIG_H
+
+#include <linux/types.h>
+#include <linux/v4l2-controls.h>
+
+#define V4L2_CID_DCMIPP_PIXELPROC_GAMMA_CORRECTION_ENABLE (V4L2_CID_USER_DCMIPP_BASE + 0x0)
+
+#endif /* __UAPI_DCMIPP_CONFIG_H */
diff --git a/include/uapi/linux/mii.h b/include/uapi/linux/mii.h
index 61d6edad4b94..d662c10ee282 100644
--- a/include/uapi/linux/mii.h
+++ b/include/uapi/linux/mii.h
@@ -81,7 +81,7 @@
#define ADVERTISE_1000XPSE_ASYM 0x0100 /* Try for 1000BASE-X asym pause */
#define ADVERTISE_100BASE4 0x0200 /* Try for 100mbps 4k packets */
#define ADVERTISE_PAUSE_CAP 0x0400 /* Try for pause */
-#define ADVERTISE_PAUSE_ASYM 0x0800 /* Try for asymetric pause */
+#define ADVERTISE_PAUSE_ASYM 0x0800 /* Try for asymmetric pause */
#define ADVERTISE_XNP 0x1000 /* Extended Next Page */
#define ADVERTISE_RESV ADVERTISE_XNP /* Used to be reserved */
#define ADVERTISE_RFAULT 0x2000 /* Say we can detect faults */
diff --git a/include/uapi/linux/mount.h b/include/uapi/linux/mount.h
index 2204708dbf7a..ac865edac517 100644
--- a/include/uapi/linux/mount.h
+++ b/include/uapi/linux/mount.h
@@ -63,6 +63,7 @@
*/
#define OPEN_TREE_CLONE (1 << 0) /* Clone the target tree and attach the clone */
#define OPEN_TREE_NAMESPACE (1 << 1) /* Clone the target tree into a new mount namespace */
+#define OPEN_TREE_DROP_MNTNS_MOUNTS (1 << 2) /* Drop mntns mounts from the clone */
#define OPEN_TREE_CLOEXEC O_CLOEXEC /* Close the file on execve() */
/*
diff --git a/include/uapi/linux/netdev.h b/include/uapi/linux/netdev.h
index 35ff083221c7..9026e0414fbe 100644
--- a/include/uapi/linux/netdev.h
+++ b/include/uapi/linux/netdev.h
@@ -58,7 +58,7 @@ enum netdev_xdp_rx_metadata {
* enum netdev_xsk_flags
* @NETDEV_XSK_FLAGS_TX_TIMESTAMP: HW timestamping egress packets is supported
* by the driver.
- * @NETDEV_XSK_FLAGS_TX_CHECKSUM: L3 checksum HW offload is supported by the
+ * @NETDEV_XSK_FLAGS_TX_CHECKSUM: L4 checksum HW offload is supported by the
* driver.
* @NETDEV_XSK_FLAGS_TX_LAUNCH_TIME_FIFO: Launch time HW offload is supported
* by the driver.
diff --git a/include/uapi/linux/netfilter/nfnetlink_conntrack.h b/include/uapi/linux/netfilter/nfnetlink_conntrack.h
index 43233af75b9d..985f9c08d3e9 100644
--- a/include/uapi/linux/netfilter/nfnetlink_conntrack.h
+++ b/include/uapi/linux/netfilter/nfnetlink_conntrack.h
@@ -285,6 +285,7 @@ enum ctattr_filter {
CTA_FILTER_UNSPEC,
CTA_FILTER_ORIG_FLAGS,
CTA_FILTER_REPLY_FLAGS,
+ CTA_FILTER_ZONE,
__CTA_FILTER_MAX
};
#define CTA_FILTER_MAX (__CTA_FILTER_MAX - 1)
diff --git a/include/uapi/linux/netlink.h b/include/uapi/linux/netlink.h
index f87aaf28a649..82c41aeb4357 100644
--- a/include/uapi/linux/netlink.h
+++ b/include/uapi/linux/netlink.h
@@ -330,6 +330,17 @@ enum netlink_attribute_type {
};
/**
+ * enum netlink_policy_byte_order - byte order of an integer attribute
+ * @NL_POLICY_BYTE_ORDER_BIG_ENDIAN: big endian (network byte order)
+ *
+ * Zero is left unassigned so that it keeps meaning host byte order,
+ * which is also what a missing byte order means.
+ */
+enum netlink_policy_byte_order {
+ NL_POLICY_BYTE_ORDER_BIG_ENDIAN = 1,
+};
+
+/**
* enum netlink_policy_type_attr - policy type attributes
* @NL_POLICY_TYPE_ATTR_UNSPEC: unused
* @NL_POLICY_TYPE_ATTR_TYPE: type of the attribute,
@@ -356,6 +367,8 @@ enum netlink_attribute_type {
* bitfield32 type (U32)
* @NL_POLICY_TYPE_ATTR_MASK: mask of valid bits for unsigned integers (U64)
* @NL_POLICY_TYPE_ATTR_PAD: pad attribute for 64-bit alignment
+ * @NL_POLICY_TYPE_ATTR_BYTE_ORDER: byte order of an integer attribute,
+ * &enum netlink_policy_byte_order, absent if host byte order (U32)
*
* @__NL_POLICY_TYPE_ATTR_MAX: number of attributes
* @NL_POLICY_TYPE_ATTR_MAX: highest attribute number
@@ -374,6 +387,7 @@ enum netlink_policy_type_attr {
NL_POLICY_TYPE_ATTR_BITFIELD32_MASK,
NL_POLICY_TYPE_ATTR_PAD,
NL_POLICY_TYPE_ATTR_MASK,
+ NL_POLICY_TYPE_ATTR_BYTE_ORDER,
/* keep last */
__NL_POLICY_TYPE_ATTR_MAX,
diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h
index 020387d76412..b56a96f57bec 100644
--- a/include/uapi/linux/nl80211.h
+++ b/include/uapi/linux/nl80211.h
@@ -937,8 +937,8 @@
* OLBC handling in hostapd. Beacons are reported in %NL80211_CMD_FRAME
* messages. Note that per PHY only one application may register.
*
- * @NL80211_CMD_SET_NOACK_MAP: sets a bitmap for the individual TIDs whether
- * No Acknowledgement Policy should be applied.
+ * @NL80211_CMD_SET_NOACK_MAP: sets a bitmap (%NL80211_ATTR_TID_BITMAP)
+ * indicating for which TIDs No Acknowledgment Policy should be applied.
*
* @NL80211_CMD_CH_SWITCH_NOTIFY: An AP or GO may decide to switch channels
* independently of the userspace SME, send this event indicating
@@ -1383,6 +1383,13 @@
* from the device to perform an announced schedule update. See
* %NL80211_ATTR_NAN_SCHED_DEFERRED for more details.
* If not set, the schedule should be applied immediately.
+ * Setting a new schedule is always allowed and is never treated as an
+ * evacuation, even if it removes channels that were previously marked as
+ * non-evacuable with %NL80211_CMD_NAN_SET_NON_EVAC_CHANNELS. The
+ * non-evacuable marking is a per-channel property of the schedule:
+ * channels that remain in the new schedule keep their marking, channels
+ * that are removed simply lose it, and newly added channels are
+ * evacuable by default.
* @NL80211_CMD_NAN_SCHED_UPDATE_DONE: Event sent to user space to notify that
* a deferred local NAN schedule update (requested with
* %NL80211_CMD_NAN_SET_LOCAL_SCHED and %NL80211_ATTR_NAN_SCHED_DEFERRED)
@@ -1399,10 +1406,12 @@
* be provided.
* Each peer channel must be compatible with at least one local channel
* set by %NL80211_CMD_SET_LOCAL_NAN_SCHED. Different maps must not
- * contain compatible channels.
- * For single-radio devices (n_radio <= 1), different maps must not
- * schedule the same time slot, as the device cannot operate on multiple
- * channels simultaneously.
+ * contain compatible channels. Two maps may schedule the same time slot.
+ * The device decides at runtime which of the channels to follow.
+ * For example, the local schedule may place slot S on channel c1 while
+ * the peer advertises slot S on both c1 and c2. If the device is anyway
+ * on c2 during slot S (e.g. via the ULW mechanism for non-NAN activity),
+ * it may use slot S on c2 to communicate with the peer.
* When updating an existing peer schedule, the full new schedule must be
* provided - partial updates are not supported. The new schedule will
* completely replace the previous one.
@@ -1427,6 +1436,38 @@
* @NL80211_CMD_STOP_PD: Stop the PD operation, identified by
* its %NL80211_ATTR_WDEV interface.
*
+ * @NL80211_CMD_NAN_SET_NON_EVAC_CHANNELS: Set the list of NAN local schedule
+ * channels that must not be evacuated. NAN must be operational
+ * (%NL80211_CMD_START_NAN was executed) and a local schedule must have
+ * been set (%NL80211_CMD_NAN_SET_LOCAL_SCHED). The command carries zero
+ * or more nested %NL80211_ATTR_NAN_CHANNEL attributes, each identifying a
+ * channel (by its channel definition) of the current local schedule that
+ * must not be evacuated for concurrent operations. The provided list
+ * replaces the previous set of non-evacuable channels; channels of the
+ * current schedule that are not included become evacuable again. All
+ * provided channels must exist in the current local schedule, otherwise
+ * the command fails. This is used to protect channels carrying NDC or
+ * immutable schedules, whose evacuation would break existing NDP
+ * connections.
+ * The non-evacuable marking is a per-channel property of the current
+ * local schedule and only affects evacuation for concurrent operations;
+ * it does not prevent the schedule itself from being changed. Removing a
+ * channel from the schedule with %NL80211_CMD_NAN_SET_LOCAL_SCHED is a
+ * user-initiated change, not an evacuation, and is allowed even for a
+ * non-evacuable channel. Across a schedule update, channels that remain
+ * keep their non-evacuable marking, removed channels lose it, and newly
+ * added channels are evacuable by default; issue this command again to
+ * change the non-evacuable set.
+ * @NL80211_CMD_UPDATE_BEACON: Update the beacon and other templates of an AP
+ * interface, but only that. Same attributes as %NL80211_CMD_SET_BEACON,
+ * %NL80211_ATTR_BEACON_HEAD and %NL80211_ATTR_BEACON_TAIL are required,
+ * configuration changes such as %NL80211_ATTR_FTM_RESPONDER rejected.
+ * This doesn't acquire the wiphy mutex internally, so it's faster, but
+ * cannot update any other configuration.
+ * For MLO a single link is set with %NL80211_ATTR_MLO_LINK_ID as usual
+ * and multiple can be nested in %NL80211_ATTR_MLO_LINKS but then the
+ * update isn't atomic if any failures happen.
+ * Only supported with %NL80211_EXT_FEATURE_UPDATE_BEACON.
* @NL80211_CMD_MAX: highest used command number
* @__NL80211_CMD_AFTER_LAST: internal use
*/
@@ -1705,6 +1746,10 @@ enum nl80211_commands {
NL80211_CMD_START_PD,
NL80211_CMD_STOP_PD,
+ NL80211_CMD_NAN_SET_NON_EVAC_CHANNELS,
+
+ NL80211_CMD_UPDATE_BEACON,
+
/* add new commands above here */
/* used to define NL80211_CMD_MAX below */
@@ -2288,8 +2333,8 @@ enum nl80211_commands {
* abides to when initiating radiation on DFS channels. A country maps
* to one DFS region.
*
- * @NL80211_ATTR_NOACK_MAP: This u16 bitmap contains the No Ack Policy of
- * up to 16 TIDs.
+ * @NL80211_ATTR_TID_BITMAP: A TID bitmap (u16) whose meaning depends
+ * on the command.
*
* @NL80211_ATTR_INACTIVITY_TIMEOUT: timeout value in seconds, this can be
* used by the drivers which has MLME in firmware and does not have support
@@ -3185,6 +3230,19 @@ enum nl80211_commands {
* The aggregated message always precedes the per-link messages for the
* same station within a dump sequence.
*
+ * @NL80211_ATTR_FRAME_NO_STA: Valid for @NL80211_CMD_FRAME to denote that
+ * the kernel had no station for a received frame or should not use a
+ * known station to transmit a frame. This is relevant to know whether
+ * MLD address translation happened or to disable it when sending a frame.
+ *
+ * @NL80211_ATTR_ASSOC_CIP: Enable Control Integrity Protocol for the
+ * association
+ * @NL80211_ATTR_CIP_CAPABILITIES: The Control Integrity Protocol for the
+ * station.
+ *
+ * @NL80211_ATTR_ASSOC_PROTECTED_TWT: Enable protected TWT for the association,
+ * requires protected TWT support (flag attribute)
+ *
* @NUM_NL80211_ATTR: total number of nl80211_attrs available
* @NL80211_ATTR_MAX: highest attribute number currently defined
* @__NL80211_ATTR_AFTER_LAST: internal use
@@ -3429,7 +3487,7 @@ enum nl80211_attrs {
NL80211_ATTR_DISABLE_HT,
NL80211_ATTR_HT_CAPABILITY_MASK,
- NL80211_ATTR_NOACK_MAP,
+ NL80211_ATTR_TID_BITMAP,
NL80211_ATTR_INACTIVITY_TIMEOUT,
@@ -3785,6 +3843,13 @@ enum nl80211_attrs {
NL80211_ATTR_STA_DUMP_LINK_STATS,
+ NL80211_ATTR_FRAME_NO_STA,
+
+ NL80211_ATTR_ASSOC_CIP,
+ NL80211_ATTR_CIP_CAPABILITIES,
+
+ NL80211_ATTR_ASSOC_PROTECTED_TWT,
+
/* add attributes here, update the policy in nl80211.c */
__NL80211_ATTR_AFTER_LAST,
@@ -3800,6 +3865,7 @@ enum nl80211_attrs {
#define NL80211_ATTR_CSA_C_OFF_BEACON NL80211_ATTR_CNTDWN_OFFS_BEACON
#define NL80211_ATTR_CSA_C_OFF_PRESP NL80211_ATTR_CNTDWN_OFFS_PRESP
#define NL80211_ATTR_ASSOC_MLD_EXT_CAPA_OPS NL80211_ATTR_EXT_MLD_CAPA_AND_OPS
+#define NL80211_ATTR_NOACK_MAP NL80211_ATTR_TID_BITMAP
/*
* Allow user space programs to use #ifdef on new attributes by defining them
@@ -3934,6 +4000,7 @@ enum nl80211_iftype {
* that support %NL80211_FEATURE_FULL_AP_CLIENT_STATE to transition a
* previously added station into associated state
* @NL80211_STA_FLAG_SPP_AMSDU: station supports SPP A-MSDUs
+ * @NL80211_STA_FLAG_CIP: station has Control Integrity Protocol (CIP) enabled
* @NL80211_STA_FLAG_MAX: highest station flag number currently defined
* @__NL80211_STA_FLAG_AFTER_LAST: internal use
*/
@@ -3947,6 +4014,7 @@ enum nl80211_sta_flags {
NL80211_STA_FLAG_TDLS_PEER,
NL80211_STA_FLAG_ASSOCIATED,
NL80211_STA_FLAG_SPP_AMSDU,
+ NL80211_STA_FLAG_CIP,
/* keep last */
__NL80211_STA_FLAG_AFTER_LAST,
@@ -5778,12 +5846,16 @@ enum nl80211_auth_type {
* @NL80211_KEYTYPE_GROUP: Group (broadcast/multicast) key
* @NL80211_KEYTYPE_PAIRWISE: Pairwise (unicast/individual) key
* @NL80211_KEYTYPE_PEERKEY: PeerKey (DLS)
+ * @NL80211_KEYTYPE_CIGTK: Control Integrity Group Temporal Key
+ * The cipher is GMAC-256 but passed as GCMP-256,
+ * same as the pairwise key when used for CIP.
* @NUM_NL80211_KEYTYPES: number of defined key types
*/
enum nl80211_key_type {
NL80211_KEYTYPE_GROUP,
NL80211_KEYTYPE_PAIRWISE,
NL80211_KEYTYPE_PEERKEY,
+ NL80211_KEYTYPE_CIGTK,
NUM_NL80211_KEYTYPES
};
@@ -5900,6 +5972,9 @@ enum nl80211_key_attributes {
* see &struct nl80211_txrate_eht
* @NL80211_TXRATE_EHT_GI: configure EHT GI, (u8, see &enum nl80211_eht_gi)
* @NL80211_TXRATE_EHT_LTF: configure EHT LTF, (u8, see &enum nl80211_eht_ltf)
+ * @NL80211_TXRATE_6GHZ_NON_HT_DUP: configure 6 GHz non-HT duplicate Beacon
+ * transmission. This flag is applicable only in Beacon TX rate setting
+ * and must be accompanied by a non-HT (legacy) Beacon rate.
* @__NL80211_TXRATE_AFTER_LAST: internal
* @NL80211_TXRATE_MAX: highest TX rate attribute
*/
@@ -5915,6 +5990,7 @@ enum nl80211_tx_rate_attributes {
NL80211_TXRATE_EHT,
NL80211_TXRATE_EHT_GI,
NL80211_TXRATE_EHT_LTF,
+ NL80211_TXRATE_6GHZ_NON_HT_DUP,
/* keep last */
__NL80211_TXRATE_AFTER_LAST,
@@ -7110,6 +7186,13 @@ enum nl80211_feature_flags {
* @NL80211_EXT_FEATURE_PROBE_AP: Driver supports probing the associated AP
* in STA mode using @NL80211_CMD_PROBE_PEER.
*
+ * @NL80211_EXT_FEATURE_FAST_ROAM_OFFLOAD: Driver supports fast roaming
+ * offload in station mode, including Fast Transition or Opportunistic
+ * Key Caching.
+ *
+ * @NL80211_EXT_FEATURE_UPDATE_BEACON: Driver supports
+ * %NL80211_CMD_UPDATE_BEACON.
+ *
* @NUM_NL80211_EXT_FEATURES: number of extended features.
* @MAX_NL80211_EXT_FEATURES: highest extended feature index.
*/
@@ -7192,6 +7275,8 @@ enum nl80211_ext_feature_index {
NL80211_EXT_FEATURE_ROC_ADDR_FILTER,
NL80211_EXT_FEATURE_SET_KEY_LTF_SEED,
NL80211_EXT_FEATURE_PROBE_AP,
+ NL80211_EXT_FEATURE_FAST_ROAM_OFFLOAD,
+ NL80211_EXT_FEATURE_UPDATE_BEACON,
/* add new features before the definition below */
NUM_NL80211_EXT_FEATURES,
@@ -7826,6 +7911,11 @@ enum nl80211_nan_band_conf_attributes {
* the upcoming discovery window with
* %NL80211_CMD_NAN_NEXT_DW_NOTIFICATION.
* This is a flag attribute.
+ * @NL80211_NAN_CONF_INSTANT_COMM: If set, the NAN synchronization logic will
+ * start Instant Communication (IC) as defined in Chapter 13 of the
+ * Wi-Fi Aware Specification v4.0.
+ * %NL80211_NAN_CONF_DISCOVERY_BEACON_INTERVAL must be set as well.
+ * This is a flag attribute.
* @NUM_NL80211_NAN_CONF_ATTR: Internal.
* @NL80211_NAN_CONF_ATTR_MAX: Highest NAN configuration attribute.
*
@@ -7841,6 +7931,7 @@ enum nl80211_nan_conf_attributes {
NL80211_NAN_CONF_SCAN_DWELL_TIME,
NL80211_NAN_CONF_DISCOVERY_BEACON_INTERVAL,
NL80211_NAN_CONF_NOTIFY_DW,
+ NL80211_NAN_CONF_INSTANT_COMM,
/* keep last */
NUM_NL80211_NAN_CONF_ATTR,
@@ -9057,6 +9148,11 @@ enum nl80211_s1g_short_beacon_attrs {
* specification Table 79 (Capabilities field).
* @NL80211_NAN_CAPA_PHY: nested attribute containing band-agnostic
* capabilities for NAN data path. See &enum nl80211_nan_phy_cap_attr.
+ * @NL80211_NAN_CAPA_INSTANT_COMM: Flag attribute indicating that the device
+ * can switch to Instant Communication (IC) mode, as defined in Chapter 13
+ * of the Wi-Fi Aware Specification v4.0. Can only be set if
+ * %NL80211_NAN_CAPA_CONFIGURABLE_SYNC is set. When IC is enabled, the IC
+ * schedule is expected to be configured by user space.
* @__NL80211_NAN_CAPABILITIES_LAST: Internal
* @NL80211_NAN_CAPABILITIES_MAX: Highest NAN capability attribute.
*/
@@ -9070,6 +9166,7 @@ enum nl80211_nan_capabilities {
NL80211_NAN_CAPA_MAX_CHANNEL_SWITCH_TIME,
NL80211_NAN_CAPA_CAPABILITIES,
NL80211_NAN_CAPA_PHY,
+ NL80211_NAN_CAPA_INSTANT_COMM,
/* keep last */
__NL80211_NAN_CAPABILITIES_LAST,
NL80211_NAN_CAPABILITIES_MAX = __NL80211_NAN_CAPABILITIES_LAST - 1,
diff --git a/include/uapi/linux/nsfs.h b/include/uapi/linux/nsfs.h
index 007fed5971b4..e5909266ec3f 100644
--- a/include/uapi/linux/nsfs.h
+++ b/include/uapi/linux/nsfs.h
@@ -55,6 +55,7 @@ enum init_ns_ino {
MNT_NS_INIT_INO = 0xEFFFFFF8U,
#ifdef __KERNEL__
MNT_NS_ANON_INO = 0xEFFFFFF7U,
+ MNT_NS_INO_SPECIAL_MAX = MNT_NS_ANON_INO,
#endif
};
diff --git a/include/uapi/linux/perf_event.h b/include/uapi/linux/perf_event.h
index fd10aa8d697f..c49fc76292f7 100644
--- a/include/uapi/linux/perf_event.h
+++ b/include/uapi/linux/perf_event.h
@@ -314,8 +314,9 @@ enum {
*/
enum perf_sample_regs_abi {
PERF_SAMPLE_REGS_ABI_NONE = 0,
- PERF_SAMPLE_REGS_ABI_32 = 1,
- PERF_SAMPLE_REGS_ABI_64 = 2,
+ PERF_SAMPLE_REGS_ABI_32 = (1 << 0),
+ PERF_SAMPLE_REGS_ABI_64 = (1 << 1),
+ PERF_SAMPLE_REGS_ABI_SIMD = (1 << 2),
};
/*
@@ -383,6 +384,7 @@ enum perf_event_read_format {
#define PERF_ATTR_SIZE_VER7 128 /* Add: sig_data */
#define PERF_ATTR_SIZE_VER8 136 /* Add: config3 */
#define PERF_ATTR_SIZE_VER9 144 /* add: config4 */
+#define PERF_ATTR_SIZE_VER10 176 /* Add: sample_simd_{vec|pred}_reg_* */
/*
* 'struct perf_event_attr' contains various attributes that define
@@ -547,6 +549,29 @@ struct perf_event_attr {
__u64 config3; /* extension of config2 */
__u64 config4; /* extension of config3 */
+
+ /*
+ * Defines the sampling SIMD/PRED(predicate) registers bitmap and
+ * qwords (8 bytes) length.
+ *
+ * sample_simd_regs_enabled != 0 indicates there are SIMD/PRED
+ * registers to be sampled, the SIMD/PRED registers bitmap and
+ * qwords length are represented in
+ * sample_simd_{vec|pred}_reg_{intr|user} and
+ * sample_simd_{vec|pred}_reg_qwords fields separately.
+ *
+ * sample_simd_regs_enabled == 0 indicates no SIMD/PRED registers
+ * are sampled.
+ */
+ __u16 sample_simd_regs_enabled;
+ __u16 sample_simd_pred_reg_qwords;
+ __u16 sample_simd_vec_reg_qwords;
+ __u16 __reserved_4;
+
+ __u32 sample_simd_pred_reg_intr;
+ __u32 sample_simd_pred_reg_user;
+ __u64 sample_simd_vec_reg_intr;
+ __u64 sample_simd_vec_reg_user;
};
/*
@@ -1020,7 +1045,15 @@ enum perf_event_type {
* } && PERF_SAMPLE_BRANCH_STACK
*
* { u64 abi; # enum perf_sample_regs_abi
- * u64 regs[weight(mask)]; } && PERF_SAMPLE_REGS_USER
+ * u64 regs[weight(mask)];
+ * struct {
+ * u64 nr_vectors; # 0 ... weight(sample_simd_vec_reg_user)
+ * u64 vector_qwords; # 0 ... sample_simd_vec_reg_qwords
+ * u64 nr_pred; # 0 ... weight(sample_simd_pred_reg_user)
+ * u64 pred_qwords; # 0 ... sample_simd_pred_reg_qwords
+ * u64 data[nr_vectors * vector_qwords + nr_pred * pred_qwords];
+ * } && (abi & PERF_SAMPLE_REGS_ABI_SIMD)
+ * } && PERF_SAMPLE_REGS_USER
*
* { u64 size;
* char data[size];
@@ -1047,7 +1080,15 @@ enum perf_event_type {
* { u64 data_src; } && PERF_SAMPLE_DATA_SRC
* { u64 transaction; } && PERF_SAMPLE_TRANSACTION
* { u64 abi; # enum perf_sample_regs_abi
- * u64 regs[weight(mask)]; } && PERF_SAMPLE_REGS_INTR
+ * u64 regs[weight(mask)];
+ * struct {
+ * u64 nr_vectors; # 0 ... weight(sample_simd_vec_reg_intr)
+ * u64 vector_qwords; # 0 ... sample_simd_vec_reg_qwords
+ * u64 nr_pred; # 0 ... weight(sample_simd_pred_reg_intr)
+ * u64 pred_qwords; # 0 ... sample_simd_pred_reg_qwords
+ * u64 data[nr_vectors * vector_qwords + nr_pred * pred_qwords];
+ * } && (abi & PERF_SAMPLE_REGS_ABI_SIMD)
+ * } && PERF_SAMPLE_REGS_INTR
* { u64 phys_addr;} && PERF_SAMPLE_PHYS_ADDR
* { u64 cgroup;} && PERF_SAMPLE_CGROUP
* { u64 data_page_size;} && PERF_SAMPLE_DATA_PAGE_SIZE
diff --git a/include/uapi/linux/psp-sev.h b/include/uapi/linux/psp-sev.h
index 52dae70b058b..536626abe6db 100644
--- a/include/uapi/linux/psp-sev.h
+++ b/include/uapi/linux/psp-sev.h
@@ -15,7 +15,7 @@
#include <linux/types.h>
-/**
+/*
* SEV platform commands
*/
enum {
@@ -36,7 +36,7 @@ enum {
SEV_MAX,
};
-/**
+/*
* SEV Firmware status code
*/
typedef enum {
@@ -109,8 +109,8 @@ typedef enum {
/**
* struct sev_user_data_status - PLATFORM_STATUS command parameters
*
- * @major: major API version
- * @minor: minor API version
+ * @api_major: major API version
+ * @api_minor: minor API version
* @state: platform state
* @flags: platform config flags
* @build: firmware build id for API version
@@ -139,12 +139,12 @@ struct sev_user_data_pek_csr {
} __packed;
/**
- * struct sev_user_data_cert_import - PEK_CERT_IMPORT command parameters
+ * struct sev_user_data_pek_cert_import - PEK_CERT_IMPORT command parameters
*
- * @pek_address: PEK certificate chain
- * @pek_len: length of PEK certificate
- * @oca_address: OCA certificate chain
- * @oca_len: length of OCA certificate
+ * @pek_cert_address: PEK certificate chain
+ * @pek_cert_len: length of PEK certificate
+ * @oca_cert_address: OCA certificate chain
+ * @oca_cert_len: length of OCA certificate
*/
struct sev_user_data_pek_cert_import {
__u64 pek_cert_address; /* In */
@@ -156,8 +156,8 @@ struct sev_user_data_pek_cert_import {
/**
* struct sev_user_data_pdh_cert_export - PDH_CERT_EXPORT command parameters
*
- * @pdh_address: PDH certificate address
- * @pdh_len: length of PDH certificate
+ * @pdh_cert_address: PDH certificate address
+ * @pdh_cert_len: length of PDH certificate
* @cert_chain_address: PDH certificate chain
* @cert_chain_len: length of PDH certificate chain
*/
@@ -248,7 +248,7 @@ struct sev_user_data_snp_config {
} __packed;
/**
- * struct sev_data_snp_vlek_load - SNP_VLEK_LOAD structure
+ * struct sev_user_data_snp_vlek_load - SNP_VLEK_LOAD structure
*
* @len: length of the command buffer read by the PSP
* @vlek_wrapped_version: version of wrapped VLEK hashstick (Must be 0h)
@@ -264,7 +264,7 @@ struct sev_user_data_snp_vlek_load {
} __packed;
/**
- * struct sev_user_data_snp_vlek_wrapped_vlek_hashstick - Wrapped VLEK data
+ * struct sev_user_data_snp_wrapped_vlek_hashstick - Wrapped VLEK data
*
* @data: Opaque data provided by AMD KDS (as described in SEV-SNP Firmware ABI
* 1.54, SNP_VLEK_LOAD)
diff --git a/include/uapi/linux/random.h b/include/uapi/linux/random.h
index 1dd047ec98a1..ef6614d9c704 100644
--- a/include/uapi/linux/random.h
+++ b/include/uapi/linux/random.h
@@ -58,7 +58,7 @@ struct rand_pool_info {
/**
* struct vgetrandom_opaque_params - arguments for allocating memory for vgetrandom
*
- * @size_per_opaque_state: Size of each state that is to be passed to vgetrandom().
+ * @size_of_opaque_state: Size of each state passed to vgetrandom().
* @mmap_prot: Value of the prot argument in mmap(2).
* @mmap_flags: Value of the flags argument in mmap(2).
* @reserved: Reserved for future use.
diff --git a/include/uapi/linux/sched.h b/include/uapi/linux/sched.h
index 33a4624285cd..19ffeba89428 100644
--- a/include/uapi/linux/sched.h
+++ b/include/uapi/linux/sched.h
@@ -53,7 +53,7 @@
*/
#define UNSHARE_EMPTY_MNTNS 0x00100000 /* Unshare an empty mount namespace. */
-#ifndef __ASSEMBLY__
+#ifndef __ASSEMBLER__
/**
* struct clone_args - arguments for the clone3 syscall
* @flags: Flags for the new process as listed above.
diff --git a/include/uapi/linux/seccomp.h b/include/uapi/linux/seccomp.h
index dbfc9b37fcae..3a0ee0551261 100644
--- a/include/uapi/linux/seccomp.h
+++ b/include/uapi/linux/seccomp.h
@@ -25,6 +25,8 @@
#define SECCOMP_FILTER_FLAG_TSYNC_ESRCH (1UL << 4)
/* Received notifications wait in killable state (only respond to fatal signals) */
#define SECCOMP_FILTER_FLAG_WAIT_KILLABLE_RECV (1UL << 5)
+/* Restart syscalls interrupted before their notification is received */
+#define SECCOMP_FILTER_FLAG_RESTART_BEFORE_RECV (1UL << 6)
/*
* All BPF programs must return a 32-bit value.
diff --git a/include/uapi/linux/tee.h b/include/uapi/linux/tee.h
index 5203977ed35d..76815b0f4b66 100644
--- a/include/uapi/linux/tee.h
+++ b/include/uapi/linux/tee.h
@@ -385,24 +385,6 @@ struct tee_iocl_supp_send_arg {
struct tee_ioctl_buf_data)
/**
- * struct tee_ioctl_shm_register_data - Shared memory register argument
- * @addr: [in] Start address of shared memory to register
- * @length: [in/out] Length of shared memory to register
- * @flags: [in/out] Flags to/from registration.
- * @id: [out] Identifier of the shared memory
- *
- * The flags field should currently be zero as input. Updated by the call
- * with actual flags as defined by TEE_IOCTL_SHM_* above.
- * This structure is used as argument for TEE_IOC_SHM_REGISTER below.
- */
-struct tee_ioctl_shm_register_data {
- __u64 addr;
- __u64 length;
- __u32 flags;
- __s32 id;
-};
-
-/**
* struct tee_ioctl_shm_register_fd_data - Shared memory registering argument
* @fd: [in] File descriptor identifying dmabuf reference
* @size: [out] Size of referenced memory
@@ -426,7 +408,7 @@ struct tee_ioctl_shm_register_fd_data {
* Returns a file descriptor on success or < 0 on failure
*
* The returned file descriptor refers to the shared memory object in the
- * kernel. The supplied file deccriptor can be closed if it's not needed
+ * kernel. The supplied file descriptor can be closed if it's not needed
* for other purposes. The shared memory is freed when the descriptor is
* closed.
*/
@@ -434,13 +416,31 @@ struct tee_ioctl_shm_register_fd_data {
struct tee_ioctl_shm_register_fd_data)
/**
+ * struct tee_ioctl_shm_register_data - Shared memory register argument
+ * @addr: [in] Start address of shared memory to register
+ * @length: [in/out] Length of shared memory to register
+ * @flags: [in/out] Flags to/from registration.
+ * @id: [out] Identifier of the shared memory
+ *
+ * The flags field should currently be zero as input. Updated by the call
+ * with actual flags as defined by TEE_IOCTL_SHM_* above.
+ * This structure is used as argument for TEE_IOC_SHM_REGISTER below.
+ */
+struct tee_ioctl_shm_register_data {
+ __u64 addr;
+ __u64 length;
+ __u32 flags;
+ __s32 id;
+};
+
+/**
* TEE_IOC_SHM_REGISTER - Register shared memory argument
*
* Registers shared memory between the user space process and secure OS.
*
* Returns a file descriptor on success or < 0 on failure
*
- * The shared memory is unregisterred when the descriptor is closed.
+ * The shared memory is unregistered when the descriptor is closed.
*/
#define TEE_IOC_SHM_REGISTER _IOWR(TEE_IOC_MAGIC, TEE_IOC_BASE + 9, \
struct tee_ioctl_shm_register_data)
diff --git a/include/uapi/linux/thermal.h b/include/uapi/linux/thermal.h
index 46a2633d33aa..36f3da2d6a7c 100644
--- a/include/uapi/linux/thermal.h
+++ b/include/uapi/linux/thermal.h
@@ -81,11 +81,11 @@ enum thermal_genl_event {
THERMAL_GENL_EVENT_CDEV_STATE_UPDATE, /* Cdev state updated */
THERMAL_GENL_EVENT_TZ_GOV_CHANGE, /* Governor policy changed */
THERMAL_GENL_EVENT_CPU_CAPABILITY_CHANGE, /* CPU capability changed */
- THERMAL_GENL_EVENT_THRESHOLD_ADD, /* A thresold has been added */
- THERMAL_GENL_EVENT_THRESHOLD_DELETE, /* A thresold has been deleted */
+ THERMAL_GENL_EVENT_THRESHOLD_ADD, /* A threshold has been added */
+ THERMAL_GENL_EVENT_THRESHOLD_DELETE, /* A threshold has been deleted */
THERMAL_GENL_EVENT_THRESHOLD_FLUSH, /* All thresolds have been deleted */
- THERMAL_GENL_EVENT_THRESHOLD_UP, /* A thresold has been crossed the way up */
- THERMAL_GENL_EVENT_THRESHOLD_DOWN, /* A thresold has been crossed the way down */
+ THERMAL_GENL_EVENT_THRESHOLD_UP, /* A threshold has been crossed the way up */
+ THERMAL_GENL_EVENT_THRESHOLD_DOWN, /* A threshold has been crossed the way down */
__THERMAL_GENL_EVENT_MAX,
};
#define THERMAL_GENL_EVENT_MAX (__THERMAL_GENL_EVENT_MAX - 1)
diff --git a/include/uapi/linux/v4l2-controls.h b/include/uapi/linux/v4l2-controls.h
index affec0ab4781..d17e41d51d2e 100644
--- a/include/uapi/linux/v4l2-controls.h
+++ b/include/uapi/linux/v4l2-controls.h
@@ -123,6 +123,15 @@ enum v4l2_colorfx {
#define V4L2_CID_USER_MEYE_BASE (V4L2_CID_USER_BASE + 0x1000)
#endif
+/*
+ * The base for the vim2m driver controls.
+ * We reserve 16 controls for this driver.
+ * The vim2m control range clashed with the meye control range, which was not
+ * intended, but since the meye driver has been removed, we can just keep the
+ * vim2m control range.
+ */
+#define V4L2_CID_USER_VIM2M_BASE (V4L2_CID_USER_BASE + 0x1000)
+
/* The base for the bttv driver controls.
* We reserve 32 controls for this driver. */
#define V4L2_CID_USER_BTTV_BASE (V4L2_CID_USER_BASE + 0x1010)
@@ -234,6 +243,18 @@ enum v4l2_colorfx {
*/
#define V4L2_CID_USER_MALI_C55_BASE (V4L2_CID_USER_BASE + 0x1230)
+/*
+ * The base for the ST DCMIPP driver controls.
+ * We reserve 16 controls for this driver
+ */
+#define V4L2_CID_USER_DCMIPP_BASE (V4L2_CID_USER_BASE + 0x1240)
+
+/*
+ * The base for IT6625/IT6626 driver controls.
+ * We reserve 16 controls for this driver.
+ */
+#define V4L2_CID_USER_IT6625_BASE (V4L2_CID_USER_BASE + 0x1250)
+
/* MPEG-class control IDs */
/* The MPEG controls are applicable to all codec controls
* and the 'MPEG' part of the define is historical */
diff --git a/include/uapi/rdma/bnxt_re-abi.h b/include/uapi/rdma/bnxt_re-abi.h
index 856a1b3036e9..15ed2a51f8f1 100644
--- a/include/uapi/rdma/bnxt_re-abi.h
+++ b/include/uapi/rdma/bnxt_re-abi.h
@@ -250,7 +250,7 @@ struct bnxt_re_query_device_ex_resp {
struct bnxt_re_db_region {
__u32 dpi;
__u32 reserved;
- __aligned_u64 umdbr;
+ __aligned_u64 reserved2;
};
enum bnxt_re_obj_dbr_alloc_attrs {
diff --git a/include/uapi/rdma/ionic-abi.h b/include/uapi/rdma/ionic-abi.h
index 2c70ac149c4f..ac48fcd19a4f 100644
--- a/include/uapi/rdma/ionic-abi.h
+++ b/include/uapi/rdma/ionic-abi.h
@@ -22,6 +22,10 @@
#define IONIC_CMB_WC 8
#define IONIC_CMB_UC 16
+enum ionic_ctx_resp_comp_mask {
+ IONIC_CTX_CMASK_IONIC_FLAGS = 1 << 0,
+};
+
struct ionic_ctx_req {
__u32 rsvd[2];
};
@@ -46,8 +50,9 @@ struct ionic_ctx_resp {
__u8 udma_count;
__u8 expdb_mask;
__u8 expdb_qtypes;
+ __u8 rcq_sign_bit;
- __u8 rsvd2[3];
+ __u16 comp_mask;
__aligned_u64 phc_offset;
};
@@ -85,6 +90,8 @@ struct ionic_qp_req {
__u8 rq_cmb;
__u8 udma_mask;
__u8 rsvd[3];
+ __u32 ionic_flags;
+ __u32 rsvd_pad;
};
struct ionic_qp_resp {
@@ -106,7 +113,7 @@ struct ionic_srq_req {
};
struct ionic_srq_resp {
- __u32 qpid;
+ __u32 srqid;
__u8 rq_cmb;
__u8 udma_idx;
__u8 rsvd[2];
diff --git a/include/uapi/rdma/mana-abi.h b/include/uapi/rdma/mana-abi.h
index 32cbbfc80f99..ebc9a655b826 100644
--- a/include/uapi/rdma/mana-abi.h
+++ b/include/uapi/rdma/mana-abi.h
@@ -48,13 +48,23 @@ struct mana_ib_create_qp_resp {
__u32 reserved;
};
+enum mana_ib_create_rc_qp_flags {
+ MANA_IB_RC_QP_FIXED_WQE = 1 << 0,
+ MANA_IB_RC_MMQ_CREATE = 1 << 1,
+};
+
struct mana_ib_create_rc_qp {
__aligned_u64 queue_buf[4];
__u32 queue_size[4];
+ __aligned_u64 mmq_buf;
+ __u32 mmq_size;
+ __u32 comp_mask;
};
struct mana_ib_create_rc_qp_resp {
__u32 queue_id[4];
+ __u32 mmq_id;
+ __u32 reserved;
};
struct mana_ib_create_uc_qp {
@@ -100,6 +110,8 @@ struct mana_ib_create_qp_rss_resp {
enum mana_ib_ucontext_support {
MANA_IB_UCNTX_ALLOC_PDN_SUPPORT = 1 << 0,
+ MANA_IB_UCNTX_RC_EXT_SUPPORT = 1 << 1,
+ MANA_IB_UCNTX_RC_SQ_POW2_SUPPORT = 1 << 2,
};
struct mana_ib_alloc_ucontext_resp {
diff --git a/include/uapi/sound/asound.h b/include/uapi/sound/asound.h
index c11da9656e38..767c96273245 100644
--- a/include/uapi/sound/asound.h
+++ b/include/uapi/sound/asound.h
@@ -99,9 +99,10 @@ enum {
SNDRV_HWDEP_IFACE_LINE6, /* Line6 USB processors */
SNDRV_HWDEP_IFACE_FW_MOTU, /* MOTU FireWire series */
SNDRV_HWDEP_IFACE_FW_FIREFACE, /* RME Fireface series */
+ SNDRV_HWDEP_IFACE_CAIAQ, /* Native Instruments caiaq USB devices */
/* Don't forget to change the following: */
- SNDRV_HWDEP_IFACE_LAST = SNDRV_HWDEP_IFACE_FW_FIREFACE
+ SNDRV_HWDEP_IFACE_LAST = SNDRV_HWDEP_IFACE_CAIAQ
};
struct snd_hwdep_info {
diff --git a/include/ufs/ufs.h b/include/ufs/ufs.h
index afbb32654fab..b0207e694911 100644
--- a/include/ufs/ufs.h
+++ b/include/ufs/ufs.h
@@ -662,6 +662,7 @@ struct ufs_dev_info {
u8 rtt_cap; /* bDeviceRTTCap */
bool hid_sup;
+ bool timestamp_sup;
/* Unique device ID string (manufacturer+model+serial+version+date) */
char *device_id;
diff --git a/include/ufs/ufshcd.h b/include/ufs/ufshcd.h
index dfd302f2dc7c..be62165b785e 100644
--- a/include/ufs/ufshcd.h
+++ b/include/ufs/ufshcd.h
@@ -1132,6 +1132,14 @@ struct ufs_hba {
/* Auto-Hibernate Idle Timer register value */
u32 ahit;
+ /* Serializes AHIT register access between sysfs and the host driver */
+ struct mutex ahit_mutex;
+ /*
+ * Nesting count of host-driver paths that have AHIT forced off.
+ * Non-zero blocks sysfs AHIT writes; AHIT is reprogrammed only when
+ * the last disabler drops it back to zero. Guarded by ahit_mutex.
+ */
+ int ahit_disable_depth;
unsigned long outstanding_tasks;
spinlock_t outstanding_lock;
diff --git a/include/vdso/getrandom.h b/include/vdso/getrandom.h
index 6ca4d6de9e46..1d9dbd4d76c1 100644
--- a/include/vdso/getrandom.h
+++ b/include/vdso/getrandom.h
@@ -64,7 +64,7 @@ extern void __arch_chacha20_blocks_nostack(u8 *dst_bytes, const u32 *key, u32 *c
* @opaque_state: Passed to __cvdso_getrandom().
* @opaque_len: Passed to __cvdso_getrandom();
*
- * This function is implemented by making a single call to to __cvdso_getrandom(), whose
+ * This function is implemented by making a single call to __cvdso_getrandom(), whose
* documentation may be consulted for more information.
*
* Returns: The return value of __cvdso_getrandom().
diff --git a/include/vdso/math64.h b/include/vdso/math64.h
index 22ae212f8b28..6f1e311cfdbd 100644
--- a/include/vdso/math64.h
+++ b/include/vdso/math64.h
@@ -2,15 +2,38 @@
#ifndef __VDSO_MATH64_H
#define __VDSO_MATH64_H
-static __always_inline u32
-__iter_div_u64_rem(u64 dividend, u32 divisor, u64 *remainder)
+#include <linux/compiler.h>
+
+static __always_inline u32 __iter_div_u64_rem(u64 dividend, u32 divisor, u64 *remainder)
+{
+ u32 ret = 0;
+
+ while (dividend >= divisor) {
+ /*
+ * Prevent the compiler from optimising this loop into a
+ * modulo operation.
+ */
+ OPTIMIZER_HIDE_VAR(dividend);
+
+ dividend -= divisor;
+ ret++;
+ }
+
+ *remainder = dividend;
+
+ return ret;
+}
+
+static __always_inline u32 __iter_div64_u64_rem(u64 dividend, u64 divisor, u64 *remainder)
{
u32 ret = 0;
while (dividend >= divisor) {
- /* The following asm() prevents the compiler from
- optimising this loop into a modulo operation. */
- asm("" : "+rm"(dividend));
+ /*
+ * Prevent the compiler from optimising this loop into a
+ * modulo operation.
+ */
+ OPTIMIZER_HIDE_VAR(dividend);
dividend -= divisor;
ret++;
diff --git a/include/vdso/vsyscall.h b/include/vdso/vsyscall.h
index c5c2a2c07857..af62bbf04eac 100644
--- a/include/vdso/vsyscall.h
+++ b/include/vdso/vsyscall.h
@@ -2,13 +2,6 @@
#ifndef __VDSO_VSYSCALL_H
#define __VDSO_VSYSCALL_H
-#ifndef __ASSEMBLER__
-
#include <asm/vdso/vsyscall.h>
-unsigned long vdso_update_begin(void);
-void vdso_update_end(unsigned long flags);
-
-#endif /* !__ASSEMBLER__ */
-
#endif /* __VDSO_VSYSCALL_H */
diff --git a/include/video/mmp_disp.h b/include/video/mmp_disp.h
index 41354bd49895..8f2b434da4e9 100644
--- a/include/video/mmp_disp.h
+++ b/include/video/mmp_disp.h
@@ -172,7 +172,7 @@ struct mmp_panel {
/* use node to register to list */
struct list_head node;
const char *name;
- /* path name used to connect to proper path configed */
+ /* path name used to connect to proper path configured */
const char *plat_path_name;
struct device *dev;
int panel_type;
@@ -291,7 +291,7 @@ static inline int mmp_overlay_set_addr(struct mmp_overlay *overlay,
* it defined a common interface that plat driver need to implement
*/
struct mmp_path_info {
- /* driver data, set when registed*/
+ /* driver data, set when registered */
const char *name;
struct device *dev;
int id;
@@ -309,7 +309,7 @@ extern void mmp_unregister_path(struct mmp_path *path);
extern void mmp_register_panel(struct mmp_panel *panel);
extern void mmp_unregister_panel(struct mmp_panel *panel);
-/* defintions for platform data */
+/* definitions for platform data */
/* interface for buffer driver */
struct mmp_buffer_driver_mach_info {
const char *name;
diff --git a/include/xen/interface/hvm/hvm_vcpu.h b/include/xen/interface/hvm/hvm_vcpu.h
deleted file mode 100644
index cbf93493275c..000000000000
--- a/include/xen/interface/hvm/hvm_vcpu.h
+++ /dev/null
@@ -1,116 +0,0 @@
-/* SPDX-License-Identifier: MIT */
-/*
- * Copyright (c) 2015, Roger Pau Monne <roger.pau@citrix.com>
- */
-
-#ifndef __XEN_PUBLIC_HVM_HVM_VCPU_H__
-#define __XEN_PUBLIC_HVM_HVM_VCPU_H__
-
-#include "../xen.h"
-
-struct vcpu_hvm_x86_32 {
- uint32_t eax;
- uint32_t ecx;
- uint32_t edx;
- uint32_t ebx;
- uint32_t esp;
- uint32_t ebp;
- uint32_t esi;
- uint32_t edi;
- uint32_t eip;
- uint32_t eflags;
-
- uint32_t cr0;
- uint32_t cr3;
- uint32_t cr4;
-
- uint32_t pad1;
-
- /*
- * EFER should only be used to set the NXE bit (if required)
- * when starting a vCPU in 32bit mode with paging enabled or
- * to set the LME/LMA bits in order to start the vCPU in
- * compatibility mode.
- */
- uint64_t efer;
-
- uint32_t cs_base;
- uint32_t ds_base;
- uint32_t ss_base;
- uint32_t es_base;
- uint32_t tr_base;
- uint32_t cs_limit;
- uint32_t ds_limit;
- uint32_t ss_limit;
- uint32_t es_limit;
- uint32_t tr_limit;
- uint16_t cs_ar;
- uint16_t ds_ar;
- uint16_t ss_ar;
- uint16_t es_ar;
- uint16_t tr_ar;
-
- uint16_t pad2[3];
-};
-
-/*
- * The layout of the _ar fields of the segment registers is the
- * following:
- *
- * Bits [0,3]: type (bits 40-43).
- * Bit 4: s (descriptor type, bit 44).
- * Bit [5,6]: dpl (descriptor privilege level, bits 45-46).
- * Bit 7: p (segment-present, bit 47).
- * Bit 8: avl (available for system software, bit 52).
- * Bit 9: l (64-bit code segment, bit 53).
- * Bit 10: db (meaning depends on the segment, bit 54).
- * Bit 11: g (granularity, bit 55)
- * Bits [12,15]: unused, must be blank.
- *
- * A more complete description of the meaning of this fields can be
- * obtained from the Intel SDM, Volume 3, section 3.4.5.
- */
-
-struct vcpu_hvm_x86_64 {
- uint64_t rax;
- uint64_t rcx;
- uint64_t rdx;
- uint64_t rbx;
- uint64_t rsp;
- uint64_t rbp;
- uint64_t rsi;
- uint64_t rdi;
- uint64_t rip;
- uint64_t rflags;
-
- uint64_t cr0;
- uint64_t cr3;
- uint64_t cr4;
- uint64_t efer;
-
- /*
- * Using VCPU_HVM_MODE_64B implies that the vCPU is launched
- * directly in long mode, so the cached parts of the segment
- * registers get set to match that environment.
- *
- * If the user wants to launch the vCPU in compatibility mode
- * the 32-bit structure should be used instead.
- */
-};
-
-struct vcpu_hvm_context {
-#define VCPU_HVM_MODE_32B 0 /* 32bit fields of the structure will be used. */
-#define VCPU_HVM_MODE_64B 1 /* 64bit fields of the structure will be used. */
- uint32_t mode;
-
- uint32_t pad;
-
- /* CPU registers. */
- union {
- struct vcpu_hvm_x86_32 x86_32;
- struct vcpu_hvm_x86_64 x86_64;
- } cpu_regs;
-};
-typedef struct vcpu_hvm_context vcpu_hvm_context_t;
-
-#endif /* __XEN_PUBLIC_HVM_HVM_VCPU_H__ */
diff --git a/include/xen/interface/platform.h b/include/xen/interface/platform.h
index 79a443c65ea9..462e36392a9f 100644
--- a/include/xen/interface/platform.h
+++ b/include/xen/interface/platform.h
@@ -421,10 +421,10 @@ struct xenpf_pcpuinfo {
/* IN */
uint32_t xen_cpuid;
/* OUT */
- /* The maxium cpu_id that is present */
+ /* The maximum cpu_id that is present */
uint32_t max_present;
#define XEN_PCPU_FLAGS_ONLINE 1
- /* Correponding xen_cpuid is not present*/
+ /* Corresponding xen_cpuid is not present*/
#define XEN_PCPU_FLAGS_INVALID 2
uint32_t flags;
uint32_t apic_id;
diff --git a/include/xen/interface/xen.h b/include/xen/interface/xen.h
index 40c9793e9880..f9acb21875cf 100644
--- a/include/xen/interface/xen.h
+++ b/include/xen/interface/xen.h
@@ -94,7 +94,7 @@
#define VIRQ_XENOPROF 7 /* V. XenOprofile interrupt: new sample available */
#define VIRQ_CON_RING 8 /* G. (DOM0) Bytes received on console */
#define VIRQ_PCPU_STATE 9 /* G. (DOM0) PCPU state changed */
-#define VIRQ_MEM_EVENT 10 /* G. (DOM0) A memory event has occured */
+#define VIRQ_MEM_EVENT 10 /* G. (DOM0) A memory event has occurred */
#define VIRQ_XC_RESERVED 11 /* G. Reserved for XenClient */
#define VIRQ_ENOMEM 12 /* G. (DOM0) Low on heap memory */
#define VIRQ_XENPMU 13 /* PMC interrupt */
diff --git a/include/xen/xenbus.h b/include/xen/xenbus.h
index 8ca15743af7f..6424c5cf8ef5 100644
--- a/include/xen/xenbus.h
+++ b/include/xen/xenbus.h
@@ -63,7 +63,7 @@ struct xenbus_watch
unsigned int nr_pending;
/*
- * Called just before enqueing new event while a spinlock is held.
+ * Called just before enqueuing new event while a spinlock is held.
* The event will be discarded if this callback returns false.
*/
bool (*will_handle)(struct xenbus_watch *,