EN JA
HWPMC(4)
HWPMC(4) FreeBSD Kernel Interfaces Manual HWPMC(4)

名称

hwpmcハードウェア性能モニタリングカウンタサポート

書式

options HWPMC_HOOKS
device hwpmc

さらに、i386 システムのために:
device apic

解説

hwpmc ドライバは、近代的な CPU でハードウェアの性能のモニタリング機能を仮想化して、ユーザレベルプロセスから、これらの機能を使用するためのサポートを行います。

ドライバは、マルチプロセッサがシステムをサポートします。

PMC は、 PMC_OP_PMCALLOCATE 要求を使用して割り付けられます。 PMC_OP_PMCALLOCATE 要求が成功すれば、要求のプロセスのハンドルを返します。割り付けられた PMC でのその後の操作で、特定の PMC を指示するためにこのハンドルを使用します。 PMC の割り付けを成功したプロセスは、“所有者 (オーナ) プロセス”と呼ばれます。

PMC は、プロセスまたはシステムスコープで割り付けられます。

プロセススコープ
PMC は、それがアタッチされているプロセスに属しているスレッドが CPU 上でスケジュールされるときだけ、アクティブです。
システムスコープ
PMC は、プロセスと関係なく動作して、全体としてシステムのためのハードウェアイベントを測定します。

PMC は、集計のため、またはサンプリングのために割り付けられます:

カウンティング
カウントモードでは、PMC は、ハードウェアイベントをカウントします。これらのカウントは、i386 と amd64 のようないくつかのアーキテクチャは、これらのカウントは、すべてのアーキテクチャで PMC_OP_PMCREAD システムコールを使用して検索可能です。いくつかのアーキテクチャは、これらのカウントを読み込むより速い方法を提供します。
サンプリング
サンプリングモードでは、PMC は、設定可能なハードウェアイベントの数が観測された後に、CPU 命令ポインタをサンプリングするために (とオプションで、サンプリングされた命令ポインタにつながる呼び出しチェーンを獲得するために) 設定されます。通常、命令ポインタのサンプルと呼び出しチェーンの記録は、その後の解析のためにログファイルに向けられます。

スコープと操作モードは、直交しています。したがって、PMC は、次の 4 つのモードの 1 つで動作するために設定されます:

プロセススコープ, カウンティング
これらの PMC は、それらのアタッチされたプロセスでのスレッドが 1 つの CPU でスケジュールされるときはいつも、ハードウェアイベントをカウントします。これらの PMC は、通常 0 からカウントしますが、初期のカウントは、 PMC_OP_SETCOUNT 操作を使用して設定されます。アプリケーションは、 PMC_OP_PMCRW 操作を使用していつでも PMC の値を読み込むことができます。
プロセススコープ, サンプリング
これらの PMC は、ハードウェアイベントの設定された数を調べた後にターゲットのプロセス命令ポインタをサンプリングします。 PMC は、それらのアタッチされたプロセスに属するスレッドがアクティブであるときだけ、イベントをカウントします。望ましいサンプリングの頻度は、 PMC を開始する前に PMC_OP_SETCOUNT 操作を使用して設定されます。ログファイルは、 PMC_OP_CONFIGURELOG 操作を使用して設定されます。
システムスコープ, カウンティング
これらの PMC は、実行しているプロセスと無関係であるそれらによって調べられたハードウェアイベントをカウントします。これらの PMC での現在のカウントは、 PMC_OP_PMCRW 要求を使用して読み込むことができます。これらの PMC は、通常 0 からカウントされますが、初期のカウントは、 PMC_OP_SETCOUNT 操作を使用して設定されます。
システムスコープ, サンプリング
これらの PMC は、それらが割り付けられた CPU の命令ポインタを周期的にサンプリングし、さらなる処理のためのログにサンプルを書き込みます。望ましいサンプリングの頻度は、PMC を開始する前に PMC_OP_SETCOUNT 操作を使用して設定されます。ログファイルは、 PMC_OP_CONFIGURELOG 操作を使用して設定されます。

システム全体の統計のサンプリングは、スーパユーザの特権があるプロセスによってのみ有効にすることができます。

