1

AFAIKは、/dev/memユーザーに物理メモリを提供し、通常、MMIOを介したデバイスの読み取り/書き込みに使用されます。私のユースケースでは、2つのpteが同じ物理ページを指すように、現在のプロセスのpteを変更したいと思います。特に、x86_64バイナリを4G仮想空間の上に移動し、mmap仮想空間を4Gの下に移動します。pteより上の4Gとpteより下の4Gが同じ物理ページを指すようにしたいので、vaddrより上の4Gに書き込み、pteより下の4Gから読み取ると、同じ結果が得られます。サンプルコードは次のようになります。

*(unsigned char *)vaddr1 = 7 // write into 4G above vaddr1

val = *(unsigned char *)vaddr2; // read from 4G below vaddr2 

printf("val should be 7, %d\n", val);

しかし、pteの下の4Gを変更して、pteの上の4Gが指す物理ページを指すようにする/dev/memと、カーネルは以下のメッセージを表示します。

BUG: Bad page map in process mmap  pte:8000000007eb2067 pmd:07acb067
page:ffffea00001fac80 count:0 mapcount:-1 mapping:          (null) index:0x101b7b
page flags: 0x4000000000000014(referenced|dirty)
addr:0000000101b7b000 vm_flags:00100073 anon_vma:ffff880007ab0708 mapping:          (null) index:101b7b
Pid: 609, comm: mmap Tainted: G    B        3.5.3 #7
Call Trace:
 [<ffffffff8107abcc>] ? print_bad_pte+0x1d2/0x1ea
 [<ffffffff8107bf18>] ? unmap_single_vma+0x3a0/0x56d
 [<ffffffff8107c745>] ? unmap_vmas+0x2c/0x46
 [<ffffffff8108106b>] ? exit_mmap+0x6e/0xdd
 [<ffffffff8101cc4f>] ? do_page_fault+0x30f/0x348
 [<ffffffff81020ce6>] ? mmput+0x20/0xb4
 [<ffffffff810256ae>] ? exit_mm+0x105/0x110
 [<ffffffff8103bb6c>] ? hrtimer_try_to_cancel+0x67/0x70
 [<ffffffff81026b59>] ? do_exit+0x211/0x711
 [<ffffffff810272e0>] ? do_group_exit+0x76/0xa0
 [<ffffffff8102731c>] ? sys_exit_group+0x12/0x19
 [<ffffffff812f3662>] ? system_call_fastpath+0x16/0x1b
 BUG: Bad rss-counter state mm:ffff880007a496c0 idx:0 val:-1
 BUG: Bad rss-counter state mm:ffff880007a496c0 idx:1 val:1

カーネルはpteが変更されているかどうかを調べると思いますが、私は何か間違ったことをしました。これが私のpte書き換えの前後のvaddr1とvaddr2のpteです。

above 4G pte: 0x8000000007eb2067
below 4G pte: 0x0000000007ea7067
after rewriting pte...
above 4G pte: 0x8000000007eb2067
below 4G pte: 0x8000000007eb2067

何か案が?ありがとう。

注:これで、vaddr2のpteが指す物理ページを解放する必要があることがわかりました。そうしないと、カーネルは物理ページがどのpteも指していないと認識し、エラーを出します。しかし、どのように?を使おうとして__free_pageいますが、以下のエラーが発生します。

BUG: unable to handle kernel paging request at ffffebe00008001c
IP: [<ffffffff8106b908>] __free_pages+0x4/0x2a
PGD 0
Oops: 0000 [#2] PREEMPT SMP
CPU 0
4

0 に答える 0