• 検索結果がありません。

第 5 章 Martini 向け

5.3 メモリ保護

以下ではMartiniの低レベルソフトウェアライブラリによるメモリ保護機構の実装について述

べる.

5.3.1 ページテーブル

Martiniでは,ネットワークインタフェース上で仮想アドレスから物理アドレスの変換を行う際

にPATLBを用いるが,ユーザプロセスが不正な仮想アドレスを伴ったPUSHPULLの通信要

求を発行した場合,PATLBでミスヒットが発生する.また,正常な仮想アドレスからの変換にお

いても,PATLB上にすべての仮想アドレスと物理アドレスの対応を同時に保持することができな

いため,同様にミスヒットが生じる可能性がある.

PATLBのミスヒットが発生した場合,正しい物理アドレスをプロセスのページテーブルから取

得して,PATLBのリプレースメント処理を行う必要がある.PATLBのミスヒットが発生すると,

ハードウェアモジュールは例外を発生し,オンチッププロセッサやホストCPUに対して割込みの 形で報告を行うが,5.4節にて述べるように,例外処理はすべてファームウェア上で処理する方針 を採用したことから,PATLBのリプレースメント処理もファームウェアで実現することとした.

ファームウェアからアクセスしやすく,大容量の領域を確保できるよう,Martiniが利用するペー ジテーブルは,ネットワークインタフェースのSDRAM上に構築することにした.PATLBがミス ヒットした場合,ファームウェアはSDRAM上のページテーブルからDMA転送を行うことで物 理アドレスを取得してリプレースメント処理を行う.

ページテーブルをネットワークインタフェース側で保持するのは,Martiniがアクセスできる領 域を,事前にピンダウン処理がなされ物理メモリ上に存在することが保証されている仮想アドレ ス空間に限定するためである.ホスト上でのピンダウン・アンピンダウン処理にあわせてSDRAM 上のページテーブルを更新することで,これを保証することができる.

5.3.2 ピンダウン・アンピンダウン処理

2.2.1節で述べたように,PUSHPULLなどでDMA対象となるユーザプロセスのメモリ領域

は,通信に先立ってピンダウン処理を行っておく必要がある.

また,5.3.1節で述べたように,PATLBやネットワークインタフェース上のページテーブルのエ

ントリは,ホスト上でのピンダウン・アンピンダウン処理と連動して更新されることを保証する 必要がある.特に,ホスト上でアンピンダウン処理を行って物理メモリへの固定が保証されなく なったエントリが,その後もPATLBやネットワークインタフェース上のページテーブルに残存 していると,Martiniがピンダウンされていないメモリ領域に対してアクセスできてしまうことに なり,最悪の場合,別プロセスに再割当てされた物理ページに対してアクセスできてしまうなど,

メモリ保護が破綻してしまう可能性がある.そのため,アンピンダウンによってその領域が物理 メモリ上に存在していることが保証できなくなる前に,PATLBなどのエントリを無効化すること を確実に行わなければならない.

このことから,ピンダウンとMartini側へのページテーブルエントリの登録およびアンピンダウ

ンとMartini側のページテーブルエントリの無効化は,それぞれひとまとめにして行うのが望ま

しい.

ピンダウン・アンピンダウン処理の実装

ピンダウン・アンピンダウン処理はカーネルの管理するページテーブルにアクセスし,ページ テーブルの各エントリのフラグを直接書き換えることで実現可能であるが,Linuxがこのようなフ ラグに対する直接操作を想定しているかどうかは不明であり,またフラグをセットしたままプロ

セスが終了してしまうとメモリが正常に解放されずカーネルで不具合が生じる可能性がある.そ こで,安全で確実にピンダウン処理が行えるよう,Martini向けの通信ライブラリでのピンダウン 処理には,OSの提供するmlock・munlockシステムコールを利用する実装とした.

Linuxでは,mlockを呼び出すと,ユーザプロセスの連続した仮想ページ領域をまとめて管理

するカーネル内のvm_area構造体がピンダウンした領域とそれ以外の領域に分割され,ピンダウ ンした領域を管理するvm_area構造体にスワップアウトを禁止するフラグがセットされ,ピンダ ウン処理が完了する.この場合,ピンダウンを解除するmunlockシステムコールを呼ばずにプロ セスが終了しても,カーネルが自動的にメモリのアンピンダウン処理を行う.