プロセスは、ハードウェアと現在の操作条件許可と同じ数の PMCs を割り付けることができます。プロセスは、システム全体とプロセスプライベートな PMC の割り付けを混在することができます。複数のプロセスは、同時に PMC を使用します。

割り付けられた PMC は、 PMC_OP_PMCSTART 操作が使用して開始され、 PMC_OP_PMCSTOP 操作を使用して停止されます。 PMC の停止と開始は、所有者のプロセスが PMC への有効なハンドルをもつときは、いつでも許可されます。

それらを使用することができるようになる前にターゲットプロセスは、プロセスプライベート PMC をアタッチする必要があります。 PMC にプロセスをアタッチすることは、 PMC_OP_PMCATTACH 操作を使用して行われます。既にアタッチされている PMC は、逆の PMC_OP_PMCDETACH 操作を使用してターゲットプロセスからデタッチされます。まだ、アタッチされていないままの PMC で PMC_OP_PMCSTART 操作を発行することによって、所有者のプロセスをそれにアタッチします。次の規則は、与えられたプロセスが PMC を別のターゲットプロセスにアタッチするかどうかを決定します:

  • スーパユーザ特権がある jail (投獄) されていないプロセスは、システムのいかなる他のプロセスにもアタッチすることができます。
  • 他のプロセスは、それらが ( p_candebug(9) で決定されるような) デバッグのためにアタッチできるターゲットにのみアタッチできます。

PMC は、 PMC_OP_PMCRELEASE を使用して解放されます。 PMC_OP_PMCRELEASE 操作が成功した後に、PMC へのハンドルは、無効になります。

修飾子フラグ

PMC_OP_PMCALLOCATE 操作は、割り付けられた PMC の振る舞いを変更する次のフラグをサポートします:
PMC_F_CALLCHAIN
この修飾子は、サンプルを獲得するとき、呼び出しチェーンを記録するために PMC のサンプリングを通知します。呼び出しチェーンが記録される最大の深さは、 kern.hwpmc.callchaindepth カーネル調整変数によって指定されます。
PMC_F_DESCENDANTS
この修飾子は、プロセスプライベートモードで割り付けられている PMC だけに有効です。それは、PMC がターゲットプロセスとターゲットの現在と将来の子孫のためのハードウェアイベントを追跡することを意味します。
PMC_F_KGMON
この修飾子は、システム全体のサンプリングモードで割り付けられている PMC だけに有効です。それは、PMC のサンプリング割り込みが kgmon(8) を通してカーネルプロファイルをドライブするために使用されることを意味します。この機能は、現在、未実装です。
PMC_F_LOG_PROCCSW
この修飾子は、プロセスプライベートモードで割り付けられている PMC だけに有効です。この修飾子があらゆるコンテキストスイッチに存在しているとき、 hwpmc は、それが CPU でスケジュールされたときターゲットプロセスによって調べれられたハードウェアイベントの数を含むレコードをログ記録します。
PMC_F_LOG_PROCEXIT
この修飾子は、プロセスプライベートモードで割り付けられている PMC だけに有効です。この修飾子が存在していると、 hwpmc は、PMC にアタッチされた各ターゲットプロセスのためのプロセスごとのカウントを保持します。プロセスの終了時に、そのプロセスのためのターゲットプロセスの PID とプロセスごとに蓄積されたカウントを含むレコードは、設定されたログファイルに書き込まれます。

修飾子 PMC_F_LOG_PROCEXITPMC_F_LOG_PROCCSW は、プロセスの複雑なパイプラインの振る舞いを追跡するために修飾子 PMC_F_DESCENDANTS と組み合わせて使用されます。修飾子 PMC_F_LOG_PROCEXITPMC_F_LOG_PROCCSW がある PMC は、それらの所有者のプロセスがログファイルを設定するまで、開始することができません。

シグナル

hwpmc ドライバは、割り付けられた PMC があるプロセスにシグナルを配信します:
SIGIO
PMC_OP_PMCRW 操作が、アタッチされたターゲットプロセスがない、プロセスプライベートな PMC で試みられました。
SIGBUS
hwpmc ドライバは、カーネルからアンロードされています。

