- DMA objectとなるのはbuf(9S)かumem_cookieで示される領域。
- memory mappingの対象となるのは、device memoryかumem_cookieで示される領域。
なので、どちらの性質も持たせるならumemを使うしかなかったが、
umemを偽造するのはDDI/DKIに違反しているし、
そもそも安全でないという問題もついてまわるという話を書いた。
これに対して、検討中の方式は以下の通り
バッファを要求されたら、カーネル空間内でumemを割り当て、それに対するuioを作成。uioは簡単な構造体で、umemに比べるとたやすく偽造できる。
umemはユーザ空間にエクスポート(user mapping)できるので、mmap(2)されたら(少なくともDMAが行なわれていない間は)アクセス可能なようにできる。
DMA開始時は以下のことをする。
- uioに対応したbuf(ここでのbufはSTREAMSのbuf構造体のこと)を作成し、physio(9f)に渡す。
- physio(9f)はbuf.b_un.b_addrにロックダウンされたメモリのアドレスを入れる
- physio(9f)はライブラリのmlb_strategy()を呼んでbufを渡す
- mbl_strategy()はdevmap_unload()を呼んでuser mappingを無効化
- mbl_strategy()はddi_dma_buf_bind_handleを呼び、DMA転送の準備
- mbl_strategy()はクライアントドライバのstrategy(9e)を呼び、DMA転送を開始
- physio(9f)はbiowait()を実行、待ち状態になる
DMA転送終了の割り込みが入ったら、
bufに対してbiodone()またはbioerror()を呼んでやればよい。
これにより、physio(9f)はbiowait()からリターンし、physio()自身もリターンする。
どんなものかなあ。
physio()を呼ぶのでブロッキング動作になってしまうのがちょっとイヤかも。
0 件のコメント:
コメントを投稿