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

[xen master] xen/arm: p2m: Use the pa_range_info table to support arm32 and arm64



commit 6d44fb48bd19c140f8601b645ea2a92895ce4ca9
Author:     Ayan Kumar Halder <ayan.kumar.halder@xxxxxxx>
AuthorDate: Fri Jun 2 13:07:50 2023 +0100
Commit:     Julien Grall <jgrall@xxxxxxxxxx>
CommitDate: Fri Jun 16 21:36:35 2023 +0100

    xen/arm: p2m: Use the pa_range_info table to support arm32 and arm64
    
    Restructure the code so that one can use pa_range_info[] table for both
    arm32 as well as arm64.
    
    Also, removed the hardcoding for P2M_ROOT_ORDER and P2M_ROOT_LEVEL as
    p2m_root_order can be obtained from the pa_range_info[].root_order and
    p2m_root_level can be obtained from pa_range_info[].sl0.
    
    Refer ARM DDI 0406C.d ID040418, B3-1345,
    "Use of concatenated first-level translation tables
    
    ...However, a 40-bit input address range with a translation granularity of 
4KB
    requires a total of 28 bits of address resolution. Therefore, a stage 2
    translation that supports a 40-bit input address range requires two 
concatenated
    first-level translation tables,..."
    
    Thus, root-order is 1 for 40-bit IPA on arm32.
    
    Refer ARM DDI 0406C.d ID040418, B3-1348,
    
    "Determining the required first lookup level for stage 2 translations
    
    For a stage 2 translation, the output address range from the stage 1
    translations determines the required input address range for the stage 2
    translation. The permitted values of VTCR.SL0 are:
    
    0b00 Stage 2 translation lookup must start at the second level.
    0b01 Stage 2 translation lookup must start at the first level.
    
    VTCR.T0SZ must indicate the required input address range. The size of the 
input
    address region is 2^(32-T0SZ) bytes."
    
    Thus VTCR.SL0 = 1 (maximum value) and VTCR.T0SZ = -8 when the size of input
    address region is 2^40 bytes.
    
    Thus, pa_range_info[].t0sz = 1 (VTCR.S) | 8 (VTCR.T0SZ) ie 11000b which is 
24.
    
    VTCR.T0SZ, is bits [5:0] for arm64.
    VTCR.T0SZ is bits [3:0] and S(sign extension), bit[4] for arm32.
    
    For this, we have used struct bitfields to convert pa_range_info[].t0sz to 
its
    arm32 variant.
    
    pa_range_info[] is indexed by ID_AA64MMFR0_EL1.PARange which is present in 
Arm64
    only. This is the reason we do not specify the indices for arm32. Also, we
    duplicated the entry "{ 40,      24/*24*/,  1,          1 }" between arm64 
and
    arm32. This is done to avoid introducing extra #if-defs.
    
    Signed-off-by: Ayan Kumar Halder <ayan.kumar.halder@xxxxxxx>
    Reviewed-by: Michal Orzel <michal.orzel@xxxxxxx>
    [julien: Tweak some comments and one check]
    Acked-by: Julien Grall <jgrall@xxxxxxxxxx>
---
 xen/arch/arm/include/asm/p2m.h |  6 ------
 xen/arch/arm/p2m.c             | 45 +++++++++++++++++++++++++++++-------------
 2 files changed, 31 insertions(+), 20 deletions(-)

diff --git a/xen/arch/arm/include/asm/p2m.h b/xen/arch/arm/include/asm/p2m.h
index f67e9ddc72..940495d42b 100644
--- a/xen/arch/arm/include/asm/p2m.h
+++ b/xen/arch/arm/include/asm/p2m.h
@@ -14,16 +14,10 @@
 /* Holds the bit size of IPAs in p2m tables.  */
 extern unsigned int p2m_ipa_bits;
 
-#ifdef CONFIG_ARM_64
 extern unsigned int p2m_root_order;
 extern unsigned int p2m_root_level;
 #define P2M_ROOT_ORDER    p2m_root_order
 #define P2M_ROOT_LEVEL p2m_root_level
-#else
-/* First level P2M is always 2 consecutive pages */
-#define P2M_ROOT_ORDER    1
-#define P2M_ROOT_LEVEL 1
-#endif
 
 struct domain;
 
diff --git a/xen/arch/arm/p2m.c b/xen/arch/arm/p2m.c
index 418997843d..d671a39457 100644
--- a/xen/arch/arm/p2m.c
+++ b/xen/arch/arm/p2m.c
@@ -19,9 +19,9 @@
 
 #define INVALID_VMID 0 /* VMID 0 is reserved */
 
-#ifdef CONFIG_ARM_64
 unsigned int __read_mostly p2m_root_order;
 unsigned int __read_mostly p2m_root_level;
+#ifdef CONFIG_ARM_64
 static unsigned int __read_mostly max_vmid = MAX_VMID_8_BIT;
 /* VMID is by default 8 bit width on AArch64 */
 #define MAX_VMID       max_vmid
