# Copyright 2022 syzkaller project authors. All rights reserved.
# Use of this source code is governed by Apache 2 LICENSE that can be found in the LICENSE file.

# https://elixir.bootlin.com/linux/latest/source/include/uapi/linux/iommufd.h
# https://elixir.bootlin.com/linux/latest/source/drivers/iommu/iommufd/main.c

include <uapi/linux/fcntl.h>
include <uapi/linux/iommufd.h>
include <uapi/linux/vfio.h>

resource fd_iommufd[fd]
resource ioas_handle[int32]

openat$iommufd(fd const[AT_FDCWD], file ptr[in, string["/dev/iommu"]], flags flags[open_flags], mode const[0]) fd_iommufd

ioctl$IOMMU_DESTROY$ioas(fd fd_iommufd, cmd const[IOMMU_DESTROY], arg ptr[in, iommu_destroy$ioas])

ioctl$IOMMU_IOAS_ALLOC(fd fd_iommufd, cmd const[IOMMU_IOAS_ALLOC], arg ptr[in, iommu_ioas_alloc])
ioctl$IOMMU_IOAS_IOVA_RANGES(fd fd_iommufd, cmd const[IOMMU_IOAS_IOVA_RANGES], arg ptr[in, iommu_ioas_iova_ranges])
ioctl$IOMMU_IOAS_ALLOW_IOVAS(fd fd_iommufd, cmd const[IOMMU_IOAS_ALLOW_IOVAS], arg ptr[in, iommu_ioas_allow_iovas])
ioctl$IOMMU_IOAS_MAP(fd fd_iommufd, cmd const[IOMMU_IOAS_MAP], arg ptr[in, iommu_ioas_map])
ioctl$IOMMU_IOAS_MAP$PAGES(fd fd_iommufd, cmd const[IOMMU_IOAS_MAP], arg ptr[in, iommu_ioas_map$PAGES])
ioctl$IOMMU_IOAS_COPY(fd fd_iommufd, cmd const[IOMMU_IOAS_COPY], arg ptr[in, iommu_ioas_copy])
ioctl$IOMMU_IOAS_COPY$syz(fd fd_iommufd, cmd const[IOMMU_IOAS_COPY], arg ptr[in, iommu_ioas_copy$syz])
ioctl$IOMMU_IOAS_UNMAP(fd fd_iommufd, cmd const[IOMMU_IOAS_UNMAP], arg ptr[in, iommu_ioas_unmap])
ioctl$IOMMU_IOAS_UNMAP$ALL(fd fd_iommufd, cmd const[IOMMU_IOAS_UNMAP], arg ptr[in, iommu_ioas_unmap$ALL])

ioctl$IOMMU_OPTION$IOMMU_OPTION_RLIMIT_MODE(fd fd_iommufd, cmd const[IOMMU_OPTION], arg ptr[in, iommu_option$IOMMU_OPTION_RLIMIT_MODE])
ioctl$IOMMU_OPTION$IOMMU_OPTION_HUGE_PAGES(fd fd_iommufd, cmd const[IOMMU_OPTION], arg ptr[in, iommu_option$IOMMU_OPTION_HUGE_PAGES])

ioctl$IOMMU_VFIO_IOAS$GET(fd fd_iommufd, cmd const[IOMMU_VFIO_IOAS], arg ptr[in, iommu_vfio_ioas$GET])
ioctl$IOMMU_VFIO_IOAS$SET(fd fd_iommufd, cmd const[IOMMU_VFIO_IOAS], arg ptr[in, iommu_vfio_ioas$SET])
ioctl$IOMMU_VFIO_IOAS$CLEAR(fd fd_iommufd, cmd const[IOMMU_VFIO_IOAS], arg ptr[in, iommu_vfio_ioas$CLEAR])

ioctl$IOMMU_HWPT_ALLOC$NONE(fd fd_iommufd, cmd const[IOMMU_HWPT_ALLOC], arg ptr[in, iommu_hwpt_alloc$IOMMU_HWPT_DATA_NONE])
ioctl$IOMMU_HWPT_ALLOC$TEST(fd fd_iommufd, cmd const[IOMMU_HWPT_ALLOC], arg ptr[in, iommu_hwpt_alloc$IOMMU_HWPT_DATA_SELFTEST])

