由DMA_ALLOC_COHERENT分配的内存由Python损坏

发布于 2025-01-22 00:48:05 字数 5869 浏览 3 评论 0原文

我有一个UIO内核驱动程序,该驱动程序将通过DMA_ALLOC_COHERT分配92M字节内存(我将CMA大小设置为256m,因此它将始终成功),并且我可以在SYSFS中看到此内存的物理地址和大小。该范围为 0x30BC2000〜0x367c2000 (0x30BC2000 + 0x05C00000)。

root@ubuntu-arm:~# cat /sys/class/uio/uio0/maps/map1/addr
0x30bc2000
root@ubuntu-arm:~# cat /sys/class/uio/uio0/maps/map1/size
0x05c00000

然后我运行了我的Python程序,但是我发现Python的代码部分破坏了由UIO驱动程序分配的内存,他们使用的是相同的物理记忆! 首先,我从/proc/self/maps获得了虚拟地址映射:

root@ubuntu-arm:~# cat /proc/2337/maps
00010000-0020d000 r-xp 00000000 b3:02 12130      /usr/bin/python2.7
0021c000-0021d000 r--p 001fc000 b3:02 12130      /usr/bin/python2.7
0021d000-00277000 rw-p 001fd000 b3:02 12130      /usr/bin/python2.7
00277000-00340000 rw-p 00000000 00:00 0          [heap]
b6bcf000-b6c0f000 rw-p 00000000 00:00 0
b6c0f000-b6c13000 r-xp 00000000 b3:02 2974       /usr/lib/python2.7/lib-dynload/mmap.arm-linux-gnueabihf.so
b6c13000-b6c22000 ---p 00004000 b3:02 2974       /usr/lib/python2.7/lib-dynload/mmap.arm-linux-gnueabihf.so
b6c22000-b6c23000 r--p 00003000 b3:02 2974       /usr/lib/python2.7/lib-dynload/mmap.arm-linux-gnueabihf.so
b6c23000-b6c24000 rw-p 00004000 b3:02 2974       /usr/lib/python2.7/lib-dynload/mmap.arm-linux-gnueabihf.so
b6c24000-b6d24000 rw-p 00000000 00:00 0
b6d24000-b6d8b000 r-xp 00000000 b3:02 15868      /lib/arm-linux-gnueabihf/libm-2.23.so
b6d8b000-b6d9a000 ---p 00067000 b3:02 15868      /lib/arm-linux-gnueabihf/libm-2.23.so
b6d9a000-b6d9b000 r--p 00066000 b3:02 15868      /lib/arm-linux-gnueabihf/libm-2.23.so
b6d9b000-b6d9c000 rw-p 00067000 b3:02 15868      /lib/arm-linux-gnueabihf/libm-2.23.so
b6d9c000-b6dad000 r-xp 00000000 b3:02 955        /lib/arm-linux-gnueabihf/libz.so.1.2.8
b6dad000-b6dbc000 ---p 00011000 b3:02 955        /lib/arm-linux-gnueabihf/libz.so.1.2.8
b6dbc000-b6dbd000 r--p 00010000 b3:02 955        /lib/arm-linux-gnueabihf/libz.so.1.2.8
b6dbd000-b6dbe000 rw-p 00011000 b3:02 955        /lib/arm-linux-gnueabihf/libz.so.1.2.8
b6dbe000-b6dc0000 r-xp 00000000 b3:02 15867      /lib/arm-linux-gnueabihf/libutil-2.23.so
b6dc0000-b6dcf000 ---p 00002000 b3:02 15867      /lib/arm-linux-gnueabihf/libutil-2.23.so
b6dcf000-b6dd0000 r--p 00001000 b3:02 15867      /lib/arm-linux-gnueabihf/libutil-2.23.so
b6dd0000-b6dd1000 rw-p 00002000 b3:02 15867      /lib/arm-linux-gnueabihf/libutil-2.23.so
b6dd1000-b6dd3000 r-xp 00000000 b3:02 15862      /lib/arm-linux-gnueabihf/libdl-2.23.so
b6dd3000-b6de2000 ---p 00002000 b3:02 15862      /lib/arm-linux-gnueabihf/libdl-2.23.so
b6de2000-b6de3000 r--p 00001000 b3:02 15862      /lib/arm-linux-gnueabihf/libdl-2.23.so
b6de3000-b6de4000 rw-p 00002000 b3:02 15862      /lib/arm-linux-gnueabihf/libdl-2.23.so
b6de4000-b6eba000 r-xp 00000000 b3:02 15882      /lib/arm-linux-gnueabihf/libc-2.23.so
b6eba000-b6eca000 ---p 000d6000 b3:02 15882      /lib/arm-linux-gnueabihf/libc-2.23.so
b6eca000-b6ecc000 r--p 000d6000 b3:02 15882      /lib/arm-linux-gnueabihf/libc-2.23.so
b6ecc000-b6ecd000 rw-p 000d8000 b3:02 15882      /lib/arm-linux-gnueabihf/libc-2.23.so
b6ecd000-b6ed0000 rw-p 00000000 00:00 0
b6ed0000-b6ee1000 r-xp 00000000 b3:02 15872      /lib/arm-linux-gnueabihf/libpthread-2.23.so
b6ee1000-b6ef0000 ---p 00011000 b3:02 15872      /lib/arm-linux-gnueabihf/libpthread-2.23.so
b6ef0000-b6ef1000 r--p 00010000 b3:02 15872      /lib/arm-linux-gnueabihf/libpthread-2.23.so
b6ef1000-b6ef2000 rw-p 00011000 b3:02 15872      /lib/arm-linux-gnueabihf/libpthread-2.23.so
b6ef2000-b6ef4000 rw-p 00000000 00:00 0
b6ef4000-b6f0c000 r-xp 00000000 b3:02 15876      /lib/arm-linux-gnueabihf/ld-2.23.so
b6f14000-b6f16000 rw-p 00000000 00:00 0
b6f1a000-b6f1b000 rw-p 00000000 00:00 0
b6f1b000-b6f1c000 r--p 00017000 b3:02 15876      /lib/arm-linux-gnueabihf/ld-2.23.so
b6f1c000-b6f1d000 rw-p 00018000 b3:02 15876      /lib/arm-linux-gnueabihf/ld-2.23.so
bef1b000-bef3c000 rw-p 00000000 00:00 0          [stack]
befda000-befdb000 r-xp 00000000 00:00 0          [sigpage]
ffff0000-ffff1000 r-xp 00000000 00:00 0          [vectors]

