Re: [PATCH 7/7] ARM: KVM: perform HYP initilization for hotplugged CPUs

2013-04-03 Thread Christoffer Dall
On Tue, Apr 02, 2013 at 02:25:15PM +0100, Marc Zyngier wrote:
 Now that we have the necessary infrastructure to boot a hotplugged CPU
 at any point in time, wire a CPU notifier that will perform the HYP
 init for the incoming CPU.
 
 Note that this depends on the platform code and/or firmware to boot the
 incoming CPU with HYP mode enabled and return to the kernel by following
 the normal boot path (HYP stub installed).
 
 Signed-off-by: Marc Zyngier marc.zyng...@arm.com
 ---
  arch/arm/kvm/arm.c | 47 +++
  1 file changed, 31 insertions(+), 16 deletions(-)
 
 diff --git a/arch/arm/kvm/arm.c b/arch/arm/kvm/arm.c
 index f0f3290..6cc076e 100644
 --- a/arch/arm/kvm/arm.c
 +++ b/arch/arm/kvm/arm.c
 @@ -793,8 +793,9 @@ long kvm_arch_vm_ioctl(struct file *filp,
   }
  }
  
 -static void cpu_init_hyp_mode(void *vector)
 +static void cpu_init_hyp_mode(void *dummy)
  {
 + phys_addr_t init_vector_addr = virt_to_phys(__kvm_hyp_init);
   unsigned long long boot_pgd_ptr;
   unsigned long long pgd_ptr;
   unsigned long hyp_stack_ptr;
 @@ -802,7 +803,7 @@ static void cpu_init_hyp_mode(void *vector)
   unsigned long vector_ptr;
  
   /* Switch from the HYP stub to our own HYP init vector */
 - __hyp_set_vectors((unsigned long)vector);
 + __hyp_set_vectors(init_vector_addr);
  
   boot_pgd_ptr = (unsigned long long)kvm_mmu_get_boot_httbr();
   pgd_ptr = (unsigned long long)kvm_mmu_get_httbr();
 @@ -813,12 +814,28 @@ static void cpu_init_hyp_mode(void *vector)
   __cpu_init_hyp_mode(boot_pgd_ptr, pgd_ptr, hyp_stack_ptr, vector_ptr);
  }
  
 +static int hyp_init_cpu_notify(struct notifier_block *self,
 +unsigned long action, void *cpu)
 +{
 + switch (action) {
 + case CPU_STARTING:
 + case CPU_STARTING_FROZEN:
 + cpu_init_hyp_mode(NULL);
 + break;
 + }
 +
 + return NOTIFY_OK;
 +}
 +
 +static struct notifier_block hyp_init_cpu_nb = {
 + .notifier_call = hyp_init_cpu_notify,
 +};
 +
  /**
   * Inits Hyp-mode on all online CPUs
   */
  static int init_hyp_mode(void)
  {
 - phys_addr_t init_phys_addr;
   int cpu;
   int err = 0;
  
 @@ -851,19 +868,6 @@ static int init_hyp_mode(void)
   }
  
   /*
 -  * Execute the init code on each CPU.
 -  *
 -  * Note: The stack is not mapped yet, so don't do anything else than
 -  * initializing the hypervisor mode on each CPU using a local stack
 -  * space for temporary storage.
 -  */
 - init_phys_addr = virt_to_phys(__kvm_hyp_init);
 - for_each_online_cpu(cpu) {
 - smp_call_function_single(cpu, cpu_init_hyp_mode,
 -  (void *)(long)init_phys_addr, 1);
 - }
 -
 - /*
* Map the Hyp-code called directly from the host
*/
   err = create_hyp_mappings(__kvm_hyp_code_start, __kvm_hyp_code_end);
 @@ -908,6 +912,11 @@ static int init_hyp_mode(void)
   }
  
   /*
 +  * Execute the init code on each CPU.
 +  */
 + on_each_cpu(cpu_init_hyp_mode, NULL, 1);
 +
 + /*
* Init HYP view of VGIC
*/
   err = kvm_vgic_hyp_init();
 @@ -963,6 +972,12 @@ int kvm_arch_init(void *opaque)
   if (err)
   goto out_err;
  
 + err = register_cpu_notifier(hyp_init_cpu_nb);
 + if (err) {
 + kvm_err(Cannot register HYP init CPU notifier (%d)\n, err);
 + goto out_err;
 + }
 +
   kvm_coproc_table_init();
   return 0;
  out_err:
 -- 
 1.8.1.4
 
 
