web-dev-qa-db-ja.com

LinuxでCPUモデル固有のレジスタを読み取る

私はUbuntu15.10を実行していますが、Debianでもテストしています。私はInteli5-5675Cプロセッサを持っています。私はそれを行うためにmsr-tools-1.3を使用しています。次のコマンドでレジスタ0x00001a2を読み取ることができます。

rdmsr 0x00001a2

データシートによると、それは私にいくつかの良い出力を与えます。しかし、私はこの値で便利なことは何もできません。

温度や電圧などに関連するモデル固有のレジスタをCPUから読み取りたいと思います。データシート情報:

データシートVol 1

データシートVol 2

データシートVol2から:5.2.52 IA32-IA32_THERM_STATUS

 rdmsr 0x000059c0
 rdmsr: CPU 0 cannot read MSR 0x000059c0

このようなエラーが発生します。 4つのCPUコアすべてで実行してみましたが、modprobeを有効にしました。ファイルは/ dev/cpu/{CPU_ID}/msrにあります。

Sudo modprobe msr

Straceの出力は次のとおりです。

Sudo strace rdmsr 0x59c0
execve("/usr/sbin/rdmsr", ["rdmsr", "0x59c0"], [/* 25 vars */]) = 0
brk(0)                                  = 0x84d000
access("/etc/ld.so.nohwcap", F_OK)      = -1 ENOENT (No such file or directory)
mmap(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7fe87cb3f000
access("/etc/ld.so.preload", R_OK)      = -1 ENOENT (No such file or directory)
open("/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3
fstat(3, {st_mode=S_IFREG|0644, st_size=92026, ...}) = 0
mmap(NULL, 92026, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7fe87cb28000
close(3)                                = 0
access("/etc/ld.so.nohwcap", F_OK)      = -1 ENOENT (No such file or directory)
open("/lib/x86_64-linux-gnu/libc.so.6", O_RDONLY|O_CLOEXEC) = 3
read(3, "\177ELF\2\1\1\3\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0`\v\2\0\0\0\0\0"..., 832) = 832
fstat(3, {st_mode=S_IFREG|0755, st_size=1869392, ...}) = 0
mmap(NULL, 3972864, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7fe87c554000
mprotect(0x7fe87c714000, 2097152, PROT_NONE) = 0
mmap(0x7fe87c914000, 24576, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x1c0000) = 0x7fe87c914000
mmap(0x7fe87c91a000, 16128, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x7fe87c91a000
close(3)                                = 0
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7fe87cb27000
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7fe87cb26000
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7fe87cb25000
Arch_prctl(Arch_SET_FS, 0x7fe87cb26700) = 0
mprotect(0x7fe87c914000, 16384, PROT_READ) = 0
mprotect(0x602000, 4096, PROT_READ)     = 0
mprotect(0x7fe87cb41000, 4096, PROT_READ) = 0
munmap(0x7fe87cb28000, 92026)           = 0
open("/dev/cpu/0/msr", O_RDONLY)        = 3
pread(3, 0x7ffcd2bddf78, 8, 22976)      = -1 EIO (Input/output error)
write(2, "rdmsr: CPU 0 cannot read MSR 0x0"..., 40rdmsr: CPU 0 cannot read MSR 0x000059c0
) = 40
exit_group(4)                           = ?
+++ exited with 4 +++
4
Zwierzak

データシートを読み間違えました。

IA32—IA32_THERM_STATUSは、CPU MSRではなく、プラットフォームPCIデバイスの構成レジスタです。 rdmsrを使用して読み取ることはできません。

1

次の行に注意してください。

pread(3, 0x7ffcd2bddf78, 8, 22976)      = -1 EIO (Input/output error)

ここで、22976 = 0x59c0は、読み取ろうとしているMSRアドレスです。 EIOエラーは、 msr_read 関数で rdmsr_safe_on_cpu を呼び出して rdmsr_safe マクロで native_read_msr_safe 関数を呼び出すと、RDMSR命令の実行時に#GP例外が発生します。

そのため、CPUは読み取ろうとしているMSRをサポートしていません。

しかし、 answer by duskwuff で指摘されているように、間違ったデータシートを読んでいます。オフセット0x59c0は、MCHBARを基準にしたオフセットであり、memoryスペースを指します。これはMSRのアドレスではありません。正しいMSRアドレスを見つけるには、インテルのマニュアルの Volume 3B –システムプログラミングガイド 、つまりその第14.4章を読む必要があります。 IA32_THERM_STATUSIA32—IA32_THERM_STATUSではなく注意)MSRのアドレスは0x19cであると言われています。

1
Ruslan

2つのことが飛び出します

open("/dev/cpu/0/msr", O_RDONLY) = 3

値3のファイル記述子を返すオープンパス

msr registersはRootでのみ読み取り/書き込みが可能です。 manページ これは明確です。

須藤は[〜#〜] s [〜#〜]uper[〜#〜] uの略でした[〜#〜]ser[〜#〜] do [〜#〜]。最近のLinuxでは、[〜#〜] s [〜#〜]ubstitute[〜#〜]に似ていますu [〜#〜]ser[〜#〜] do [〜#〜]。 Sudoは、タスクを実行するユーザーが必ずしもルートであるという意味ではありません。多くの場合、一時的にユーザーのステータスを上げて、そのユーザーとしてasを実行します。したがって、mayがroot権限を持っていても、canは失敗しますUserID == 0 小切手。

ルートシェルで同じコマンドを試して、失敗するかどうかを確認します。

0
Valarauca