Re: [Xen-devel] [PATCH v2 05/10] xen/arm: Setup virtual paging for non-boot CPUs on hotplug/resume
On 04/24/2018 03:50 PM, Mirela Simonovic wrote: Hi Julien, Hi, Sorry I forgot to answer to some part of the e-mail. On Mon, Apr 23, 2018 at 1:28 PM, Julien Grallwrote: Hi Mirela, On 20/04/18 13:25, Mirela Simonovic wrote: diff --git a/xen/arch/arm/p2m.c b/xen/arch/arm/p2m.c index d43c3aa896..9bb62c13cd 100644 --- a/xen/arch/arm/p2m.c +++ b/xen/arch/arm/p2m.c @@ -1451,13 +1451,21 @@ err: return page; } -static void __init setup_virt_paging_one(void *data) +static void setup_virt_paging_one(void *data) { unsigned long val = (unsigned long)data; WRITE_SYSREG32(val, VTCR_EL2); isb(); } +/* VTCR value to be configured by all CPUs. Set only once by the boot CPU */ +static unsigned long __read_mostly vtcr_value; VTCR is a register, so the type should be represented in term of bits (i.e uint*_t). I followed the type used in setup_virt_paging() and it's unsigned long. However, the spec says the VTCR_EL2 is 32-bit register, meaning that in the current implementation the type is not correct. If I want the type to be correct in this patch Xen will not compile. Are you suggesting to fix the type in existing implementation? The unsigned long is just a workaround to avoid an extra variable for the cast. As you introduce a static variable, then the cast become unnecessary. + +void setup_virt_paging_secondary(void) +{ +setup_virt_paging_one((void *)vtcr_value); That's fairly ugly. Is there any way to rework the interface? For instance, because you have a static variable which contain the VTCR, you could just use the variable in setup_virt_paging one. I If the argument provided to setup_virt_paging_one() is NULL within the setup_virt_paging_one() I configure saved static vtcr_value? If that is what you meant it was submitted in previous version of this patch :) Are you suggesting to revert the change to v1? I would suggest a mix between v1 and v2. Something like: static uint64_t vtcr; static setup_init_paging_one(void *data) { WRITE_SYSREG(vtcr, VTRC_EL2); [...] } r void __init setup_virt_paging(...) { vtcr = val; } Potentially, you could drop val and use vtcr everywhere in setup_virt_paging(). Cheers, -- Julien Grall ___ Xen-devel mailing list Xen-devel@lists.xenproject.org https://lists.xenproject.org/mailman/listinfo/xen-devel
Re: [Xen-devel] [PATCH v2 05/10] xen/arm: Setup virtual paging for non-boot CPUs on hotplug/resume
On 04/24/2018 03:50 PM, Mirela Simonovic wrote: Hi Julien, Hi Mirela, Thanks for the feedback. On Mon, Apr 23, 2018 at 1:28 PM, Julien Grallwrote: Hi Mirela, On 20/04/18 13:25, Mirela Simonovic wrote: In existing code the 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 if the current system state is not boot. This way, the paging for secondary CPUs will be setup in non-boot scenarios as well, while the 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, these in 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 --- CC: Stefano Stabellini CC: Julien Grall --- Changes in v2: -Fix commit message -Save configured VTCR_EL2 value into static variable that will be used by non-boot CPUs on hotplug -Add setup_virt_paging_secondary() and invoke it from start_secondary() if that CPU has to setup virtual paging (if the system state is not boot) --- xen/arch/arm/p2m.c| 13 - xen/arch/arm/smpboot.c| 3 +++ xen/include/asm-arm/p2m.h | 3 +++ 3 files changed, 18 insertions(+), 1 deletion(-) diff --git a/xen/arch/arm/p2m.c b/xen/arch/arm/p2m.c index d43c3aa896..9bb62c13cd 100644 --- a/xen/arch/arm/p2m.c +++ b/xen/arch/arm/p2m.c @@ -1451,13 +1451,21 @@ err: return page; } -static void __init setup_virt_paging_one(void *data) +static void setup_virt_paging_one(void *data) { unsigned long val = (unsigned long)data; WRITE_SYSREG32(val, VTCR_EL2); isb(); } +/* VTCR value to be configured by all CPUs. Set only once by the boot CPU */ +static unsigned long __read_mostly vtcr_value; VTCR is a register, so the type should be represented in term of bits (i.e uint*_t). I followed the type used in setup_virt_paging() and it's unsigned long. However, the spec says the VTCR_EL2 is 32-bit register, meaning that in the current implementation the type is not correct. If I want the type to be correct in this patch Xen will not compile. Are you suggesting to fix the type in existing implementation? + +void setup_virt_paging_secondary(void) +{ +setup_virt_paging_one((void *)vtcr_value); That's fairly ugly. Is there any way to rework the interface? For instance, because you have a static variable which contain the VTCR, you could just use the variable in setup_virt_paging one. If the argument provided to setup_virt_paging_one() is NULL within the setup_virt_paging_one() I configure saved static vtcr_value? If that is what you meant it was submitted in previous version of this patch :) Are you suggesting to revert the change to v1? +} + void __init setup_virt_paging(void) { /* Setup Stage 2 address translation */ @@ -1540,6 +1548,9 @@ void __init setup_virt_paging(void) 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); + +/* Save configured value (to be used later for secondary CPUs hotplug) */ +vtcr_value = val; } /* diff --git a/xen/arch/arm/smpboot.c b/xen/arch/arm/smpboot.c index 38b665a6d2..abc642804f 100644 --- a/xen/arch/arm/smpboot.c +++ b/xen/arch/arm/smpboot.c @@ -358,6 +358,9 @@ void start_secondary(unsigned long boot_phys_offset, local_irq_enable(); local_abort_enable(); +if ( system_state != SYS_STATE_boot ) +setup_virt_paging_secondary(); I think this code needs some documentation. So people understand why you only call setup_virt_paging_secondary() after boot. But is there any reason to not use a notifier (see notify_cpu_starting)? This would avoid yet another export. It works using notifiers, but I wouldn't say it's worth the overhead. Implementation using notifiers requires 1 additional data structure (notifier_block) and 2 functions to be implemented (an __init function to register a notifier and another one for callback). Moreover, such a callback would be called for each CPU event, which is 3 times when the CPU is hot-unplugged and nothing needs to be done. I've
Re: [Xen-devel] [PATCH v2 05/10] xen/arm: Setup virtual paging for non-boot CPUs on hotplug/resume
Hi Julien, Thanks for the feedback. On Mon, Apr 23, 2018 at 1:28 PM, Julien Grallwrote: > Hi Mirela, > > > On 20/04/18 13:25, Mirela Simonovic wrote: >> >> In existing code the 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 if the current system state is not boot. This way, the paging >> for secondary CPUs will be setup in non-boot scenarios as well, while the >> 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, these in 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 >> >> --- >> CC: Stefano Stabellini >> CC: Julien Grall >> --- >> Changes in v2: >> -Fix commit message >> -Save configured VTCR_EL2 value into static variable that will be used >> by non-boot CPUs on hotplug >> -Add setup_virt_paging_secondary() and invoke it from start_secondary() >> if that CPU has to setup virtual paging (if the system state is not >> boot) >> --- >> xen/arch/arm/p2m.c| 13 - >> xen/arch/arm/smpboot.c| 3 +++ >> xen/include/asm-arm/p2m.h | 3 +++ >> 3 files changed, 18 insertions(+), 1 deletion(-) >> >> diff --git a/xen/arch/arm/p2m.c b/xen/arch/arm/p2m.c >> index d43c3aa896..9bb62c13cd 100644 >> --- a/xen/arch/arm/p2m.c >> +++ b/xen/arch/arm/p2m.c >> @@ -1451,13 +1451,21 @@ err: >> return page; >> } >> -static void __init setup_virt_paging_one(void *data) >> +static void setup_virt_paging_one(void *data) >> { >> unsigned long val = (unsigned long)data; >> WRITE_SYSREG32(val, VTCR_EL2); >> isb(); >> } >> +/* VTCR value to be configured by all CPUs. Set only once by the boot >> CPU */ >> +static unsigned long __read_mostly vtcr_value; > > > VTCR is a register, so the type should be represented in term of bits (i.e > uint*_t). I followed the type used in setup_virt_paging() and it's unsigned long. However, the spec says the VTCR_EL2 is 32-bit register, meaning that in the current implementation the type is not correct. If I want the type to be correct in this patch Xen will not compile. Are you suggesting to fix the type in existing implementation? > >> + >> +void setup_virt_paging_secondary(void) >> +{ >> +setup_virt_paging_one((void *)vtcr_value); > > > That's fairly ugly. Is there any way to rework the interface? For instance, > because you have a static variable which contain the VTCR, you could just > use the variable in setup_virt_paging one. > If the argument provided to setup_virt_paging_one() is NULL within the setup_virt_paging_one() I configure saved static vtcr_value? If that is what you meant it was submitted in previous version of this patch :) Are you suggesting to revert the change to v1? >> +} >> + >> void __init setup_virt_paging(void) >> { >> /* Setup Stage 2 address translation */ >> @@ -1540,6 +1548,9 @@ void __init setup_virt_paging(void) >> 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); >> + >> +/* Save configured value (to be used later for secondary CPUs >> hotplug) */ >> +vtcr_value = val; >> } >> /* >> diff --git a/xen/arch/arm/smpboot.c b/xen/arch/arm/smpboot.c >> index 38b665a6d2..abc642804f 100644 >> --- a/xen/arch/arm/smpboot.c >> +++ b/xen/arch/arm/smpboot.c >> @@ -358,6 +358,9 @@ void start_secondary(unsigned long boot_phys_offset, >> local_irq_enable(); >> local_abort_enable(); >> +if ( system_state != SYS_STATE_boot ) >> +setup_virt_paging_secondary(); > > I think this code needs some documentation. So people understand why you > only call setup_virt_paging_secondary() after boot. But is there any reason > to not use a notifier (see notify_cpu_starting)? This would avoid yet > another export. It works using notifiers, but I wouldn't say it's worth the overhead. Implementation using notifiers requires 1 additional data structure (notifier_block) and 2 functions to be implemented (an __init function to register a
Re: [Xen-devel] [PATCH v2 05/10] xen/arm: Setup virtual paging for non-boot CPUs on hotplug/resume
Hi Mirela, On 20/04/18 13:25, Mirela Simonovic wrote: In existing code the 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 if the current system state is not boot. This way, the paging for secondary CPUs will be setup in non-boot scenarios as well, while the 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, these in 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--- CC: Stefano Stabellini CC: Julien Grall --- Changes in v2: -Fix commit message -Save configured VTCR_EL2 value into static variable that will be used by non-boot CPUs on hotplug -Add setup_virt_paging_secondary() and invoke it from start_secondary() if that CPU has to setup virtual paging (if the system state is not boot) --- xen/arch/arm/p2m.c| 13 - xen/arch/arm/smpboot.c| 3 +++ xen/include/asm-arm/p2m.h | 3 +++ 3 files changed, 18 insertions(+), 1 deletion(-) diff --git a/xen/arch/arm/p2m.c b/xen/arch/arm/p2m.c index d43c3aa896..9bb62c13cd 100644 --- a/xen/arch/arm/p2m.c +++ b/xen/arch/arm/p2m.c @@ -1451,13 +1451,21 @@ err: return page; } -static void __init setup_virt_paging_one(void *data) +static void setup_virt_paging_one(void *data) { unsigned long val = (unsigned long)data; WRITE_SYSREG32(val, VTCR_EL2); isb(); } +/* VTCR value to be configured by all CPUs. Set only once by the boot CPU */ +static unsigned long __read_mostly vtcr_value; VTCR is a register, so the type should be represented in term of bits (i.e uint*_t). + +void setup_virt_paging_secondary(void) +{ +setup_virt_paging_one((void *)vtcr_value); That's fairly ugly. Is there any way to rework the interface? For instance, because you have a static variable which contain the VTCR, you could just use the variable in setup_virt_paging one. +} + void __init setup_virt_paging(void) { /* Setup Stage 2 address translation */ @@ -1540,6 +1548,9 @@ void __init setup_virt_paging(void) 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); + +/* Save configured value (to be used later for secondary CPUs hotplug) */ +vtcr_value = val; } /* diff --git a/xen/arch/arm/smpboot.c b/xen/arch/arm/smpboot.c index 38b665a6d2..abc642804f 100644 --- a/xen/arch/arm/smpboot.c +++ b/xen/arch/arm/smpboot.c @@ -358,6 +358,9 @@ void start_secondary(unsigned long boot_phys_offset, local_irq_enable(); local_abort_enable(); +if ( system_state != SYS_STATE_boot ) +setup_virt_paging_secondary(); I think this code needs some documentation. So people understand why you only call setup_virt_paging_secondary() after boot. But is there any reason to not use a notifier (see notify_cpu_starting)? This would avoid yet another export. + check_local_cpu_errata(); printk(XENLOG_DEBUG "CPU %u booted.\n", smp_processor_id()); diff --git a/xen/include/asm-arm/p2m.h b/xen/include/asm-arm/p2m.h index 8823707c17..85b66a1196 100644 --- a/xen/include/asm-arm/p2m.h +++ b/xen/include/asm-arm/p2m.h @@ -153,6 +153,9 @@ void p2m_altp2m_check(struct vcpu *v, uint16_t idx) /* Second stage paging setup, to be called on all CPUs */ void setup_virt_paging(void); +/* To be called by secondary CPU on hotplug */ +void setup_virt_paging_secondary(void); + /* Init the datastructures for later use by the p2m code */ int p2m_init(struct domain *d); Cheers, -- Julien Grall ___ Xen-devel mailing list Xen-devel@lists.xenproject.org https://lists.xenproject.org/mailman/listinfo/xen-devel
[Xen-devel] [PATCH v2 05/10] xen/arm: Setup virtual paging for non-boot CPUs on hotplug/resume
In existing code the 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 if the current system state is not boot. This way, the paging for secondary CPUs will be setup in non-boot scenarios as well, while the 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, these in 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--- CC: Stefano Stabellini CC: Julien Grall --- Changes in v2: -Fix commit message -Save configured VTCR_EL2 value into static variable that will be used by non-boot CPUs on hotplug -Add setup_virt_paging_secondary() and invoke it from start_secondary() if that CPU has to setup virtual paging (if the system state is not boot) --- xen/arch/arm/p2m.c| 13 - xen/arch/arm/smpboot.c| 3 +++ xen/include/asm-arm/p2m.h | 3 +++ 3 files changed, 18 insertions(+), 1 deletion(-) diff --git a/xen/arch/arm/p2m.c b/xen/arch/arm/p2m.c index d43c3aa896..9bb62c13cd 100644 --- a/xen/arch/arm/p2m.c +++ b/xen/arch/arm/p2m.c @@ -1451,13 +1451,21 @@ err: return page; } -static void __init setup_virt_paging_one(void *data) +static void setup_virt_paging_one(void *data) { unsigned long val = (unsigned long)data; WRITE_SYSREG32(val, VTCR_EL2); isb(); } +/* VTCR value to be configured by all CPUs. Set only once by the boot CPU */ +static unsigned long __read_mostly vtcr_value; + +void setup_virt_paging_secondary(void) +{ +setup_virt_paging_one((void *)vtcr_value); +} + void __init setup_virt_paging(void) { /* Setup Stage 2 address translation */ @@ -1540,6 +1548,9 @@ void __init setup_virt_paging(void) 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); + +/* Save configured value (to be used later for secondary CPUs hotplug) */ +vtcr_value = val; } /* diff --git a/xen/arch/arm/smpboot.c b/xen/arch/arm/smpboot.c index 38b665a6d2..abc642804f 100644 --- a/xen/arch/arm/smpboot.c +++ b/xen/arch/arm/smpboot.c @@ -358,6 +358,9 @@ void start_secondary(unsigned long boot_phys_offset, local_irq_enable(); local_abort_enable(); +if ( system_state != SYS_STATE_boot ) +setup_virt_paging_secondary(); + check_local_cpu_errata(); printk(XENLOG_DEBUG "CPU %u booted.\n", smp_processor_id()); diff --git a/xen/include/asm-arm/p2m.h b/xen/include/asm-arm/p2m.h index 8823707c17..85b66a1196 100644 --- a/xen/include/asm-arm/p2m.h +++ b/xen/include/asm-arm/p2m.h @@ -153,6 +153,9 @@ void p2m_altp2m_check(struct vcpu *v, uint16_t idx) /* Second stage paging setup, to be called on all CPUs */ void setup_virt_paging(void); +/* To be called by secondary CPU on hotplug */ +void setup_virt_paging_secondary(void); + /* Init the datastructures for later use by the p2m code */ int p2m_init(struct domain *d); -- 2.13.0 ___ Xen-devel mailing list Xen-devel@lists.xenproject.org https://lists.xenproject.org/mailman/listinfo/xen-devel