[BitVisor-devel:30] BitVisor-copy patch

Shougo Matsushita shougo @ softlab.cs.tsukuba.ac.jp
2012年 2月 29日 (水) 15:42:24 JST


BitVisorメーリングリストの皆さん

筑波大学 ソフトウェア研究室の松下正吾です。

今回、BitVisorにコピーを高速化するための関数を追加し、パッチを書きました。これとは別
で投稿しているRPCのパッチとプロセスの動的読み込みのためのパッチはこのパッチに依
存しています。このコピーの関数は他の用途にも利用できるので、BitVisor本体に取り
込んでいただけると幸いです。


(1) APIの解説

今回のパッチで追加したAPIの解説をします。

int copy_from_guest(u8 *vmm_addr, const u8 *guest_addr, size_t len)

copy_from_guest()はゲストOSのメモリからBitVisorのメモリへ書き込むための関数です。
現在でも、read_linearaddr_b, read_linearaddr_w, read_linearaddr_l,
read_linearaddr_qなどの関数によりゲストOSのメモリからBitVisorのメモリへ1/2/4/8
バイト単位で書き込むことができます。しかし、これらの関数は多数のデータがあると
きに動作が非常に遅いです。そこでこの関数を追加しました。

引数vmm_addrはBitVisor上のメモリアドレス、guest_addrはゲストOSでのアドレス、len
はゲストOSのアドレスからコピーする長さになります。

int copy_to_guest(u8 *guest_addr, const u8 *vmm_addr, size_t len)

copy_to_guest()はBitVisorのメモリからゲストOSのメモリへ書き込むための関数です。
現在でも、write_linearaddr_b, write_linearaddr_w, write_linearaddr_l,
write_linearaddr_qなどの関数により同様のことが行えますが、これもデータが大量に
あると遅いです。

引数guest_addrはゲストOSでのアドレス、vmm_addrはBitVisor上のメモリアドレス、len
はゲストOSのアドレスからコピーする長さになります。

(2) APIの利用例

copy_from_guest()の利用例をvmmcall_newprocessから抜き出しました。

static int read_sign(unsigned char *dest_sign, size_t dest_size, ulong
sign_addr, ulong sign_len)
{
        if (sign_len > dest_size) {
                sign_len = dest_size;
        }

        if (copy_from_guest(dest_sign, (u8 *)sign_addr, sign_len)) {
                return -1;
        }

        return 0;
}

使用方法はC言語のmemcpy()に似ています。ただしそれぞれのメモリ空間はBitVisorとゲ
ストOSであり、違いがあります。dest_signはBitVisor内のバッファを表すメモリアドレ
スです。sign_addrはvmmcallの引数に渡されたゲストOSでのアドレスとなります。
sign_lenはsign_addrから何バイトコピーするかを表す長さです。

copy_from_guest()の利用例をvmmcall_rpcから抜き出しました。

static int vmmcall_rpc (ulong desc,
                struct rpc_request *request,
                struct rpc_result *result)
{
        u8 *arguments_buffer = NULL, *results_buffer = NULL;
        struct rpc_request request_header;
        struct rpc_result result_header;
        struct msgbuf vmm_buffers[2];
        int ret = 0;

...
        /* Copy guest OS return data. */
        if (copy_to_guest((u8 *)result, (u8 *)vmm_buffers[1].base,
                                vmm_buffers[1].len)) {
                goto error;
        }
        if (arguments_buffer) {
                free_page_phys((phys_t)arguments_buffer);
        }

        return ret;

error:
        if (arguments_buffer) {
                free_page_phys((phys_t)arguments_buffer);
        }

        return -1;
}

copy_to_guest()の使い方はcopy_from_guest()と似ています。ただし、第一引数はゲス
トOS空間でのアドレスで、第二引数はBitVisor内でのアドレスとなります。この例では、
RPCの結果を格納するゲストOS空間のアドレスresultに対し、vmm_buffers[1].baseの
先にあるデータを書き込んでいます。データの長さはvmm_buffers[1].lenで与えられて
います。
-------------- next part --------------
テキスト形式以外の添付ファイルを保管しました...
ファイル名: bitvisor-copy.patch
型:         text/x-patch
サイズ:     3846 バイト
説明:       無し
URL:        <http://www.bitvisor.org/archives/bitvisor-devel/attachments/20120229/7e789f93/attachment.bin>


BitVisor-devel メーリングリストの案内