[PATCH] hw/riscv/virt-acpi-build: Fix off-by-one error in RIMT ID mapping

Zishun Yi posted 1 patch 2 weeks, 4 days ago
Patches applied successfully (tree, apply log)
git fetch https://github.com/patchew-project/qemu tags/patchew/20260512062310.348208-1-vulab@iscas.ac.cn
Maintainers: Sunil V L <sunilvl@ventanamicro.com>, Palmer Dabbelt <palmer@dabbelt.com>, Alistair Francis <alistair.francis@wdc.com>, Weiwei Li <liwei1518@gmail.com>, Daniel Henrique Barboza <daniel.barboza@oss.qualcomm.com>, Liu Zhiwei <zhiwei_liu@linux.alibaba.com>, Chao Liu <chao.liu.zevorn@gmail.com>
hw/riscv/virt-acpi-build.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
[PATCH] hw/riscv/virt-acpi-build: Fix off-by-one error in RIMT ID mapping
Posted by Zishun Yi 2 weeks, 4 days ago
In build_rimt(), the calculation of `num_ids` for the ID mapping array
incorrectly uses the same formula (`0xffff - s->pci_iommu_bdf`) for both
System IOMMU and PCI IOMMU topologies.

For a System IOMMU, `s->pci_iommu_bdf` is 0. This results in a `num_ids`
value of 0xffff. Since the source ID base starts at 0, the mapping only
covers Requester IDs from 0 to 0xfffe. The final valid PCI Requester ID
(0xffff) is erroneously omitted from the RIMT table.

Fix this by decoupling the `num_ids` calculation. For System IOMMUs,
explicitly set `num_ids` to 0x10000 to cover the entire PCI Requester ID
space.

This issue was discovered and reported by SpecHunter, an AI-driven
architecture specification analysis tool.

Link: https://github.com/yizishun/rv-isa-sec/blob/c78dacf66c8acd677b3538c837fde310bb71a97b/output/riscv-server-platform/pr-102/qemu.txt#L32
Signed-off-by: Zishun Yi <vulab@iscas.ac.cn>
---
 hw/riscv/virt-acpi-build.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/hw/riscv/virt-acpi-build.c b/hw/riscv/virt-acpi-build.c
index fd6ca5dbc4ff..413d47d70ef1 100644
--- a/hw/riscv/virt-acpi-build.c
+++ b/hw/riscv/virt-acpi-build.c
@@ -802,10 +802,11 @@ static void build_rimt(GArray *table_data, BIOSLinker *linker,
         range = &g_array_index(iommu_idmaps, AcpiRimtIdMapping, i);
         if (virt_is_iommu_sys_enabled(s)) {
             range->source_id_base = 0;
+            range->num_ids = 0x10000;
         } else {
             range->source_id_base = s->pci_iommu_bdf + 1;
+            range->num_ids = 0xffff - s->pci_iommu_bdf;
         }
-        range->num_ids = 0xffff - s->pci_iommu_bdf;
         build_rimt_id_mapping(table_data, range->source_id_base,
                               range->num_ids, iommu_offset);
     }
-- 
2.51.2
Re: [PATCH] hw/riscv/virt-acpi-build: Fix off-by-one error in RIMT ID mapping
Posted by Alistair Francis 1 week, 4 days ago
On Tue, May 12, 2026 at 4:26 PM Zishun Yi <vulab@iscas.ac.cn> wrote:
>
> In build_rimt(), the calculation of `num_ids` for the ID mapping array
> incorrectly uses the same formula (`0xffff - s->pci_iommu_bdf`) for both
> System IOMMU and PCI IOMMU topologies.
>
> For a System IOMMU, `s->pci_iommu_bdf` is 0. This results in a `num_ids`
> value of 0xffff. Since the source ID base starts at 0, the mapping only
> covers Requester IDs from 0 to 0xfffe. The final valid PCI Requester ID
> (0xffff) is erroneously omitted from the RIMT table.
>
> Fix this by decoupling the `num_ids` calculation. For System IOMMUs,
> explicitly set `num_ids` to 0x10000 to cover the entire PCI Requester ID
> space.
>
> This issue was discovered and reported by SpecHunter, an AI-driven
> architecture specification analysis tool.
>
> Link: https://github.com/yizishun/rv-isa-sec/blob/c78dacf66c8acd677b3538c837fde310bb71a97b/output/riscv-server-platform/pr-102/qemu.txt#L32
> Signed-off-by: Zishun Yi <vulab@iscas.ac.cn>