PMC 行の傾向

PMC 行は、システムの CPU の同じハードウェアアドレスで PMC リソースのセットとして定義されます。プロセススコープ PMC は、それらのターゲットスレッドに従う CPU の間で動く必要があるので、プリセススコープ PMC の割り付けは、プロセススコープ PMC でのみ使用するために PMC 行のすべての PMC を予約します。それに従って、PMC 行は、次の傾向の 1 つになります:
PMC_DISP_FREE
この行のハードウェアカウンタは、フリー (空き) であり、システムスコープまたはプロセススコープの割り付け要求を満たすために使用されます。
PMC_DISP_THREAD
この行のハードウェアカウンタは、プロセススコープ PMC によって使用中であり、プロセススコープ割り付け要求にのみ利用可能です。
PMC_DISP_STANDALONE
この行のいくつかのハードウェアカウンタは、管理上無効にされているか、またはシステムスコープ PMC によって使用中です。そのような行の無効化されないハードウェアカウンタは、システムスコープ割り付け要求を満たすのに使用されます。プロセススコープ PMC は、この行でハードウェアカウンタを使用しません。

プログラミング API

アプリケーションプログラムが hwpmc ドライバの機能を使用するためのお勧めの方法は、 pmc(3) ライブラリによって提供された API を使用することです。

hwpmc ドライバは、それがカーネルにロードされるとき、動的にそれに割り付けられたシステムコール番号を使用して動作します。

hwpmc ドライバは、次の操作をサポートします:

PMC_OP_CONFIGURELOG
ログファイルを必要とする PMC のためのログファイルを設定します。 hwpmc ドライバは、ログデータをこのファイルに非同期に書き込みます。エラー遭遇するなら、ログ記録は、停止され、遭遇したエラーコードが、 PMC_OP_FLUSHLOG 要求によって、その後の検索のために保存されます。
PMC_OP_FLUSHLOG
hwpmc の中にバッファリングされたログデータを設定された出力ファイルに転送します。この操作は、書き込み操作が返されたの後に呼び出し側に返ります。返されたエラーコードは、 hwpmc 内の任意の保留中 (pending) のエラー状態を反映します。
PMC_OP_GETCPUINFO
システムのできるだけ大きな CPU 番号、と CPU ごとに利用可能なハードウェア性能モニタリングカウンタの数に関する情報を検索します。
PMC_OP_GETDRIVERSTATS
( hwpmc 自体の振る舞いを解析するための) モジュール統計を検索します。
PMC_OP_GETMODULEVERSION
API のバージョン番号を検索します。
PMC_OP_GETPMCINFO
与えられた CPU 上で PMC の現在の状態に関する情報を検索します。
PMC_OP_PMCADMIN
hwpmc ドライバによって管理されたハードウェア PMC のための管理状態 (すなわち、有効にされるか、または無効にされるかどうか) を設定します。呼び出しプロセスは、 PRIV_PMC_MANAGE 特権を保有する必要があります。
PMC_OP_PMCALLOCATE
PMC を割り付けて、設定します。割り付けが成功すれば、PMC (32 ビット値) へのハンドルが返されます。
PMC_OP_PMCATTACH
プロセスモード PMC をターゲットプロセスにアタッチします。ターゲットプロセスのスレッドが CPU 上でスケジュールされるときはいつでも PMC は、アクティブになります。

PMC_F_DESCENDANTS フラグが PMC 割り付け時に指定されたなら、PMC は、ターゲットプロセスのすべての現在と将来の子孫にアタッチされます。

PMC_OP_PMCDETACH
ターゲットプロセスから PMC をデタッチします。
PMC_OP_PMCRELEASE
PMC を解放します。
PMC_OP_PMCRW
PMC を読み込んでで書き込みます。この操作は、カウントモードで設定された PMC だけに有効です。
PMC_OP_SETCOUNT
(カウントモード PMC のための) 初期のカウントか、または (サンプルモード PMC のための) 必要なサンプリングレートを設定します。
PMC_OP_PMCSTART
PMC を開始します。
PMC_OP_PMCSTOP
PMC を停止します。
PMC_OP_WRITELOG
タイムスタンプの付いたユーザレコードをログファイルに挿入します。

