呼び出しプロセスからページをマップするためにget_user_pages
(または)を使用するLinuxドライバーについて考えてみます。get_page
次に、ページの物理アドレスがハードウェアデバイスに渡されます。当事者が通信を終了することを決定するまで、プロセスとデバイスの両方がページの読み取りと書き込みを行うことができます。特に、呼び出し元のシステムコールがget_user_pages
戻った後も、通信はページを使用し続ける場合があります。システムコールは、事実上、プロセスとハードウェアデバイスの間に共有メモリゾーンを設定しています。
プロセスが呼び出した場合に何が起こるかについて心配していますfork
(別のスレッドからのものである可能性があり、呼び出しを行うシステムコールget_user_pages
の進行中またはそれ以降に発生する可能性があります)。特に、親がフォークの後に共有メモリ領域に書き込む場合、基になる物理アドレス(おそらくコピーオンライトのために変更された)について何を知っていますか?理解したい:
- 潜在的に誤動作するプロセスから防御するためにカーネルが行う必要があること(セキュリティホールを作成したくない!)。
ドライバの機能が正しく機能するためにプロセスが従う必要のある制限(つまり、物理メモリが親プロセスの同じアドレスにマップされたままになる)。
- 理想的には、子プロセスがドライバーをまったく使用しない(おそらく
exec
ほとんどすぐに呼び出される)一般的なケースを機能させたいと思います。 - 理想的には、スタック割り当てバッファをドライバに渡す既存のコードがあるため、メモリを割り当てるときに親プロセスが特別な手順を実行する必要はありません。
- 私はを知っ
madvise
てMADV_DONTFORK
います。子プロセスのスペースからメモリを消してもかまいませんが、スタックに割り当てられたバッファには適用できません。 - 「ドライバーとの接続がアクティブな間はフォークを使用しないでください」というのは煩わしいことですが、ポイント1が満たされれば、最後の手段として受け入れられます。
- 理想的には、子プロセスがドライバーをまったく使用しない(おそらく
ドキュメントやソースコードを紹介したいと思います。特にLinuxデバイスドライバーを調べましたが、この問題が解決されていませんでした。カーネルソースの関連部分だけに適用されるRTFSは、少し圧倒されます。
カーネルバージョンは完全には修正されていませんが、最近のものです(たとえば≥2.6.26)。重要な場合は、Armプラットフォーム(これまではシングルプロセッサですが、マルチコアはもうすぐです)のみを対象としています。