ioctl$IOMMU_GET_HW_INFO(fd fd_iommufd, cmd const[IOMMU_GET_HW_INFO], arg ptr[in, iommu_hw_info])
ioctl$IOMMU_HWPT_SET_DIRTY_TRACKING(fd fd_iommufd, cmd const[IOMMU_HWPT_SET_DIRTY_TRACKING], arg ptr[in, iommu_hwpt_set_dirty_tracking])
ioctl$IOMMU_HWPT_GET_DIRTY_BITMAP(fd fd_iommufd, cmd const[IOMMU_HWPT_GET_DIRTY_BITMAP], arg ptr[in, iommu_hwpt_get_dirty_bitmap])
ioctl$IOMMU_HWPT_INVALIDATE$TEST(fd fd_iommufd, cmd const[IOMMU_HWPT_INVALIDATE], arg ptr[in, iommu_hwpt_invalidate$IOMMU_HWPT_INVALIDATE_DATA_SELFTEST])

# VFIO compatibility ioctls
# This shares a few structs with dev_vfio.txt
ioctl$IOMMU_VFIO_GET_API_VERSION(fd fd_iommufd, cmd const[VFIO_GET_API_VERSION])
ioctl$IOMMU_VFIO_SET_IOMMU(fd fd_iommufd, cmd const[VFIO_SET_IOMMU], arg flags[iommu_type])
ioctl$IOMMU_VFIO_CHECK_EXTENSION(fd fd_iommufd, cmd const[VFIO_CHECK_EXTENSION], arg flags[iommu_extension])
ioctl$IOMMU_VFIO_IOMMU_GET_INFO(fd fd_iommufd, cmd const[VFIO_IOMMU_GET_INFO], arg ptr[inout, vfio_iommu_type1_info])

ioctl$IOMMU_VFIO_IOMMU_MAP_DMA(fd fd_iommufd, cmd const[VFIO_IOMMU_MAP_DMA], arg ptr[in, vfio_iommu_type1_dma_map])
ioctl$IOMMU_VFIO_IOMMU_UNMAP_DMA(fd fd_iommufd, cmd const[VFIO_IOMMU_UNMAP_DMA], arg ptr[in, vfio_iommu_type1_dma_unmap])

iommu_destroy$ioas {
	size	len[parent, int32]
	id	ioas_handle
}

iommu_ioas_alloc {
	size		len[parent, int32]
	flags		const[0, int32]
	out_ioas_id	ioas_handle	(out)
}

iommu_ioas_iova_ranges {
	size			len[parent, int32]
	ioas_id			ioas_handle
	num_iovas		len[allowed_iovas, int32]
	__reserved		const[0x0, int32]
	allowed_iovas		ptr64[out, array[iommu_iova_range]]
	out_iova_alignment	int64	(out)
}

iommu_ioas_allow_iovas {
	size		len[parent, int32]
	ioas_id		ioas_handle
	num_iovas	len[allowed_iovas, int32]
	__reserved	const[0x0, int32]
	allowed_iovas	ptr64[in, array[iommu_iova_range]]
}

# user_va/length is a pointer to a chunk of memory
# iova on output is the address that memory was placed at.
# The iova/len pair must be used as an input to unmap
# IOMMU_IOAS_MAP_FIXED_IOVA means iova is an input
iommu_ioas_map {
	size		len[parent, int32]
	flags		flags[iommufd_ioas_map_flags, int32]
	ioas_id		ioas_handle
	__reserved	const[0x0, int32]
	user_va		ptr64[in, array[int8]]
	length		len[user_va, int64]
	iova		int64	(inout)
}

# Version that guarantees 4k alignment, has a higher chance of success
iommu_ioas_map$PAGES {
	size		len[parent, int32]
	flags		flags[iommufd_ioas_map_flags, int32]
	ioas_id		ioas_handle
	__reserved	const[0x0, int32]
	user_va		vma64
	length		len[user_va, int64]
	iova		int64	(inout)
}

iommu_ioas_copy {
	size		len[parent, int32]
	flags		flags[iommufd_ioas_map_flags, int32]
	dst_ioas_id	ioas_handle
	src_ioas_id	ioas_handle
	length		int64
	dst_iova	int64	(inout)
	src_iova	int64
}