i386 特有の API

いくつかの i386 ファミリの CPU は、ユーザプロセスが、 PMC_OP_PMCRW 操作を呼び出す必要なしで PMC 値を読み込むことができる RDPMC 命令をサポートします。そのような CPU では、割り付けられた PMC に関連しているマシンアドレスは、 PMC_OP_PMCX86GETMSR システムコールを使用して検索可能です。
PMC_OP_PMCX86GETMSR
与えられた PMC ハンドルに関連している MSR (マシン特有のレジスタ) 番号を検索します。

PMC は、プロセスプライベートモードであることが必要であり、 PMC_F_DESCENDANTS 修飾子フラグなしで割り付けられ、呼び出し時点で、所有者のプロセスだけアタッチされるべきです。

amd64 特有の API

AMD64 CPU は、ユーザプロセスが、 PMC_OP_PMCRW 操作を呼び出す必要なしで PMC 値を読み込むことができる RDPMC 命令をサポートします。割り付けられた PMC に関連しているマシンアドレスは、 PMC_OP_PMCX86GETMSR システムコールを使用して検索可能です。
PMC_OP_PMCX86GETMSR
与えられた PMC ハンドルに関連している MSR (マシン特有のレジスタ) 番号を検索します。

PMC は、プロセスプライベートモードであることが必要であり、 PMC_F_DESCENDANTS 修飾子フラグなしで割り付けられ、呼び出し時点で、所有者のプロセスだけアタッチされるべきです。

SYSCTL 変数とローダ調整変数

hwpmc の振る舞いは、次の sysctl(8)loader(8) 調整変数によって影響されます:
kern.hwpmc.callchaindepth (整数, 読み込み専用)
サンプル毎に獲得するチェーンレコードを呼び出しの最大数。デフォルトは、8 です。
kern.hwpmc.debugflags (文字列, 読み込み書き込み)
( hwpmc ドライバが -DDEBUG でコンパイルされた場合のみ利用可能です。) hwpmc ドライバからのデバッグメッセージの冗長さを制御します。
kern.hwpmc.hashsize (整数, 読み込み専用)
ハッシュテーブルの列の数は、所有者とターゲットプロセスの経過を追うために使用されます。デフォルトは、16 です。
kern.hwpmc.logbuffersize (整数, 読み込み専用)
hwpmc のログ記録関数によって使用される各ログバッファのキロバイト単位のサイズ。デフォルトのバッファサイズは、4KB です。
kern.hwpmc.mtxpoolsize (整数, 読み込み専用)
PMC ドライバによって使用されるスピンミューテックスプールのサイズ。デフォルトは、32 です。
kern.hwpmc.nbuffers (整数, 読み込み専用)
ログ記録のために hwpmc によって使用されるログバッファの数。デフォルトは、64 です。
kern.hwpmc.nsamples (整数, 読み込み専用)
サンプリングの間に使用される CPU ごとのリングバッファのエントリの数。デフォルトは、512 です。
security.bsd.unprivileged_syspmcs (ブール値, 読み込み書き込み)
0 以外に設定されるなら、非特権プロセスは、システム全体の PMC を割り付けることができます。デフォルト値は、0 です。
security.bsd.unprivileged_proc_debug (ブール値, 読み込み書き込み)
0 に設定されるなら、 hwpmc ドライバは、特権があるプロセスのみ PMC を他のプロセスにアタッチすることができます。

これらの変数は、 hwpmc がロードされる前に、 kenv(1) を使用するカーネル環境で設定されます。

実装に関する注

SMP 対称性

カーネルドライバは、SMP システムのすべての物理的な CPU には、同一の性能モニタリングカウンタハードウェアがあることを必要とします。

まばらな CPU 番号付け

まばらな数の CPU と CPU の活線そうばつ (hot-plugging) をサポートするプラットフォームでは、実在しないか、または無効にされている CPU を指定する要求は、エラーで失敗します。システムスコープ PMC を割り付けるアプリケーションは、そのような一時的障害の可能性を注意している必要があります。

x86 TSC 操作

