On Wed, Nov 09, 2011 at 12:05:04PM -0500, Brynet wrote:
> On Wed, Nov 09, 2011 at 03:35:01PM +0100, Walter Haidinger wrote:
> > Does the patch fix the following?
> > 
> > I've forwarding the bug report to the Linux KVM developers.
> > The response:
> 
> The patch in my first email should be enough to avoid the issue, the i386 
> patch was fine, only the amd64 patch was incorrect.
> 
> > On 09.11.2011 14:40, Avi Kivity wrote:
> > > Actually, it looks like an OpenBSD bug.  According to the AMD
> > > documentation:
> > >> "The current P-state value can be read using the P-State Status
> > >> Register. The P-State Current Limit Register and the P-State
> > >> Status Register are read-only registers. Writes to these
> > >> registers cause a #GP exception. Support for hardware P-state
> > >> control is indicated by EDX bit 7 as returned by CPUID function
> > >> 8000_0007h. Figure 18-1 shows the format of the P-State Current
> > >> Limit register."
> 
> The panic you hit is for an msr read, not a write. I'm aware those registers 
> are read-only.
> 
> The CPUID check isn't done, it matches on all family 10 and/or higher AMD 
> processors.

As pointed out earlier the AMD documentation says it should be,
the MSRs shouldn't be touched if the cpuid flag isn't set.

Access to unimplemented MSRs often leads to things like faults/reboots
on real hardware.  And while a K1x machine that doesn't have hardware
pstate control might not exist now, code that follows AMD's documentation
would work on such a machine.

The k1x_init() function should probably be renamed to something
like k1x_pstate_init() for clarity as well.

Index: i386/locore.s
===================================================================
RCS file: /cvs/src/sys/arch/i386/i386/locore.s,v
retrieving revision 1.141
diff -u -p -r1.141 locore.s
--- i386/locore.s       2 Nov 2011 23:53:44 -0000       1.141
+++ i386/locore.s       10 Nov 2011 01:15:46 -0000
@@ -157,6 +157,7 @@
        .globl  _C_LABEL(cpu_miscinfo)
        .globl  _C_LABEL(cpu_feature), _C_LABEL(cpu_ecxfeature)
        .globl  _C_LABEL(ecpu_feature), _C_LABEL(ecpu_ecxfeature)
+       .globl  _C_LABEL(cpu_apmfeature)
        .globl  _C_LABEL(cpu_cache_eax), _C_LABEL(cpu_cache_ebx)
        .globl  _C_LABEL(cpu_cache_ecx), _C_LABEL(cpu_cache_edx)
        .globl  _C_LABEL(cold), _C_LABEL(cnvmem), _C_LABEL(extmem)
@@ -197,6 +198,7 @@ _C_LABEL(cpu_feature):      .long   0       # feature
 _C_LABEL(ecpu_feature): .long  0       # extended feature flags from 'cpuid'
 _C_LABEL(cpu_ecxfeature):.long 0       # ecx feature flags from 'cpuid'
 _C_LABEL(ecpu_ecxfeature): .long 0     # extended ecx feature flags
+_C_LABEL(cpu_apmfeature): .long 0      # Advanced Power Management Information
 _C_LABEL(cpuid_level): .long   -1      # max. lvl accepted by 'cpuid' insn
 _C_LABEL(cpu_cache_eax):.long  0
 _C_LABEL(cpu_cache_ebx):.long  0
@@ -414,6 +416,9 @@ try586:     /* Use the `cpuid' instruction. 
        cpuid
        movl    %edx,RELOC(_C_LABEL(ecpu_feature))
        movl    %ecx,RELOC(_C_LABEL(ecpu_ecxfeature))
+       movl    $0x80000007,%eax
+       cpuid
+       movl    %edx,RELOC(_C_LABEL(cpu_apmfeature))
        movl    $0x80000002,%eax
        cpuid
        movl    %eax,RELOC(_C_LABEL(cpu_brandstr))
Index: i386/machdep.c
===================================================================
RCS file: /cvs/src/sys/arch/i386/i386/machdep.c,v
retrieving revision 1.506
diff -u -p -r1.506 machdep.c
--- i386/machdep.c      2 Nov 2011 23:53:44 -0000       1.506
+++ i386/machdep.c      10 Nov 2011 01:15:48 -0000
@@ -1347,7 +1347,7 @@ amd_family6_setperf_setup(struct cpu_inf
                k8_powernow_init();
                break;
        }
-       if (ci->ci_family >= 0x10)
+       if (ci->ci_family >= 0x10 && cpu_apmfeature & CPUIDAPM_PSTATE)
                k1x_init(ci);
 }
 #endif
Index: include/cpu.h
===================================================================
RCS file: /cvs/src/sys/arch/i386/include/cpu.h,v
retrieving revision 1.121
diff -u -p -r1.121 cpu.h
--- include/cpu.h       2 Nov 2011 23:53:44 -0000       1.121
+++ include/cpu.h       10 Nov 2011 01:15:48 -0000
@@ -314,6 +314,7 @@ extern int cpu_feature;
 extern int ecpu_feature;
 extern int cpu_ecxfeature;
 extern int ecpu_ecxfeature;
+extern int cpu_apmfeature;
 extern int cpu_cache_eax;
 extern int cpu_cache_ebx;
 extern int cpu_cache_ecx;
Index: include/specialreg.h
===================================================================
RCS file: /cvs/src/sys/arch/i386/include/specialreg.h,v
retrieving revision 1.40
diff -u -p -r1.40 specialreg.h
--- include/specialreg.h        2 Nov 2011 23:53:44 -0000       1.40
+++ include/specialreg.h        10 Nov 2011 01:15:50 -0000
@@ -167,6 +167,8 @@
 #define CPUIDECX_WDT   0x00002000      /* watchdog timer */
 #define CPUIDECX_FMA4  0x00010000      /* 4-operand FMA instructions */
 
+#define CPUIDAPM_PSTATE        0x00000080      /* hardware P-state control */
+
 /*
  * Model-specific registers for the i386 family
  */

Reply via email to