]> git.hungrycats.org Git - linux/commitdiff
arm: kvm: implement CPU PM notifier
authorLorenzo Pieralisi <lorenzo.pieralisi@arm.com>
Mon, 5 Aug 2013 14:04:46 +0000 (15:04 +0100)
committerJiri Slaby <jslaby@suse.cz>
Thu, 30 Apr 2015 09:15:01 +0000 (11:15 +0200)
commit 1fcf7ce0c60213994269fb59569ec161eb6e08d6 upstream.

Upon CPU shutdown and consequent warm-reboot, the hypervisor CPU state
must be re-initialized. This patch implements a CPU PM notifier that
upon warm-boot calls a KVM hook to reinitialize properly the hypervisor
state so that the CPU can be safely resumed.

Acked-by: Marc Zyngier <marc.zyngier@arm.com>
Acked-by: Christoffer Dall <christoffer.dall@linaro.org>
Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
Signed-off-by: Shannon Zhao <shannon.zhao@linaro.org>
Signed-off-by: Jiri Slaby <jslaby@suse.cz>
arch/arm/kvm/arm.c

index 78ee10bed798c12b0f3f08f6636ee735b34490b8..64ec98b786ae50921d95f2079dea040d8621f70b 100644 (file)
@@ -17,6 +17,7 @@
  */
 
 #include <linux/cpu.h>
+#include <linux/cpu_pm.h>
 #include <linux/errno.h>
 #include <linux/err.h>
 #include <linux/kvm_host.h>
@@ -857,6 +858,33 @@ static struct notifier_block hyp_init_cpu_nb = {
        .notifier_call = hyp_init_cpu_notify,
 };
 
+#ifdef CONFIG_CPU_PM
+static int hyp_init_cpu_pm_notifier(struct notifier_block *self,
+                                   unsigned long cmd,
+                                   void *v)
+{
+       if (cmd == CPU_PM_EXIT) {
+               cpu_init_hyp_mode(NULL);
+               return NOTIFY_OK;
+       }
+
+       return NOTIFY_DONE;
+}
+
+static struct notifier_block hyp_init_cpu_pm_nb = {
+       .notifier_call = hyp_init_cpu_pm_notifier,
+};
+
+static void __init hyp_cpu_pm_init(void)
+{
+       cpu_pm_register_notifier(&hyp_init_cpu_pm_nb);
+}
+#else
+static inline void hyp_cpu_pm_init(void)
+{
+}
+#endif
+
 /**
  * Inits Hyp-mode on all online CPUs
  */
@@ -1017,6 +1045,8 @@ int kvm_arch_init(void *opaque)
                goto out_err;
        }
 
+       hyp_cpu_pm_init();
+
        kvm_coproc_table_init();
        return 0;
 out_err: