2007-01-12

mmap(2)した領域へのDMA

bt848xドライバではmmap(2)した領域へDMAを行なっているけど、じつはこれは相当に危ないシロモノである。

この方式は

  • ddi_dma_mem_alloc()でDMAオブジェクト(=DMAバッファ)を取得
  • DMAオブジェクトからumem_cookie(=mmap用のデータ構造)を偽造
  • umem_cookieをddi_devmap_umem_setupにてユーザ空間にエクスポート

というもので、2つの危険性がある。

まず1つめはumem_cookieを自前ででっち上げている点で、現状ではひとまず問題はないっぽいけど、カーネルのバージョンが上がったらいつダメになるかわからない危うさがある。
2つめがDMA転送中にユーザによるメモリアクセスが発生することを阻止できない点で、DMA転送によって生じたパリティ不整合を検知してしまう可能性がある。もし検知した場合はまず間違いなく訂正不能なパリティエラーになり、カーネルが落ちることになる。

じゃあ、こんなややこしくてあぶないことは最初からしなければいいじゃんというのはもっともな話なのだけど、DMA転送の対象となる領域は、ユーザ空間にエクスポートできる領域とは個別に管理されており、実は両者の性能を備えた領域を確保することは不可能だったりする。DMAはDMAオブジェクトとして申請した領域か、デバイスのレジスタ領域だけでしかできず、一方ユーザ空間へのエクスポートはumem_cookieを使うしか手段がない。
なので、従来はmmap(2)した領域へのDMAは無理というのが定説だったはずで、それを無茶を承知でごまかしたのがbt848xドライバ、無茶が通らなくなったのがcaptorsドライバというわけだ。

なので、多少複雑になるのはあきらめて、新しい安全なDMA転送方法を検討中。詳細は次回。

0 件のコメント: