qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v1 0/8] PRI support for VT-d
@ 2024-05-30 12:24 CLEMENT MATHIEU--DRIF
  2024-05-30 12:25 ` [PATCH v1 1/8] pcie: add a helper to declare the PRI capability for a pcie device CLEMENT MATHIEU--DRIF
                   ` (10 more replies)
  0 siblings, 11 replies; 16+ messages in thread
From: CLEMENT MATHIEU--DRIF @ 2024-05-30 12:24 UTC (permalink / raw)
  To: qemu-devel@nongnu.org
  Cc: jasowang@redhat.com, zhenzhong.duan@intel.com,
	kevin.tian@intel.com, yi.l.liu@intel.com,
	joao.m.martins@oracle.com, peterx@redhat.com,
	CLEMENT MATHIEU--DRIF

This series belongs to a list of series that add SVM support for VT-d.

Here we focus on the implementation of PRI support in the IOMMU and on a PCI-level
API for PRI to be used by virtual devices.

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
        - Device IOTLB invalidations
        - 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 (8):
  pcie: add a helper to declare the PRI capability for a pcie device
  pcie: helper functions to check to check if PRI is enabled
  pcie: add a way to get the outstanding page request allocation (pri)
    from the config space.
  pci: declare structures and IOMMU operation for PRI
  pci: add a PCI-level API for PRI
  intel_iommu: declare PRI constants and structures
  intel_iommu: declare registers for PRI
  intel_iommu: add PRI operations support

 hw/i386/intel_iommu.c          | 302 +++++++++++++++++++++++++++++++++
 hw/i386/intel_iommu_internal.h |  54 +++++-
 hw/pci/pci.c                   |  37 ++++
 hw/pci/pcie.c                  |  42 +++++
 include/exec/memory.h          |  65 +++++++
 include/hw/pci/pci.h           |  45 +++++
 include/hw/pci/pci_bus.h       |   1 +
 include/hw/pci/pcie.h          |   7 +-
 include/hw/pci/pcie_regs.h     |   4 +
 system/memory.c                |  49 ++++++
 10 files changed, 604 insertions(+), 2 deletions(-)

-- 
2.45.1

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

* [PATCH v1 1/8] pcie: add a helper to declare the PRI capability for a pcie device
  2024-05-30 12:24 [PATCH v1 0/8] PRI support for VT-d CLEMENT MATHIEU--DRIF
@ 2024-05-30 12:25 ` CLEMENT MATHIEU--DRIF
  2024-05-30 12:25 ` [PATCH v1 2/8] pcie: helper functions to check to check if PRI is enabled CLEMENT MATHIEU--DRIF
                   ` (9 subsequent siblings)
  10 siblings, 0 replies; 16+ messages in thread
From: CLEMENT MATHIEU--DRIF @ 2024-05-30 12:25 UTC (permalink / raw)
  To: qemu-devel@nongnu.org
  Cc: jasowang@redhat.com, zhenzhong.duan@intel.com,
	kevin.tian@intel.com, yi.l.liu@intel.com,
	joao.m.martins@oracle.com, peterx@redhat.com,
	CLEMENT MATHIEU--DRIF

the pri configuration offset is also stored into the PCIExpressDevice
to make it easier to get the PRI status register

Signed-off-by: Clément Mathieu--Drif <clement.mathieu--drif@eviden.com>
---
 hw/pci/pcie.c              | 25 +++++++++++++++++++++++++
 include/hw/pci/pcie.h      |  5 ++++-
 include/hw/pci/pcie_regs.h |  4 ++++
 3 files changed, 33 insertions(+), 1 deletion(-)

diff --git a/hw/pci/pcie.c b/hw/pci/pcie.c
index 4efd84fed5..053bca6949 100644
--- a/hw/pci/pcie.c
+++ b/hw/pci/pcie.c
@@ -1202,6 +1202,31 @@ void pcie_pasid_init(PCIDevice *dev, uint16_t offset, uint8_t pasid_width,
     dev->exp.pasid_cap = offset;
 }
 
+/* PRI */
+void pcie_pri_init(PCIDevice *dev, uint16_t offset, uint32_t outstanding_pr_cap,
+                   bool prg_response_pasid_req)
+{
+    static const uint16_t control_reg_rw_mask = 0x3;
+    static const uint16_t status_reg_rw1_mask = 0x3;
+    static const uint32_t pr_alloc_reg_rw_mask = 0xffffffff;
+
+    uint16_t status_reg = prg_response_pasid_req ? PCI_PRI_STATUS_PASID : 0;
+    status_reg |= PCI_PRI_STATUS_STOPPED; /* Stopped by default */
+
+    pcie_add_capability(dev, PCI_EXT_CAP_ID_PRI, PCI_PRI_VER, offset,
+                        PCI_EXT_CAP_PRI_SIZEOF);
+    /* Disabled by default */
+
+    pci_set_word(dev->config + offset + PCI_PRI_STATUS, status_reg);
+    pci_set_long(dev->config + offset + PCI_PRI_MAX_REQ, outstanding_pr_cap);
+
+    pci_set_word(dev->wmask + offset + PCI_PRI_CTRL, control_reg_rw_mask);
+    pci_set_word(dev->w1cmask + offset + PCI_PRI_STATUS, status_reg_rw1_mask);
+    pci_set_long(dev->wmask + offset + PCI_PRI_ALLOC_REQ, pr_alloc_reg_rw_mask);
+
+    dev->exp.pri_cap = offset;
+}
+
 bool pcie_pasid_enabled(const PCIDevice *dev)
 {
     if (!pci_is_express(dev) || !dev->exp.pasid_cap) {
diff --git a/include/hw/pci/pcie.h b/include/hw/pci/pcie.h
index 0c127b29dc..198d6da817 100644
--- a/include/hw/pci/pcie.h
+++ b/include/hw/pci/pcie.h
@@ -72,9 +72,10 @@ struct PCIExpressDevice {
     uint16_t aer_cap;
     PCIEAERLog aer_log;
 
-    /* Offset of ATS and PASID capabilities in config space */
+    /* Offset of ATS, PRI and PASID capabilities in config space */
     uint16_t ats_cap;
     uint16_t pasid_cap;
+    uint16_t pri_cap;
 
     /* ACS */
     uint16_t acs_cap;
@@ -154,6 +155,8 @@ void pcie_cap_slot_unplug_request_cb(HotplugHandler *hotplug_dev,
 
 void pcie_pasid_init(PCIDevice *dev, uint16_t offset, uint8_t pasid_width,
                      bool exec_perm, bool priv_mod);
+void pcie_pri_init(PCIDevice *dev, uint16_t offset, uint32_t outstanding_pr_cap,
+                   bool prg_response_pasid_req);
 
 bool pcie_pasid_enabled(const PCIDevice *dev);
 bool pcie_ats_enabled(const PCIDevice *dev);
diff --git a/include/hw/pci/pcie_regs.h b/include/hw/pci/pcie_regs.h
index 0a86598f80..bb8791d1b3 100644
--- a/include/hw/pci/pcie_regs.h
+++ b/include/hw/pci/pcie_regs.h
@@ -89,6 +89,10 @@ typedef enum PCIExpLinkWidth {
 /* PASID */
 #define PCI_PASID_VER                   1
 #define PCI_EXT_CAP_PASID_MAX_WIDTH     20
+
+/* PRI */
+#define PCI_PRI_VER                     1
+
 /* AER */
 #define PCI_ERR_VER                     2
 #define PCI_ERR_SIZEOF                  0x48
-- 
2.45.1

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

* [PATCH v1 2/8] pcie: helper functions to check to check if PRI is enabled
  2024-05-30 12:24 [PATCH v1 0/8] PRI support for VT-d CLEMENT MATHIEU--DRIF
  2024-05-30 12:25 ` [PATCH v1 1/8] pcie: add a helper to declare the PRI capability for a pcie device CLEMENT MATHIEU--DRIF
@ 2024-05-30 12:25 ` CLEMENT MATHIEU--DRIF
  2024-05-30 12:25 ` [PATCH v1 3/8] pcie: add a way to get the outstanding page request allocation (pri) from the config space CLEMENT MATHIEU--DRIF
                   ` (8 subsequent siblings)
  10 siblings, 0 replies; 16+ messages in thread
From: CLEMENT MATHIEU--DRIF @ 2024-05-30 12:25 UTC (permalink / raw)
  To: qemu-devel@nongnu.org
  Cc: jasowang@redhat.com, zhenzhong.duan@intel.com,
	kevin.tian@intel.com, yi.l.liu@intel.com,
	joao.m.martins@oracle.com, peterx@redhat.com,
	CLEMENT MATHIEU--DRIF

pri_enabled can be used to check whether the capability is present and
enabled on a PCIe device

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

diff --git a/hw/pci/pcie.c b/hw/pci/pcie.c
index 053bca6949..3fb6588c31 100644
--- a/hw/pci/pcie.c
+++ b/hw/pci/pcie.c
@@ -1227,6 +1227,15 @@ void pcie_pri_init(PCIDevice *dev, uint16_t offset, uint32_t outstanding_pr_cap,
     dev->exp.pri_cap = offset;
 }
 
+bool pcie_pri_enabled(const PCIDevice *dev)
+{
+    if (!pci_is_express(dev) || !dev->exp.pri_cap) {
+        return false;
+    }
+    return (pci_get_word(dev->config + dev->exp.pri_cap + PCI_PRI_CTRL) &
+                PCI_PRI_CTRL_ENABLE) != 0;
+}
+
 bool pcie_pasid_enabled(const PCIDevice *dev)
 {
     if (!pci_is_express(dev) || !dev->exp.pasid_cap) {
diff --git a/include/hw/pci/pcie.h b/include/hw/pci/pcie.h
index 198d6da817..b976fd739a 100644
--- a/include/hw/pci/pcie.h
+++ b/include/hw/pci/pcie.h
@@ -158,6 +158,7 @@ void pcie_pasid_init(PCIDevice *dev, uint16_t offset, uint8_t pasid_width,
 void pcie_pri_init(PCIDevice *dev, uint16_t offset, uint32_t outstanding_pr_cap,
                    bool prg_response_pasid_req);
 
+bool pcie_pri_enabled(const PCIDevice *dev);
 bool pcie_pasid_enabled(const PCIDevice *dev);
 bool pcie_ats_enabled(const PCIDevice *dev);
 #endif /* QEMU_PCIE_H */
-- 
2.45.1

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

* [PATCH v1 3/8] pcie: add a way to get the outstanding page request allocation (pri) from the config space.
  2024-05-30 12:24 [PATCH v1 0/8] PRI support for VT-d CLEMENT MATHIEU--DRIF
  2024-05-30 12:25 ` [PATCH v1 1/8] pcie: add a helper to declare the PRI capability for a pcie device CLEMENT MATHIEU--DRIF
  2024-05-30 12:25 ` [PATCH v1 2/8] pcie: helper functions to check to check if PRI is enabled CLEMENT MATHIEU--DRIF
@ 2024-05-30 12:25 ` CLEMENT MATHIEU--DRIF
  2024-05-30 12:25 ` [PATCH v1 4/8] pci: declare structures and IOMMU operation for PRI CLEMENT MATHIEU--DRIF
                   ` (7 subsequent siblings)
  10 siblings, 0 replies; 16+ messages in thread
