All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH intel_iommu 1/7] intel_iommu: fix FRCD construction macro.
  2024-04-22 15:52 [PATCH intel_iommu 0/7] FLTS for VT-d CLEMENT MATHIEU--DRIF
@ 2024-04-22 15:52 ` CLEMENT MATHIEU--DRIF
  2024-04-22 15:52 ` [PATCH intel_iommu 2/7] intel_iommu: rename slpte to pte before adding FLTS CLEMENT MATHIEU--DRIF
                   ` (7 subsequent siblings)
  8 siblings, 0 replies; 22+ messages in thread
From: CLEMENT MATHIEU--DRIF @ 2024-04-22 15:52 UTC (permalink / raw)
  To: qemu-devel; +Cc: jasowang, CLEMENT MATHIEU--DRIF

The constant must be unsigned, otherwise the two's complement
overrides the other fields when a PASID is present

Signed-off-by: Clément Mathieu--Drif <clement.mathieu--drif@eviden.com>
---
 hw/i386/intel_iommu_internal.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/hw/i386/intel_iommu_internal.h b/hw/i386/intel_iommu_internal.h
index f8cf99bddf..cbc4030031 100644
--- a/hw/i386/intel_iommu_internal.h
+++ b/hw/i386/intel_iommu_internal.h
@@ -267,7 +267,7 @@
 /* For the low 64-bit of 128-bit */
 #define VTD_FRCD_FI(val)        ((val) & ~0xfffULL)
 #define VTD_FRCD_PV(val)        (((val) & 0xffffULL) << 40)
-#define VTD_FRCD_PP(val)        (((val) & 0x1) << 31)
+#define VTD_FRCD_PP(val)        (((val) & 0x1ULL) << 31)
 #define VTD_FRCD_IR_IDX(val)    (((val) & 0xffffULL) << 48)
 
 /* DMA Remapping Fault Conditions */
-- 
2.44.0

^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [PATCH intel_iommu 0/7] FLTS for VT-d
@ 2024-04-22 15:52 CLEMENT MATHIEU--DRIF
  2024-04-22 15:52 ` [PATCH intel_iommu 1/7] intel_iommu: fix FRCD construction macro CLEMENT MATHIEU--DRIF
                   ` (8 more replies)
  0 siblings, 9 replies; 22+ messages in thread
From: CLEMENT MATHIEU--DRIF @ 2024-04-22 15:52 UTC (permalink / raw)
  To: qemu-devel; +Cc: jasowang, CLEMENT MATHIEU--DRIF

This series is the first of a list that add support for SVM in the Intel IOMMU.

Here, we implement support for first-stage translation in VT-d.
The PASID-based IOTLB invalidation is also added in this series as it is a
requirement of FLTS.

The last patch introduces the 'flts' option to enable the feature from
the command line.
Once enabled, several drivers of the Linux kernel use this feature.

This work is based on the VT-d specification version 4.1 (March 2023)

Here is a link to a GitHub repository where you can find the following elements :
    - Qemu with all the patches for SVM
        - ATS
        - PRI
        - PASID based IOTLB invalidation
        - Device IOTLB invalidations
        - First-stage translations
        - Requests with already translated addresses
    - A demo device
    - A simple driver for the demo device
    - A userspace program (for testing and demonstration purposes)

https://github.com/BullSequana/Qemu-in-guest-SVM-demo

Clément Mathieu--Drif (7):
  intel_iommu: fix FRCD construction macro.
  intel_iommu: rename slpte to pte before adding FLTS
  intel_iommu: make types match
  intel_iommu: add support for first-stage translation
  intel_iommu: extract device IOTLB invalidation logic
  intel_iommu: add PASID-based IOTLB invalidation
  intel_iommu: add a CLI option to enable FLTS

 hw/i386/intel_iommu.c          | 655 ++++++++++++++++++++++++++-------
 hw/i386/intel_iommu_internal.h | 114 ++++--
 include/hw/i386/intel_iommu.h  |   3 +-
 3 files changed, 609 insertions(+), 163 deletions(-)

-- 
2.44.0

^ permalink raw reply	[flat|nested] 22+ messages in thread

* [PATCH intel_iommu 2/7] intel_iommu: rename slpte to pte before adding FLTS
  2024-04-22 15:52 [PATCH intel_iommu 0/7] FLTS for VT-d CLEMENT MATHIEU--DRIF
  2024-04-22 15:52 ` [PATCH intel_iommu 1/7] intel_iommu: fix FRCD construction macro CLEMENT MATHIEU--DRIF
@ 2024-04-22 15:52 ` CLEMENT MATHIEU--DRIF
  2024-04-22 15:52 ` [PATCH intel_iommu 7/7] intel_iommu: add a CLI option to enable FLTS CLEMENT MATHIEU--DRIF
                   ` (6 subsequent siblings)
  8 siblings, 0 replies; 22+ messages in thread
From: CLEMENT MATHIEU--DRIF @ 2024-04-22 15:52 UTC (permalink / raw)
  To: qemu-devel; +Cc: jasowang, CLEMENT MATHIEU--DRIF

Some variables struct fields and functions can be used for both
slpte and flpte. We can modify certain identifiers to make them
more generic.

- slpte in IOMMUTLBEntry becomes pte and will be used for both FL and SL
- VTD_SL_PT_LEVEL, VTD_SL_PT_PAGE_SIZE_MASK and VTD_SL_LEVEL_BITS can be
  renamed and considered as a common constants
- vtd_iova_range_check becomes vtd_iova_sl_range_check because the range
  check depends on the translation type
- vtd_do_iommu_translate now handles both FL and SL so we can rename
  slpte to pte
- VTD_SL_PT_BASE_ADDR_MASK becomes VTD_PT_BASE_ADDR_MASK because the
  address offset within a 64bits word of a Scalable-Mode PASID Table
  Entry is the same for FL and SL. As a consequence, vtd_get_slpte_addr
  is also renamed to vtd_get_pte_addr.
- vtd_is_last_slpte becomes vtd_is_last_slpte because the same bit is
  used for FL and SL.
- vtd_slpt_level_page_mask becomes vtd_pt_level_page_mask
- vtd_get_slpte becomes vtd_get_pte

Signed-off-by: Clément Mathieu--Drif <clement.mathieu--drif@eviden.com>
---
 hw/i386/intel_iommu.c          | 106 ++++++++++++++++-----------------
 hw/i386/intel_iommu_internal.h |  10 ++--
 include/hw/i386/intel_iommu.h  |   2 +-
 3 files changed, 60 insertions(+), 58 deletions(-)

diff --git a/hw/i386/intel_iommu.c b/hw/i386/intel_iommu.c
index cc8e59674e..6f1364b3fd 100644
--- a/hw/i386/intel_iommu.c
+++ b/hw/i386/intel_iommu.c
@@ -259,15 +259,15 @@ static gboolean vtd_hash_remove_by_domain(gpointer key, gpointer value,
 }
 
 /* The shift of an addr for a certain level of paging structure */
-static inline uint32_t vtd_slpt_level_shift(uint32_t level)
+static inline uint32_t vtd_pt_level_shift(uint32_t level)
 {
     assert(level != 0);
-    return VTD_PAGE_SHIFT_4K + (level - 1) * VTD_SL_LEVEL_BITS;
+    return VTD_PAGE_SHIFT_4K + (level - 1) * VTD_LEVEL_BITS;
 }
 
-static inline uint64_t vtd_slpt_level_page_mask(uint32_t level)
+static inline uint64_t vtd_pt_level_page_mask(uint32_t level)
 {
-    return ~((1ULL << vtd_slpt_level_shift(level)) - 1);
+    return ~((1ULL << vtd_pt_level_shift(level)) - 1);
 }
 
 static gboolean vtd_hash_remove_by_page(gpointer key, gpointer value,
@@ -324,7 +324,7 @@ static void vtd_reset_caches(IntelIOMMUState *s)
 
 static uint64_t vtd_get_iotlb_gfn(hwaddr addr, uint32_t level)
 {
-    return (addr & vtd_slpt_level_page_mask(level)) >> VTD_PAGE_SHIFT_4K;
+    return (addr & vtd_pt_level_page_mask(level)) >> VTD_PAGE_SHIFT_4K;
 }
 
 /* Must be called with IOMMU lock held */
@@ -352,7 +352,7 @@ out:
 
 /* Must be with IOMMU lock held */
 static void vtd_update_iotlb(IntelIOMMUState *s, uint16_t source_id,
-                             uint16_t domain_id, hwaddr addr, uint64_t slpte,
+                             uint16_t domain_id, hwaddr addr, uint64_t pte,
                              uint8_t access_flags, uint32_t level,
                              uint32_t pasid)
 {
@@ -360,7 +360,7 @@ static void vtd_update_iotlb(IntelIOMMUState *s, uint16_t source_id,
     struct vtd_iotlb_key *key = g_malloc(sizeof(*key));
     uint64_t gfn = vtd_get_iotlb_gfn(addr, level);
 
-    trace_vtd_iotlb_page_update(source_id, addr, slpte, domain_id);
+    trace_vtd_iotlb_page_update(source_id, addr, pte, domain_id);
     if (g_hash_table_size(s->iotlb) >= VTD_IOTLB_MAX_SIZE) {
         trace_vtd_iotlb_reset("iotlb exceeds size limit");
         vtd_reset_iotlb_locked(s);
@@ -368,9 +368,9 @@ static void vtd_update_iotlb(IntelIOMMUState *s, uint16_t source_id,
 
     entry->gfn = gfn;
     entry->domain_id = domain_id;
-    entry->slpte = slpte;
+    entry->pte = pte;
     entry->access_flags = access_flags;
-    entry->mask = vtd_slpt_level_page_mask(level);
+    entry->mask = vtd_pt_level_page_mask(level);
     entry->pasid = pasid;
 
     key->gfn = gfn;
@@ -685,32 +685,32 @@ static inline dma_addr_t vtd_ce_get_slpt_base(VTDContextEntry *ce)
     return ce->lo & VTD_CONTEXT_ENTRY_SLPTPTR;
 }
 
-static inline uint64_t vtd_get_slpte_addr(uint64_t slpte, uint8_t aw)
+static inline uint64_t vtd_get_pte_addr(uint64_t pte, uint8_t aw)
 {
-    return slpte & VTD_SL_PT_BASE_ADDR_MASK(aw);
+    return pte & VTD_PT_BASE_ADDR_MASK(aw);
 }
 
 /* Whether the pte indicates the address of the page frame */
-static inline bool vtd_is_last_slpte(uint64_t slpte, uint32_t level)
+static inline bool vtd_is_last_pte(uint64_t pte, uint32_t level)
 {
-    return level == VTD_SL_PT_LEVEL || (slpte & VTD_SL_PT_PAGE_SIZE_MASK);
+    return level == VTD_COMMON_PT_LEVEL || (pte & VTD_PT_PAGE_SIZE_MASK);
 }
 
-/* Get the content of a spte located in @base_addr[@index] */
-static uint64_t vtd_get_slpte(dma_addr_t base_addr, uint32_t index)
+/* Get the content of a pte located in @base_addr[@index] */
+static uint64_t vtd_get_pte(dma_addr_t base_addr, uint32_t index)
 {
-    uint64_t slpte;
+    uint64_t pte;
 
-    assert(index < VTD_SL_PT_ENTRY_NR);
+    assert(index < VTD_PT_ENTRY_NR);
 
     if (dma_memory_read(&address_space_memory,
-                        base_addr + index * sizeof(slpte),
-                        &slpte, sizeof(slpte), MEMTXATTRS_UNSPECIFIED)) {
-        slpte = (uint64_t)-1;
-        return slpte;
+                        base_addr + index * sizeof(pte),
+                        &pte, sizeof(pte), MEMTXATTRS_UNSPECIFIED)) {
+        pte = (uint64_t)-1;
+        return pte;
     }
-    slpte = le64_to_cpu(slpte);
-    return slpte;
+    pte = le64_to_cpu(pte);
+    return pte;
 }
 
 /* Given an iova and the level of paging structure, return the offset
@@ -718,8 +718,8 @@ static uint64_t vtd_get_slpte(dma_addr_t base_addr, uint32_t index)
  */
 static inline uint32_t vtd_iova_level_offset(uint64_t iova, uint32_t level)
 {
-    return (iova >> vtd_slpt_level_shift(level)) &
-            ((1ULL << VTD_SL_LEVEL_BITS) - 1);
+    return (iova >> vtd_pt_level_shift(level)) &
+            ((1ULL << VTD_LEVEL_BITS) - 1);
 }
 
 /* Check Capability Register to see if the @level of page-table is supported */
@@ -1016,7 +1016,7 @@ static inline uint64_t vtd_iova_limit(IntelIOMMUState *s,
 }
 
 /* Return true if IOVA passes range check, otherwise false. */
-static inline bool vtd_iova_range_check(IntelIOMMUState *s,
+static inline bool vtd_iova_sl_range_check(IntelIOMMUState *s,
                                         uint64_t iova, VTDContextEntry *ce,
                                         uint8_t aw, uint32_t pasid)
 {
@@ -1064,12 +1064,12 @@ static bool vtd_slpte_nonzero_rsvd(uint64_t slpte, uint32_t level)
     assert(level < VTD_SPTE_RSVD_LEN);
     /*
      * Zero level doesn't exist. The smallest level is VTD_SL_PT_LEVEL=1 and
-     * checked by vtd_is_last_slpte().
+     * checked by vtd_is_last_pte().
      */
     assert(level);
 
     if ((level == VTD_SL_PD_LEVEL || level == VTD_SL_PDP_LEVEL) &&
-        (slpte & VTD_SL_PT_PAGE_SIZE_MASK)) {
+        (slpte & VTD_PT_PAGE_SIZE_MASK)) {
         /* large page */
         rsvd_mask = vtd_spte_rsvd_large[level];
     } else {
@@ -1095,7 +1095,7 @@ static int vtd_iova_to_slpte(IntelIOMMUState *s, VTDContextEntry *ce,
     uint64_t access_right_check;
     uint64_t xlat, size;
 
-    if (!vtd_iova_range_check(s, iova, ce, aw_bits, pasid)) {
+    if (!vtd_iova_sl_range_check(s, iova, ce, aw_bits, pasid)) {
         error_report_once("%s: detected IOVA overflow (iova=0x%" PRIx64 ","
                           "pasid=0x%" PRIx32 ")", __func__, iova, pasid);
         return -VTD_FR_ADDR_BEYOND_MGAW;
@@ -1106,7 +1106,7 @@ static int vtd_iova_to_slpte(IntelIOMMUState *s, VTDContextEntry *ce,
 
     while (true) {
         offset = vtd_iova_level_offset(iova, level);
-        slpte = vtd_get_slpte(addr, offset);
+        slpte = vtd_get_pte(addr, offset);
 
         if (slpte == (uint64_t)-1) {
             error_report_once("%s: detected read error on DMAR slpte "
@@ -1137,17 +1137,17 @@ static int vtd_iova_to_slpte(IntelIOMMUState *s, VTDContextEntry *ce,
             return -VTD_FR_PAGING_ENTRY_RSVD;
         }
 
-        if (vtd_is_last_slpte(slpte, level)) {
+        if (vtd_is_last_pte(slpte, level)) {
             *slptep = slpte;
             *slpte_level = level;
             break;
         }
-        addr = vtd_get_slpte_addr(slpte, aw_bits);
+        addr = vtd_get_pte_addr(slpte, aw_bits);
         level--;
     }
 
-    xlat = vtd_get_slpte_addr(*slptep, aw_bits);
-    size = ~vtd_slpt_level_page_mask(level) + 1;
+    xlat = vtd_get_pte_addr(*slptep, aw_bits);
+    size = ~vtd_pt_level_page_mask(level) + 1;
 
     /*
      * From VT-d spec 3.14: Untranslated requests and translation
@@ -1298,14 +1298,14 @@ static int vtd_page_walk_level(dma_addr_t addr, uint64_t start,
 
     trace_vtd_page_walk_level(addr, level, start, end);
 
-    subpage_size = 1ULL << vtd_slpt_level_shift(level);
-    subpage_mask = vtd_slpt_level_page_mask(level);
+    subpage_size = 1ULL << vtd_pt_level_shift(level);
+    subpage_mask = vtd_pt_level_page_mask(level);
 
     while (iova < end) {
         iova_next = (iova & subpage_mask) + subpage_size;
 
         offset = vtd_iova_level_offset(iova, level);
-        slpte = vtd_get_slpte(addr, offset);
+        slpte = vtd_get_pte(addr, offset);
 
         if (slpte == (uint64_t)-1) {
             trace_vtd_page_walk_skip_read(iova, iova_next);
@@ -1328,12 +1328,12 @@ static int vtd_page_walk_level(dma_addr_t addr, uint64_t start,
          */
         entry_valid = read_cur | write_cur;
 
-        if (!vtd_is_last_slpte(slpte, level) && entry_valid) {
+        if (!vtd_is_last_pte(slpte, level) && entry_valid) {
             /*
              * This is a valid PDE (or even bigger than PDE).  We need
              * to walk one further level.
              */
-            ret = vtd_page_walk_level(vtd_get_slpte_addr(slpte, info->aw),
+            ret = vtd_page_walk_level(vtd_get_pte_addr(slpte, info->aw),
                                       iova, MIN(iova_next, end), level - 1,
                                       read_cur, write_cur, info);
         } else {
@@ -1350,7 +1350,7 @@ static int vtd_page_walk_level(dma_addr_t addr, uint64_t start,
             event.entry.perm = IOMMU_ACCESS_FLAG(read_cur, write_cur);
             event.entry.addr_mask = ~subpage_mask;
             /* NOTE: this is only meaningful if entry_valid == true */
-            event.entry.translated_addr = vtd_get_slpte_addr(slpte, info->aw);
+            event.entry.translated_addr = vtd_get_pte_addr(slpte, info->aw);
             event.type = event.entry.perm ? IOMMU_NOTIFIER_MAP :
                                             IOMMU_NOTIFIER_UNMAP;
             ret = vtd_page_walk_one(&event, info);
@@ -1384,11 +1384,11 @@ static int vtd_page_walk(IntelIOMMUState *s, VTDContextEntry *ce,
     dma_addr_t addr = vtd_get_iova_pgtbl_base(s, ce, pasid);
     uint32_t level = vtd_get_iova_level(s, ce, pasid);
 
-    if (!vtd_iova_range_check(s, start, ce, info->aw, pasid)) {
+    if (!vtd_iova_sl_range_check(s, start, ce, info->aw, pasid)) {
         return -VTD_FR_ADDR_BEYOND_MGAW;
     }
 
-    if (!vtd_iova_range_check(s, end, ce, info->aw, pasid)) {
+    if (!vtd_iova_sl_range_check(s, end, ce, info->aw, pasid)) {
         /* Fix end so that it reaches the maximum */
         end = vtd_iova_limit(s, ce, info->aw, pasid);
     }
@@ -1869,7 +1869,7 @@ static bool vtd_do_iommu_translate(VTDAddressSpace *vtd_as, PCIBus *bus,
     VTDContextEntry ce;
     uint8_t bus_num = pci_bus_num(bus);
     VTDContextCacheEntry *cc_entry;
-    uint64_t slpte, page_mask;
+    uint64_t pte, page_mask;
     uint32_t level, pasid = vtd_as->pasid;
     uint16_t source_id = PCI_BUILD_BDF(bus_num, devfn);
     int ret_fr;
@@ -1890,13 +1890,13 @@ static bool vtd_do_iommu_translate(VTDAddressSpace *vtd_as, PCIBus *bus,
 
     cc_entry = &vtd_as->context_cache_entry;
 
-    /* Try to fetch slpte form IOTLB, we don't need RID2PASID logic */
+    /* Try to fetch pte form IOTLB, we don't need RID2PASID logic */
     if (!rid2pasid) {
         iotlb_entry = vtd_lookup_iotlb(s, source_id, pasid, addr);
         if (iotlb_entry) {
-            trace_vtd_iotlb_page_hit(source_id, addr, iotlb_entry->slpte,
+            trace_vtd_iotlb_page_hit(source_id, addr, iotlb_entry->pte,
                                      iotlb_entry->domain_id);
-            slpte = iotlb_entry->slpte;
+            pte = iotlb_entry->pte;
             access_flags = iotlb_entry->access_flags;
             page_mask = iotlb_entry->mask;
             goto out;
@@ -1968,20 +1968,20 @@ static bool vtd_do_iommu_translate(VTDAddressSpace *vtd_as, PCIBus *bus,
         return true;
     }
 
-    /* Try to fetch slpte form IOTLB for RID2PASID slow path */
+    /* Try to fetch pte form IOTLB for RID2PASID slow path */
     if (rid2pasid) {
         iotlb_entry = vtd_lookup_iotlb(s, source_id, pasid, addr);
         if (iotlb_entry) {
-            trace_vtd_iotlb_page_hit(source_id, addr, iotlb_entry->slpte,
+            trace_vtd_iotlb_page_hit(source_id, addr, iotlb_entry->pte,
                                      iotlb_entry->domain_id);
-            slpte = iotlb_entry->slpte;
+            pte = iotlb_entry->pte;
             access_flags = iotlb_entry->access_flags;
             page_mask = iotlb_entry->mask;
             goto out;
         }
     }
 
-    ret_fr = vtd_iova_to_slpte(s, &ce, addr, is_write, &slpte, &level,
+    ret_fr = vtd_iova_to_slpte(s, &ce, addr, is_write, &pte, &level,
                                &reads, &writes, s->aw_bits, pasid);
     if (ret_fr) {
         vtd_report_fault(s, -ret_fr, is_fpd_set, source_id,
@@ -1989,14 +1989,14 @@ static bool vtd_do_iommu_translate(VTDAddressSpace *vtd_as, PCIBus *bus,
         goto error;
     }
 
-    page_mask = vtd_slpt_level_page_mask(level);
+    page_mask = vtd_pt_level_page_mask(level);
     access_flags = IOMMU_ACCESS_FLAG(reads, writes);
     vtd_update_iotlb(s, source_id, vtd_get_domain_id(s, &ce, pasid),
-                     addr, slpte, access_flags, level, pasid);
+                     addr, pte, access_flags, level, pasid);
 out:
     vtd_iommu_unlock(s);
     entry->iova = addr & page_mask;
-    entry->translated_addr = vtd_get_slpte_addr(slpte, s->aw_bits) & page_mask;
+    entry->translated_addr = vtd_get_pte_addr(pte, s->aw_bits) & page_mask;
     entry->addr_mask = ~page_mask;
     entry->perm = access_flags;
     return true;
diff --git a/hw/i386/intel_iommu_internal.h b/hw/i386/intel_iommu_internal.h
index cbc4030031..8d27b1c15b 100644
--- a/hw/i386/intel_iommu_internal.h
+++ b/hw/i386/intel_iommu_internal.h
@@ -518,22 +518,24 @@ typedef struct VTDRootEntry VTDRootEntry;
 #define VTD_SM_PASID_ENTRY_SLPTPTR     (~0xfffULL)
 
 /* Paging Structure common */
-#define VTD_SL_PT_PAGE_SIZE_MASK    (1ULL << 7)
+#define VTD_SM_PASID_ENTRY_PTPTR    (~0xfffULL)
+#define VTD_PT_PAGE_SIZE_MASK       (1ULL << 7)
+#define VTD_PT_ENTRY_NR             512
+#define VTD_PT_BASE_ADDR_MASK(aw)   (~(VTD_PAGE_SIZE - 1) & VTD_HAW_MASK(aw))
+#define VTD_COMMON_PT_LEVEL         1
 /* Bits to decide the offset for each level */
-#define VTD_SL_LEVEL_BITS           9
+#define VTD_LEVEL_BITS              9
 
 /* Second Level Paging Structure */
 #define VTD_SL_PML4_LEVEL           4
 #define VTD_SL_PDP_LEVEL            3
 #define VTD_SL_PD_LEVEL             2
 #define VTD_SL_PT_LEVEL             1
-#define VTD_SL_PT_ENTRY_NR          512
 
 /* Masks for Second Level Paging Entry */
 #define VTD_SL_RW_MASK              3ULL
 #define VTD_SL_R                    1ULL
 #define VTD_SL_W                    (1ULL << 1)
-#define VTD_SL_PT_BASE_ADDR_MASK(aw) (~(VTD_PAGE_SIZE - 1) & VTD_HAW_MASK(aw))
 #define VTD_SL_IGN_COM              0xbff0000000000000ULL
 #define VTD_SL_TM                   (1ULL << 62)
 
diff --git a/include/hw/i386/intel_iommu.h b/include/hw/i386/intel_iommu.h
index 7fa0a695c8..b9a01556ec 100644
--- a/include/hw/i386/intel_iommu.h
+++ b/include/hw/i386/intel_iommu.h
@@ -152,7 +152,7 @@ struct VTDIOTLBEntry {
     uint64_t gfn;
     uint16_t domain_id;
     uint32_t pasid;
-    uint64_t slpte;
+    uint64_t pte;
     uint64_t mask;
     uint8_t access_flags;
 };
-- 
2.44.0

^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [PATCH intel_iommu 6/7] intel_iommu: add PASID-based IOTLB invalidation
  2024-04-22 15:52 [PATCH intel_iommu 0/7] FLTS for VT-d CLEMENT MATHIEU--DRIF
                   ` (3 preceding siblings ...)
  2024-04-22 15:52 ` [PATCH intel_iommu 3/7] intel_iommu: make types match CLEMENT MATHIEU--DRIF
@ 2024-04-22 15:52 ` CLEMENT MATHIEU--DRIF
  2024-04-22 15:52 ` [PATCH intel_iommu 5/7] intel_iommu: extract device IOTLB invalidation logic CLEMENT MATHIEU--DRIF
                   ` (3 subsequent siblings)
  8 siblings, 0 replies; 22+ messages in thread
