DMA の検証

DMA 検証は、ダイレクト メモリ アクセス (DMA) の使用を監視します。 Windows の開発に合わせて DMA ルーチンが変更されたため、多くのドライバーが DMA 呼び出しを誤って使用します。 さらに、一部のドライバー ライターは、HAL DMA サブシステム全体をバイパスしようとします。 その場合、ドライバーに隠れたバグが発生する可能性があります。

ドライバー検証ツールの DMA 検証オプションは、一般的な DMA エラーをキャッチしようとします。 このオプションは、!dma カーネル デバッガー拡張機能と共に、ドライバーが DMA を適切な方法で使用していることを確認するために使用できます。

このドライバー検証ツール オプションは、HAL 検証とも呼ばれます。 この用語は、ドライバー検証ツールによって生成される一部のエラー メッセージで使用される場合があります。

さまざまな種類の DMA

DMA は、ハードウェア デバイスがプロセッサを使用せずにメモリとの間でデータを転送できるメカニズムです。 転送を設定するにはプロセッサが必要です。デバイスは、転送が完了するとプロセッサに通知します。 このシステムの利点は、DMA 転送の実行中にプロセッサが他のタスクを実行できることです。

Windows 2000 以降では、いくつかの種類の DMA が使用されています。

共通バッファー DMA
共通バッファー DMA は、ハードウェアとソフトウェアの両方からアクセスできる単一のバッファーをシステムが割り当てることができる場合に実行されます。 ドライバーは、バッファーへのアクセスの同期を担当します。 メモリはキャッシュされないため、ドライバーにとってこの同期が容易になります。 共通バッファーを設定した後、ドライバーとハードウェアの両方が、HAL からの介入なしでバッファー内のアドレスに直接書き込むことができます。

パケット DMA
パケット DMA は、ハードウェアで使用するためにマップする必要がある既存のバッファーが 1 つある場合に実行されます。 パケット DMA を使用する例として、メモリからディスクへのファイルの転送があります。 この状況で共通バッファー DMA を使用すると、ハードウェアがファイルをディスクに転送する前にそれを共通バッファーに転送する必要があるため、無駄になります。 代わりに、HAL に対する問い合わせが行われ、これによってハードウェアがメモリ内の実際のバッファーを見つけるのに役立つ情報がドライバーに提供されます。 この操作は、関連するルーチンが異なるアーキテクチャ間で動作する必要があるため、複雑になります。

スキャッター/ギャザー DMA
スキャッター/ギャザー DMA は、一度に複数のパケット DMA 転送を設定するショートカット メソッドです。 たとえば、ネットワーク経由でパケットを転送する場合は、ネットワーク スタックの各部分に独自のヘッダー (TCP、IP、イーサネットなど) が追加されます。 これらのヘッダーはすべて、メモリ内の異なる場所から割り当てられます。 この場合、スキャッター/ギャザー DMA は、ハードウェアによるアクセスのために各ヘッダーとデータ セグメントをマップするバッチ要求を HAL に発行することで、時間を節約します。 このメソッドは、パケットの各部分でパケット DMA ルーチンを呼び出す代わりに、各ルーチンを 1 回呼び出し、それぞれを個別にマップする操作を HAL に任せます。

スキャッター/ギャザー機能は、デバイスがスキャッター/ギャザー ルーチンを使用できることを意味するものではありません。 スキャッター/ギャザー機能とは、デバイスが特定の範囲ではなく、メモリ内の任意の領域に対して読み取りまたは書き込みを行うことができることを示す、デバイスの説明内のフラグを指します。

システム DMA
システム DMA は、直接転送を行うようにマザーボード上のシステム DMA コントローラーをプログラミングすることによって実行されます。 システム DMA を使用できるのは ISA カードだけです。

DMA 検証の効果

