All of lore.kernel.org
 help / color / mirror / Atom feed
From: Jan Beulich <JBeulich@suse.com>
To: "xen-devel@lists.xenproject.org" <xen-devel@lists.xenproject.org>
Cc: Andrew Cooper <andrew.cooper3@citrix.com>,
	Brian Woods <brian.woods@amd.com>,
	Suravee Suthikulpanit <suravee.suthikulpanit@amd.com>
Subject: [Xen-devel] [PATCH v4 03/12] AMD/IOMMU: use bit field for IRTE
Date: Thu, 25 Jul 2019 13:30:10 +0000	[thread overview]
Message-ID: <12881c67-924c-6c38-9966-5de534a60001@suse.com> (raw)
In-Reply-To: <b8ae110a-f94a-4ed2-5cf9-c00ff1c0cb81@suse.com>

At the same time restrict its scope to just the single source file
actually using it, and abstract accesses by introducing a union of
pointers. (A union of the actual table entries is not used to make it
impossible to [wrongly, once the 128-bit form gets added] perform
pointer arithmetic / array accesses on derived types.)

Also move away from updating the entries piecemeal: Construct a full new
entry, and write it out.

Signed-off-by: Jan Beulich <jbeulich@suse.com>
Acked-by: Andrew Cooper <andrew.cooper3@citrix.com>
Acked-by: Brian Woods <brian.woods@amd.com>
---
v4: Re-base. Do away with standalone struct irte_basic.
v3: Switch boolean bitfields to bool.
v2: name {get,free}_intremap_entry()'s last parameter "index" instead of
     "offset". Introduce union irte32.

--- a/xen/drivers/passthrough/amd/iommu_intr.c
+++ b/xen/drivers/passthrough/amd/iommu_intr.c
@@ -24,6 +24,26 @@
  #include <xen/keyhandler.h>
  #include <xen/softirq.h>
  
+union irte32 {
+    uint32_t raw;
+    struct {
+        bool remap_en:1;
+        bool sup_io_pf:1;
+        unsigned int int_type:3;
+        bool rq_eoi:1;
+        bool dm:1;
+        bool guest_mode:1; /* MBZ */
+        unsigned int dest:8;
+        unsigned int vector:8;
+        unsigned int :8;
+    } flds;
+};
+
+union irte_ptr {
+    void *ptr;
+    union irte32 *ptr32;
+};
+
  #define INTREMAP_TABLE_ORDER    1
  #define INTREMAP_LENGTH 0xB
  #define INTREMAP_ENTRIES (1 << INTREMAP_LENGTH)
@@ -102,47 +122,45 @@ static unsigned int alloc_intremap_entry
      return slot;
  }
  
-static u32 *get_intremap_entry(int seg, int bdf, int offset)
+static union irte_ptr get_intremap_entry(unsigned int seg, unsigned int bdf,
+                                         unsigned int index)
  {
-    u32 *table = get_ivrs_mappings(seg)[bdf].intremap_table;
+    union irte_ptr table = {
+        .ptr = get_ivrs_mappings(seg)[bdf].intremap_table
+    };
+
+    ASSERT(table.ptr && (index < INTREMAP_ENTRIES));
  
-    ASSERT( (table != NULL) && (offset < INTREMAP_ENTRIES) );
+    table.ptr32 += index;
  
-    return table + offset;
+    return table;
  }
  
