Merge branch 'pm-cpuidle'
[linux-2.6-block.git] / arch / x86 / kernel / kvm.c
index b7f34fe2171e472f7f64bf7f93c9bdfcaefba710..98dafc1ea33d7f0fe8101995626691fcf35099f6 100644 (file)
@@ -308,9 +308,6 @@ static notrace void kvm_guest_apic_eoi_write(u32 reg, u32 val)
 
 static void kvm_guest_cpu_init(void)
 {
-       if (!kvm_para_available())
-               return;
-
        if (kvm_para_has_feature(KVM_FEATURE_ASYNC_PF) && kvmapf) {
                u64 pa = slow_virt_to_phys(this_cpu_ptr(&apf_reason));
 
@@ -625,9 +622,6 @@ static void __init kvm_guest_init(void)
 {
        int i;
 
-       if (!kvm_para_available())
-               return;
-
        paravirt_ops_setup();
        register_reboot_notifier(&kvm_pv_reboot_nb);
        for (i = 0; i < KVM_TASK_SLEEP_HASHSIZE; i++)
@@ -711,6 +705,7 @@ unsigned int kvm_arch_para_hints(void)
 {
        return cpuid_edx(kvm_cpuid_base() | KVM_CPUID_FEATURES);
 }
+EXPORT_SYMBOL_GPL(kvm_arch_para_hints);
 
 static uint32_t __init kvm_detect(void)
 {
@@ -848,8 +843,6 @@ asm(
  */
 void __init kvm_spinlock_init(void)
 {
-       if (!kvm_para_available())
-               return;
        /* Does host kernel support KVM_FEATURE_PV_UNHALT? */
        if (!kvm_para_has_feature(KVM_FEATURE_PV_UNHALT))
                return;
@@ -875,3 +868,39 @@ void __init kvm_spinlock_init(void)
 }
 
 #endif /* CONFIG_PARAVIRT_SPINLOCKS */
+
+#ifdef CONFIG_ARCH_CPUIDLE_HALTPOLL
+
+static void kvm_disable_host_haltpoll(void *i)
+{
+       wrmsrl(MSR_KVM_POLL_CONTROL, 0);
+}
+
+static void kvm_enable_host_haltpoll(void *i)
+{
+       wrmsrl(MSR_KVM_POLL_CONTROL, 1);
+}
+
+void arch_haltpoll_enable(unsigned int cpu)
+{
+       if (!kvm_para_has_feature(KVM_FEATURE_POLL_CONTROL)) {
+               pr_err_once("kvm: host does not support poll control\n");
+               pr_err_once("kvm: host upgrade recommended\n");
+               return;
+       }
+
+       /* Enable guest halt poll disables host halt poll */
+       smp_call_function_single(cpu, kvm_disable_host_haltpoll, NULL, 1);
+}
+EXPORT_SYMBOL_GPL(arch_haltpoll_enable);
+
+void arch_haltpoll_disable(unsigned int cpu)
+{
+       if (!kvm_para_has_feature(KVM_FEATURE_POLL_CONTROL))
+               return;
+
+       /* Enable guest halt poll disables host halt poll */
+       smp_call_function_single(cpu, kvm_enable_host_haltpoll, NULL, 1);
+}
+EXPORT_SYMBOL_GPL(arch_haltpoll_disable);
+#endif