From: Mostafa Saleh <smostafa@google.com>
To: Nicolin Chen <nicolinc@nvidia.com>
Cc: will@kernel.org, robin.murphy@arm.com, joro@8bytes.org,
jgg@nvidia.com, praan@google.com, kevin.tian@intel.com,
linux-arm-kernel@lists.infradead.org, iommu@lists.linux.dev,
linux-kernel@vger.kernel.org, jamien@nvidia.com, kas@kernel.org,
Cristian Prundeanu <cpru@amazon.com>,
Breno Leitao <leitao@kernel.org>
Subject: Re: [PATCH v11 06/11] iommu/arm-smmu-v3: Add ARM_SMMU_OPT_KDUMP_ADOPT for kdump kernel
Date: Tue, 20 Oct 2026 11:38:21 +0000 [thread overview]
Message-ID: <atdSrRwrphdI9ZQA@google.com> (raw)
In-Reply-To: <ee4257b62324aa75d7140f1f4a49aa0f78586fff.1791226953.git.nicolinc@nvidia.com>
On Mon, Oct 05, 2026 at 12:30:49PM -0700, Nicolin Chen wrote:
> When transitioning to a kdump kernel, the primary kernel might have crashed
> while endpoint devices were actively bus-mastering DMA. Currently, the SMMU
> driver aggressively resets the hardware during probe by clearing CR0_SMMUEN
> and setting the Global Bypass Attribute (GBPA) to ABORT.
>
> In a kdump scenario, this aggressive reset is highly destructive:
> a) If GBPA is set to ABORT, in-flight DMA will be aborted, generating fatal
> PCIe AER or SErrors that may panic the kdump kernel
> b) If GBPA is set to BYPASS, in-flight DMA targeting some IOVAs will bypass
> the SMMU and corrupt the physical memory at those 1:1 mapped IOVAs.
>
> To safely absorb in-flight DMAs, a kdump kernel will have to leave SMMUEN=1
> intact and avoid modifying STRTAB_BASE, allowing HW to continue translating
> in-flight DMAs reusing the crashed kernel's page tables until the endpoint
> device drivers probe and quiesce their respective hardware.
>
> However, the ARM SMMUv3 architecture specification states that updating the
> SMMU_STRTAB_BASE register while SMMUEN == 1 is UNPREDICTABLE or ignored.
>
> This leaves a kdump kernel no choice but to adopt the stream table from the
> crashed kernel.
>
> Introduce ARM_SMMU_OPT_KDUMP_ADOPT and adoption functions that memremap the
> stream tables extracted from STRTAB_BASE and STRTAB_BASE_CFG.
>
> Note that the adoption of the crashed kernel's stream table follows certain
> strict rules, since the old stream table might be compromised. Thus, apply
> some basic validations against the values read from the registers. If tests
> fail, it means the stream table cannot be trusted, so toss it entirely. To
> avoid OOM due to a potentially corrupted stream table, the memremap for l2
> tables is done lazily on the kdump kernel's demand.
>
> The new option will be set in a following change, once the device reset and
> the RMR setup are reworked not to overwrite the adopted stream table, and
> the crashed kernel's in-use ASIDs and VMIDs are reserved.
>
> Keep all kdump functions and kexec helpers in a new arm-smmu-v3-kexec file,
> which will be shared with the liveupdate series in the future.
>
> Suggested-by: Jason Gunthorpe <jgg@nvidia.com>
> Suggested-by: Pranjal Shrivastava <praan@google.com>
> Reviewed-by: Jason Gunthorpe <jgg@nvidia.com>
> Tested-by: Breno Leitao <leitao@kernel.org>
> Tested-by: Cristian Prundeanu <cpru@amazon.com>
> Assisted-by: LLM
> Signed-off-by: Nicolin Chen <nicolinc@nvidia.com>
> ---
> drivers/iommu/arm/Kconfig | 3 +
> drivers/iommu/arm/arm-smmu-v3/Makefile | 1 +
> drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h | 21 +
> .../iommu/arm/arm-smmu-v3/arm-smmu-v3-kexec.c | 398 ++++++++++++++++++
> drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c | 21 +-
> 5 files changed, 441 insertions(+), 3 deletions(-)
> create mode 100644 drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-kexec.c
>
> diff --git a/drivers/iommu/arm/Kconfig b/drivers/iommu/arm/Kconfig
> index 5fac08b89deea..9a7bebe16f395 100644
> --- a/drivers/iommu/arm/Kconfig
> +++ b/drivers/iommu/arm/Kconfig
> @@ -109,6 +109,9 @@ config ARM_SMMU_V3_IOMMUFD
>
> Say Y here if you are doing development and testing on this feature.
>
> +config ARM_SMMU_V3_KEXEC
> + def_bool CRASH_DUMP
> +
> config ARM_SMMU_V3_KUNIT_TEST
> tristate "KUnit tests for arm-smmu-v3 driver" if !KUNIT_ALL_TESTS
> depends on KUNIT
> diff --git a/drivers/iommu/arm/arm-smmu-v3/Makefile b/drivers/iommu/arm/arm-smmu-v3/Makefile
> index 493a659cc66bb..89a27de8dd2f0 100644
> --- a/drivers/iommu/arm/arm-smmu-v3/Makefile
> +++ b/drivers/iommu/arm/arm-smmu-v3/Makefile
> @@ -3,6 +3,7 @@ obj-$(CONFIG_ARM_SMMU_V3) += arm_smmu_v3.o
> arm_smmu_v3-y := arm-smmu-v3.o
> arm_smmu_v3-$(CONFIG_ARM_SMMU_V3_IOMMUFD) += arm-smmu-v3-iommufd.o
> arm_smmu_v3-$(CONFIG_ARM_SMMU_V3_SVA) += arm-smmu-v3-sva.o
> +arm_smmu_v3-$(CONFIG_ARM_SMMU_V3_KEXEC) += arm-smmu-v3-kexec.o
> arm_smmu_v3-$(CONFIG_TEGRA241_CMDQV) += tegra241-cmdqv.o
>
> obj-$(CONFIG_ARM_SMMU_V3_KUNIT_TEST) += arm-smmu-v3-test.o
> diff --git a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h
> index 559bfa8cbc5e0..a1f947e7d9fe4 100644
> --- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h
> +++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h
> @@ -986,6 +986,7 @@ struct arm_smmu_device {
> * invalidated CONT
> */
> #define ARM_SMMU_OPT_FULL_CONT_RANGE_INV (1 << 6)
> +#define ARM_SMMU_OPT_KDUMP_ADOPT (1 << 7)
> u32 options;
>
> struct arm_smmu_cmdq cmdq;
> @@ -1312,6 +1313,26 @@ tegra241_cmdqv_probe(struct arm_smmu_device *smmu)
> }
> #endif /* CONFIG_TEGRA241_CMDQV */
>
> +#ifdef CONFIG_CRASH_DUMP
> +int arm_smmu_kdump_adopt_strtab(struct arm_smmu_device *smmu);
> +int arm_smmu_kdump_adopt_deferred_l2_strtab(struct arm_smmu_device *smmu,
> + u32 sid, phys_addr_t base, u32 span,
> + struct arm_smmu_strtab_l2 **l2table);
> +#else /* CONFIG_CRASH_DUMP */
> +static inline int arm_smmu_kdump_adopt_strtab(struct arm_smmu_device *smmu)
> +{
> + return -EOPNOTSUPP;
> +}
> +
> +static inline int
> +arm_smmu_kdump_adopt_deferred_l2_strtab(struct arm_smmu_device *smmu, u32 sid,
> + phys_addr_t base, u32 span,
> + struct arm_smmu_strtab_l2 **l2table)
> +{
> + return -EOPNOTSUPP;
> +}
> +#endif /* CONFIG_CRASH_DUMP */
> +
> struct arm_vsmmu {
> struct iommufd_viommu core;
> struct arm_smmu_device *smmu;
> diff --git a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-kexec.c b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-kexec.c
> new file mode 100644
> index 0000000000000..6bbc369df86bb
> --- /dev/null
> +++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-kexec.c
> @@ -0,0 +1,398 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Copyright (c) 2026, NVIDIA CORPORATION & AFFILIATES
> + */
> +
> +#define dev_fmt(fmt) "kexec: " fmt
> +
> +#include <linux/io.h>
> +#include <linux/slab.h>
> +
> +#include "arm-smmu-v3.h"
> +
> +/*
> + * Common helpers for a kexec'd kernel to parse, validate, and walk through the
> + * previous kernel's SMMU table structures, shared by the kdump adoption and a
> + * future live-update restoration.
> + *
> + * The common helpers are read-only against the previous kernel's structures: a
> + * table that is not yet mapped by this kernel gets a transient memremap during
> + * a walk, followed by an immediate memunmap. They never allocate memory or take
> + * ownership of the previous kernel's tables; the callers make those decisions.
> + */
> +
> +/**
> + * arm_smmu_kexec_parse_strtab_2lvl() - Validate a 2-level stream table
> + * @smmu: SMMU device of this kernel
> + * @cfg_reg: STRTAB_BASE_CFG register value set by the previous kernel
> + * @base: stream table base address extracted from the STRTAB_BASE register
> + * @num_l1_ents: pointer to return the number of L1 entries
> + *
> + * Validate the 2-level stream table geometry in @cfg_reg and @base's alignment
> + * against this kernel's hardware limits.
> + *
> + * Return: 0 on success with @num_l1_ents set, or -EINVAL on a bad geometry
> + */
> +static int arm_smmu_kexec_parse_strtab_2lvl(struct arm_smmu_device *smmu,
> + u32 cfg_reg, phys_addr_t base,
> + u32 *num_l1_ents)
> +{
> + u32 log2size = FIELD_GET(STRTAB_BASE_CFG_LOG2SIZE, cfg_reg);
> + u32 split = FIELD_GET(STRTAB_BASE_CFG_SPLIT, cfg_reg);
> + u32 num_ents;
> + size_t size;
> +
> + if (log2size < split || log2size > smmu->sid_bits) {
> + dev_err(smmu->dev, "log2size %u out of range [%u, %u]\n",
> + log2size, split, smmu->sid_bits);
> + return -EINVAL;
> + }
> + if (split != STRTAB_SPLIT) {
> + dev_err(smmu->dev,
> + "unsupported STRTAB_SPLIT %u (expected %u)\n", split,
> + STRTAB_SPLIT);
> + return -EINVAL;
> + }
> +
> + /*
> + * Bound the entry count before the shift, as a log2size wider than what
> + * this kernel itself supports would overflow it.
> + */
> + if (log2size - split > ilog2(STRTAB_MAX_L1_ENTRIES)) {
> + dev_err(smmu->dev, "l1 entries 2^%u exceeds max %u\n",
> + log2size - split, STRTAB_MAX_L1_ENTRIES);
> + return -EINVAL;
> + }
> +
> + num_ents = 1U << (log2size - split);
> +
> + size = num_ents * sizeof(struct arm_smmu_strtab_l1);
> + /*
> + * According to spec (6.3.24), HW aligns the base down to the L1 table
> + * size, i.e. min 64 bytes, so an unaligned base would make this kernel
> + * read another table.
> + */
> + if (!IS_ALIGNED(base, size)) {
> + dev_err(smmu->dev, "unaligned l1 stream table base %pa\n",
> + &base);
> + return -EINVAL;
> + }
> +
> + *num_l1_ents = num_ents;
> + return 0;
> +}
> +
> +/**
> + * arm_smmu_kexec_parse_strtab_linear() - Validate a linear stream table
> + * @smmu: SMMU device of this kernel
> + * @cfg_reg: STRTAB_BASE_CFG register value set by the previous kernel
> + * @base: stream table base address extracted from the STRTAB_BASE register
> + * @num_ents: pointer to return the number of STEs
> + *
> + * Validate the linear stream table geometry in @cfg_reg and @base's alignment
> + * against this kernel's own limits.
> + *
> + * Return: 0 on success with @num_ents set, or -EINVAL on a bad geometry
> + */
> +static int arm_smmu_kexec_parse_strtab_linear(struct arm_smmu_device *smmu,
> + u32 cfg_reg, phys_addr_t base,
> + u32 *num_ents)
> +{
> + u32 log2size = FIELD_GET(STRTAB_BASE_CFG_LOG2SIZE, cfg_reg);
> + unsigned int max_log2size = smmu->sid_bits;
> + size_t size;
> +
> + /* Cap the size at what this kernel itself would have allocated */
> + if (smmu->features & ARM_SMMU_FEAT_2_LVL_STRTAB)
> + max_log2size = min_t(
> + unsigned int, max_log2size,
> + ilog2(STRTAB_MAX_L1_ENTRIES * STRTAB_NUM_L2_STES));
> +
> + /* num_ents is limited to a u32, so cap log2size at 31 */
> + max_log2size = min(max_log2size, 31U);
> + if (log2size > max_log2size) {
> + dev_err(smmu->dev, "unsupported log2size %u (> %u)\n", log2size,
> + max_log2size);
> + return -EINVAL;
> + }
> +
> + size = (1U << log2size) * sizeof(struct arm_smmu_ste);
> + /*
> + * According to spec (6.3.24), HW aligns the base down to the table size
> + * and ignores the low bits, so an unaligned base would make this kernel
> + * read a different table.
> + */
> + if (!IS_ALIGNED(base, size)) {
> + dev_err(smmu->dev, "unaligned stream table base %pa\n", &base);
I understand these are best effort, but what happens if the address
corrupted and happens to be aligned?
> + return -EINVAL;
> + }
> +
> + *num_ents = 1U << log2size;
> + return 0;
> +}
> +
> +/**
> + * arm_smmu_kexec_check_strtab_l1_desc() - Check one stream table L1 descriptor
> + * @smmu: SMMU device of this kernel
> + * @l1_desc: L1 descriptor value from the previous kernel's stream table
> + * @idx: index of the L1 descriptor, for diagnostics
> + * @l2_base: pointer to return the L2 table's physical address
> + *
> + * Return: 1 if the descriptor is unused, 0 if it is valid with @l2_base set, or
> + * -EINVAL if it is malformed
> + */
> +static int arm_smmu_kexec_check_strtab_l1_desc(struct arm_smmu_device *smmu,
> + u64 l1_desc, u32 idx,
> + phys_addr_t *l2_base)
> +{
> + phys_addr_t base = l1_desc & STRTAB_L1_DESC_L2PTR_MASK;
> + u32 span = FIELD_GET(STRTAB_L1_DESC_SPAN, l1_desc);
> +
> + /* L1STD.L2Ptr is invalid */
> + if (!span)
> + return 1;
> +
> + if (span != STRTAB_SPLIT + 1) {
> + dev_err(smmu->dev, "L1[%u] unsupported span %u (vs %u)\n", idx,
> + span, STRTAB_SPLIT + 1);
> + return -EINVAL;
> + }
> +
> + /*
> + * A valid descriptor never carries a null pointer. Also, HW aligns the
> + * pointer down to the L2 table size, so an unaligned pointer would make
> + * this kernel read a different table.
> + */
> + if (!base || !IS_ALIGNED(base, sizeof(struct arm_smmu_strtab_l2))) {
> + dev_err(smmu->dev, "L1[%u] bad l2 table base %pa\n", idx,
> + &base);
> + return -EINVAL;
> + }
> +
> + *l2_base = base;
> + return 0;
> +}
> +
> +#ifdef CONFIG_CRASH_DUMP
> +/*
> + * Helper functions of the kdump stream table adoption for ARM SMMUv3
> + *
> + * When the crashed kernel left the SMMU enabled with in-flight DMAs, the kdump
> + * kernel adopts the crashed kernel's stream tables, instead of doing a regular
> + * reset, to keep in-flight DMAs translating until the endpoint device drivers
> + * re-probe and quiesce their devices.
> + *
> + * Note:
> + * - Adoption only starts on an SMMU that the crashed kernel left enabled, as a
> + * disabled SMMU (CR0_SMMUEN=0) could hold meaningless register values.
> + * - Values read from the crashed kernel's registers get structural validation
> + * only (format, size, span, alignment, and ID range); the physical addresses
> + * are not vetted, as the kdump kernel has no record of which pages held the
> + * tables.
> + * - A structural inconsistency at adoption time tosses the entire adoption and
> + * makes the SMMU fall back to a full reset blocking in-flight DMAs.
> + * - L2 stream tables are adopted lazily at master-inserting time, to bound the
> + * peak memory use against a corrupted L1 table; any lazy L2 adoption failure
> + * rejects that device alone, as its blast radius is bounded to the bus.
> + * - Only a coherent SMMU (ARM_SMMU_FEAT_COHERENCY) is supported, as the stream
> + * table adoption is done by memremap with MEMREMAP_WB, which is verified on
> + * the real hardware. Callers of these functions are responsible for gating
> + * ARM_SMMU_FEAT_COHERENCY once during the probe.
> + */
> +
> +int arm_smmu_kdump_adopt_deferred_l2_strtab(struct arm_smmu_device *smmu,
> + u32 sid, phys_addr_t base, u32 span,
> + struct arm_smmu_strtab_l2 **l2table)
> +{
> + struct arm_smmu_strtab_l2 *table;
> + size_t size;
> +
> + /*
> + * Retest the span in case the L1 descriptor has been overwritten since
> + * the adopt. Reject this master's insert; panic or SMMU-disable would
> + * either lose the vmcore or cascade aborts. Do not try to fix it, as it
> + * would break all other SIDs in the same bus (PCI case). The corruption
> + * blast radius is already bounded to that bus range.
> + */
> + if (span != STRTAB_SPLIT + 1) {
> + dev_err(smmu->dev,
> + "L1[%u] span %u changed since adopt (was %u)\n",
> + arm_smmu_strtab_l1_idx(sid), span, STRTAB_SPLIT + 1);
> + return -EINVAL;
> + }
> +
> + size = (1UL << (span - 1)) * sizeof(struct arm_smmu_ste);
> +
> + /* Same live-corruption check as the span; reject an overwritten base */
> + if (!base || !IS_ALIGNED(base, size)) {
> + dev_err(smmu->dev, "L1[%u] bad l2 table base %pa\n",
> + arm_smmu_strtab_l1_idx(sid), &base);
> + return -EINVAL;
> + }
> +
Those are a bit similar to arm_smmu_kexec_parse_strtab_2lvl() is it
possible to have some helpers instead?
> + /*
> + * This L2 table is mapped lazily per master; devres frees it at unbind,
> + * as with the dmam_alloc_coherent() used for a fresh L2.
> + */
> + table = devm_memremap(smmu->dev, base, size, MEMREMAP_WB);
> + if (IS_ERR(table)) {
> + dev_err(smmu->dev,
> + "failed to adopt l2 stream table for SID %u\n", sid);
> + return PTR_ERR(table);
> + }
> +
> + *l2table = table;
> + return 0;
> +}
> +
> +static int arm_smmu_kdump_adopt_strtab_2lvl(struct arm_smmu_device *smmu,
> + u32 cfg_reg, phys_addr_t base)
> +{
> + struct arm_smmu_strtab_cfg *cfg = &smmu->strtab_cfg;
> + u32 num_l1_ents;
> + size_t size;
> + int ret, i;
> +
> + ret = arm_smmu_kexec_parse_strtab_2lvl(smmu, cfg_reg, base,
> + &num_l1_ents);
> + if (ret)
> + return ret;
> +
> + cfg->l2.num_l1_ents = num_l1_ents;
> +
> + size = num_l1_ents * sizeof(struct arm_smmu_strtab_l1);
> + cfg->l2.l1tab = memremap(base, size, MEMREMAP_WB);
> + if (!cfg->l2.l1tab)
> + return -ENOMEM;
> +
> + cfg->l2.l2ptrs =
> + kcalloc(num_l1_ents, sizeof(*cfg->l2.l2ptrs), GFP_KERNEL);
> + if (!cfg->l2.l2ptrs)
> + return -ENOMEM;
> +
> + for (i = 0; i < num_l1_ents; i++) {
> + u64 l2ptr = le64_to_cpu(cfg->l2.l1tab[i].l2ptr);
> + phys_addr_t l2_base;
> +
> + ret = arm_smmu_kexec_check_strtab_l1_desc(smmu, l2ptr, i,
> + &l2_base);
> + if (ret < 0)
> + return ret;
> +
> + /*
> + * If the crashed kernel's l1 descriptors are deeply corrupted,
> + * blindly memremapping every l2 table here could lead to OOM.
> + *
> + * Defer the l2 memremap to arm_smmu_init_l2_strtab(), so peak
> + * memory is bounded by the kdump kernel's actual demand.
> + */
> + }
> +
> + return 0;
> +}
> +
> +static int arm_smmu_kdump_adopt_strtab_linear(struct arm_smmu_device *smmu,
> + u32 cfg_reg, phys_addr_t base)
> +{
> + struct arm_smmu_strtab_cfg *cfg = &smmu->strtab_cfg;
> + u32 num_ents;
> + size_t size;
> + int ret;
> +
> + ret = arm_smmu_kexec_parse_strtab_linear(smmu, cfg_reg, base,
> + &num_ents);
> + if (ret)
> + return ret;
> +
> + /*
> + * We might end up with a num_ents != sid_bits, which is fine, since the
> + * ARM_SMMU_OPT_KDUMP_ADOPT case bypasses arm_smmu_write_strtab().
> + */
> + cfg->linear.num_ents = num_ents;
> +
> + size = num_ents * sizeof(struct arm_smmu_ste);
> + cfg->linear.table = memremap(base, size, MEMREMAP_WB);
> + if (!cfg->linear.table)
> + return -ENOMEM;
> + return 0;
> +}
> +
> +static void arm_smmu_kdump_adopt_cleanup(void *data)
> +{
> + struct arm_smmu_device *smmu = data;
> + struct arm_smmu_strtab_cfg *cfg = &smmu->strtab_cfg;
> +
> + if (smmu->features & ARM_SMMU_FEAT_2_LVL_STRTAB) {
> + kfree(cfg->l2.l2ptrs);
> + if (cfg->l2.l1tab)
> + memunmap(cfg->l2.l1tab);
> + } else {
> + if (cfg->linear.table)
> + memunmap(cfg->linear.table);
> + }
> +}
> +
> +int arm_smmu_kdump_adopt_strtab(struct arm_smmu_device *smmu)
> +{
> + u32 cfg_reg = readl_relaxed(smmu->base + ARM_SMMU_STRTAB_BASE_CFG);
> + u64 base_reg = readq_relaxed(smmu->base + ARM_SMMU_STRTAB_BASE);
> + bool was_2lvl = smmu->features & ARM_SMMU_FEAT_2_LVL_STRTAB;
> + phys_addr_t base = base_reg & STRTAB_BASE_ADDR_MASK;
> + u32 fmt = FIELD_GET(STRTAB_BASE_CFG_FMT, cfg_reg);
> + int ret;
> +
> + dev_dbg(smmu->dev, "adopting crashed kernel's stream table\n");
> +
> + if (fmt == STRTAB_BASE_CFG_FMT_2LVL) {
> + /*
> + * Both kernels run on the same hardware, so it's impossible for
> + * kdump kernel to see the support for linear stream table only.
> + */
STRTAB_SPLIT which influences ARM_SMMU_FEAT_2_LVL_STRTAB is a SW choice, so it is
possible to get such mismatch if STRTAB_SPLIT of the newer kernel is larger than the
older kernel.
However, I agree that in that case it's better to refuse the adoption.
> + if (WARN_ON(!(smmu->features & ARM_SMMU_FEAT_2_LVL_STRTAB)))
> + ret = -EINVAL;
> + else
> + ret = arm_smmu_kdump_adopt_strtab_2lvl(smmu, cfg_reg,
> + base);
> + } else if (fmt == STRTAB_BASE_CFG_FMT_LINEAR) {
> + /*
> + * The kdump kernel need not match the crashed kernel. An older
> + * crashed kernel that predates two-level stream table support
> + * may have used a linear table on 2-level-capable hardware, so
> + * enforce the same format here to match the adopted table.
> + */
> + ret = arm_smmu_kdump_adopt_strtab_linear(smmu, cfg_reg, base);
> + if (!ret)
> + smmu->features &= ~ARM_SMMU_FEAT_2_LVL_STRTAB;
For simplicity, it is better to enforce the same table formats between
kernels as the rest of the file, for example,
arm_smmu_kexec_parse_strtab_2lvl() refuses different STRTAB_SPLIT.
Some checks can be removed and the was_2lvl error path. It's
very unlikely to hit such case anyway.
> + } else {
> + dev_err(smmu->dev, "invalid STRTAB format %u\n", fmt);
> + ret = -EINVAL;
> + }
> +
> + if (ret) {
> + arm_smmu_kdump_adopt_cleanup(smmu);
Probably easier to inline the error handling after each call and remove this?
Thanks,
Mostafa
next prev parent reply other threads:[~2026-10-20 11:38 UTC|newest]
Thread overview: 30+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-10-05 19:30 [PATCH v11 00/11] iommu/arm-smmu-v3: Adopt the crashed kernel's stream table for kdump Nicolin Chen
2026-10-05 19:30 ` [PATCH v11 01/11] iommu/arm-smmu-v3: Init the vmid_map ida before the stream table setup Nicolin Chen
2026-10-20 11:13 ` Mostafa Saleh
2026-10-05 19:30 ` [PATCH v11 02/11] iommu/arm-smmu-v3: Make the ASID space per SMMU instance Nicolin Chen
2026-10-20 11:14 ` Mostafa Saleh
2026-10-05 19:30 ` [PATCH v11 03/11] iommu/arm-smmu-v3: Swap EVTQ_MSI_INDEX and GERROR_MSI_INDEX Nicolin Chen
2026-10-13 14:49 ` Jason Gunthorpe
2026-10-13 17:41 ` Nicolin Chen
2026-10-20 14:26 ` Jason Gunthorpe
2026-10-05 19:30 ` [PATCH v11 04/11] iommu/arm-smmu-v3: Add ARM_SMMU_FEAT_EVTQ for the event queue Nicolin Chen
2026-10-20 11:16 ` Mostafa Saleh
2026-10-20 16:49 ` Nicolin Chen
2026-10-05 19:30 ` [PATCH v11 05/11] iommu/arm-smmu-v3: Disable the EVTQ and the PRIQ in a kdump kernel Nicolin Chen
2026-10-20 11:22 ` Mostafa Saleh
2026-10-20 16:59 ` Nicolin Chen
2026-10-05 19:30 ` [PATCH v11 06/11] iommu/arm-smmu-v3: Add ARM_SMMU_OPT_KDUMP_ADOPT for " Nicolin Chen
2026-10-20 11:38 ` Mostafa Saleh [this message]
2026-10-20 14:25 ` Jason Gunthorpe
2026-10-20 17:36 ` Nicolin Chen
2026-10-20 17:47 ` Nicolin Chen
2026-10-05 19:30 ` [PATCH v11 07/11] iommu/arm-smmu-v3-kexec: Reserve crashed kernel's ASIDs and VMIDs Nicolin Chen
2026-10-05 19:30 ` [PATCH v11 08/11] iommu/arm-smmu-v3-kexec: Implement is_attach_deferred() Nicolin Chen
2026-10-05 19:30 ` [PATCH v11 09/11] iommu/arm-smmu-v3: Retain CR0_SMMUEN during kdump device reset Nicolin Chen
2026-10-13 14:49 ` Jason Gunthorpe
2026-10-05 19:30 ` [PATCH v11 10/11] iommu/arm-smmu-v3: Skip RMR bypass for kdump adoption Nicolin Chen
2026-10-05 19:30 ` [PATCH v11 11/11] iommu/arm-smmu-v3: Detect ARM_SMMU_OPT_KDUMP_ADOPT in probe() Nicolin Chen
2026-10-05 20:48 ` [PATCH v11 00/11] iommu/arm-smmu-v3: Adopt the crashed kernel's stream table for kdump Nicolin Chen
2026-10-17 8:19 ` Shuai Xue
2026-10-17 11:40 ` Jason Gunthorpe
2026-10-17 18:52 ` Nicolin Chen
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=atdSrRwrphdI9ZQA@google.com \
--to=smostafa@google.com \
--cc=cpru@amazon.com \
--cc=iommu@lists.linux.dev \
--cc=jamien@nvidia.com \
--cc=jgg@nvidia.com \
--cc=joro@8bytes.org \
--cc=kas@kernel.org \
--cc=kevin.tian@intel.com \
--cc=leitao@kernel.org \
--cc=linux-arm-kernel@lists.infradead.org \
--cc=linux-kernel@vger.kernel.org \
--cc=nicolinc@nvidia.com \
--cc=praan@google.com \
--cc=robin.murphy@arm.com \
--cc=will@kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox