All of lore.kernel.org
 help / color / mirror / Atom feed
From: Paul Durrant <paul.durrant@citrix.com>
To: xen-devel@lists.xenproject.org
Cc: Paul Durrant <paul.durrant@citrix.com>,
	Brian Woods <brian.woods@amd.com>,
	Suravee Suthikulpanit <suravee.suthikulpanit@amd.com>
Subject: [PATCH 5/7] amd-iommu: introduce new get/set_iommu_pde_info() functions...
Date: Thu, 20 Sep 2018 15:11:47 +0100	[thread overview]
Message-ID: <20180920141149.1643-6-paul.durrant@citrix.com> (raw)
In-Reply-To: <20180920141149.1643-1-paul.durrant@citrix.com>

...and use set_iommu_pde_info() in set_iommu_pde_present().

set_iommu_pde_info() only sets the address and read/write flags in the PDE,
leaving the (PTE-only) FC bit, level value and presence bit to be
subsequently set by set_iommu_pde_present(). A memory barrier is added to
ensure that the presence bit is last to be set.

A subsequent patch will make further use of get_iommu_pde_info().

Signed-off-by: Paul Durrant <paul.durrant@citrix.com>
---
Cc: Suravee Suthikulpanit <suravee.suthikulpanit@amd.com>
Cc: Brian Woods <brian.woods@amd.com>
---
 xen/drivers/passthrough/amd/iommu_map.c | 88 +++++++++++++++++++++------------
 1 file changed, 56 insertions(+), 32 deletions(-)

diff --git a/xen/drivers/passthrough/amd/iommu_map.c b/xen/drivers/passthrough/amd/iommu_map.c
index a186c8d28b..fecde9d645 100644
--- a/xen/drivers/passthrough/amd/iommu_map.c
+++ b/xen/drivers/passthrough/amd/iommu_map.c
@@ -45,15 +45,10 @@ void clear_iommu_pte_present(unsigned long l1_mfn, unsigned long dfn)
     unmap_domain_page(table);
 }
 
-static bool set_iommu_pde_present(uint32_t *pde, unsigned long next_mfn,
-                                  unsigned int next_level,
-                                  bool iw, bool ir)
+static void get_iommu_pde_info(uint32_t *pde, uint64_t *maddr, bool *iw,
+                               bool *ir)
 {
-    uint64_t addr_lo, addr_hi, maddr_old, maddr_next;
-    uint32_t entry;
-    bool need_flush = false;
-
-    maddr_next = (uint64_t)next_mfn << PAGE_SHIFT;
+    uint64_t addr_lo, addr_hi;
 
     addr_hi = get_field_from_reg_u32(pde[1],
                                      IOMMU_PTE_ADDR_HIGH_MASK,
@@ -61,45 +56,74 @@ static bool set_iommu_pde_present(uint32_t *pde, unsigned long next_mfn,
     addr_lo = get_field_from_reg_u32(pde[0],
                                      IOMMU_PTE_ADDR_LOW_MASK,
                                      IOMMU_PTE_ADDR_LOW_SHIFT);
+    *maddr = (addr_hi << 32) | (addr_lo << PAGE_SHIFT);
 
-    maddr_old = (addr_hi << 32) | (addr_lo << PAGE_SHIFT);
+    if ( iw )
+        *iw = !!get_field_from_reg_u32(pde[1],
+                                       IOMMU_PDE_IO_WRITE_PERMISSION_MASK,
+                                       IOMMU_PDE_IO_WRITE_PERMISSION_SHIFT);
+
+    if ( ir )
+        *ir = !!get_field_from_reg_u32(pde[1],
+                                       IOMMU_PDE_IO_READ_PERMISSION_MASK,
+                                       IOMMU_PDE_IO_READ_PERMISSION_SHIFT);
+}
+
+static bool set_iommu_pde_info(uint32_t *pde, uint64_t maddr, bool iw,
+                               bool ir)
+{
+    uint64_t addr_lo, addr_hi, maddr_old;
 
-    if ( maddr_old != maddr_next )
-        need_flush = 1;
+    get_iommu_pde_info(pde, &maddr_old, NULL, NULL);
 
-    addr_lo = maddr_next & DMA_32BIT_MASK;
-    addr_hi = maddr_next >> 32;
+    addr_lo = (maddr & DMA_32BIT_MASK) >> PAGE_SHIFT;
+    addr_hi = maddr >> 32;
 
-    /* enable read/write permissions,which will be enforced at the PTE */
     set_field_in_reg_u32((uint32_t)addr_hi, 0,
                          IOMMU_PDE_ADDR_HIGH_MASK,
-                         IOMMU_PDE_ADDR_HIGH_SHIFT, &entry);
-    set_field_in_reg_u32(iw, entry,
+                         IOMMU_PDE_ADDR_HIGH_SHIFT, &pde[1]);
+    set_field_in_reg_u32(iw, pde[1],
                          IOMMU_PDE_IO_WRITE_PERMISSION_MASK,
-                         IOMMU_PDE_IO_WRITE_PERMISSION_SHIFT, &entry);
-    set_field_in_reg_u32(ir, entry,
+                         IOMMU_PDE_IO_WRITE_PERMISSION_SHIFT, &pde[1]);
+    set_field_in_reg_u32(ir, pde[1],
                          IOMMU_PDE_IO_READ_PERMISSION_MASK,
-                         IOMMU_PDE_IO_READ_PERMISSION_SHIFT, &entry);
+                         IOMMU_PDE_IO_READ_PERMISSION_SHIFT, &pde[1]);
+    set_field_in_reg_u32((uint32_t)addr_lo, 0,
+                         IOMMU_PDE_ADDR_LOW_MASK,
+                         IOMMU_PDE_ADDR_LOW_SHIFT, &pde[0]);
+
+    return maddr != maddr_old;
+}
+
+static bool set_iommu_pde_present(uint32_t *pde, unsigned long next_mfn,
+                                  unsigned int next_level,
+                                  bool_t iw, bool_t ir)
+{
+    bool need_flush = set_iommu_pde_info(pde, next_mfn << PAGE_SHIFT, iw,
+                                         ir);
 
-    /* FC bit should be enabled in PTE, this helps to solve potential
-     * issues with ATS devices
+    /*
+     * FC bit should be enabled in PTE, this helps to solve potential
+     * issues with ATS devices.
      */
     if ( next_level == IOMMU_PAGING_MODE_LEVEL_0 )
-        set_field_in_reg_u32(IOMMU_CONTROL_ENABLED, entry,
-                             IOMMU_PTE_FC_MASK, IOMMU_PTE_FC_SHIFT, &entry);
-    pde[1] = entry;
+        set_field_in_reg_u32(IOMMU_CONTROL_ENABLED, pde[1],
+                             IOMMU_PTE_FC_MASK, IOMMU_PTE_FC_SHIFT,
+                             &pde[1]);
 
     /* mark next level as 'present' */
-    set_field_in_reg_u32((uint32_t)addr_lo >> PAGE_SHIFT, 0,
-                         IOMMU_PDE_ADDR_LOW_MASK,
-                         IOMMU_PDE_ADDR_LOW_SHIFT, &entry);
-    set_field_in_reg_u32(next_level, entry,
+    set_field_in_reg_u32(next_level, pde[0],
                          IOMMU_PDE_NEXT_LEVEL_MASK,
-                         IOMMU_PDE_NEXT_LEVEL_SHIFT, &entry);
-    set_field_in_reg_u32(IOMMU_CONTROL_ENABLED, entry,
+                         IOMMU_PDE_NEXT_LEVEL_SHIFT, &pde[0]);
+
+    /*
+     * Make sure all other bits are written before the entry is made
+     * present.
+     */
+    smp_mb();
+    set_field_in_reg_u32(IOMMU_CONTROL_ENABLED, pde[0],
                          IOMMU_PDE_PRESENT_MASK,
-                         IOMMU_PDE_PRESENT_SHIFT, &entry);
-    pde[0] = entry;
+                         IOMMU_PDE_PRESENT_SHIFT, &pde[0]);
 
     return need_flush;
 }
-- 
2.11.0


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

  parent reply	other threads:[~2018-09-20 14:14 UTC|newest]

Thread overview: 15+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-09-20 14:11 [PATCH 0/7] amd-iommu: cleanup and add lookup_page method Paul Durrant
2018-09-20 14:11 ` [PATCH 1/7] amd-iommu: don't domain_crash() inside map/unmap_page() Paul Durrant
2018-09-20 14:11 ` [PATCH 2/7] amd-iommu: re-name u8/16/32/64 to uint8/16/32/64_t Paul Durrant
2018-09-20 14:11 ` [PATCH 3/7] amd-iommu: convert all bool_t to bool Paul Durrant
2018-09-20 14:11 ` [PATCH 4/7] amd-iommu: reduce code duplication Paul Durrant
2018-09-20 14:11 ` Paul Durrant [this message]
2018-09-20 14:11 ` [PATCH 6/7] vtd: change lookup_page failure semantics Paul Durrant
2018-09-21  0:58   ` Tian, Kevin
2018-09-21 10:16   ` Jan Beulich
2018-09-21 10:18     ` Paul Durrant
2018-09-21 10:27       ` Jan Beulich
2018-09-21 10:31         ` Paul Durrant
2018-09-20 14:11 ` [PATCH 7/7] amd-iommu: add lookup_page method to iommu_ops Paul Durrant
2018-09-20 15:03   ` Jan Beulich
2018-09-20 15:41     ` Paul Durrant

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20180920141149.1643-6-paul.durrant@citrix.com \
    --to=paul.durrant@citrix.com \
    --cc=brian.woods@amd.com \
    --cc=suravee.suthikulpanit@amd.com \
    --cc=xen-devel@lists.xenproject.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.