Pentium F00F バグ

出典: フリー百科事典『ウィキペディア(Wikipedia)』
移動: 案内検索

f00f("foof"と発音する)は、IntelのPentium、Pentium MMX、Pentiumオーバードライブプロセッサの、ある世代以前のモデルにある、公開されている設計上の不具合の通称である。問題[1]を起こす機械語バイト列「f0 0f c7 c8」の先頭2バイトの16進表現に由来する。

Intelはこの問題を「ロックされたCMPXCHG8B インストラクションでの不正なオペランド」と呼んでいる。

内容[編集]

問題を起こす機械語コード(f0 0f c7 c8)に対応するアセンブリ言語表現は以下のようになる。本来はメモリオペランドを指定して使用する前提の命令であり、下記のコードは実際のアセンブラで処理できないかもしれない。

lock cmpxchg8b eax

不具合を引き起こすにはオペランドはレジスタである必要がある。ここでは例示としてeaxをオペランドにしているが、その他のレジスタでもよい。

cmpxchg8b命令は、オペランドとして指定されたアドレスのメモリ上の8byteの領域を取る。この命令を実行すると、edx:eaxの値とメモリ上の8byte値を比較し、一致したらZフラグをセットするとともにecx:ebxの値をこの8byte領域にストアし、一致しなければZフラグをクリアするとともに8byteのデータをedx:eaxにロードする(コンペア・アンド・スワップ、詳細はリファレンスマニュアル等を参照)。ただし、この命令の機械語では、命令フォーマット上はオペランドにレジスタも指定することが許容される。そして、レジスタオペランドを指定したcmpxchg8b命令を、lockプレフィクス付で実行すると、この不具合が引き起こされる。

lockプレフィックス[2]なしでは、この命令は不正命令例外を引き起こすだけである。即ち、レジスタペアedx:eaxに格納された8byte=64bitのデータと、指定されたレジスタ、上記の例ではeaxに格納された4byte=32bitのデータの比較は妥当ではないからである。

しかし、lockプリフィックスを付けた場合、以後のメモリアクセスが抑制されるために、プロセッサは不正命令例外ハンドラに移行することができず、この段階でハングアップし以後は一切の命令をせず、割り込みも受け付けなくなってしまう。復旧するにはシステムを再起動しなければならない。

対策[編集]

この命令は特別な権限を要求せず、特にユーザープロセスの実行中にOSが全く関与できずに発生すると思われたため、当初は重大な問題と考えられた。以後、OSでの対策が行われるとともに、プロセッサ側でも対策が行われた。

オペレーティングシステムでの対応[編集]

広く普及していたプロセッサにエラッタが発見されたことから、オペレーティングシステムベンダは発生条件を検知してクラッシュを防ぐ対策を実装する作業に追われた。

回避にはオペレーティングシステムでの対策を要する。例外発生時に、例外ハンドラへのアクセスが、まずページフォールトを発生するようにして、不具合を回避する(詳細はインテルの技術資料等を参照)。

プロセッサのバグフィクス[編集]

Pentium Pro以降のIntelプロセッサにはこのバグの影響はない。また、最新のIntel Pentium Processor Speficificationもアップデートされ、B2ステッピングではこの問題は修正されている。

影響[編集]

f00f命令を問題のあるシステム上で実行しても、ハードウェア的なダメージを起こさない。もちろんファイルシステムオペレーティングシステム、その他の状況にもよるが、ディスクバッファがフラッシュされていなかったり書込み操作中にドライブに割り込まれたり、とあるアトミックでない操作中に割り込まれたりした状態でこのコードを踏み、フリーズしたならば、データを失うことはあり得る。

技術的に正しい例えかどうかわからないが、f00f命令はしばしばHCF命令、ないしkiller pokeとして考えられる。f00fバグは一般的に知られたので、この言葉は時々よく似たハードウェア設計ミス、例えばCyrix coma バグようなものを指すのにも使われる。

備考[編集]

  1. ^ OS側で特別の対策をしていないとプロセッサが止まる。
  2. ^ 排他制御を指示するもので、同じメモリアドレスに対して2つのプロセッサが競合しないように使われる。

関連項目[編集]

外部リンク[編集]