iommu_ioas_copy$syz {
	size		len[parent, int32]
	flags		flags[iommufd_ioas_map_flags_syz, int32]
	dst_ioas_id	ioas_handle
	src_ioas_id	ioas_handle
	length		int64[0:4194304]
	dst_iova	int64	(inout)
# See iommufd_test_syz_conv_iova_id()
	nth_area	int32[0:10]
	offset		int32[0:4194304]
}

iommu_ioas_unmap {
	size	len[parent, int32]
	ioas_id	ioas_handle
	iova	int64
	length	int64
}

iommu_ioas_unmap$ALL {
	size	len[parent, int32]
	ioas_id	ioas_handle
	iova	const[0x0, int64]
	length	const[-1, int64]
}

iommu_option$IOMMU_OPTION_RLIMIT_MODE {
	size		len[parent, int32]
	option_id	const[IOMMU_OPTION_RLIMIT_MODE, int32]
	op		flags[iommufd_option_ops, int16]
	__reserved	const[0x0, int16]
	object_id	const[0x0, int32]
	val64		int64	(inout)
}

iommu_option$IOMMU_OPTION_HUGE_PAGES {
	size		len[parent, int32]
	option_id	const[IOMMU_OPTION_HUGE_PAGES, int32]
	op		flags[iommufd_option_ops, int16]
	__reserved	const[0x0, int16]
	object_id	ioas_handle
	val64		int64	(inout)
}

iommu_vfio_ioas$GET {
	size		len[parent, int32]
	ioas_id		ioas_handle	(out)
	opt		const[IOMMU_VFIO_IOAS_GET, int16]
	__reserved	const[0x0, int16]
}

iommu_vfio_ioas$SET {
	size		len[parent, int32]
	ioas_id		ioas_handle
	opt		const[IOMMU_VFIO_IOAS_SET, int16]
	__reserved	const[0x0, int16]
}

iommu_vfio_ioas$CLEAR {
	size		len[parent, int32]
	ioas_id		const[0x0, int32]
	opt		const[IOMMU_VFIO_IOAS_CLEAR, int16]
	__reserved	const[0x0, int16]
}

type iommu_hwpt_alloc[DATA_TYPE, DATA] {
	size		len[parent, int32]
	flags		flags[iommufd_hwpt_alloc_flags, int32]
	dev_id		device_handle
	pt_id		ioas_handle
	out_hwpt_id	hwpt_handle	(out)
	__reserved	const[0x0, int32]
	data_type	const[DATA_TYPE, int32]
	data_len	len[uptr, int32]
	uptr		ptr64[in, DATA]
}

type iommu_hwpt_alloc$IOMMU_HWPT_DATA_NONE iommu_hwpt_alloc[IOMMU_HWPT_DATA_NONE, array[int8]]

iommu_hwpt_selftest {
	iotlb	const[0xbadbeef, int32]
}

type iommu_hwpt_alloc$IOMMU_HWPT_DATA_SELFTEST iommu_hwpt_alloc[IOMMU_HWPT_DATA_SELFTEST, iommu_hwpt_selftest]

iommu_hw_info {
	size			len[parent, int32]
	flags			const[0x0, int32]
	dev_id			device_handle
	data_len		len[data_uptr, int32]
	data_uptr		ptr64[out, array[int8]]
	out_data_type		int32	(out)
	__reserved		const[0x0, int32]
	out_capabilities	int64	(out)
}

iommu_hwpt_set_dirty_tracking {
	size		len[parent, int32]
	flags		flags[iommufd_hwpt_set_dirty_tracking_flags, int32]
	hwpt_id		hwpt_handle
	__reserved	const[0x0, int32]
}

iommu_hwpt_get_dirty_bitmap {
	size		len[parent, int32]
	hwpt_id		hwpt_handle
	flags		flags[iommufd_hwpt_get_dirty_bitmap_flags, int32]
	__reserved	const[0x0, int32]
	iova		int64
	length		int64
	page_size	int64
	data		ptr64[out, array[int8]]
}

iommu_hwpt_invalidate_selftest {
	flags		flags[iommufd_hwpt_invalidate_selftest_flags, int32]
	iotlb_id	int32[0:MOCK_NESTED_DOMAIN_IOTLB_ID_MAX]
}