-static void free_intremap_entry(int seg, int bdf, int offset)
-{
-    u32 *entry = get_intremap_entry(seg, bdf, offset);
-
-    memset(entry, 0, sizeof(u32));
-    __clear_bit(offset, get_ivrs_mappings(seg)[bdf].intremap_inuse);
-}
-
-static void update_intremap_entry(u32* entry, u8 vector, u8 int_type,
-    u8 dest_mode, u8 dest)
-{
-    set_field_in_reg_u32(IOMMU_CONTROL_ENABLED, 0,
-                            INT_REMAP_ENTRY_REMAPEN_MASK,
-                            INT_REMAP_ENTRY_REMAPEN_SHIFT, entry);
-    set_field_in_reg_u32(IOMMU_CONTROL_DISABLED, *entry,
-                            INT_REMAP_ENTRY_SUPIOPF_MASK,
-                            INT_REMAP_ENTRY_SUPIOPF_SHIFT, entry);
-    set_field_in_reg_u32(int_type, *entry,
-                            INT_REMAP_ENTRY_INTTYPE_MASK,
-                            INT_REMAP_ENTRY_INTTYPE_SHIFT, entry);
-    set_field_in_reg_u32(IOMMU_CONTROL_DISABLED, *entry,
-                            INT_REMAP_ENTRY_REQEOI_MASK,
-                            INT_REMAP_ENTRY_REQEOI_SHIFT, entry);
-    set_field_in_reg_u32((u32)dest_mode, *entry,
-                            INT_REMAP_ENTRY_DM_MASK,
-                            INT_REMAP_ENTRY_DM_SHIFT, entry);
-    set_field_in_reg_u32((u32)dest, *entry,
-                            INT_REMAP_ENTRY_DEST_MAST,
-                            INT_REMAP_ENTRY_DEST_SHIFT, entry);
-    set_field_in_reg_u32((u32)vector, *entry,
-                            INT_REMAP_ENTRY_VECTOR_MASK,
-                            INT_REMAP_ENTRY_VECTOR_SHIFT, entry);
+static void free_intremap_entry(unsigned int seg, unsigned int bdf,
+                                unsigned int index)
+{
+    union irte_ptr entry = get_intremap_entry(seg, bdf, index);
+
+    ACCESS_ONCE(entry.ptr32->raw) = 0;
+
+    __clear_bit(index, get_ivrs_mappings(seg)[bdf].intremap_inuse);
+}
+
+static void update_intremap_entry(union irte_ptr entry, unsigned int vector,
+                                  unsigned int int_type,
+                                  unsigned int dest_mode, unsigned int dest)
+{
+    union irte32 irte = {
+        .flds = {
+            .remap_en = true,
+            .int_type = int_type,
+            .dm = dest_mode,
+            .dest = dest,
+            .vector = vector,
+        },
+    };
+
+    ACCESS_ONCE(entry.ptr32->raw) = irte.raw;
  }
  
  static inline int get_rte_index(const struct IO_APIC_route_entry *rte)
@@ -164,7 +182,7 @@ static int update_intremap_entry_from_io
      u16 *index)
  {
      unsigned long flags;
-    u32* entry;
+    union irte_ptr entry;
      u8 delivery_mode, dest, vector, dest_mode;
      int req_id;
      spinlock_t *lock;
@@ -202,12 +220,8 @@ static int update_intremap_entry_from_io
           * so need to recover vector and delivery mode from IRTE.
           */
          ASSERT(get_rte_index(rte) == offset);
-        vector = get_field_from_reg_u32(*entry,
-                                        INT_REMAP_ENTRY_VECTOR_MASK,
-                                        INT_REMAP_ENTRY_VECTOR_SHIFT);
-        delivery_mode = get_field_from_reg_u32(*entry,
-                                               INT_REMAP_ENTRY_INTTYPE_MASK,
-                                               INT_REMAP_ENTRY_INTTYPE_SHIFT);
+        vector = entry.ptr32->flds.vector;
+        delivery_mode = entry.ptr32->flds.int_type;
      }
      update_intremap_entry(entry, vector, delivery_mode, dest_mode, dest);
  