From: CLEMENT MATHIEU--DRIF @ 2024-05-30 12:25 UTC (permalink / raw)
  To: qemu-devel@nongnu.org
  Cc: jasowang@redhat.com, zhenzhong.duan@intel.com,
	kevin.tian@intel.com, yi.l.liu@intel.com,
	joao.m.martins@oracle.com, peterx@redhat.com,
	CLEMENT MATHIEU--DRIF

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

diff --git a/hw/pci/pcie.c b/hw/pci/pcie.c
index 3fb6588c31..d11b11fc34 100644
--- a/hw/pci/pcie.c
+++ b/hw/pci/pcie.c
@@ -1227,6 +1227,14 @@ void pcie_pri_init(PCIDevice *dev, uint16_t offset, uint32_t outstanding_pr_cap,
     dev->exp.pri_cap = offset;
 }
 
+uint32_t pcie_pri_get_req_alloc(const PCIDevice *dev)
+{
+    if (!pcie_pri_enabled(dev)) {
+        return 0;
+    }
+    return pci_get_long(dev->config + dev->exp.pri_cap + PCI_PRI_ALLOC_REQ);
+}
+
 bool pcie_pri_enabled(const PCIDevice *dev)
 {
     if (!pci_is_express(dev) || !dev->exp.pri_cap) {
diff --git a/include/hw/pci/pcie.h b/include/hw/pci/pcie.h
index b976fd739a..7eb448148b 100644
--- a/include/hw/pci/pcie.h
+++ b/include/hw/pci/pcie.h
@@ -158,6 +158,7 @@ void pcie_pasid_init(PCIDevice *dev, uint16_t offset, uint8_t pasid_width,
 void pcie_pri_init(PCIDevice *dev, uint16_t offset, uint32_t outstanding_pr_cap,
                    bool prg_response_pasid_req);
 
+uint32_t pcie_pri_get_req_alloc(const PCIDevice *dev);
 bool pcie_pri_enabled(const PCIDevice *dev);
 bool pcie_pasid_enabled(const PCIDevice *dev);
 bool pcie_ats_enabled(const PCIDevice *dev);
-- 
2.45.1

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

* [PATCH v1 4/8] pci: declare structures and IOMMU operation for PRI
  2024-05-30 12:24 [PATCH v1 0/8] PRI support for VT-d CLEMENT MATHIEU--DRIF
                   ` (2 preceding siblings ...)
  2024-05-30 12:25 ` [PATCH v1 3/8] pcie: add a way to get the outstanding page request allocation (pri) from the config space CLEMENT MATHIEU--DRIF
@ 2024-05-30 12:25 ` CLEMENT MATHIEU--DRIF
  2024-05-30 12:25 ` [PATCH v1 6/8] intel_iommu: declare PRI constants and structures CLEMENT MATHIEU--DRIF
                   ` (6 subsequent siblings)
  10 siblings, 0 replies; 16+ messages in thread
From: CLEMENT MATHIEU--DRIF @ 2024-05-30 12:25 UTC (permalink / raw)
  To: qemu-devel@nongnu.org
  Cc: jasowang@redhat.com, zhenzhong.duan@intel.com,
	kevin.tian@intel.com, yi.l.liu@intel.com,
	joao.m.martins@oracle.com, peterx@redhat.com,
	CLEMENT MATHIEU--DRIF

The API deliberately designed to be similar to the ATS one.
We define a struct that stores a function pointer to the device's callback.
Registering and unregistering a notifier is done using a pair of functions
that will be added in a future commit of this series.

An IOMMU can support PRI by implementing the iommu_pri_request_page
operation declared in IOMMUMemoryRegionClass.

Signed-off-by: Clément Mathieu--Drif <clement.mathieu--drif@eviden.com>
---
 include/exec/memory.h    | 30 ++++++++++++++++++++++++++++++
 include/hw/pci/pci_bus.h |  1 +
 2 files changed, 31 insertions(+)

diff --git a/include/exec/memory.h b/include/exec/memory.h
index 0ced7c33b1..f4780d3920 100644
--- a/include/exec/memory.h
+++ b/include/exec/memory.h
@@ -218,6 +218,25 @@ typedef struct IOMMUTLBEvent {
     IOMMUTLBEntry entry;
 } IOMMUTLBEvent;
 
+/* Page Request Interface */
+#define IOMMU_PRI_RESP_CODE_SUCCESS(val)            (!(val))
+#define IOMMU_PRI_RESP_CODE_INVALID_REQUEST(val)    ((val) == 0x1u)
+#define IOMMU_PRI_RESP_CODE_FAILURE(val)            ((val) & 0xeu)
+
+typedef struct IOMMUPRIResponse {
+    uint8_t response_code;
+    uint16_t prgi;
+} IOMMUPRIResponse;
+
+struct IOMMUPRINotifier;
+
+typedef void (*IOMMUPRINotify)(struct IOMMUPRINotifier *notifier,
+                               IOMMUPRIResponse *response);
+
+typedef struct IOMMUPRINotifier {
+    IOMMUPRINotify notify;
+} IOMMUPRINotifier;
+
 /* RAM is pre-allocated and passed into qemu_ram_alloc_from_ptr */
 #define RAM_PREALLOC   (1 << 0)
 
@@ -589,6 +608,16 @@ struct IOMMUMemoryRegionClass {
                                              IOMMUTLBEntry *result,
                                              size_t result_length,
                                              uint32_t *err_count);
+
+    /**
+     * @iommu_pri_request_page:
+     * This method must be implemented if the IOMMU has PRI enabled
+     *
+     * @see pci_pri_request_page_pasid
+     */
+    int (*iommu_pri_request_page)(IOMMUMemoryRegion *iommu, hwaddr addr,
+                                  bool lpig, uint16_t prgi, bool is_read,
+                                  bool is_write, bool exec_req, bool priv_req);
 };
 
 typedef struct RamDiscardListener RamDiscardListener;
@@ -878,6 +907,7 @@ struct IOMMUMemoryRegion {
 
     QLIST_HEAD(, IOMMUNotifier) iommu_notify;
     IOMMUNotifierFlag iommu_notify_flags;
+    IOMMUPRINotifier *pri_notifier;
 };
 
 #define IOMMU_NOTIFIER_FOREACH(n, mr) \
diff --git a/include/hw/pci/pci_bus.h b/include/hw/pci/pci_bus.h
index 2261312546..eaa777fde4 100644
--- a/include/hw/pci/pci_bus.h
+++ b/include/hw/pci/pci_bus.h
@@ -29,6 +29,7 @@ enum PCIBusFlags {
 };
 
 #define PCI_NO_PASID UINT32_MAX
+#define PCI_PRI_PRGI_MASK 0x1ffU
 
 struct PCIBus {
     BusState qbus;
-- 
2.45.1

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

* [PATCH v1 6/8] intel_iommu: declare PRI constants and structures
  2024-05-30 12:24 [PATCH v1 0/8] PRI support for VT-d CLEMENT MATHIEU--DRIF
                   ` (3 preceding siblings ...)
  2024-05-30 12:25 ` [PATCH v1 4/8] pci: declare structures and IOMMU operation for PRI CLEMENT MATHIEU--DRIF
@ 2024-05-30 12:25 ` CLEMENT MATHIEU--DRIF
  2024-05-30 12:25 ` [PATCH v1 5/8] pci: add a PCI-level API for PRI CLEMENT MATHIEU--DRIF
                   ` (5 subsequent siblings)
  10 siblings, 0 replies; 16+ messages in thread
From: CLEMENT MATHIEU--DRIF @ 2024-05-30 12:25 UTC (permalink / raw)
  To: qemu-devel@nongnu.org
  Cc: jasowang@redhat.com, zhenzhong.duan@intel.com,
	kevin.tian@intel.com, yi.l.liu@intel.com,
	joao.m.martins@oracle.com, peterx@redhat.com,
	CLEMENT MATHIEU--DRIF

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

diff --git a/hw/i386/intel_iommu_internal.h b/hw/i386/intel_iommu_internal.h
index 461158f588..9e01251335 100644
--- a/hw/i386/intel_iommu_internal.h
+++ b/hw/i386/intel_iommu_internal.h
@@ -191,6 +191,7 @@
 #define VTD_ECAP_EIM                (1ULL << 4)
 #define VTD_ECAP_PT                 (1ULL << 6)
 #define VTD_ECAP_SC                 (1ULL << 7)
+#define VTD_ECAP_PRS                (1ULL << 29)
 #define VTD_ECAP_MHMV               (15ULL << 20)
 #define VTD_ECAP_NEST               (1ULL << 26)
 #define VTD_ECAP_SRS                (1ULL << 31)
@@ -373,6 +374,18 @@ union VTDInvDesc {
 };
 typedef union VTDInvDesc VTDInvDesc;
 
+/* Page Request Descriptor */
+union VTDPRDesc {
+    struct {
+        uint64_t lo;
+        uint64_t hi;
+    };
+    struct {
+        uint64_t val[4];
+    };
+};
+typedef union VTDPRDesc VTDPRDesc;
+
 /* Masks for struct VTDInvDesc */
 #define VTD_INV_DESC_TYPE               0xf
 #define VTD_INV_DESC_CC                 0x1 /* Context-cache Invalidate Desc */
@@ -384,6 +397,7 @@ typedef union VTDInvDesc VTDInvDesc;
 #define VTD_INV_DESC_PIOTLB             0x6 /* PASID-IOTLB Invalidate Desc */
 #define VTD_INV_DESC_PC                 0x7 /* PASID-cache Invalidate Desc */
 #define VTD_INV_DESC_DEV_PIOTLB         0x8 /* PASID-based-DIOTLB inv_desc*/
+#define VTD_INV_DESC_PGRESP             0x9 /* Page Group Response Desc */
 #define VTD_INV_DESC_NONE               0   /* Not an Invalidate Descriptor */
 
 /* Masks for Invalidation Wait Descriptor*/
@@ -425,7 +439,16 @@ typedef union VTDInvDesc VTDInvDesc;
 #define VTD_INV_DESC_DEVICE_IOTLB_SIZE(val) ((val) & 0x1)
 #define VTD_INV_DESC_DEVICE_IOTLB_SID(val) (((val) >> 32) & 0xFFFFULL)
 #define VTD_INV_DESC_DEVICE_IOTLB_RSVD_HI 0xffeULL
-#define VTD_INV_DESC_DEVICE_IOTLB_RSVD_LO 0xffff0000ffe0fff8
+#define VTD_INV_DESC_DEVICE_IOTLB_RSVD_LO 0xffff0000ffe0fff8ULL
+
+/* Mask for Page Group Response Descriptor */
+#define VTD_INV_DESC_PGRESP_RSVD_HI             0xfffffffffffff003ULL
+#define VTD_INV_DESC_PGRESP_RSVD_LO             0xfff0000000000fe0ULL
+#define VTD_INV_DESC_PGRESP_PP(val)             ((val >> 4) & 0x1ULL)
+#define VTD_INV_DESC_PGRESP_RC(val)             ((val >> 12) & 0xfULL)
+#define VTD_INV_DESC_PGRESP_RID(val)            ((val >> 16) & 0xffffULL)
+#define VTD_INV_DESC_PGRESP_PASID(val)          ((val >> 32) & 0xfffffULL)
+#define VTD_INV_DESC_PGRESP_PRGI(val)           ((val >> 3) & 0x1ffULL)
 
 /* Mask for PASID Device IOTLB Invalidate Descriptor */
 #define VTD_INV_DESC_PASID_DEVICE_IOTLB_ADDR(val) ((val) & \
@@ -545,6 +568,7 @@ typedef struct VTDRootEntry VTDRootEntry;
 #define VTD_SM_CONTEXT_ENTRY_RID2PASID_MASK 0xfffff
 #define VTD_SM_CONTEXT_ENTRY_RSVD_VAL0(aw)  (0x1e0ULL | ~VTD_HAW_MASK(aw))
 #define VTD_SM_CONTEXT_ENTRY_RSVD_VAL1      0xffffffffffe00000ULL
+#define VTD_SM_CONTEXT_ENTRY_PRE            0x10ULL
 
 typedef struct VTDPASIDCacheEntry {
     struct VTDPASIDEntry pasid_entry;
@@ -700,4 +724,30 @@ typedef struct VTDHostIOMMUDevice {
     uint32_t errata;
     QLIST_ENTRY(VTDHostIOMMUDevice) next;
 } VTDHostIOMMUDevice;
+
+/* Page Request Descriptor */
+/* For the low 64-bit of 128-bit */
+#define VTD_PRD_TYPE            (1ULL)
+#define VTD_PRD_PP(val)         ((val & 1ULL) << 8)
+#define VTD_PRD_RID(val)        ((val & 0xffffULL) << 16)
+#define VTD_PRD_PASID(val)      ((val & 0xfffffULL) << 32)
+#define VTD_PRD_EXR(val)        ((val & 1ULL) << 52)
+#define VTD_PRD_PMR(val)        ((val & 1ULL) << 53)
+/* For the high 64-bit of 128-bit */
+#define VTD_PRD_RDR(val)        (val & 1ULL)
+#define VTD_PRD_WRR(val)        ((val & 1ULL) << 1)
+#define VTD_PRD_LPIG(val)       ((val & 1ULL) << 2)
+#define VTD_PRD_PRGI(val)       ((val & 0x1ffULL) << 3)
+#define VTD_PRD_ADDR(val)       (val & 0xfffffffffffff000ULL)
+
+/* Page Request Queue constants */
+#define VTD_PQA_ENTRY_SIZE      32 /* Size of an entry in bytes */
+/* Page Request Queue masks */
+#define VTD_PQA_ADDR            0xfffffffffffff000ULL /* PR queue address */
+#define VTD_PQA_SIZE            0x7ULL /* PR queue size */
+#define VTD_PR_STATUS_PPR       1UL /* Pending page request */
+#define VTD_PR_STATUS_PRO       2UL /* Page request overflow */
+#define VTD_PR_PECTL_IP         0X40000000UL /* PR control interrup pending */
+#define VTD_PR_PECTL_IM         0X80000000UL /* PR control interrup mask */
+
 #endif
-- 
2.45.1

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

* [PATCH v1 5/8] pci: add a PCI-level API for PRI
  2024-05-30 12:24 [PATCH v1 0/8] PRI support for VT-d CLEMENT MATHIEU--DRIF
                   ` (4 preceding siblings ...)
  2024-05-30 12:25 ` [PATCH v1 6/8] intel_iommu: declare PRI constants and structures CLEMENT MATHIEU--DRIF
@ 2024-05-30 12:25 ` CLEMENT MATHIEU--DRIF
  2024-05-30 12:25 ` [PATCH v1 7/8] intel_iommu: declare registers " CLEMENT MATHIEU--DRIF
                   ` (4 subsequent siblings)
  10 siblings, 0 replies; 16+ messages in thread
From: CLEMENT MATHIEU--DRIF @ 2024-05-30 12:25 UTC (permalink / raw)
  To: qemu-devel@nongnu.org
  Cc: jasowang@redhat.com, zhenzhong.duan@intel.com,
	kevin.tian@intel.com, yi.l.liu@intel.com,
	joao.m.martins@oracle.com, peterx@redhat.com,
	CLEMENT MATHIEU--DRIF

A device can send a PRI request to the IOMMU using pci_pri_request_page_pasid.
The PRI response is sent back using the notifier managed with
pci_pri_register_notifier and pci_pri_unregister_notifier.

Signed-off-by: Clément Mathieu--Drif <clement.mathieu--drif@eviden.com>
---
 hw/pci/pci.c          | 37 ++++++++++++++++++++++++++++++++
 include/exec/memory.h | 35 +++++++++++++++++++++++++++++++
 include/hw/pci/pci.h  | 45 +++++++++++++++++++++++++++++++++++++++
 system/memory.c       | 49 +++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 166 insertions(+)

diff --git a/hw/pci/pci.c b/hw/pci/pci.c
index 10b0708130..dd854fc18f 100644
--- a/hw/pci/pci.c
+++ b/hw/pci/pci.c
@@ -2833,6 +2833,43 @@ void pci_device_unset_iommu_device(PCIDevice *dev)
     }
 }
 
+int pci_pri_request_page_pasid(PCIDevice *dev, uint32_t pasid, bool priv_req,
+                               bool exec_req, hwaddr addr, bool lpig,
+                               uint16_t prgi, bool is_read, bool is_write)
+{
+    IOMMUMemoryRegion *iommu_mr = pci_device_iommu_memory_region_pasid(dev,
+                                                                        pasid);
+    if (!iommu_mr || !pcie_pri_enabled(dev)) {
+        return -EPERM;
+    }
+    return memory_region_iommu_pri_request_page(iommu_mr, priv_req, exec_req,
+                                                addr, lpig, prgi, is_read,
+                                                is_write);
+}
+
+int pci_pri_register_notifier(PCIDevice *dev, uint32_t pasid,
+                              IOMMUPRINotifier *notifier)
+{
+    IOMMUMemoryRegion *iommu_mr = pci_device_iommu_memory_region_pasid(dev,
+                                                                        pasid);
+    if (!iommu_mr || !pcie_pri_enabled(dev)) {
+        return -EPERM;
+    }
+    return memory_region_register_iommu_pri_notifier(MEMORY_REGION(iommu_mr),
+                                                     notifier);
+}
+
+int pci_pri_unregister_notifier(PCIDevice *dev, uint32_t pasid)
+{
+    IOMMUMemoryRegion *iommu_mr = pci_device_iommu_memory_region_pasid(dev,
+                                                                        pasid);
+    if (!iommu_mr || !pcie_pri_enabled(dev)) {
+        return -EPERM;
+    }
+    memory_region_unregister_iommu_pri_notifier(MEMORY_REGION(iommu_mr));
+    return 0;
+}
+
 ssize_t pci_ats_request_translation_pasid(PCIDevice *dev, uint32_t pasid,
                                           bool priv_req, bool exec_req, hwaddr addr,
                                           size_t length, bool no_write,
diff --git a/include/exec/memory.h b/include/exec/memory.h
index f4780d3920..71bdd7e64d 100644
--- a/include/exec/memory.h
+++ b/include/exec/memory.h
@@ -1870,6 +1870,16 @@ void memory_region_notify_iommu(IOMMUMemoryRegion *iommu_mr,
                                 int iommu_idx,
                                 IOMMUTLBEvent event);
 
+/**
+ * Notify the device attached to a memory region by calling the PRI
+ * callback (if exists)
+ *
+ * @iommu_mr: the region in which the PRI request has been performed
+ * @response: the response to be forwarded to the device
+ */
+void memory_region_notify_pri_iommu(IOMMUMemoryRegion *iommu_mr,
+                                    IOMMUPRIResponse *response);
+
 /**
  * memory_region_notify_iommu_one: notify a change in an IOMMU translation
  *                           entry to a single notifier
@@ -1944,6 +1954,31 @@ ssize_t memory_region_iommu_ats_request_translation(IOMMUMemoryRegion *iommu_mr,
                                                 size_t result_length,
                                                 uint32_t *err_count);
 
+/**
+ * Register a PRI callback in an IOMMU memory region
+ *
+ * Return 0 if the notifier has been installed,
+ * error code otherwise.
+ * An error occurs when the region already has a
+ * callback configured.
+ *
+ * @mr: the target iommu memory region
+ * @n: the notifier to be installed
+ */
+int memory_region_register_iommu_pri_notifier(MemoryRegion *mr,
+                                              IOMMUPRINotifier *n);
+
+/**
+ * Unregister a PRI callback from an IOMMU memory region
+ *
+ * @mr: the target iommu memory region
+ */
+void memory_region_unregister_iommu_pri_notifier(MemoryRegion *mr);
+
+int memory_region_iommu_pri_request_page(IOMMUMemoryRegion *iommu_mr,
+                                         bool priv_req, bool exec_req,
+                                         hwaddr addr, bool lpig, uint16_t prgi,
+                                         bool is_read, bool is_write);
 /**
  * memory_region_iommu_get_attr: return an IOMMU attr if get_attr() is
  * defined on the IOMMU.
diff --git a/include/hw/pci/pci.h b/include/hw/pci/pci.h
index 8adba6af97..76a6031d8d 100644
--- a/include/hw/pci/pci.h
+++ b/include/hw/pci/pci.h
@@ -473,6 +473,51 @@ bool pci_iommu_init_iotlb_notifier(PCIDevice *dev, uint32_t pasid,
                                    IOMMUNotifier *n, IOMMUNotify fn,
                                    void* opaque);
 
+/**
+ * Perform a PRI request
+ *
+ * This function is intended to be used by PCIe devices using SVM
+ *
+ * Return 0 if the PRI request has been sent to the guest OS,
+ * an error code otherwise
+ *
+ * @dev: the PRI capable PCI device
+ * @pasid: the pasid of the address space in which the translation will be made
+ * @priv_req: privileged mode bit (PASID TLP)
+ * @exec_req: execute request bit (PASID TLP)
+ * @addr: untranslated address of the requested page
+ * @lpig: last page in group
+ * @prgi: page request group index
+ * @is_read: request read access
+ * @is_write: request write access
+ */
+int pci_pri_request_page_pasid(PCIDevice *dev, uint32_t pasid, bool priv_req,
+                               bool exec_req, hwaddr addr, bool lpig,
+                               uint16_t prgi, bool is_read, bool is_write);
+
+/**
+ * Register a PRI callback for a given address space
+ *
+ * Return 0 on success, an error code otherwise
+ *
+ * @dev: the PRI-capable PCI device
+ * @pasid: the pasid of the address space to install the callback in
+ * @notifier: the notifier to register
+ */
+int pci_pri_register_notifier(PCIDevice *dev, uint32_t pasid,
+                              IOMMUPRINotifier *notifier);
+
+/**
+ * Unregister a PRI callback from a given address space identified
+ * by a pasid.
+ *
+ * Return 0 if the callback has been unregistered, an error code otherwise
+ *
+ * @dev: the PRI-capable PCI device
+ * @pasid: the pasid of the address space to remove the callback from
+ */
+int pci_pri_unregister_notifier(PCIDevice *dev, uint32_t pasid);
+
 /**
  * pci_ats_request_translation_pasid: perform an ATS request
  *
diff --git a/system/memory.c b/system/memory.c
index d9d66ae2e1..105c02b686 100644
--- a/system/memory.c
+++ b/system/memory.c
@@ -1765,6 +1765,7 @@ void memory_region_init_iommu(void *_iommu_mr,
     mr->terminates = true;  /* then re-forwards */
     QLIST_INIT(&iommu_mr->iommu_notify);
     iommu_mr->iommu_notify_flags = IOMMU_NOTIFIER_NONE;
+    iommu_mr->pri_notifier = NULL;
 }
 
 static void memory_region_finalize(Object *obj)
@@ -2025,6 +2026,45 @@ ssize_t memory_region_iommu_ats_request_translation(IOMMUMemoryRegion *iommu_mr,
                                                result_length, err_count);
 }
 
+int memory_region_register_iommu_pri_notifier(MemoryRegion *mr,
+                                               IOMMUPRINotifier *n)
+{
+    IOMMUMemoryRegion *iommu_mr;
+    if (mr->alias) {
+        return memory_region_register_iommu_pri_notifier(mr->alias, n);
+    }
+    iommu_mr = IOMMU_MEMORY_REGION(mr);
+    if (iommu_mr->pri_notifier) {
+        return -EBUSY;
+    }
+    iommu_mr->pri_notifier = n;
+    return 0;
+}
+
+void memory_region_unregister_iommu_pri_notifier(MemoryRegion *mr)
+{
+    IOMMUMemoryRegion *iommu_mr;
+    if (mr->alias) {
+        memory_region_unregister_iommu_pri_notifier(mr->alias);
+        return;
+    }
+    iommu_mr = IOMMU_MEMORY_REGION(mr);
+    iommu_mr->pri_notifier = NULL;
+}
+
+int memory_region_iommu_pri_request_page(IOMMUMemoryRegion *iommu_mr,
+                                         bool priv_req, bool exec_req,
+                                         hwaddr addr, bool lpig, uint16_t prgi,
+                                         bool is_read, bool is_write)
+{
+    IOMMUMemoryRegionClass *imrc = memory_region_get_iommu_class_nocheck(iommu_mr);
+    if (!imrc->iommu_pri_request_page) {
+        return -ENODEV;
+    }
+    return imrc->iommu_pri_request_page(iommu_mr, addr, lpig, prgi, is_read,
+                                        is_write, exec_req, priv_req);
+}
+
 void memory_region_notify_iommu_one(IOMMUNotifier *notifier,
                                     IOMMUTLBEvent *event)
 {
@@ -2085,6 +2125,15 @@ void memory_region_notify_iommu(IOMMUMemoryRegion *iommu_mr,
     }
 }
 
+void memory_region_notify_pri_iommu(IOMMUMemoryRegion *iommu_mr,
+                                    IOMMUPRIResponse *response)
+{
+    assert(memory_region_is_iommu(MEMORY_REGION(iommu_mr)));
+    if (iommu_mr->pri_notifier) {
+        iommu_mr->pri_notifier->notify(iommu_mr->pri_notifier, response);
+    }
+}
+
 int memory_region_iommu_get_attr(IOMMUMemoryRegion *iommu_mr,
                                  enum IOMMUMemoryRegionAttr attr,
                                  void *data)
-- 
2.45.1

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

* [PATCH v1 7/8] intel_iommu: declare registers for PRI
  2024-05-30 12:24 [PATCH v1 0/8] PRI support for VT-d CLEMENT MATHIEU--DRIF
                   ` (5 preceding siblings ...)
  2024-05-30 12:25 ` [PATCH v1 5/8] pci: add a PCI-level API for PRI CLEMENT MATHIEU--DRIF
@ 2024-05-30 12:25 ` CLEMENT MATHIEU--DRIF
  2024-05-30 12:25 ` [PATCH v1 8/8] intel_iommu: add PRI operations support CLEMENT MATHIEU--DRIF
                   ` (3 subsequent siblings)
  10 siblings, 0 replies; 16+ messages in thread
From: CLEMENT MATHIEU--DRIF @ 2024-05-30 12:25 UTC (permalink / raw)
  To: qemu-devel@nongnu.org
  Cc: jasowang@redhat.com, zhenzhong.duan@intel.com,
	kevin.tian@intel.com, yi.l.liu@intel.com,
	joao.m.martins@oracle.com, peterx@redhat.com,
	CLEMENT MATHIEU--DRIF

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

diff --git a/hw/i386/intel_iommu.c b/hw/i386/intel_iommu.c
index 2e78ebe6d2..899655928d 100644
--- a/hw/i386/intel_iommu.c
+++ b/hw/i386/intel_iommu.c
@@ -4609,6 +4609,27 @@ static void vtd_handle_iectl_write(IntelIOMMUState *s)
     }
 }
 
+static void vtd_handle_prs_write(IntelIOMMUState *s)
+{
+    uint32_t prs = vtd_get_long_raw(s, DMAR_PRS_REG);
+    if (!(prs & VTD_PR_STATUS_PPR) && !(prs & VTD_PR_STATUS_PRO)) {
+        vtd_set_clear_mask_long(s, DMAR_PECTL_REG, VTD_PR_PECTL_IP, 0);
+    }
+}
+
+static void vtd_handle_pectl_write(IntelIOMMUState *s)
+{
+    uint32_t pectl = vtd_get_long_raw(s, DMAR_PECTL_REG);
+    if ((pectl & VTD_PR_PECTL_IP) && !(pectl & VTD_PR_PECTL_IM)) {
+        /*
+         * If IP field was 1 when software clears the IM field,
+         * the  interrupt is generated along with clearing the IP field.
+         */
+        vtd_set_clear_mask_long(s, DMAR_PECTL_REG, VTD_PR_PECTL_IP, 0);
+        vtd_generate_interrupt(s, DMAR_PEADDR_REG, DMAR_PEDATA_REG);
+    }
+}
+
 static uint64_t vtd_mem_read(void *opaque, hwaddr addr, unsigned size)
 {
     IntelIOMMUState *s = opaque;
@@ -4649,6 +4670,17 @@ static uint64_t vtd_mem_read(void *opaque, hwaddr addr, unsigned size)
         val = s->iq >> 32;
         break;
 
+    /* Page Request Event Address Register */
+    case DMAR_PEADDR_REG:
+        assert(size == 4);
+        val = vtd_get_long_raw(s, DMAR_PEADDR_REG);
+        break;
+
+    case DMAR_PEUADDR_REG:
+        assert(size == 4);
+        val = vtd_get_long_raw(s, DMAR_PEUADDR_REG);
+        break;
+
     default:
         if (size == 4) {
             val = vtd_get_long(s, addr);
@@ -4712,6 +4744,17 @@ static void vtd_mem_write(void *opaque, hwaddr addr,
         vtd_handle_iotlb_write(s);
         break;
 
+    /* Page Request Event Address Register */
+    case DMAR_PEADDR_REG:
+        assert(size == 4);
+        vtd_set_long(s, addr, val);
+        break;
+
+    case DMAR_PEUADDR_REG:
+        assert(size == 4);
+        vtd_set_long(s, addr, val);
+        break;
+
     /* Invalidate Address Register, 64-bit */
     case DMAR_IVA_REG:
         if (size == 4) {
@@ -4892,6 +4935,18 @@ static void vtd_mem_write(void *opaque, hwaddr addr,
         vtd_set_long(s, addr, val);
         break;
 
+    case DMAR_PRS_REG:
+        assert(size == 4);
+        vtd_set_long(s, addr, val);
+        vtd_handle_prs_write(s);
+        break;
+
+    case DMAR_PECTL_REG:
+        assert(size == 4);
+        vtd_set_long(s, addr, val);
+        vtd_handle_pectl_write(s);
+        break;
+
     default:
         if (size == 4) {
             vtd_set_long(s, addr, val);
@@ -5957,6 +6012,18 @@ static void vtd_init(IntelIOMMUState *s)
      * Interrupt remapping registers.
      */
     vtd_define_quad(s, DMAR_IRTA_REG, 0, 0xfffffffffffff80fULL, 0);
+
+    /* Page request registers */
+    if (s->ecap & VTD_ECAP_PRS) {
+        vtd_define_quad(s, DMAR_PQH_REG, 0, 0x7ffe0ULL, 0);
+        vtd_define_quad(s, DMAR_PQT_REG, 0, 0x7ffe0ULL, 0);
+        vtd_define_quad(s, DMAR_PQA_REG, 0, 0xfffffffffffff007ULL, 0);
+        vtd_define_long(s, DMAR_PRS_REG, 0, 0, 0x3UL);
+        vtd_define_long(s, DMAR_PECTL_REG, 0, 0x80000000UL, 0);
+        vtd_define_long(s, DMAR_PEDATA_REG, 0, 0xffffUL, 0);
+        vtd_define_long(s, DMAR_PEADDR_REG, 0, 0xfffffffcUL, 0);
+        vtd_define_long(s, DMAR_PEUADDR_REG, 0, 0xffffffffUL, 0);
+    }
 }
 
 /* Should not reset address_spaces when reset because devices will still use
-- 
2.45.1

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

* [PATCH v1 8/8] intel_iommu: add PRI operations support
  2024-05-30 12:24 [PATCH v1 0/8] PRI support for VT-d CLEMENT MATHIEU--DRIF
                   ` (6 preceding siblings ...)
  2024-05-30 12:25 ` [PATCH v1 7/8] intel_iommu: declare registers " CLEMENT MATHIEU--DRIF
@ 2024-05-30 12:25 ` CLEMENT MATHIEU--DRIF
  2024-06-06 16:12 ` [PATCH v1 0/8] PRI support for VT-d CLEMENT MATHIEU--DRIF
                   ` (2 subsequent siblings)
  10 siblings, 0 replies; 16+ messages in thread
From: CLEMENT MATHIEU--DRIF @ 2024-05-30 12:25 UTC (permalink / raw)
  To: qemu-devel@nongnu.org
  Cc: jasowang@redhat.com, zhenzhong.duan@intel.com,
	kevin.tian@intel.com, yi.l.liu@intel.com,
	joao.m.martins@oracle.com, peterx@redhat.com,
	CLEMENT MATHIEU--DRIF

Implement the iommu_pri_request_page IOMMU operation
and the behavior when receiving a page group response descriptor

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

diff --git a/hw/i386/intel_iommu.c b/hw/i386/intel_iommu.c
index 899655928d..dcc92aae58 100644
--- a/hw/i386/intel_iommu.c
+++ b/hw/i386/intel_iommu.c
@@ -51,6 +51,8 @@
     ((ce)->val[1] & VTD_SM_CONTEXT_ENTRY_RID2PASID_MASK)
 #define VTD_CE_GET_PASID_DIR_TABLE(ce) \
     ((ce)->val[0] & VTD_PASID_DIR_BASE_ADDR_MASK)
+#define VTD_CE_GET_PRE(ce) \
+    ((ce)->val[0] & VTD_SM_CONTEXT_ENTRY_PRE)
 
 /* pe operations */
 #define VTD_PE_GET_TYPE(pe) ((pe)->val[0] & VTD_SM_PASID_ENTRY_PGTT)
@@ -1922,6 +1924,7 @@ static const bool vtd_qualified_faults[] = {
     [VTD_FR_PASID_ENTRY_P] = true,
     [VTD_FR_PASID_TABLE_ENTRY_INV] = true,
     [VTD_FR_SM_INTERRUPT_ADDR] = true,
+    [VTD_FR_SM_PRE_ABS] = true,
     [VTD_FR_FS_NON_CANONICAL] = true,
     [VTD_FR_FS_BIT_UPDATE_FAILED] = true,
     [VTD_FR_MAX] = false,
@@ -4379,6 +4382,45 @@ static bool vtd_process_device_piotlb_desc(IntelIOMMUState *s,
     return true;
 }
 
+static bool vtd_process_page_group_response_desc(IntelIOMMUState *s,
+                                                 VTDInvDesc *inv_desc)
+{
+    VTDAddressSpace *vtd_dev_as;
+
+    if ((inv_desc->lo & VTD_INV_DESC_PGRESP_RSVD_LO) ||
+        (inv_desc->hi & VTD_INV_DESC_PGRESP_RSVD_HI)) {
+        error_report_once("%s: invalid page group response desc: hi=%"PRIx64
+                            ", lo=%"PRIx64" (reserved nonzero)", __func__,
+                            inv_desc->hi, inv_desc->lo);
+        return false;
+    }
+
+    bool pasid_present = VTD_INV_DESC_PGRESP_PP(inv_desc->lo);
+    uint8_t response_code = VTD_INV_DESC_PGRESP_RC(inv_desc->lo);
+    uint16_t rid = VTD_INV_DESC_PGRESP_RID(inv_desc->lo);
+    uint32_t pasid = VTD_INV_DESC_PGRESP_PASID(inv_desc->lo);
+    uint16_t prgi = VTD_INV_DESC_PGRESP_PRGI(inv_desc->hi);
+
+    if (!pasid_present) {
+        error_report_once("Page group response without PASID is"
+                          "not supported yet");
+        return false;
+    }
+
+    vtd_dev_as = vtd_get_as_by_sid_and_pasid(s, rid, pasid);
+    if (!vtd_dev_as) {
+        return true;
+    }
+
+    IOMMUPRIResponse response = {
+        .prgi = prgi,
+        .response_code = response_code
+    };
+    memory_region_notify_pri_iommu(&vtd_dev_as->iommu, &response);
+
+    return true;
+}
+
 static bool vtd_process_device_iotlb_desc(IntelIOMMUState *s,
                                           VTDInvDesc *inv_desc)
 {
@@ -4486,6 +4528,13 @@ static bool vtd_process_inv_desc(IntelIOMMUState *s)
         }
         break;
 
+    case VTD_INV_DESC_PGRESP:
+        trace_vtd_inv_desc("page group response", inv_desc.hi, inv_desc.lo);
+        if (!vtd_process_page_group_response_desc(s, &inv_desc)) {
+            return false;
+        }
+        break;
+
     default:
         error_report_once("%s: invalid inv desc: hi=%"PRIx64", lo=%"PRIx64
                           " (unknown type)", __func__, inv_desc.hi,
@@ -6138,6 +6187,191 @@ static uint64_t vtd_get_min_page_size(IOMMUMemoryRegion *iommu)
     return VTD_PAGE_SIZE;
 }
 
+/* 11.4.11.3 : The number of entries in the page request queue is 2^(PQS + 7) */
+static inline uint64_t vtd_prq_size(IntelIOMMUState *s)
+{
+    return 1ULL << ((vtd_get_quad(s, DMAR_PQA_REG) & VTD_PQA_SIZE) + 7);
+}
+
+/**
+ * Return true if the bit is accessible and correctly set, false otherwise
+ */
+static bool vtd_check_pre_bit(VTDAddressSpace *vtd_as, hwaddr addr,
+                              uint16_t sid, bool is_write)
+{
+    int ret;
+    IntelIOMMUState *s = vtd_as->iommu_state;
+    uint8_t bus_n = pci_bus_num(vtd_as->bus);
+    VTDContextEntry ce;
+    bool is_fpd_set = false;
+
+    ret = vtd_dev_to_context_entry(s, bus_n, vtd_as->devfn, &ce);
+
+    if (ret) {
+        goto error_report;
+    }
+
+    if (!VTD_CE_GET_PRE(&ce)) {
+        ret = -VTD_FR_SM_PRE_ABS;
+        goto error_get_fpd_and_report;
+    }
+
+    return true;
+
+error_get_fpd_and_report:
+    /* Try to get fpd (may not work but we are already on an error path) */
+    is_fpd_set = ce.lo & VTD_CONTEXT_ENTRY_FPD;
+    vtd_ce_get_pasid_fpd(s, &ce, &is_fpd_set, vtd_as->pasid);
+error_report:
+    vtd_report_fault(s, -ret, is_fpd_set, sid, addr, is_write,
+                     vtd_as->pasid != PCI_NO_PASID, vtd_as->pasid);
+    return false;
+}
+
+/* Logic described in section 7.5 */
+static void vtd_generate_page_request_event(IntelIOMMUState *s,
+                                            uint32_t old_pr_status)
+{
+    uint32_t current_pectl = vtd_get_long(s, DMAR_PECTL_REG);
+    /*
+     * Hardware evaluates PPR and PRO fields in the Page Request Status Register
+     * and if any of them is set, Page Request Event is not generated
+     */
+    if (old_pr_status & (VTD_PR_STATUS_PRO | VTD_PR_STATUS_PPR)) {
+        return;
+    }
+
+    vtd_set_clear_mask_long(s, DMAR_PECTL_REG, 0, VTD_PR_PECTL_IP);
+    if (!(current_pectl & VTD_PR_PECTL_IM)) {
+        vtd_set_clear_mask_long(s, DMAR_PECTL_REG, VTD_PR_PECTL_IP, 0);
+        vtd_generate_interrupt(s, DMAR_PEADDR_REG, DMAR_PEDATA_REG);
+    }
+}
+
+/* When calling this function, we known that we are in scalable mode */
+static int vtd_pri_perform_implicit_invalidation(VTDAddressSpace *vtd_as,
+                                                 hwaddr addr)
+{
+    IntelIOMMUState *s = vtd_as->iommu_state;
+    VTDContextEntry ce;
+    VTDPASIDEntry pe;
+    uint16_t pgtt;
+    uint16_t domain_id;
+    int ret = vtd_dev_to_context_entry(s, pci_bus_num(vtd_as->bus),
+                                       vtd_as->devfn, &ce);
+    if (ret) {
+        return -EINVAL;
+    }
+    ret = vtd_ce_get_rid2pasid_entry(s, &ce, &pe, vtd_as->pasid);
+    if (ret) {
+        return -EINVAL;
+    }
+    pgtt = VTD_PE_GET_TYPE(&pe);
+    domain_id = VTD_SM_PASID_ENTRY_DID(pe.val[1]);
+    ret = 0;
+    switch (pgtt) {
+    case VTD_SM_PASID_ENTRY_FLT:
+        vtd_piotlb_page_invalidate(s, domain_id, vtd_as->pasid, addr, 0, false);
+        break;
+    /* Room for other pgtt values */
+    default:
+        error_report_once("Translation type not supported yet : %d", pgtt);
+        ret = -EINVAL;
+        break;
+    }
+
+    return ret;
+}
+
+/* Page Request Descriptor : 7.4.1.1 */
+static int vtd_iommu_pri_request_page(IOMMUMemoryRegion *iommu, hwaddr addr,
+                                      bool lpig, uint16_t prgi, bool is_read,
+                                      bool is_write, bool exec_req,
+                                      bool priv_req)
+{
+    VTDAddressSpace *vtd_as = container_of(iommu, VTDAddressSpace, iommu);
+    IntelIOMMUState *s = vtd_as->iommu_state;
+    uint64_t queue_addr_reg = vtd_get_quad(s, DMAR_PQA_REG);
+    uint64_t queue_tail_offset_reg = vtd_get_quad(s, DMAR_PQT_REG);
+    uint64_t new_queue_tail_offset = (
+                                (queue_tail_offset_reg + VTD_PQA_ENTRY_SIZE) %
+                                (vtd_prq_size(s) * VTD_PQA_ENTRY_SIZE));
+    uint64_t queue_head_offset_reg = vtd_get_quad(s, DMAR_PQH_REG);
+    hwaddr queue_tail = (queue_addr_reg & VTD_PQA_ADDR) + queue_tail_offset_reg;
+    uint32_t old_pr_status = vtd_get_long(s, DMAR_PRS_REG);
+    uint16_t sid = PCI_BUILD_BDF(pci_bus_num(vtd_as->bus), vtd_as->devfn);
+    VTDPRDesc desc;
+
+    if (!(s->ecap & VTD_ECAP_PRS)) {
+        return -EPERM;
+    }
+
+    /*
+     * No need to check if scalable mode is enabled as we already known that
+     * VTD_ECAP_PRS is set (see vtd_decide_config)
+     */
+
+    /* We do not support PRI without PASID */
+    if (vtd_as->pasid == PCI_NO_PASID) {
+        return -EPERM;
+    }
+    if (exec_req && !is_read) {
+        return -EINVAL;
+    }
+
+    /* Check PRE bit in the scalable mode context entry */
+    if (!vtd_check_pre_bit(vtd_as, addr, sid, is_write)) {
+        return -EPERM;
+    }
+
+    if (old_pr_status & VTD_PR_STATUS_PRO) {
+        /*
+         * No action is taken by hardware to report a fault
+         * or generate an event
+         */
+        return -ENOSPC;
+    }
+
+    /* Check for overflow */
+    if (new_queue_tail_offset == queue_head_offset_reg) {
+        vtd_set_clear_mask_long(s, DMAR_PRS_REG, 0, VTD_PR_STATUS_PRO);
+        vtd_generate_page_request_event(s, old_pr_status);
+        return -ENOSPC;
+    }
+
+    if (vtd_pri_perform_implicit_invalidation(vtd_as, addr)) {
+        return -EINVAL;
+    }
+
+    desc.lo = VTD_PRD_TYPE | VTD_PRD_PP(true) | VTD_PRD_RID(sid) |
+              VTD_PRD_PASID(vtd_as->pasid) | VTD_PRD_PMR(priv_req);
+    desc.hi = VTD_PRD_RDR(is_read) | VTD_PRD_WRR(is_write) |
+              VTD_PRD_LPIG(lpig) | VTD_PRD_PRGI(prgi) | VTD_PRD_ADDR(addr);
+
+    desc.lo = cpu_to_le64(desc.lo);
+    desc.hi = cpu_to_le64(desc.hi);
+    if (dma_memory_write(&address_space_memory, queue_tail, &desc, sizeof(desc),
+                         MEMTXATTRS_UNSPECIFIED)) {
+        error_report_once("IO error, the PQ tail cannot be updated");
+        return -EIO;
+    }
+
+    /* increment the tail register and set the pending request bit */
+    vtd_set_quad(s, DMAR_PQT_REG, new_queue_tail_offset);
+    /*
+     * read status again so that the kernel does not miss a request.
+     * in some cases, we can trigger an unecessary interrupt but this strategy
+     * drastically improves performance as we don't need to take a lock.
+     */
+    old_pr_status = vtd_get_long(s, DMAR_PRS_REG);
+    if (!(old_pr_status & VTD_PR_STATUS_PPR)) {
+        vtd_set_clear_mask_long(s, DMAR_PRS_REG, 0, VTD_PR_STATUS_PPR);
+        vtd_generate_page_request_event(s, old_pr_status);
+    }
+
+    return 0;
+}
+
 static PCIIOMMUOps vtd_iommu_ops = {
     .get_address_space = vtd_host_dma_iommu,
     .get_address_space_pasid = vtd_host_dma_iommu_pasid,
@@ -6346,6 +6580,7 @@ static void vtd_iommu_memory_region_class_init(ObjectClass *klass,
     imrc->replay = vtd_iommu_replay;
     imrc->iommu_ats_request_translation = vtd_iommu_ats_request_translation;
     imrc->get_min_page_size = vtd_get_min_page_size;
+    imrc->iommu_pri_request_page = vtd_iommu_pri_request_page;
 }
 
 static const TypeInfo vtd_iommu_memory_region_info = {
diff --git a/hw/i386/intel_iommu_internal.h b/hw/i386/intel_iommu_internal.h
index 9e01251335..b2314c6a95 100644
--- a/hw/i386/intel_iommu_internal.h
+++ b/hw/i386/intel_iommu_internal.h
@@ -319,6 +319,8 @@ typedef enum VTDFaultReason {
                                   * request while disabled */
     VTD_FR_IR_SID_ERR = 0x26,   /* Invalid Source-ID */
 
+    VTD_FR_SM_PRE_ABS = 0x47,   /* SCT.8 : PRE bit in a present SM CE is 0 */
+
     VTD_FR_RTADDR_INV_TTM = 0x31,  /* Invalid TTM in RTADDR */
     /* PASID directory entry access failure */
     VTD_FR_PASID_DIR_ACCESS_ERR = 0x50,
-- 
2.45.1

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

* Re: [PATCH v1 0/8] PRI support for VT-d
  2024-05-30 12:24 [PATCH v1 0/8] PRI support for VT-d CLEMENT MATHIEU--DRIF
                   ` (7 preceding siblings ...)
  2024-05-30 12:25 ` [PATCH v1 8/8] intel_iommu: add PRI operations support CLEMENT MATHIEU--DRIF
@ 2024-06-06 16:12 ` CLEMENT MATHIEU--DRIF
  2024-07-04  6:24 ` Michael S. Tsirkin
  2024-07-05  3:03 ` Yi Liu
  10 siblings, 0 replies; 16+ messages in thread
From: CLEMENT MATHIEU--DRIF @ 2024-06-06 16:12 UTC (permalink / raw)
  To: qemu-devel@nongnu.org
  Cc: jasowang@redhat.com, zhenzhong.duan@intel.com,
	kevin.tian@intel.com, yi.l.liu@intel.com,
	joao.m.martins@oracle.com, peterx@redhat.com, Michael S. Tsirkin

Hi,

Just adding Michael in Cc:

Thanks
 >cmd


On 30/05/2024 14:24, CLEMENT MATHIEU--DRIF wrote:
> This series belongs to a list of series that add SVM support for VT-d.
>
> Here we focus on the implementation of PRI support in the IOMMU and on a PCI-level
> API for PRI to be used by virtual devices.
>
> 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
>          - Device IOTLB invalidations
>          - 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 (8):
>    pcie: add a helper to declare the PRI capability for a pcie device
>    pcie: helper functions to check to check if PRI is enabled
>    pcie: add a way to get the outstanding page request allocation (pri)
>      from the config space.
>    pci: declare structures and IOMMU operation for PRI
>    pci: add a PCI-level API for PRI
>    intel_iommu: declare PRI constants and structures
>    intel_iommu: declare registers for PRI
>    intel_iommu: add PRI operations support
>
>   hw/i386/intel_iommu.c          | 302 +++++++++++++++++++++++++++++++++
>   hw/i386/intel_iommu_internal.h |  54 +++++-
>   hw/pci/pci.c                   |  37 ++++
>   hw/pci/pcie.c                  |  42 +++++
>   include/exec/memory.h          |  65 +++++++
>   include/hw/pci/pci.h           |  45 +++++
>   include/hw/pci/pci_bus.h       |   1 +
>   include/hw/pci/pcie.h          |   7 +-
>   include/hw/pci/pcie_regs.h     |   4 +
>   system/memory.c                |  49 ++++++
>   10 files changed, 604 insertions(+), 2 deletions(-)
>

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

* Re: [PATCH v1 0/8] PRI support for VT-d
  2024-05-30 12:24 [PATCH v1 0/8] PRI support for VT-d CLEMENT MATHIEU--DRIF
                   ` (8 preceding siblings ...)
  2024-06-06 16:12 ` [PATCH v1 0/8] PRI support for VT-d CLEMENT MATHIEU--DRIF
@ 2024-07-04  6:24 ` Michael S. Tsirkin
  2024-07-04 14:53   ` CLEMENT MATHIEU--DRIF
  2024-07-05  3:03 ` Yi Liu
  10 siblings, 1 reply; 16+ messages in thread
From: Michael S. Tsirkin @ 2024-07-04  6:24 UTC (permalink / raw)
  To: CLEMENT MATHIEU--DRIF
  Cc: qemu-devel@nongnu.org, jasowang@redhat.com,
	zhenzhong.duan@intel.com, kevin.tian@intel.com,
	yi.l.liu@intel.com, joao.m.martins@oracle.com, peterx@redhat.com

On Thu, May 30, 2024 at 12:24:58PM +0000, CLEMENT MATHIEU--DRIF wrote:
> This series belongs to a list of series that add SVM support for VT-d.
> 
> Here we focus on the implementation of PRI support in the IOMMU and on a PCI-level
> API for PRI to be used by virtual devices.
> 
> 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
>         - Device IOTLB invalidations
>         - 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


To make things clear, is this patchset independent or
does it have a dependency, too?


> Clément Mathieu--Drif (8):
>   pcie: add a helper to declare the PRI capability for a pcie device
>   pcie: helper functions to check to check if PRI is enabled
>   pcie: add a way to get the outstanding page request allocation (pri)
>     from the config space.
>   pci: declare structures and IOMMU operation for PRI
>   pci: add a PCI-level API for PRI
>   intel_iommu: declare PRI constants and structures
>   intel_iommu: declare registers for PRI
>   intel_iommu: add PRI operations support
> 
>  hw/i386/intel_iommu.c          | 302 +++++++++++++++++++++++++++++++++
>  hw/i386/intel_iommu_internal.h |  54 +++++-
>  hw/pci/pci.c                   |  37 ++++
>  hw/pci/pcie.c                  |  42 +++++
>  include/exec/memory.h          |  65 +++++++
>  include/hw/pci/pci.h           |  45 +++++
>  include/hw/pci/pci_bus.h       |   1 +
>  include/hw/pci/pcie.h          |   7 +-
>  include/hw/pci/pcie_regs.h     |   4 +
>  system/memory.c                |  49 ++++++
>  10 files changed, 604 insertions(+), 2 deletions(-)
> 
> -- 
> 2.45.1



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

* Re: [PATCH v1 0/8] PRI support for VT-d
  2024-07-04  6:24 ` Michael S. Tsirkin
@ 2024-07-04 14:53   ` CLEMENT MATHIEU--DRIF
  0 siblings, 0 replies; 16+ messages in thread
From: CLEMENT MATHIEU--DRIF @ 2024-07-04 14:53 UTC (permalink / raw)
  To: Michael S. Tsirkin
  Cc: qemu-devel@nongnu.org, jasowang@redhat.com,
	zhenzhong.duan@intel.com, kevin.tian@intel.com,
	yi.l.liu@intel.com, joao.m.martins@oracle.com, peterx@redhat.com

[-- Attachment #1: Type: text/plain, Size: 3260 bytes --]



________________________________
From: Michael S. Tsirkin <mst@redhat.com>
Sent: 04 July 2024 08:24
To: CLEMENT MATHIEU--DRIF <clement.mathieu--drif@eviden.com>
Cc: qemu-devel@nongnu.org <qemu-devel@nongnu.org>; jasowang@redhat.com <jasowang@redhat.com>; zhenzhong.duan@intel.com <zhenzhong.duan@intel.com>; kevin.tian@intel.com <kevin.tian@intel.com>; yi.l.liu@intel.com <yi.l.liu@intel.com>; joao.m.martins@oracle.com <joao.m.martins@oracle.com>; peterx@redhat.com <peterx@redhat.com>
Subject: Re: [PATCH v1 0/8] PRI support for VT-d

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.


On Thu, May 30, 2024 at 12:24:58PM +0000, CLEMENT MATHIEU--DRIF wrote:
> This series belongs to a list of series that add SVM support for VT-d.
>
> Here we focus on the implementation of PRI support in the IOMMU and on a PCI-level
> API for PRI to be used by virtual devices.
>
> 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
>         - Device IOTLB invalidations
>         - Requests with already translated addresses
>     - A demo device
>     - A simple driver for the demo device
>     - A userspace program (for testing and demonstration purposes)
>
> https://eur06.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.com%2FBullSequana%2FQemu-in-guest-SVM-demo&data=05%7C02%7Cclement.mathieu--drif%40eviden.com%7C0b2efce63b3b400a2a9408dc9bf1f45c%7C7d1c77852d8a437db8421ed5d8fbe00a%7C0%7C0%7C638556710682005347%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C0%7C%7C%7C&sdata=QzUQdYTeIxZ0poSL0MvM2x%2F8ar4R%2B7YioDTO3WQeFAU%3D&reserved=0<https://github.com/BullSequana/Qemu-in-guest-SVM-demo>


To make things clear, is this patchset independent or
does it have a dependency, too?

Hi Michael,
This also depends on the ATS series (which also has dependencies itself).
I will make this very clear in future versions.

> Clément Mathieu--Drif (8):
>   pcie: add a helper to declare the PRI capability for a pcie device
>   pcie: helper functions to check to check if PRI is enabled
>   pcie: add a way to get the outstanding page request allocation (pri)
>     from the config space.
>   pci: declare structures and IOMMU operation for PRI
>   pci: add a PCI-level API for PRI
>   intel_iommu: declare PRI constants and structures
>   intel_iommu: declare registers for PRI
>   intel_iommu: add PRI operations support
>
>  hw/i386/intel_iommu.c          | 302 +++++++++++++++++++++++++++++++++
>  hw/i386/intel_iommu_internal.h |  54 +++++-
>  hw/pci/pci.c                   |  37 ++++
>  hw/pci/pcie.c                  |  42 +++++
>  include/exec/memory.h          |  65 +++++++
>  include/hw/pci/pci.h           |  45 +++++
>  include/hw/pci/pci_bus.h       |   1 +
>  include/hw/pci/pcie.h          |   7 +-
>  include/hw/pci/pcie_regs.h     |   4 +
>  system/memory.c                |  49 ++++++
>  10 files changed, 604 insertions(+), 2 deletions(-)
>
> --
> 2.45.1


[-- Attachment #2: Type: text/html, Size: 5967 bytes --]

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

* Re: [PATCH v1 0/8] PRI support for VT-d
  2024-05-30 12:24 [PATCH v1 0/8] PRI support for VT-d CLEMENT MATHIEU--DRIF
                   ` (9 preceding siblings ...)
  2024-07-04  6:24 ` Michael S. Tsirkin
@ 2024-07-05  3:03 ` Yi Liu
  2024-07-05  5:13   ` CLEMENT MATHIEU--DRIF
  10 siblings, 1 reply; 16+ messages in thread
From: Yi Liu @ 2024-07-05  3:03 UTC (permalink / raw)
  To: CLEMENT MATHIEU--DRIF, qemu-devel@nongnu.org
  Cc: jasowang@redhat.com, zhenzhong.duan@intel.com,
	kevin.tian@intel.com, joao.m.martins@oracle.com,
	peterx@redhat.com

On 2024/5/30 20:24, CLEMENT MATHIEU--DRIF wrote:
> This series belongs to a list of series that add SVM support for VT-d.
> 
> Here we focus on the implementation of PRI support in the IOMMU and on a PCI-level
> API for PRI to be used by virtual devices.
> 
> 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
>          - Device IOTLB invalidations
>          - Requests with already translated addresses
>      - A demo device
>      - A simple driver for the demo device
>      - A userspace program (for testing and demonstration purposes)

I didn't see the drain PRQ related logics in this series. Please consider
adding it in next version. It's needed when repurposing a PASID.

> https://github.com/BullSequana/Qemu-in-guest-SVM-demo
> 
> Clément Mathieu--Drif (8):
>    pcie: add a helper to declare the PRI capability for a pcie device
>    pcie: helper functions to check to check if PRI is enabled
>    pcie: add a way to get the outstanding page request allocation (pri)
>      from the config space.
>    pci: declare structures and IOMMU operation for PRI
>    pci: add a PCI-level API for PRI
>    intel_iommu: declare PRI constants and structures
>    intel_iommu: declare registers for PRI
>    intel_iommu: add PRI operations support
> 
>   hw/i386/intel_iommu.c          | 302 +++++++++++++++++++++++++++++++++
>   hw/i386/intel_iommu_internal.h |  54 +++++-
>   hw/pci/pci.c                   |  37 ++++
>   hw/pci/pcie.c                  |  42 +++++
>   include/exec/memory.h          |  65 +++++++
>   include/hw/pci/pci.h           |  45 +++++
>   include/hw/pci/pci_bus.h       |   1 +
>   include/hw/pci/pcie.h          |   7 +-
>   include/hw/pci/pcie_regs.h     |   4 +
>   system/memory.c                |  49 ++++++
>   10 files changed, 604 insertions(+), 2 deletions(-)
> 

-- 
Regards,
Yi Liu


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

* Re: [PATCH v1 0/8] PRI support for VT-d
  2024-07-05  3:03 ` Yi Liu
@ 2024-07-05  5:13   ` CLEMENT MATHIEU--DRIF
  2024-07-05  6:20     ` Yi Liu
  0 siblings, 1 reply; 16+ messages in thread
From: CLEMENT MATHIEU--DRIF @ 2024-07-05  5:13 UTC (permalink / raw)
  To: Yi Liu, qemu-devel@nongnu.org
  Cc: jasowang@redhat.com, zhenzhong.duan@intel.com,
	kevin.tian@intel.com, joao.m.martins@oracle.com,
	peterx@redhat.com


On 05/07/2024 05:03, Yi Liu 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.
>
>
> On 2024/5/30 20:24, CLEMENT MATHIEU--DRIF wrote:
>> This series belongs to a list of series that add SVM support for VT-d.
>>
>> Here we focus on the implementation of PRI support in the IOMMU and
>> on a PCI-level
>> API for PRI to be used by virtual devices.
>>
>> 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
>>          - Device IOTLB invalidations
>>          - Requests with already translated addresses
>>      - A demo device
>>      - A simple driver for the demo device
>>      - A userspace program (for testing and demonstration purposes)
>
> I didn't see the drain PRQ related logics in this series. Please consider
> adding it in next version. It's needed when repurposing a PASID.

Hi,

Are you talking about wait descriptors with SW = 0, IF = 0, FN = 1
(section 7.10 of VT-d)?

I'll move that to the PRI series.

>
>> https://github.com/BullSequana/Qemu-in-guest-SVM-demo
>>
>>
>> Clément Mathieu--Drif (8):
>>    pcie: add a helper to declare the PRI capability for a pcie device
>>    pcie: helper functions to check to check if PRI is enabled
>>    pcie: add a way to get the outstanding page request allocation (pri)
>>      from the config space.
>>    pci: declare structures and IOMMU operation for PRI
>>    pci: add a PCI-level API for PRI
>>    intel_iommu: declare PRI constants and structures
>>    intel_iommu: declare registers for PRI
>>    intel_iommu: add PRI operations support
>>
>>   hw/i386/intel_iommu.c          | 302 +++++++++++++++++++++++++++++++++
>>   hw/i386/intel_iommu_internal.h |  54 +++++-
>>   hw/pci/pci.c                   |  37 ++++
>>   hw/pci/pcie.c                  |  42 +++++
>>   include/exec/memory.h          |  65 +++++++
>>   include/hw/pci/pci.h           |  45 +++++
>>   include/hw/pci/pci_bus.h       |   1 +
>>   include/hw/pci/pcie.h          |   7 +-
>>   include/hw/pci/pcie_regs.h     |   4 +
>>   system/memory.c                |  49 ++++++
>>   10 files changed, 604 insertions(+), 2 deletions(-)
>>
>
> --
> Regards,
> Yi Liu

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

* Re: [PATCH v1 0/8] PRI support for VT-d
  2024-07-05  5:13   ` CLEMENT MATHIEU--DRIF
@ 2024-07-05  6:20     ` Yi Liu
  2024-07-05 10:03       ` cmd
  0 siblings, 1 reply; 16+ messages in thread
From: Yi Liu @ 2024-07-05  6:20 UTC (permalink / raw)
  To: CLEMENT MATHIEU--DRIF, qemu-devel@nongnu.org
  Cc: jasowang@redhat.com, zhenzhong.duan@intel.com,
	kevin.tian@intel.com, joao.m.martins@oracle.com,
	peterx@redhat.com

On 2024/7/5 13:13, CLEMENT MATHIEU--DRIF wrote:
> 
> On 05/07/2024 05:03, Yi Liu 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.
>>
>>
>> On 2024/5/30 20:24, CLEMENT MATHIEU--DRIF wrote:
>>> This series belongs to a list of series that add SVM support for VT-d.
>>>
>>> Here we focus on the implementation of PRI support in the IOMMU and
>>> on a PCI-level
>>> API for PRI to be used by virtual devices.
>>>
>>> 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
>>>           - Device IOTLB invalidations
>>>           - Requests with already translated addresses
>>>       - A demo device
>>>       - A simple driver for the demo device
>>>       - A userspace program (for testing and demonstration purposes)
>>
>> I didn't see the drain PRQ related logics in this series. Please consider
>> adding it in next version. It's needed when repurposing a PASID.
> 
> Hi,
> 
> Are you talking about wait descriptors with SW = 0, IF = 0, FN = 1
> (section 7.10 of VT-d)?
> 
> I'll move that to the PRI series.

yes. But not only that patch. When guest software submitting the
descriptors per CH7.10 of VT-d spec, QEMU need to emulate the
PRQ drain behavior.

>>
>>> https://github.com/BullSequana/Qemu-in-guest-SVM-demo
>>>
>>>
>>> Clément Mathieu--Drif (8):
>>>     pcie: add a helper to declare the PRI capability for a pcie device
>>>     pcie: helper functions to check to check if PRI is enabled
>>>     pcie: add a way to get the outstanding page request allocation (pri)
>>>       from the config space.
>>>     pci: declare structures and IOMMU operation for PRI
>>>     pci: add a PCI-level API for PRI
>>>     intel_iommu: declare PRI constants and structures
>>>     intel_iommu: declare registers for PRI
>>>     intel_iommu: add PRI operations support
>>>
>>>    hw/i386/intel_iommu.c          | 302 +++++++++++++++++++++++++++++++++
>>>    hw/i386/intel_iommu_internal.h |  54 +++++-
>>>    hw/pci/pci.c                   |  37 ++++
>>>    hw/pci/pcie.c                  |  42 +++++
>>>    include/exec/memory.h          |  65 +++++++
>>>    include/hw/pci/pci.h           |  45 +++++
>>>    include/hw/pci/pci_bus.h       |   1 +
>>>    include/hw/pci/pcie.h          |   7 +-
>>>    include/hw/pci/pcie_regs.h     |   4 +
>>>    system/memory.c                |  49 ++++++
>>>    10 files changed, 604 insertions(+), 2 deletions(-)
>>>
>>
>> --
>> Regards,
>> Yi Liu

-- 
Regards,
Yi Liu


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

* Re: [PATCH v1 0/8] PRI support for VT-d
  2024-07-05  6:20     ` Yi Liu
@ 2024-07-05 10:03       ` cmd
  0 siblings, 0 replies; 16+ messages in thread
From: cmd @ 2024-07-05 10:03 UTC (permalink / raw)
  To: Yi Liu, CLEMENT MATHIEU--DRIF, qemu-devel@nongnu.org
  Cc: jasowang@redhat.com, zhenzhong.duan@intel.com,
	kevin.tian@intel.com, joao.m.martins@oracle.com,
	peterx@redhat.com



On 05/07/2024 08:20, Yi Liu wrote:
> On 2024/7/5 13:13, CLEMENT MATHIEU--DRIF wrote:
>>
>> On 05/07/2024 05:03, Yi Liu 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.
>>>
>>>
>>> On 2024/5/30 20:24, CLEMENT MATHIEU--DRIF wrote:
>>>> This series belongs to a list of series that add SVM support for VT-d.
>>>>
>>>> Here we focus on the implementation of PRI support in the IOMMU and
>>>> on a PCI-level
>>>> API for PRI to be used by virtual devices.
>>>>
>>>> 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
>>>>           - Device IOTLB invalidations
>>>>           - Requests with already translated addresses
>>>>       - A demo device
>>>>       - A simple driver for the demo device
>>>>       - A userspace program (for testing and demonstration purposes)
>>>
>>> I didn't see the drain PRQ related logics in this series. Please 
>>> consider
>>> adding it in next version. It's needed when repurposing a PASID.
>>
>> Hi,
>>
>> Are you talking about wait descriptors with SW = 0, IF = 0, FN = 1
>> (section 7.10 of VT-d)?
>>
>> I'll move that to the PRI series.
>
> yes. But not only that patch. When guest software submitting the
> descriptors per CH7.10 of VT-d spec, QEMU need to emulate the
> PRQ drain behavior.
>
Ok, will check
>>>
>>>> https://github.com/BullSequana/Qemu-in-guest-SVM-demo
>>>>
>>>>
>>>> Clément Mathieu--Drif (8):
>>>>     pcie: add a helper to declare the PRI capability for a pcie device
>>>>     pcie: helper functions to check to check if PRI is enabled
>>>>     pcie: add a way to get the outstanding page request allocation 
>>>> (pri)
>>>>       from the config space.
>>>>     pci: declare structures and IOMMU operation for PRI
>>>>     pci: add a PCI-level API for PRI
>>>>     intel_iommu: declare PRI constants and structures
>>>>     intel_iommu: declare registers for PRI
>>>>     intel_iommu: add PRI operations support
>>>>
>>>>    hw/i386/intel_iommu.c          | 302 
>>>> +++++++++++++++++++++++++++++++++
>>>>    hw/i386/intel_iommu_internal.h |  54 +++++-
>>>>    hw/pci/pci.c                   |  37 ++++
>>>>    hw/pci/pcie.c                  |  42 +++++
>>>>    include/exec/memory.h          |  65 +++++++
>>>>    include/hw/pci/pci.h           |  45 +++++
>>>>    include/hw/pci/pci_bus.h       |   1 +
>>>>    include/hw/pci/pcie.h          |   7 +-
>>>>    include/hw/pci/pcie_regs.h     |   4 +
>>>>    system/memory.c                |  49 ++++++
>>>>    10 files changed, 604 insertions(+), 2 deletions(-)
>>>>
>>>
>>> -- 
>>> Regards,
>>> Yi Liu
>



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

end of thread, other threads:[~2024-07-05 10:04 UTC | newest]

Thread overview: 16+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-05-30 12:24 [PATCH v1 0/8] PRI support for VT-d CLEMENT MATHIEU--DRIF
2024-05-30 12:25 ` [PATCH v1 1/8] pcie: add a helper to declare the PRI capability for a pcie device CLEMENT MATHIEU--DRIF
2024-05-30 12:25 ` [PATCH v1 2/8] pcie: helper functions to check to check if PRI is enabled CLEMENT MATHIEU--DRIF
2024-05-30 12:25 ` [PATCH v1 3/8] pcie: add a way to get the outstanding page request allocation (pri) from the config space CLEMENT MATHIEU--DRIF
2024-05-30 12:25 ` [PATCH v1 4/8] pci: declare structures and IOMMU operation for PRI CLEMENT MATHIEU--DRIF
2024-05-30 12:25 ` [PATCH v1 6/8] intel_iommu: declare PRI constants and structures CLEMENT MATHIEU--DRIF
2024-05-30 12:25 ` [PATCH v1 5/8] pci: add a PCI-level API for PRI CLEMENT MATHIEU--DRIF
2024-05-30 12:25 ` [PATCH v1 7/8] intel_iommu: declare registers " CLEMENT MATHIEU--DRIF
2024-05-30 12:25 ` [PATCH v1 8/8] intel_iommu: add PRI operations support CLEMENT MATHIEU--DRIF
2024-06-06 16:12 ` [PATCH v1 0/8] PRI support for VT-d CLEMENT MATHIEU--DRIF
2024-07-04  6:24 ` Michael S. Tsirkin
2024-07-04 14:53   ` CLEMENT MATHIEU--DRIF
2024-07-05  3:03 ` Yi Liu
2024-07-05  5:13   ` CLEMENT MATHIEU--DRIF
2024-07-05  6:20     ` Yi Liu
2024-07-05 10:03       ` cmd

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).