From: CLEMENT MATHIEU--DRIF @ 2024-04-22 15:52 UTC (permalink / raw)
  To: qemu-devel; +Cc: jasowang, CLEMENT MATHIEU--DRIF

Signed-off-by: Clément Mathieu--Drif <clement.mathieu--drif@eviden.com>
---
 hw/i386/intel_iommu.c          | 130 ++++++++++++++++++++++++++++++---
 hw/i386/intel_iommu_internal.h |  51 +++++++------
 2 files changed, 150 insertions(+), 31 deletions(-)

diff --git a/hw/i386/intel_iommu.c b/hw/i386/intel_iommu.c
index aaac61bf6a..4b54a45107 100644
--- a/hw/i386/intel_iommu.c
+++ b/hw/i386/intel_iommu.c
@@ -277,9 +277,22 @@ static gboolean vtd_hash_remove_by_page(gpointer key, gpointer value,
     VTDIOTLBPageInvInfo *info = (VTDIOTLBPageInvInfo *)user_data;
     uint64_t gfn = (info->addr >> VTD_PAGE_SHIFT_4K) & info->mask;
     uint64_t gfn_tlb = (info->addr & entry->mask) >> VTD_PAGE_SHIFT_4K;
-    return (entry->domain_id == info->domain_id) &&
-            (((entry->gfn & info->mask) == gfn) ||
-             (entry->gfn == gfn_tlb));
+    return (
+            (entry->domain_id == info->domain_id) &&
+            (info->pasid == entry->pasid)
+        ) && (
+            ((entry->gfn & info->mask) == gfn) ||
+            (entry->gfn == gfn_tlb)
+        );
+}
+
+static gboolean vtd_hash_remove_by_pasid(gpointer key, gpointer value,
+                                        gpointer user_data)
+{
+    VTDIOTLBEntry *entry = (VTDIOTLBEntry *)value;
+    VTDIOTLBPasidEntryInvInfo *info = (VTDIOTLBPasidEntryInvInfo *)user_data;
+    return ((entry->domain_id == info->domain_id) &&
+            (info->pasid == entry->pasid));
 }
 
 /* Reset all the gen of VTDAddressSpace to zero and set the gen of
@@ -1287,8 +1300,10 @@ static int vtd_iova_to_pte_sl(IntelIOMMUState *s,  VTDContextEntry *ce,
         if (ret != 0) {
             return ret;
         }
+
         *reads = (*reads) && (slpte & VTD_SL_R);
         *writes = (*writes) && (slpte & VTD_SL_W);
+
         if ((slpte & access_right_check) != access_right_check) {
             error_report_once("%s: detected slpte permission error "
                               "(iova=0x%" PRIx64 ", level=0x%" PRIx32 ", "
@@ -2484,23 +2499,61 @@ static void vtd_iotlb_page_invalidate_notify(IntelIOMMUState *s,
     }
 }
 
+static VTDIOTLBPageInvInfo vtd_build_tlb_page_inv_info(uint16_t domain_id,
+                                                       hwaddr addr, uint8_t am,
+                                                       uint32_t pasid)
+{
+    assert(am <= VTD_MAMV);
+    VTDIOTLBPageInvInfo info = {
+        .domain_id = domain_id,
+        .addr = addr,
+        .mask = ~((1ULL << am) - 1),
+        .pasid = pasid
+    };
+    return info;
+}
+
 static void vtd_iotlb_page_invalidate(IntelIOMMUState *s, uint16_t domain_id,
                                       hwaddr addr, uint8_t am)
 {
-    VTDIOTLBPageInvInfo info;
+    VTDIOTLBPageInvInfo info = vtd_build_tlb_page_inv_info(domain_id, addr,
+                                                           am, PCI_NO_PASID);
 
     trace_vtd_inv_desc_iotlb_pages(domain_id, addr, am);
 
-    assert(am <= VTD_MAMV);
-    info.domain_id = domain_id;
-    info.addr = addr;
-    info.mask = ~((1 << am) - 1);
     vtd_iommu_lock(s);
     g_hash_table_foreach_remove(s->iotlb, vtd_hash_remove_by_page, &info);
     vtd_iommu_unlock(s);
+
     vtd_iotlb_page_invalidate_notify(s, domain_id, addr, am, PCI_NO_PASID);
 }
 
+static void vtd_pasid_based_iotlb_page_invalidate(IntelIOMMUState *s,
+                                                  uint16_t domain_id,
+                                                  hwaddr addr,
+                                                  uint8_t am, uint32_t pasid)
+{
+    VTDIOTLBPageInvInfo info = vtd_build_tlb_page_inv_info(domain_id, addr,
+                                                           am, pasid);
+    vtd_iommu_lock(s);
+    g_hash_table_foreach_remove(s->iotlb, vtd_hash_remove_by_page, &info);
+    vtd_iommu_unlock(s);
+}
+
+static void vtd_pasid_based_iotlb_invalidate(IntelIOMMUState *s,
+                                             uint16_t domain_id,
+                                             uint32_t pasid)
+{
+    assert(pasid != PCI_NO_PASID);
+    VTDIOTLBPasidEntryInvInfo info = {
+        .domain_id = domain_id,
+        .pasid = pasid
+    };
+    vtd_iommu_lock(s);
+    g_hash_table_foreach_remove(s->iotlb, vtd_hash_remove_by_pasid, &info);
+    vtd_iommu_unlock(s);
+}
+
 /* Flush IOTLB
  * Returns the IOTLB Actual Invalidation Granularity.
  * @val: the content of the IOTLB_REG
@@ -2759,7 +2812,7 @@ static bool vtd_get_inv_desc(IntelIOMMUState *s,
 static bool vtd_process_wait_desc(IntelIOMMUState *s, VTDInvDesc *inv_desc)
 {
     if ((inv_desc->hi & VTD_INV_DESC_WAIT_RSVD_HI) ||
-        (inv_desc->lo & VTD_INV_DESC_WAIT_RSVD_LO)) {
+        (inv_desc->lo & VTD_INV_DESC_WAIT_RSVD_LO(s->ecap))) {
         error_report_once("%s: invalid wait desc: hi=%"PRIx64", lo=%"PRIx64
                           " (reserved nonzero)", __func__, inv_desc->hi,
                           inv_desc->lo);
@@ -2785,6 +2838,11 @@ static bool vtd_process_wait_desc(IntelIOMMUState *s, VTDInvDesc *inv_desc)
     } else if (inv_desc->lo & VTD_INV_DESC_WAIT_IF) {
         /* Interrupt flag */
         vtd_generate_completion_event(s);
