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: correct way to submit command to GC

To: xen-changelog@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-changelog] [xen-unstable] VT-d: correct way to submit command to GCMD register
From: Xen patchbot-unstable <patchbot-unstable@xxxxxxxxxxxxxxxxxxx>
Date: Fri, 05 Jun 2009 19:15:19 -0700
Delivery-date: Fri, 05 Jun 2009 19:15:45 -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 1244190582 -3600
# Node ID 4fb8a6c993e21e18b5eefddd6d5df20e7f8c7848
# Parent  a69daf23602a8b7f41a7dc304c7050def59597c7
VT-d: correct way to submit command to GCMD register

Per VT-d spec, software should submit only one "incremental" command
at a time to Global Command reigster. Current implementation uses a
variable (gcmd) to record the state of Global Status register. It's
error prone.

Signed-off-by: Weidong Han <weidong.han@xxxxxxxxx>
---
 xen/drivers/passthrough/vtd/intremap.c |   19 ++++++++++---------
 xen/drivers/passthrough/vtd/iommu.c    |   19 ++++++++++---------
 xen/drivers/passthrough/vtd/qinval.c   |    8 ++++----
 xen/include/xen/iommu.h                |    1 -
 4 files changed, 24 insertions(+), 23 deletions(-)

diff -r a69daf23602a -r 4fb8a6c993e2 xen/drivers/passthrough/vtd/intremap.c
--- a/xen/drivers/passthrough/vtd/intremap.c    Fri Jun 05 09:27:18 2009 +0100
+++ b/xen/drivers/passthrough/vtd/intremap.c    Fri Jun 05 09:29:42 2009 +0100
@@ -534,7 +534,7 @@ int enable_intremap(struct iommu *iommu)
 int enable_intremap(struct iommu *iommu)
 {
     struct ir_ctrl *ir_ctrl;
-    u32 sts;
+    u32 sts, gcmd;
 
     ASSERT(ecap_intr_remap(iommu->ecap) && iommu_intremap);
 
@@ -561,22 +561,23 @@ int enable_intremap(struct iommu *iommu)
     dmar_writeq(iommu->reg, DMAR_IRTA_REG, ir_ctrl->iremap_maddr);
 
     /* set SIRTP */
-    iommu->gcmd |= DMA_GCMD_SIRTP;
-    dmar_writel(iommu->reg, DMAR_GCMD_REG, iommu->gcmd);
+    gcmd = dmar_readl(iommu->reg, DMAR_GSTS_REG);
+    gcmd |= DMA_GCMD_SIRTP;
+    dmar_writel(iommu->reg, DMAR_GCMD_REG, gcmd);
 
     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);
+    gcmd |= DMA_GCMD_CFI;
+    dmar_writel(iommu->reg, DMAR_GCMD_REG, gcmd);
 
     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);
+    gcmd |= DMA_GCMD_IRE;
+    dmar_writel(iommu->reg, DMAR_GCMD_REG, gcmd);
 
     IOMMU_WAIT_OP(iommu, DMAR_GSTS_REG, dmar_readl,
                   (sts & DMA_GSTS_IRES), sts);
@@ -593,8 +594,8 @@ void disable_intremap(struct iommu *iomm
 
     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);
+    sts = dmar_readl(iommu->reg, DMAR_GSTS_REG);
+    dmar_writel(iommu->reg, DMAR_GCMD_REG, sts & (~DMA_GCMD_IRE));
 
     IOMMU_WAIT_OP(iommu, DMAR_GSTS_REG, dmar_readl,
                   !(sts & DMA_GSTS_IRES), sts);
