[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Xen-devel] [PATCH] xen/arm: Add support for 16 bit VMIDs



Hello Bhupinder,

On 11/11/16 09:06, Bhupinder Thakur wrote:
VMID space is increased to 16-bits from 8-bits in ARMv8 8.1 revision.
This allows more than 256 VMs to be supported by Xen.

This change adds support for 16-bit VMIDs in Xen based on whether the
architecture supports it.

Signed-off-by: Bhupinder Thakur <bhupinder.thakur@xxxxxxxxxx>
---
 xen/arch/arm/p2m.c              | 44 +++++++++++++++++++++++++++++++++++------
 xen/include/asm-arm/p2m.h       |  2 +-
 xen/include/asm-arm/processor.h | 17 +++++++++++++++-
 3 files changed, 55 insertions(+), 8 deletions(-)

diff --git a/xen/arch/arm/p2m.c b/xen/arch/arm/p2m.c
index cc5634b..6ed7e5c 100644
--- a/xen/arch/arm/p2m.c
+++ b/xen/arch/arm/p2m.c
@@ -19,6 +19,7 @@ static unsigned int __read_mostly p2m_root_order;
 static unsigned int __read_mostly p2m_root_level;
 #define P2M_ROOT_ORDER    p2m_root_order
 #define P2M_ROOT_LEVEL p2m_root_level
+static unsigned int __read_mostly max_vmid;
 #else
 /* First level P2M is alway 2 consecutive pages */
 #define P2M_ROOT_LEVEL 1
@@ -1219,7 +1220,7 @@ static int p2m_alloc_table(struct domain *d)

     p2m->root = page;

-    p2m->vttbr = page_to_maddr(p2m->root) | ((uint64_t)p2m->vmid & 0xff) << 48;
+    p2m->vttbr = page_to_maddr(p2m->root) | ((uint64_t)p2m->vmid << 48);

     /*
      * Make sure that all TLBs corresponding to the new VMID are flushed
@@ -1230,20 +1231,47 @@ static int p2m_alloc_table(struct domain *d)
     return 0;
 }

-#define MAX_VMID 256
+#ifdef CONFIG_ARM_64
+#define MAX_VMID  (1UL << 16)
+#else
+#define MAX_VMID (1UL << 8)
+#endif
+
 #define INVALID_VMID 0 /* VMID 0 is reserved */

 static spinlock_t vmid_alloc_lock = SPIN_LOCK_UNLOCKED;

 /*
- * VTTBR_EL2 VMID field is 8 bits. Using a bitmap here limits us to
- * 256 concurrent domains.
+ * VTTBR_EL2 VMID field is 8 or 16 bits. Aarch64 supports 16-bit VMID.
+ * Using a bitmap here limits us to 256 or 65536 (for Aarch64) concurrent
+ * domains.
  */
 static DECLARE_BITMAP(vmid_mask, MAX_VMID);

 void p2m_vmid_allocator_init(void)
 {
+    unsigned int cpu;
+
     set_bit(INVALID_VMID, vmid_mask);
+
+    max_vmid = MAX_VMID;

max_vmid is only declared for ARM64 and will break compilation for ARM32. Please try to build each patch for both architecture before sending to the ML.

However, in this case. It would make more sense to keep the maximum vmid static for ARM32 as it will never change.

I quite like what has been done for P2M_ROOT_{LEVEL,ORDER} where the define is a constant on ARM32 and point to a variable on ARM64.

+
+#ifdef CONFIG_ARM_64
+    /*
+     * if any cpu does not support 16-bit VMID then restrict the
+     * max VMIDs which can be allocated to 256
+     */
+    for_each_online_cpu ( cpu )
+    {
+        const struct cpuinfo_arm *info = &cpu_data[cpu];
+
+        if ( info->mm64.vmid_bits != VMID_16_BITS_SUPPORT )
+        {
+            max_vmid = (1UL << 8);
+            break;
+        }
+    }
+#endif

I would rework this code to have max_vmid set to 8 bits by default and the turn on 16 bits if available on every CPU.

 }

 static int p2m_alloc_vmid(struct domain *d)
@@ -1254,11 +1282,11 @@ static int p2m_alloc_vmid(struct domain *d)

     spin_lock(&vmid_alloc_lock);

-    nr = find_first_zero_bit(vmid_mask, MAX_VMID);
+    nr = find_first_zero_bit(vmid_mask, max_vmid);

     ASSERT(nr != INVALID_VMID);

-    if ( nr == MAX_VMID )
+    if ( nr == max_vmid )
     {
         rc = -EBUSY;
         printk(XENLOG_ERR "p2m.c: dom%d: VMID pool exhausted\n", d->domain_id);
@@ -1646,6 +1674,10 @@ void __init setup_virt_paging(void)

     val |= VTCR_PS(pa_range);
     val |= VTCR_TG0_4K;
+
+    /* set the VS bit only if 16 bit VMID is supported */
+    if ( max_vmid == MAX_VMID )

This check is confusing, I would be clearer to use MAX_VMID_16 or else.

+        val |= VTCR_VS;
     val |= VTCR_SL0(pa_range_info[pa_range].sl0);
     val |= VTCR_T0SZ(pa_range_info[pa_range].t0sz);

diff --git a/xen/include/asm-arm/p2m.h b/xen/include/asm-arm/p2m.h
index fdb6b47..bfcdbf1 100644
--- a/xen/include/asm-arm/p2m.h
+++ b/xen/include/asm-arm/p2m.h
@@ -30,7 +30,7 @@ struct p2m_domain {
     struct page_info *root;

     /* Current VMID in use */
-    uint8_t vmid;
+    uint16_t vmid;

     /* Current Translation Table Base Register for the p2m */
     uint64_t vttbr;
diff --git a/xen/include/asm-arm/processor.h b/xen/include/asm-arm/processor.h
index 15bf890..4b6be3d 100644
--- a/xen/include/asm-arm/processor.h
+++ b/xen/include/asm-arm/processor.h
@@ -215,6 +215,7 @@

 #define VTCR_PS(x)      ((x)<<16)

+#define VTCR_VS        (_AC(0x1,UL)<<19)

Newline here please.

 #endif

 #define VTCR_RES1       (_AC(1,UL)<<31)
@@ -269,6 +270,11 @@
 /* FSR long format */
 #define FSRL_STATUS_DEBUG       (_AC(0x22,UL)<<0)

+#ifdef CONFIG_ARM_64
+#define VMID_8_BITS_SUPPORT         0x0
+#define VMID_16_BITS_SUPPORT        0x2
+#endif

I would prefix the 2 define with MM64_ so we know how the values will be matched.

+
 #ifndef __ASSEMBLY__

 struct cpuinfo_arm {
@@ -337,7 +343,16 @@ struct cpuinfo_arm {
             unsigned long tgranule_64K:4;
             unsigned long tgranule_4K:4;
             unsigned long __res0:32;
-       };
+
+            unsigned long hafdbs:4;
+            unsigned long vmid_bits:4;
+            unsigned long vh:4;
+            unsigned long hpds:4;
+            unsigned long lo:4;
+            unsigned long pan:4;
+            unsigned long __res1:8;
+            unsigned long __res2:32;
+        };
     } mm64;

     struct {


Regards,

--
Julien Grall

_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxx
https://lists.xen.org/xen-devel

 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.