--- linux-2.6.16-mtyrel-k8-64bit-xen/arch/i386/kernel/cpu/cpufreq/powernow-k8.c~ 2006-03-28 13:52:05.553985250 -0500 +++ linux-2.6.16-mtyrel-k8-64bit-xen/arch/i386/kernel/cpu/cpufreq/powernow-k8.c 2006-03-29 18:30:17.260355500 -0500 @@ -48,6 +48,37 @@ #define VERSION "version 1.60.0" #include "powernow-k8.h" +/* 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 + /* serialize freq changes */ static DECLARE_MUTEX(fidvid_sem); @@ -98,7 +129,7 @@ { u32 lo, hi; - rdmsr(MSR_FIDVID_STATUS, lo, hi); + cpu_rdmsr(MSR_FIDVID_STATUS, lo, hi); return lo & MSR_S_LO_CHANGE_PENDING ? 1 : 0; } @@ -116,7 +147,7 @@ dprintk("detected change pending stuck\n"); return 1; } - rdmsr(MSR_FIDVID_STATUS, lo, hi); + cpu_rdmsr(MSR_FIDVID_STATUS, lo, hi); } while (lo & MSR_S_LO_CHANGE_PENDING); data->currvid = hi & MSR_S_HI_CURRENT_VID; @@ -145,13 +176,13 @@ u32 lo, hi; u8 fid, vid; - rdmsr(MSR_FIDVID_STATUS, lo, hi); + cpu_rdmsr(MSR_FIDVID_STATUS, lo, hi); vid = hi & MSR_S_HI_CURRENT_VID; fid = lo & MSR_S_LO_CURRENT_FID; lo = fid | (vid << MSR_C_LO_VID_SHIFT); hi = MSR_C_HI_STP_GNT_BENIGN; dprintk("cpu%d, init lo 0x%x, hi 0x%x\n", smp_processor_id(), lo, hi); - wrmsr(MSR_FIDVID_CTL, lo, hi); + cpu_wrmsr(MSR_FIDVID_CTL, lo, hi); } @@ -173,7 +204,7 @@ fid, lo, data->plllock * PLL_LOCK_CONVERSION); do { - wrmsr(MSR_FIDVID_CTL, lo, data->plllock * PLL_LOCK_CONVERSION); + cpu_wrmsr(MSR_FIDVID_CTL, lo, data->plllock * PLL_LOCK_CONVERSION); if (i++ > 100) { printk(KERN_ERR PFX "internal error - pending bit very stuck - no further pstate changes possible\n"); return 1; @@ -215,7 +246,7 @@ vid, lo, STOP_GRANT_5NS); do { - wrmsr(MSR_FIDVID_CTL, lo, STOP_GRANT_5NS); + cpu_wrmsr(MSR_FIDVID_CTL, lo, STOP_GRANT_5NS); if (i++ > 100) { printk(KERN_ERR PFX "internal error - pending bit very stuck - no further pstate changes possible\n"); return 1; @@ -294,7 +325,7 @@ smp_processor_id(), data->currfid, data->currvid, reqvid, data->rvo); - rdmsr(MSR_FIDVID_STATUS, lo, maxvid); + cpu_rdmsr(MSR_FIDVID_STATUS, lo, maxvid); maxvid = 0x1f & (maxvid >> 16); dprintk("ph1 maxvid=0x%x\n", maxvid); if (reqvid < maxvid) /* lower numbers are higher voltages */