Hi,
The attached patch fixes the speedstep-centrino driver, to use the
hypervisors MSR's instead of direct MSR access.
Without the patch the frequency seems to have changed, but the
powerconsumption of the CPU has not.
Thanks to the patch of Matt T. Yourst found here
http://lists.xensource.com/archives/html/xen-devel/2006-03/msg01410.html
It was easy to fix the centrino driver, too.
If someone could review the patch and bring it upsream (if it's ok), it
would be very nice.
cheers,
ck
Subject: Make speedstep-centrino driver work under Xen
Signed-off-by: Christian Krafft <parabelboi@xxxxxxxxxxxxxxx>
---
Index: linux/arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c
===================================================================
--- linux.orig/arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c
+++ linux/arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c
@@ -41,6 +41,37 @@
#define dprintk(msg...) cpufreq_debug_printk(CPUFREQ_DEBUG_DRIVER,
"speedstep-centrino", msg)
+/* Xen support */
+
+#ifdef CONFIG_XEN_PRIVILEGED_GUEST
+int xen_access_msr(u32 msr, int write, u32* out1, u32* out2, u32 in1, u32 in2)
{
+ dom0_op_t op;
+ op.cmd = DOM0_MSR;
+ op.u.msr.write = write;
+ op.u.msr.cpu_mask = 1; /* only first CPU: not clear how to read
multiple CPUs */
+ op.u.msr.msr = msr;
+ op.u.msr.in1 = in1;
+ op.u.msr.in2 = in2;
+ BUG_ON(HYPERVISOR_dom0_op(&op));
+
+ if (!write) {
+ *out1 = op.u.msr.out1; /* low 32 bits */
+ *out2 = op.u.msr.out2; /* high 32 bits */
+ }
+
+ return 0;
+}
+
+#define cpu_rdmsr(msr, val1, val2) xen_access_msr((msr), 0, &(val1), &(val2),
0, 0)
+#define cpu_wrmsr(msr, val1, val2) xen_access_msr((msr), 1, NULL, NULL,
(val1), (val2))
+
+#else
+
+#define cpu_rdmsr(msr, val1, val2) rdmsr(msr, val1, val2)
+#define cpu_wrmsr(msr, val1, val2) wrmsr(msr, val1, val2)
+
+#endif
+
struct cpu_id
{
__u8 x86; /* CPU family */
@@ -330,7 +361,7 @@ static unsigned int get_cur_freq(unsigne
if (smp_processor_id() != cpu)
return 0;
- rdmsr(MSR_IA32_PERF_STATUS, l, h);
+ cpu_rdmsr(MSR_IA32_PERF_STATUS, l, h);
clock_freq = extract_clock(l, cpu, 0);
if (unlikely(clock_freq == 0)) {
@@ -340,7 +371,7 @@ static unsigned int get_cur_freq(unsigne
* P-state transition (like TM2). Get the last freq set
* in PERF_CTL.
*/
- rdmsr(MSR_IA32_PERF_CTL, l, h);
+ cpu_rdmsr(MSR_IA32_PERF_CTL, l, h);
clock_freq = extract_clock(l, cpu, 1);
}
@@ -514,15 +545,15 @@ static int centrino_cpu_init(struct cpuf
/* Check to see if Enhanced SpeedStep is enabled, and try to
enable it if not. */
- rdmsr(MSR_IA32_MISC_ENABLE, l, h);
+ cpu_rdmsr(MSR_IA32_MISC_ENABLE, l, h);
if (!(l & (1<<16))) {
l |= (1<<16);
dprintk("trying to enable Enhanced SpeedStep (%x)\n", l);
- wrmsr(MSR_IA32_MISC_ENABLE, l, h);
+ cpu_wrmsr(MSR_IA32_MISC_ENABLE, l, h);
/* check to see if it stuck */
- rdmsr(MSR_IA32_MISC_ENABLE, l, h);
+ cpu_rdmsr(MSR_IA32_MISC_ENABLE, l, h);
if (!(l & (1<<16))) {
printk(KERN_INFO PFX "couldn't enable Enhanced
SpeedStep\n");
return -ENODEV;
@@ -620,7 +651,7 @@ static int centrino_target (struct cpufr
}
msr = centrino_model[cpu]->op_points[newstate].index;
- rdmsr(MSR_IA32_PERF_CTL, oldmsr, h);
+ cpu_rdmsr(MSR_IA32_PERF_CTL, oldmsr, h);
if (msr == (oldmsr & 0xffff)) {
retval = 0;
@@ -643,7 +674,7 @@ static int centrino_target (struct cpufr
msr &= 0xffff;
oldmsr |= msr;
- wrmsr(MSR_IA32_PERF_CTL, oldmsr, h);
+ cpu_wrmsr(MSR_IA32_PERF_CTL, oldmsr, h);
cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-devel
|