Solaris 8 のソフトウェア開発 (追補)

DMA の切り離し

障害のあるデバイスは、バス上で不適切な DMA 転送を開始する可能性があります。このデータ転送によって、配信済みの正常データが破壊されることがあります。障害のあるデバイスは、そのデバイスのドライバに属さないメモリーにまで悪影響をおよぼすような破壊されたアドレスを生成しかねません。

IOMMU が備わったシステムでは、デバイスは DMA 用に書き込み可能として対応付けされたページに限って書き込むことができます。したがって、DMA 書き込みのターゲットとなるページは、1 つのドライバインスタンスが単独で所有し、他のカーネル構造体と共有することはありません。該当するページが DMA 用に書き込み可能として対応付けされている場合、ドライバはそのページのデータを疑ってみるべきです。ページをドライバの外部に渡す前に、またはデータを検証する前に、ページと IOMMU の対応付けを解除しなければなりません。

ddi_umem_alloc(9F) を使用して、整合ページ全体が割り当てられる、または複数のページを割り当てて最初のページ境界より下のメモリーを無視することができます。ddi_ptob(9F) を使用すると、IOMMU ページのサイズを調べることができます。

あるいは、ドライバは、メモリーの安全な部分にデータをコピーしてから、そのデータを処理することもできます。この場合、最初に ddi_dma_sync(9F) を使用してデータを同期させる必要があります。

ddi_dma_sync(9F) を呼び出すときには、DMA を使用してデバイスにデータを転送する前に SYNC_FOR_DEV を指定し、デバイスからメモリーへ DMA を使用してデータを転送した後で SYNC_FOR_CPU を指定する必要があります。

IOMMU が備わった一部の PCI ベースのシステムでは、デバイスは PCI デュアルアドレスサイクル (64 ビットアドレス) を使用して、IOMMU をバイパスすることができます。その結果、デバイスにおいてメインメモリーの領域が破壊されてしまう潜在的可能性が生じます。強化されたデバイスドライバでは、このようなモードを使用しようとしてはならず、使用不可にしておくべきです。