Linuxでは、いつデバイスがDMAを介してメインメモリに書き込むことができますか?

Linuxでは、いつデバイスがDMAを介してメインメモリに書き込むことができますか?

LinuxがPCIeの周辺機器に直接メモリアクセス(DMA)を実行する権限を与える方法とタイミングを把握しようとしています。カーネルでDMAがどのように始まるかを読んだ。DMA APIガイドしかし、まだいくつかのことを明確にしたいと思います。

この質問はこの質問に関連しています。DMA攻撃からLinuxを強化する方法は?おそらくIOMMUに関するご意見それが答えです。 HOWTOは合格しながらIOMMUに言及し、言った。

I / Oデバイスは、3番目のタイプのアドレス「バスアドレス」を使用します。デバイスのMMIOアドレスにレジスタがある場合、またはDMAを実行してシステムメモリを読み書きする場合、デバイスが使用するアドレスはバスアドレスです。一部のシステムでは、バスアドレスはCPU物理アドレスと同じですが、通常は異なります。 IOMMUとホストブリッジは、物理アドレスとバスアドレス間のランダムマッピングを生成できます。

ただし、DMA攻撃に関する質問に対する回答では、IOMMUを参照せずに攻撃を軽減することを提案しているため、IOMMUを搭載したシステムがどれほど一般的であるか疑問に思います。これはサーバーに共通のアーキテクチャですが、PCには適用されませんか?

IOMMUマッピングでアクセスが定義されている場合はいつ設定されますか?

HOWTOでは、「どのメモリがDMAをサポートしていますか?」と書いています。

知っておくべき最初の情報は、DMAマッピングツールが使用できるカーネルメモリです。これには未記録のルールセットがあり、この記事では最終的にこれを記録しようとします。

ページアロケータ(つまり__get_free_page *())または汎用メモリアロケータ(つまり、kmalloc()またはkmem_cache_alloc())を介してメモリを取得する場合は、アドレスを使用してそのメモリにDMA転送を実行できます。このルーチンから返されました。

しかし、彼らはデバイスにいくつかの権限を与え、実際にDMAを有効にすることについては言及していません。これにより、デバイスが許可なくすぐにそのメモリに書き込むことができるかどうか疑問に思います。その場合、割り当てはオペレーティングシステムのソフトウェアビジネスなので、デバイスが他のメモリに書き込むことができるという意味です。

問題は、いつプライマリメモリブロックをPCIeバスに書き込むことができるかということです。

しかし、以下は答えかもしれません:

正しい操作を行うには、DMAマスクを設定してデバイスのDMAアドレッシング機能をカーネルに通知する必要があります。

これはdma_set_mask_and_coherent():: を呼び出して行われます。

int dma_set_mask_and_coherent(struct device *dev, u64 mask);

これにより、ストリーミングAPIと整合性APIの両方にマスクが設定されます。

これらの呼び出しは通常ゼロを返します。これは、あなたが提供したアドレスマスクが与えられると、デバイスがコンピュータでDMAを正しく実行できることを示します。ただし、マスクが小さすぎて指定されたシステムでサポートできない場合は、エラーが返される可能性があります。0以外の値を返すと、デバイスはこのプラットフォームでDMAを正しく実行できなくなり、そうしようとすると未定義の動作が発生します。。この機能シリーズが成功を返さない限り、このデバイスdma_set_maskでDMAを使用しないでください。

ああ!もしそうなら、DMAマスクはメモリへのアクセスを定義しますか?関数群は、dma_set_mask割り当て方式に関係なくメインメモリのDMAを可能にするAPIですか?デフォルトでは、「正しく動作するには、デバイスのDMAアドレッシング機能をカーネルに通知するためにDMAマスクを設定する必要があります」とはどういう意味ですか? DMAマスクでカーネルに何を知らせていますか?一部のソフトウェアやハードウェア技術(IOMMUなど)を介してPCIeバスから物理メモリへのアクセスを定義しますか、または外部デバイスがメモリフラグメントを使用できることをカーネルに通知するだけで、カーネルがそのメモリを使用できないようにします。 ?仮想メモリシステムなどの独自の目的。最後のシナリオは、単に「デバイスにDMAアドレッシング機能を知らせること」なので、可能性が高いようです。その後、システムは外部装置の任意のDMAアクセスに対して開いたままである。

また、IOMMUがMMUのように動作することを正しく理解していますか?各デバイスのメモリマップを設定しますか?したがって、IOMMUは、許可されたマッピングの外側のメモリにアクセスしようとするすべてのデバイスをブロックします。 segfaultのようないくつかの割り込みをCPUに送りますか?この場合、「未定義の動作」はなく、アクセスがブロックされるだけでそれ以上はありません。

おそらく、この問題は次のように関連しています。PCIe デバイスから RAM にアクセスできません。、CPUが別のPCでWindowsまたはLinuxを実行している場合、RAMはPCIeのFPGAからアクセスできますが、LinuxのプライマリPCからはアクセスできません。したがって、Windowsでは何らかの方法でRAMへのアクセスを許可しますが、Linuxではそうではありません。 DMAを許可するには、Linuxで何をすべきですか?

ベストアンサー1

おすすめ記事