@@ -229,7 +243,7 @@ int __init amd_iommu_setup_ioapic_remapp
  {
      struct IO_APIC_route_entry rte;
      unsigned long flags;
-    u32* entry;
+    union irte_ptr entry;
      int apic, pin;
      u8 delivery_mode, dest, vector, dest_mode;
      u16 seg, bdf, req_id;
@@ -408,16 +422,14 @@ unsigned int amd_iommu_read_ioapic_from_
          u16 bdf = ioapic_sbdf[idx].bdf;
          u16 seg = ioapic_sbdf[idx].seg;
          u16 req_id = get_intremap_requestor_id(seg, bdf);
-        const u32 *entry = get_intremap_entry(seg, req_id, offset);
+        union irte_ptr entry = get_intremap_entry(seg, req_id, offset);
  
          ASSERT(offset == (val & (INTREMAP_ENTRIES - 1)));
          val &= ~(INTREMAP_ENTRIES - 1);
-        val |= get_field_from_reg_u32(*entry,
-                                      INT_REMAP_ENTRY_INTTYPE_MASK,
-                                      INT_REMAP_ENTRY_INTTYPE_SHIFT) << 8;
-        val |= get_field_from_reg_u32(*entry,
-                                      INT_REMAP_ENTRY_VECTOR_MASK,
-                                      INT_REMAP_ENTRY_VECTOR_SHIFT);
+        val |= MASK_INSR(entry.ptr32->flds.int_type,
+                         IO_APIC_REDIR_DELIV_MODE_MASK);
+        val |= MASK_INSR(entry.ptr32->flds.vector,
+                         IO_APIC_REDIR_VECTOR_MASK);
      }
  
      return val;
