[PULL 16/51] intel_iommu: Handle insufficient permissions during translation requests

Michael S. Tsirkin posted 51 patches 4 days, 4 hours ago
Maintainers: "Gonglei (Arei)" <arei.gonglei@huawei.com>, zhenwei pi <zhenwei.pi@linux.dev>, "Michael S. Tsirkin" <mst@redhat.com>, Stefano Garzarella <sgarzare@redhat.com>, Pierrick Bouvier <pierrick.bouvier@linaro.org>, Igor Mammedov <imammedo@redhat.com>, Ani Sinha <anisinha@redhat.com>, Dongjiu Geng <gengdongjiu1@gmail.com>, Marcel Apfelbaum <marcel.apfelbaum@gmail.com>, Raphael Norwitz <raphael@enfabrica.net>, Kevin Wolf <kwolf@redhat.com>, Hanna Reitz <hreitz@redhat.com>, Jonathan Cameron <jonathan.cameron@huawei.com>, Fan Ni <fan.ni@samsung.com>, Albert Esteve <aesteve@redhat.com>, "Alex Bennée" <alex.bennee@linaro.org>, Akihiko Odaki <odaki@rsg.ci.i.u-tokyo.ac.jp>, Dmitry Osipenko <dmitry.osipenko@collabora.com>, Paolo Bonzini <pbonzini@redhat.com>, Richard Henderson <richard.henderson@linaro.org>, Eduardo Habkost <eduardo@habkost.net>, Jason Wang <jasowang@redhat.com>, Yi Liu <yi.l.liu@intel.com>, "Clément Mathieu--Drif" <clement.mathieu--drif@eviden.com>, BALATON Zoltan <balaton@eik.bme.hu>, "Cédric Le Goater" <clg@kaod.org>, Peter Maydell <peter.maydell@linaro.org>, Steven Lee <steven_lee@aspeedtech.com>, Troy Lee <leetroy@gmail.com>, Jamin Lin <jamin_lin@aspeedtech.com>, Andrew Jeffery <andrew@codeconstruct.com.au>, Joel Stanley <joel@jms.id.au>, Andrey Smirnov <andrew.smirnov@gmail.com>, Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>, "Philippe Mathieu-Daudé" <philmd@linaro.org>, Aurelien Jarno <aurelien@aurel32.net>, Nicholas Piggin <npiggin@gmail.com>, Aditya Gupta <adityag@linux.ibm.com>, Glenn Miles <milesg@linux.ibm.com>, Bernhard Beschow <shentey@gmail.com>, "Hervé Poussineau" <hpoussin@reactos.org>, Elena Ufimtseva <elena.ufimtseva@oracle.com>, Jagannathan Raman <jag.raman@oracle.com>, Paul Burton <paulburton@kernel.org>, Aleksandar Rikalo <arikalo@gmail.com>, "Eugenio Pérez" <eperezma@redhat.com>, Haixu Cui <quic_haixcui@quicinc.com>, Peter Xu <peterx@redhat.com>, Fabiano Rosas <farosas@suse.de>, Cornelia Huck <cohuck@redhat.com>, Eric Blake <eblake@redhat.com>, Markus Armbruster <armbru@redhat.com>, Laurent Vivier <lvivier@redhat.com>
There is a newer version of this series
[PULL 16/51] intel_iommu: Handle insufficient permissions during translation requests
Posted by Michael S. Tsirkin 4 days, 5 hours ago
From: CLEMENT MATHIEU--DRIF <clement.mathieu--drif@eviden.com>

ATS translations should not fail when the write permission is not set.

Signed-off-by: Clement Mathieu--Drif <clement.mathieu--drif@eviden.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Message-Id: <20251029105137.1097933-6-clement.mathieu--drif@eviden.com>
---
 hw/i386/intel_iommu.c          | 14 ++++++++------
 hw/i386/intel_iommu_internal.h |  3 ++-
 2 files changed, 10 insertions(+), 7 deletions(-)

