Re: [PATCH v3 02/18] iommu: Implement IOMMU Live update FLB callbacks

Ankit Soni <[email protected]> Fri, 31 Jul 2026 05:58:20 +0000
Newsgroups dev.linux.lists.iommu,org.kernel.vger.kvm,org.kernel.vger.linux-kernel
Message-ID <fjma5ub62ia4pbcvs4yek52r6jlhut4fidutow3g5uhf6iel3o@iqx3a6bm4q2e>
On Sun, Jun 14, 2026 at 11:37:12PM +0000, Samiullah Khawaja wrote:
> Add liveupdate FLB for IOMMU state preservation. Use KHO preserve memory
> alloc/free helper functions to allocate memory for the IOMMU Live update
> FLB object and the serialization structs for device, domain and iommu.
> 
> During retrieve, walk through the preserved obj array headers and
> restore each folio. Also recreate the FLB obj.
> 
> Signed-off-by: Samiullah Khawaja <[email protected]>
> ---
>  MAINTAINERS                      |   9 ++
>  drivers/iommu/Kconfig            |  12 ++
>  drivers/iommu/Makefile           |   1 +
>  drivers/iommu/liveupdate.c       | 212 +++++++++++++++++++++++++++++++
>  include/linux/iommu-liveupdate.h |  18 +++
>  include/linux/kho/abi/iommu.h    | 207 ++++++++++++++++++++++++++++++
>  6 files changed, 459 insertions(+)
>  create mode 100644 drivers/iommu/liveupdate.c
>  create mode 100644 include/linux/iommu-liveupdate.h
>  create mode 100644 include/linux/kho/abi/iommu.h
> 

../..

> diff --git a/include/linux/kho/abi/iommu.h b/include/linux/kho/abi/iommu.h
> new file mode 100644
> index 000000000000..d06f251a2df4
> --- /dev/null
> +++ b/include/linux/kho/abi/iommu.h
> @@ -0,0 +1,207 @@
> +/* SPDX-License-Identifier: GPL-2.0 */
> +
> +/*
> + * Copyright (C) 2026, Google LLC
> + * Author: Samiullah Khawaja <[email protected]>
> + */
> +
> +#ifndef _LINUX_KHO_ABI_IOMMU_H
> +#define _LINUX_KHO_ABI_IOMMU_H
> +
> +#include <linux/mutex_types.h>
> +#include <linux/compiler.h>
> +#include <linux/types.h>
> +
> +/**
> + * DOC: IOMMU File-Lifecycle Bound (FLB) Live Update ABI
> + *
> + * This header defines the ABI for preserving IOMMU state across kexec using
> + * Live Update File-Lifecycle Bound (FLB) data.
> + *
> + * This interface is a contract. Any modification to any of the serialization
> + * structs defined here constitutes a breaking change. Such changes require
> + * incrementing the version number in the IOMMU_LUO_FLB_COMPATIBLE string.
> + *
> + * Memory Layout of Serialization Structures:
> + * ==========================================
> + *
> + * Each serialized type (IOMMU, Domain, Device) is stored in a linked list of
> + * arrays. The first array is allocated initially. When an array is full, a new
> + * array is allocated and its physical address is stored in the next_array_phys
> + * field of the hdr of the current array.
> + *
> + * Top Level (struct iommu_flb_ser):
> + * +---------------------------+
> + * | - iommu_array_phys        |
> + * | - iommu_domain_array_phys |
> + * | - device_array_phys       |
> + * +---------------------------+
> + *
> + * Each Array contains the serialized objects of the respective type. For
> + * example see below the representation of struct iommu_domain_array_ser.
> + *
> + * +---------------------------+   +---------------------------+
> + * | iommu_domain_array_ser    |-->| iommu_domain_array_ser    |--> NULL
> + * | - hdr.next_array_phys     |   | - hdr.next_array_phys     |
> + * | - hdr.nr_objects          |   | - hdr.nr_objects          |
> + * |                           |   |                           |
> + * | objects[]:                |   | objects[]:                |
> + * | [ iommu_domain_ser ]      |   | [ iommu_domain_ser ]      |
> + * | [ iommu_domain_ser ]      |   | [ iommu_domain_ser ]      |
> + * | ...                       |   | ...                       |
> + * +---------------------------+   +---------------------------+
> + *
> + * Each object in the array starts with a common header (iommu_hdr_ser).
> + * For example, the layout of struct iommu_domain_ser is:
> + *
> + *   +-----------------------------+
> + *   | iommu_domain_ser            |
> + *   | +-------------------------+ |
> + *   | | hdr (iommu_hdr_ser)     | |
> + *   | | - ref_count             | |
> + *   | | - deleted / incoming    | |
> + *   | +-------------------------+ |
> + *   | - top_table_phys          | |
> + *   | - top_level               | |
> + *   | - restored_domain         | |
> + *   +-----------------------------+
> + *
> + * This pattern applies identically to iommu_device_ser and iommu_hw_ser.
> + */
> +
> +#define IOMMU_LUO_FLB_COMPATIBLE "iommu-liveupdate-v1"
> +
> +/**
> + * enum iommu_type_ser - Type of the IOMMU being preserved
> + * @IOMMU_INVALID: Invalid type of IOMMU
> + *
> + * IOMMU type is stored in the IOMMU HW state to differentiate between various
> + * IOMMU HWs.
> + */
> +enum iommu_type_ser {
> +	IOMMU_INVALID,
> +};
> +
> +#define IOMMU_SER_FLAG_DELETED	(1 << 0)
> +#define IOMMU_SER_FLAG_INCOMING	(1 << 1)
> +
> +/**
> + * struct iommu_hdr_ser - Common header for all serialized IOMMU objects
> + * @ref_count: Reference count for the object
> + * @flags: Bitmask of IOMMU_SER_FLAG_* flags indicating object state
> + */
> +struct iommu_hdr_ser {
> +	u32 ref_count;
> +	u32 flags;
> +} __packed;
> +
> +/**
> + * struct iommu_domain_ser - Serialized state of an IOMMU domain
> + * @hdr: Common object header
> + * @top_table_phys: Physical address of the top-level page table
> + * @top_level: Level of the top-level page table
> + * @vasz: Virtual Address Size
> + * @sign_extend: FEAT_SIGN_EXTEND is enabled for this domain
> + * @restored_domain: Pointer to the restored domain (valid only after restore)
> + */
> +struct iommu_domain_ser {
> +	struct iommu_hdr_ser hdr;
> +	u64 top_table_phys;
> +	u64 top_level;
> +	u32 vasz;
> +	u32 sign_extend:1;
> +	struct iommu_domain *restored_domain;
> +} __packed;
> +

