PCIデバイスドライバは、PCIメモリをユーザ空間にどのように再マップしますか?

PCIデバイスドライバは、PCIメモリをユーザ空間にどのように再マップしますか?

QEMUで仮想PCIデバイス用のPCIデバイスドライバを実装しようとしています。デバイスはBAR領域をRAMとして定義し、ドライバは領域をioremap()して問題なくアクセスできます。次のステップは、この領域(またはその一部)をユーザーアプリケーションに割り当てることです。この目的のために、ドライバファイルの操作の一部として.mmap機能も実装しました。このmmapはremap_pfn_rangeを使用しますが、以前にioremap()から返されたメモリポインタのpfnも渡します。

ただし、ユーザースペースアプリケーションを実行するとmmapは成功しますが、アプリケーションがメモリにアクセスしようとすると、次のdmesgエラーで終了します。

[ 1502.402970] a.out: Corrupted page table at address 7f911b79f000
[ 1502.404085] PGD 13926d067 P4D 13926d067 PUD 1317aa067 PMD 1326d9067 PTE 800026d901000227
[ 1502.404085] Bad pagetable: 000f [#1] SMP NOPTI
[ 1502.404085] Modules linked in: edu_driver(OE) ppdev kvm_amd kvm irqbypass input_leds parport_pc serio_raw parport mac_hid qemu_fw_cfg sch_fq_codel ib_iser rdma_cm iw_cm ib_cm ib_core iscsi_tcp libiscsi_tcp libiscsi scsi_transport_iscsi ip_tables x_tables autofs4 btrfs zstd_compress raid10 raid456 async_raid6_recov async_memcpy async_pq async_xor async_tx xor raid6_pq libcrc32c raid1 raid0 multipath linear psmouse pata_acpi floppy e1000 i2c_piix4
[ 1502.404085] CPU: 0 PID: 1988 Comm: a.out Tainted: G           OE    4.15.0-55-generic #60-Ubuntu
[ 1502.404085] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.14.0-0-g155821a1990b-prebuilt.qemu.org 04/01/2014
[ 1502.404085] RIP: 0033:0x55d687642811
[ 1502.404085] RSP: 002b:00007ffe16c38da0 EFLAGS: 00000213
[ 1502.404085] RAX: 00007f911b79f000 RBX: 0000000000000000 RCX: 00007f911b2a1813
[ 1502.404085] RDX: 0000000000000003 RSI: 0000000000001000 RDI: 0000000000000000
[ 1502.404085] RBP: 00007ffe16c38dc0 R08: 0000000000000003 R09: 0000000000000000
[ 1502.404085] R10: 0000000000008001 R11: 0000000000000246 R12: 000055d687642660
[ 1502.404085] R13: 00007ffe16c38ea0 R14: 0000000000000000 R15: 0000000000000000
[ 1502.404085] FS:  00007f911b7984c0(0000) GS:ffff97237fc00000(0000) knlGS:0000000000000000
[ 1502.404085] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[ 1502.404085] CR2: 00007f911b79f000 CR3: 0000000132cd8000 CR4: 00000000000006f0
[ 1502.404085] RIP: 0x55d687642811 RSP: 00007ffe16c38da0
[ 1502.404085] ---[ end trace 6b088b58eb816baf ]---

私が間違っていることを知っている人はいますか?私は一歩も逃したのですか?それともQEMU固有のバグかもしれませんか? QEMU構成でx86_softmmuを実行しており、カーネルは4.14です。

ベストアンサー1

問題を解決し、ドライバを介してPCIメモリをユーザースペースにマッピングしました。remap_pfn_rangeカスタム.mmapで使用される関数のpfn入力を変更しました。

元のテキストは次のとおりです。

io_remap_pfn_range(vma, vma->vm_start, pfn, vma->vm_end - vma->vm_start, vma->vm_page_prot ))

ここで、pfnは)から返されたバッファポインタの結果ですioremap(。 pfnを次のように変更しました。

pfn = pci_resource_start(pdev, BAR) >> PAGE_SHIFT .

これはデフォルトでBARが指す実際の開始アドレスを指します。

私の現在の作業remap_pfn_range機能は次のとおりです。

io_remap_pfn_range(vma, vma->vm_start, pci_resource_start(pdev, BAR) >> PAGE_SHIFT, vma->vm_end - vma->vm_start,vma->vm_page_prot )

ドライバのバッファポインタにダミー書き込みを行い、ユーザ空間アプリケーションで読み書きを行うことで動作することを確認しました。

おすすめ記事