diff -r a69daf23602a -r 4fb8a6c993e2 xen/drivers/passthrough/vtd/iommu.c
--- a/xen/drivers/passthrough/vtd/iommu.c       Fri Jun 05 09:27:18 2009 +0100
+++ b/xen/drivers/passthrough/vtd/iommu.c       Fri Jun 05 09:29:42 2009 +0100
@@ -233,10 +233,10 @@ static void iommu_flush_write_buffer(str
 
     if ( !rwbf_quirk && !cap_rwbf(iommu->cap) )
         return;
-    val = iommu->gcmd | DMA_GCMD_WBF;
 
     spin_lock_irqsave(&iommu->register_lock, flag);
-    dmar_writel(iommu->reg, DMAR_GCMD_REG, val);
+    val = dmar_readl(iommu->reg, DMAR_GSTS_REG);
+    dmar_writel(iommu->reg, DMAR_GCMD_REG, val | DMA_GCMD_WBF);
 
     /* Make sure hardware complete it */
     IOMMU_WAIT_OP(iommu, DMAR_GSTS_REG, dmar_readl,
@@ -548,7 +548,7 @@ static void iommu_free_pagetable(u64 pt_
 
 static int iommu_set_root_entry(struct iommu *iommu)
 {
-    u32 cmd, sts;
+    u32 sts;
     unsigned long flags;
 
     spin_lock(&iommu->lock);
@@ -564,8 +564,9 @@ static int iommu_set_root_entry(struct i
     spin_unlock(&iommu->lock);
     spin_lock_irqsave(&iommu->register_lock, flags);
     dmar_writeq(iommu->reg, DMAR_RTADDR_REG, iommu->root_maddr);
-    cmd = iommu->gcmd | DMA_GCMD_SRTP;
-    dmar_writel(iommu->reg, DMAR_GCMD_REG, cmd);
+
+    sts = dmar_readl(iommu->reg, DMAR_GSTS_REG);
+    dmar_writel(iommu->reg, DMAR_GCMD_REG, sts | DMA_GCMD_SRTP);
 
     /* Make sure hardware complete it */
     IOMMU_WAIT_OP(iommu, DMAR_GSTS_REG, dmar_readl,
@@ -583,8 +584,8 @@ static void iommu_enable_translation(str
     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);
+    sts = dmar_readl(iommu->reg, DMAR_GSTS_REG);
+    dmar_writel(iommu->reg, DMAR_GCMD_REG, sts | DMA_GCMD_TE);
 
     /* Make sure hardware complete it */
     IOMMU_WAIT_OP(iommu, DMAR_GSTS_REG, dmar_readl,
@@ -601,8 +602,8 @@ static void iommu_disable_translation(st
     unsigned long flags;
 
     spin_lock_irqsave(&iommu->register_lock, flags);
-    iommu->gcmd &= ~ DMA_GCMD_TE;
-    dmar_writel(iommu->reg, DMAR_GCMD_REG, iommu->gcmd);
+    sts = dmar_readl(iommu->reg, DMAR_GSTS_REG);
+    dmar_writel(iommu->reg, DMAR_GCMD_REG, sts & (~DMA_GCMD_TE));
 
     /* Make sure hardware complete it */
     IOMMU_WAIT_OP(iommu, DMAR_GSTS_REG, dmar_readl,
diff -r a69daf23602a -r 4fb8a6c993e2 xen/drivers/passthrough/vtd/qinval.c
--- a/xen/drivers/passthrough/vtd/qinval.c      Fri Jun 05 09:27:18 2009 +0100
+++ b/xen/drivers/passthrough/vtd/qinval.c      Fri Jun 05 09:29:42 2009 +0100
@@ -454,8 +454,8 @@ int enable_qinval(struct iommu *iommu)
     dmar_writeq(iommu->reg, DMAR_IQT_REG, 0);
 
     /* enable queued invalidation hardware */
-    iommu->gcmd |= DMA_GCMD_QIE;
-    dmar_writel(iommu->reg, DMAR_GCMD_REG, iommu->gcmd);
+    sts = dmar_readl(iommu->reg, DMAR_GSTS_REG);
+    dmar_writel(iommu->reg, DMAR_GCMD_REG, sts | DMA_GCMD_QIE);
 
     /* Make sure hardware complete it */
     IOMMU_WAIT_OP(iommu, DMAR_GSTS_REG, dmar_readl,
@@ -471,8 +471,8 @@ void disable_qinval(struct iommu *iommu)
 
     ASSERT(ecap_queued_inval(iommu->ecap) && iommu_qinval);
 
-    iommu->gcmd &= ~DMA_GCMD_QIE;
-    dmar_writel(iommu->reg, DMAR_GCMD_REG, iommu->gcmd);
+    sts = dmar_readl(iommu->reg, DMAR_GSTS_REG);
+    dmar_writel(iommu->reg, DMAR_GCMD_REG, sts & (~DMA_GCMD_QIE));
 
     /* Make sure hardware complete it */
     IOMMU_WAIT_OP(iommu, DMAR_GSTS_REG, dmar_readl,
diff -r a69daf23602a -r 4fb8a6c993e2 xen/include/xen/iommu.h
--- a/xen/include/xen/iommu.h   Fri Jun 05 09:27:18 2009 +0100
+++ b/xen/include/xen/iommu.h   Fri Jun 05 09:29:42 2009 +0100
@@ -47,7 +47,6 @@ struct iommu {
     struct list_head list;
     void __iomem *reg; /* Pointer to hardware regs, virtual addr */
     u32        index;         /* Sequence number of iommu */
-    u32        gcmd;          /* Holds TE, EAFL. Don't need SRTP, SFL, WBF */
     u32 nr_pt_levels;
     u64        cap;
     u64        ecap;

_______________________________________________
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: correct way to submit command to GCMD register, Xen patchbot-unstable <=