iommu_hwpt_invalidate$IOMMU_HWPT_INVALIDATE_DATA_SELFTEST {
	size		len[parent, int32]
	hwpt_id		hwpt_handle
	data_uptr	ptr64[in, array[iommu_hwpt_invalidate_selftest]]
	data_type	const[IOMMU_HWPT_INVALIDATE_DATA_SELFTEST, int32]
	entry_len	const[0x8, int32]
	entry_num	len[data_uptr, int32]
	__reserved	const[0x0, int32]
}

iommu_iova_range {
	start	int64
	last	int64
}

iommufd_ioas_map_flags = IOMMU_IOAS_MAP_FIXED_IOVA, IOMMU_IOAS_MAP_WRITEABLE, IOMMU_IOAS_MAP_READABLE
iommufd_ioas_map_flags_syz = MOCK_FLAGS_ACCESS_SYZ, IOMMU_IOAS_MAP_WRITEABLE, IOMMU_IOAS_MAP_READABLE, MOCK_FLAGS_ACCESS_SYZ, IOMMU_IOAS_MAP_READABLE
iommufd_option_ops = IOMMU_OPTION_OP_SET, IOMMU_OPTION_OP_GET
iommufd_hwpt_alloc_flags = IOMMU_HWPT_ALLOC_NEST_PARENT, IOMMU_HWPT_ALLOC_DIRTY_TRACKING
iommufd_hwpt_set_dirty_tracking_flags = IOMMU_HWPT_DIRTY_TRACKING_ENABLE
iommufd_hwpt_get_dirty_bitmap_flags = IOMMU_HWPT_GET_DIRTY_BITMAP_NO_CLEAR

iommu_type = VFIO_TYPE1_IOMMU, VFIO_TYPE1v2_IOMMU
iommu_extension = VFIO_TYPE1_IOMMU, VFIO_TYPE1v2_IOMMU, VFIO_UNMAP_ALL, VFIO_DMA_CC_IOMMU, VFIO_UPDATE_VADDR

# This section requires CONFIG_IOMMUFD_TEST
# It allows the kernel to provide a mock consumer of iommufd which allows greater coverage

include <../drivers/iommu/iommufd/iommufd_test.h>

define IOMMU_TEST_CMD_SIZE	sizeof(struct iommu_test_cmd)

resource device_handle[int32]
resource hwpt_handle[int32]
resource fd_access[fd]
resource access_pages_handle[int32]
resource selftest_device_handle[int32]

ioctl$IOMMU_TEST_OP_ADD_RESERVED(fd fd_iommufd, cmd const[IOMMU_TEST_CMD], arg ptr[in, iommu_test_cmd$add_reserved])
ioctl$IOMMU_TEST_OP_MOCK_DOMAIN(fd fd_iommufd, cmd const[IOMMU_TEST_CMD], arg ptr[in, iommu_test_cmd$mock_domain])
ioctl$IOMMU_TEST_OP_MOCK_DOMAIN_FLAGS(fd fd_iommufd, cmd const[IOMMU_TEST_CMD], arg ptr[in, iommu_test_cmd$mock_domain_flags])
ioctl$IOMMU_TEST_OP_MD_CHECK_MAP(fd fd_iommufd, cmd const[IOMMU_TEST_CMD], arg ptr[in, iommu_test_cmd$md_check_map])
ioctl$IOMMU_TEST_OP_MD_CHECK_REFS(fd fd_iommufd, cmd const[IOMMU_TEST_CMD], arg ptr[in, iommu_test_cmd$md_check_refs])
ioctl$IOMMU_TEST_OP_CREATE_ACCESS(fd fd_iommufd, cmd const[IOMMU_TEST_CMD], arg ptr[in, iommu_test_cmd$create_access])
ioctl$IOMMU_TEST_OP_DESTROY_ACCESS_PAGES(fd fd_iommufd, cmd const[IOMMU_TEST_CMD], arg ptr[in, iommu_test_cmd$destroy_access_pages])
ioctl$IOMMU_TEST_OP_ACCESS_PAGES(fd fd_iommufd, cmd const[IOMMU_TEST_CMD], arg ptr[in, iommu_test_cmd$access_pages])
ioctl$IOMMU_TEST_OP_ACCESS_PAGES$syz(fd fd_iommufd, cmd const[IOMMU_TEST_CMD], arg ptr[in, iommu_test_cmd$access_pages$syz])
ioctl$IOMMU_TEST_OP_ACCESS_RW(fd fd_iommufd, cmd const[IOMMU_TEST_CMD], arg ptr[in, iommu_test_cmd$access_rw])
ioctl$IOMMU_TEST_OP_ACCESS_RW$syz(fd fd_iommufd, cmd const[IOMMU_TEST_CMD], arg ptr[in, iommu_test_cmd$access_rw$syz])
ioctl$IOMMU_TEST_OP_SET_TEMP_MEMORY_LIMIT(fd fd_iommufd, cmd const[IOMMU_TEST_CMD], arg ptr[in, iommu_test_cmd$memory_limit])
ioctl$IOMMU_TEST_OP_MOCK_DOMAIN_REPLACE(fd fd_iommufd, cmd const[IOMMU_TEST_CMD], arg ptr[in, iommu_test_cmd$mock_domain_replace])
ioctl$IOMMU_TEST_OP_ACCESS_REPLACE_IOAS(fd fd_iommufd, cmd const[IOMMU_TEST_CMD], arg ptr[in, iommu_test_cmd$access_replace_ioas])