@@ -428,7 +440,7 @@ static int update_intremap_entry_from_ms
      int *remap_index, const struct msi_msg *msg, u32 *data)
  {
      unsigned long flags;
-    u32* entry;
+    union irte_ptr entry;
      u16 req_id, alias_id;
      u8 delivery_mode, dest, vector, dest_mode;
      spinlock_t *lock;
@@ -582,7 +594,7 @@ void amd_iommu_read_msi_from_ire(
      const struct pci_dev *pdev = msi_desc->dev;
      u16 bdf = pdev ? PCI_BDF2(pdev->bus, pdev->devfn) : hpet_sbdf.bdf;
      u16 seg = pdev ? pdev->seg : hpet_sbdf.seg;
-    const u32 *entry;
+    union irte_ptr entry;
  
      if ( IS_ERR_OR_NULL(_find_iommu_for_device(seg, bdf)) )
          return;
@@ -598,12 +610,10 @@ void amd_iommu_read_msi_from_ire(
      }
  
      msg->data &= ~(INTREMAP_ENTRIES - 1);
-    msg->data |= get_field_from_reg_u32(*entry,
-                                        INT_REMAP_ENTRY_INTTYPE_MASK,
-                                        INT_REMAP_ENTRY_INTTYPE_SHIFT) << 8;
-    msg->data |= get_field_from_reg_u32(*entry,
-                                        INT_REMAP_ENTRY_VECTOR_MASK,
-                                        INT_REMAP_ENTRY_VECTOR_SHIFT);
+    msg->data |= MASK_INSR(entry.ptr32->flds.int_type,
+                           MSI_DATA_DELIVERY_MODE_MASK);
+    msg->data |= MASK_INSR(entry.ptr32->flds.vector,
+                           MSI_DATA_VECTOR_MASK);
  }
  
  int __init amd_iommu_free_intremap_table(
--- a/xen/include/asm-x86/hvm/svm/amd-iommu-defs.h
+++ b/xen/include/asm-x86/hvm/svm/amd-iommu-defs.h
@@ -469,22 +469,6 @@ struct amd_iommu_pte {
  #define IOMMU_CONTROL_DISABLED	0
  #define IOMMU_CONTROL_ENABLED	1
  
-/* interrupt remapping table */
-#define INT_REMAP_ENTRY_REMAPEN_MASK    0x00000001
-#define INT_REMAP_ENTRY_REMAPEN_SHIFT   0
-#define INT_REMAP_ENTRY_SUPIOPF_MASK    0x00000002
-#define INT_REMAP_ENTRY_SUPIOPF_SHIFT   1
-#define INT_REMAP_ENTRY_INTTYPE_MASK    0x0000001C
-#define INT_REMAP_ENTRY_INTTYPE_SHIFT   2
-#define INT_REMAP_ENTRY_REQEOI_MASK     0x00000020
-#define INT_REMAP_ENTRY_REQEOI_SHIFT    5
-#define INT_REMAP_ENTRY_DM_MASK         0x00000040
-#define INT_REMAP_ENTRY_DM_SHIFT        6
-#define INT_REMAP_ENTRY_DEST_MAST       0x0000FF00
-#define INT_REMAP_ENTRY_DEST_SHIFT      8
-#define INT_REMAP_ENTRY_VECTOR_MASK     0x00FF0000
-#define INT_REMAP_ENTRY_VECTOR_SHIFT    16
-
  #define INV_IOMMU_ALL_PAGES_ADDRESS      ((1ULL << 63) - 1)
  
  #define IOMMU_RING_BUFFER_PTR_MASK                  0x0007FFF0

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

  parent reply	other threads:[~2019-07-25 13:32 UTC|newest]

Thread overview: 23+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-07-25 13:19 [Xen-devel] [PATCH v4 00/12] x86: AMD x2APIC support / AMD IOMMU improvements Jan Beulich
2019-07-25 13:29 ` [Xen-devel] [PATCH v4 01/12] AMD/IOMMU: use bit field for extended feature register Jan Beulich
2019-07-30  9:14   ` [Xen-devel] Ping: " Jan Beulich
2019-07-30 16:35   ` [Xen-devel] " Woods, Brian
2019-07-25 13:29 ` [Xen-devel] [PATCH v4 02/12] AMD/IOMMU: use bit field for control register Jan Beulich
2019-07-25 13:30 ` Jan Beulich [this message]
2019-07-25 13:30 ` [Xen-devel] [PATCH v4 04/12] AMD/IOMMU: pass IOMMU to {get, free, update}_intremap_entry() Jan Beulich
2019-07-25 13:31 ` [Xen-devel] [PATCH v4 05/12] AMD/IOMMU: introduce 128-bit IRTE non-guest-APIC IRTE format Jan Beulich
2019-07-30 10:13   ` Andrew Cooper
2019-07-30 16:36   ` Woods, Brian
2019-07-25 13:31 ` [Xen-devel] [PATCH v4 06/12] AMD/IOMMU: split amd_iommu_init_one() Jan Beulich
2019-07-25 13:31 ` [Xen-devel] [PATCH v4 07/12] AMD/IOMMU: allow enabling with IRQ not yet set up Jan Beulich
2019-07-25 13:32 ` [Xen-devel] [PATCH v4 08/12] AMD/IOMMU: adjust setup of internal interrupt for x2APIC mode Jan Beulich
2019-07-25 13:32 ` [Xen-devel] [PATCH v4 09/12] AMD/IOMMU: enable x2APIC mode when available Jan Beulich
2019-07-25 13:33 ` [Xen-devel] [PATCH v4 10/12] AMD/IOMMU: correct IRTE updating Jan Beulich
2019-07-25 14:04   ` Woods, Brian
2019-07-25 13:33 ` [Xen-devel] [PATCH v4 11/12] AMD/IOMMU: don't needlessly log headers when dumping IRTs Jan Beulich
2019-07-30 10:25   ` Andrew Cooper
2019-07-30 16:36   ` Woods, Brian
2019-07-25 13:33 ` [Xen-devel] [PATCH v4 12/12] AMD/IOMMU: miscellaneous DTE handling adjustments Jan Beulich
2019-07-30 13:42   ` Andrew Cooper
2019-07-30 14:10     ` Jan Beulich
2019-08-06 19:41   ` Woods, Brian

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=12881c67-924c-6c38-9966-5de534a60001@suse.com \
    --to=jbeulich@suse.com \
    --cc=andrew.cooper3@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.