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

[Xen-changelog] [xen staging] xen/arm: Setup virtual paging for non-boot CPUs on hotplug/resume

commit 2116030345746c4716b36a0af53b2a6e59ac93d6
Author:     Mirela Simonovic <mirela.simonovic@xxxxxxxxxx>
AuthorDate: Fri Jun 1 15:17:45 2018 +0200
Commit:     Julien Grall <julien.grall@xxxxxxx>
CommitDate: Tue Jun 5 19:07:50 2018 +0100

    xen/arm: Setup virtual paging for non-boot CPUs on hotplug/resume
    In existing code the virtual paging for non-boot CPUs is setup only on boot.
    The setup is triggered from start_xen() after all CPUs are brought online.
    In other words, the initialization of VTCR_EL2 register is done out of the
    cpu_up/start_secondary() control flow. However, the cpu_up flow is also used
    to hotplug non-boot CPUs on resume from suspend to RAM state, in which case
    the virtual paging will not be configured.
    With this patch the setting of paging is triggered from start_secondary()
    function using cpu starting notifier (notify_cpu_starting() call). The
    notifier is registered in p2m.c using init call. This has to be done with
    init call rather than presmp_init because the registered callback depends
    on vtcr configuration value which is setup after the presmp init calls
    are executed (do_presmp_initcalls() called from start_xen()). Init calls
    are executed after initial virtual paging is set up for all CPUs on boot.
    This ensures that no callback can fire until the vtcr value is calculated
    by Xen and virtual paging is set up initially for all CPUs. Also, this way
    the virtual paging setup in boot scenario remains unchanged.
    It is assumed here that after the system completed the boot, CPUs that
    execute start_secondary() were booted as well when the Xen itself was
    booted. According to this assumption non-boot CPUs will always be compliant
    with the VTCR_EL2 value that was selected by Xen on boot.
    Currently, there is no mechanism to trigger hotplugging of a CPU. This
    will be added with the suspend to RAM support for ARM, where the hotplug
    of non-boot CPUs will be triggered via enable_nonboot_cpus() call.
    Signed-off-by: Mirela Simonovic <mirela.simonovic@xxxxxxxxxx>
    Reviewed-by: Julien Grall <julien.grall@xxxxxxx>
 xen/arch/arm/p2m.c | 53 ++++++++++++++++++++++++++++++++++++++++++++++++-----
 1 file changed, 48 insertions(+), 5 deletions(-)

diff --git a/xen/arch/arm/p2m.c b/xen/arch/arm/p2m.c
index d43c3aa896..14791388ad 100644
--- a/xen/arch/arm/p2m.c
+++ b/xen/arch/arm/p2m.c
@@ -8,6 +8,8 @@
 #include <xen/iocap.h>
 #include <xen/mem_access.h>
 #include <xen/xmalloc.h>
+#include <xen/cpu.h>
+#include <xen/notifier.h>
 #include <public/vm_event.h>
 #include <asm/flushtlb.h>
 #include <asm/event.h>
@@ -1451,10 +1453,12 @@ err:
     return page;
-static void __init setup_virt_paging_one(void *data)
+/* VTCR value to be configured by all CPUs. Set only once by the boot CPU */
+static uint32_t __read_mostly vtcr;
+static void setup_virt_paging_one(void *data)
-    unsigned long val = (unsigned long)data;
-    WRITE_SYSREG32(val, VTCR_EL2);
+    WRITE_SYSREG32(vtcr, VTCR_EL2);
@@ -1538,10 +1542,49 @@ void __init setup_virt_paging(void)
     /* It is not allowed to concatenate a level zero root */
     BUG_ON( P2M_ROOT_LEVEL == 0 && P2M_ROOT_ORDER > 0 );
-    setup_virt_paging_one((void *)val);
-    smp_call_function(setup_virt_paging_one, (void *)val, 1);
+    vtcr = val;
+    setup_virt_paging_one(NULL);
+    smp_call_function(setup_virt_paging_one, NULL, 1);
+static int cpu_virt_paging_callback(struct notifier_block *nfb,
+                                    unsigned long action,
+                                    void *hcpu)
+    switch ( action )
+    {
+    case CPU_STARTING:
+        ASSERT(system_state != SYS_STATE_boot);
+        setup_virt_paging_one(NULL);
+        break;
+    default:
+        break;
+    }
+    return NOTIFY_DONE;
+static struct notifier_block cpu_virt_paging_nfb = {
+    .notifier_call = cpu_virt_paging_callback,
+static int __init cpu_virt_paging_init(void)
+    register_cpu_notifier(&cpu_virt_paging_nfb);
+    return 0;
+ * Initialization of the notifier has to be done at init rather than 
+ * phase because: the registered notifier is used to setup virtual paging for
+ * non-boot CPUs after the initial virtual paging for all CPUs is already 
+ * i.e. when a non-boot CPU is hotplugged after the system has booted. In other
+ * words, the notifier should be registered after the virtual paging is
+ * initially setup (setup_virt_paging() is called from start_xen()). This is
+ * required because vtcr config value has to be set before a notifier can fire.
+ */
  * Local variables:
  * mode: C
generated by git-patchbot for /home/xen/git/xen.git#staging

Xen-changelog mailing list



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