« PCI Expressのリードライト | トップページ | バーストライト »

2008.01.10

バーストリード

PCI Expressコアで、バーストリードができるようにしてみました。
DMAコントローラを作り、BAR0空間に設定レジスタをおきます。

だいたいこんな感じです。
BAR0 +0 パソコン側の物理アドレス
BAR0 +4 転送長
BAR0 +8 転送開始レジスタ

このコアを動かすには、パソコンのソフトはまずカーネルモードでメモリ確保し、そのバッファの物理アドレスを取得します。そして、BAR0+0にそのアドレスをセットします。

で、実際に実行してみたのが下の図です。

Dma_rd

PCI Expressでは規格上の最大転送長が4096バイトなので、長いデータをリードライトするには複数回に分けてリクエストを発行しなければなりません。ところが今回のデータ長は512バイトにしたのですが、なぜか64バイトのトランザクション8回に分けて発行されました。
(Read Completion Boundaryとよばれる仕様です)

PCI ExpressのTLPパケットのオーバーヘッドは20バイトあるので、64バイトのデータを送るのに84バイト必要という計算になります。
今回は切れ目無くパケットを送ってきているので理想的な転送なのですが、メモリリードの帯域は190MBytes/secでした。
最大250MBytes/secの帯域を十分に活かしきれていないのは、パソコンから送ってくる際に64バイトづつ、というのがボトルネックになっているようです。


ところで、上の波形は、ユーザプログラムが用意したバッファではなく、CPUの物理アドレス0番地からのデータを読み出しているのです。

ダミーのデータが見えているのか、それとも本当に0番地のデータが見えているのかわかりませんが、ひょっとするとPCI Expressのボードからメモリリードコマンドを送ると、OSの保護とかそういうものは関係なしに何でも読めてしまう可能性があります。
(PCI Expressからのメモリリードリクエストへの応答はハードウェアレベルでの反応であって、OSでは拒否できない?)

もし本当に任意の物理アドレスの内容が読めるなら、すごいセキュリティーホールとなる予感がします。

この問題はいずれ検証してみることにします。

Boshu

|

« PCI Expressのリードライト | トップページ | バーストライト »

コメント

コメントを書く



(ウェブ上には掲載しません)




« PCI Expressのリードライト | トップページ | バーストライト »