[PATCH] intel_iommu: Check address mask before using it in pasid-based iotlb invalidation

Clément MATHIEU--DRIF posted 1 patch 1 week, 3 days ago
Patches applied successfully (tree, apply log)
git fetch https://github.com/patchew-project/qemu tags/patchew/20260715132652.1488991-1-clement.mathieu--drif@bull.com
Maintainers: "Michael S. Tsirkin" <mst@redhat.com>, Jason Wang <jasowangio@gmail.com>, Yi Liu <yi.l.liu@intel.com>, "Clément Mathieu--Drif" <clement.mathieu--drif@bull.com>, Paolo Bonzini <pbonzini@redhat.com>, Richard Henderson <richard.henderson@linaro.org>
There is a newer version of this series
hw/i386/intel_iommu.c | 9 +++++++++
1 file changed, 9 insertions(+)
[PATCH] intel_iommu: Check address mask before using it in pasid-based iotlb invalidation
Posted by Clément MATHIEU--DRIF 1 week, 3 days ago
Prevent a buggy driver to execute malformed invalidation operations.

Add the same assert as in vtd_iotlb_page_invalidate.

Link: https://gitlab.com/qemu-project/qemu/-/work_items/3619
Fixes: 6ebe6cf2a066 ("intel_iommu: Process PASID-based iotlb invalidation")
Signed-off-by: Clement Mathieu--Drif <clement.mathieu--drif@bull.com>
---
 hw/i386/intel_iommu.c | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/hw/i386/intel_iommu.c b/hw/i386/intel_iommu.c
