diff mbox series

[RFC,v1,09/18] intel_iommu: process pasid cache invalidation

Message ID 1562324511-2910-10-git-send-email-yi.l.liu@intel.com
State New
Headers show
Series intel_iommu: expose Shared Virtual Addressing to VM | expand

Commit Message

Liu, Yi L July 5, 2019, 11:01 a.m. UTC
This patch adds PASID cache flush emulation framework. Per Intel VT-d 3.0
spec, PASID cache invalidation under caching-mode provides a mechanism
software Intel VT-d(vIOMMU) implementations to track guest PASID bind/unbind
operations. This is a key part of vIOMMU support for guest SVA. And this
patch only adds the frame of it. The detailed implementation relies on
PASID records management implementation in vIOMMU, which will be covered
in later patch of this series.

Cc: Kevin Tian <kevin.tian@intel.com>
Cc: Jacob Pan <jacob.jun.pan@linux.intel.com>
Cc: Peter Xu <peterx@redhat.com>
Cc: Yi Sun <yi.y.sun@linux.intel.com>
Signed-off-by: Liu Yi L <yi.l.liu@intel.com>
---
 hw/i386/intel_iommu.c          | 40 +++++++++++++++++++++++++++++++++++-----
 hw/i386/intel_iommu_internal.h | 12 ++++++++++++
 2 files changed, 47 insertions(+), 5 deletions(-)

Comments

Peter Xu July 9, 2019, 4:47 a.m. UTC | #1
On Fri, Jul 05, 2019 at 07:01:42PM +0800, Liu Yi L wrote:
> +static bool vtd_process_pasid_desc(IntelIOMMUState *s,
> +                                   VTDInvDesc *inv_desc)
> +{
> +    if ((inv_desc->val[0] & VTD_INV_DESC_PASIDC_RSVD_VAL0) ||
> +        (inv_desc->val[1] & VTD_INV_DESC_PASIDC_RSVD_VAL1) ||
> +        (inv_desc->val[2] & VTD_INV_DESC_PASIDC_RSVD_VAL2) ||
> +        (inv_desc->val[3] & VTD_INV_DESC_PASIDC_RSVD_VAL3)) {
> +        trace_vtd_inv_desc("non-zero-field-in-pc_inv_desc",
> +                            inv_desc->val[1], inv_desc->val[0]);

The first parameter of trace_vtd_inv_desc() should be the type.

Can use error_report_once() here.

> +        return false;
> +    }
> +
> +    switch (inv_desc->val[0] & VTD_INV_DESC_PASIDC_G) {
> +    case VTD_INV_DESC_PASIDC_DSI:
> +        break;
> +
> +    case VTD_INV_DESC_PASIDC_PASID_SI:
> +        break;
> +
> +    case VTD_INV_DESC_PASIDC_GLOBAL:
> +        break;
> +
> +    default:
> +        trace_vtd_inv_desc("invalid-inv-granu-in-pc_inv_desc",
> +                            inv_desc->val[1], inv_desc->val[0]);

Here too.

> +        return false;
> +    }
> +
> +    return true;
> +}

Regards,
Liu, Yi L July 11, 2019, 6:22 a.m. UTC | #2
> From: Peter Xu [mailto:zhexu@redhat.com]
> Sent: Tuesday, July 9, 2019 12:48 PM
> To: Liu, Yi L <yi.l.liu@intel.com>
> Cc: qemu-devel@nongnu.org; mst@redhat.com; pbonzini@redhat.com;
> alex.williamson@redhat.com; eric.auger@redhat.com;
> david@gibson.dropbear.id.au; tianyu.lan@intel.com; Tian, Kevin
> <kevin.tian@intel.com>; Tian, Jun J <jun.j.tian@intel.com>; Sun, Yi Y
> <yi.y.sun@intel.com>; kvm@vger.kernel.org; Jacob Pan
> <jacob.jun.pan@linux.intel.com>; Yi Sun <yi.y.sun@linux.intel.com>
> Subject: Re: [RFC v1 09/18] intel_iommu: process pasid cache invalidation
> 
> On Fri, Jul 05, 2019 at 07:01:42PM +0800, Liu Yi L wrote:
> > +static bool vtd_process_pasid_desc(IntelIOMMUState *s,
> > +                                   VTDInvDesc *inv_desc) {
> > +    if ((inv_desc->val[0] & VTD_INV_DESC_PASIDC_RSVD_VAL0) ||
> > +        (inv_desc->val[1] & VTD_INV_DESC_PASIDC_RSVD_VAL1) ||
> > +        (inv_desc->val[2] & VTD_INV_DESC_PASIDC_RSVD_VAL2) ||
> > +        (inv_desc->val[3] & VTD_INV_DESC_PASIDC_RSVD_VAL3)) {
> > +        trace_vtd_inv_desc("non-zero-field-in-pc_inv_desc",
> > +                            inv_desc->val[1], inv_desc->val[0]);
> 
> The first parameter of trace_vtd_inv_desc() should be the type.
> 
> Can use error_report_once() here.

I think so, let me switch to use it in next version.

> > +        return false;
> > +    }
> > +
> > +    switch (inv_desc->val[0] & VTD_INV_DESC_PASIDC_G) {
> > +    case VTD_INV_DESC_PASIDC_DSI:
> > +        break;
> > +
> > +    case VTD_INV_DESC_PASIDC_PASID_SI:
> > +        break;
> > +
> > +    case VTD_INV_DESC_PASIDC_GLOBAL:
> > +        break;
> > +
> > +    default:
> > +        trace_vtd_inv_desc("invalid-inv-granu-in-pc_inv_desc",
> > +                            inv_desc->val[1], inv_desc->val[0]);
> 
> Here too.

Got it.

Thanks,
Yi Liu

> > +        return false;
> > +    }
> > +
> > +    return true;
> > +}
> 
> Regards,
> 
> --
> Peter Xu
diff mbox series