@@ -2247,16 +2247,6 @@ void __init setup_virt_paging(void)
     /* Setup Stage 2 address translation */
     register_t val = VTCR_RES1|VTCR_SH0_IS|VTCR_ORGN0_WBWA|VTCR_IRGN0_WBWA;
 
-#ifdef CONFIG_ARM_32
-    if ( p2m_ipa_bits < 40 )
-        panic("P2M: Not able to support %u-bit IPA at the moment\n",
-              p2m_ipa_bits);
-
-    printk("P2M: 40-bit IPA\n");
-    p2m_ipa_bits = 40;
-    val |= VTCR_T0SZ(0x18); /* 40 bit IPA */
-    val |= VTCR_SL0(0x1); /* P2M starts at first level */
-#else /* CONFIG_ARM_64 */
     static const struct {
         unsigned int pabits; /* Physical Address Size */
         unsigned int t0sz;   /* Desired T0SZ, minimum in comment */
@@ -2265,6 +2255,7 @@ void __init setup_virt_paging(void)
     } pa_range_info[] __initconst = {
         /* T0SZ minimum and SL0 maximum from ARM DDI 0487H.a Table D5-6 */
         /*      PA size, t0sz(min), root-order, sl0(max) */
+#ifdef CONFIG_ARM_64
         [0] = { 32,      32/*32*/,  0,          1 },
         [1] = { 36,      28/*28*/,  0,          1 },
         [2] = { 40,      24/*24*/,  1,          1 },
@@ -2273,11 +2264,27 @@ void __init setup_virt_paging(void)
         [5] = { 48,      16/*16*/,  0,          2 },
         [6] = { 52,      12/*12*/,  4,          2 },
         [7] = { 0 }  /* Invalid */
+#else
+        { 40,      24/*24*/,  1,          1 }
+#endif
     };
 
     unsigned int i;
     unsigned int pa_range = 0x10; /* Larger than any possible value */
 
+#ifdef CONFIG_ARM_32
+    /*
+     * Typecast pa_range_info[].t0sz into arm32 bit variant.
+     *
+     * VTCR.T0SZ is bits [3:0] and S(sign extension), bit[4] for arm322.
+     * Thus, pa_range_info[].t0sz is translated to its arm32 variant using
+     * struct bitfields.
+     */
+    struct
+    {
+        signed int val:5;
+    } t0sz_32;
+#else
     /*
      * Restrict "p2m_ipa_bits" if needed. As P2M table is always configured
      * with IPA bits == PA bits, compare against "pabits".
@@ -2291,6 +2298,7 @@ void __init setup_virt_paging(void)
      */
     if ( system_cpuinfo.mm64.vmid_bits == MM64_VMID_16_BITS_SUPPORT )
         max_vmid = MAX_VMID_16_BIT;
+#endif
 
     /* Choose suitable "pa_range" according to the resulted "p2m_ipa_bits". */
     for ( i = 0; i < ARRAY_SIZE(pa_range_info); i++ )
@@ -2302,28 +2310,37 @@ void __init setup_virt_paging(void)
         }
     }
 
-    /* pa_range is 4 bits but we don't support all modes */
+    /* Check if we found the associated entry in the array */
     if ( pa_range >= ARRAY_SIZE(pa_range_info) || 
!pa_range_info[pa_range].pabits )
-        panic("Unknown encoding of ID_AA64MMFR0_EL1.PARange %x\n", pa_range);
+        panic("%u-bit P2M is not supported\n", p2m_ipa_bits);
 
+#ifdef CONFIG_ARM_64
     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_16_BIT )
         val |= VTCR_VS;
+#endif
+
     val |= VTCR_SL0(pa_range_info[pa_range].sl0);
     val |= VTCR_T0SZ(pa_range_info[pa_range].t0sz);
 
     p2m_root_order = pa_range_info[pa_range].root_order;
     p2m_root_level = 2 - pa_range_info[pa_range].sl0;
+
+#ifdef CONFIG_ARM_64
     p2m_ipa_bits = 64 - pa_range_info[pa_range].t0sz;
+#else
+    t0sz_32.val = pa_range_info[pa_range].t0sz;
+    p2m_ipa_bits = 32 - t0sz_32.val;
+#endif
 
     printk("P2M: %d-bit IPA with %d-bit PA and %d-bit VMID\n",
            p2m_ipa_bits,
            pa_range_info[pa_range].pabits,
            ( MAX_VMID == MAX_VMID_16_BIT ) ? 16 : 8);
-#endif
+
     printk("P2M: %d levels with order-%d root, VTCR 0x%"PRIregister"\n",
            4 - P2M_ROOT_LEVEL, P2M_ROOT_ORDER, val);
 
--
generated by git-patchbot for /home/xen/git/xen.git#master



 


Rackspace

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