Re: [PATCH v3 02/18] iommu: Implement IOMMU Live update FLB callbacks
From: Ankit Soni
Date: Fri Jul 31 2026 - 02:04:18 EST
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 <skhawaja@xxxxxxxxxx>
> ---
> 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 <skhawaja@xxxxxxxxxx>
> + */
> +
> +#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
>