Thanks!

Applied to riscv-to-apply.next

Alistair

> ---
>  hw/riscv/virt-acpi-build.c | 3 ++-
>  1 file changed, 2 insertions(+), 1 deletion(-)
>
> diff --git a/hw/riscv/virt-acpi-build.c b/hw/riscv/virt-acpi-build.c
> index fd6ca5dbc4ff..413d47d70ef1 100644
> --- a/hw/riscv/virt-acpi-build.c
> +++ b/hw/riscv/virt-acpi-build.c
> @@ -802,10 +802,11 @@ static void build_rimt(GArray *table_data, BIOSLinker *linker,
>          range = &g_array_index(iommu_idmaps, AcpiRimtIdMapping, i);
>          if (virt_is_iommu_sys_enabled(s)) {
>              range->source_id_base = 0;
> +            range->num_ids = 0x10000;
>          } else {
>              range->source_id_base = s->pci_iommu_bdf + 1;
> +            range->num_ids = 0xffff - s->pci_iommu_bdf;
>          }
> -        range->num_ids = 0xffff - s->pci_iommu_bdf;
>          build_rimt_id_mapping(table_data, range->source_id_base,
>                                range->num_ids, iommu_offset);
>      }
> --
> 2.51.2
>
>
Re: [PATCH] hw/riscv/virt-acpi-build: Fix off-by-one error in RIMT ID mapping
Posted by Alistair Francis 1 week, 4 days ago
On Tue, May 12, 2026 at 4:26 PM Zishun Yi <vulab@iscas.ac.cn> wrote:
>
> In build_rimt(), the calculation of `num_ids` for the ID mapping array
> incorrectly uses the same formula (`0xffff - s->pci_iommu_bdf`) for both
> System IOMMU and PCI IOMMU topologies.
>
> For a System IOMMU, `s->pci_iommu_bdf` is 0. This results in a `num_ids`
> value of 0xffff. Since the source ID base starts at 0, the mapping only
> covers Requester IDs from 0 to 0xfffe. The final valid PCI Requester ID
> (0xffff) is erroneously omitted from the RIMT table.
>
> Fix this by decoupling the `num_ids` calculation. For System IOMMUs,
> explicitly set `num_ids` to 0x10000 to cover the entire PCI Requester ID
> space.
>
> This issue was discovered and reported by SpecHunter, an AI-driven
> architecture specification analysis tool.
>
> Link: https://github.com/yizishun/rv-isa-sec/blob/c78dacf66c8acd677b3538c837fde310bb71a97b/output/riscv-server-platform/pr-102/qemu.txt#L32
> Signed-off-by: Zishun Yi <vulab@iscas.ac.cn>

Acked-by: Alistair Francis <alistair.francis@wdc.com>

Alistair

> ---
>  hw/riscv/virt-acpi-build.c | 3 ++-
>  1 file changed, 2 insertions(+), 1 deletion(-)
>
> diff --git a/hw/riscv/virt-acpi-build.c b/hw/riscv/virt-acpi-build.c
> index fd6ca5dbc4ff..413d47d70ef1 100644
> --- a/hw/riscv/virt-acpi-build.c
> +++ b/hw/riscv/virt-acpi-build.c
> @@ -802,10 +802,11 @@ static void build_rimt(GArray *table_data, BIOSLinker *linker,
>          range = &g_array_index(iommu_idmaps, AcpiRimtIdMapping, i);
>          if (virt_is_iommu_sys_enabled(s)) {
>              range->source_id_base = 0;
> +            range->num_ids = 0x10000;
>          } else {
>              range->source_id_base = s->pci_iommu_bdf + 1;
> +            range->num_ids = 0xffff - s->pci_iommu_bdf;
>          }
> -        range->num_ids = 0xffff - s->pci_iommu_bdf;
>          build_rimt_id_mapping(table_data, range->source_id_base,
>                                range->num_ids, iommu_offset);
>      }
> --
> 2.51.2
>
>