しかしながら,mlock・munlockシステムコールをそのまま用いてページのピンダウン・アンピ ンダウンを行う場合,ユーザの責任のもとでページテーブルへの登録・無効化をあわせて呼び出 す必要が生じ,これらがひとまとめに行われることを保証できないという問題が発生する.mlock によってピンダウンした後に,ネットワークインタフェース側のページテーブルへの登録を行わ なかった場合は単にMartiniDMAに失敗するだけ済むが,PATLBやネットワークインタフェー スのページテーブルの無効化を行う前にmunlockを呼び出すことができてしまうと,対象となる 通信領域が物理メモリ上に存在することが保証できなくなってしまうため,ホストのOSの提供 するメモリ保護が破綻してしまうという問題がある.また,mlockは特権が必要なシステムコー ルであるため,ユーザ権限で実行されている並列プロセスからそのままでは利用できないという 点も問題となる.

そこで,Martiniの低レベルソフトウェアライブラリではデバイスドライバ内でmlock・munlock システムコールに対するフックを用意し,デバイスドライバがロードされた際にmlock・munlock システムコールに前処理および後処理を追加することで,これらの問題を解決することにした.

図5.1にmlockおよびmunlockシステムコールに対するフックの処理の流れを示す.

munlock mlock

System Call Table

Using Martini?

munlock invalidate Pagetable Using Martini?

mlock

register to pagetable

Yes Yes

No No

Hook Hook

lower CAP_IPC_LOCK raise CAP_IPC_LOCK

Original

Original

return return

図5.1 mlock/munlockシステムコールへのフック

mlockシステムコールに対するフックでは,まずmlockを呼んだプロセスがMartiniを利用し ているプロセスかどうかを確認し,そうであればプロセスに対して一時的にmlockを許可する権 限であるCAP_IPC_LOCKを付与し,オリジナルのmlockを呼び出す.プロセスがMartiniを利用 しているかどうかの確認は,事前に設定されているプロセスの管理構造体のフラグを参照して行 う.オリジナルのmlockから戻ったら,プロセスのCAP_IPC_LOCKを解除し,続いてネットワー クインタフェース上のページテーブルへの登録を行い,処理を完了する.一方,munlockシステ ムコールに対するフックでは,まずmunlockを呼んだプロセスがMartiniを利用しているプロセ スであった場合,先にPATLBとネットワークインタフェース上のページテーブルの無効化処理を 行った上で,元のmunlockを呼び出す.mlock・munlockを呼び出したプロセスがMartiniを利用 していないプロセスであった場合,どちらの場合もそのまま元のmlock・munlockを呼び出して 処理を完了する.

この実装では,プロセス終了時にmlockしたままの領域が残存していた場合,メモリ領域のア ンピンダウン自体は行われるが,PATLBやネットワークインタフェース側のページテーブルに 不正な値が残ってしまうという問題がある.この問題は,プロセス終了時にデバイスファイルが

closeされた際にページテーブルの無効化処理を行うことで回避することにした.

以上の方法で,ページテーブルと確実に連動し,メモリ保護を破綻させないピンダウン・アン ピンダウン処理を実現した.なお,この実装では,ピンダウン処理にMartiniとのデータのやりと りが含まれるため処理に時間を要してしまうが,これは通信に用いる領域を事前にまとめて確保 したり,あらかじめピンダウンした領域を,通信終了後にすぐにアンピンダウンせずに再利用す るなどの工夫をアプリケーション側で行うことで隠蔽できる[104]

5.3.3 contflag領域

4.6.2節において述べたように,Martiniは,Windowを通じて発行された処理が完了すると, CON-TTBLが指すホストメモリ上の領域に対してDMAWindowが再利用可能となったことを示す contflagを書き込む.その際,CONTTBLのエントリは物理アドレスとしてMartiniに処理される.

contflagが書き込まれる領域(contflag領域)は,ユーザプロセスがWindowの空きを確認するた めに頻繁にアクセスすることになるため,PUSHPULLで用いる通信領域などと同様にユーザ プロセスから直接ポーリングできることが望ましい.そこで,contflag領域をデバイスドライバ内 のメモリ上に確保し,Windowと同様にユーザプロセスに対してマップすることにした.

contflag領域は各Windowに一対一対応する領域であることから,デバイスドライバ内にWindow の個数分のページを確保し,各ページの先頭部分の物理アドレスをcontflag領域としてCONTTBL に登録しておく.contflag領域自体はWindowに付随するリソースであることから,ユーザから デバイスドライバに対してWindowのマップ要求があった際に,Windowに加えてcontflag領域を ユーザプロセスにマップする.

5.3.4 プロセス登録機能

4.2.4節で述べたように,Martiniの提供するメモリ保護機構は,PGIDTBLに登録されたPID PGIDが正しい値であることを前提とした設計となっている.そこで,このPGIDTBLへのPID PGIDの登録を,デバイスドライバを通じてのみ可能なように制限し,さらにこのデバイスドラ イバ内のPIDとPGIDの登録処理を呼び出すことが可能なプロセスを,並列プロセスの実行を管