+    } else if (inv_desc->lo & VTD_INV_DESC_WAIT_FN) {
+        /*
+         * SW = 0, IF = 0, FN = 1
+         * Nothing to do as we process the events sequentially
+         */
     } else {
         error_report_once("%s: invalid wait desc: hi=%"PRIx64", lo=%"PRIx64
                           " (unknown type)", __func__, inv_desc->hi,
@@ -2957,6 +3015,54 @@ done:
     return true;
 }
 
+static bool vtd_process_piotlb_desc(IntelIOMMUState *s,
+                                    VTDInvDesc *inv_desc)
+{
+    uint32_t pasid;
+    uint16_t domain_id;
+    hwaddr addr;
+    uint8_t am;
+
+    if ((inv_desc->lo & VTD_INV_DESC_IOTLB_PASID_RSVD_LO) ||
+        (inv_desc->hi & VTD_INV_DESC_IOTLB_PASID_RSVD_HI)) {
+        error_report_once("%s: invalid piotlb inv desc: hi=0x%"PRIx64
+                          ", lo=0x%"PRIx64" (reserved bits unzero)",
+                          __func__, inv_desc->hi, inv_desc->lo);
+        return false;
+    }
+
+    domain_id = VTD_INV_DESC_IOTLB_DID(inv_desc->lo);
+    pasid = VTD_INV_DESC_IOTLB_PASID(inv_desc->lo);
+    addr = VTD_INV_DESC_IOTLB_ADDR(inv_desc->hi);
+    am = VTD_INV_DESC_IOTLB_AM(inv_desc->hi);
+
+    switch (inv_desc->lo & VTD_INV_DESC_IOTLB_G) {
+    case VTD_INV_DESC_IOTLB_PASID_PASID:
+        vtd_pasid_based_iotlb_invalidate(s, domain_id, pasid);
+        break;
+
+    case VTD_INV_DESC_IOTLB_PASID_PAGE:
+        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->hi, inv_desc->lo,
+                              am, (unsigned)VTD_MAMV);
+            return false;
+        }
+        vtd_pasid_based_iotlb_page_invalidate(s, domain_id, addr, am, pasid);
+        break;
+
+    default:
+        error_report_once("%s: invalid piotlb inv desc: hi=0x%"PRIx64
+                          ", lo=0x%"PRIx64" (type mismatch: 0x%llx)",
+                          __func__, inv_desc->hi, inv_desc->lo,
+                          inv_desc->lo & VTD_INV_DESC_IOTLB_G);
+        return false;
+    }
+
+    return true;
+}
+
 static bool vtd_process_inv_desc(IntelIOMMUState *s)
 {
     VTDInvDesc inv_desc;
@@ -2988,7 +3094,7 @@ static bool vtd_process_inv_desc(IntelIOMMUState *s)
         break;
 
     /*
-     * TODO: the entity of below two cases will be implemented in future series.
+     * TODO: the entity of below case will be implemented in future series.
      * To make guest (which integrates scalable mode support patch set in
      * iommu driver) work, just return true is enough so far.
      */
@@ -2996,6 +3102,10 @@ static bool vtd_process_inv_desc(IntelIOMMUState *s)
         break;
 
     case VTD_INV_DESC_PIOTLB:
+        trace_vtd_inv_desc("piotlb", inv_desc.hi, inv_desc.lo);
+        if (!vtd_process_piotlb_desc(s, &inv_desc)) {
+            return false;
+        }
         break;
 
     case VTD_INV_DESC_WAIT:
diff --git a/hw/i386/intel_iommu_internal.h b/hw/i386/intel_iommu_internal.h
index ed61979934..4f734ce67b 100644
--- a/hw/i386/intel_iommu_internal.h
+++ b/hw/i386/intel_iommu_internal.h
@@ -193,6 +193,7 @@
 #define VTD_ECAP_MHMV               (15ULL << 20)
 #define VTD_ECAP_SRS                (1ULL << 31)
 #define VTD_ECAP_PASID              (1ULL << 40)
+#define VTD_ECAP_PDS                (1ULL << 42)
 #define VTD_ECAP_SMTS               (1ULL << 43)
 #define VTD_ECAP_SLTS               (1ULL << 46)
 #define VTD_ECAP_FLTS               (1ULL << 47)
@@ -386,12 +387,13 @@ typedef union VTDInvDesc VTDInvDesc;
 #define VTD_INV_DESC_NONE               0   /* Not an Invalidate Descriptor */
 
 /* Masks for Invalidation Wait Descriptor*/
-#define VTD_INV_DESC_WAIT_SW            (1ULL << 5)
-#define VTD_INV_DESC_WAIT_IF            (1ULL << 4)
-#define VTD_INV_DESC_WAIT_FN            (1ULL << 6)
-#define VTD_INV_DESC_WAIT_DATA_SHIFT    32
-#define VTD_INV_DESC_WAIT_RSVD_LO       0Xffffff80ULL
-#define VTD_INV_DESC_WAIT_RSVD_HI       3ULL
+#define VTD_INV_DESC_WAIT_SW             (1ULL << 5)
+#define VTD_INV_DESC_WAIT_IF             (1ULL << 4)
+#define VTD_INV_DESC_WAIT_FN             (1ULL << 6)
+#define VTD_INV_DESC_WAIT_DATA_SHIFT     32
+#define VTD_INV_DESC_WAIT_RSVD_LO(ecap)  (0xffffff00ULL | \
+                                         ((ecap & VTD_ECAP_PDS) ? 0 : (1 << 7)))
+#define VTD_INV_DESC_WAIT_RSVD_HI        3ULL
 
 /* Masks for Context-cache Invalidation Descriptor */
 #define VTD_INV_DESC_CC_G               (3ULL << 4)
@@ -404,20 +406,20 @@ typedef union VTDInvDesc VTDInvDesc;
 #define VTD_INV_DESC_CC_RSVD            0xfffc00000000ffc0ULL
 
 /* Masks for IOTLB Invalidate Descriptor */
-#define VTD_INV_DESC_IOTLB_G            (3ULL << 4)
-#define VTD_INV_DESC_IOTLB_GLOBAL       (1ULL << 4)
-#define VTD_INV_DESC_IOTLB_DOMAIN       (2ULL << 4)
-#define VTD_INV_DESC_IOTLB_PAGE         (3ULL << 4)
-#define VTD_INV_DESC_IOTLB_DID(val)     (((val) >> 16) & VTD_DOMAIN_ID_MASK)
-#define VTD_INV_DESC_IOTLB_ADDR(val)    ((val) & ~0xfffULL)
-#define VTD_INV_DESC_IOTLB_AM(val)      ((val) & 0x3fULL)
-#define VTD_INV_DESC_IOTLB_RSVD_LO      0xffffffff0000ff00ULL
-#define VTD_INV_DESC_IOTLB_RSVD_HI      0xf80ULL
-#define VTD_INV_DESC_IOTLB_PASID_PASID  (2ULL << 4)
-#define VTD_INV_DESC_IOTLB_PASID_PAGE   (3ULL << 4)
-#define VTD_INV_DESC_IOTLB_PASID(val)   (((val) >> 32) & VTD_PASID_ID_MASK)
-#define VTD_INV_DESC_IOTLB_PASID_RSVD_LO      0xfff00000000001c0ULL
-#define VTD_INV_DESC_IOTLB_PASID_RSVD_HI      0xf80ULL
+#define VTD_INV_DESC_IOTLB_G                (3ULL << 4)
+#define VTD_INV_DESC_IOTLB_GLOBAL           (1ULL << 4)
+#define VTD_INV_DESC_IOTLB_DOMAIN           (2ULL << 4)
+#define VTD_INV_DESC_IOTLB_PAGE             (3ULL << 4)
+#define VTD_INV_DESC_IOTLB_DID(val)         (((val) >> 16) & VTD_DOMAIN_ID_MASK)
+#define VTD_INV_DESC_IOTLB_ADDR(val)        ((val) & ~0xfffULL)
+#define VTD_INV_DESC_IOTLB_AM(val)          ((val) & 0x3fULL)
+#define VTD_INV_DESC_IOTLB_RSVD_LO          0xffffffff0000ff00ULL
+#define VTD_INV_DESC_IOTLB_RSVD_HI          0xf80ULL
+#define VTD_INV_DESC_IOTLB_PASID_PASID      (2ULL << 4)
+#define VTD_INV_DESC_IOTLB_PASID_PAGE       (3ULL << 4)
+#define VTD_INV_DESC_IOTLB_PASID(val)       (((val) >> 32) & VTD_PASID_ID_MASK)
+#define VTD_INV_DESC_IOTLB_PASID_RSVD_LO    0xfff000000000ffc0ULL
+#define VTD_INV_DESC_IOTLB_PASID_RSVD_HI    0xf80ULL
 
 /* Mask for Device IOTLB Invalidate Descriptor */
 #define VTD_INV_DESC_DEVICE_IOTLB_ADDR(val) ((val) & 0xfffffffffffff000ULL)
@@ -471,10 +473,17 @@ struct VTDIOTLBPageInvInfo {
     uint16_t domain_id;
     uint32_t pasid;
     uint64_t addr;
-    uint8_t mask;
+    uint64_t mask;
 };
 typedef struct VTDIOTLBPageInvInfo VTDIOTLBPageInvInfo;
 
+/* Information about PASID-selective IOTLB invalidate */
+struct VTDIOTLBPasidEntryInvInfo {
+    uint16_t domain_id;
+    uint32_t pasid;
+};
+typedef struct VTDIOTLBPasidEntryInvInfo VTDIOTLBPasidEntryInvInfo;
+
 /* Pagesize of VTD paging structures, including root and context tables */
 #define VTD_PAGE_SHIFT              12
 #define VTD_PAGE_SIZE               (1ULL << VTD_PAGE_SHIFT)
-- 
2.44.0

^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [PATCH intel_iommu 5/7] intel_iommu: extract device IOTLB invalidation logic
  2024-04-22 15:52 [PATCH intel_iommu 0/7] FLTS for VT-d CLEMENT MATHIEU--DRIF
                   ` (4 preceding siblings ...)
  2024-04-22 15:52 ` [PATCH intel_iommu 6/7] intel_iommu: add PASID-based IOTLB invalidation CLEMENT MATHIEU--DRIF
@ 2024-04-22 15:52 ` CLEMENT MATHIEU--DRIF
  2024-04-22 16:59   ` Philippe Mathieu-Daudé
  2024-04-22 15:52 ` [PATCH intel_iommu 4/7] intel_iommu: add support for first-stage translation CLEMENT MATHIEU--DRIF
                   ` (2 subsequent siblings)
  8 siblings, 1 reply; 22+ messages in thread
From: CLEMENT MATHIEU--DRIF @ 2024-04-22 15:52 UTC (permalink / raw)
  To: qemu-devel; +Cc: jasowang, CLEMENT MATHIEU--DRIF

This piece of code can be shared by both IOTLB invalidation and
PASID-based IOTLB invalidation

Signed-off-by: Clément Mathieu--Drif <clement.mathieu--drif@eviden.com>
---
 hw/i386/intel_iommu.c | 57 +++++++++++++++++++++++++------------------
 1 file changed, 33 insertions(+), 24 deletions(-)

diff --git a/hw/i386/intel_iommu.c b/hw/i386/intel_iommu.c
index 3b9f120dec..aaac61bf6a 100644
--- a/hw/i386/intel_iommu.c
+++ b/hw/i386/intel_iommu.c
@@ -2890,13 +2890,42 @@ static bool vtd_process_inv_iec_desc(IntelIOMMUState *s,
     return true;
 }
 
+static void do_invalidate_device_tlb(VTDAddressSpace *vtd_dev_as,
+                                     bool size, hwaddr addr)
+{
+    /*
+     * According to ATS spec table 2.4:
+     * S = 0, bits 15:12 = xxxx     range size: 4K
+     * S = 1, bits 15:12 = xxx0     range size: 8K
+     * S = 1, bits 15:12 = xx01     range size: 16K
+     * S = 1, bits 15:12 = x011     range size: 32K
+     * S = 1, bits 15:12 = 0111     range size: 64K
+     * ...
+     */
+
+    IOMMUTLBEvent event;
+    uint64_t sz;
+
+    if (size) {
+        sz = (VTD_PAGE_SIZE * 2) << cto64(addr >> VTD_PAGE_SHIFT);
+        addr &= ~(sz - 1);
+    } else {
+        sz = VTD_PAGE_SIZE;
+    }
+
+    event.type = IOMMU_NOTIFIER_DEVIOTLB_UNMAP;
+    event.entry.target_as = &vtd_dev_as->as;
+    event.entry.addr_mask = sz - 1;
+    event.entry.iova = addr;
+    event.entry.perm = IOMMU_NONE;
+    event.entry.translated_addr = 0;
+    memory_region_notify_iommu(&vtd_dev_as->iommu, 0, event);
+}
 static bool vtd_process_device_iotlb_desc(IntelIOMMUState *s,
                                           VTDInvDesc *inv_desc)
 {
     VTDAddressSpace *vtd_dev_as;
-    IOMMUTLBEvent event;
     hwaddr addr;
-    uint64_t sz;
     uint16_t sid;
     bool size;
 
@@ -2912,6 +2941,7 @@ static bool vtd_process_device_iotlb_desc(IntelIOMMUState *s,
         return false;
     }
 
+
     /*
      * Using sid is OK since the guest should have finished the
      * initialization of both the bus and device.
@@ -2921,28 +2951,7 @@ static bool vtd_process_device_iotlb_desc(IntelIOMMUState *s,
         goto done;
     }
 
-    /* According to ATS spec table 2.4:
-     * S = 0, bits 15:12 = xxxx     range size: 4K
-     * S = 1, bits 15:12 = xxx0     range size: 8K
-     * S = 1, bits 15:12 = xx01     range size: 16K
-     * S = 1, bits 15:12 = x011     range size: 32K
-     * S = 1, bits 15:12 = 0111     range size: 64K
-     * ...
-     */
-    if (size) {
-        sz = (VTD_PAGE_SIZE * 2) << cto64(addr >> VTD_PAGE_SHIFT);
-        addr &= ~(sz - 1);
-    } else {
-        sz = VTD_PAGE_SIZE;
-    }
-
-    event.type = IOMMU_NOTIFIER_DEVIOTLB_UNMAP;
-    event.entry.target_as = &vtd_dev_as->as;
-    event.entry.addr_mask = sz - 1;
-    event.entry.iova = addr;
-    event.entry.perm = IOMMU_NONE;
-    event.entry.translated_addr = 0;
-    memory_region_notify_iommu(&vtd_dev_as->iommu, 0, event);
+    do_invalidate_device_tlb(vtd_dev_as, size, addr);
 
 done:
     return true;
-- 
2.44.0

^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [PATCH intel_iommu 7/7] intel_iommu: add a CLI option to enable FLTS
  2024-04-22 15:52 [PATCH intel_iommu 0/7] FLTS for VT-d CLEMENT MATHIEU--DRIF
  2024-04-22 15:52 ` [PATCH intel_iommu 1/7] intel_iommu: fix FRCD construction macro CLEMENT MATHIEU--DRIF
  2024-04-22 15:52 ` [PATCH intel_iommu 2/7] intel_iommu: rename slpte to pte before adding FLTS CLEMENT MATHIEU--DRIF
@ 2024-04-22 15:52 ` CLEMENT MATHIEU--DRIF
  2024-04-22 15:52 ` [PATCH intel_iommu 3/7] intel_iommu: make types match CLEMENT MATHIEU--DRIF
                   ` (5 subsequent siblings)
  8 siblings, 0 replies; 22+ messages in thread
From: CLEMENT MATHIEU--DRIF @ 2024-04-22 15:52 UTC (permalink / raw)
  To: qemu-devel; +Cc: jasowang, CLEMENT MATHIEU--DRIF

Signed-off-by: Clément Mathieu--Drif <clement.mathieu--drif@eviden.com>
---
 hw/i386/intel_iommu.c         | 6 ++++++
 include/hw/i386/intel_iommu.h | 1 +
 2 files changed, 7 insertions(+)

diff --git a/hw/i386/intel_iommu.c b/hw/i386/intel_iommu.c
index 4b54a45107..c35ccc3a98 100644
--- a/hw/i386/intel_iommu.c
+++ b/hw/i386/intel_iommu.c
@@ -3704,6 +3704,7 @@ static Property vtd_properties[] = {
     DEFINE_PROP_BOOL("x-scalable-mode", IntelIOMMUState, scalable_mode, FALSE),
     DEFINE_PROP_BOOL("snoop-control", IntelIOMMUState, snoop_control, false),
     DEFINE_PROP_BOOL("x-pasid-mode", IntelIOMMUState, pasid, false),
+    DEFINE_PROP_BOOL("flts", IntelIOMMUState, flts, false),
     DEFINE_PROP_BOOL("dma-drain", IntelIOMMUState, dma_drain, true),
     DEFINE_PROP_BOOL("dma-translation", IntelIOMMUState, dma_translation, true),
     DEFINE_PROP_END_OF_LIST(),
@@ -4413,6 +4414,11 @@ static void vtd_init(IntelIOMMUState *s)
         s->ecap |= VTD_ECAP_PASID;
     }
 
+    if (s->flts) {
+        s->ecap |= VTD_ECAP_FLTS;
+        s->cap |= VTD_CAP_FS1GP;
+    }
+
     vtd_reset_caches(s);
 
     /* Define registers with default values and bit semantics */
diff --git a/include/hw/i386/intel_iommu.h b/include/hw/i386/intel_iommu.h
index b9a01556ec..6ecc8bb8a9 100644
--- a/include/hw/i386/intel_iommu.h
+++ b/include/hw/i386/intel_iommu.h
@@ -263,6 +263,7 @@ struct IntelIOMMUState {
     bool caching_mode;              /* RO - is cap CM enabled? */
     bool scalable_mode;             /* RO - is Scalable Mode supported? */
     bool snoop_control;             /* RO - is SNP filed supported? */
+    bool flts;                      /* RO - is FS translation supported? */
 
     dma_addr_t root;                /* Current root table pointer */
     bool root_scalable;             /* Type of root table (scalable or not) */
-- 
2.44.0

^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [PATCH intel_iommu 3/7] intel_iommu: make types match
  2024-04-22 15:52 [PATCH intel_iommu 0/7] FLTS for VT-d CLEMENT MATHIEU--DRIF
                   ` (2 preceding siblings ...)
  2024-04-22 15:52 ` [PATCH intel_iommu 7/7] intel_iommu: add a CLI option to enable FLTS CLEMENT MATHIEU--DRIF
@ 2024-04-22 15:52 ` CLEMENT MATHIEU--DRIF
  2024-04-22 17:03   ` Philippe Mathieu-Daudé
  2024-04-22 15:52 ` [PATCH intel_iommu 6/7] intel_iommu: add PASID-based IOTLB invalidation CLEMENT MATHIEU--DRIF
                   ` (4 subsequent siblings)
  8 siblings, 1 reply; 22+ messages in thread
From: CLEMENT MATHIEU--DRIF @ 2024-04-22 15:52 UTC (permalink / raw)
  To: qemu-devel; +Cc: jasowang, CLEMENT MATHIEU--DRIF

The 'level' field in vtd_iotlb_key is an uint8_t.
We don't need to store level as an int in vtd_lookup_iotlb

Signed-off-by: Clément Mathieu--Drif <clement.mathieu--drif@eviden.com>
---
 hw/i386/intel_iommu.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/hw/i386/intel_iommu.c b/hw/i386/intel_iommu.c
index 6f1364b3fd..ba545590b1 100644
--- a/hw/i386/intel_iommu.c
+++ b/hw/i386/intel_iommu.c
@@ -333,7 +333,7 @@ static VTDIOTLBEntry *vtd_lookup_iotlb(IntelIOMMUState *s, uint16_t source_id,
 {
     struct vtd_iotlb_key key;
     VTDIOTLBEntry *entry;
-    int level;
+    uint8_t level;
 
     for (level = VTD_SL_PT_LEVEL; level < VTD_SL_PML4_LEVEL; level++) {
         key.gfn = vtd_get_iotlb_gfn(addr, level);
-- 
2.44.0

^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [PATCH intel_iommu 4/7] intel_iommu: add support for first-stage translation
  2024-04-22 15:52 [PATCH intel_iommu 0/7] FLTS for VT-d CLEMENT MATHIEU--DRIF
                   ` (5 preceding siblings ...)
  2024-04-22 15:52 ` [PATCH intel_iommu 5/7] intel_iommu: extract device IOTLB invalidation logic CLEMENT MATHIEU--DRIF
@ 2024-04-22 15:52 ` CLEMENT MATHIEU--DRIF
  2024-04-30 14:04 ` [PATCH intel_iommu 0/7] FLTS for VT-d Philippe Mathieu-Daudé
  2024-04-30 14:13 ` Cédric Le Goater
  8 siblings, 0 replies; 22+ messages in thread
From: CLEMENT MATHIEU--DRIF @ 2024-04-22 15:52 UTC (permalink / raw)
  To: qemu-devel; +Cc: jasowang, CLEMENT MATHIEU--DRIF

This translation mode will only be made available in scalable mode

Signed-off-by: Clément Mathieu--Drif <clement.mathieu--drif@eviden.com>
---
 hw/i386/intel_iommu.c          | 364 ++++++++++++++++++++++++++++-----
 hw/i386/intel_iommu_internal.h |  51 ++++-
 2 files changed, 362 insertions(+), 53 deletions(-)

diff --git a/hw/i386/intel_iommu.c b/hw/i386/intel_iommu.c
index ba545590b1..3b9f120dec 100644
--- a/hw/i386/intel_iommu.c
+++ b/hw/i386/intel_iommu.c
@@ -713,6 +713,21 @@ static uint64_t vtd_get_pte(dma_addr_t base_addr, uint32_t index)
     return pte;
 }
 