歴史的に、x86 アーキテクチャでは、 FreeBSD は、RDTSC 命令を使用して TSC を読み込むために 3 のプロセッサ CPL でユーザプロセスを実行することを許します。 hwpmc ドライバは、この振る舞いを保存しています。

Intel P4/HTT 操作

HTT サポートがある CPU では、Intel P4 PMC は、論理的な CPU の基準ごとにハードウェアイベントの部分集合のみに限定することができます。その結果として、HTT が Intel Pentium P4 PMC があるシステムで有効にされるなら、 hwpmc ドライバは、別々にそれぞれの論理的な CPU をカウントできないハードウェアイベントのカウントを要求するプロセスプライベートな PMC を要求する割り付けを拒否します。

Intel Pentium-Pro 操作

Intel Pentium-Pro スタイル PMC (Intel Pentium Pro, Pentium II, Pentium III, Pentium M と Celeron プロセッサ) で見つけられる PMC MSR に値を書き込むことは、これらの PMC の使用可能な幅を 31 ビットまで減少して、 MSR の上位 8 ビットに書き込まれている値のビット 31 を複写します。プロセス仮想 PMC に関しては、 hwpmc ドライバは、ソフトウェアの次善策を実装して、 PMC_OP_RW 操作を通して訂正された 64 ビットカウントを利用可能にします。直接 RDPMC 命令を使用しようとするか、または PMC_OP_RW でこれらの PMC に 2^31 より大きい値を書き込もうとするプロセスは、このハードウェア制限を承知している必要があります。

診断

hwpmc: [class/npmc/capabilities]...
ビット文字列 capabilities によって記述されているケーパビリティで、クラス class のクラスの npmc PMC の存在をアナウンスします。
hwpmc: kernel version (0x%x) does not match module version (0x%x).
「カーネルバージョン (0x%x) は、モジュールバージョン (0x%x) に適合しません.」現在実行しているカーネルとロードされているモジュールの間でバージョンミスマッチが検出されたので、モジュールローディングプロセスは、失敗しました。
hwpmc: this kernel has not been compiled with 'options HWPMC_HOOKS'.
「このカーネルは、'options HWPMC_HOOKS' でコンパイルされていません.」現在実行しているカーネルが必要な設定オプション HWPMC_HOOKS で設定されていなかったので、モジュールローディングプロセスは、失敗しました。
hwpmc: tunable hashsize=%d must be greater than zero.
「調整変数 hashsize=%d は、0 より大きくなければなりません.」負の値が調整変数 kern.hwpmc.hashsize に供給されました。
hwpmc: tunable logbuffersize=%d must be greater than zero.
「調整変数 logbuffersize=%d は、0 より大きくなければなりません.」負の値が調整変数 kern.hwpmc.logbuffersize に供給されました。
hwpmc: tunable nlogbuffers=%d must be greater than zero.
「調整変数 nlogbuffers=%d は、0 より大きくなければなりません.」負の値が調整変数 kern.hwpmc.nlogbuffers に供給されました。
hwpmc: tunable nsamples=%d out of range.
「調整変数 nsamples=%d は、範囲外です.」調整変数 kern.hwpmc.nsamples のための値は、負または 65535 より大きいです。

互換性

hwpmc ドライバは、現在、開発中です。このマニュアルページに文書化された API と ABI は、将来、変更されるかもしれません。このドライバをアクセスするお勧めの方法は、 pmc(3) API を使用することです。

エラー

