Dave Jones 6f9fa1a
commit 866111646f2c5d4c6c25e2bb97f5c61c3992defb
Dave Jones 6f9fa1a
Author: Dirk Brandewie <dirk.brandewie@gmail.com>
Dave Jones 6f9fa1a
Date:   Mon Mar 18 16:55:02 2013 -0700
Dave Jones 6f9fa1a
Dave Jones 6f9fa1a
    cpufreq/intel_pstate: Add function to check that all MSR's are valid
Dave Jones 6f9fa1a
    
Dave Jones 6f9fa1a
    Some VMs seem to try to implement some MSRs but not all the registers
Dave Jones 6f9fa1a
    the driver needs.  Check to make sure all the MSR that we need are
Dave Jones 6f9fa1a
    available. If any of the required MSRs are not available refuse to
Dave Jones 6f9fa1a
    load.
Dave Jones 6f9fa1a
    
Dave Jones 6f9fa1a
    Signed-off-by: Dirk Brandewie <dirk.brandewie@gmail.com>
Dave Jones 6f9fa1a
Dave Jones 6f9fa1a
--- linux-3.9.0-0.rc3.git0.2.fc19.x86_64/drivers/cpufreq/intel_pstate.c~	2013-03-19 14:54:33.489581718 -0400
Dave Jones 6f9fa1a
+++ linux-3.9.0-0.rc3.git0.2.fc19.x86_64/drivers/cpufreq/intel_pstate.c	2013-03-19 14:55:09.667523730 -0400
Dave Jones 6f9fa1a
@@ -752,6 +752,30 @@ static struct cpufreq_driver intel_pstat
Dave Jones 6f9fa1a
 
Dave Jones 6f9fa1a
 static int __initdata no_load;
Dave Jones 6f9fa1a
 
Dave Jones 6f9fa1a
+static int intel_pstate_msrs_not_valid(void)
Dave Jones 6f9fa1a
+{
Dave Jones 6f9fa1a
+	/* Check that all the msr's we are using are valid. */
Dave Jones 6f9fa1a
+	u64 aperf, mperf, tmp;
Dave Jones 6f9fa1a
+
Dave Jones 6f9fa1a
+	rdmsrl(MSR_IA32_APERF, aperf);
Dave Jones 6f9fa1a
+	rdmsrl(MSR_IA32_MPERF, mperf);
Dave Jones 6f9fa1a
+
Dave Jones 6f9fa1a
+	if (!intel_pstate_min_pstate() ||
Dave Jones 6f9fa1a
+		!intel_pstate_max_pstate() ||
Dave Jones 6f9fa1a
+		!intel_pstate_turbo_pstate())
Dave Jones 6f9fa1a
+		return -ENODEV;
Dave Jones 6f9fa1a
+
Dave Jones 6f9fa1a
+	rdmsrl(MSR_IA32_APERF, tmp);
Dave Jones 6f9fa1a
+	if (!(tmp - aperf))
Dave Jones 6f9fa1a
+		return -ENODEV;
Dave Jones 6f9fa1a
+
Dave Jones 6f9fa1a
+	rdmsrl(MSR_IA32_MPERF, tmp);
Dave Jones 6f9fa1a
+	if (!(tmp - mperf))
Dave Jones 6f9fa1a
+		return -ENODEV;
Dave Jones 6f9fa1a
+
Dave Jones 6f9fa1a
+	return 0;
Dave Jones 6f9fa1a
+}
Dave Jones 6f9fa1a
+
Dave Jones 6f9fa1a
 static int __init intel_pstate_init(void)
Dave Jones 6f9fa1a
 {
Dave Jones 6f9fa1a
 	int cpu, rc = 0;
Dave Jones 6f9fa1a
@@ -764,6 +788,9 @@ static int __init intel_pstate_init(void
Dave Jones 6f9fa1a
 	if (!id)
Dave Jones 6f9fa1a
 		return -ENODEV;
Dave Jones 6f9fa1a
 
Dave Jones 6f9fa1a
+	if (intel_pstate_msrs_not_valid())
Dave Jones 6f9fa1a
+		return -ENODEV;
Dave Jones 6f9fa1a
+
Dave Jones 6f9fa1a
 	pr_info("Intel P-state driver initializing.\n");
Dave Jones 6f9fa1a
 
Dave Jones 6f9fa1a
 	all_cpu_data = vmalloc(sizeof(void *) * num_possible_cpus());