diff --git a/hw/i386/intel_iommu.c b/hw/i386/intel_iommu.c
index 7e7c31cb55..6ba1c1676b 100644
--- a/hw/i386/intel_iommu.c
+++ b/hw/i386/intel_iommu.c
@@ -1998,7 +1998,7 @@ static int vtd_iova_to_fspte(IntelIOMMUState *s, VTDContextEntry *ce,
                              uint64_t iova, bool is_write,
                              uint64_t *fsptep, uint32_t *fspte_level,
                              bool *reads, bool *writes, uint8_t aw_bits,
-                             uint32_t pasid)
+                             uint32_t pasid, int iommu_idx)
 {
     dma_addr_t addr = vtd_get_iova_pgtbl_base(s, ce, pasid);
     uint32_t offset;
@@ -2039,7 +2039,8 @@ static int vtd_iova_to_fspte(IntelIOMMUState *s, VTDContextEntry *ce,
 
         *reads = true;
         *writes = (*writes) && (fspte & VTD_FS_RW);
-        if (is_write && !(fspte & VTD_FS_RW)) {
+        /* ATS should not fail when the write permission is not set */
+        if (is_write && !(fspte & VTD_FS_RW) && iommu_idx != VTD_IDX_ATS) {
             return -VTD_FR_SM_WRITE;
         }
         if (vtd_fspte_nonzero_rsvd(fspte, *fspte_level)) {
@@ -2098,7 +2099,7 @@ static void vtd_report_fault(IntelIOMMUState *s,
  */
 static bool vtd_do_iommu_translate(VTDAddressSpace *vtd_as, PCIBus *bus,
                                    uint8_t devfn, hwaddr addr, bool is_write,
-                                   IOMMUTLBEntry *entry)
+                                   IOMMUTLBEntry *entry, int iommu_idx)
 {
     IntelIOMMUState *s = vtd_as->iommu_state;
     VTDContextEntry ce;
@@ -2204,7 +2205,8 @@ static bool vtd_do_iommu_translate(VTDAddressSpace *vtd_as, PCIBus *bus,
 
     if (s->fsts && s->root_scalable) {
         ret_fr = vtd_iova_to_fspte(s, &ce, addr, is_write, &pte, &level,
-                                   &reads, &writes, s->aw_bits, pasid);
+                                   &reads, &writes, s->aw_bits, pasid,
+                                   iommu_idx);
         pgtt = VTD_SM_PASID_ENTRY_FST;
     } else {
         ret_fr = vtd_iova_to_sspte(s, &ce, addr, is_write, &pte, &level,
@@ -4033,7 +4035,7 @@ static IOMMUTLBEntry vtd_iommu_translate(IOMMUMemoryRegion *iommu, hwaddr addr,
             }
         } else {
             success = vtd_do_iommu_translate(vtd_as, vtd_as->bus, vtd_as->devfn,
-                                            addr, is_write, &iotlb);
+                                            addr, is_write, &iotlb, iommu_idx);
         }
     } else {
         /* DMAR disabled, passthrough, use 4k-page*/
@@ -5196,7 +5198,7 @@ static IOMMUTLBEntry vtd_iommu_ats_do_translate(IOMMUMemoryRegion *iommu,
         vtd_prepare_error_entry(&entry);
         entry.target_as = &address_space_memory;
     } else {
-        entry = vtd_iommu_translate(iommu, addr, flags, VTD_IDX_UNTRANSLATED);
+        entry = vtd_iommu_translate(iommu, addr, flags, VTD_IDX_ATS);
     }
 
     return entry;
diff --git a/hw/i386/intel_iommu_internal.h b/hw/i386/intel_iommu_internal.h
index be757c290d..18d50191d2 100644
--- a/hw/i386/intel_iommu_internal.h
+++ b/hw/i386/intel_iommu_internal.h
@@ -692,7 +692,8 @@ typedef struct VTDPIOTLBInvInfo {
 typedef enum VTDIOMMUIndex {
     VTD_IDX_UNTRANSLATED = 0, /* Default */
     VTD_IDX_TRANSLATED = 1,
-    VTD_IDX_COUNT = 2, /* Number of supported indexes */
+    VTD_IDX_ATS = 2,
+    VTD_IDX_COUNT = 3, /* Number of supported indexes */
 } VTDIOMMUIndex;
 
 typedef struct VTDHostIOMMUDevice {
-- 
MST