hwpmc ドライバに発行されたコマンドは、次のエラーで失敗するかもしれません:
[ EAGAIN]
ヘルパプロセス作成は、カーネルの一時的なリソース不足によって PMC_OP_CONFIGURELOG 要求のために失敗しました。
[ EBUSY]
既存のログがアクティブであった間に PMC_OP_CONFIGURELOG 操作が要求されました。
[ EBUSY]
DISABLE 操作は、現在プロセスプライベートな PMC で使用中の 1 組のハードウェアリソースを要求する PMC_OP_PMCADMIN を使用して要求されました。
[ EBUSY]
PMC_OP_PMCADMIN 操作は、アクティブシステムモード PMC で要求されました。
[ EBUSY]
PMC_OP_PMCATTACH 操作は、それにアタッチされた同じハードウェアリソースを使用して既に別の PMC があるターゲットプロセスのために要求されました。
[ EBUSY]
新しい値を書き込む PMC_OP_PMCRW 要求は、アクティブであった PMC で発行されました。
[ EBUSY]
PMC_OP_PMCSETCOUNT 要求は、アクティブであった PMC で発行されました。
[ EDOOFUS]
PMC_OP_PMCSTART 操作が、 PMC_F_LOG_PROCCSWPMC_F_LOG_PROCEXIT 修飾子と共に割り付けられた PMC のために設定されているログファイルなしで要求されました。
[ EDOOFUS]
PMC_OP_PMCSTART 操作が、構成されているログファイルなしでシステム全体のサンプリング PMC で要求されました。
[ EEXIST]
PMC_OP_PMCATTACH 要求が、既にこの PMC のターゲットであるターゲットプロセスのために再発行されました。
[ EFAULT]
悪いアドレスが、ドライバに渡されました。
[ EINVAL]
無効の PMC ハンドルが指定されました。
[ EINVAL]
無効の CPU 番号が、 PMC_OP_GETPMCINFO 操作のために渡されました。
[ EINVAL]
ログファイルを設定しない PMC_OP_CONFIGURELOG 要求が、構成されているログファイルなしで出力されました。
[ EINVAL]
PMC_OP_FLUSHLOG 要求が、構成されているログファイルなしで出力されました。
[ EINVAL]
無効の CPU 番号が、 PMC_OP_PMCADMIN 操作のために渡されました。
[ EINVAL]
無効の操作要求が、 PMC_OP_PMCADMIN 操作のために渡されました。
[ EINVAL]
無効の PMC ID が、 PMC_OP_PMCADMIN 操作のために渡されました。
[ EINVAL]
PMC_OP_PMCALLOCATE 要求に渡されたパラメータに適合する適当な PMC を、割り付けることができませんでした。
[ EINVAL]
無効の PMC モードが、 PMC_OP_PMCALLOCATE 要求の間に要求されました。
[ EINVAL]
無効の CPU 番号が、 PMC_OP_PMCALLOCATE 要求の間に指定されました。
[ EINVAL]
PMC_CPU_ANY 以外の CPU が、プロセスプライベートな PMC のための PMC_OP_PMCALLOCATE 要求で指定されました。
[ EINVAL]
PMC_CPU_ANY の CPU 番号が、システム全体の PMC のための PMC_OP_PMCALLOCATE 要求で指定されました。
[ EINVAL]
PMC_OP_PMCALLOCATE 要求への pm_flags 引数が未知のフラグを含んでいます。
[ EINVAL]
(HTT サポートがある Intel Pentium 4 CPU で) プロセスプライベート PMC のための PMC_OP_PMCALLOCATE 要求は、論理 CPU ベース毎に集計をサポートしないイベントのために出力されます。
[ EINVAL]
システム全体の操作のために割り付けられた PMC が、 PMC_OP_PMCATTACH または PMC_OP_PMCDETACH 要求で指定されました。
[ EINVAL]
PMC_OP_PMCATTACH または PMC_OP_PMCDETACH 要求への pm_pid 引数が不正なプロセス ID を指定しました。
[ EINVAL]
PMC_OP_PMCDETACH 要求がターゲットプロセスにアタッチされなかった PMC のために発行されました。
[ EINVAL]
PMC_OP_PMCRW 要求への引数 pm_flags は、不正なフラグを含んでいます。
[ EINVAL]
PMC_OP_PMCX86GETMSR 操作が、プロセス仮想モードでないの PMC のために、または、所有者のプロセスに唯一アタッチされない PMCのために、または、フラグ PMC_F_DESCENDANTS で割り付けられた PMC のために要求されました。
[ EINVAL]
PMC_OP_WRITELOG 要求は、設定されたログファイルなしで所有者プロセスのために出力されます。
[ ENOMEM]
システムは、カーネルメモリを割り付けることができませんでした。
[ ENOSYS]
(i386 と amd64 アーキテクチャで) PMC_OP_PMCX86GETMSR 操作が、RDPMC 命令で直接 PMC の読み込みをサポートしないハードウェアのために要求されました。
[ ENXIO]
PMC_OP_GETPMCINFO 操作が、欠けているか、または無効となっている CPU に対して要求されました。
[ ENXIO]
PMC_OP_PMCALLOCATE 操作が、欠けているか、または無効となっている CPU で、システム全体の PMC の割り付けを指定しました。
[ ENXIO]
PMC_OP_PMCSTART または PMC_OP_PMCSTOP 要求が、現在、欠けているか、または無効となっている CPU で割り付けられたシステム全体の PMC のために発行されました。
[ EOPNOTSUPP]
PMC_OP_PMCALLOCATE 要求が、指定された PMC のクラスによってサポートされなかった PMC ケーパビリティのために発行されました。
[ EOPNOTSUPP]
(i386 アーキテクチャ) サンプリングモード PMC が、APIC が欠けている CPU で要求されました。
[ EPERM]
PMC_OP_PMCADMIN 要求が、スーパユーザ特権のないプロセス、または jail (投獄) されたスーパユーザプロセスによって発行されました。
[ EPERM]
PMC_OP_PMCATTACH 操作が、現在のプロセスがアタッチするパーミッションがないターゲットプロセスのために発行されました。
[ EPERM]
(i386 と amd64 アーキテクチャ) MSR が PMC_OP_PMCX86GETMSR を使用して検索された PMC で PMC_OP_PMCATTACH 操作が発行されました。
[ ESRCH]
PMC 操作を発行したプロセスが、任意の PMC 割り付けなしに要求しました。
[ ESRCH]
PMC 操作を発行したプロセスは、PMC がすべてのターゲットプロセスからデタッチされた後に要求しました。
[ ESRCH]
PMC_OP_PMCATTACH または PMC_OP_PMCDETACH 要求が実在しないプロセス ID を指定しました。
[ ESRCH]
PMC_OP_PMCDETACH 操作のためのターゲットプロセスは、 hwpmc によってモニタされていません。

