OSDN Git Service

x86_64: printout msr -v2
authorYinghai Lu <yhlu.kernel@gmail.com>
Fri, 22 Aug 2008 08:32:50 +0000 (01:32 -0700)
committerIngo Molnar <mingo@elte.hu>
Fri, 22 Aug 2008 08:43:21 +0000 (10:43 +0200)
commandline show_msr=1 for bsp, show_msr=32 for all 32 cpus.

[ mingo@elte.hu: added documentation ]

Signed-off-by: Yinghai Lu <yhlu.kernel@gmail.com>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Documentation/kernel-parameters.txt
arch/x86/kernel/cpu/common_64.c
arch/x86/kernel/paravirt.c
include/asm-x86/msr.h
include/asm-x86/paravirt.h

index 47e7d87..8679e80 100644 (file)
@@ -1852,6 +1852,12 @@ and is between 256 and 4096 characters. It is defined in the file
        shapers=        [NET]
                        Maximal number of shapers.
 
+       show_msr=       [x86] show boot-time MSR settings
+                       Format: { <integer> }
+                       Show boot-time (BIOS-initialized) MSR settings.
+                       The parameter means the number of CPUs to show,
+                       for example 1 means boot CPU only.
+
        sim710=         [SCSI,HW]
                        See header of drivers/scsi/sim710.c.
 
index dd6e3f1..bca2d69 100644 (file)
@@ -394,6 +394,49 @@ static __init int setup_noclflush(char *arg)
 }
 __setup("noclflush", setup_noclflush);
 
+struct msr_range {
+       unsigned min;
+       unsigned max;
+};
+
+static struct msr_range msr_range_array[] __cpuinitdata = {
+       { 0x00000000, 0x00000418},
+       { 0xc0000000, 0xc000040b},
+       { 0xc0010000, 0xc0010142},
+       { 0xc0011000, 0xc001103b},
+};
+
+static void __cpuinit print_cpu_msr(void)
+{
+       unsigned index;
+       u64 val;
+       int i;
+       unsigned index_min, index_max;
+
+       for (i = 0; i < ARRAY_SIZE(msr_range_array); i++) {
+               index_min = msr_range_array[i].min;
+               index_max = msr_range_array[i].max;
+               for (index = index_min; index < index_max; index++) {
+                       if (rdmsrl_amd_safe(index, &val))
+                               continue;
+                       printk(KERN_INFO " MSR%08x: %016llx\n", index, val);
+               }
+       }
+}
+
+static int show_msr __cpuinitdata;
+static __init int setup_show_msr(char *arg)
+{
+       int num;
+
+       get_option(&arg, &num);
+
+       if (num > 0)
+               show_msr = num;
+       return 1;
+}
+__setup("show_msr=", setup_show_msr);
+
 void __cpuinit print_cpu_info(struct cpuinfo_x86 *c)
 {
        if (c->x86_model_id[0])
@@ -403,6 +446,14 @@ void __cpuinit print_cpu_info(struct cpuinfo_x86 *c)
                printk(KERN_CONT " stepping %02x\n", c->x86_mask);
        else
                printk(KERN_CONT "\n");
+
+#ifdef CONFIG_SMP
+       if (c->cpu_index < show_msr)
+               print_cpu_msr();
+#else
+       if (show_msr)
+               print_cpu_msr();
+#endif
 }
 
 static __init int setup_disablecpuid(char *arg)
index 94da4d5..c604468 100644 (file)
@@ -330,6 +330,7 @@ struct pv_cpu_ops pv_cpu_ops = {
 #endif
        .wbinvd = native_wbinvd,
        .read_msr = native_read_msr_safe,
+       .read_msr_amd = native_read_msr_amd_safe,
        .write_msr = native_write_msr_safe,
        .read_tsc = native_read_tsc,
        .read_pmc = native_read_pmc,
index ca110ee..a30e586 100644 (file)
@@ -63,6 +63,22 @@ static inline unsigned long long native_read_msr_safe(unsigned int msr,
        return EAX_EDX_VAL(val, low, high);
 }
 
+static inline unsigned long long native_read_msr_amd_safe(unsigned int msr,
+                                                     int *err)
+{
+       DECLARE_ARGS(val, low, high);
+
+       asm volatile("2: rdmsr ; xor %0,%0\n"
+                    "1:\n\t"
+                    ".section .fixup,\"ax\"\n\t"
+                    "3:  mov %3,%0 ; jmp 1b\n\t"
+                    ".previous\n\t"
+                    _ASM_EXTABLE(2b, 3b)
+                    : "=r" (*err), EAX_EDX_RET(val, low, high)
+                    : "c" (msr), "D" (0x9c5a203a), "i" (-EFAULT));
+       return EAX_EDX_VAL(val, low, high);
+}
+
 static inline void native_write_msr(unsigned int msr,
                                    unsigned low, unsigned high)
 {
@@ -158,6 +174,13 @@ static inline int rdmsrl_safe(unsigned msr, unsigned long long *p)
        *p = native_read_msr_safe(msr, &err);
        return err;
 }
+static inline int rdmsrl_amd_safe(unsigned msr, unsigned long long *p)
+{
+       int err;
+
+       *p = native_read_msr_amd_safe(msr, &err);
+       return err;
+}
 
 #define rdtscl(low)                                            \
        ((low) = (u32)native_read_tsc())
index fbbde93..d5cfc5e 100644 (file)
@@ -137,6 +137,7 @@ struct pv_cpu_ops {
 
        /* MSR, PMC and TSR operations.
           err = 0/-EFAULT.  wrmsr returns 0/-EFAULT. */
+       u64 (*read_msr_amd)(unsigned int msr, int *err);
        u64 (*read_msr)(unsigned int msr, int *err);
        int (*write_msr)(unsigned int msr, unsigned low, unsigned high);
 
@@ -726,6 +727,10 @@ static inline u64 paravirt_read_msr(unsigned msr, int *err)
 {
        return PVOP_CALL2(u64, pv_cpu_ops.read_msr, msr, err);
 }
+static inline u64 paravirt_read_msr_amd(unsigned msr, int *err)
+{
+       return PVOP_CALL2(u64, pv_cpu_ops.read_msr_amd, msr, err);
+}
 static inline int paravirt_write_msr(unsigned msr, unsigned low, unsigned high)
 {
        return PVOP_CALL3(int, pv_cpu_ops.write_msr, msr, low, high);
@@ -771,6 +776,13 @@ static inline int rdmsrl_safe(unsigned msr, unsigned long long *p)
        *p = paravirt_read_msr(msr, &err);
        return err;
 }
+static inline int rdmsrl_amd_safe(unsigned msr, unsigned long long *p)
+{
+       int err;
+
+       *p = paravirt_read_msr_amd(msr, &err);
+       return err;
+}
 
 static inline u64 paravirt_read_tsc(void)
 {