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.