Acked-by: Christoffer Dall cd...@cs.columbia.edu
--
To unsubscribe from this list: send the line unsubscribe kvm in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 7/7] ARM: KVM: perform HYP initilization for hotplugged CPUs

2013-04-02 Thread Marc Zyngier
Now that we have the necessary infrastructure to boot a hotplugged CPU
at any point in time, wire a CPU notifier that will perform the HYP
init for the incoming CPU.

Note that this depends on the platform code and/or firmware to boot the
incoming CPU with HYP mode enabled and return to the kernel by following
the normal boot path (HYP stub installed).

Signed-off-by: Marc Zyngier marc.zyng...@arm.com
---
 arch/arm/kvm/arm.c | 47 +++
 1 file changed, 31 insertions(+), 16 deletions(-)

diff --git a/arch/arm/kvm/arm.c b/arch/arm/kvm/arm.c
index f0f3290..6cc076e 100644
--- a/arch/arm/kvm/arm.c
+++ b/arch/arm/kvm/arm.c
@@ -793,8 +793,9 @@ long kvm_arch_vm_ioctl(struct file *filp,
}
 }
 
-static void cpu_init_hyp_mode(void *vector)
+static void cpu_init_hyp_mode(void *dummy)
 {
+   phys_addr_t init_vector_addr = virt_to_phys(__kvm_hyp_init);
unsigned long long boot_pgd_ptr;
unsigned long long pgd_ptr;
unsigned long hyp_stack_ptr;
@@ -802,7 +803,7 @@ static void cpu_init_hyp_mode(void *vector)
unsigned long vector_ptr;
 
/* Switch from the HYP stub to our own HYP init vector */
-   __hyp_set_vectors((unsigned long)vector);
+   __hyp_set_vectors(init_vector_addr);
 
boot_pgd_ptr = (unsigned long long)kvm_mmu_get_boot_httbr();
pgd_ptr = (unsigned long long)kvm_mmu_get_httbr();
@@ -813,12 +814,28 @@ static void cpu_init_hyp_mode(void *vector)
__cpu_init_hyp_mode(boot_pgd_ptr, pgd_ptr, hyp_stack_ptr, vector_ptr);
 }
 
+static int hyp_init_cpu_notify(struct notifier_block *self,
+  unsigned long action, void *cpu)
+{
+   switch (action) {
+   case CPU_STARTING:
+   case CPU_STARTING_FROZEN:
+   cpu_init_hyp_mode(NULL);
+   break;
+   }
+
+   return NOTIFY_OK;
+}
+
+static struct notifier_block hyp_init_cpu_nb = {
+   .notifier_call = hyp_init_cpu_notify,
+};
+
 /**
  * Inits Hyp-mode on all online CPUs
  */
 static int init_hyp_mode(void)
 {
-   phys_addr_t init_phys_addr;
int cpu;
int err = 0;
 
@@ -851,19 +868,6 @@ static int init_hyp_mode(void)
}
 
/*
-* Execute the init code on each CPU.
-*
-* Note: The stack is not mapped yet, so don't do anything else than
-* initializing the hypervisor mode on each CPU using a local stack
-* space for temporary storage.
-*/
-   init_phys_addr = virt_to_phys(__kvm_hyp_init);
-   for_each_online_cpu(cpu) {
-   smp_call_function_single(cpu, cpu_init_hyp_mode,
-(void *)(long)init_phys_addr, 1);
-   }
-
-   /*
 * Map the Hyp-code called directly from the host
 */
err = create_hyp_mappings(__kvm_hyp_code_start, __kvm_hyp_code_end);
@@ -908,6 +912,11 @@ static int init_hyp_mode(void)
}
 
/*
+* Execute the init code on each CPU.
+*/
+   on_each_cpu(cpu_init_hyp_mode, NULL, 1);
+
+   /*
 * Init HYP view of VGIC
 */
err = kvm_vgic_hyp_init();
@@ -963,6 +972,12 @@ int kvm_arch_init(void *opaque)
if (err)
goto out_err;
 
+   err = register_cpu_notifier(hyp_init_cpu_nb);
+   if (err) {
+   kvm_err(Cannot register HYP init CPU notifier (%d)\n, err);
+   goto out_err;
+   }
+
kvm_coproc_table_init();
return 0;
 out_err:
-- 
1.8.1.4


--
To unsubscribe from this list: send the line unsubscribe kvm in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html