我尝试通过/proc/pid/pagemap将虚拟地址转换为物理地址。 从0x00010000-0020D000开始(我认为Python的代码部分):

root@ubuntu-arm:~# ./virt_to_phys 2337 0x10000
Big endian? 0
Vaddr: 0x10000, Page_size: 4096, Entry_size: 8
Reading /proc/2337/pagemap at 0x80
[0]0xbc [1]0xb9 [2]0x3 [3]0x0 [4]0x0 [5]0x0 [6]0x0 [7]0xa1
Result: 0xa10000000003b9bc
PFN: 0x3b9bc (0x3b9bc000)
root@ubuntu-arm:~#
root@ubuntu-arm:~# ./virt_to_phys 2337 0x20000
Big endian? 0
Vaddr: 0x20000, Page_size: 4096, Entry_size: 8
Reading /proc/2337/pagemap at 0x100
[0]0xd0 [1]0xb6 [2]0x3 [3]0x0 [4]0x0 [5]0x0 [6]0x0 [7]0xa1
Result: 0xa10000000003b6d0
PFN: 0x3b6d0 (0x3b6d0000)
root@ubuntu-arm:~#
root@ubuntu-arm:~# ./virt_to_phys 2337 0x30000
Big endian? 0
Vaddr: 0x30000, Page_size: 4096, Entry_size: 8
Reading /proc/2337/pagemap at 0x180
[0]0x0 [1]0x0 [2]0x0 [3]0x0 [4]0x0 [5]0x0 [6]0x0 [7]0x0
Result: 0x0
Page not present
root@ubuntu-arm:~#
root@ubuntu-arm:~# ./virt_to_phys 2337 0x40000
Big endian? 0
Vaddr: 0x40000, Page_size: 4096, Entry_size: 8
Reading /proc/2337/pagemap at 0x200
[0]0x0 [1]0xb5 [2]0x3 [3]0x0 [4]0x0 [5]0x0 [6]0x0 [7]0xa1
Result: 0xa10000000003b500
PFN: 0x3b500 (0x3b500000)
root@ubuntu-arm:~#
root@ubuntu-arm:~# ./virt_to_phys 2337 0x50000
Big endian? 0
Vaddr: 0x50000, Page_size: 4096, Entry_size: 8
Reading /proc/2337/pagemap at 0x280
[0]0xa5 [1]0x5d [2]0x3 [3]0x0 [4]0x0 [5]0x0 [6]0x0 [7]0xa1
Result: 0xa100000000035da5
PFN: 0x35da5 (0x35da5000)

正如我们可以看到虚拟地址0x50000映射到Physcal地址 0x35DA5000 ,物理地址仅在范围内( 0x30BC2000〜0X30BC2000〜00我的UIO驱动程序DMA内存的0x367C2000 )。 我的问题是,为什么OS将相同的内存分配给不同的过程,还有任何线索吗? 这是我的操作系统信息:

root@ubuntu-arm:~# uname -a
Linux ubuntu-arm 4.9.0-xilinx #1 SMP PREEMPT Mon Jan 10 06:52:07 UTC 2022 armv7l armv7l armv7l GNU/Linux
root@ubuntu-arm:~#
root@ubuntu-arm:~# python --version
Python 2.7.12

谢谢。

I have a UIO kernel driver which will allocate 92M bytes memory by dma_alloc_coherent(I have set CMA size to 256M so it will always succeed), and I can see the physical address and size of this memory in sysfs. The range is 0x30bc2000~0x367c2000(0x30bc2000 + 0x05c00000).

root@ubuntu-arm:~# cat /sys/class/uio/uio0/maps/map1/addr
0x30bc2000
root@ubuntu-arm:~# cat /sys/class/uio/uio0/maps/map1/size
0x05c00000

Then I run my python program, but I found the code sections of python corrupt the memory allocated by my UIO driver, they are using the same physcal memory!
First I got the virtual address mapping from /proc/self/maps:

root@ubuntu-arm:~# cat /proc/2337/maps
00010000-0020d000 r-xp 00000000 b3:02 12130      /usr/bin/python2.7
0021c000-0021d000 r--p 001fc000 b3:02 12130      /usr/bin/python2.7
0021d000-00277000 rw-p 001fd000 b3:02 12130      /usr/bin/python2.7
00277000-00340000 rw-p 00000000 00:00 0          [heap]
b6bcf000-b6c0f000 rw-p 00000000 00:00 0
b6c0f000-b6c13000 r-xp 00000000 b3:02 2974       /usr/lib/python2.7/lib-dynload/mmap.arm-linux-gnueabihf.so
b6c13000-b6c22000 ---p 00004000 b3:02 2974       /usr/lib/python2.7/lib-dynload/mmap.arm-linux-gnueabihf.so
b6c22000-b6c23000 r--p 00003000 b3:02 2974       /usr/lib/python2.7/lib-dynload/mmap.arm-linux-gnueabihf.so
b6c23000-b6c24000 rw-p 00004000 b3:02 2974       /usr/lib/python2.7/lib-dynload/mmap.arm-linux-gnueabihf.so
b6c24000-b6d24000 rw-p 00000000 00:00 0
b6d24000-b6d8b000 r-xp 00000000 b3:02 15868      /lib/arm-linux-gnueabihf/libm-2.23.so
b6d8b000-b6d9a000 ---p 00067000 b3:02 15868      /lib/arm-linux-gnueabihf/libm-2.23.so
b6d9a000-b6d9b000 r--p 00066000 b3:02 15868      /lib/arm-linux-gnueabihf/libm-2.23.so
b6d9b000-b6d9c000 rw-p 00067000 b3:02 15868      /lib/arm-linux-gnueabihf/libm-2.23.so
b6d9c000-b6dad000 r-xp 00000000 b3:02 955        /lib/arm-linux-gnueabihf/libz.so.1.2.8
b6dad000-b6dbc000 ---p 00011000 b3:02 955        /lib/arm-linux-gnueabihf/libz.so.1.2.8
b6dbc000-b6dbd000 r--p 00010000 b3:02 955        /lib/arm-linux-gnueabihf/libz.so.1.2.8
b6dbd000-b6dbe000 rw-p 00011000 b3:02 955        /lib/arm-linux-gnueabihf/libz.so.1.2.8
b6dbe000-b6dc0000 r-xp 00000000 b3:02 15867      /lib/arm-linux-gnueabihf/libutil-2.23.so
b6dc0000-b6dcf000 ---p 00002000 b3:02 15867      /lib/arm-linux-gnueabihf/libutil-2.23.so
b6dcf000-b6dd0000 r--p 00001000 b3:02 15867      /lib/arm-linux-gnueabihf/libutil-2.23.so
b6dd0000-b6dd1000 rw-p 00002000 b3:02 15867      /lib/arm-linux-gnueabihf/libutil-2.23.so
b6dd1000-b6dd3000 r-xp 00000000 b3:02 15862      /lib/arm-linux-gnueabihf/libdl-2.23.so
b6dd3000-b6de2000 ---p 00002000 b3:02 15862      /lib/arm-linux-gnueabihf/libdl-2.23.so
b6de2000-b6de3000 r--p 00001000 b3:02 15862      /lib/arm-linux-gnueabihf/libdl-2.23.so
b6de3000-b6de4000 rw-p 00002000 b3:02 15862      /lib/arm-linux-gnueabihf/libdl-2.23.so
b6de4000-b6eba000 r-xp 00000000 b3:02 15882      /lib/arm-linux-gnueabihf/libc-2.23.so
b6eba000-b6eca000 ---p 000d6000 b3:02 15882      /lib/arm-linux-gnueabihf/libc-2.23.so
b6eca000-b6ecc000 r--p 000d6000 b3:02 15882      /lib/arm-linux-gnueabihf/libc-2.23.so
b6ecc000-b6ecd000 rw-p 000d8000 b3:02 15882      /lib/arm-linux-gnueabihf/libc-2.23.so
b6ecd000-b6ed0000 rw-p 00000000 00:00 0
b6ed0000-b6ee1000 r-xp 00000000 b3:02 15872      /lib/arm-linux-gnueabihf/libpthread-2.23.so
b6ee1000-b6ef0000 ---p 00011000 b3:02 15872      /lib/arm-linux-gnueabihf/libpthread-2.23.so
b6ef0000-b6ef1000 r--p 00010000 b3:02 15872      /lib/arm-linux-gnueabihf/libpthread-2.23.so
b6ef1000-b6ef2000 rw-p 00011000 b3:02 15872      /lib/arm-linux-gnueabihf/libpthread-2.23.so
b6ef2000-b6ef4000 rw-p 00000000 00:00 0
b6ef4000-b6f0c000 r-xp 00000000 b3:02 15876      /lib/arm-linux-gnueabihf/ld-2.23.so
b6f14000-b6f16000 rw-p 00000000 00:00 0
b6f1a000-b6f1b000 rw-p 00000000 00:00 0
b6f1b000-b6f1c000 r--p 00017000 b3:02 15876      /lib/arm-linux-gnueabihf/ld-2.23.so
b6f1c000-b6f1d000 rw-p 00018000 b3:02 15876      /lib/arm-linux-gnueabihf/ld-2.23.so
bef1b000-bef3c000 rw-p 00000000 00:00 0          [stack]
befda000-befdb000 r-xp 00000000 00:00 0          [sigpage]
ffff0000-ffff1000 r-xp 00000000 00:00 0          [vectors]

