Linux でのIOMMUサポートについて読んでいて、IOMMU のページ テーブルに関していくつか質問があります。
- IOMMU は VA → PA マッピングを格納するために CPU MMU ページ テーブルを使用しますか?
- そうでない場合、つまり仮想アドレスが異なる場合、マッピングはデバイスごとまたは IOMMU ユニットごとに作成されますか?
私はまだドライバー コードを見ていないので、サンプル ドライバー コードを教えていただけると助かります。
Linux でのIOMMUサポートについて読んでいて、IOMMU のページ テーブルに関していくつか質問があります。
私はまだドライバー コードを見ていないので、サンプル ドライバー コードを教えていただけると助かります。
IOMMU は VA->PA マッピングを格納するために CPU MMU ページ テーブルを使用しますか?
いいえ。OS には多くのプロセスがあり、すべてのプロセスには独自の VA->PA マッピングがあります (それらはすべて別々の仮想アドレス空間で実行されます)。
メモリコントローラによって制御される物理メモリがあります。また、物理メモリにアクセスしたいデバイスがあります: CPU と外部バス コントローラです。CPU には独自の変換があり、バス コントローラーには独自の変換があります。
そうでない場合、つまり仮想アドレスが異なる場合、マッピングはデバイスごとまたは IOMMU ユニットごとに作成されますか?
マッピングは、IOMMU の機能に従って作成されます。一部の単純な IOMMU には、デバイス バス ルート コントローラ (PCI-express ルート コンプリート) 用のグローバル マッピングが 1 つある場合があります。Intel の VT-d のような複雑な IOMMU には、いくつかのポートごとのルールに基づいて選択された、複数のマッピングまたはネストされた変換がある場合があります。(ただし、通常、ブリッジの背後にある 2 つのデバイスは同じ変換になります。)
https://www.kernel.org/doc/Documentation/Intel-IOMMU.txt
Intel IOMMU ドライバーは、ドメインごとに仮想アドレスを割り当てます。各 PCIE デバイスには独自のドメインがあります (保護のため)。p2p ブリッジの下にあるデバイスは、p2p ブリッジのトランザクション ID エイリアシングにより、p2p ブリッジの下にあるすべてのデバイスと仮想アドレスを共有します。
https://www.kernel.org/doc/Documentation/DMA-API-HOWTO.txt
一部のシステムでは、バス アドレスは CPU の物理アドレスと同一ですが、一般的にはそうではありません。IOMMU とホスト ブリッジは、物理アドレスとバス アドレスの間で任意のマッピングを生成できます。
( https://www.kernel.org/doc/Documentation/DMA-API-HOWTO.txtの「Here's a picture and some examples:」の近くの図も確認してください)
仮想アドレス (X)... 仮想メモリ システムは、X をシステム RAM の物理アドレス (Y) にマップします。ドライバーは仮想アドレス X を使用してバッファーにアクセスできますが、DMA は CPU 仮想メモリ システムを経由しないため、デバイス自体はアクセスできません。
一部の単純なシステムでは、デバイスは物理アドレス Y に直接 DMA を実行できます。しかし、他の多くのシステムでは、DMA アドレスを物理アドレスに変換する IOMMU ハードウェアがあります。たとえば、Z を Y に変換します。
https://events.linuxfoundation.org/sites/events/files/slides/20140429-dma.pdf (2014) およびhttp://www.linuxplumbersconf.org/2014/wp-content/uploads/2014/10も確認してください。 /LPC2014_IOMMU.txt
また、http://developer.amd.com/wordpress/media/2012/10/IOMMU-ben-yehuda.pdfペーパー (2012) では、デバイス メモリの再マッピングの歴史と、仮想化のための IOMMU の使用について説明しています。
osgxの答えはカーネルでの IOMMU の歴史的な使用に当てはまりますが、特に PCIe PASID を使用した共有仮想メモリのユースケースでは、IOMMU と CPU ページテーブルを共有またはシャドーイングする必要があります。 dma_map 関連のカーネル サービスなしで、ユーザー空間ドライバーからデバイスに直接渡されます。
もちろん、これには、ユーザー空間がSVM /shared page テーブルを要求できるようにするための新しい API が必要になります。
Intel グラフィックスの SVM を参照してください