commit acf7e2c93cb3efda0add6fd5f3b5b447e63d6367 (HEAD -> master)
Author: paulian <paulian@marinca.net>
Date: Sun Apr 12 18:08:45 2026 +0300
hw/i386/intel_iommu: advertise PT in ECAP, not CAP
Commit c7b2e22bd957 ("hw/i386/x86-iommu: Remove X86IOMMUState::pt_supported
field") made pass-through translation type always supported, but moved
VTD_ECAP_PT into s->cap in vtd_cap_init().
VTD_ECAP_PT is an ECAP bit, not a CAP bit, and the rest of the VT-d code
checks it via s->ecap. Advertise PT in s->ecap and stop setting the bit in
s->cap.
Fixes: c7b2e22bd957 ("hw/i386/x86-iommu: Remove
X86IOMMUState::pt_supported field")
Signed-off-by: Paulian Marinca <paulian@marinca.net>
diff --git a/hw/i386/intel_iommu.c b/hw/i386/intel_iommu.c
index f395fa248c..7b2cead8f8 100644
--- a/hw/i386/intel_iommu.c
+++ b/hw/i386/intel_iommu.c
@@ -4998,7 +4998,7 @@ static void vtd_cap_init(IntelIOMMUState *s)
{
X86IOMMUState *x86_iommu = X86_IOMMU_DEVICE(s);
- s->cap = VTD_CAP_FRO | VTD_CAP_NFR | VTD_CAP_ND | VTD_ECAP_PT |
+ s->cap = VTD_CAP_FRO | VTD_CAP_NFR | VTD_CAP_ND |
VTD_CAP_MAMV | VTD_CAP_PSI | VTD_CAP_SSLPS | VTD_CAP_DRAIN |
VTD_CAP_ESRTPS | VTD_CAP_MGAW(s->aw_bits);
if (x86_iommu->dma_translation) {
@@ -5009,7 +5009,7 @@ static void vtd_cap_init(IntelIOMMUState *s)
s->cap |= VTD_CAP_SAGAW_48bit;
}
}
- s->ecap = VTD_ECAP_QI | VTD_ECAP_IRO;
+ s->ecap = VTD_ECAP_QI | VTD_ECAP_IRO | VTD_ECAP_PT;
if (x86_iommu_ir_supported(x86_iommu)) {
s->ecap |= VTD_ECAP_IR | VTD_ECAP_MHMV;
Good catch!
Reviewed-by: Clement Mathieu--Drif <clement.mathieu--drif@bull.com>
Thanks
On Sun, 2026-04-12 at 18:17 +0300, Paulian Bogdan Marinca wrote:
> commit acf7e2c93cb3efda0add6fd5f3b5b447e63d6367 (HEAD -> master)
> Author: paulian <[paulian@marinca.net](mailto:paulian@marinca.net)>
> Date: Sun Apr 12 18:08:45 2026 +0300
>
> hw/i386/intel_iommu: advertise PT in ECAP, not CAP
>
> Commit c7b2e22bd957 ("hw/i386/x86-iommu: Remove X86IOMMUState::pt_supported
> field") made pass-through translation type always supported, but moved
> VTD_ECAP_PT into s->cap in vtd_cap_init().
>
> VTD_ECAP_PT is an ECAP bit, not a CAP bit, and the rest of the VT-d code
> checks it via s->ecap. Advertise PT in s->ecap and stop setting the bit in
> s->cap.
>
> Fixes: c7b2e22bd957 ("hw/i386/x86-iommu: Remove
> X86IOMMUState::pt_supported field")
> Signed-off-by: Paulian Marinca <[paulian@marinca.net](mailto:paulian@marinca.net)>
>
> diff --git a/hw/i386/intel_iommu.c b/hw/i386/intel_iommu.c
> index f395fa248c..7b2cead8f8 100644
> --- a/hw/i386/intel_iommu.c
> +++ b/hw/i386/intel_iommu.c
> @@ -4998,7 +4998,7 @@ static void vtd_cap_init(IntelIOMMUState *s)
> {
> X86IOMMUState *x86_iommu = X86_IOMMU_DEVICE(s);
>
> - s->cap = VTD_CAP_FRO | VTD_CAP_NFR | VTD_CAP_ND | VTD_ECAP_PT |
> + s->cap = VTD_CAP_FRO | VTD_CAP_NFR | VTD_CAP_ND |
> VTD_CAP_MAMV | VTD_CAP_PSI | VTD_CAP_SSLPS | VTD_CAP_DRAIN |
> VTD_CAP_ESRTPS | VTD_CAP_MGAW(s->aw_bits);
> if (x86_iommu->dma_translation) {
> @@ -5009,7 +5009,7 @@ static void vtd_cap_init(IntelIOMMUState *s)
> s->cap |= VTD_CAP_SAGAW_48bit;
> }
> }
> - s->ecap = VTD_ECAP_QI | VTD_ECAP_IRO;
> + s->ecap = VTD_ECAP_QI | VTD_ECAP_IRO | VTD_ECAP_PT;
>
> if (x86_iommu_ir_supported(x86_iommu)) {
> s->ecap |= VTD_ECAP_IR | VTD_ECAP_MHMV;
>
© 2016 - 2026 Red Hat, Inc.