WARNING - OLD ARCHIVES

This is an archived copy of the Xen.org mailing list, which we have preserved to ensure that existing links to archives are not broken. The live archive, which contains the latest emails, can be found at http://lists.xen.org/
   
 
 
Xen 
 
Home Products Support Community News
 
   
 

xen-changelog

[Xen-changelog] [xen-unstable] VT-d: define a macro for waiting hardare

To: xen-changelog@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-changelog] [xen-unstable] VT-d: define a macro for waiting hardare completion
From: Xen patchbot-unstable <patchbot-unstable@xxxxxxxxxxxxxxxxxxx>
Date: Fri, 05 Jun 2009 19:15:18 -0700
Delivery-date: Fri, 05 Jun 2009 19:15:37 -0700
Envelope-to: www-data@xxxxxxxxxxxxxxxxxxx
List-help: <mailto:xen-changelog-request@lists.xensource.com?subject=help>
List-id: BK change log <xen-changelog.lists.xensource.com>
List-post: <mailto:xen-changelog@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=unsubscribe>
Reply-to: xen-devel@xxxxxxxxxxxxxxxxxxx
Sender: xen-changelog-bounces@xxxxxxxxxxxxxxxxxxx
# HG changeset patch
# User Keir Fraser <keir.fraser@xxxxxxxxxx>
# Date 1244190438 -3600
# Node ID a69daf23602a8b7f41a7dc304c7050def59597c7
# Parent  931dbe86e5f37d5eb89e7383098f04b934475c48
VT-d: define a macro for waiting hardare completion

When set some registers of VT-d, it must wait for hardware
completion. There are lots of duplicated code to do that. This patch
defines a macro for it, thus it is much cleaner.

Signed-off-by: Weidong Han <weidong.han@xxxxxxxxx>
---
 xen/drivers/passthrough/vtd/dmar.h     |   14 +++++
 xen/drivers/passthrough/vtd/intremap.c |   45 ++++------------
 xen/drivers/passthrough/vtd/iommu.c    |   88 +++++----------------------------
 xen/drivers/passthrough/vtd/qinval.c   |   24 ++-------
 xen/drivers/passthrough/vtd/utils.c    |   19 +------
 5 files changed, 52 insertions(+), 138 deletions(-)