Patch

diff --git a/hw/i386/intel_iommu.c b/hw/i386/intel_iommu.c
index 3cf250d..ef13662 100644
--- a/hw/i386/intel_iommu.c
+++ b/hw/i386/intel_iommu.c
@@ -2331,6 +2331,37 @@  static bool vtd_process_iotlb_desc(IntelIOMMUState *s, VTDInvDesc *inv_desc)
     return true;
 }
 
+static bool vtd_process_pasid_desc(IntelIOMMUState *s,
+                                   VTDInvDesc *inv_desc)
+{
+    if ((inv_desc->val[0] & VTD_INV_DESC_PASIDC_RSVD_VAL0) ||
+        (inv_desc->val[1] & VTD_INV_DESC_PASIDC_RSVD_VAL1) ||
+        (inv_desc->val[2] & VTD_INV_DESC_PASIDC_RSVD_VAL2) ||
+        (inv_desc->val[3] & VTD_INV_DESC_PASIDC_RSVD_VAL3)) {
+        trace_vtd_inv_desc("non-zero-field-in-pc_inv_desc",
+                            inv_desc->val[1], inv_desc->val[0]);
+        return false;
+    }
+
+    switch (inv_desc->val[0] & VTD_INV_DESC_PASIDC_G) {
+    case VTD_INV_DESC_PASIDC_DSI:
+        break;
+
+    case VTD_INV_DESC_PASIDC_PASID_SI:
+        break;
+
+    case VTD_INV_DESC_PASIDC_GLOBAL:
+        break;
+
+    default:
+        trace_vtd_inv_desc("invalid-inv-granu-in-pc_inv_desc",
+                            inv_desc->val[1], inv_desc->val[0]);
+        return false;
+    }
+
+    return true;
+}
+
 static bool vtd_process_inv_iec_desc(IntelIOMMUState *s,
                                      VTDInvDesc *inv_desc)
 {
@@ -2437,12 +2468,11 @@  static bool vtd_process_inv_desc(IntelIOMMUState *s)
         }
         break;
 
-    /*
-     * TODO: the entity of below two cases 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.
-     */
     case VTD_INV_DESC_PC:
+        trace_vtd_inv_desc("pasid-cache", inv_desc.val[1], inv_desc.val[0]);
+        if (!vtd_process_pasid_desc(s, &inv_desc)) {
+            return false;
+        }
         break;
 
     case VTD_INV_DESC_PIOTLB:
diff --git a/hw/i386/intel_iommu_internal.h b/hw/i386/intel_iommu_internal.h
index f5a2f0d..e335800 100644
--- a/hw/i386/intel_iommu_internal.h
+++ b/hw/i386/intel_iommu_internal.h
@@ -436,6 +436,18 @@  typedef union VTDInvDesc VTDInvDesc;
 #define VTD_SPTE_LPAGE_L4_RSVD_MASK(aw) \
         (0x880ULL | ~(VTD_HAW_MASK(aw) | VTD_SL_IGN_COM))
 
+#define VTD_INV_DESC_PASIDC_G          (3ULL << 4)
+#define VTD_INV_DESC_PASIDC_PASID(val) (((val) >> 32) & 0xfffffULL)
+#define VTD_INV_DESC_PASIDC_DID(val)   (((val) >> 16) & VTD_DOMAIN_ID_MASK)
+#define VTD_INV_DESC_PASIDC_RSVD_VAL0  0xfff000000000ffc0ULL
+#define VTD_INV_DESC_PASIDC_RSVD_VAL1  0xffffffffffffffffULL
+#define VTD_INV_DESC_PASIDC_RSVD_VAL2  0xffffffffffffffffULL
+#define VTD_INV_DESC_PASIDC_RSVD_VAL3  0xffffffffffffffffULL
+
+#define VTD_INV_DESC_PASIDC_DSI        (0ULL << 4)
+#define VTD_INV_DESC_PASIDC_PASID_SI   (1ULL << 4)
+#define VTD_INV_DESC_PASIDC_GLOBAL     (3ULL << 4)
+
 /* Information about page-selective IOTLB invalidate */
 struct VTDIOTLBPageInvInfo {
     uint16_t domain_id;