DMA 検証がアクティブな場合、ドライバー検証ツールは、次のような DMA ルーチンの誤用を検出します。

  • DMA メモリ バッファーのオーバーランまたはアンダーラン (これらのエラーは、ハードウェアまたはドライバーによって発生する可能性があります)。

  • 共通バッファー、アダプター チャネル、マップ レジスタ、またはスキャッター/ギャザー リストの二重の解放。

  • 共通バッファー、アダプター チャネル、マップ レジスタ、スキャッター/ギャザー リスト、またはアダプターを解放しないことによるメモリ リーク。

  • 1 つのアダプターに対して一度に複数のアダプター チャネルが存在する。

  • 既に解放され、存在しなくなったアダプターを使用する試み。

  • アダプター バッファーがフラッシュされない。

  • アダプターの未処理の参照カウントが多すぎる。

  • ページング可能なバッファーに対して DMA を実行する (DMA 転送を開始する前にすべてのバッファーをロックする必要があります)。

  • 無効なフラグを使用して MDL で DMA を実行する。

  • 最初の MDL の前、または最初の MDL の末尾の後、または MDL バッファーよりも長く、かつ MDL 内のページ境界を越える転送長を使用して、無効なシステム アドレスを参照する。

  • 一度に割り当てるマップ レジスタが多すぎる。または、許可されている最大数よりも多くのマップ レジスタを割り当てる。

  • マップ レジスタの二重マッピング。

  • マップ レジスタの一部がまだマップされている間にマップ レジスタを解放する試み。

  • マップされていないマップ レジスタをフラッシュする試み。

  • マップ レジスタ ファイルの末尾でフラッシュしようとしたバイト数が多すぎる。

  • 不適切な IRQL での DMA ルーチンの呼び出し。

  • NULL 値の DMA_ADAPTER が HAL ルーチンに渡される。

  • アドレスが MDL に含まれていないときにアドレスと MDL が HAL ルーチンに渡される。

  • 既にマップされているアドレス範囲をマップする試み。

  • マップされていないバッファーをフラッシュする試み。

  • 転送用に長さ 0 のバッファーをマップする試み。

  • 廃止された関数 HalGetAdapter の呼び出し (すべてのドライバーで代わりに IoGetDmaAdapter を使用する必要があります)。

ドライバーの検証ツールは、ドライバーの動作を監視し、これらの違反が発生した場合はバグ チェック 0xE6 を発行します。 バグ チェック パラメーターのリストについては、「バグ チェック 0xE6」 (DRIVER_VERIFIER_DMA_VIOLATION) を参照してください。

DMA 検証が役立つのはいつですか?

(HAL DMA ルーチンを呼び出すことによって) DMA を直接使用するすべてのドライバーは、DMA 検証を使用してテストする必要があります。

さらに、間接的に DMA を使用することが多いミニポート ドライバーも、(DMA を使用するポート ドライバーを呼び出すことによって) テストする必要があります。

DMA 検証は、ドライバーまたはハードウェア デバイスが DMA バッファーをオーバーランしたことを検出できるため、メモリの破損を検出する効果的な方法でもあります。

DMA 検証の監視

カーネル デバッガー拡張機能 !dma を使用して、豊富な DMA 情報を表示できます。 各 DMA アダプターの動作に関するさまざまな詳細を表示できます。 !dma 拡張機能の詳細な例とデバッガー拡張機能に関する一般的な情報については、Windows 用デバッグ ツール パッケージのドキュメントを参照してください。 詳細については、「Windows のデバッグ」を参照してください。

このオプションのアクティブ化

ドライバー検証ツール マネージャーまたは Verifier.exe コマンド ラインを使用して、1 つ以上のドライバーの DMA 検証機能をアクティブ化できます。 詳細については、「ドライバー検証ツール オプションの選択」を参照してください。

  • コマンド ラインを使用する場合

    コマンド ラインでは、DMA 検証オプションはビット 7 (0x80) で表されます。 DMA 検証をアクティブ化するには、0x80 のフラグ値を使用するか、フラグ値に 0x80 を追加します。 次に例を示します。

    verifier /flags 0x80 /driver MyDriver.sys
    

    この機能は次回の起動後に有効になります。

    Windows Vista 以降のバージョンの Windows では、/volatile パラメーターをコマンドに追加することで、コンピューターを再起動せずに DMA 検証をアクティブ化および非アクティブ化することもできます。 次に例を示します。

    verifier /volatile /flags 0x80 /adddriver MyDriver.sys
    

    この設定はすぐに有効になりますが、コンピューターをシャットダウンまたは再起動すると失われます。 詳細については、「揮発性設定の使用」を参照してください。

    DMA 検証機能は標準設定にも含まれています。 次に例を示します。

    verifier /standard /driver MyDriver.sys
    
  • ドライバー検証マネージャーの使用

    1. ドライバー検証マネージャーを起動します。 コマンド プロンプト ウィンドウに「Verifier」と入力します。
    2. [カスタム設定の作成 (コード開発者用)] を選択し、[次へ] をクリックします。
    3. [完全なリストから個別の設定を選択] を選択します。
    4. [DMA 検証] を選択 (チェック) します。

    DMA 検証機能は標準設定にも含まれています。 この機能を使用するには、ドライバー検証ツール マネージャーで、[標準設定の作成] をクリックします。