ioctl$IOMMU_DESTROY$stdev(fd fd_iommufd, cmd const[IOMMU_DESTROY], arg ptr[in, iommu_destroy$stdev])
ioctl$IOMMU_DESTROY$hwpt(fd fd_iommufd, cmd const[IOMMU_DESTROY], arg ptr[in, iommu_destroy$hwpt])

iommu_test_cmd$add_reserved {
	size		len[parent, int32]
	op		const[IOMMU_TEST_OP_ADD_RESERVED, int32]
	id		ioas_handle
	__reserved	const[0x0, int32]
	start		int64
	length		int64
} [size[IOMMU_TEST_CMD_SIZE]]

iommu_test_cmd$mock_domain {
	size		len[parent, int32]
	op		const[IOMMU_TEST_OP_MOCK_DOMAIN, int32]
	id		ioas_handle
	__reserved	const[0x0, int32]
	out_stdev_id	selftest_device_handle	(out)
	out_hwpt_id	hwpt_handle	(out)
	out_idev_id	device_handle	(out)
} [size[IOMMU_TEST_CMD_SIZE]]

iommu_test_cmd$mock_domain_flags {
	size		len[parent, int32]
	op		const[IOMMU_TEST_OP_MOCK_DOMAIN, int32]
	id		ioas_handle
	__reserved	const[0x0, int32]
	out_stdev_id	selftest_device_handle	(out)
	out_hwpt_id	hwpt_handle	(out)
	out_idev_id	device_handle	(out)
	dev_flags	flags[iommu_test_cmd_mock_domain_flags, int32]
} [size[IOMMU_TEST_CMD_SIZE]]

iommu_test_cmd$md_check_map {
	size		len[parent, int32]
	op		const[IOMMU_TEST_OP_MD_CHECK_MAP, int32]
	id		hwpt_handle
	__reserved	const[0x0, int32]
	iova		int64
	length		len[uptr, int64]
	uptr		ptr64[in, array[int8]]
} [size[IOMMU_TEST_CMD_SIZE]]

iommu_test_cmd$md_check_refs {
	size		len[parent, int32]
	op		const[IOMMU_TEST_OP_MD_CHECK_REFS, int32]
	id		const[0x0, int32]
	__reserved	const[0x0, int32]
	length		len[uptr, int64]
	uptr		ptr64[in, array[int8]]
	refs		int32
} [size[IOMMU_TEST_CMD_SIZE]]

iommu_test_cmd$create_access {
	size		len[parent, int32]
	op		const[IOMMU_TEST_OP_CREATE_ACCESS, int32]
	id		ioas_handle
	__reserved	const[0x0, int32]
	out_access_fd	fd_access	(out)
	flags		flags[iommu_test_cmd_create_access_flags, int32]
} [size[IOMMU_TEST_CMD_SIZE]]

iommu_test_cmd$destroy_access_pages {
	size		len[parent, int32]
	op		const[IOMMU_TEST_OP_DESTROY_ACCESS_PAGES, int32]
	id		ioas_handle
	__reserved	const[0x0, int32]
	access_pages_id	access_pages_handle
} [size[IOMMU_TEST_CMD_SIZE]]

