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

[Xen-devel] [PATCH v1 1/2] arm: Add ability to relocate Xen in over 4GB space



From: Iurii Konovalenko <iurii.konovalenko@xxxxxxxxxxxxxxx>

Primary CPU relocate Xen in over 4GB space and wake up seondary CPUs.
Secondary CPUs run on unrelocated copy of Xen until turning on MMU.
After turning on MMU secondary CPUs run on relocated copy of Xen.

To add ability to relocate Xen in over 4GB space add following to
compilation command: ARM32_RELOCATE_OVER_4GB=y

Signed-off-by: Iurii Konovalenko <iurii.konovalenko@xxxxxxxxxxxxxxx>
Signed-off-by: Andrii Anisov <andrii.anisov@xxxxxxxxxxxxxxx>
---
 xen/Rules.mk                   |  1 +
 xen/arch/arm/arm32/head.S      | 21 ++++++++++++++++++++-
 xen/arch/arm/platforms/rcar2.c |  9 ++++++++-
 xen/arch/arm/setup.c           | 17 ++++++++++++++++-
 xen/arch/arm/smpboot.c         | 33 +++++++++++++++++++++++++++++----
 5 files changed, 74 insertions(+), 7 deletions(-)

diff --git a/xen/Rules.mk b/xen/Rules.mk
index feb08d6..fbd34a5 100644
--- a/xen/Rules.mk
+++ b/xen/Rules.mk
@@ -64,6 +64,7 @@ CFLAGS-$(HAS_PCI)       += -DHAS_PCI
 CFLAGS-$(HAS_IOPORTS)   += -DHAS_IOPORTS
 CFLAGS-$(HAS_PDX)       += -DHAS_PDX
 CFLAGS-$(frame_pointer) += -fno-omit-frame-pointer -DCONFIG_FRAME_POINTER
+CFLAGS-$(ARM32_RELOCATE_OVER_4GB) += -DARM32_RELOCATE_OVER_4GB
 
 ifneq ($(max_phys_cpus),)
 CFLAGS-y                += -DMAX_PHYS_CPUS=$(max_phys_cpus)
diff --git a/xen/arch/arm/arm32/head.S b/xen/arch/arm/arm32/head.S
index 5c0263e..26be1d0 100644
--- a/xen/arch/arm/arm32/head.S
+++ b/xen/arch/arm/arm32/head.S
@@ -262,8 +262,21 @@ cpu_init_done:
         add   r4, r4, r10            /* r4 := paddr (boot_pagetable) */
         mov   r5, #0                 /* r4:r5 is paddr (boot_pagetable) */
         mcrr  CP64(r4, r5, HTTBR)
+#ifdef ARM32_RELOCATE_OVER_4GB
+        teq   r7, #0
+        beq   1f                     /* construct pagetable if CPU0 */
 
-        /* Setup boot_pgtable: */
+        /*Skip constructing TLBs for secondary CPUs, use constructed by CPU0*/
+        PRINT("- Skip construction pagetable, using CPU0 table @")
+        mov   r0, r5
+        bl    putn
+        mov   r0, r4
+        bl    putn
+        PRINT("  -\r\n")
+        b   skip_constructing
+#endif
+
+1:      /* Setup boot_pgtable: */
         ldr   r1, =boot_second
         add   r1, r1, r10            /* r1 := paddr (boot_second) */
 
@@ -346,6 +359,7 @@ virtphys_clash:
         PRINT("- Unable to build boot page tables - virt and phys addresses 
clash. -\r\n")
         b     fail
 
+skip_constructing:
 1:
         PRINT("- Turning on paging -\r\n")
 
@@ -427,6 +441,11 @@ paging:
          * setup in init_secondary_pagetables. */
 
         ldr   r4, =init_ttbr         /* VA of HTTBR value stashed by CPU 0 */
+#ifdef ARM32_RELOCATE_OVER_4GB
+        ldr   r1, =_start
+        sub r4, r1
+        add r4, #BOOT_RELOC_VIRT_START
+#endif
         ldrd  r4, r5, [r4]           /* Actual value */
         dsb
         mcrr  CP64(r4, r5, HTTBR)
diff --git a/xen/arch/arm/platforms/rcar2.c b/xen/arch/arm/platforms/rcar2.c
index aef544c..4365166 100644
--- a/xen/arch/arm/platforms/rcar2.c
+++ b/xen/arch/arm/platforms/rcar2.c
@@ -25,6 +25,9 @@
 #define RCAR2_RAM_SIZE                         0x1000
 #define RCAR2_SMP_START_OFFSET                 0xFFC
 
+#ifdef ARM32_RELOCATE_OVER_4GB
+extern paddr_t xen_relocation_offset;
+#endif
 static int __init rcar2_smp_init(void)
 {
     void __iomem *pram;
@@ -38,7 +41,11 @@ static int __init rcar2_smp_init(void)
     }
 
     /* setup reset vectors */
-    writel(__pa(init_secondary), pram + RCAR2_SMP_START_OFFSET);
+    writel(__pa(init_secondary)
+#ifdef ARM32_RELOCATE_OVER_4GB
+            - xen_relocation_offset
+#endif
+            , pram + RCAR2_SMP_START_OFFSET);
     iounmap(pram);
 
     sev();
diff --git a/xen/arch/arm/setup.c b/xen/arch/arm/setup.c
index 4ec7c13..66e2834 100644
--- a/xen/arch/arm/setup.c
+++ b/xen/arch/arm/setup.c
@@ -407,7 +407,7 @@ static paddr_t __init get_xen_paddr(void)
             if ( !e )
                 continue;
 
-#ifdef CONFIG_ARM_32
+#if defined (CONFIG_ARM_32) && !defined(ARM32_RELOCATE_OVER_4GB)
             /* Xen must be under 4GB */
             if ( e > 0x100000000ULL )
                 e = 0x100000000ULL;
@@ -699,6 +699,9 @@ void __init setup_cache(void)
     cacheline_bytes = 1U << (4 + (ccsid & 0x7));
 }
 