+static MemTxResult vtd_set_flag_in_pte(dma_addr_t base_addr, uint32_t index,
+                                       uint64_t pte, uint64_t flag)
+{
+    assert(index < VTD_PT_ENTRY_NR);
+    if (pte & flag) {
+        return MEMTX_OK;
+    }
+    pte |= flag;
+    pte = cpu_to_le64(pte);
+    return dma_memory_write(&address_space_memory,
+                            base_addr + index * sizeof(pte),
+                            &pte, sizeof(pte),
+                            MEMTXATTRS_UNSPECIFIED);
+}
+
 /* Given an iova and the level of paging structure, return the offset
  * of current level.
  */
@@ -730,11 +745,17 @@ static inline bool vtd_is_level_supported(IntelIOMMUState *s, uint32_t level)
 }
 
 /* Return true if check passed, otherwise false */
-static inline bool vtd_pe_type_check(X86IOMMUState *x86_iommu,
+static inline bool vtd_pe_type_check(IntelIOMMUState *s,
                                      VTDPASIDEntry *pe)
 {
+    X86IOMMUState *x86_iommu = X86_IOMMU_DEVICE(s);
+
     switch (VTD_PE_GET_TYPE(pe)) {
     case VTD_SM_PASID_ENTRY_FLT:
+        if (!(s->ecap & VTD_ECAP_FLTS)) {
+            return false;
+        }
+        break;
     case VTD_SM_PASID_ENTRY_SLT:
     case VTD_SM_PASID_ENTRY_NESTED:
         break;
@@ -784,6 +805,11 @@ static inline bool vtd_pe_present(VTDPASIDEntry *pe)
     return pe->val[0] & VTD_PASID_ENTRY_P;
 }
 
+static inline bool vtd_fl_pte_present(uint64_t pte)
+{
+    return pte & VTD_FL_PTE_P;
+}
+
 static int vtd_get_pe_in_pasid_leaf_table(IntelIOMMUState *s,
                                           uint32_t pasid,
                                           dma_addr_t addr,
@@ -791,7 +817,6 @@ static int vtd_get_pe_in_pasid_leaf_table(IntelIOMMUState *s,
 {
     uint32_t index;
     dma_addr_t entry_size;
-    X86IOMMUState *x86_iommu = X86_IOMMU_DEVICE(s);
 
     index = VTD_PASID_TABLE_INDEX(pasid);
     entry_size = VTD_PASID_ENTRY_SIZE;
@@ -805,7 +830,7 @@ static int vtd_get_pe_in_pasid_leaf_table(IntelIOMMUState *s,
     }
 
     /* Do translation type check */
-    if (!vtd_pe_type_check(x86_iommu, pe)) {
+    if (!vtd_pe_type_check(s, pe)) {
         return -VTD_FR_PASID_TABLE_INV;
     }
 
@@ -1027,6 +1052,34 @@ static inline bool vtd_iova_sl_range_check(IntelIOMMUState *s,
     return !(iova & ~(vtd_iova_limit(s, ce, aw, pasid) - 1));
 }
 
+/* Return true if IOVA is canonical, otherwise false. */
+static bool vtd_iova_fl_check_canonical(IntelIOMMUState *s,
+                                        uint64_t iova, VTDContextEntry *ce,
+                                        uint8_t aw, uint32_t pasid)
+{
+    uint64_t iova_limit = vtd_iova_limit(s, ce, aw, pasid);
+    uint64_t upper_bits_mask = ~(iova_limit - 1);
+    uint64_t upper_bits = iova & upper_bits_mask;
+    bool msb = ((iova & (iova_limit >> 1)) != 0);
+    return !(
+             (!msb && (upper_bits != 0)) ||
+             (msb && (upper_bits != upper_bits_mask))
+            );
+}
+
+/* Return the page table base address corresponding to the translation type. */
+static dma_addr_t vtd_pe_get_pgtbl_base(VTDPASIDEntry *pe)
+{
+    uint16_t pgtt = VTD_PE_GET_TYPE(pe);
+    if (pgtt == VTD_SM_PASID_ENTRY_FLT) {
+        return pe->val[2] & VTD_SM_PASID_ENTRY_PTPTR;
+    } else if (pgtt == VTD_SM_PASID_ENTRY_SLT) {
+        return pe->val[0] & VTD_SM_PASID_ENTRY_PTPTR;
+    }
+
+    return 0; /* Not supported */
+}
+
 static dma_addr_t vtd_get_iova_pgtbl_base(IntelIOMMUState *s,
                                           VTDContextEntry *ce,
                                           uint32_t pasid)
@@ -1035,7 +1088,7 @@ static dma_addr_t vtd_get_iova_pgtbl_base(IntelIOMMUState *s,
 
     if (s->root_scalable) {
         vtd_ce_get_rid2pasid_entry(s, ce, &pe, pasid);
-        return pe.val[0] & VTD_SM_PASID_ENTRY_SLPTPTR;
+        return vtd_pe_get_pgtbl_base(&pe);
     }
 
     return vtd_ce_get_slpt_base(ce);
@@ -1053,6 +1106,10 @@ static dma_addr_t vtd_get_iova_pgtbl_base(IntelIOMMUState *s,
 static uint64_t vtd_spte_rsvd[VTD_SPTE_RSVD_LEN];
 static uint64_t vtd_spte_rsvd_large[VTD_SPTE_RSVD_LEN];
 
+#define VTD_FPTE_RSVD_LEN 5
+static uint64_t vtd_fpte_rsvd[VTD_FPTE_RSVD_LEN];
+static uint64_t vtd_fpte_rsvd_large[VTD_FPTE_RSVD_LEN];
+
 static bool vtd_slpte_nonzero_rsvd(uint64_t slpte, uint32_t level)
 {
     uint64_t rsvd_mask;
@@ -1079,21 +1136,140 @@ static bool vtd_slpte_nonzero_rsvd(uint64_t slpte, uint32_t level)
     return slpte & rsvd_mask;
 }
 
-/* Given the @iova, get relevant @slptep. @slpte_level will be the last level
- * of the translation, can be used for deciding the size of large page.
- */
-static int vtd_iova_to_slpte(IntelIOMMUState *s, VTDContextEntry *ce,
-                             uint64_t iova, bool is_write,
-                             uint64_t *slptep, uint32_t *slpte_level,
-                             bool *reads, bool *writes, uint8_t aw_bits,
-                             uint32_t pasid)
+static bool vtd_flpte_nonzero_rsvd(uint64_t flpte, uint32_t level)
+{
+    uint64_t rsvd_mask;
+    assert(level < VTD_FPTE_RSVD_LEN);
+    assert(level);
+
+    if ((level == VTD_FL_PD_LEVEL || level == VTD_FL_PDP_LEVEL) &&
+        (flpte & VTD_PT_PAGE_SIZE_MASK)) {
+        /* large page */
+        rsvd_mask = vtd_fpte_rsvd_large[level];
+    } else {
+        rsvd_mask = vtd_fpte_rsvd[level];
+    }
+
+    return flpte & rsvd_mask;
+}
+
+static int vtd_iova_to_pte_check_read_error(IntelIOMMUState *s,
+                                            VTDContextEntry *ce, uint64_t iova,
+                                            uint64_t pte, uint32_t pasid,
+                                            uint32_t level, uint16_t pgtt)
+{
+    if (pte == (uint64_t)-1) {
+        error_report_once("%s: detected read error on DMAR pte "
+                            "(iova=0x%" PRIx64 ", pasid=0x%" PRIx32 ")",
+                            __func__, iova, pasid);
+        if (level == vtd_get_iova_level(s, ce, pasid)) {
+            /* Invalid programming of context-entry */
+            if (s->root_scalable) {
+                return pgtt == VTD_SM_PASID_ENTRY_FLT ?
+                                    -VTD_FR_FIRST_FSPE_ACCESS :
+                                    -VTD_FR_FIRST_SSPE_ACCESS;
+            } else {
+                return -VTD_FR_CONTEXT_ENTRY_INV;
+            }
+        } else {
+            if (s->root_scalable) {
+                return pgtt == VTD_SM_PASID_ENTRY_FLT ?
+                                    -VTD_FR_FSPE_ACCESS :
+                                    -VTD_FR_SSPE_ACCESS;
+            } else {
+                return -VTD_FR_PAGING_ENTRY_INV;
+            }
+        }
+    }
+
+    return 0;
+}
+
+static inline bool vtd_addr_in_interrup_range(hwaddr addr, uint64_t size)
+{
+    return !((addr > VTD_INTERRUPT_ADDR_LAST) ||
+             (addr + size - 1 < VTD_INTERRUPT_ADDR_FIRST));
+}
+
+static int vtd_iova_to_pte_fl(IntelIOMMUState *s,  VTDContextEntry *ce,
+                              uint64_t iova, bool is_write, uint64_t *ptep,
+                              uint32_t *pte_level, bool *reads, bool *writes,
+                              uint8_t aw_bits, uint32_t pasid, dma_addr_t addr)
+{
+    uint32_t offset;
+    uint64_t pte;
+    uint64_t access_right_check = is_write ? VTD_FL_W : 0;
+    int ret;
+
+    if (!vtd_iova_fl_check_canonical(s, iova, ce, aw_bits, pasid)) {
+        error_report_once("%s: detected non canonical IOVA (iova=0x%" PRIx64 ","
+                          "pasid=0x%" PRIx32 ")", __func__, iova, pasid);
+        return -VTD_FR_FS_NON_CANONICAL;
+    }
+
+    while (true) {
+        offset = vtd_iova_level_offset(iova, *pte_level);
+        pte = vtd_get_pte(addr, offset);
+
+        ret = vtd_iova_to_pte_check_read_error(s, ce, iova, pte,
+                                               pasid, *pte_level,
+                                               VTD_SM_PASID_ENTRY_FLT);
+        if (ret != 0) {
+            return ret;
+        }
+
+        if (!vtd_fl_pte_present(pte)) {
+            return -VTD_FR_FSPE_NOT_PRESENT;
+        }
+
+        *reads = true;
+        *writes = (*writes) && (pte & VTD_FL_W);
+
+        if (vtd_set_flag_in_pte(addr, offset, pte, VTD_FL_PTE_A) != MEMTX_OK) {
+            return -VTD_FR_FS_BIT_UPDATE_FAILED;
+        }
+
+        if ((pte & access_right_check) != access_right_check) {
+            error_report_once("%s: detected pte permission error "
+                              "(iova=0x%" PRIx64 ", level=0x%" PRIx32 ", "
+                              "pte=0x%" PRIx64 ", write=%d, pasid=0x%"
+                              PRIx32 ")", __func__, iova, *pte_level,
+                              pte, is_write, pasid);
+            return is_write ? -VTD_FR_SM_WRITE : -VTD_FR_SM_READ;
+        }
+        if (vtd_flpte_nonzero_rsvd(pte, *pte_level)) {
+            error_report_once("%s: detected flpte reserved non-zero "
+                              "iova=0x%" PRIx64 ", level=0x%" PRIx32
+                              "pte=0x%" PRIx64 ", pasid=0x%" PRIX32 ")",
+                              __func__, iova, *pte_level, pte, pasid);
+            return -VTD_FR_PAGING_ENTRY_RSVD;
+        }
+
+        if (vtd_is_last_pte(pte, *pte_level)) {
+            *ptep = pte;
+            break;
+        }
+        addr = vtd_get_pte_addr(pte, aw_bits);
+        (*pte_level)--;
+    }
+
+    if (is_write &&
+        (vtd_set_flag_in_pte(addr, offset, pte, VTD_FL_PTE_D) != MEMTX_OK)) {
+            return -VTD_FR_FS_BIT_UPDATE_FAILED;
+    }
+
+    return 0;
+}
+
+static int vtd_iova_to_pte_sl(IntelIOMMUState *s,  VTDContextEntry *ce,
+                              uint64_t iova, bool is_write, uint64_t *slptep,
+                              uint32_t *pte_level, bool *reads, bool *writes,
+                              uint8_t aw_bits, uint32_t pasid, dma_addr_t addr)
 {
-    dma_addr_t addr = vtd_get_iova_pgtbl_base(s, ce, pasid);
-    uint32_t level = vtd_get_iova_level(s, ce, pasid);
     uint32_t offset;
     uint64_t slpte;
-    uint64_t access_right_check;
-    uint64_t xlat, size;
+    uint64_t access_right_check = is_write ? VTD_SL_W : VTD_SL_R;
+    int ret;
 
     if (!vtd_iova_sl_range_check(s, iova, ce, aw_bits, pasid)) {
         error_report_once("%s: detected IOVA overflow (iova=0x%" PRIx64 ","
@@ -1101,72 +1277,128 @@ static int vtd_iova_to_slpte(IntelIOMMUState *s, VTDContextEntry *ce,
         return -VTD_FR_ADDR_BEYOND_MGAW;
     }
 
-    /* FIXME: what is the Atomics request here? */
-    access_right_check = is_write ? VTD_SL_W : VTD_SL_R;
-
     while (true) {
-        offset = vtd_iova_level_offset(iova, level);
+        offset = vtd_iova_level_offset(iova, *pte_level);
         slpte = vtd_get_pte(addr, offset);
 
-        if (slpte == (uint64_t)-1) {
-            error_report_once("%s: detected read error on DMAR slpte "
-                              "(iova=0x%" PRIx64 ", pasid=0x%" PRIx32 ")",
-                              __func__, iova, pasid);
-            if (level == vtd_get_iova_level(s, ce, pasid)) {
-                /* Invalid programming of context-entry */
-                return -VTD_FR_CONTEXT_ENTRY_INV;
-            } else {
-                return -VTD_FR_PAGING_ENTRY_INV;
-            }
+        ret = vtd_iova_to_pte_check_read_error(s, ce, iova, slpte,
+                                               pasid, *pte_level,
+                                               VTD_SM_PASID_ENTRY_SLT);
+        if (ret != 0) {
+            return ret;
         }
         *reads = (*reads) && (slpte & VTD_SL_R);
         *writes = (*writes) && (slpte & VTD_SL_W);
-        if (!(slpte & access_right_check)) {
+        if ((slpte & access_right_check) != access_right_check) {
             error_report_once("%s: detected slpte permission error "
                               "(iova=0x%" PRIx64 ", level=0x%" PRIx32 ", "
                               "slpte=0x%" PRIx64 ", write=%d, pasid=0x%"
-                              PRIx32 ")", __func__, iova, level,
+                              PRIx32 ")", __func__, iova, *pte_level,
                               slpte, is_write, pasid);
-            return is_write ? -VTD_FR_WRITE : -VTD_FR_READ;
+            if (s->root_scalable) {
+                return is_write ? -VTD_FR_SM_WRITE : -VTD_FR_SM_READ;
+            } else {
+                return is_write ? -VTD_FR_WRITE : -VTD_FR_READ;
+            }
         }
-        if (vtd_slpte_nonzero_rsvd(slpte, level)) {
+        if (vtd_slpte_nonzero_rsvd(slpte, *pte_level)) {
             error_report_once("%s: detected splte reserve non-zero "
                               "iova=0x%" PRIx64 ", level=0x%" PRIx32
                               "slpte=0x%" PRIx64 ", pasid=0x%" PRIX32 ")",
-                              __func__, iova, level, slpte, pasid);
+                              __func__, iova, *pte_level, slpte, pasid);
             return -VTD_FR_PAGING_ENTRY_RSVD;
         }
 
-        if (vtd_is_last_pte(slpte, level)) {
+        if (vtd_is_last_pte(slpte, *pte_level)) {
             *slptep = slpte;
-            *slpte_level = level;
             break;
         }
         addr = vtd_get_pte_addr(slpte, aw_bits);
-        level--;
+        (*pte_level)--;
+    }
+
+    return 0;
+}
+
+/*
+ * Given the @iova, get relevant @ptep. @pte_level will be the last level
+ * of the translation, can be used for deciding the size of large page.
+ */
+static int vtd_iova_to_pte(IntelIOMMUState *s, VTDContextEntry *ce,
+                             uint64_t iova, bool is_write,
+                             uint64_t *ptep, uint32_t *pte_level,
+                             bool *reads, bool *writes, uint8_t aw_bits,
+                             uint32_t pasid)
+{
+    dma_addr_t addr;
+    uint16_t pgtt;
+    uint64_t xlat, size;
+    VTDPASIDEntry pe;
+    int ret;
+
+    /* FIXME: what is the Atomics request in access rights? */
+
+    if (s->root_scalable) {
+        vtd_ce_get_rid2pasid_entry(s, ce, &pe, pasid);
+        pgtt = VTD_PE_GET_TYPE(&pe);
+        *pte_level = VTD_PE_GET_LEVEL(&pe);
+        addr = vtd_pe_get_pgtbl_base(&pe);
+        switch (pgtt) {
+        case VTD_SM_PASID_ENTRY_FLT:
+            if (s->ecap & VTD_ECAP_FLTS) {
+                ret = vtd_iova_to_pte_fl(s, ce, iova, is_write, ptep, pte_level,
+                                         reads, writes, aw_bits, pasid, addr);
+            } else {
+                error_report_once("First-stage translation not supported : %d",
+                                  pgtt);
+                return -VTD_FR_INVALID_PGTT;
+            }
+            break;
+        case VTD_SM_PASID_ENTRY_SLT:
+            if (s->ecap & VTD_ECAP_SLTS) {
+                ret = vtd_iova_to_pte_sl(s, ce, iova, is_write, ptep, pte_level,
+                                         reads, writes, aw_bits, pasid, addr);
+            } else {
+                error_report_once("Second-stage translation not supported : %d",
+                                  pgtt);
+                return -VTD_FR_INVALID_PGTT;
+            }
+            break;
+        default:
+            error_report_once("Unsupported PGTT : %d", pgtt);
+            ret = -VTD_FR_INVALID_PGTT;
+            break;
+        }
+    } else {
+        *pte_level = vtd_ce_get_level(ce);
+        addr = vtd_ce_get_slpt_base(ce);
+        ret = vtd_iova_to_pte_sl(s, ce, iova, is_write, ptep, pte_level,
+                                 reads, writes, aw_bits, pasid, addr);
     }
 
-    xlat = vtd_get_pte_addr(*slptep, aw_bits);
-    size = ~vtd_pt_level_page_mask(level) + 1;
+    if (ret != 0) {
+        return ret;
+    }
+
+    xlat = vtd_get_pte_addr(*ptep, aw_bits);
+    size = ~vtd_pt_level_page_mask(*pte_level) + 1;
 
     /*
      * From VT-d spec 3.14: Untranslated requests and translation
      * requests that result in an address in the interrupt range will be
      * blocked with condition code LGN.4 or SGN.8.
      */
-    if ((xlat > VTD_INTERRUPT_ADDR_LAST ||
-         xlat + size - 1 < VTD_INTERRUPT_ADDR_FIRST)) {
+    if (!vtd_addr_in_interrup_range(xlat, size)) {
         return 0;
     } else {
         error_report_once("%s: xlat address is in interrupt range "
                           "(iova=0x%" PRIx64 ", level=0x%" PRIx32 ", "
-                          "slpte=0x%" PRIx64 ", write=%d, "
+                          "pte=0x%" PRIx64 ", write=%d, "
                           "xlat=0x%" PRIx64 ", size=0x%" PRIx64 ", "
                           "pasid=0x%" PRIx32 ")",
-                          __func__, iova, level, slpte, is_write,
+                          __func__, iova, *pte_level, *ptep, is_write,
                           xlat, size, pasid);
-        return s->scalable_mode ? -VTD_FR_SM_INTERRUPT_ADDR :
-                                  -VTD_FR_INTERRUPT_ADDR;
+        return -VTD_INTERRUPT_RANGE_ERROR(s);
     }
 }
 
@@ -1772,6 +2004,16 @@ static const bool vtd_qualified_faults[] = {
     [VTD_FR_CONTEXT_ENTRY_TT] = true,
     [VTD_FR_PASID_TABLE_INV] = false,
     [VTD_FR_SM_INTERRUPT_ADDR] = true,
+    [VTD_FR_INVALID_PGTT] = true,
+    [VTD_FR_FSPE_ACCESS] = true,
+    [VTD_FR_FSPE_NOT_PRESENT] = true,
+    [VTD_FR_FIRST_FSPE_ACCESS] = true,
+    [VTD_FR_SSPE_ACCESS] = true,
+    [VTD_FR_FIRST_SSPE_ACCESS] = true,
+    [VTD_FR_FS_NON_CANONICAL] = true,
+    [VTD_FR_SM_WRITE] = true,
+    [VTD_FR_SM_READ] = true,
+    [VTD_FR_FS_BIT_UPDATE_FAILED] = true,
     [VTD_FR_MAX] = false,
 };
 
@@ -1870,7 +2112,8 @@ static bool vtd_do_iommu_translate(VTDAddressSpace *vtd_as, PCIBus *bus,
     uint8_t bus_num = pci_bus_num(bus);
     VTDContextCacheEntry *cc_entry;
     uint64_t pte, page_mask;
-    uint32_t level, pasid = vtd_as->pasid;
+    uint32_t level = UINT32_MAX;
+    uint32_t pasid = vtd_as->pasid;
     uint16_t source_id = PCI_BUILD_BDF(bus_num, devfn);
     int ret_fr;
     bool is_fpd_set = false;
@@ -1981,7 +2224,7 @@ static bool vtd_do_iommu_translate(VTDAddressSpace *vtd_as, PCIBus *bus,
         }
     }
 
-    ret_fr = vtd_iova_to_slpte(s, &ce, addr, is_write, &pte, &level,
+    ret_fr = vtd_iova_to_pte(s, &ce, addr, is_write, &pte, &level,
                                &reads, &writes, s->aw_bits, pasid);
     if (ret_fr) {
         vtd_report_fault(s, -ret_fr, is_fpd_set, source_id,
@@ -1990,6 +2233,7 @@ static bool vtd_do_iommu_translate(VTDAddressSpace *vtd_as, PCIBus *bus,
     }
 
     page_mask = vtd_pt_level_page_mask(level);
+    /* Exe is always set to 0 in the spec */
     access_flags = IOMMU_ACCESS_FLAG(reads, writes);
     vtd_update_iotlb(s, source_id, vtd_get_domain_id(s, &ce, pasid),
                      addr, pte, access_flags, level, pasid);
@@ -2005,7 +2249,12 @@ error:
     vtd_iommu_unlock(s);
     entry->iova = 0;
     entry->translated_addr = 0;
-    entry->addr_mask = 0;
+    /*
+     * Set the mask for ATS (the range must be present even when the
+     * translation fails : PCIe rev 5 10.2.3.5)
+     */
+    entry->addr_mask = (level != UINT32_MAX) ?
+                        (~vtd_pt_level_page_mask(level)) : (~VTD_PAGE_MASK_4K);
     entry->perm = IOMMU_NONE;
     return false;
 }
@@ -3187,6 +3436,8 @@ static IOMMUTLBEntry vtd_iommu_translate(IOMMUMemoryRegion *iommu, hwaddr addr,
     };
     bool success;
 
+    /* IOMMUAccessFlags : IOMMU_EXEC and IOMMU_PRIV not supported */
+
     if (likely(s->dmar_enabled)) {
         success = vtd_do_iommu_translate(vtd_as, vtd_as->bus, vtd_as->devfn,
                                          addr, flag & IOMMU_WO, &iotlb);
@@ -3989,6 +4240,21 @@ static void vtd_init(IntelIOMMUState *s)
     vtd_spte_rsvd_large[3] = VTD_SPTE_LPAGE_L3_RSVD_MASK(s->aw_bits,
                                                          x86_iommu->dt_supported);
 
+    /*
+     * Rsvd field masks for fpte
+     */
+    vtd_fpte_rsvd[0] = ~0ULL;
+    vtd_fpte_rsvd[1] = VTD_FPTE_PAGE_L1_RSVD_MASK(s->aw_bits);
+    vtd_fpte_rsvd[2] = VTD_FPTE_PAGE_L2_RSVD_MASK(s->aw_bits);
+    vtd_fpte_rsvd[3] = VTD_FPTE_PAGE_L3_RSVD_MASK(s->aw_bits);
+    vtd_fpte_rsvd[4] = VTD_FPTE_PAGE_L4_RSVD_MASK(s->aw_bits);
+
+    vtd_fpte_rsvd_large[0] = ~0ULL;
+    vtd_fpte_rsvd_large[1] = ~0ULL;
+    vtd_fpte_rsvd_large[2] = VTD_FPTE_PAGE_L2_FS2MP_RSVD_MASK(s->aw_bits);
+    vtd_fpte_rsvd_large[3] = VTD_FPTE_PAGE_L3_FS1GP_RSVD_MASK(s->aw_bits);
+    vtd_fpte_rsvd_large[4] = ~0ULL;
+
     if (s->scalable_mode || s->snoop_control) {
         vtd_spte_rsvd[1] &= ~VTD_SPTE_SNP;
         vtd_spte_rsvd_large[2] &= ~VTD_SPTE_SNP;
diff --git a/hw/i386/intel_iommu_internal.h b/hw/i386/intel_iommu_internal.h
index 8d27b1c15b..ed61979934 100644
--- a/hw/i386/intel_iommu_internal.h
+++ b/hw/i386/intel_iommu_internal.h
@@ -195,6 +195,7 @@
 #define VTD_ECAP_PASID              (1ULL << 40)
 #define VTD_ECAP_SMTS               (1ULL << 43)
 #define VTD_ECAP_SLTS               (1ULL << 46)
+#define VTD_ECAP_FLTS               (1ULL << 47)
 
 /* CAP_REG */
 /* (offset >> 4) << 24 */
@@ -215,6 +216,7 @@
 #define VTD_CAP_CM                  (1ULL << 7)
 #define VTD_PASID_ID_SHIFT          20
 #define VTD_PASID_ID_MASK           ((1ULL << VTD_PASID_ID_SHIFT) - 1)
+#define VTD_CAP_FS1GP               (1ULL << 56)
 
 /* Supported Adjusted Guest Address Widths */
 #define VTD_CAP_SAGAW_SHIFT         8
@@ -270,6 +272,10 @@
 #define VTD_FRCD_PP(val)        (((val) & 0x1ULL) << 31)
 #define VTD_FRCD_IR_IDX(val)    (((val) & 0xffffULL) << 48)
 
+#define VTD_INTERRUPT_RANGE_ERROR(s) ((s)->scalable_mode ? \
+                                      VTD_FR_SM_INTERRUPT_ADDR : \
+                                      VTD_FR_INTERRUPT_ADDR)
+
 /* DMA Remapping Fault Conditions */
 typedef enum VTDFaultReason {
     VTD_FR_RESERVED = 0,        /* Reserved for Advanced Fault logging */
@@ -312,9 +318,21 @@ typedef enum VTDFaultReason {
     VTD_FR_IR_SID_ERR = 0x26,   /* Invalid Source-ID */
 
     VTD_FR_PASID_TABLE_INV = 0x58,  /*Invalid PASID table entry */
+    VTD_FR_INVALID_PGTT = 0x5b,  /* SPT.4.2 Invalid PGTT */
+
+    VTD_FR_FSPE_ACCESS = 0x70, /* SFS.1 */
+    VTD_FR_FSPE_NOT_PRESENT = 0x71, /* SFS.2 : Present (P) field is 0.*/
+    VTD_FR_FIRST_FSPE_ACCESS = 0x73, /* SFS.4 */
+    VTD_FR_SSPE_ACCESS = 0x78, /* SSS.1 */
+    VTD_FR_FIRST_SSPE_ACCESS = 0x7b, /* SSS.4 */
+    VTD_FR_FS_NON_CANONICAL = 0x80, /* SNG.1 : Address for FS not canonical.*/
+
+    VTD_FR_SM_WRITE = 0x85, /* SGN.6 */
+    VTD_FR_SM_READ = 0x86, /* SGN.7 */
 
     /* Output address in the interrupt address range for scalable mode */
-    VTD_FR_SM_INTERRUPT_ADDR = 0x87,
+    VTD_FR_SM_INTERRUPT_ADDR = 0x87, /* SGN.8 */
+    VTD_FR_FS_BIT_UPDATE_FAILED = 0x91, /* SFS.10 */
     VTD_FR_MAX,                 /* Guard */
 } VTDFaultReason;
 
@@ -431,6 +449,23 @@ typedef union VTDInvDesc VTDInvDesc;
         (0x3ffff800ULL | ~(VTD_HAW_MASK(aw) | VTD_SL_IGN_COM | VTD_SL_TM)) : \
         (0x3ffff800ULL | ~(VTD_HAW_MASK(aw) | VTD_SL_IGN_COM))
 
+#define VTD_FS_UPPER_IGNORED 0xfff0000000000000ULL
+#define VTD_FPTE_PAGE_L1_RSVD_MASK(aw) (~(VTD_HAW_MASK(aw)) & \
+                                       (~VTD_FS_UPPER_IGNORED))
+#define VTD_FPTE_PAGE_L2_RSVD_MASK(aw) (~(VTD_HAW_MASK(aw)) & \
+                                       (~VTD_FS_UPPER_IGNORED))
+#define VTD_FPTE_PAGE_L3_RSVD_MASK(aw) (~(VTD_HAW_MASK(aw)) & \
+                                       (~VTD_FS_UPPER_IGNORED))
+#define VTD_FPTE_PAGE_L3_FS1GP_RSVD_MASK(aw) ((0x3fffe000ULL | \
+                                                ~(VTD_HAW_MASK(aw))) \
+                                              & (~VTD_FS_UPPER_IGNORED))
+#define VTD_FPTE_PAGE_L2_FS2MP_RSVD_MASK(aw) ((0x1fe000ULL | \
+                                                ~(VTD_HAW_MASK(aw))) \
+                                              & (~VTD_FS_UPPER_IGNORED))
+#define VTD_FPTE_PAGE_L4_RSVD_MASK(aw) ((0x80ULL | \
+                                            ~(VTD_HAW_MASK(aw))) \
+                                        & (~VTD_FS_UPPER_IGNORED))
+
 /* Information about page-selective IOTLB invalidate */
 struct VTDIOTLBPageInvInfo {
     uint16_t domain_id;
@@ -514,9 +549,6 @@ typedef struct VTDRootEntry VTDRootEntry;
 #define VTD_SM_PASID_ENTRY_AW          7ULL /* Adjusted guest-address-width */
 #define VTD_SM_PASID_ENTRY_DID(val)    ((val) & VTD_DOMAIN_ID_MASK)
 
-/* Second Level Page Translation Pointer*/
-#define VTD_SM_PASID_ENTRY_SLPTPTR     (~0xfffULL)
-
 /* Paging Structure common */
 #define VTD_SM_PASID_ENTRY_PTPTR    (~0xfffULL)
 #define VTD_PT_PAGE_SIZE_MASK       (1ULL << 7)
@@ -532,6 +564,14 @@ typedef struct VTDRootEntry VTDRootEntry;
 #define VTD_SL_PD_LEVEL             2
 #define VTD_SL_PT_LEVEL             1
 
+/* First Level Paging Structure */
+#define VTD_FL_PDP_LEVEL            3
+#define VTD_FL_PD_LEVEL             2
+#define VTD_FL_PTE_P                0x1
+#define VTD_FL_PTE_A                0x20
+#define VTD_FL_PTE_D                0x40
+#define VTD_FL_PTE_EA               0x400
+
 /* Masks for Second Level Paging Entry */
 #define VTD_SL_RW_MASK              3ULL
 #define VTD_SL_R                    1ULL
@@ -539,4 +579,7 @@ typedef struct VTDRootEntry VTDRootEntry;
 #define VTD_SL_IGN_COM              0xbff0000000000000ULL
 #define VTD_SL_TM                   (1ULL << 62)
 
+/* Masks for First Level Paging Entry */
+#define VTD_FL_W                    (1ULL << 1)
+
 #endif
-- 
2.44.0

^ permalink raw reply related	[flat|nested] 22+ messages in thread

* Re: [PATCH intel_iommu 5/7] intel_iommu: extract device IOTLB invalidation logic
  2024-04-22 15:52 ` [PATCH intel_iommu 5/7] intel_iommu: extract device IOTLB invalidation logic CLEMENT MATHIEU--DRIF
@ 2024-04-22 16:59   ` Philippe Mathieu-Daudé
  2024-04-23  5:07     ` CLEMENT MATHIEU--DRIF
  0 siblings, 1 reply; 22+ messages in thread
From: Philippe Mathieu-Daudé @ 2024-04-22 16:59 UTC (permalink / raw)
  To: CLEMENT MATHIEU--DRIF, qemu-devel; +Cc: jasowang

On 22/4/24 17:52, CLEMENT MATHIEU--DRIF wrote:
> This piece of code can be shared by both IOTLB invalidation and
> PASID-based IOTLB invalidation
> 
> Signed-off-by: Clément Mathieu--Drif <clement.mathieu--drif@eviden.com>
> ---
>   hw/i386/intel_iommu.c | 57 +++++++++++++++++++++++++------------------
>   1 file changed, 33 insertions(+), 24 deletions(-)


>   static bool vtd_process_device_iotlb_desc(IntelIOMMUState *s,
>                                             VTDInvDesc *inv_desc)
>   {
>       VTDAddressSpace *vtd_dev_as;
> -    IOMMUTLBEvent event;
>       hwaddr addr;
> -    uint64_t sz;
>       uint16_t sid;
>       bool size;
>   
> @@ -2912,6 +2941,7 @@ static bool vtd_process_device_iotlb_desc(IntelIOMMUState *s,
>           return false;
>       }
>   
> +

Spurious newline ;)

Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>

>       /*



^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [PATCH intel_iommu 3/7] intel_iommu: make types match
  2024-04-22 15:52 ` [PATCH intel_iommu 3/7] intel_iommu: make types match CLEMENT MATHIEU--DRIF
@ 2024-04-22 17:03   ` Philippe Mathieu-Daudé
  2024-04-23  5:05     ` CLEMENT MATHIEU--DRIF
  0 siblings, 1 reply; 22+ messages in thread
From: Philippe Mathieu-Daudé @ 2024-04-22 17:03 UTC (permalink / raw)
  To: CLEMENT MATHIEU--DRIF, qemu-devel; +Cc: jasowang

On 22/4/24 17:52, CLEMENT MATHIEU--DRIF wrote:
> The 'level' field in vtd_iotlb_key is an uint8_t.
> We don't need to store level as an int in vtd_lookup_iotlb
> 
> Signed-off-by: Clément Mathieu--Drif <clement.mathieu--drif@eviden.com>
> ---
>   hw/i386/intel_iommu.c | 2 +-
>   1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/hw/i386/intel_iommu.c b/hw/i386/intel_iommu.c
> index 6f1364b3fd..ba545590b1 100644
> --- a/hw/i386/intel_iommu.c
> +++ b/hw/i386/intel_iommu.c
> @@ -333,7 +333,7 @@ static VTDIOTLBEntry *vtd_lookup_iotlb(IntelIOMMUState *s, uint16_t source_id,
>   {
>       struct vtd_iotlb_key key;
>       VTDIOTLBEntry *entry;
> -    int level;
> +    uint8_t level;

Or simply 'unsigned' up to vtd_slpt_level_shift()?



^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [PATCH intel_iommu 3/7] intel_iommu: make types match
  2024-04-22 17:03   ` Philippe Mathieu-Daudé
@ 2024-04-23  5:05     ` CLEMENT MATHIEU--DRIF
  2024-04-23  8:19       ` Philippe Mathieu-Daudé
  0 siblings, 1 reply; 22+ messages in thread
From: CLEMENT MATHIEU--DRIF @ 2024-04-23  5:05 UTC (permalink / raw)
  To: Philippe Mathieu-Daudé, qemu-devel; +Cc: jasowang


On 22/04/2024 19:03, Philippe Mathieu-Daudé wrote:
> On 22/4/24 17:52, CLEMENT MATHIEU--DRIF wrote:
>> The 'level' field in vtd_iotlb_key is an uint8_t.
>> We don't need to store level as an int in vtd_lookup_iotlb
>>
>> Signed-off-by: Clément Mathieu--Drif <clement.mathieu--drif@eviden.com>
>> ---
>>   hw/i386/intel_iommu.c | 2 +-
>>   1 file changed, 1 insertion(+), 1 deletion(-)
>>
>> diff --git a/hw/i386/intel_iommu.c b/hw/i386/intel_iommu.c
>> index 6f1364b3fd..ba545590b1 100644
>> --- a/hw/i386/intel_iommu.c
>> +++ b/hw/i386/intel_iommu.c
>> @@ -333,7 +333,7 @@ static VTDIOTLBEntry 
>> *vtd_lookup_iotlb(IntelIOMMUState *s, uint16_t source_id,
>>   {
>>       struct vtd_iotlb_key key;
>>       VTDIOTLBEntry *entry;
>> -    int level;
>> +    uint8_t level;
>
> Or simply 'unsigned' up to vtd_slpt_level_shift()?
vtd_iotlb_key.level is an uint8_t, just avoiding a warning here

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [PATCH intel_iommu 5/7] intel_iommu: extract device IOTLB invalidation logic
  2024-04-22 16:59   ` Philippe Mathieu-Daudé
@ 2024-04-23  5:07     ` CLEMENT MATHIEU--DRIF
  0 siblings, 0 replies; 22+ messages in thread
From: CLEMENT MATHIEU--DRIF @ 2024-04-23  5:07 UTC (permalink / raw)
  To: Philippe Mathieu-Daudé, qemu-devel; +Cc: jasowang


On 22/04/2024 18:59, Philippe Mathieu-Daudé wrote:
> On 22/4/24 17:52, CLEMENT MATHIEU--DRIF wrote:
>> This piece of code can be shared by both IOTLB invalidation and
>> PASID-based IOTLB invalidation
>>
>> Signed-off-by: Clément Mathieu--Drif <clement.mathieu--drif@eviden.com>
>> ---
>>   hw/i386/intel_iommu.c | 57 +++++++++++++++++++++++++------------------
>>   1 file changed, 33 insertions(+), 24 deletions(-)
>
>
>>   static bool vtd_process_device_iotlb_desc(IntelIOMMUState *s,
>>                                             VTDInvDesc *inv_desc)
>>   {
>>       VTDAddressSpace *vtd_dev_as;
>> -    IOMMUTLBEvent event;
>>       hwaddr addr;
>> -    uint64_t sz;
>>       uint16_t sid;
>>       bool size;
>>
>> @@ -2912,6 +2941,7 @@ static bool 
>> vtd_process_device_iotlb_desc(IntelIOMMUState *s,
>>           return false;
>>       }
>>
>> +
>
> Spurious newline ;)
Oups, sorry, it's fixed
>
> Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
>
>>       /*
>

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [PATCH intel_iommu 3/7] intel_iommu: make types match
  2024-04-23  5:05     ` CLEMENT MATHIEU--DRIF
@ 2024-04-23  8:19       ` Philippe Mathieu-Daudé
  2024-04-23 15:17         ` CLEMENT MATHIEU--DRIF
  0 siblings, 1 reply; 22+ messages in thread
From: Philippe Mathieu-Daudé @ 2024-04-23  8:19 UTC (permalink / raw)
  To: CLEMENT MATHIEU--DRIF, qemu-devel; +Cc: jasowang

On 23/4/24 07:05, CLEMENT MATHIEU--DRIF wrote:
> 
> On 22/04/2024 19:03, Philippe Mathieu-Daudé wrote:
>> On 22/4/24 17:52, CLEMENT MATHIEU--DRIF wrote:
>>> The 'level' field in vtd_iotlb_key is an uint8_t.
>>> We don't need to store level as an int in vtd_lookup_iotlb
>>>
>>> Signed-off-by: Clément Mathieu--Drif <clement.mathieu--drif@eviden.com>
>>> ---
>>>    hw/i386/intel_iommu.c | 2 +-
>>>    1 file changed, 1 insertion(+), 1 deletion(-)
>>>
>>> diff --git a/hw/i386/intel_iommu.c b/hw/i386/intel_iommu.c
>>> index 6f1364b3fd..ba545590b1 100644
>>> --- a/hw/i386/intel_iommu.c
>>> +++ b/hw/i386/intel_iommu.c
>>> @@ -333,7 +333,7 @@ static VTDIOTLBEntry
>>> *vtd_lookup_iotlb(IntelIOMMUState *s, uint16_t source_id,
>>>    {
>>>        struct vtd_iotlb_key key;
>>>        VTDIOTLBEntry *entry;
>>> -    int level;
>>> +    uint8_t level;
>>
>> Or simply 'unsigned' up to vtd_slpt_level_shift()?
> vtd_iotlb_key.level is an uint8_t, just avoiding a warning here

What warning?


^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [PATCH intel_iommu 3/7] intel_iommu: make types match
  2024-04-23  8:19       ` Philippe Mathieu-Daudé
@ 2024-04-23 15:17         ` CLEMENT MATHIEU--DRIF
  0 siblings, 0 replies; 22+ messages in thread
From: CLEMENT MATHIEU--DRIF @ 2024-04-23 15:17 UTC (permalink / raw)
  To: Philippe Mathieu-Daudé, qemu-devel; +Cc: jasowang


On 23/04/2024 10:19, Philippe Mathieu-Daudé wrote:
>
> On 23/4/24 07:05, CLEMENT MATHIEU--DRIF wrote:
>>
>> On 22/04/2024 19:03, Philippe Mathieu-Daudé wrote:
>>> On 22/4/24 17:52, CLEMENT MATHIEU--DRIF wrote:
>>>> The 'level' field in vtd_iotlb_key is an uint8_t.
>>>> We don't need to store level as an int in vtd_lookup_iotlb
>>>>
>>>> Signed-off-by: Clément Mathieu--Drif 
>>>> <clement.mathieu--drif@eviden.com>
>>>> ---
>>>>    hw/i386/intel_iommu.c | 2 +-
>>>>    1 file changed, 1 insertion(+), 1 deletion(-)
>>>>
>>>> diff --git a/hw/i386/intel_iommu.c b/hw/i386/intel_iommu.c
>>>> index 6f1364b3fd..ba545590b1 100644
>>>> --- a/hw/i386/intel_iommu.c
>>>> +++ b/hw/i386/intel_iommu.c
>>>> @@ -333,7 +333,7 @@ static VTDIOTLBEntry
>>>> *vtd_lookup_iotlb(IntelIOMMUState *s, uint16_t source_id,
>>>>    {
>>>>        struct vtd_iotlb_key key;
>>>>        VTDIOTLBEntry *entry;
>>>> -    int level;
>>>> +    uint8_t level;
>>>
>>> Or simply 'unsigned' up to vtd_slpt_level_shift()?
>> vtd_iotlb_key.level is an uint8_t, just avoiding a warning here
>
> What warning?
A linter warning, but it's not a big deal in our case because we know 
the value is lower than 5

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [PATCH intel_iommu 0/7] FLTS for VT-d
  2024-04-22 15:52 [PATCH intel_iommu 0/7] FLTS for VT-d CLEMENT MATHIEU--DRIF
                   ` (6 preceding siblings ...)
  2024-04-22 15:52 ` [PATCH intel_iommu 4/7] intel_iommu: add support for first-stage translation CLEMENT MATHIEU--DRIF
@ 2024-04-30 14:04 ` Philippe Mathieu-Daudé
  2024-04-30 14:13 ` Cédric Le Goater
  8 siblings, 0 replies; 22+ messages in thread
From: Philippe Mathieu-Daudé @ 2024-04-30 14:04 UTC (permalink / raw)
  To: CLEMENT MATHIEU--DRIF, Michael S. Tsirkin, qemu-devel
  Cc: jasowang, Eric Auger, Zhenzhong Duan, Eugenio Pérez

Cc'ing few developers who touched the intel_iommu model ;)

On 22/4/24 17:52, CLEMENT MATHIEU--DRIF wrote:
> This series is the first of a list that add support for SVM in the Intel IOMMU.
> 
> Here, we implement support for first-stage translation in VT-d.
> The PASID-based IOTLB invalidation is also added in this series as it is a
> requirement of FLTS.
> 
> The last patch introduces the 'flts' option to enable the feature from
> the command line.
> Once enabled, several drivers of the Linux kernel use this feature.
> 
> This work is based on the VT-d specification version 4.1 (March 2023)
> 
> Here is a link to a GitHub repository where you can find the following elements :
>      - Qemu with all the patches for SVM
>          - ATS
>          - PRI
>          - PASID based IOTLB invalidation
>          - Device IOTLB invalidations
>          - First-stage translations
>          - Requests with already translated addresses
>      - A demo device
>      - A simple driver for the demo device
>      - A userspace program (for testing and demonstration purposes)
> 
> https://github.com/BullSequana/Qemu-in-guest-SVM-demo
> 
> Clément Mathieu--Drif (7):
>    intel_iommu: fix FRCD construction macro.
>    intel_iommu: rename slpte to pte before adding FLTS
>    intel_iommu: make types match
>    intel_iommu: add support for first-stage translation
>    intel_iommu: extract device IOTLB invalidation logic
>    intel_iommu: add PASID-based IOTLB invalidation
>    intel_iommu: add a CLI option to enable FLTS
> 
>   hw/i386/intel_iommu.c          | 655 ++++++++++++++++++++++++++-------
>   hw/i386/intel_iommu_internal.h | 114 ++++--
>   include/hw/i386/intel_iommu.h  |   3 +-
>   3 files changed, 609 insertions(+), 163 deletions(-)
> 



^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [PATCH intel_iommu 0/7] FLTS for VT-d
  2024-04-22 15:52 [PATCH intel_iommu 0/7] FLTS for VT-d CLEMENT MATHIEU--DRIF
                   ` (7 preceding siblings ...)
  2024-04-30 14:04 ` [PATCH intel_iommu 0/7] FLTS for VT-d Philippe Mathieu-Daudé
@ 2024-04-30 14:13 ` Cédric Le Goater
  2024-05-01 12:40   ` Duan, Zhenzhong
  8 siblings, 1 reply; 22+ messages in thread
From: Cédric Le Goater @ 2024-04-30 14:13 UTC (permalink / raw)
  To: CLEMENT MATHIEU--DRIF, qemu-devel
  Cc: jasowang, Zhenzhong Duan, Tian, Kevin, Liu Yi L, Joao Martins, Peter Xu

Hello,

Adding a few people in Cc: who are familiar with the Intel IOMMU.

Thanks,

C.




On 4/22/24 17:52, CLEMENT MATHIEU--DRIF wrote:
> This series is the first of a list that add support for SVM in the Intel IOMMU.
> 
> Here, we implement support for first-stage translation in VT-d.
> The PASID-based IOTLB invalidation is also added in this series as it is a
> requirement of FLTS.
> 
> The last patch introduces the 'flts' option to enable the feature from
> the command line.
> Once enabled, several drivers of the Linux kernel use this feature.
> 
> This work is based on the VT-d specification version 4.1 (March 2023)
> 
> Here is a link to a GitHub repository where you can find the following elements :
>      - Qemu with all the patches for SVM
>          - ATS
>          - PRI
>          - PASID based IOTLB invalidation
>          - Device IOTLB invalidations
>          - First-stage translations
>          - Requests with already translated addresses
>      - A demo device
>      - A simple driver for the demo device
>      - A userspace program (for testing and demonstration purposes)
> 
> https://github.com/BullSequana/Qemu-in-guest-SVM-demo
> 
> Clément Mathieu--Drif (7):
>    intel_iommu: fix FRCD construction macro.
>    intel_iommu: rename slpte to pte before adding FLTS
>    intel_iommu: make types match
>    intel_iommu: add support for first-stage translation
>    intel_iommu: extract device IOTLB invalidation logic
>    intel_iommu: add PASID-based IOTLB invalidation
>    intel_iommu: add a CLI option to enable FLTS
> 
>   hw/i386/intel_iommu.c          | 655 ++++++++++++++++++++++++++-------
>   hw/i386/intel_iommu_internal.h | 114 ++++--
>   include/hw/i386/intel_iommu.h  |   3 +-
>   3 files changed, 609 insertions(+), 163 deletions(-)
> 



^ permalink raw reply	[flat|nested] 22+ messages in thread

* RE: [PATCH intel_iommu 0/7] FLTS for VT-d
  2024-04-30 14:13 ` Cédric Le Goater
@ 2024-05-01 12:40   ` Duan, Zhenzhong
  2024-05-02  5:03     ` CLEMENT MATHIEU--DRIF
  0 siblings, 1 reply; 22+ messages in thread
From: Duan, Zhenzhong @ 2024-05-01 12:40 UTC (permalink / raw)
  To: Cédric Le Goater, CLEMENT MATHIEU--DRIF, qemu-devel
  Cc: jasowang, Tian, Kevin, Liu, Yi L, Joao Martins, Peter Xu,
	Eric Auger, eperezma, Peng, Chao P

Ah, this is a duplicate effort on stage-1 translation.

Hi Clement,

We had ever sent a rfcv1 series "intel_iommu: Enable stage-1 translation"
for both emulated and passthrough device, link:
https://lists.gnu.org/archive/html/qemu-devel/2024-01/msg02740.html
which now evolves to rfcv2, link:
https://github.com/yiliu1765/qemu/commits/zhenzhong/iommufd_nesting_rfcv2/

It had addressed recent community comments, also the comments in old history series: 
https://patchwork.kernel.org/project/kvm/cover/20210302203827.437645-1-yi.l.liu@intel.com/

Would you mind rebasing your remaining part, i.e., ATS, PRI emulation, etc on to our rfcv2?

Thanks
Zhenzhong

>-----Original Message-----
>From: Cédric Le Goater <clg@redhat.com>
>Subject: Re: [PATCH intel_iommu 0/7] FLTS for VT-d
>
>Hello,
>
>Adding a few people in Cc: who are familiar with the Intel IOMMU.
>
>Thanks,
>
>C.
>
>
>
>
>On 4/22/24 17:52, CLEMENT MATHIEU--DRIF wrote:
>> This series is the first of a list that add support for SVM in the Intel IOMMU.
>>
>> Here, we implement support for first-stage translation in VT-d.
>> The PASID-based IOTLB invalidation is also added in this series as it is a
>> requirement of FLTS.
>>
>> The last patch introduces the 'flts' option to enable the feature from
>> the command line.
>> Once enabled, several drivers of the Linux kernel use this feature.
>>
>> This work is based on the VT-d specification version 4.1 (March 2023)
>>
>> Here is a link to a GitHub repository where you can find the following
>elements :
>>      - Qemu with all the patches for SVM
>>          - ATS
>>          - PRI
>>          - PASID based IOTLB invalidation
>>          - Device IOTLB invalidations
>>          - First-stage translations
>>          - Requests with already translated addresses
>>      - A demo device
>>      - A simple driver for the demo device
>>      - A userspace program (for testing and demonstration purposes)
>>
>> https://github.com/BullSequana/Qemu-in-guest-SVM-demo
>>
>> Clément Mathieu--Drif (7):
>>    intel_iommu: fix FRCD construction macro.
>>    intel_iommu: rename slpte to pte before adding FLTS
>>    intel_iommu: make types match
>>    intel_iommu: add support for first-stage translation
>>    intel_iommu: extract device IOTLB invalidation logic
>>    intel_iommu: add PASID-based IOTLB invalidation
>>    intel_iommu: add a CLI option to enable FLTS
>>
>>   hw/i386/intel_iommu.c          | 655 ++++++++++++++++++++++++++------
>-
>>   hw/i386/intel_iommu_internal.h | 114 ++++--
>>   include/hw/i386/intel_iommu.h  |   3 +-
>>   3 files changed, 609 insertions(+), 163 deletions(-)
>>


^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [PATCH intel_iommu 0/7] FLTS for VT-d
  2024-05-01 12:40   ` Duan, Zhenzhong
@ 2024-05-02  5:03     ` CLEMENT MATHIEU--DRIF
  2024-05-06  1:38       ` Duan, Zhenzhong
  0 siblings, 1 reply; 22+ messages in thread
From: CLEMENT MATHIEU--DRIF @ 2024-05-02  5:03 UTC (permalink / raw)
  To: Duan, Zhenzhong, Cédric Le Goater, qemu-devel
  Cc: jasowang, Tian, Kevin, Liu, Yi L, Joao Martins, Peter Xu,
	Eric Auger, eperezma, Peng, Chao P

Hi Zhenzhong,

I will rebase,

thanks

On 01/05/2024 14:40, Duan, Zhenzhong wrote:
> Caution: External email. Do not open attachments or click links, unless this email comes from a known sender and you know the content is safe.
>
>
> Ah, this is a duplicate effort on stage-1 translation.
>
> Hi Clement,
>
> We had ever sent a rfcv1 series "intel_iommu: Enable stage-1 translation"
> for both emulated and passthrough device, link:
> https://lists.gnu.org/archive/html/qemu-devel/2024-01/msg02740.html
> which now evolves to rfcv2, link:
> https://github.com/yiliu1765/qemu/commits/zhenzhong/iommufd_nesting_rfcv2/
>
> It had addressed recent community comments, also the comments in old history series:
> https://patchwork.kernel.org/project/kvm/cover/20210302203827.437645-1-yi.l.liu@intel.com/
>
> Would you mind rebasing your remaining part, i.e., ATS, PRI emulation, etc on to our rfcv2?
>
> Thanks
> Zhenzhong
>
>> -----Original Message-----
>> From: Cédric Le Goater <clg@redhat.com>
>> Subject: Re: [PATCH intel_iommu 0/7] FLTS for VT-d
>>
>> Hello,
>>
>> Adding a few people in Cc: who are familiar with the Intel IOMMU.
>>
>> Thanks,
>>
>> C.
>>
>>
>>
>>
>> On 4/22/24 17:52, CLEMENT MATHIEU--DRIF wrote:
>>> This series is the first of a list that add support for SVM in the Intel IOMMU.
>>>
>>> Here, we implement support for first-stage translation in VT-d.
>>> The PASID-based IOTLB invalidation is also added in this series as it is a
>>> requirement of FLTS.
>>>
>>> The last patch introduces the 'flts' option to enable the feature from
>>> the command line.
>>> Once enabled, several drivers of the Linux kernel use this feature.
>>>
>>> This work is based on the VT-d specification version 4.1 (March 2023)
>>>
>>> Here is a link to a GitHub repository where you can find the following
>> elements :
>>>       - Qemu with all the patches for SVM
>>>           - ATS
>>>           - PRI
>>>           - PASID based IOTLB invalidation
>>>           - Device IOTLB invalidations
>>>           - First-stage translations
>>>           - Requests with already translated addresses
>>>       - A demo device
>>>       - A simple driver for the demo device
>>>       - A userspace program (for testing and demonstration purposes)
>>>
>>> https://github.com/BullSequana/Qemu-in-guest-SVM-demo
>>>
>>> Clément Mathieu--Drif (7):
>>>     intel_iommu: fix FRCD construction macro.
>>>     intel_iommu: rename slpte to pte before adding FLTS
>>>     intel_iommu: make types match
>>>     intel_iommu: add support for first-stage translation
>>>     intel_iommu: extract device IOTLB invalidation logic
>>>     intel_iommu: add PASID-based IOTLB invalidation
>>>     intel_iommu: add a CLI option to enable FLTS
>>>
>>>    hw/i386/intel_iommu.c          | 655 ++++++++++++++++++++++++++------
>> -
>>>    hw/i386/intel_iommu_internal.h | 114 ++++--
>>>    include/hw/i386/intel_iommu.h  |   3 +-
>>>    3 files changed, 609 insertions(+), 163 deletions(-)
>>>

^ permalink raw reply	[flat|nested] 22+ messages in thread

* RE: [PATCH intel_iommu 0/7] FLTS for VT-d
  2024-05-02  5:03     ` CLEMENT MATHIEU--DRIF
@ 2024-05-06  1:38       ` Duan, Zhenzhong
  2024-05-14  5:02         ` CLEMENT MATHIEU--DRIF
  0 siblings, 1 reply; 22+ messages in thread
From: Duan, Zhenzhong @ 2024-05-06  1:38 UTC (permalink / raw)
  To: CLEMENT MATHIEU--DRIF, Cédric Le Goater, qemu-devel
  Cc: jasowang, Tian, Kevin, Liu, Yi L, Joao Martins, Peter Xu,
	Eric Auger, eperezma, Peng, Chao P

Hi Clement,

Sorry for late response, just back from vacation.
I saw your rebased version and thanks for your work.
I'll schedule a timeslot to review them.

Thanks
Zhenzhong

>-----Original Message-----
>From: CLEMENT MATHIEU--DRIF <clement.mathieu--drif@eviden.com>
>Subject: Re: [PATCH intel_iommu 0/7] FLTS for VT-d
>
>Hi Zhenzhong,
>
>I will rebase,
>
>thanks
>
>On 01/05/2024 14:40, Duan, Zhenzhong wrote:
>> Caution: External email. Do not open attachments or click links, unless this
>email comes from a known sender and you know the content is safe.
>>
>>
>> Ah, this is a duplicate effort on stage-1 translation.
>>
>> Hi Clement,
>>
>> We had ever sent a rfcv1 series "intel_iommu: Enable stage-1 translation"
>> for both emulated and passthrough device, link:
>> https://lists.gnu.org/archive/html/qemu-devel/2024-01/msg02740.html
>> which now evolves to rfcv2, link:
>>
>https://github.com/yiliu1765/qemu/commits/zhenzhong/iommufd_nesting
>_rfcv2/
>>
>> It had addressed recent community comments, also the comments in old
>history series:
>>
>https://patchwork.kernel.org/project/kvm/cover/20210302203827.437645
>-1-yi.l.liu@intel.com/
>>
>> Would you mind rebasing your remaining part, i.e., ATS, PRI emulation, etc
>on to our rfcv2?
>>
>> Thanks
>> Zhenzhong
>>
>>> -----Original Message-----
>>> From: Cédric Le Goater <clg@redhat.com>
>>> Subject: Re: [PATCH intel_iommu 0/7] FLTS for VT-d
>>>
>>> Hello,
>>>
>>> Adding a few people in Cc: who are familiar with the Intel IOMMU.
>>>
>>> Thanks,
>>>
>>> C.
>>>
>>>
>>>
>>>
>>> On 4/22/24 17:52, CLEMENT MATHIEU--DRIF wrote:
>>>> This series is the first of a list that add support for SVM in the Intel
>IOMMU.
>>>>
>>>> Here, we implement support for first-stage translation in VT-d.
>>>> The PASID-based IOTLB invalidation is also added in this series as it is a
>>>> requirement of FLTS.
>>>>
>>>> The last patch introduces the 'flts' option to enable the feature from
>>>> the command line.
>>>> Once enabled, several drivers of the Linux kernel use this feature.
>>>>
>>>> This work is based on the VT-d specification version 4.1 (March 2023)
>>>>
>>>> Here is a link to a GitHub repository where you can find the following
>>> elements :
>>>>       - Qemu with all the patches for SVM
>>>>           - ATS
>>>>           - PRI
>>>>           - PASID based IOTLB invalidation
>>>>           - Device IOTLB invalidations
>>>>           - First-stage translations
>>>>           - Requests with already translated addresses
>>>>       - A demo device
>>>>       - A simple driver for the demo device
>>>>       - A userspace program (for testing and demonstration purposes)
>>>>
>>>> https://github.com/BullSequana/Qemu-in-guest-SVM-demo
>>>>
>>>> Clément Mathieu--Drif (7):
>>>>     intel_iommu: fix FRCD construction macro.
>>>>     intel_iommu: rename slpte to pte before adding FLTS
>>>>     intel_iommu: make types match
>>>>     intel_iommu: add support for first-stage translation
>>>>     intel_iommu: extract device IOTLB invalidation logic
>>>>     intel_iommu: add PASID-based IOTLB invalidation
>>>>     intel_iommu: add a CLI option to enable FLTS
>>>>
>>>>    hw/i386/intel_iommu.c          | 655 ++++++++++++++++++++++++++-
>-----
>>> -
>>>>    hw/i386/intel_iommu_internal.h | 114 ++++--
>>>>    include/hw/i386/intel_iommu.h  |   3 +-
>>>>    3 files changed, 609 insertions(+), 163 deletions(-)
>>>>

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [PATCH intel_iommu 0/7] FLTS for VT-d
  2024-05-06  1:38       ` Duan, Zhenzhong
@ 2024-05-14  5:02         ` CLEMENT MATHIEU--DRIF
  2024-05-14  5:50           ` Duan, Zhenzhong
  0 siblings, 1 reply; 22+ messages in thread
From: CLEMENT MATHIEU--DRIF @ 2024-05-14  5:02 UTC (permalink / raw)
  To: Duan, Zhenzhong, Cédric Le Goater, qemu-devel
  Cc: jasowang, Tian, Kevin, Liu, Yi L, Joao Martins, Peter Xu,
	Eric Auger, eperezma, Peng, Chao P

Hi Zhenzhong

Have you had time to review the ATS series rebased on you FLTS patches?

Thanks
 >cmd


On 06/05/2024 03:38, Duan, Zhenzhong wrote:
> Caution: External email. Do not open attachments or click links, unless this email comes from a known sender and you know the content is safe.
>
>
> Hi Clement,
>
> Sorry for late response, just back from vacation.
> I saw your rebased version and thanks for your work.
> I'll schedule a timeslot to review them.
>
> Thanks
> Zhenzhong
>
>> -----Original Message-----
>> From: CLEMENT MATHIEU--DRIF <clement.mathieu--drif@eviden.com>
>> Subject: Re: [PATCH intel_iommu 0/7] FLTS for VT-d
>>
>> Hi Zhenzhong,
>>
>> I will rebase,
>>
>> thanks
>>
>> On 01/05/2024 14:40, Duan, Zhenzhong wrote:
>>> Caution: External email. Do not open attachments or click links, unless this
>> email comes from a known sender and you know the content is safe.
>>>
>>> Ah, this is a duplicate effort on stage-1 translation.
>>>
>>> Hi Clement,
>>>
>>> We had ever sent a rfcv1 series "intel_iommu: Enable stage-1 translation"
>>> for both emulated and passthrough device, link:
>>> https://lists.gnu.org/archive/html/qemu-devel/2024-01/msg02740.html
>>> which now evolves to rfcv2, link:
>>>
>> https://github.com/yiliu1765/qemu/commits/zhenzhong/iommufd_nesting
>> _rfcv2/
>>> It had addressed recent community comments, also the comments in old
>> history series:
>> https://patchwork.kernel.org/project/kvm/cover/20210302203827.437645
>> -1-yi.l.liu@intel.com/
>>> Would you mind rebasing your remaining part, i.e., ATS, PRI emulation, etc
>> on to our rfcv2?
>>> Thanks
>>> Zhenzhong
>>>
>>>> -----Original Message-----
>>>> From: Cédric Le Goater <clg@redhat.com>
>>>> Subject: Re: [PATCH intel_iommu 0/7] FLTS for VT-d
>>>>
>>>> Hello,
>>>>
>>>> Adding a few people in Cc: who are familiar with the Intel IOMMU.
>>>>
>>>> Thanks,
>>>>
>>>> C.
>>>>
>>>>
>>>>
>>>>
>>>> On 4/22/24 17:52, CLEMENT MATHIEU--DRIF wrote:
>>>>> This series is the first of a list that add support for SVM in the Intel
>> IOMMU.
>>>>> Here, we implement support for first-stage translation in VT-d.
>>>>> The PASID-based IOTLB invalidation is also added in this series as it is a
>>>>> requirement of FLTS.
>>>>>
>>>>> The last patch introduces the 'flts' option to enable the feature from
>>>>> the command line.
>>>>> Once enabled, several drivers of the Linux kernel use this feature.
>>>>>
>>>>> This work is based on the VT-d specification version 4.1 (March 2023)
>>>>>
>>>>> Here is a link to a GitHub repository where you can find the following
>>>> elements :
>>>>>        - Qemu with all the patches for SVM
>>>>>            - ATS
>>>>>            - PRI
>>>>>            - PASID based IOTLB invalidation
>>>>>            - Device IOTLB invalidations
>>>>>            - First-stage translations
>>>>>            - Requests with already translated addresses
>>>>>        - A demo device
>>>>>        - A simple driver for the demo device
>>>>>        - A userspace program (for testing and demonstration purposes)
>>>>>
>>>>> https://github.com/BullSequana/Qemu-in-guest-SVM-demo
>>>>>
>>>>> Clément Mathieu--Drif (7):
>>>>>      intel_iommu: fix FRCD construction macro.
>>>>>      intel_iommu: rename slpte to pte before adding FLTS
>>>>>      intel_iommu: make types match
>>>>>      intel_iommu: add support for first-stage translation
>>>>>      intel_iommu: extract device IOTLB invalidation logic
>>>>>      intel_iommu: add PASID-based IOTLB invalidation
>>>>>      intel_iommu: add a CLI option to enable FLTS
>>>>>
>>>>>     hw/i386/intel_iommu.c          | 655 ++++++++++++++++++++++++++-
>> -----
>>>> -
>>>>>     hw/i386/intel_iommu_internal.h | 114 ++++--
>>>>>     include/hw/i386/intel_iommu.h  |   3 +-
>>>>>     3 files changed, 609 insertions(+), 163 deletions(-)
>>>>>

^ permalink raw reply	[flat|nested] 22+ messages in thread

* RE: [PATCH intel_iommu 0/7] FLTS for VT-d
  2024-05-14  5:02         ` CLEMENT MATHIEU--DRIF
@ 2024-05-14  5:50           ` Duan, Zhenzhong
  2024-05-14  6:13             ` CLEMENT MATHIEU--DRIF
  0 siblings, 1 reply; 22+ messages in thread
From: Duan, Zhenzhong @ 2024-05-14  5:50 UTC (permalink / raw)
  To: CLEMENT MATHIEU--DRIF, Cédric Le Goater, qemu-devel
  Cc: jasowang, Tian, Kevin, Liu, Yi L, Joao Martins, Peter Xu,
	Eric Auger, eperezma, Peng, Chao P

Hi Clement,

I'll learn and try to give comments this week.

Thanks
Zhenzhong

>-----Original Message-----
>From: CLEMENT MATHIEU--DRIF <clement.mathieu--drif@eviden.com>
>Subject: Re: [PATCH intel_iommu 0/7] FLTS for VT-d
>
>Hi Zhenzhong
>
>Have you had time to review the ATS series rebased on you FLTS patches?
>
>Thanks
> >cmd
>
>
>On 06/05/2024 03:38, Duan, Zhenzhong wrote:
>> Caution: External email. Do not open attachments or click links, unless this
>email comes from a known sender and you know the content is safe.
>>
>>
>> Hi Clement,
>>
>> Sorry for late response, just back from vacation.
>> I saw your rebased version and thanks for your work.
>> I'll schedule a timeslot to review them.
>>
>> Thanks
>> Zhenzhong
>>
>>> -----Original Message-----
>>> From: CLEMENT MATHIEU--DRIF <clement.mathieu--drif@eviden.com>
>>> Subject: Re: [PATCH intel_iommu 0/7] FLTS for VT-d
>>>
>>> Hi Zhenzhong,
>>>
>>> I will rebase,
>>>
>>> thanks
>>>
>>> On 01/05/2024 14:40, Duan, Zhenzhong wrote:
>>>> Caution: External email. Do not open attachments or click links, unless
>this
>>> email comes from a known sender and you know the content is safe.
>>>>
>>>> Ah, this is a duplicate effort on stage-1 translation.
>>>>
>>>> Hi Clement,
>>>>
>>>> We had ever sent a rfcv1 series "intel_iommu: Enable stage-1
>translation"
>>>> for both emulated and passthrough device, link:
>>>> https://lists.gnu.org/archive/html/qemu-devel/2024-
>01/msg02740.html
>>>> which now evolves to rfcv2, link:
>>>>
>>>
>https://github.com/yiliu1765/qemu/commits/zhenzhong/iommufd_nesting
>>> _rfcv2/
>>>> It had addressed recent community comments, also the comments in
>old
>>> history series:
>>>
>https://patchwork.kernel.org/project/kvm/cover/20210302203827.437645
>>> -1-yi.l.liu@intel.com/
>>>> Would you mind rebasing your remaining part, i.e., ATS, PRI emulation,
>etc
>>> on to our rfcv2?
>>>> Thanks
>>>> Zhenzhong
>>>>
>>>>> -----Original Message-----
>>>>> From: Cédric Le Goater <clg@redhat.com>
>>>>> Subject: Re: [PATCH intel_iommu 0/7] FLTS for VT-d
>>>>>
>>>>> Hello,
>>>>>
>>>>> Adding a few people in Cc: who are familiar with the Intel IOMMU.
>>>>>
>>>>> Thanks,
>>>>>
>>>>> C.
>>>>>
>>>>>
>>>>>
>>>>>
>>>>> On 4/22/24 17:52, CLEMENT MATHIEU--DRIF wrote:
>>>>>> This series is the first of a list that add support for SVM in the Intel
>>> IOMMU.
>>>>>> Here, we implement support for first-stage translation in VT-d.
>>>>>> The PASID-based IOTLB invalidation is also added in this series as it is
>a
>>>>>> requirement of FLTS.
>>>>>>
>>>>>> The last patch introduces the 'flts' option to enable the feature from
>>>>>> the command line.
>>>>>> Once enabled, several drivers of the Linux kernel use this feature.
>>>>>>
>>>>>> This work is based on the VT-d specification version 4.1 (March 2023)
>>>>>>
>>>>>> Here is a link to a GitHub repository where you can find the following
>>>>> elements :
>>>>>>        - Qemu with all the patches for SVM
>>>>>>            - ATS
>>>>>>            - PRI
>>>>>>            - PASID based IOTLB invalidation
>>>>>>            - Device IOTLB invalidations
>>>>>>            - First-stage translations
>>>>>>            - Requests with already translated addresses
>>>>>>        - A demo device
>>>>>>        - A simple driver for the demo device
>>>>>>        - A userspace program (for testing and demonstration purposes)
>>>>>>
>>>>>> https://github.com/BullSequana/Qemu-in-guest-SVM-demo
>>>>>>
>>>>>> Clément Mathieu--Drif (7):
>>>>>>      intel_iommu: fix FRCD construction macro.
>>>>>>      intel_iommu: rename slpte to pte before adding FLTS
>>>>>>      intel_iommu: make types match
>>>>>>      intel_iommu: add support for first-stage translation
>>>>>>      intel_iommu: extract device IOTLB invalidation logic
>>>>>>      intel_iommu: add PASID-based IOTLB invalidation
>>>>>>      intel_iommu: add a CLI option to enable FLTS
>>>>>>
>>>>>>     hw/i386/intel_iommu.c          | 655
>++++++++++++++++++++++++++-
>>> -----
>>>>> -
>>>>>>     hw/i386/intel_iommu_internal.h | 114 ++++--
>>>>>>     include/hw/i386/intel_iommu.h  |   3 +-
>>>>>>     3 files changed, 609 insertions(+), 163 deletions(-)
>>>>>>

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [PATCH intel_iommu 0/7] FLTS for VT-d
  2024-05-14  5:50           ` Duan, Zhenzhong
@ 2024-05-14  6:13             ` CLEMENT MATHIEU--DRIF
  0 siblings, 0 replies; 22+ messages in thread
From: CLEMENT MATHIEU--DRIF @ 2024-05-14  6:13 UTC (permalink / raw)
  To: Duan, Zhenzhong, Cédric Le Goater, qemu-devel
  Cc: jasowang, Tian, Kevin, Liu, Yi L, Joao Martins, Peter Xu,
	Eric Auger, eperezma, Peng, Chao P

Thanks ;)

 >cmd

On 14/05/2024 07:50, Duan, Zhenzhong wrote:
> Caution: External email. Do not open attachments or click links, unless this email comes from a known sender and you know the content is safe.
>
>
> Hi Clement,
>
> I'll learn and try to give comments this week.
>
> Thanks
> Zhenzhong
>
>> -----Original Message-----
>> From: CLEMENT MATHIEU--DRIF <clement.mathieu--drif@eviden.com>
>> Subject: Re: [PATCH intel_iommu 0/7] FLTS for VT-d
>>
>> Hi Zhenzhong
>>
>> Have you had time to review the ATS series rebased on you FLTS patches?
>>
>> Thanks
>>> cmd
>>
>> On 06/05/2024 03:38, Duan, Zhenzhong wrote:
>>> Caution: External email. Do not open attachments or click links, unless this
>> email comes from a known sender and you know the content is safe.
>>>
>>> Hi Clement,
>>>
>>> Sorry for late response, just back from vacation.
>>> I saw your rebased version and thanks for your work.
>>> I'll schedule a timeslot to review them.
>>>
>>> Thanks
>>> Zhenzhong
>>>
>>>> -----Original Message-----
>>>> From: CLEMENT MATHIEU--DRIF <clement.mathieu--drif@eviden.com>
>>>> Subject: Re: [PATCH intel_iommu 0/7] FLTS for VT-d
>>>>
>>>> Hi Zhenzhong,
>>>>
>>>> I will rebase,
>>>>
>>>> thanks
>>>>
>>>> On 01/05/2024 14:40, Duan, Zhenzhong wrote:
>>>>> Caution: External email. Do not open attachments or click links, unless
>> this
>>>> email comes from a known sender and you know the content is safe.
>>>>> Ah, this is a duplicate effort on stage-1 translation.
>>>>>
>>>>> Hi Clement,
>>>>>
>>>>> We had ever sent a rfcv1 series "intel_iommu: Enable stage-1
>> translation"
>>>>> for both emulated and passthrough device, link:
>>>>> https://lists.gnu.org/archive/html/qemu-devel/2024-
>> 01/msg02740.html
>>>>> which now evolves to rfcv2, link:
>>>>>
>> https://github.com/yiliu1765/qemu/commits/zhenzhong/iommufd_nesting
>>>> _rfcv2/
>>>>> It had addressed recent community comments, also the comments in
>> old
>>>> history series:
>>>>
>> https://patchwork.kernel.org/project/kvm/cover/20210302203827.437645
>>>> -1-yi.l.liu@intel.com/
>>>>> Would you mind rebasing your remaining part, i.e., ATS, PRI emulation,
>> etc
>>>> on to our rfcv2?
>>>>> Thanks
>>>>> Zhenzhong
>>>>>
>>>>>> -----Original Message-----
>>>>>> From: Cédric Le Goater <clg@redhat.com>
>>>>>> Subject: Re: [PATCH intel_iommu 0/7] FLTS for VT-d
>>>>>>
>>>>>> Hello,
>>>>>>
>>>>>> Adding a few people in Cc: who are familiar with the Intel IOMMU.
>>>>>>
>>>>>> Thanks,
>>>>>>
>>>>>> C.
>>>>>>
>>>>>>
>>>>>>
>>>>>>
>>>>>> On 4/22/24 17:52, CLEMENT MATHIEU--DRIF wrote:
>>>>>>> This series is the first of a list that add support for SVM in the Intel
>>>> IOMMU.
>>>>>>> Here, we implement support for first-stage translation in VT-d.
>>>>>>> The PASID-based IOTLB invalidation is also added in this series as it is
>> a
>>>>>>> requirement of FLTS.
>>>>>>>
>>>>>>> The last patch introduces the 'flts' option to enable the feature from
>>>>>>> the command line.
>>>>>>> Once enabled, several drivers of the Linux kernel use this feature.
>>>>>>>
>>>>>>> This work is based on the VT-d specification version 4.1 (March 2023)
>>>>>>>
>>>>>>> Here is a link to a GitHub repository where you can find the following
>>>>>> elements :
>>>>>>>         - Qemu with all the patches for SVM
>>>>>>>             - ATS
>>>>>>>             - PRI
>>>>>>>             - PASID based IOTLB invalidation
>>>>>>>             - Device IOTLB invalidations
>>>>>>>             - First-stage translations
>>>>>>>             - Requests with already translated addresses
>>>>>>>         - A demo device
>>>>>>>         - A simple driver for the demo device
>>>>>>>         - A userspace program (for testing and demonstration purposes)
>>>>>>>
>>>>>>> https://github.com/BullSequana/Qemu-in-guest-SVM-demo
>>>>>>>
>>>>>>> Clément Mathieu--Drif (7):
>>>>>>>       intel_iommu: fix FRCD construction macro.
>>>>>>>       intel_iommu: rename slpte to pte before adding FLTS
>>>>>>>       intel_iommu: make types match
>>>>>>>       intel_iommu: add support for first-stage translation
>>>>>>>       intel_iommu: extract device IOTLB invalidation logic
>>>>>>>       intel_iommu: add PASID-based IOTLB invalidation
>>>>>>>       intel_iommu: add a CLI option to enable FLTS
>>>>>>>
>>>>>>>      hw/i386/intel_iommu.c          | 655
>> ++++++++++++++++++++++++++-
>>>> -----
>>>>>> -
>>>>>>>      hw/i386/intel_iommu_internal.h | 114 ++++--
>>>>>>>      include/hw/i386/intel_iommu.h  |   3 +-
>>>>>>>      3 files changed, 609 insertions(+), 163 deletions(-)
>>>>>>>

^ permalink raw reply	[flat|nested] 22+ messages in thread

end of thread, other threads:[~2024-05-14  6:14 UTC | newest]

Thread overview: 22+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2024-04-22 15:52 [PATCH intel_iommu 0/7] FLTS for VT-d CLEMENT MATHIEU--DRIF
2024-04-22 15:52 ` [PATCH intel_iommu 1/7] intel_iommu: fix FRCD construction macro CLEMENT MATHIEU--DRIF
2024-04-22 15:52 ` [PATCH intel_iommu 2/7] intel_iommu: rename slpte to pte before adding FLTS CLEMENT MATHIEU--DRIF
2024-04-22 15:52 ` [PATCH intel_iommu 7/7] intel_iommu: add a CLI option to enable FLTS CLEMENT MATHIEU--DRIF
2024-04-22 15:52 ` [PATCH intel_iommu 3/7] intel_iommu: make types match CLEMENT MATHIEU--DRIF
2024-04-22 17:03   ` Philippe Mathieu-Daudé
2024-04-23  5:05     ` CLEMENT MATHIEU--DRIF
2024-04-23  8:19       ` Philippe Mathieu-Daudé
2024-04-23 15:17         ` CLEMENT MATHIEU--DRIF
2024-04-22 15:52 ` [PATCH intel_iommu 6/7] intel_iommu: add PASID-based IOTLB invalidation CLEMENT MATHIEU--DRIF
2024-04-22 15:52 ` [PATCH intel_iommu 5/7] intel_iommu: extract device IOTLB invalidation logic CLEMENT MATHIEU--DRIF
2024-04-22 16:59   ` Philippe Mathieu-Daudé
2024-04-23  5:07     ` CLEMENT MATHIEU--DRIF
2024-04-22 15:52 ` [PATCH intel_iommu 4/7] intel_iommu: add support for first-stage translation CLEMENT MATHIEU--DRIF
2024-04-30 14:04 ` [PATCH intel_iommu 0/7] FLTS for VT-d Philippe Mathieu-Daudé
2024-04-30 14:13 ` Cédric Le Goater
2024-05-01 12:40   ` Duan, Zhenzhong
2024-05-02  5:03     ` CLEMENT MATHIEU--DRIF
2024-05-06  1:38       ` Duan, Zhenzhong
2024-05-14  5:02         ` CLEMENT MATHIEU--DRIF
2024-05-14  5:50           ` Duan, Zhenzhong
2024-05-14  6:13             ` CLEMENT MATHIEU--DRIF

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.