I try to convert the virtual address to physical address by /proc/pid/pagemap.
Starting from 0x00010000-0020d000 (code section of python I think):

root@ubuntu-arm:~# ./virt_to_phys 2337 0x10000
Big endian? 0
Vaddr: 0x10000, Page_size: 4096, Entry_size: 8
Reading /proc/2337/pagemap at 0x80
[0]0xbc [1]0xb9 [2]0x3 [3]0x0 [4]0x0 [5]0x0 [6]0x0 [7]0xa1
Result: 0xa10000000003b9bc
PFN: 0x3b9bc (0x3b9bc000)
root@ubuntu-arm:~#
root@ubuntu-arm:~# ./virt_to_phys 2337 0x20000
Big endian? 0
Vaddr: 0x20000, Page_size: 4096, Entry_size: 8
Reading /proc/2337/pagemap at 0x100
[0]0xd0 [1]0xb6 [2]0x3 [3]0x0 [4]0x0 [5]0x0 [6]0x0 [7]0xa1
Result: 0xa10000000003b6d0
PFN: 0x3b6d0 (0x3b6d0000)
root@ubuntu-arm:~#
root@ubuntu-arm:~# ./virt_to_phys 2337 0x30000
Big endian? 0
Vaddr: 0x30000, Page_size: 4096, Entry_size: 8
Reading /proc/2337/pagemap at 0x180
[0]0x0 [1]0x0 [2]0x0 [3]0x0 [4]0x0 [5]0x0 [6]0x0 [7]0x0
Result: 0x0
Page not present
root@ubuntu-arm:~#
root@ubuntu-arm:~# ./virt_to_phys 2337 0x40000
Big endian? 0
Vaddr: 0x40000, Page_size: 4096, Entry_size: 8
Reading /proc/2337/pagemap at 0x200
[0]0x0 [1]0xb5 [2]0x3 [3]0x0 [4]0x0 [5]0x0 [6]0x0 [7]0xa1
Result: 0xa10000000003b500
PFN: 0x3b500 (0x3b500000)
root@ubuntu-arm:~#
root@ubuntu-arm:~# ./virt_to_phys 2337 0x50000
Big endian? 0
Vaddr: 0x50000, Page_size: 4096, Entry_size: 8
Reading /proc/2337/pagemap at 0x280
[0]0xa5 [1]0x5d [2]0x3 [3]0x0 [4]0x0 [5]0x0 [6]0x0 [7]0xa1
Result: 0xa100000000035da5
PFN: 0x35da5 (0x35da5000)

As we can see that virtual address 0x50000 is mapping to physcal address 0x35da5000, the physical address is just in the range(0x30bc2000~0x367c2000) of my UIO driver DMA memory.
My question is why the OS assigns the same memory to different process, any clue?
And here is my OS information:

root@ubuntu-arm:~# uname -a
Linux ubuntu-arm 4.9.0-xilinx #1 SMP PREEMPT Mon Jan 10 06:52:07 UTC 2022 armv7l armv7l armv7l GNU/Linux
root@ubuntu-arm:~#
root@ubuntu-arm:~# python --version
Python 2.7.12

Thanks.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文