diff -r 931dbe86e5f3 -r a69daf23602a xen/drivers/passthrough/vtd/dmar.h
--- a/xen/drivers/passthrough/vtd/dmar.h        Fri Jun 05 09:26:39 2009 +0100
+++ b/xen/drivers/passthrough/vtd/dmar.h        Fri Jun 05 09:27:18 2009 +0100
@@ -90,6 +90,20 @@ void dmar_scope_remove_buses(struct dmar
 
 #define DMAR_OPERATION_TIMEOUT MILLISECS(1000)
 
+#define IOMMU_WAIT_OP(iommu, offset, op, cond, sts) \
+do {                                                \
+    s_time_t start_time = NOW();                    \
+    while (1) {                                     \
+        sts = op(iommu->reg, offset);               \
+        if ( cond )                                 \
+            break;                                  \
+        if ( NOW() > start_time + DMAR_OPERATION_TIMEOUT )      \
+            panic("%s:%d:%s: DMAR hardware is malfunctional\n", \
+                  __FILE__, __LINE__, __func__);                \
+        cpu_relax();                                            \
+    }                                                           \
+} while (0)
+
 int vtd_hw_check(void);
 void disable_pmr(struct iommu *iommu);
 int is_usb_device(u8 bus, u8 devfn);
diff -r 931dbe86e5f3 -r a69daf23602a xen/drivers/passthrough/vtd/intremap.c
--- a/xen/drivers/passthrough/vtd/intremap.c    Fri Jun 05 09:26:39 2009 +0100
+++ b/xen/drivers/passthrough/vtd/intremap.c    Fri Jun 05 09:27:18 2009 +0100
@@ -534,7 +534,7 @@ int enable_intremap(struct iommu *iommu)
 int enable_intremap(struct iommu *iommu)
 {
     struct ir_ctrl *ir_ctrl;
-    s_time_t start_time;
+    u32 sts;
 
     ASSERT(ecap_intr_remap(iommu->ecap) && iommu_intremap);
 
@@ -564,38 +564,22 @@ int enable_intremap(struct iommu *iommu)
     iommu->gcmd |= DMA_GCMD_SIRTP;
     dmar_writel(iommu->reg, DMAR_GCMD_REG, iommu->gcmd);
 
-    /* Make sure hardware complete it */
-    start_time = NOW();
-    while ( !(dmar_readl(iommu->reg, DMAR_GSTS_REG) & DMA_GSTS_SIRTPS) )
-    {
-        if ( NOW() > (start_time + DMAR_OPERATION_TIMEOUT) )
-            panic("Cannot set SIRTP field for interrupt remapping\n");
-        cpu_relax();
-    }
-
+    IOMMU_WAIT_OP(iommu, DMAR_GSTS_REG, dmar_readl,
+                  (sts & DMA_GSTS_SIRTPS), sts);
+ 
     /* enable comaptiblity format interrupt pass through */
     iommu->gcmd |= DMA_GCMD_CFI;
     dmar_writel(iommu->reg, DMAR_GCMD_REG, iommu->gcmd);
 
-    start_time = NOW();
-    while ( !(dmar_readl(iommu->reg, DMAR_GSTS_REG) & DMA_GSTS_CFIS) )
-    {
-        if ( NOW() > (start_time + DMAR_OPERATION_TIMEOUT) )
-            panic("Cannot set CFI field for interrupt remapping\n");
-        cpu_relax();
-    }
+    IOMMU_WAIT_OP(iommu, DMAR_GSTS_REG, dmar_readl,
+                  (sts & DMA_GSTS_CFIS), sts);
 
     /* enable interrupt remapping hardware */
     iommu->gcmd |= DMA_GCMD_IRE;
     dmar_writel(iommu->reg, DMAR_GCMD_REG, iommu->gcmd);
 
-    start_time = NOW();
-    while ( !(dmar_readl(iommu->reg, DMAR_GSTS_REG) & DMA_GSTS_IRES) )
-    {
-        if ( NOW() > (start_time + DMAR_OPERATION_TIMEOUT) )
-            panic("Cannot set IRE field for interrupt remapping\n");
-        cpu_relax();
-    }
+    IOMMU_WAIT_OP(iommu, DMAR_GSTS_REG, dmar_readl,
+                  (sts & DMA_GSTS_IRES), sts);
 
     /* After set SIRTP, we should do globally invalidate the IEC */
     iommu_flush_iec_global(iommu);
@@ -605,18 +589,13 @@ int enable_intremap(struct iommu *iommu)
 
 void disable_intremap(struct iommu *iommu)
 {
-    s_time_t start_time;
+    u32 sts;
 
     ASSERT(ecap_intr_remap(iommu->ecap) && iommu_intremap);
 
     iommu->gcmd &= ~(DMA_GCMD_SIRTP | DMA_GCMD_CFI | DMA_GCMD_IRE);
     dmar_writel(iommu->reg, DMAR_GCMD_REG, iommu->gcmd);
 
-    start_time = NOW();
-    while ( dmar_readl(iommu->reg, DMAR_GSTS_REG) & DMA_GSTS_IRES )
-    {
-        if ( NOW() > (start_time + DMAR_OPERATION_TIMEOUT) )
-            panic("Cannot clear IRE field for interrupt remapping\n");
-        cpu_relax();
-    }
-}
+    IOMMU_WAIT_OP(iommu, DMAR_GSTS_REG, dmar_readl,
+                  !(sts & DMA_GSTS_IRES), sts);
+}
diff -r 931dbe86e5f3 -r a69daf23602a xen/drivers/passthrough/vtd/iommu.c
--- a/xen/drivers/passthrough/vtd/iommu.c       Fri Jun 05 09:26:39 2009 +0100
+++ b/xen/drivers/passthrough/vtd/iommu.c       Fri Jun 05 09:27:18 2009 +0100
@@ -230,7 +230,6 @@ static void iommu_flush_write_buffer(str
 {
     u32 val;
     unsigned long flag;
-    s_time_t start_time;
 
     if ( !rwbf_quirk && !cap_rwbf(iommu->cap) )
         return;
@@ -240,17 +239,9 @@ static void iommu_flush_write_buffer(str
     dmar_writel(iommu->reg, DMAR_GCMD_REG, val);
 
     /* Make sure hardware complete it */
-    start_time = NOW();
-    for ( ; ; )
-    {
-        val = dmar_readl(iommu->reg, DMAR_GSTS_REG);
-        if ( !(val & DMA_GSTS_WBFS) )
-            break;
-        if ( NOW() > start_time + DMAR_OPERATION_TIMEOUT )
-            panic("%s: DMAR hardware is malfunctional,"
-                  " please disable IOMMU\n", __func__);
-        cpu_relax();
-    }
+    IOMMU_WAIT_OP(iommu, DMAR_GSTS_REG, dmar_readl,
+                  !(val & DMA_GSTS_WBFS), val);
+
     spin_unlock_irqrestore(&iommu->register_lock, flag);
 }
 
@@ -263,7 +254,6 @@ static int flush_context_reg(
     struct iommu *iommu = (struct iommu *) _iommu;
     u64 val = 0;
     unsigned long flag;
-    s_time_t start_time;
 
     /*
      * In the non-present entry flush case, if hardware doesn't cache
@@ -301,17 +291,9 @@ static int flush_context_reg(
     dmar_writeq(iommu->reg, DMAR_CCMD_REG, val);
 
     /* Make sure hardware complete it */
-    start_time = NOW();
-    for ( ; ; )
-    {
-        val = dmar_readq(iommu->reg, DMAR_CCMD_REG);
-        if ( !(val & DMA_CCMD_ICC) )
-            break;
-        if ( NOW() > start_time + DMAR_OPERATION_TIMEOUT )
-            panic("%s: DMAR hardware is malfunctional,"
-                  " please disable IOMMU\n", __func__);
-        cpu_relax();
-    }
+    IOMMU_WAIT_OP(iommu, DMAR_CCMD_REG, dmar_readq,
+                  !(val & DMA_CCMD_ICC), val);
+
     spin_unlock_irqrestore(&iommu->register_lock, flag);
     /* flush context entry will implicitly flush write buffer */
     return 0;
@@ -352,7 +334,6 @@ static int flush_iotlb_reg(void *_iommu,
     int tlb_offset = ecap_iotlb_offset(iommu->ecap);
     u64 val = 0, val_iva = 0;
     unsigned long flag;
-    s_time_t start_time;
 
     /*
      * In the non-present entry flush case, if hardware doesn't cache
@@ -399,17 +380,8 @@ static int flush_iotlb_reg(void *_iommu,
     dmar_writeq(iommu->reg, tlb_offset + 8, val);
 
     /* Make sure hardware complete it */
-    start_time = NOW();
-    for ( ; ; )
-    {
-        val = dmar_readq(iommu->reg, tlb_offset + 8);
-        if ( !(val & DMA_TLB_IVT) )
-            break;
-        if ( NOW() > start_time + DMAR_OPERATION_TIMEOUT )
-            panic("%s: DMAR hardware is malfunctional,"
-                  " please disable IOMMU\n", __func__);
-        cpu_relax();
-    }
+    IOMMU_WAIT_OP(iommu, (tlb_offset + 8), dmar_readq,
+                  !(val & DMA_TLB_IVT), val);
     spin_unlock_irqrestore(&iommu->register_lock, flag);
 
     /* check IOTLB invalidation granularity */
@@ -578,7 +550,6 @@ static int iommu_set_root_entry(struct i
 {
     u32 cmd, sts;
     unsigned long flags;
-    s_time_t start_time;
 
     spin_lock(&iommu->lock);
 
@@ -597,18 +568,8 @@ static int iommu_set_root_entry(struct i
     dmar_writel(iommu->reg, DMAR_GCMD_REG, cmd);
 
     /* Make sure hardware complete it */
-    start_time = NOW();
-    for ( ; ; )
-    {
-        sts = dmar_readl(iommu->reg, DMAR_GSTS_REG);
-        if ( sts & DMA_GSTS_RTPS )
-            break;
-        if ( NOW() > start_time + DMAR_OPERATION_TIMEOUT )
-            panic("%s: DMAR hardware is malfunctional,"
-                  " please disable IOMMU\n", __func__);
-        cpu_relax();
-    }
-
+    IOMMU_WAIT_OP(iommu, DMAR_GSTS_REG, dmar_readl,
+                  (sts & DMA_GSTS_RTPS), sts);
     spin_unlock_irqrestore(&iommu->register_lock, flags);
 
     return 0;
@@ -618,25 +579,16 @@ static void iommu_enable_translation(str
 {
     u32 sts;
     unsigned long flags;
-    s_time_t start_time;
 
     dprintk(XENLOG_INFO VTDPREFIX,
             "iommu_enable_translation: iommu->reg = %p\n", iommu->reg);
     spin_lock_irqsave(&iommu->register_lock, flags);
     iommu->gcmd |= DMA_GCMD_TE;
     dmar_writel(iommu->reg, DMAR_GCMD_REG, iommu->gcmd);
+
     /* Make sure hardware complete it */
-    start_time = NOW();
-    for ( ; ; )
-    {
-        sts = dmar_readl(iommu->reg, DMAR_GSTS_REG);
-        if ( sts & DMA_GSTS_TES )
-            break;
-        if ( NOW() > start_time + DMAR_OPERATION_TIMEOUT )
-            panic("%s: DMAR hardware is malfunctional,"
-                  " please disable IOMMU\n", __func__);
-        cpu_relax();
-    }
+    IOMMU_WAIT_OP(iommu, DMAR_GSTS_REG, dmar_readl,
+                  (sts & DMA_GSTS_TES), sts);
 
     /* Disable PMRs when VT-d engine takes effect per spec definition */
     disable_pmr(iommu);
@@ -647,24 +599,14 @@ static void iommu_disable_translation(st
 {
     u32 sts;
     unsigned long flags;
-    s_time_t start_time;
 
     spin_lock_irqsave(&iommu->register_lock, flags);
     iommu->gcmd &= ~ DMA_GCMD_TE;
     dmar_writel(iommu->reg, DMAR_GCMD_REG, iommu->gcmd);
 
     /* Make sure hardware complete it */
-    start_time = NOW();
-    for ( ; ; )
-    {
-        sts = dmar_readl(iommu->reg, DMAR_GSTS_REG);
-        if ( !(sts & DMA_GSTS_TES) )
-            break;
-        if ( NOW() > start_time + DMAR_OPERATION_TIMEOUT )
-            panic("%s: DMAR hardware is malfunctional,"
-                  " please disable IOMMU\n", __func__);
-        cpu_relax();
-    }
+    IOMMU_WAIT_OP(iommu, DMAR_GSTS_REG, dmar_readl,
+                  !(sts & DMA_GSTS_TES), sts);
     spin_unlock_irqrestore(&iommu->register_lock, flags);
 }
 
diff -r 931dbe86e5f3 -r a69daf23602a xen/drivers/passthrough/vtd/qinval.c
--- a/xen/drivers/passthrough/vtd/qinval.c      Fri Jun 05 09:26:39 2009 +0100
+++ b/xen/drivers/passthrough/vtd/qinval.c      Fri Jun 05 09:27:18 2009 +0100
@@ -418,9 +418,9 @@ static int flush_iotlb_qi(
 
 int enable_qinval(struct iommu *iommu)
 {
-    s_time_t start_time;
     struct qi_ctrl *qi_ctrl;
     struct iommu_flush *flush;
+    u32 sts;
 
     qi_ctrl = iommu_qi_ctrl(iommu);
     flush = iommu_get_flush(iommu);
@@ -458,13 +458,8 @@ int enable_qinval(struct iommu *iommu)
     dmar_writel(iommu->reg, DMAR_GCMD_REG, iommu->gcmd);
 
     /* Make sure hardware complete it */
-    start_time = NOW();
-    while ( !(dmar_readl(iommu->reg, DMAR_GSTS_REG) & DMA_GSTS_QIES) )
-    {
-        if ( NOW() > (start_time + DMAR_OPERATION_TIMEOUT) )
-            panic("Cannot set QIE field for queue invalidation\n");
-        cpu_relax();
-    }
+    IOMMU_WAIT_OP(iommu, DMAR_GSTS_REG, dmar_readl,
+                  (sts & DMA_GSTS_QIES), sts);
 
     qinval_enabled = 1;
     return 0;
@@ -472,7 +467,7 @@ int enable_qinval(struct iommu *iommu)
 
 void disable_qinval(struct iommu *iommu)
 {
-    s_time_t start_time;
+    u32 sts;
 
     ASSERT(ecap_queued_inval(iommu->ecap) && iommu_qinval);
 
@@ -480,11 +475,6 @@ void disable_qinval(struct iommu *iommu)
     dmar_writel(iommu->reg, DMAR_GCMD_REG, iommu->gcmd);
 
     /* Make sure hardware complete it */
-    start_time = NOW();
-    while ( dmar_readl(iommu->reg, DMAR_GSTS_REG) & DMA_GSTS_QIES )
-    {
-        if ( NOW() > (start_time + DMAR_OPERATION_TIMEOUT) )
-            panic("Cannot clear QIE field for queue invalidation\n");
-        cpu_relax();
-    }
-}
+    IOMMU_WAIT_OP(iommu, DMAR_GSTS_REG, dmar_readl,
+                  !(sts & DMA_GSTS_QIES), sts);
+}
diff -r 931dbe86e5f3 -r a69daf23602a xen/drivers/passthrough/vtd/utils.c
--- a/xen/drivers/passthrough/vtd/utils.c       Fri Jun 05 09:26:39 2009 +0100
+++ b/xen/drivers/passthrough/vtd/utils.c       Fri Jun 05 09:27:18 2009 +0100
@@ -38,27 +38,16 @@ int is_usb_device(u8 bus, u8 devfn)
 /* Disable vt-d protected memory registers. */
 void disable_pmr(struct iommu *iommu)
 {
-    s_time_t start_time;
-    unsigned int val;
+    u32 val;
 
     val = dmar_readl(iommu->reg, DMAR_PMEN_REG);
     if ( !(val & DMA_PMEN_PRS) )
         return;
 
     dmar_writel(iommu->reg, DMAR_PMEN_REG, val & ~DMA_PMEN_EPM);
-    start_time = NOW();
-
-    for ( ; ; )
-    {
-        val = dmar_readl(iommu->reg, DMAR_PMEN_REG);
-        if ( (val & DMA_PMEN_PRS) == 0 )
-            break;
-
-        if ( NOW() > start_time + DMAR_OPERATION_TIMEOUT )
-            panic("Disable PMRs timeout\n");
-
-        cpu_relax();
-    }
+
+    IOMMU_WAIT_OP(iommu, DMAR_PMEN_REG, dmar_readl,
+                  !(val & DMA_PMEN_PRS), val);
 
     dprintk(XENLOG_INFO VTDPREFIX,
             "Disabled protected memory registers\n");

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog

<Prev in Thread] Current Thread [Next in Thread>
  • [Xen-changelog] [xen-unstable] VT-d: define a macro for waiting hardare completion, Xen patchbot-unstable <=