Cyrix coma バグ

From Wikipedia, the free encyclopedia

Cyrix coma バグは、サイリックス製のCPUであるCyrix 6x86、6x86L、およびRev. 1.4までの6x86MXに存在する、CPUの設計上の不具合(エラッタ)の通称である[1]。「coma」は「昏睡」を意味する医学用語で、特権をもたないコードが割り込みを無視する状態で無限ループに陥ってしまう状態を昏睡になぞらえている[2]

1996年頃、ロシア人で当時モスクワ在住のプログラマであったセルゲイ・シュティリョフが、アセンブリ言語を使用したIDEディスクのデバイスドライバの開発中に、この問題に気づいたとされる[1][注 1]。この件の詳細を当時西シベリアオムスク在住だったアレクサンドル・コノセヴィチが詳細を調査し、当時ドイツのコンピュータ雑誌「c't」の編集者であったウーヴェ・ポストドイツ語版と連絡を取り合い、ポストと共同で執筆した記事が同誌の1997年13号に「サイリックスでのハロウィン」というタイトルで掲載された[3]。同記事の中ではこの現象は「Hidden-CLI-Bug(隠れたCLIバグ)」と呼ばれていた[注 2]

動作原理

以下のようなインラインアセンブリを使ったコードが、非特権ユーザーによってコンパイル・実行できることが確認されている[1]

unsigned char c[4] = {0x36, 0x78, 0x38, 0x36}; // "6x86"
int main()
{
  asm (
  "        movl    $c, %ebx\n"
  "again:  xchgl   (%ebx), %eax\n"
  "        movl    %eax, %edx\n"
  "        jmp     again\n"
  );
}

6x86を使用したシステムでこのプログラムを実行すると、CPUは割り込みの効かない無限ループに陥り、リセットなどによるシステムの再起動以外で終了させることはできなくなる[注 3]

このコードには割り込みを禁止する命令は含まれていないが、xchg命令が分割不能(アトミック)な命令のため、CPUはこの命令の実行中には割り込みを禁止するように設計されている。ところが、CPUの命令パイプラインと分岐予測により、最初のxchg命令の処理とその処理結果と依存関係にあるmov命令が完了する前に、jump命令の飛び先である次のxchg命令がパイプラインに入ってしまい、その結果割り込みが許可されるタイミングを失い、デッドロックを起こしてしまうと推測されている[1]

ただし、実際にはコンパイラが上記のようなコードを出力することはないと思われ、アセンブリ言語で意図的に記述する以外では、この問題に遭遇することはないと考えられている。

回避策

最も簡単な対応は、CPUコントロールレジスタ(CCR1)の4bit目(NO_LOCKビット)を1にして、xchg命令中のバスロックを解除することである[1][注 4]。先述のコードの場合、ループ内にnop命令など別の命令を追加することにより、割り込みが実行できる余地ができる[注 5]。当時サイリックスが非公式で配布していた対策プログラムでは、Windows/DOS用の実行ファイルを逆アセンブルして調査したところ、非公開のCPUコントロールレジスタを使用してxchg命令をデバッグ用のコードとして定義し、該当命令をシリアライズすることで対応していたことが判明している[2]

出典

注釈

関連項目

外部リンク

Related Articles

Wikiwand AI