+#ifdef ARM32_RELOCATE_OVER_4GB
+paddr_t xen_relocation_offset;
+#endif
 /* C entry point for boot CPU */
 void __init start_xen(unsigned long boot_phys_offset,
                       unsigned long fdt_paddr,
@@ -740,8 +743,20 @@ void __init start_xen(unsigned long boot_phys_offset,
                              (paddr_t)(uintptr_t)(_end - _start + 1), NULL);
     BUG_ON(!xen_bootmodule);
 
+#ifdef ARM32_RELOCATE_OVER_4GB
+    //save physical address of init_secondary
+    xen_relocation_offset = __pa(init_secondary);
+#endif
     xen_paddr = get_xen_paddr();
     setup_pagetables(boot_phys_offset, xen_paddr);
+#ifdef ARM32_RELOCATE_OVER_4GB
+    //Now Xen is relocated
+    //Calculate offset of Xen relocation
+    //It is difference between new physical address of init_secondary an old 
one
+    //This offset is needed in several places when we have to write to old Xen 
location
+    //(secondary CPUs run on old-located Xen and rely on some variables from 
CPU0)
+    xen_relocation_offset = __pa(init_secondary) - xen_relocation_offset;
+#endif
 
     /* Update Xen's address now that we have relocated. */
     printk("Update BOOTMOD_XEN from %"PRIpaddr"-%"PRIpaddr" => 
%"PRIpaddr"-%"PRIpaddr"\n",
diff --git a/xen/arch/arm/smpboot.c b/xen/arch/arm/smpboot.c
index a96cda2..731144c 100644
--- a/xen/arch/arm/smpboot.c
+++ b/xen/arch/arm/smpboot.c
@@ -31,6 +31,9 @@
 #include <xen/console.h>
 #include <asm/gic.h>
 #include <asm/psci.h>
+#ifdef ARM32_RELOCATE_OVER_4GB
+#include <xen/vmap.h>
+#endif
 
 cpumask_t cpu_online_map;
 cpumask_t cpu_present_map;
@@ -353,17 +356,33 @@ int __init cpu_up_send_sgi(int cpu)
     return 0;
 }
 
+#ifdef ARM32_RELOCATE_OVER_4GB
+extern paddr_t xen_relocation_offset;
+#endif
 /* Bring up a remote CPU */
 int __cpu_up(unsigned int cpu)
 {
     int rc;
     s_time_t deadline;
+#ifdef ARM32_RELOCATE_OVER_4GB
+    paddr_t p_info = __pa(&smp_up_cpu) - xen_relocation_offset;
+    unsigned long* info = ioremap_nocache(p_info, sizeof(unsigned long));
+#else
+    unsigned long* info = &smp_up_cpu;
+#endif
 
     printk("Bringing up CPU%d\n", cpu);
 
     rc = init_secondary_pagetables(cpu);
     if ( rc < 0 )
+#ifdef ARM32_RELOCATE_OVER_4GB
+    {
+        iounmap(info);
+        return rc;
+    }
+#else
         return rc;
+#endif
 
     console_start_sync(); /* Secondary may use early_printk */
 
@@ -374,8 +393,8 @@ int __cpu_up(unsigned int cpu)
     init_data.cpuid = cpu;
 
     /* Open the gate for this CPU */
-    smp_up_cpu = cpu_logical_map(cpu);
-    clean_dcache(smp_up_cpu);
+    *info = cpu_logical_map(cpu);
+    clean_dcache(*info);
 
     rc = arch_cpu_up(cpu);
 
@@ -383,6 +402,9 @@ int __cpu_up(unsigned int cpu)
 
     if ( rc < 0 )
     {
+#ifdef ARM32_RELOCATE_OVER_4GB
+        iounmap(info);
+#endif
         printk("Failed to bring up CPU%d\n", cpu);
         return rc;
     }
@@ -406,8 +428,11 @@ int __cpu_up(unsigned int cpu)
      */
     init_data.stack = NULL;
     init_data.cpuid = ~0;
-    smp_up_cpu = MPIDR_INVALID;
-    clean_dcache(smp_up_cpu);
+    *info = MPIDR_INVALID;
+    clean_dcache(*info);
+#ifdef ARM32_RELOCATE_OVER_4GB
+    iounmap(info);
+#endif
 
     if ( !cpu_online(cpu) )
     {
-- 
1.9.1


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


 


Rackspace

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