Hi,

nit, The v3 changelog has "Replace bitfields with u32 flags", but sign_extend:1
looks like it was missed. this is 37 bytes, the only arrayed record in this 
header that isn't a multiple of 8 (iommu_device_ser is 56, iommu_hw_ser 112).
The arrays are strided with pointer arithmetic, so the skew accumulates: from 
objects[1] onwards none of the u64s are naturally aligned.

Looks like a leftover from the bitfield cleanup.

-Ankit

> +/**
> + * struct iommu_dev_map_ser - Serialized mapping between device, domain,
> + *				    and IOMMU instance.
> + * @attachment_id: ID of the attachment between device and domain.
> + * @domain_phys: Physical address of the domain
> + * @iommu_phys: Physical address of the IOMMU
> + */
> +struct iommu_dev_map_ser {
> +	u64 attachment_id;
> +	u64 domain_phys;
> +	u64 iommu_phys;
> +} __packed;
> +
> +/**
> + * struct iommu_device_ser - Serialized state of a device
> + * @hdr: Common object header
> + * @devid: Device ID
> + * @pci_domain_nr: PCI domain number
> + * @domain_iommu_ser: Domain and IOMMU mapping
> + */
> +struct iommu_device_ser {
> +	struct iommu_hdr_ser hdr;
> +	u32 devid;
> +	u32 pci_domain_nr;
> +	struct iommu_dev_map_ser domain_iommu_ser;
> +} __packed;
> +
> +/**
> + * struct iommu_hw_ser - Serialized state of an IOMMU instance
> + * @hdr: Common object header
> + * @token: Unique token for the IOMMU
> + * @type: IOMMU type serialized state belongs to
> + */
> +struct iommu_hw_ser {
> +	struct iommu_hdr_ser hdr;
> +	u64 token;
> +	u64 type;
> +} __packed;
> +
> +/**
> + * struct iommu_array_hdr_ser - Header for an array of serialized objects
> + * @next_array_phys: Physical address of the next array of objects
> + * @nr_objects: Number of objects in the current array
> + */
> +struct iommu_array_hdr_ser {
> +	u64 next_array_phys;
> +	u64 nr_objects;
> +} __packed;
> +
> +/**
> + * struct iommu_hw_array_ser - An array containing serialized IOMMU HWs
> + * @hdr: Array header
> + * @objects: Array of serialized IOMMU devices
> + */
> +struct iommu_hw_array_ser {
> +	struct iommu_array_hdr_ser hdr;
> +	struct iommu_hw_ser objects[];
> +} __packed;
> +
> +/**
> + * struct iommu_domain_array_ser - An array containing serialized domains
> + * @hdr: Array header
> + * @objects: Array of serialized domains
> + */
> +struct iommu_domain_array_ser {
> +	struct iommu_array_hdr_ser hdr;
> +	struct iommu_domain_ser objects[];
> +} __packed;
> +
> +/**
> + * struct iommu_device_array_ser - An array containing serialized devices
> + * @hdr: Array header
> + * @objects: Array of serialized devices
> + */
> +struct iommu_device_array_ser {
> +	struct iommu_array_hdr_ser hdr;
> +	struct iommu_device_ser objects[];
> +} __packed;
> +
> +/**
> + * struct iommu_flb_ser - Top-level serialization structure
> + * @iommu_array_phys: Physical address of the first array of IOMMU HWs
> + * @iommu_domain_array_phys: Physical address of the first array of domains
> + * @device_array_phys: Physical address of the first array of devices
> + */
> +struct iommu_flb_ser {
> +	u64 iommu_array_phys;
> +	u64 iommu_domain_array_phys;
> +	u64 device_array_phys;
> +} __packed;
> +
> +#endif /* _LINUX_KHO_ABI_IOMMU_H */
> -- 
> 2.54.0.1136.gdb2ca164c4-goog
>