diff options
| author | Yinghai Lu <yhlu.kernel@gmail.com> | 2008-08-22 04:32:50 -0400 |
|---|---|---|
| committer | Ingo Molnar <mingo@elte.hu> | 2008-08-22 04:43:21 -0400 |
| commit | b05f78f5c713eda2c34e495d92495ee4f1c3b5e1 (patch) | |
| tree | 87dd57341abc375131d3268d33c504e3eb609462 | |
| parent | c9c3dddd8f9a05b25d4ce53e8e80cc0ea1759d18 (diff) | |
x86_64: printout msr -v2
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>
| -rw-r--r-- | Documentation/kernel-parameters.txt | 6 | ||||
| -rw-r--r-- | arch/x86/kernel/cpu/common_64.c | 51 | ||||
| -rw-r--r-- | arch/x86/kernel/paravirt.c | 1 | ||||
| -rw-r--r-- | include/asm-x86/msr.h | 23 | ||||
| -rw-r--r-- | include/asm-x86/paravirt.h | 12 |
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 | ||
| 397 | struct msr_range { | ||
| 398 | unsigned min; | ||
| 399 | unsigned max; | ||
| 400 | }; | ||
| 401 | |||
| 402 | static struct msr_range msr_range_array[] __cpuinitdata = { | ||
| 403 | { 0x00000000, 0x00000418}, | ||
| 404 | { 0xc0000000, 0xc000040b}, | ||
| 405 | { 0xc0010000, 0xc0010142}, | ||
| 406 | { 0xc0011000, 0xc001103b}, | ||
| 407 | }; | ||
| 408 | |||
| 409 | static 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 | |||
| 427 | static int show_msr __cpuinitdata; | ||
| 428 | static __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 | |||
| 397 | void __cpuinit print_cpu_info(struct cpuinfo_x86 *c) | 440 | void __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 | ||
| 408 | static __init int setup_disablecpuid(char *arg) | 459 | static __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 | ||
| 66 | static 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 | |||
| 66 | static inline void native_write_msr(unsigned int msr, | 82 | static 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 | } |
| 177 | static 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 | } |
| 730 | static 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 | } | ||
| 729 | static inline int paravirt_write_msr(unsigned msr, unsigned low, unsigned high) | 734 | static 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 | } |
| 779 | static 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 | ||
| 775 | static inline u64 paravirt_read_tsc(void) | 787 | static inline u64 paravirt_read_tsc(void) |
| 776 | { | 788 | { |