iommu_test_cmd$access_pages {
	size			len[parent, int32]
	op			const[IOMMU_TEST_OP_ACCESS_PAGES, int32]
	id			fd_access
	__reserved		const[0x0, int32]
	flags			flags[iommu_test_cmd_acess_pages_flags, int32]
	out_access_pages_id	access_pages_handle	(out)
	iova			int64
	length			int64
# The test suite uses uptr to confirm the pages are the right pages, 0 will disable the check
	uptr			const[0x0, int64]
} [size[IOMMU_TEST_CMD_SIZE]]

iommu_test_cmd$access_pages$syz {
	size			len[parent, int32]
	op			const[IOMMU_TEST_OP_ACCESS_PAGES, int32]
	id			fd_access
	__reserved		const[0x0, int32]
	flags			flags[iommu_test_cmd_acess_pages_flags_syz, int32]
	out_access_pages_id	access_pages_handle	(out)
# See iommufd_test_syz_conv_iova_id()
	nth_area		int32[0:10]
	offset			int32[0:4194304]
	length			int64[0:4194304]
# The test suite uses uptr to confirm the pages are the right pages, 0 will disable the check
	uptr			const[0x0, int64]
} [size[IOMMU_TEST_CMD_SIZE]]

iommu_test_cmd$access_rw {
	size		len[parent, int32]
	op		const[IOMMU_TEST_OP_ACCESS_RW, int32]
	id		fd_access
	__reserved	const[0x0, int32]
	iova		int64
	length		len[uptr, int64]
	uptr		ptr64[in, array[int8]]
	flags		flags[iommu_test_cmd_acess_rw_flags, int32]
} [size[IOMMU_TEST_CMD_SIZE]]

iommu_test_cmd$access_rw$syz {
	size		len[parent, int32]
	op		const[IOMMU_TEST_OP_ACCESS_RW, int32]
	id		fd_access
	__reserved	const[0x0, int32]
# See iommufd_test_syz_conv_iova_id()
	nth_area	int32[0:10]
	offset		int32[0:4194304]
	length		len[uptr, int64]
	uptr		ptr64[in, array[int8]]
	flags		flags[iommu_test_cmd_acess_rw_flags_syz, int32]
} [size[IOMMU_TEST_CMD_SIZE]]

iommu_test_cmd$memory_limit {
	size		len[parent, int32]
	op		const[IOMMU_TEST_OP_SET_TEMP_MEMORY_LIMIT, int32]
	id		const[0x0, int32]
	__reserved	const[0x0, int32]
	limit		int32
} [size[IOMMU_TEST_CMD_SIZE]]

iommu_test_cmd$mock_domain_replace {
	size		len[parent, int32]
	op		const[IOMMU_TEST_OP_MOCK_DOMAIN_REPLACE, int32]
	id		selftest_device_handle
	__reserved	const[0x0, int32]
# or hwpt_handle
	pt_id		ioas_handle
} [size[IOMMU_TEST_CMD_SIZE]]

iommu_test_cmd$access_replace_ioas {
	size		len[parent, int32]
	op		const[IOMMU_TEST_OP_ACCESS_REPLACE_IOAS, int32]
	id		fd_access
	__reserved	const[0x0, int32]
	ioas_id		ioas_handle
} [size[IOMMU_TEST_CMD_SIZE]]

iommu_destroy$stdev {
	size	len[parent, int32]
	id	selftest_device_handle
}

iommu_destroy$hwpt {
	size	len[parent, int32]
	id	hwpt_handle
}

iommu_test_cmd_create_access_flags = MOCK_FLAGS_ACCESS_CREATE_NEEDS_PIN_PAGES
iommu_test_cmd_acess_pages_flags = MOCK_FLAGS_ACCESS_WRITE
iommu_test_cmd_acess_pages_flags_syz = MOCK_FLAGS_ACCESS_SYZ, MOCK_FLAGS_ACCESS_WRITE
iommu_test_cmd_acess_rw_flags = MOCK_ACCESS_RW_WRITE, MOCK_ACCESS_RW_SLOW_PATH
iommu_test_cmd_acess_rw_flags_syz = MOCK_FLAGS_ACCESS_SYZ, iommu_test_cmd_acess_rw_flags
iommu_test_cmd_mock_domain_flags = MOCK_FLAGS_DEVICE_NO_DIRTY
iommufd_hwpt_invalidate_selftest_flags = IOMMU_TEST_INVALIDATE_FLAG_ALL