index bf4f0f2f6b..c591d1db3f 100644
--- a/hw/i386/intel_iommu.c
+++ b/hw/i386/intel_iommu.c
@@ -3021,6 +3021,8 @@ static void vtd_piotlb_page_invalidate(IntelIOMMUState *s, uint16_t domain_id,
 {
     VTDIOTLBPageInvInfo info;
 
+    assert(am <= VTD_MAMV);
+
     info.domain_id = domain_id;
     info.pasid = pasid;
     info.addr = addr;
@@ -3060,6 +3062,13 @@ static bool vtd_process_piotlb_desc(IntelIOMMUState *s,
 
     case VTD_INV_DESC_PIOTLB_PSI_IN_PASID:
         am = VTD_INV_DESC_PIOTLB_AM(inv_desc->val[1]);
+        if (am > VTD_MAMV) {
+            error_report_once("%s: invalid piotlb inv desc: hi=0x%"PRIx64
+                              ", lo=0x%"PRIx64" (am=%u > VTD_MAMV=%u)",
+                              __func__, inv_desc->val[1], inv_desc->val[0],
+                              am, (unsigned)VTD_MAMV);
+            return false;
+        }
         addr = (hwaddr) VTD_INV_DESC_PIOTLB_ADDR(inv_desc->val[1]);
         vtd_piotlb_page_invalidate(s, domain_id, pasid, addr, am,
                                    VTD_INV_DESC_PIOTLB_IH(inv_desc));
-- 
2.54.0
Re: [PATCH] intel_iommu: Check address mask before using it in pasid-based iotlb invalidation
Posted by Philippe Mathieu-Daudé 1 day, 10 hours ago
On 15/7/26 15:27, Clément MATHIEU--DRIF wrote:
> Prevent a buggy driver to execute malformed invalidation operations.
> 
> Add the same assert as in vtd_iotlb_page_invalidate.
> 
> Link: https://gitlab.com/qemu-project/qemu/-/work_items/3619
> Fixes: 6ebe6cf2a066 ("intel_iommu: Process PASID-based iotlb invalidation")
> Signed-off-by: Clement Mathieu--Drif <clement.mathieu--drif@bull.com>
> ---
>   hw/i386/intel_iommu.c | 9 +++++++++
>   1 file changed, 9 insertions(+)
> 
> diff --git a/hw/i386/intel_iommu.c b/hw/i386/intel_iommu.c
> index bf4f0f2f6b..c591d1db3f 100644
> --- a/hw/i386/intel_iommu.c
> +++ b/hw/i386/intel_iommu.c
> @@ -3021,6 +3021,8 @@ static void vtd_piotlb_page_invalidate(IntelIOMMUState *s, uint16_t domain_id,
>   {
>       VTDIOTLBPageInvInfo info;
>   
> +    assert(am <= VTD_MAMV);
> +
>       info.domain_id = domain_id;
>       info.pasid = pasid;
>       info.addr = addr;
> @@ -3060,6 +3062,13 @@ static bool vtd_process_piotlb_desc(IntelIOMMUState *s,
>   
>       case VTD_INV_DESC_PIOTLB_PSI_IN_PASID:
>           am = VTD_INV_DESC_PIOTLB_AM(inv_desc->val[1]);
> +        if (am > VTD_MAMV) {
> +            error_report_once("%s: invalid piotlb inv desc: hi=0x%"PRIx64
> +                              ", lo=0x%"PRIx64" (am=%u > VTD_MAMV=%u)",
> +                              __func__, inv_desc->val[1], inv_desc->val[0],
> +                              am, (unsigned)VTD_MAMV);

Better use the PRIu64 format instead of this surprising cast, anyway:
Reviewed-by: Philippe Mathieu-Daudé <philmd@oss.qualcomm.com>

> +            return false;
> +        }
>           addr = (hwaddr) VTD_INV_DESC_PIOTLB_ADDR(inv_desc->val[1]);
>           vtd_piotlb_page_invalidate(s, domain_id, pasid, addr, am,
>                                      VTD_INV_DESC_PIOTLB_IH(inv_desc));


Re: [PATCH] intel_iommu: Check address mask before using it in pasid-based iotlb invalidation
Posted by Michael S. Tsirkin 1 day, 8 hours ago
On Fri, Jul 24, 2026 at 08:08:50AM +0200, Philippe Mathieu-Daudé wrote:
> On 15/7/26 15:27, Clément MATHIEU--DRIF wrote:
> > Prevent a buggy driver to execute malformed invalidation operations.
> > 
> > Add the same assert as in vtd_iotlb_page_invalidate.
> > 
> > Link: https://gitlab.com/qemu-project/qemu/-/work_items/3619
> > Fixes: 6ebe6cf2a066 ("intel_iommu: Process PASID-based iotlb invalidation")
> > Signed-off-by: Clement Mathieu--Drif <clement.mathieu--drif@bull.com>
> > ---
> >   hw/i386/intel_iommu.c | 9 +++++++++
> >   1 file changed, 9 insertions(+)
> > 
> > diff --git a/hw/i386/intel_iommu.c b/hw/i386/intel_iommu.c
> > index bf4f0f2f6b..c591d1db3f 100644
> > --- a/hw/i386/intel_iommu.c
> > +++ b/hw/i386/intel_iommu.c
> > @@ -3021,6 +3021,8 @@ static void vtd_piotlb_page_invalidate(IntelIOMMUState *s, uint16_t domain_id,
> >   {
> >       VTDIOTLBPageInvInfo info;
> > +    assert(am <= VTD_MAMV);
> > +
> >       info.domain_id = domain_id;
> >       info.pasid = pasid;
> >       info.addr = addr;
> > @@ -3060,6 +3062,13 @@ static bool vtd_process_piotlb_desc(IntelIOMMUState *s,
> >       case VTD_INV_DESC_PIOTLB_PSI_IN_PASID:
> >           am = VTD_INV_DESC_PIOTLB_AM(inv_desc->val[1]);
> > +        if (am > VTD_MAMV) {
> > +            error_report_once("%s: invalid piotlb inv desc: hi=0x%"PRIx64
> > +                              ", lo=0x%"PRIx64" (am=%u > VTD_MAMV=%u)",
> > +                              __func__, inv_desc->val[1], inv_desc->val[0],
> > +                              am, (unsigned)VTD_MAMV);
> 
> Better use the PRIu64 format instead of this surprising cast,

I think you mean %llu - PRIu64 is for uint64_t

> anyway:
> Reviewed-by: Philippe Mathieu-Daudé <philmd@oss.qualcomm.com>
> 
> > +            return false;
> > +        }
> >           addr = (hwaddr) VTD_INV_DESC_PIOTLB_ADDR(inv_desc->val[1]);
> >           vtd_piotlb_page_invalidate(s, domain_id, pasid, addr, am,
> >                                      VTD_INV_DESC_PIOTLB_IH(inv_desc));
Re: [PATCH] intel_iommu: Check address mask before using it in pasid-based iotlb invalidation
Posted by Philippe Mathieu-Daudé 1 day, 8 hours ago
On 24/7/26 10:31, Michael S. Tsirkin wrote:
> On Fri, Jul 24, 2026 at 08:08:50AM +0200, Philippe Mathieu-Daudé wrote:
>> On 15/7/26 15:27, Clément MATHIEU--DRIF wrote:
>>> Prevent a buggy driver to execute malformed invalidation operations.
>>>
>>> Add the same assert as in vtd_iotlb_page_invalidate.
>>>
>>> Link: https://gitlab.com/qemu-project/qemu/-/work_items/3619
>>> Fixes: 6ebe6cf2a066 ("intel_iommu: Process PASID-based iotlb invalidation")
>>> Signed-off-by: Clement Mathieu--Drif <clement.mathieu--drif@bull.com>
>>> ---
>>>    hw/i386/intel_iommu.c | 9 +++++++++
>>>    1 file changed, 9 insertions(+)
>>>
>>> diff --git a/hw/i386/intel_iommu.c b/hw/i386/intel_iommu.c
>>> index bf4f0f2f6b..c591d1db3f 100644
>>> --- a/hw/i386/intel_iommu.c
>>> +++ b/hw/i386/intel_iommu.c
>>> @@ -3021,6 +3021,8 @@ static void vtd_piotlb_page_invalidate(IntelIOMMUState *s, uint16_t domain_id,
>>>    {
>>>        VTDIOTLBPageInvInfo info;
>>> +    assert(am <= VTD_MAMV);
>>> +
>>>        info.domain_id = domain_id;
>>>        info.pasid = pasid;
>>>        info.addr = addr;
>>> @@ -3060,6 +3062,13 @@ static bool vtd_process_piotlb_desc(IntelIOMMUState *s,
>>>        case VTD_INV_DESC_PIOTLB_PSI_IN_PASID:
>>>            am = VTD_INV_DESC_PIOTLB_AM(inv_desc->val[1]);
>>> +        if (am > VTD_MAMV) {
>>> +            error_report_once("%s: invalid piotlb inv desc: hi=0x%"PRIx64
>>> +                              ", lo=0x%"PRIx64" (am=%u > VTD_MAMV=%u)",
>>> +                              __func__, inv_desc->val[1], inv_desc->val[0],
>>> +                              am, (unsigned)VTD_MAMV);
>>
>> Better use the PRIu64 format instead of this surprising cast,
> 
> I think you mean %llu - PRIu64 is for uint64_t

Yes <:)

> 
>> anyway:
>> Reviewed-by: Philippe Mathieu-Daudé <philmd@oss.qualcomm.com>
>>
>>> +            return false;
>>> +        }
>>>            addr = (hwaddr) VTD_INV_DESC_PIOTLB_ADDR(inv_desc->val[1]);
>>>            vtd_piotlb_page_invalidate(s, domain_id, pasid, addr, am,
>>>                                       VTD_INV_DESC_PIOTLB_IH(inv_desc));
> 
> 


RE: [PATCH] intel_iommu: Check address mask before using it in pasid-based iotlb invalidation
Posted by Duan, Zhenzhong 1 day, 14 hours ago
Hi Clement,

>-----Original Message-----
>From: Clément MATHIEU--DRIF <clement.mathieu--drif@bull.com>
>Subject: [PATCH] intel_iommu: Check address mask before using it in pasid-based
>iotlb invalidation
>
>Prevent a buggy driver to execute malformed invalidation operations.
>
>Add the same assert as in vtd_iotlb_page_invalidate.
>
>Link: https://gitlab.com/qemu-project/qemu/-/work_items/3619
>Fixes: 6ebe6cf2a066 ("intel_iommu: Process PASID-based iotlb invalidation")
>Signed-off-by: Clement Mathieu--Drif <clement.mathieu--drif@bull.com>

Reviewed-by: Zhenzhong Duan <zhenzhong.duan@intel.com>

Thanks
Zhenzhong

>---
> hw/i386/intel_iommu.c | 9 +++++++++
> 1 file changed, 9 insertions(+)
>
>diff --git a/hw/i386/intel_iommu.c b/hw/i386/intel_iommu.c
>index bf4f0f2f6b..c591d1db3f 100644
>--- a/hw/i386/intel_iommu.c
>+++ b/hw/i386/intel_iommu.c
>@@ -3021,6 +3021,8 @@ static void
>vtd_piotlb_page_invalidate(IntelIOMMUState *s, uint16_t domain_id,
> {
>     VTDIOTLBPageInvInfo info;
>
>+    assert(am <= VTD_MAMV);
>+
>     info.domain_id = domain_id;
>     info.pasid = pasid;
>     info.addr = addr;
>@@ -3060,6 +3062,13 @@ static bool vtd_process_piotlb_desc(IntelIOMMUState
>*s,
>
>     case VTD_INV_DESC_PIOTLB_PSI_IN_PASID:
>         am = VTD_INV_DESC_PIOTLB_AM(inv_desc->val[1]);
>+        if (am > VTD_MAMV) {
>+            error_report_once("%s: invalid piotlb inv desc: hi=0x%"PRIx64
>+                              ", lo=0x%"PRIx64" (am=%u > VTD_MAMV=%u)",
>+                              __func__, inv_desc->val[1], inv_desc->val[0],
>+                              am, (unsigned)VTD_MAMV);
>+            return false;
>+        }
>         addr = (hwaddr) VTD_INV_DESC_PIOTLB_ADDR(inv_desc->val[1]);
>         vtd_piotlb_page_invalidate(s, domain_id, pasid, addr, am,
>                                    VTD_INV_DESC_PIOTLB_IH(inv_desc));
>--
>2.54.0