aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/kernel-parameters.txt6
-rw-r--r--arch/x86/kernel/cpu/common_64.c51
-rw-r--r--arch/x86/kernel/paravirt.c1
-rw-r--r--include/asm-x86/msr.h23
-rw-r--r--include/asm-x86/paravirt.h12
5 files changed, 93 insertions, 0 deletions
diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt
index 47e7d8794fc6..8679e80b9fc4 100644
--- a/Documentation/kernel-parameters.txt
+++ b/Documentation/kernel-parameters.txt
@@ -1852,6 +1852,12 @@ and is between 256 and 4096 characters. It is defined in the file
1852 shapers= [NET] 1852 shapers= [NET]
1853 Maximal number of shapers. 1853 Maximal number of shapers.
1854 1854
1855 show_msr= [x86] show boot-time MSR settings
1856 Format: { <integer> }
1857 Show boot-time (BIOS-initialized) MSR settings.
1858 The parameter means the number of CPUs to show,
1859 for example 1 means boot CPU only.
1860
1855 sim710= [SCSI,HW] 1861 sim710= [SCSI,HW]
1856 See header of drivers/scsi/sim710.c. 1862 See header of drivers/scsi/sim710.c.
1857 1863
diff --git a/arch/x86/kernel/cpu/common_64.c b/arch/x86/kernel/cpu/common_64.c
index dd6e3f15017e..bca2d6980e82 100644
--- a/arch/x86/kernel/cpu/common_64.c
+++ b/arch/x86/kernel/cpu/common_64.c
@@ -394,6 +394,49 @@ static __init int setup_noclflush(char *arg)
394} 394}
395__setup("noclflush", setup_noclflush); 395__setup("noclflush", setup_noclflush);
396 396
397struct msr_range {
398 unsigned min;
399 unsigned max;
400};
401
402static struct msr_range msr_range_array[] __cpuinitdata = {
403 { 0x00000000, 0x00000418},
404 { 0xc0000000, 0xc000040b},
405 { 0xc0010000, 0xc0010142},
406 { 0xc0011000, 0xc001103b},
407};
408
409static void __cpuinit print_cpu_msr(void)
410{
411 unsigned index;
412 u64 val;
413 int i;
414 unsigned index_min, index_max;
415
416 for (i = 0; i < ARRAY_SIZE(msr_range_array); i++) {
417 index_min = msr_range_array[i].min;
418 index_max = msr_range_array[i].max;
419 for (index = index_min; index < index_max; index++) {
420 if (rdmsrl_amd_safe(index, &val))
421 continue;
422 printk(KERN_INFO " MSR%08x: %016llx\n", index, val);
423 }
424 }
425}
426
427static int show_msr __cpuinitdata;
428static __init int setup_show_msr(char *arg)
429{
430 int num;
431
432 get_option(&arg, &num);
433
434 if (num > 0)
435 show_msr = num;
436 return 1;
437}
438__setup("show_msr=", setup_show_msr);
439
397void __cpuinit print_cpu_info(struct cpuinfo_x86 *c) 440void __cpuinit print_cpu_info(struct cpuinfo_x86 *c)
398{ 441{
399 if (c->x86_model_id[0]) 442 if (c->x86_model_id[0])
@@ -403,6 +446,14 @@ void __cpuinit print_cpu_info(struct cpuinfo_x86 *c)
403 printk(KERN_CONT " stepping %02x\n", c->x86_mask); 446 printk(KERN_CONT " stepping %02x\n", c->x86_mask);
404 else 447 else
405 printk(KERN_CONT "\n"); 448 printk(KERN_CONT "\n");
449
450#ifdef CONFIG_SMP
451 if (c->cpu_index < show_msr)
452 print_cpu_msr();
453#else
454 if (show_msr)
455 print_cpu_msr();
456#endif
406} 457}
407 458
408static __init int setup_disablecpuid(char *arg) 459static __init int setup_disablecpuid(char *arg)
diff --git a/arch/x86/kernel/paravirt.c b/arch/x86/kernel/paravirt.c
index 94da4d52d798..c6044682e1e7 100644
--- a/arch/x86/kernel/paravirt.c
+++ b/arch/x86/kernel/paravirt.c
@@ -330,6 +330,7 @@ struct pv_cpu_ops pv_cpu_ops = {
330#endif 330#endif
331 .wbinvd = native_wbinvd, 331 .wbinvd = native_wbinvd,
332 .read_msr = native_read_msr_safe, 332 .read_msr = native_read_msr_safe,
333 .read_msr_amd = native_read_msr_amd_safe,
333 .write_msr = native_write_msr_safe, 334 .write_msr = native_write_msr_safe,
334 .read_tsc = native_read_tsc, 335 .read_tsc = native_read_tsc,
335 .read_pmc = native_read_pmc, 336 .read_pmc = native_read_pmc,
diff --git a/include/asm-x86/msr.h b/include/asm-x86/msr.h
index ca110ee73f07..a30e586df933 100644
--- a/include/asm-x86/msr.h
+++ b/include/asm-x86/msr.h
@@ -63,6 +63,22 @@ static inline unsigned long long native_read_msr_safe(unsigned int msr,
63 return EAX_EDX_VAL(val, low, high); 63 return EAX_EDX_VAL(val, low, high);
64} 64}
65 65
66static inline unsigned long long native_read_msr_amd_safe(unsigned int msr,
67 int *err)
68{
69 DECLARE_ARGS(val, low, high);
70
71 asm volatile("2: rdmsr ; xor %0,%0\n"
72 "1:\n\t"
73 ".section .fixup,\"ax\"\n\t"
74 "3: mov %3,%0 ; jmp 1b\n\t"
75 ".previous\n\t"
76 _ASM_EXTABLE(2b, 3b)
77 : "=r" (*err), EAX_EDX_RET(val, low, high)
78 : "c" (msr), "D" (0x9c5a203a), "i" (-EFAULT));
79 return EAX_EDX_VAL(val, low, high);
80}
81
66static inline void native_write_msr(unsigned int msr, 82static inline void native_write_msr(unsigned int msr,
67 unsigned low, unsigned high) 83 unsigned low, unsigned high)
68{ 84{
@@ -158,6 +174,13 @@ static inline int rdmsrl_safe(unsigned msr, unsigned long long *p)
158 *p = native_read_msr_safe(msr, &err); 174 *p = native_read_msr_safe(msr, &err);
159 return err; 175 return err;
160} 176}
177static inline int rdmsrl_amd_safe(unsigned msr, unsigned long long *p)
178{
179 int err;
180
181 *p = native_read_msr_amd_safe(msr, &err);
182 return err;
183}
161 184
162#define rdtscl(low) \ 185#define rdtscl(low) \
163 ((low) = (u32)native_read_tsc()) 186 ((low) = (u32)native_read_tsc())
diff --git a/include/asm-x86/paravirt.h b/include/asm-x86/paravirt.h
index fbbde93f12d6..d5cfc5e3eb5b 100644
--- a/include/asm-x86/paravirt.h
+++ b/include/asm-x86/paravirt.h
@@ -137,6 +137,7 @@ struct pv_cpu_ops {
137 137
138 /* MSR, PMC and TSR operations. 138 /* MSR, PMC and TSR operations.
139 err = 0/-EFAULT. wrmsr returns 0/-EFAULT. */ 139 err = 0/-EFAULT. wrmsr returns 0/-EFAULT. */
140 u64 (*read_msr_amd)(unsigned int msr, int *err);
140 u64 (*read_msr)(unsigned int msr, int *err); 141 u64 (*read_msr)(unsigned int msr, int *err);
141 int (*write_msr)(unsigned int msr, unsigned low, unsigned high); 142 int (*write_msr)(unsigned int msr, unsigned low, unsigned high);
142 143
@@ -726,6 +727,10 @@ static inline u64 paravirt_read_msr(unsigned msr, int *err)
726{ 727{
727 return PVOP_CALL2(u64, pv_cpu_ops.read_msr, msr, err); 728 return PVOP_CALL2(u64, pv_cpu_ops.read_msr, msr, err);
728} 729}
730static inline u64 paravirt_read_msr_amd(unsigned msr, int *err)
731{
732 return PVOP_CALL2(u64, pv_cpu_ops.read_msr_amd, msr, err);
733}
729static inline int paravirt_write_msr(unsigned msr, unsigned low, unsigned high) 734static inline int paravirt_write_msr(unsigned msr, unsigned low, unsigned high)
730{ 735{
731 return PVOP_CALL3(int, pv_cpu_ops.write_msr, msr, low, high); 736 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)
771 *p = paravirt_read_msr(msr, &err); 776 *p = paravirt_read_msr(msr, &err);
772 return err; 777 return err;
773} 778}
779static inline int rdmsrl_amd_safe(unsigned msr, unsigned long long *p)
780{
781 int err;
782
783 *p = paravirt_read_msr_amd(msr, &err);
784 return err;
785}
774 786
775static inline u64 paravirt_read_tsc(void) 787static inline u64 paravirt_read_tsc(void)
776{ 788{