* remotes/origin/tmp-d62984a:
ANDROID: delete tool added by mistake
ANDROID: fix ENOMEM check of binder_proc_ext
ANDROID: binder: fix KMI issues due to frozen notification
BACKPORT: FROMGIT: binder: frozen notification binder_features flag
BACKPORT: FROMGIT: binder: frozen notification
BACKPORT: selftests/binderfs: add test for feature files
UPSTREAM: docs: binderfs: add section about feature files
BACKPORT: binderfs: add support for feature files
FROMLIST: binder: fix memory leaks of spam and pending work
FROMGIT: Binder: add TF_UPDATE_TXN to replace outdated txn
BACKPORT: binder: tell userspace to dump current backtrace when detected oneway spamming
UPSTREAM: net: sched: sch_multiq: fix possible OOB write in multiq_tune()
FROMLIST: binder: fix UAF caused by offsets overwrite
Revert "net: mac802154: Fix racy device stats updates by DEV_STATS_INC() and DEV_STATS_ADD()"
Linux 5.4.281
tap: add missing verification for short frame
tun: add missing verification for short frame
filelock: Fix fcntl/close race recovery compat path
ALSA: hda/realtek: Enable headset mic on Positivo SU C1400
jfs: don't walk off the end of ealist
ocfs2: add bounds checking to ocfs2_check_dir_entry()
net: relax socket state check at accept time.
drm/amdgpu: Fix signedness bug in sdma_v4_0_process_trap_irq()
ACPI: processor_idle: Fix invalid comparison with insertion sort for latency
ARM: 9324/1: fix get_user() broken with veneer
hfsplus: fix uninit-value in copy_name
selftests/vDSO: fix clang build errors and warnings
spi: imx: Don't expect DMA for i.MX{25,35,50,51,53} cspi devices
fs: better handle deep ancestor chains in is_subdir()
Bluetooth: hci_core: cancel all works upon hci_unregister_dev()
scsi: libsas: Fix exp-attached device scan after probe failure scanned in again after probe failed
powerpc/eeh: avoid possible crash when edev->pdev changes
powerpc/pseries: Whitelist dtl slub object for copying to userspace
net: mac802154: Fix racy device stats updates by DEV_STATS_INC() and DEV_STATS_ADD()
net: usb: qmi_wwan: add Telit FN912 compositions
ALSA: dmaengine_pcm: terminate dmaengine before synchronize
s390/sclp: Fix sclp_init() cleanup on failure
can: kvaser_usb: fix return value for hif_usb_send_regout
ASoC: ti: omap-hdmi: Fix too long driver name
ASoC: ti: davinci-mcasp: Set min period size using FIFO config
bytcr_rt5640 : inverse jack detect for Archos 101 cesium
Input: elantech - fix touchpad state on resume for Lenovo N24
mips: fix compat_sys_lseek syscall
ALSA: hda/realtek: Add more codec ID to no shutup pins list
KVM: PPC: Book3S HV: Prevent UAF in kvm_spapr_tce_attach_iommu_group()
wifi: cfg80211: wext: add extra SIOCSIWSCAN data check
mei: demote client disconnect warning on suspend to debug
fs/file: fix the check in find_next_fd()
kconfig: remove wrong expr_trans_bool()
kconfig: gconf: give a proper initial state to the Save button
ila: block BH in ila_output()
Input: silead - Always support 10 fingers
wifi: mac80211: fix UBSAN noise in ieee80211_prep_hw_scan()
wifi: mac80211: mesh: init nonpeer_pm to active by default in mesh sdata
ACPI: EC: Avoid returning AE_OK on errors in address space handler
ACPI: EC: Abort address space access upon error
scsi: qedf: Set qed_slowpath_params to zero before use
filelock: Remove locks reliably when fcntl/close race is detected
gcc-plugins: Rename last_stmt() for GCC 14+
ANDROID: GKI: refresh ABI to include kimage_vaddr
ANDROID: preserve CRC for struct tcp_sock
Linux 5.4.280
i2c: rcar: bring hardware to known state when probing
nilfs2: fix kernel bug on rename operation of broken directory
tcp: avoid too many retransmit packets
tcp: use signed arithmetic in tcp_rtx_probe0_timed_out()
net: tcp: fix unexcepted socket die when snd_wnd is 0
tcp: refactor tcp_retransmit_timer()
SUNRPC: Fix RPC client cleaned up the freed pipefs dentries
libceph: fix race between delayed_work() and ceph_monc_stop()
ALSA: hda/realtek: Limit mic boost on VAIO PRO PX
nvmem: meson-efuse: Fix return value of nvmem callbacks
hpet: Support 32-bit userspace
USB: core: Fix duplicate endpoint bug by clearing reserved bits in the descriptor
usb: gadget: configfs: Prevent OOB read/write in usb_string_copy()
USB: Add USB_QUIRK_NO_SET_INTF quirk for START BP-850k
USB: serial: option: add Rolling RW350-GL variants
USB: serial: option: add Netprisma LCUK54 series modules
USB: serial: option: add support for Foxconn T99W651
USB: serial: option: add Fibocom FM350-GL
USB: serial: option: add Telit FN912 rmnet compositions
USB: serial: option: add Telit generic core-dump composition
octeontx2-af: fix detection of IP layer
ARM: davinci: Convert comma to semicolon
s390: Mark psw in __load_psw_mask() as __unitialized
udp: Set SOCK_RCU_FREE earlier in udp_lib_get_port().
ppp: reject claimed-as-LCP but actually malformed packets
net: ethernet: lantiq_etop: fix double free in detach
net: lantiq_etop: add blank line after declaration
octeontx2-af: Fix incorrect value output on error path in rvu_check_rsrc_availability()
tcp: fix incorrect undo caused by DSACK of TLP retransmit
tcp: add TCP_INFO status for failed client TFO
vfs: don't mod negative dentry count when on shrinker list
fs/dcache: Re-use value stored to dentry->d_flags instead of re-reading
filelock: fix potential use-after-free in posix_lock_inode
nilfs2: fix incorrect inode allocation from reserved inodes
nvme-multipath: find NUMA path only for online numa-node
ALSA: hda/realtek: Enable headset mic of JP-IK LEAP W502 with ALC897
i2c: pnx: Fix potential deadlock warning from del_timer_sync() call in isr
media: dw2102: fix a potential buffer overflow
bnx2x: Fix multiple UBSAN array-index-out-of-bounds
drm/amdgpu/atomfirmware: silence UBSAN warning
drm/nouveau: fix null pointer dereference in nouveau_connector_get_modes
Revert "mm/writeback: fix possible divide-by-zero in wb_dirty_limits(), again"
fsnotify: Do not generate events for O_PATH file descriptors
can: kvaser_usb: Explicitly initialize family in leafimx driver_info struct
mm: optimize the redundant loop of mm_update_owner_next()
nilfs2: add missing check for inode numbers on directory entries
nilfs2: fix inode number range checks
inet_diag: Initialize pad field in struct inet_diag_req_v2
selftests: make order checking verbose in msg_zerocopy selftest
selftests: fix OOM in msg_zerocopy selftest
bonding: Fix out-of-bounds read in bond_option_arp_ip_targets_set()
wifi: wilc1000: fix ies_len type in connect path
tcp_metrics: validate source addr length
UPSTREAM: tcp: fix DSACK undo in fast recovery to call tcp_try_to_open()
net: tcp better handling of reordering then loss cases
tcp: add ece_ack flag to reno sack functions
tcp: tcp_mark_head_lost is only valid for sack-tcp
s390/pkey: Wipe sensitive data on failure
jffs2: Fix potential illegal address access in jffs2_free_inode
powerpc/xmon: Check cpu id in commands "c#", "dp#" and "dx#"
orangefs: fix out-of-bounds fsid access
powerpc/64: Set _IO_BASE to POISON_POINTER_DELTA not 0 for CONFIG_PCI=n
i2c: i801: Annotate apanel_addr as __ro_after_init
media: dvb-frontends: tda10048: Fix integer overflow
media: s2255: Use refcount_t instead of atomic_t for num_channels
media: dvb-frontends: tda18271c2dd: Remove casting during div
net: dsa: mv88e6xxx: Correct check for empty list
Input: ff-core - prefer struct_size over open coded arithmetic
firmware: dmi: Stop decoding on broken entry
sctp: prefer struct_size over open coded arithmetic
media: dw2102: Don't translate i2c read into write
drm/amd/display: Skip finding free audio for unknown engine_id
drm/amdgpu: Initialize timestamp for some legacy SOCs
scsi: qedf: Make qedf_execute_tmf() non-preemptible
IB/core: Implement a limit on UMAD receive List
media: dvb-usb: dib0700_devices: Add missing release_firmware()
media: dvb: as102-fe: Fix as10x_register_addr packing
drm/lima: fix shared irq handling on driver remove
Compiler Attributes: Add __uninitialized macro
Linux 5.4.279
arm64: dts: rockchip: Add sound-dai-cells for RK3368
ARM: dts: rockchip: rk3066a: add #sound-dai-cells to hdmi node
tcp: Fix data races around icsk->icsk_af_ops.
ipv6: Fix data races around sk->sk_prot.
ipv6: annotate some data-races around sk->sk_prot
nfs: Leave pages in the pagecache if readpage failed
pwm: stm32: Refuse too small period requests
mtd: spinand: macronix: Add support for serial NAND flash
ftruncate: pass a signed offset
ata: libata-core: Fix double free on error
batman-adv: Don't accept TT entries for out-of-spec VIDs
drm/nouveau/dispnv04: fix null pointer dereference in nv17_tv_get_hd_modes
drm/nouveau/dispnv04: fix null pointer dereference in nv17_tv_get_ld_modes
hexagon: fix fadvise64_64 calling conventions
csky, hexagon: fix broken sys_sync_file_range
net: can: j1939: enhanced error handling for tightly received RTS messages in xtp_rx_rts_session_new
net: can: j1939: recover socket queue on CAN bus error during BAM transmission
net: can: j1939: Initialize unused data in j1939_send_one()
tty: mcf: MCF54418 has 10 UARTS
usb: atm: cxacru: fix endpoint checking in cxacru_bind()
usb: musb: da8xx: fix a resource leak in probe()
usb: gadget: printer: SS+ support
net: usb: ax88179_178a: improve link status logs
iio: chemical: bme680: Fix sensor data read operation
iio: chemical: bme680: Fix overflows in compensate() functions
iio: chemical: bme680: Fix calibration data variable
iio: chemical: bme680: Fix pressure value output
iio: adc: ad7266: Fix variable checking bug
mmc: sdhci: Do not lock spinlock around mmc_gpio_get_ro()
mmc: sdhci: Do not invert write-protect twice
mmc: sdhci-pci: Convert PCIBIOS_* return codes to errnos
x86: stop playing stack games in profile_pc()
gpio: davinci: Validate the obtained number of IRQs
nvme: fixup comment for nvme RDMA Provider Type
soc: ti: wkup_m3_ipc: Send NULL dummy message instead of pointer message
media: dvbdev: Initialize sbuf
ALSA: emux: improve patch ioctl data validation
net/dpaa2: Avoid explicit cpumask var allocation on stack
net/iucv: Avoid explicit cpumask var allocation on stack
mtd: partitions: redboot: Added conversion of operands to a larger type
drm/panel: ilitek-ili9881c: Fix warning with GPIO controllers that sleep
netfilter: nf_tables: fully validate NFT_DATA_VALUE on store to data registers
parisc: use correct compat recv/recvfrom syscalls
sparc: fix old compat_sys_select()
net: phy: micrel: add Microchip KSZ 9477 to the device table
net: phy: mchp: Add support for LAN8814 QUAD PHY
net: dsa: microchip: fix initial port flush problem
ASoC: fsl-asoc-card: set priv->pdev before using it
netfilter: nf_tables: validate family when identifying table via handle
drm/amdgpu: fix UBSAN warning in kv_dpm.c
pinctrl: rockchip: fix pinmux reset in rockchip_pmx_set
pinctrl: rockchip: fix pinmux bits for RK3328 GPIO3-B pins
pinctrl: rockchip: fix pinmux bits for RK3328 GPIO2-B pins
pinctrl: fix deadlock in create_pinctrl() when handling -EPROBE_DEFER
iio: dac: ad5592r: fix temperature channel scaling value
iio: dac: ad5592r: un-indent code-block for scale read
iio: dac: ad5592r-base: Replace indio_dev->mlock with own device lock
x86/amd_nb: Check for invalid SMN reads
PCI: Add PCI_ERROR_RESPONSE and related definitions
perf/core: Fix missing wakeup when waiting for context reference
kheaders: explicitly define file modes for archived headers
Revert "kheaders: substituting --sort in archive creation"
tracing: Add MODULE_DESCRIPTION() to preemptirq_delay_test
arm64: dts: qcom: qcs404: fix bluetooth device address
ARM: dts: samsung: smdk4412: fix keypad no-autorepeat
ARM: dts: samsung: exynos4412-origen: fix keypad no-autorepeat
ARM: dts: samsung: smdkv310: fix keypad no-autorepeat
i2c: ocores: set IACK bit after core is enabled
gcov: add support for GCC 14
drm/radeon: fix UBSAN warning in kv_dpm.c
ACPICA: Revert "ACPICA: avoid Info: mapping multiple BARs. Your kernel is fine."
dmaengine: ioatdma: Fix missing kmem_cache_destroy()
regulator: core: Fix modpost error "regulator_get_regmap" undefined
net: usb: rtl8150 fix unintiatilzed variables in rtl8150_get_link_ksettings
netfilter: ipset: Fix suspicious rcu_dereference_protected()
virtio_net: checksum offloading handling fix
net/sched: act_api: fix possible infinite loop in tcf_idr_check_alloc()
net/sched: act_api: rely on rcu in tcf_idr_check_alloc
netns: Make get_net_ns() handle zero refcount net
xfrm6: check ip6_dst_idev() return value in xfrm6_get_saddr()
ipv6: prevent possible NULL dereference in rt6_probe()
ipv6: prevent possible NULL deref in fib6_nh_init()
netrom: Fix a memory leak in nr_heartbeat_expiry()
cipso: fix total option length computation
mips: bmips: BCM6358: make sure CBR is correctly set
MIPS: Routerboard 532: Fix vendor retry check code
MIPS: Octeon: Add PCIe link status check
PCI/PM: Avoid D3cold for HP Pavilion 17 PC/1972 PCIe Ports
udf: udftime: prevent overflow in udf_disk_stamp_to_time()
usb: misc: uss720: check for incompatible versions of the Belkin F5U002
powerpc/io: Avoid clang null pointer arithmetic warnings
powerpc/pseries: Enforce hcall result buffer validity and size
Bluetooth: ath3k: Fix multiple issues reported by checkpatch.pl
scsi: qedi: Fix crash while reading debugfs attribute
drop_monitor: replace spin_lock by raw_spin_lock
batman-adv: bypass empty buckets in batadv_purge_orig_ref()
selftests/bpf: Prevent client connect before server bind in test_tc_tunnel.sh
rcutorture: Fix rcu_torture_one_read() pipe_count overflow comment
i2c: at91: Fix the functionality flags of the slave-only interface
usb-storage: alauda: Check whether the media is initialized
greybus: Fix use-after-free bug in gb_interface_release due to race condition.
netfilter: nftables: exthdr: fix 4-byte stack OOB write
hugetlb_encode.h: fix undefined behaviour (34 << 26)
hv_utils: drain the timesync packets on onchannelcallback
tick/nohz_full: Don't abuse smp_call_function_single() in tick_setup_device()
nilfs2: fix potential kernel bug due to lack of writeback flag waiting
intel_th: pci: Add Lunar Lake support
intel_th: pci: Add Meteor Lake-S support
intel_th: pci: Add Sapphire Rapids SOC support
intel_th: pci: Add Granite Rapids SOC support
intel_th: pci: Add Granite Rapids support
dmaengine: axi-dmac: fix possible race in remove()
PCI: rockchip-ep: Remove wrong mask on subsys_vendor_id
ocfs2: fix races between hole punching and AIO+DIO
ocfs2: use coarse time for new created files
fs/proc: fix softlockup in __read_vmcore
vmci: prevent speculation leaks by sanitizing event in event_deliver()
tracing/selftests: Fix kprobe event name test for .isra. functions
drm/exynos: hdmi: report safe 640x480 mode as a fallback when no EDID found
drm/exynos/vidi: fix memory leak in .get_modes()
drivers: core: synchronize really_probe() and dev_uevent()
ionic: fix use after netif_napi_del()
net/ipv6: Fix the RT cache flush via sysctl using a previous delay
netfilter: ipset: Fix race between namespace cleanup and gc in the list:set type
Bluetooth: L2CAP: Fix rejecting L2CAP_CONN_PARAM_UPDATE_REQ
net/mlx5e: Fix features validation check for tunneled UDP (non-VXLAN) packets
tcp: fix race in tcp_v6_syn_recv_sock()
drm/bridge/panel: Fix runtime warning on panel bridge release
drm/komeda: check for error-valued pointer
liquidio: Adjust a NULL pointer handling path in lio_vf_rep_copy_packet
HID: logitech-dj: Fix memory leak in logi_dj_recv_switch_to_dj_mode()
iommu: Return right value in iommu_sva_bind_device()
iommu/amd: Fix sysfs leak in iommu init
HID: core: remove unnecessary WARN_ON() in implement()
gpio: tqmx86: fix typo in Kconfig label
SUNRPC: return proper error from gss_wrap_req_priv
Input: try trimming too long modalias strings
scsi: mpt3sas: Avoid test/set_bit() operating in non-allocated memory
xhci: Apply broken streams quirk to Etron EJ188 xHCI host
xhci: Apply reset resume quirk to Etron EJ188 xHCI host
xhci: Set correct transferred length for cancelled bulk transfers
jfs: xattr: fix buffer overflow for invalid xattr
mei: me: release irq in mei_me_pci_resume error path
USB: class: cdc-wdm: Fix CPU lockup caused by excessive log messages
nilfs2: fix nilfs_empty_dir() misjudgment and long loop on I/O errors
nilfs2: return the mapped address from nilfs_get_page()
nilfs2: Remove check for PageError
selftests/mm: compaction_test: fix bogus test success on Aarch64
selftests/mm: conform test to TAP format output
selftests/mm: compaction_test: fix incorrect write of zero to nr_hugepages
serial: sc16is7xx: fix bug in sc16is7xx_set_baud() when using prescaler
serial: sc16is7xx: replace hardcoded divisor value with BIT() macro
drm/amd/display: Handle Y carry-over in VCP X.Y calculation
ASoC: ti: davinci-mcasp: Fix race condition during probe
ASoC: ti: davinci-mcasp: Handle missing required DT properties
ASoC: ti: davinci-mcasp: Simplify the configuration parameter handling
ASoC: ti: davinci-mcasp: Remove legacy dma_request parsing
ASoC: ti: davinci-mcasp: Use platform_get_irq_byname_optional
ASoC: ti: davinci-mcasp: remove always zero of davinci_mcasp_get_dt_params
ASoC: ti: davinci-mcasp: remove redundant assignment to variable ret
usb: gadget: f_fs: Fix race between aio_cancel() and AIO request complete
ipv6: fix possible race in __fib6_drop_pcpu_from()
af_unix: Annotate data-race of sk->sk_shutdown in sk_diag_fill().
af_unix: Use skb_queue_len_lockless() in sk_diag_show_rqlen().
af_unix: Use unix_recvq_full_lockless() in unix_stream_connect().
af_unix: Annotate data-race of net->unx.sysctl_max_dgram_qlen.
af_unix: Annotate data-races around sk->sk_state in UNIX_DIAG.
af_unix: Annotate data-races around sk->sk_state in sendmsg() and recvmsg().
af_unix: Annotate data-races around sk->sk_state in unix_write_space() and poll().
af_unix: Annotate data-race of sk->sk_state in unix_inq_len().
ptp: Fix error message on failed pin verification
net/sched: taprio: always validate TCA_TAPRIO_ATTR_PRIOMAP
net/mlx5: Stop waiting for PCI if pci channel is offline
tcp: count CLOSE-WAIT sockets for TCP_MIB_CURRESTAB
vxlan: Fix regression when dropping packets due to invalid src addresses
net: sched: sch_multiq: fix possible OOB write in multiq_tune()
ipv6: sr: block BH in seg6_output_core() and seg6_input_core()
wifi: iwlwifi: mvm: don't read past the mfuart notifcation
wifi: iwlwifi: dbg_ini: move iwl_dbg_tlv_free outside of debugfs ifdef
wifi: iwlwifi: mvm: revert gen2 TX A-MPDU size to 64
wifi: cfg80211: pmsr: use correct nla_get_uX functions
wifi: mac80211: Fix deadlock in ieee80211_sta_ps_deliver_wakeup()
wifi: mac80211: mesh: Fix leak of mesh_preq_queue objects
Conflicts:
kernel/gen_kheaders.sh
Change-Id: I4a0de5504b5e61a23b78a1a8f06aceaac810f3c7
Signed-off-by: kamasali Satyanarayan <quic_kamasali@quicinc.com>
1160 lines
36 KiB
C
1160 lines
36 KiB
C
/* SPDX-License-Identifier: GPL-2.0-only */
|
|
/*
|
|
* Copyright (C) 2007-2008 Advanced Micro Devices, Inc.
|
|
* Author: Joerg Roedel <joerg.roedel@amd.com>
|
|
*/
|
|
|
|
#ifndef __LINUX_IOMMU_H
|
|
#define __LINUX_IOMMU_H
|
|
|
|
#include <linux/scatterlist.h>
|
|
#include <linux/device.h>
|
|
#include <linux/types.h>
|
|
#include <linux/errno.h>
|
|
#include <linux/err.h>
|
|
#include <linux/of.h>
|
|
#include <uapi/linux/iommu.h>
|
|
|
|
#define IOMMU_READ (1 << 0)
|
|
#define IOMMU_WRITE (1 << 1)
|
|
#define IOMMU_CACHE (1 << 2) /* DMA cache coherency */
|
|
#define IOMMU_NOEXEC (1 << 3)
|
|
#define IOMMU_MMIO (1 << 4) /* e.g. things like MSI doorbells */
|
|
/*
|
|
* Where the bus hardware includes a privilege level as part of its access type
|
|
* markings, and certain devices are capable of issuing transactions marked as
|
|
* either 'supervisor' or 'user', the IOMMU_PRIV flag requests that the other
|
|
* given permission flags only apply to accesses at the higher privilege level,
|
|
* and that unprivileged transactions should have as little access as possible.
|
|
* This would usually imply the same permissions as kernel mappings on the CPU,
|
|
* if the IOMMU page table format is equivalent.
|
|
*/
|
|
#define IOMMU_PRIV (1 << 5)
|
|
/*
|
|
* Non-coherent masters on few Qualcomm SoCs can use this page protection flag
|
|
* to set correct cacheability attributes to use an outer level of cache -
|
|
* last level cache, aka system cache.
|
|
*/
|
|
#define IOMMU_QCOM_SYS_CACHE (1 << 6)
|
|
/* Use upstream device's bus attribute */
|
|
#define IOMMU_USE_UPSTREAM_HINT (1 << 7)
|
|
|
|
/* Use upstream device's bus attribute with no write-allocate cache policy */
|
|
#define IOMMU_USE_LLC_NWA (1 << 8)
|
|
|
|
struct iommu_ops;
|
|
struct iommu_group;
|
|
struct bus_type;
|
|
struct device;
|
|
struct iommu_domain;
|
|
struct notifier_block;
|
|
struct iommu_sva;
|
|
struct iommu_fault_event;
|
|
|
|
/* iommu fault flags */
|
|
#define IOMMU_FAULT_READ (1 << 0)
|
|
#define IOMMU_FAULT_WRITE (1 << 1)
|
|
#define IOMMU_FAULT_TRANSLATION (1 << 2)
|
|
#define IOMMU_FAULT_PERMISSION (1 << 3)
|
|
#define IOMMU_FAULT_EXTERNAL (1 << 4)
|
|
#define IOMMU_FAULT_TRANSACTION_STALLED (1 << 5)
|
|
|
|
typedef int (*iommu_fault_handler_t)(struct iommu_domain *,
|
|
struct device *, unsigned long, int, void *);
|
|
typedef int (*iommu_mm_exit_handler_t)(struct device *dev, struct iommu_sva *,
|
|
void *);
|
|
typedef int (*iommu_dev_fault_handler_t)(struct iommu_fault *, void *);
|
|
|
|
struct iommu_fault_ids {
|
|
u32 bid;
|
|
u32 pid;
|
|
u32 mid;
|
|
};
|
|
|
|
struct iommu_domain_geometry {
|
|
dma_addr_t aperture_start; /* First address that can be mapped */
|
|
dma_addr_t aperture_end; /* Last address that can be mapped */
|
|
bool force_aperture; /* DMA only allowed in mappable range? */
|
|
};
|
|
|
|
/* iommu transaction flags */
|
|
#define IOMMU_TRANS_WRITE BIT(0) /* 1 Write, 0 Read */
|
|
#define IOMMU_TRANS_PRIV BIT(1) /* 1 Privileged, 0 Unprivileged */
|
|
#define IOMMU_TRANS_INST BIT(2) /* 1 Instruction fetch, 0 Data access */
|
|
#define IOMMU_TRANS_SEC BIT(3) /* 1 Secure, 0 Non-secure access*/
|
|
|
|
/* Non secure unprivileged Data read operation */
|
|
#define IOMMU_TRANS_DEFAULT (0U)
|
|
|
|
struct iommu_pgtbl_info {
|
|
void *ops;
|
|
};
|
|
|
|
/* Domain feature flags */
|
|
#define __IOMMU_DOMAIN_PAGING (1U << 0) /* Support for iommu_map/unmap */
|
|
#define __IOMMU_DOMAIN_DMA_API (1U << 1) /* Domain for use in DMA-API
|
|
implementation */
|
|
#define __IOMMU_DOMAIN_PT (1U << 2) /* Domain is identity mapped */
|
|
|
|
/*
|
|
* This are the possible domain-types
|
|
*
|
|
* IOMMU_DOMAIN_BLOCKED - All DMA is blocked, can be used to isolate
|
|
* devices
|
|
* IOMMU_DOMAIN_IDENTITY - DMA addresses are system physical addresses
|
|
* IOMMU_DOMAIN_UNMANAGED - DMA mappings managed by IOMMU-API user, used
|
|
* for VMs
|
|
* IOMMU_DOMAIN_DMA - Internally used for DMA-API implementations.
|
|
* This flag allows IOMMU drivers to implement
|
|
* certain optimizations for these domains
|
|
*/
|
|
#define IOMMU_DOMAIN_BLOCKED (0U)
|
|
#define IOMMU_DOMAIN_IDENTITY (__IOMMU_DOMAIN_PT)
|
|
#define IOMMU_DOMAIN_UNMANAGED (__IOMMU_DOMAIN_PAGING)
|
|
#define IOMMU_DOMAIN_DMA (__IOMMU_DOMAIN_PAGING | \
|
|
__IOMMU_DOMAIN_DMA_API)
|
|
|
|
#define to_msm_iommu_ops(_iommu_ops) \
|
|
container_of(_iommu_ops, struct msm_iommu_ops, iommu_ops)
|
|
#define to_msm_iommu_domain(_iommu_domain) \
|
|
container_of(_iommu_domain, struct msm_iommu_domain, iommu_domain)
|
|
|
|
#define IOMMU_DOMAIN_NAME_LEN 32
|
|
struct iommu_domain {
|
|
unsigned type;
|
|
const struct iommu_ops *ops;
|
|
unsigned long pgsize_bitmap; /* Bitmap of page sizes in use */
|
|
iommu_fault_handler_t handler;
|
|
void *handler_token;
|
|
struct iommu_domain_geometry geometry;
|
|
void *iova_cookie;
|
|
};
|
|
|
|
struct msm_iommu_domain {
|
|
char name[IOMMU_DOMAIN_NAME_LEN];
|
|
bool is_debug_domain;
|
|
struct iommu_domain iommu_domain;
|
|
};
|
|
|
|
enum iommu_cap {
|
|
IOMMU_CAP_CACHE_COHERENCY, /* IOMMU can enforce cache coherent DMA
|
|
transactions */
|
|
IOMMU_CAP_INTR_REMAP, /* IOMMU supports interrupt isolation */
|
|
IOMMU_CAP_NOEXEC, /* IOMMU_NOEXEC flag */
|
|
};
|
|
|
|
/*
|
|
* Following constraints are specifc to FSL_PAMUV1:
|
|
* -aperture must be power of 2, and naturally aligned
|
|
* -number of windows must be power of 2, and address space size
|
|
* of each window is determined by aperture size / # of windows
|
|
* -the actual size of the mapped region of a window must be power
|
|
* of 2 starting with 4KB and physical address must be naturally
|
|
* aligned.
|
|
* DOMAIN_ATTR_FSL_PAMUV1 corresponds to the above mentioned contraints.
|
|
* The caller can invoke iommu_domain_get_attr to check if the underlying
|
|
* iommu implementation supports these constraints.
|
|
*
|
|
* DOMAIN_ATTR_NO_CFRE
|
|
* Some bus implementations may enter a bad state if iommu reports an error
|
|
* on context fault. As context faults are not always fatal, this must be
|
|
* avoided.
|
|
*/
|
|
|
|
enum iommu_attr {
|
|
DOMAIN_ATTR_GEOMETRY,
|
|
DOMAIN_ATTR_PAGING,
|
|
DOMAIN_ATTR_WINDOWS,
|
|
DOMAIN_ATTR_FSL_PAMU_STASH,
|
|
DOMAIN_ATTR_FSL_PAMU_ENABLE,
|
|
DOMAIN_ATTR_FSL_PAMUV1,
|
|
DOMAIN_ATTR_NESTING, /* two stages of translation */
|
|
DOMAIN_ATTR_DMA_USE_FLUSH_QUEUE,
|
|
DOMAIN_ATTR_MAX,
|
|
};
|
|
|
|
#define EXTENDED_ATTR_BASE (DOMAIN_ATTR_MAX + 16)
|
|
|
|
#define DOMAIN_ATTR_PT_BASE_ADDR (EXTENDED_ATTR_BASE + 0)
|
|
#define DOMAIN_ATTR_CONTEXT_BANK (EXTENDED_ATTR_BASE + 1)
|
|
#define DOMAIN_ATTR_DYNAMIC (EXTENDED_ATTR_BASE + 2)
|
|
#define DOMAIN_ATTR_TTBR0 (EXTENDED_ATTR_BASE + 3)
|
|
#define DOMAIN_ATTR_CONTEXTIDR (EXTENDED_ATTR_BASE + 4)
|
|
#define DOMAIN_ATTR_PROCID (EXTENDED_ATTR_BASE + 5)
|
|
#define DOMAIN_ATTR_NON_FATAL_FAULTS (EXTENDED_ATTR_BASE + 6)
|
|
#define DOMAIN_ATTR_S1_BYPASS (EXTENDED_ATTR_BASE + 7)
|
|
#define DOMAIN_ATTR_ATOMIC (EXTENDED_ATTR_BASE + 8)
|
|
#define DOMAIN_ATTR_SECURE_VMID (EXTENDED_ATTR_BASE + 9)
|
|
#define DOMAIN_ATTR_FAST (EXTENDED_ATTR_BASE + 10)
|
|
#define DOMAIN_ATTR_PGTBL_INFO (EXTENDED_ATTR_BASE + 11)
|
|
#define DOMAIN_ATTR_USE_UPSTREAM_HINT (EXTENDED_ATTR_BASE + 12)
|
|
#define DOMAIN_ATTR_EARLY_MAP (EXTENDED_ATTR_BASE + 13)
|
|
#define DOMAIN_ATTR_PAGE_TABLE_IS_COHERENT (EXTENDED_ATTR_BASE + 14)
|
|
#define DOMAIN_ATTR_PAGE_TABLE_FORCE_COHERENT (EXTENDED_ATTR_BASE + 15)
|
|
#define DOMAIN_ATTR_USE_LLC_NWA (EXTENDED_ATTR_BASE + 16)
|
|
#define DOMAIN_ATTR_SPLIT_TABLES (EXTENDED_ATTR_BASE + 17)
|
|
#define DOMAIN_ATTR_FAULT_MODEL_NO_CFRE (EXTENDED_ATTR_BASE + 18)
|
|
#define DOMAIN_ATTR_FAULT_MODEL_NO_STALL (EXTENDED_ATTR_BASE + 19)
|
|
#define DOMAIN_ATTR_FAULT_MODEL_HUPCF (EXTENDED_ATTR_BASE + 20)
|
|
#define DOMAIN_ATTR_EXTENDED_MAX (EXTENDED_ATTR_BASE + 21)
|
|
|
|
/* These are the possible reserved region types */
|
|
enum iommu_resv_type {
|
|
/* Memory regions which must be mapped 1:1 at all times */
|
|
IOMMU_RESV_DIRECT,
|
|
/*
|
|
* Memory regions which are advertised to be 1:1 but are
|
|
* commonly considered relaxable in some conditions,
|
|
* for instance in device assignment use case (USB, Graphics)
|
|
*/
|
|
IOMMU_RESV_DIRECT_RELAXABLE,
|
|
/* Arbitrary "never map this or give it to a device" address ranges */
|
|
IOMMU_RESV_RESERVED,
|
|
/* Hardware MSI region (untranslated) */
|
|
IOMMU_RESV_MSI,
|
|
/* Software-managed MSI translation window */
|
|
IOMMU_RESV_SW_MSI,
|
|
};
|
|
|
|
/**
|
|
* struct iommu_resv_region - descriptor for a reserved memory region
|
|
* @list: Linked list pointers
|
|
* @start: System physical start address of the region
|
|
* @length: Length of the region in bytes
|
|
* @prot: IOMMU Protection flags (READ/WRITE/...)
|
|
* @type: Type of the reserved region
|
|
*/
|
|
struct iommu_resv_region {
|
|
struct list_head list;
|
|
phys_addr_t start;
|
|
size_t length;
|
|
int prot;
|
|
enum iommu_resv_type type;
|
|
};
|
|
|
|
/* Per device IOMMU features */
|
|
enum iommu_dev_features {
|
|
IOMMU_DEV_FEAT_AUX, /* Aux-domain feature */
|
|
IOMMU_DEV_FEAT_SVA, /* Shared Virtual Addresses */
|
|
};
|
|
|
|
#define IOMMU_PASID_INVALID (-1U)
|
|
|
|
/**
|
|
* struct iommu_sva_ops - device driver callbacks for an SVA context
|
|
*
|
|
* @mm_exit: called when the mm is about to be torn down by exit_mmap. After
|
|
* @mm_exit returns, the device must not issue any more transaction
|
|
* with the PASID given as argument.
|
|
*
|
|
* The @mm_exit handler is allowed to sleep. Be careful about the
|
|
* locks taken in @mm_exit, because they might lead to deadlocks if
|
|
* they are also held when dropping references to the mm. Consider the
|
|
* following call chain:
|
|
* mutex_lock(A); mmput(mm) -> exit_mm() -> @mm_exit() -> mutex_lock(A)
|
|
* Using mmput_async() prevents this scenario.
|
|
*
|
|
*/
|
|
struct iommu_sva_ops {
|
|
iommu_mm_exit_handler_t mm_exit;
|
|
};
|
|
|
|
#ifdef CONFIG_IOMMU_API
|
|
|
|
/**
|
|
* struct iommu_iotlb_gather - Range information for a pending IOTLB flush
|
|
*
|
|
* @start: IOVA representing the start of the range to be flushed
|
|
* @end: IOVA representing the end of the range to be flushed (exclusive)
|
|
* @pgsize: The interval at which to perform the flush
|
|
*
|
|
* This structure is intended to be updated by multiple calls to the
|
|
* ->unmap() function in struct iommu_ops before eventually being passed
|
|
* into ->iotlb_sync().
|
|
*/
|
|
struct iommu_iotlb_gather {
|
|
unsigned long start;
|
|
unsigned long end;
|
|
size_t pgsize;
|
|
};
|
|
|
|
/**
|
|
* struct iommu_ops - iommu ops and capabilities
|
|
* @capable: check capability
|
|
* @domain_alloc: allocate iommu domain
|
|
* @domain_free: free iommu domain
|
|
* @attach_dev: attach device to an iommu domain
|
|
* @detach_dev: detach device from an iommu domain
|
|
* @map: map a physically contiguous memory region to an iommu domain
|
|
* @unmap: unmap a physically contiguous memory region from an iommu domain
|
|
* @flush_iotlb_all: Synchronously flush all hardware TLBs for this domain
|
|
* @iotlb_sync_map: Sync mappings created recently using @map to the hardware
|
|
* @iotlb_sync: Flush all queued ranges from the hardware TLBs and empty flush
|
|
* queue
|
|
* @iova_to_phys: translate iova to physical address
|
|
* @add_device: add device to iommu grouping
|
|
* @remove_device: remove device from iommu grouping
|
|
* @device_group: find iommu group for a particular device
|
|
* @domain_get_attr: Query domain attributes
|
|
* @domain_set_attr: Change domain attributes
|
|
* @get_resv_regions: Request list of reserved regions for a device
|
|
* @put_resv_regions: Free list of reserved regions for a device
|
|
* @apply_resv_region: Temporary helper call-back for iova reserved ranges
|
|
* @domain_window_enable: Configure and enable a particular window for a domain
|
|
* @domain_window_disable: Disable a particular window for a domain
|
|
* @of_xlate: add OF master IDs to iommu grouping
|
|
* @is_attach_deferred: Check if domain attach should be deferred from iommu
|
|
* driver init to device driver init (default no)
|
|
* @dev_has/enable/disable_feat: per device entries to check/enable/disable
|
|
* iommu specific features.
|
|
* @dev_feat_enabled: check enabled feature
|
|
* @aux_attach/detach_dev: aux-domain specific attach/detach entries.
|
|
* @aux_get_pasid: get the pasid given an aux-domain
|
|
* @sva_bind: Bind process address space to device
|
|
* @sva_unbind: Unbind process address space from device
|
|
* @sva_get_pasid: Get PASID associated to a SVA handle
|
|
* @page_response: handle page request response
|
|
* @pgsize_bitmap: bitmap of all possible supported page sizes
|
|
* @owner: Driver module providing these ops
|
|
*/
|
|
struct iommu_ops {
|
|
bool (*capable)(enum iommu_cap);
|
|
|
|
/* Domain allocation and freeing by the iommu driver */
|
|
struct iommu_domain *(*domain_alloc)(unsigned iommu_domain_type);
|
|
void (*domain_free)(struct iommu_domain *);
|
|
|
|
int (*attach_dev)(struct iommu_domain *domain, struct device *dev);
|
|
void (*detach_dev)(struct iommu_domain *domain, struct device *dev);
|
|
int (*map)(struct iommu_domain *domain, unsigned long iova,
|
|
phys_addr_t paddr, size_t size, int prot);
|
|
size_t (*unmap)(struct iommu_domain *domain, unsigned long iova,
|
|
size_t size, struct iommu_iotlb_gather *iotlb_gather);
|
|
void (*flush_iotlb_all)(struct iommu_domain *domain);
|
|
void (*iotlb_sync_map)(struct iommu_domain *domain);
|
|
void (*iotlb_sync)(struct iommu_domain *domain,
|
|
struct iommu_iotlb_gather *iotlb_gather);
|
|
phys_addr_t (*iova_to_phys)(struct iommu_domain *domain, dma_addr_t iova);
|
|
int (*add_device)(struct device *dev);
|
|
void (*remove_device)(struct device *dev);
|
|
struct iommu_group *(*device_group)(struct device *dev);
|
|
int (*domain_get_attr)(struct iommu_domain *domain,
|
|
enum iommu_attr attr, void *data);
|
|
int (*domain_set_attr)(struct iommu_domain *domain,
|
|
enum iommu_attr attr, void *data);
|
|
|
|
/* Request/Free a list of reserved regions for a device */
|
|
void (*get_resv_regions)(struct device *dev, struct list_head *list);
|
|
void (*put_resv_regions)(struct device *dev, struct list_head *list);
|
|
void (*apply_resv_region)(struct device *dev,
|
|
struct iommu_domain *domain,
|
|
struct iommu_resv_region *region);
|
|
|
|
/* Window handling functions */
|
|
int (*domain_window_enable)(struct iommu_domain *domain, u32 wnd_nr,
|
|
phys_addr_t paddr, u64 size, int prot);
|
|
void (*domain_window_disable)(struct iommu_domain *domain, u32 wnd_nr);
|
|
|
|
int (*of_xlate)(struct device *dev, struct of_phandle_args *args);
|
|
bool (*is_attach_deferred)(struct iommu_domain *domain, struct device *dev);
|
|
|
|
/* Per device IOMMU features */
|
|
bool (*dev_has_feat)(struct device *dev, enum iommu_dev_features f);
|
|
bool (*dev_feat_enabled)(struct device *dev, enum iommu_dev_features f);
|
|
int (*dev_enable_feat)(struct device *dev, enum iommu_dev_features f);
|
|
int (*dev_disable_feat)(struct device *dev, enum iommu_dev_features f);
|
|
|
|
/* Aux-domain specific attach/detach entries */
|
|
int (*aux_attach_dev)(struct iommu_domain *domain, struct device *dev);
|
|
void (*aux_detach_dev)(struct iommu_domain *domain, struct device *dev);
|
|
int (*aux_get_pasid)(struct iommu_domain *domain, struct device *dev);
|
|
|
|
struct iommu_sva *(*sva_bind)(struct device *dev, struct mm_struct *mm,
|
|
void *drvdata);
|
|
void (*sva_unbind)(struct iommu_sva *handle);
|
|
int (*sva_get_pasid)(struct iommu_sva *handle);
|
|
|
|
int (*page_response)(struct device *dev,
|
|
struct iommu_fault_event *evt,
|
|
struct iommu_page_response *msg);
|
|
|
|
unsigned long pgsize_bitmap;
|
|
struct module *owner;
|
|
};
|
|
|
|
/**
|
|
* struct msm_iommu_ops - standard iommu ops, as well as additional MSM
|
|
* specific iommu ops
|
|
* @map_sg: map a scatter-gather list of physically contiguous memory chunks
|
|
* to an iommu domain
|
|
* @iova_to_phys_hard: translate iova to physical address using IOMMU hardware
|
|
* @is_iova_coherent: checks coherency of the given iova
|
|
* @tlbi_domain: Invalidate all TLBs covering an iommu domain
|
|
* @iova_to_pte: translate iova to Page Table Entry (PTE).
|
|
* @iommu_ops: the standard iommu ops
|
|
*/
|
|
struct msm_iommu_ops {
|
|
size_t (*map_sg)(struct iommu_domain *domain, unsigned long iova,
|
|
struct scatterlist *sg, unsigned int nents, int prot);
|
|
phys_addr_t (*iova_to_phys_hard)(struct iommu_domain *domain,
|
|
dma_addr_t iova,
|
|
unsigned long trans_flags);
|
|
bool (*is_iova_coherent)(struct iommu_domain *domain, dma_addr_t iova);
|
|
void (*tlbi_domain)(struct iommu_domain *domain);
|
|
uint64_t (*iova_to_pte)(struct iommu_domain *domain, dma_addr_t iova);
|
|
struct iommu_ops iommu_ops;
|
|
};
|
|
|
|
/**
|
|
* struct iommu_device - IOMMU core representation of one IOMMU hardware
|
|
* instance
|
|
* @list: Used by the iommu-core to keep a list of registered iommus
|
|
* @ops: iommu-ops for talking to this iommu
|
|
* @dev: struct device for sysfs handling
|
|
*/
|
|
struct iommu_device {
|
|
struct list_head list;
|
|
const struct iommu_ops *ops;
|
|
struct fwnode_handle *fwnode;
|
|
struct device *dev;
|
|
};
|
|
|
|
/**
|
|
* struct iommu_fault_event - Generic fault event
|
|
*
|
|
* Can represent recoverable faults such as a page requests or
|
|
* unrecoverable faults such as DMA or IRQ remapping faults.
|
|
*
|
|
* @fault: fault descriptor
|
|
* @list: pending fault event list, used for tracking responses
|
|
*/
|
|
struct iommu_fault_event {
|
|
struct iommu_fault fault;
|
|
struct list_head list;
|
|
};
|
|
|
|
/**
|
|
* struct iommu_fault_param - per-device IOMMU fault data
|
|
* @handler: Callback function to handle IOMMU faults at device level
|
|
* @data: handler private data
|
|
* @faults: holds the pending faults which needs response
|
|
* @lock: protect pending faults list
|
|
*/
|
|
struct iommu_fault_param {
|
|
iommu_dev_fault_handler_t handler;
|
|
void *data;
|
|
struct list_head faults;
|
|
struct mutex lock;
|
|
};
|
|
|
|
/**
|
|
* struct iommu_param - collection of per-device IOMMU data
|
|
*
|
|
* @fault_param: IOMMU detected device fault reporting data
|
|
*
|
|
* TODO: migrate other per device data pointers under iommu_dev_data, e.g.
|
|
* struct iommu_group *iommu_group;
|
|
* struct iommu_fwspec *iommu_fwspec;
|
|
*/
|
|
struct iommu_param {
|
|
struct mutex lock;
|
|
struct iommu_fault_param *fault_param;
|
|
};
|
|
|
|
int iommu_device_register(struct iommu_device *iommu);
|
|
void iommu_device_unregister(struct iommu_device *iommu);
|
|
int iommu_device_sysfs_add(struct iommu_device *iommu,
|
|
struct device *parent,
|
|
const struct attribute_group **groups,
|
|
const char *fmt, ...) __printf(4, 5);
|
|
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);
|
|
|
|
static inline void __iommu_device_set_ops(struct iommu_device *iommu,
|
|
const struct iommu_ops *ops)
|
|
{
|
|
iommu->ops = ops;
|
|
}
|
|
|
|
#define iommu_device_set_ops(iommu, ops) \
|
|
do { \
|
|
struct iommu_ops *__ops = (struct iommu_ops *)(ops); \
|
|
__ops->owner = THIS_MODULE; \
|
|
__iommu_device_set_ops(iommu, __ops); \
|
|
} while (0)
|
|
|
|
static inline void iommu_device_set_fwnode(struct iommu_device *iommu,
|
|
struct fwnode_handle *fwnode)
|
|
{
|
|
iommu->fwnode = fwnode;
|
|
}
|
|
|
|
static inline struct iommu_device *dev_to_iommu_device(struct device *dev)
|
|
{
|
|
return (struct iommu_device *)dev_get_drvdata(dev);
|
|
}
|
|
|
|
static inline void iommu_iotlb_gather_init(struct iommu_iotlb_gather *gather)
|
|
{
|
|
*gather = (struct iommu_iotlb_gather) {
|
|
.start = ULONG_MAX,
|
|
};
|
|
}
|
|
|
|
#define IOMMU_GROUP_NOTIFY_ADD_DEVICE 1 /* Device added */
|
|
#define IOMMU_GROUP_NOTIFY_DEL_DEVICE 2 /* Pre Device removed */
|
|
#define IOMMU_GROUP_NOTIFY_BIND_DRIVER 3 /* Pre Driver bind */
|
|
#define IOMMU_GROUP_NOTIFY_BOUND_DRIVER 4 /* Post Driver bind */
|
|
#define IOMMU_GROUP_NOTIFY_UNBIND_DRIVER 5 /* Pre Driver unbind */
|
|
#define IOMMU_GROUP_NOTIFY_UNBOUND_DRIVER 6 /* Post Driver unbind */
|
|
|
|
extern int bus_set_iommu(struct bus_type *bus, const struct iommu_ops *ops);
|
|
extern bool iommu_present(struct bus_type *bus);
|
|
extern bool iommu_capable(struct bus_type *bus, enum iommu_cap cap);
|
|
extern struct iommu_domain *iommu_domain_alloc(struct bus_type *bus);
|
|
extern struct iommu_group *iommu_group_get_by_id(int id);
|
|
extern void iommu_domain_free(struct iommu_domain *domain);
|
|
extern int iommu_attach_device(struct iommu_domain *domain,
|
|
struct device *dev);
|
|
extern void iommu_detach_device(struct iommu_domain *domain,
|
|
struct device *dev);
|
|
extern struct iommu_domain *iommu_get_domain_for_dev(struct device *dev);
|
|
extern size_t iommu_pgsize(unsigned long pgsize_bitmap,
|
|
unsigned long addr_merge, size_t size);
|
|
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);
|
|
extern size_t iommu_unmap(struct iommu_domain *domain, unsigned long iova,
|
|
size_t size);
|
|
extern size_t iommu_unmap_fast(struct iommu_domain *domain,
|
|
unsigned long iova, size_t size,
|
|
struct iommu_iotlb_gather *iotlb_gather);
|
|
extern size_t iommu_map_sg(struct iommu_domain *domain, unsigned long iova,
|
|
struct scatterlist *sg,unsigned int nents, int prot);
|
|
extern size_t default_iommu_map_sg(struct iommu_domain *domain,
|
|
unsigned long iova, struct scatterlist *sg,
|
|
unsigned int nents, int prot);
|
|
extern phys_addr_t iommu_iova_to_phys(struct iommu_domain *domain, dma_addr_t iova);
|
|
extern phys_addr_t iommu_iova_to_phys_hard(struct iommu_domain *domain,
|
|
dma_addr_t iova, unsigned long trans_flags);
|
|
extern bool iommu_is_iova_coherent(struct iommu_domain *domain,
|
|
dma_addr_t iova);
|
|
extern void iommu_set_fault_handler(struct iommu_domain *domain,
|
|
iommu_fault_handler_t handler, void *token);
|
|
extern int iommu_get_fault_ids(struct iommu_domain *domain,
|
|
struct iommu_fault_ids *f_ids);
|
|
extern void iommu_get_resv_regions(struct device *dev, struct list_head *list);
|
|
extern void iommu_put_resv_regions(struct device *dev, struct list_head *list);
|
|
extern int iommu_request_dm_for_dev(struct device *dev);
|
|
extern int iommu_request_dma_domain_for_dev(struct device *dev);
|
|
extern void iommu_set_default_passthrough(bool cmd_line);
|
|
extern void iommu_set_default_translated(bool cmd_line);
|
|
extern bool iommu_default_passthrough(void);
|
|
extern struct iommu_resv_region *
|
|
iommu_alloc_resv_region(phys_addr_t start, size_t length, int prot,
|
|
enum iommu_resv_type type);
|
|
extern int iommu_get_group_resv_regions(struct iommu_group *group,
|
|
struct list_head *head);
|
|
|
|
extern int iommu_attach_group(struct iommu_domain *domain,
|
|
struct iommu_group *group);
|
|
extern void iommu_detach_group(struct iommu_domain *domain,
|
|
struct iommu_group *group);
|
|
extern struct iommu_group *iommu_group_alloc(void);
|
|
extern void *iommu_group_get_iommudata(struct iommu_group *group);
|
|
extern void iommu_group_set_iommudata(struct iommu_group *group,
|
|
void *iommu_data,
|
|
void (*release)(void *iommu_data));
|
|
extern int iommu_group_set_name(struct iommu_group *group, const char *name);
|
|
extern int iommu_group_add_device(struct iommu_group *group,
|
|
struct device *dev);
|
|
extern void iommu_group_remove_device(struct device *dev);
|
|
extern int iommu_group_for_each_dev(struct iommu_group *group, void *data,
|
|
int (*fn)(struct device *, void *));
|
|
extern struct iommu_group *iommu_group_get(struct device *dev);
|
|
extern struct iommu_group *iommu_group_ref_get(struct iommu_group *group);
|
|
extern void iommu_group_put(struct iommu_group *group);
|
|
extern int iommu_group_register_notifier(struct iommu_group *group,
|
|
struct notifier_block *nb);
|
|
extern int iommu_group_unregister_notifier(struct iommu_group *group,
|
|
struct notifier_block *nb);
|
|
extern int iommu_register_device_fault_handler(struct device *dev,
|
|
iommu_dev_fault_handler_t handler,
|
|
void *data);
|
|
|
|
extern int iommu_unregister_device_fault_handler(struct device *dev);
|
|
|
|
extern int iommu_report_device_fault(struct device *dev,
|
|
struct iommu_fault_event *evt);
|
|
extern int iommu_page_response(struct device *dev,
|
|
struct iommu_page_response *msg);
|
|
|
|
extern int iommu_group_id(struct iommu_group *group);
|
|
extern struct iommu_group *iommu_group_get_for_dev(struct device *dev);
|
|
extern struct iommu_domain *iommu_group_default_domain(struct iommu_group *);
|
|
|
|
extern int iommu_domain_get_attr(struct iommu_domain *domain, enum iommu_attr,
|
|
void *data);
|
|
extern int iommu_domain_set_attr(struct iommu_domain *domain, enum iommu_attr,
|
|
void *data);
|
|
|
|
/* Window handling function prototypes */
|
|
extern int iommu_domain_window_enable(struct iommu_domain *domain, u32 wnd_nr,
|
|
phys_addr_t offset, u64 size,
|
|
int prot);
|
|
extern void iommu_domain_window_disable(struct iommu_domain *domain, u32 wnd_nr);
|
|
|
|
extern uint64_t iommu_iova_to_pte(struct iommu_domain *domain,
|
|
dma_addr_t iova);
|
|
|
|
extern int report_iommu_fault(struct iommu_domain *domain, struct device *dev,
|
|
unsigned long iova, int flags);
|
|
|
|
static inline void iommu_flush_tlb_all(struct iommu_domain *domain)
|
|
{
|
|
if (domain->ops->flush_iotlb_all)
|
|
domain->ops->flush_iotlb_all(domain);
|
|
}
|
|
|
|
static inline void iommu_tlb_sync(struct iommu_domain *domain,
|
|
struct iommu_iotlb_gather *iotlb_gather)
|
|
{
|
|
if (domain->ops->iotlb_sync)
|
|
domain->ops->iotlb_sync(domain, iotlb_gather);
|
|
|
|
iommu_iotlb_gather_init(iotlb_gather);
|
|
}
|
|
|
|
static inline void iommu_iotlb_gather_add_page(struct iommu_domain *domain,
|
|
struct iommu_iotlb_gather *gather,
|
|
unsigned long iova, size_t size)
|
|
{
|
|
unsigned long start = iova, end = start + size;
|
|
|
|
/*
|
|
* If the new page is disjoint from the current range or is mapped at
|
|
* a different granularity, then sync the TLB so that the gather
|
|
* structure can be rewritten.
|
|
*/
|
|
if (gather->pgsize != size ||
|
|
end < gather->start || start > gather->end) {
|
|
if (gather->pgsize)
|
|
iommu_tlb_sync(domain, gather);
|
|
gather->pgsize = size;
|
|
}
|
|
|
|
if (gather->end < end)
|
|
gather->end = end;
|
|
|
|
if (gather->start > start)
|
|
gather->start = start;
|
|
}
|
|
|
|
/* PCI device grouping function */
|
|
extern struct iommu_group *pci_device_group(struct device *dev);
|
|
/* Generic device grouping function */
|
|
extern struct iommu_group *generic_device_group(struct device *dev);
|
|
/* FSL-MC device grouping function */
|
|
struct iommu_group *fsl_mc_device_group(struct device *dev);
|
|
|
|
static inline void iommu_tlbiall(struct iommu_domain *domain)
|
|
{
|
|
struct msm_iommu_ops *ops = to_msm_iommu_ops(domain->ops);
|
|
|
|
if (ops->tlbi_domain)
|
|
ops->tlbi_domain(domain);
|
|
}
|
|
|
|
/**
|
|
* struct iommu_fwspec - per-device IOMMU instance data
|
|
* @ops: ops for this device's IOMMU
|
|
* @iommu_fwnode: firmware handle for this device's IOMMU
|
|
* @iommu_priv: IOMMU driver private data for this device
|
|
* @num_ids: number of associated device IDs
|
|
* @ids: IDs which this device may present to the IOMMU
|
|
*/
|
|
struct iommu_fwspec {
|
|
const struct iommu_ops *ops;
|
|
struct fwnode_handle *iommu_fwnode;
|
|
void *iommu_priv;
|
|
u32 flags;
|
|
unsigned int num_ids;
|
|
u32 ids[1];
|
|
};
|
|
|
|
/* ATS is supported */
|
|
#define IOMMU_FWSPEC_PCI_RC_ATS (1 << 0)
|
|
|
|
/**
|
|
* struct iommu_sva - handle to a device-mm bond
|
|
*/
|
|
struct iommu_sva {
|
|
struct device *dev;
|
|
const struct iommu_sva_ops *ops;
|
|
};
|
|
|
|
int iommu_fwspec_init(struct device *dev, struct fwnode_handle *iommu_fwnode,
|
|
const struct iommu_ops *ops);
|
|
void iommu_fwspec_free(struct device *dev);
|
|
int iommu_fwspec_add_ids(struct device *dev, u32 *ids, int num_ids);
|
|
const struct iommu_ops *iommu_ops_from_fwnode(struct fwnode_handle *fwnode);
|
|
|
|
static inline struct iommu_fwspec *dev_iommu_fwspec_get(struct device *dev)
|
|
{
|
|
return dev->iommu_fwspec;
|
|
}
|
|
|
|
static inline void dev_iommu_fwspec_set(struct device *dev,
|
|
struct iommu_fwspec *fwspec)
|
|
{
|
|
dev->iommu_fwspec = fwspec;
|
|
}
|
|
|
|
int iommu_probe_device(struct device *dev);
|
|
void iommu_release_device(struct device *dev);
|
|
|
|
bool iommu_dev_has_feature(struct device *dev, enum iommu_dev_features f);
|
|
int iommu_dev_enable_feature(struct device *dev, enum iommu_dev_features f);
|
|
int iommu_dev_disable_feature(struct device *dev, enum iommu_dev_features f);
|
|
bool iommu_dev_feature_enabled(struct device *dev, enum iommu_dev_features f);
|
|
int iommu_aux_attach_device(struct iommu_domain *domain, struct device *dev);
|
|
void iommu_aux_detach_device(struct iommu_domain *domain, struct device *dev);
|
|
int iommu_aux_get_pasid(struct iommu_domain *domain, struct device *dev);
|
|
|
|
struct iommu_sva *iommu_sva_bind_device(struct device *dev,
|
|
struct mm_struct *mm,
|
|
void *drvdata);
|
|
void iommu_sva_unbind_device(struct iommu_sva *handle);
|
|
int iommu_sva_set_ops(struct iommu_sva *handle,
|
|
const struct iommu_sva_ops *ops);
|
|
int iommu_sva_get_pasid(struct iommu_sva *handle);
|
|
|
|
#else /* CONFIG_IOMMU_API */
|
|
|
|
struct iommu_ops {};
|
|
struct iommu_group {};
|
|
struct iommu_fwspec {};
|
|
struct iommu_device {};
|
|
struct iommu_fault_param {};
|
|
struct iommu_iotlb_gather {};
|
|
|
|
static inline bool iommu_present(struct bus_type *bus)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
static inline bool iommu_capable(struct bus_type *bus, enum iommu_cap cap)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
static inline struct iommu_domain *iommu_domain_alloc(struct bus_type *bus)
|
|
{
|
|
return NULL;
|
|
}
|
|
|
|
static inline struct iommu_group *iommu_group_get_by_id(int id)
|
|
{
|
|
return NULL;
|
|
}
|
|
|
|
static inline void iommu_domain_free(struct iommu_domain *domain)
|
|
{
|
|
}
|
|
|
|
static inline int iommu_attach_device(struct iommu_domain *domain,
|
|
struct device *dev)
|
|
{
|
|
return -ENODEV;
|
|
}
|
|
|
|
static inline void iommu_detach_device(struct iommu_domain *domain,
|
|
struct device *dev)
|
|
{
|
|
}
|
|
|
|
static inline struct iommu_domain *iommu_get_domain_for_dev(struct device *dev)
|
|
{
|
|
return NULL;
|
|
}
|
|
|
|
static inline int iommu_map(struct iommu_domain *domain, unsigned long iova,
|
|
phys_addr_t paddr, size_t size, int prot)
|
|
{
|
|
return -ENODEV;
|
|
}
|
|
|
|
static inline size_t iommu_unmap(struct iommu_domain *domain,
|
|
unsigned long iova, size_t size)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
static inline size_t iommu_unmap_fast(struct iommu_domain *domain,
|
|
unsigned long iova, int gfp_order,
|
|
struct iommu_iotlb_gather *iotlb_gather)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
static inline size_t iommu_map_sg(struct iommu_domain *domain,
|
|
unsigned long iova, struct scatterlist *sg,
|
|
unsigned int nents, int prot)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
static inline void iommu_flush_tlb_all(struct iommu_domain *domain)
|
|
{
|
|
}
|
|
|
|
static inline void iommu_tlb_sync(struct iommu_domain *domain,
|
|
struct iommu_iotlb_gather *iotlb_gather)
|
|
{
|
|
}
|
|
|
|
static inline int iommu_domain_window_enable(struct iommu_domain *domain,
|
|
u32 wnd_nr, phys_addr_t paddr,
|
|
u64 size, int prot)
|
|
{
|
|
return -ENODEV;
|
|
}
|
|
|
|
static inline void iommu_domain_window_disable(struct iommu_domain *domain,
|
|
u32 wnd_nr)
|
|
{
|
|
}
|
|
|
|
static inline phys_addr_t iommu_iova_to_phys(struct iommu_domain *domain, dma_addr_t iova)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
static inline phys_addr_t iommu_iova_to_phys_hard(struct iommu_domain *domain,
|
|
dma_addr_t iova, unsigned long trans_flags)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
static inline bool iommu_is_iova_coherent(struct iommu_domain *domain,
|
|
dma_addr_t iova)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
static inline void iommu_set_fault_handler(struct iommu_domain *domain,
|
|
iommu_fault_handler_t handler, void *token)
|
|
{
|
|
}
|
|
static inline int iommu_get_fault_ids(struct iommu_domain *domain,
|
|
struct iommu_fault_ids *f_ids)
|
|
{
|
|
return -EINVAL;
|
|
}
|
|
|
|
static inline void iommu_get_resv_regions(struct device *dev,
|
|
struct list_head *list)
|
|
{
|
|
}
|
|
static inline void iommu_put_resv_regions(struct device *dev,
|
|
struct list_head *list)
|
|
{
|
|
}
|
|
|
|
static inline int iommu_get_group_resv_regions(struct iommu_group *group,
|
|
struct list_head *head)
|
|
{
|
|
return -ENODEV;
|
|
}
|
|
|
|
static inline int iommu_request_dm_for_dev(struct device *dev)
|
|
{
|
|
return -ENODEV;
|
|
}
|
|
|
|
static inline int iommu_request_dma_domain_for_dev(struct device *dev)
|
|
{
|
|
return -ENODEV;
|
|
}
|
|
|
|
static inline void iommu_set_default_passthrough(bool cmd_line)
|
|
{
|
|
}
|
|
|
|
static inline void iommu_set_default_translated(bool cmd_line)
|
|
{
|
|
}
|
|
|
|
static inline bool iommu_default_passthrough(void)
|
|
{
|
|
return true;
|
|
}
|
|
|
|
static inline int iommu_attach_group(struct iommu_domain *domain,
|
|
struct iommu_group *group)
|
|
{
|
|
return -ENODEV;
|
|
}
|
|
|
|
static inline void iommu_detach_group(struct iommu_domain *domain,
|
|
struct iommu_group *group)
|
|
{
|
|
}
|
|
|
|
static inline struct iommu_group *iommu_group_alloc(void)
|
|
{
|
|
return ERR_PTR(-ENODEV);
|
|
}
|
|
|
|
static inline void *iommu_group_get_iommudata(struct iommu_group *group)
|
|
{
|
|
return NULL;
|
|
}
|
|
|
|
static inline void iommu_group_set_iommudata(struct iommu_group *group,
|
|
void *iommu_data,
|
|
void (*release)(void *iommu_data))
|
|
{
|
|
}
|
|
|
|
static inline int iommu_group_set_name(struct iommu_group *group,
|
|
const char *name)
|
|
{
|
|
return -ENODEV;
|
|
}
|
|
|
|
static inline int iommu_group_add_device(struct iommu_group *group,
|
|
struct device *dev)
|
|
{
|
|
return -ENODEV;
|
|
}
|
|
|
|
static inline void iommu_group_remove_device(struct device *dev)
|
|
{
|
|
}
|
|
|
|
static inline int iommu_group_for_each_dev(struct iommu_group *group,
|
|
void *data,
|
|
int (*fn)(struct device *, void *))
|
|
{
|
|
return -ENODEV;
|
|
}
|
|
|
|
static inline struct iommu_group *iommu_group_get(struct device *dev)
|
|
{
|
|
return NULL;
|
|
}
|
|
|
|
static inline void iommu_group_put(struct iommu_group *group)
|
|
{
|
|
}
|
|
|
|
static inline int iommu_group_register_notifier(struct iommu_group *group,
|
|
struct notifier_block *nb)
|
|
{
|
|
return -ENODEV;
|
|
}
|
|
|
|
static inline int iommu_group_unregister_notifier(struct iommu_group *group,
|
|
struct notifier_block *nb)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
static inline
|
|
int iommu_register_device_fault_handler(struct device *dev,
|
|
iommu_dev_fault_handler_t handler,
|
|
void *data)
|
|
{
|
|
return -ENODEV;
|
|
}
|
|
|
|
static inline int iommu_unregister_device_fault_handler(struct device *dev)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
static inline
|
|
int iommu_report_device_fault(struct device *dev, struct iommu_fault_event *evt)
|
|
{
|
|
return -ENODEV;
|
|
}
|
|
|
|
static inline int iommu_page_response(struct device *dev,
|
|
struct iommu_page_response *msg)
|
|
{
|
|
return -ENODEV;
|
|
}
|
|
|
|
static inline int iommu_group_id(struct iommu_group *group)
|
|
{
|
|
return -ENODEV;
|
|
}
|
|
|
|
static inline int iommu_domain_get_attr(struct iommu_domain *domain,
|
|
enum iommu_attr attr, void *data)
|
|
{
|
|
return -EINVAL;
|
|
}
|
|
|
|
static inline int iommu_domain_set_attr(struct iommu_domain *domain,
|
|
enum iommu_attr attr, void *data)
|
|
{
|
|
return -EINVAL;
|
|
}
|
|
|
|
static inline int iommu_device_register(struct iommu_device *iommu)
|
|
{
|
|
return -ENODEV;
|
|
}
|
|
|
|
static inline void iommu_device_set_ops(struct iommu_device *iommu,
|
|
const struct iommu_ops *ops)
|
|
{
|
|
}
|
|
|
|
static inline void iommu_device_set_fwnode(struct iommu_device *iommu,
|
|
struct fwnode_handle *fwnode)
|
|
{
|
|
}
|
|
|
|
static inline struct iommu_device *dev_to_iommu_device(struct device *dev)
|
|
{
|
|
return NULL;
|
|
}
|
|
|
|
static inline void iommu_iotlb_gather_init(struct iommu_iotlb_gather *gather)
|
|
{
|
|
}
|
|
|
|
static inline void iommu_iotlb_gather_add_page(struct iommu_domain *domain,
|
|
struct iommu_iotlb_gather *gather,
|
|
unsigned long iova, size_t size)
|
|
{
|
|
}
|
|
|
|
static inline void iommu_device_unregister(struct iommu_device *iommu)
|
|
{
|
|
}
|
|
|
|
static inline int iommu_device_sysfs_add(struct iommu_device *iommu,
|
|
struct device *parent,
|
|
const struct attribute_group **groups,
|
|
const char *fmt, ...)
|
|
{
|
|
return -ENODEV;
|
|
}
|
|
|
|
static inline void iommu_device_sysfs_remove(struct iommu_device *iommu)
|
|
{
|
|
}
|
|
|
|
static inline int iommu_device_link(struct device *dev, struct device *link)
|
|
{
|
|
return -EINVAL;
|
|
}
|
|
|
|
static inline void iommu_device_unlink(struct device *dev, struct device *link)
|
|
{
|
|
}
|
|
|
|
static inline void iommu_tlbiall(struct iommu_domain *domain)
|
|
{
|
|
}
|
|
|
|
static inline int iommu_fwspec_init(struct device *dev,
|
|
struct fwnode_handle *iommu_fwnode,
|
|
const struct iommu_ops *ops)
|
|
{
|
|
return -ENODEV;
|
|
}
|
|
|
|
static inline void iommu_fwspec_free(struct device *dev)
|
|
{
|
|
}
|
|
|
|
static inline int iommu_fwspec_add_ids(struct device *dev, u32 *ids,
|
|
int num_ids)
|
|
{
|
|
return -ENODEV;
|
|
}
|
|
|
|
static inline
|
|
const struct iommu_ops *iommu_ops_from_fwnode(struct fwnode_handle *fwnode)
|
|
{
|
|
return NULL;
|
|
}
|
|
|
|
static inline bool
|
|
iommu_dev_has_feature(struct device *dev, enum iommu_dev_features feat)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
static inline bool
|
|
iommu_dev_feature_enabled(struct device *dev, enum iommu_dev_features feat)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
static inline int
|
|
iommu_dev_enable_feature(struct device *dev, enum iommu_dev_features feat)
|
|
{
|
|
return -ENODEV;
|
|
}
|
|
|
|
static inline int
|
|
iommu_dev_disable_feature(struct device *dev, enum iommu_dev_features feat)
|
|
{
|
|
return -ENODEV;
|
|
}
|
|
|
|
static inline int
|
|
iommu_aux_attach_device(struct iommu_domain *domain, struct device *dev)
|
|
{
|
|
return -ENODEV;
|
|
}
|
|
|
|
static inline void
|
|
iommu_aux_detach_device(struct iommu_domain *domain, struct device *dev)
|
|
{
|
|
}
|
|
|
|
static inline int
|
|
iommu_aux_get_pasid(struct iommu_domain *domain, struct device *dev)
|
|
{
|
|
return -ENODEV;
|
|
}
|
|
|
|
static inline struct iommu_sva *
|
|
iommu_sva_bind_device(struct device *dev, struct mm_struct *mm, void *drvdata)
|
|
{
|
|
return ERR_PTR(-ENODEV);
|
|
}
|
|
|
|
static inline void iommu_sva_unbind_device(struct iommu_sva *handle)
|
|
{
|
|
}
|
|
|
|
static inline int iommu_sva_set_ops(struct iommu_sva *handle,
|
|
const struct iommu_sva_ops *ops)
|
|
{
|
|
return -EINVAL;
|
|
}
|
|
|
|
static inline int iommu_sva_get_pasid(struct iommu_sva *handle)
|
|
{
|
|
return IOMMU_PASID_INVALID;
|
|
}
|
|
|
|
#endif /* CONFIG_IOMMU_API */
|
|
|
|
#ifdef CONFIG_IOMMU_DEBUGFS
|
|
extern struct dentry *iommu_debugfs_dir;
|
|
void iommu_debugfs_setup(void);
|
|
#else
|
|
static inline void iommu_debugfs_setup(void) {}
|
|
#endif
|
|
|
|
#endif /* __LINUX_IOMMU_H */
|