歴史

hwpmc ドライバは、 FreeBSD 6.0 ではじめて登場しました。

作者

hwpmc ドライバは、 Joseph Koshy <jkoshy@FreeBSD.org>によって書かれました。

バグ

ドライバは、初期化の (すなわち、モジュールロード時) 時点で、カーネルの論理的なプロセッサのサポートの状態をサンプリングします。論理的なプロセッサをサポートする CPU では、ドライバがアクティブである間に論理的なプロセッサがその後に有効にされるか、または無効にされるなら、ドライバは、不作法に振る舞うかもしれません。

i386 アーキテクチャでは、ドライバは、CPU でローカル APIC がサポートされているサンプリングモードが有効にされることを必要とします。多くの単一プロセッサのマザーボードは、BIOS で APIC を無効にし続けます。そのようなシステムでは、 hwpmc は、サンプリング PMC をサポートしません。

セキュリティの考察

PMC は、ハードウェアでのシステムの実際の振る舞いをモニタするために使用されます。望ましくない情報漏洩を構成する場所の状況で、次のオプションが利用可能です:
  1. sysctl(8) 調整変数 security.bsd.unprivileged_syspmcs を 0 に設定します。これは、非特権のプロセスがシステム全体の PMC を割り付けることができず、その結果、全体としてシステムのハードウェアの振る舞いを観測することができないようにします。また、この調整変数は、 loader(8) を使用するブート時に、または、 hwpmc ドライバをカーネルにロードする前の kenv(1) でも設定できます。
  2. sysctl(8) 調整変数 security.bsd.unprivileged_proc_debug を 0 に設定します。これは、非特権のプロセスが PMC を、それ自体以外の任意のプロセスにアタッチすることができず、その結果、同じ資格証明がある他のプロセスのハードウェアの振る舞いを観測することができないようにします。

システム管理者は、IA-32 プラットフォームで FreeBSD が、IA-32 TSC カウンタの内容を RDTSC 命令を通してすべてのプロセスに利用可能とすることに注意するべきです。

November 2, 2012 FreeBSD