Can we use virt_to_phys for user space memory in the kernel module?

I will allocate memory in the user application with mallocand send the returned address mallocto the kernel module through the character driver interface.

I will bind pages for this memory using get_user_pages_fastin the kernel module.

Can I use virt_to_physto get the address returned malloc. It's really? If not, how can I get the correct physical address?

My goal is to get the physical address of the allocated memory in user space. I limit the transfer size to page size (4KB).

+4
source share
3 answers

No, you cannot, virt_to_phys translates virtual kernel addresses to physical addresses. There are 3 (or 4) address types in linux:

  • virtual kernel address: physical address +/- offset (PAGE_OFFSET).
  • kernel physical address: actual physical address (obtained by __pa or virt_to_phys functions).
  • User virtual address: translation to a physical address is located inside the process page table.

Please note that the table layout table depends on the processor architecture, so you need to implement a page page table that matches the architecture in which you work.

And the last word, 4th form of existing addresses:

  • bus address: this is the address visible to the device.
+1

malloc . , , malloc .

virt_to_phys: - () . , kmalloc. , ( )

+1

. mmap /dev/mem(RAM)

#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <unistd.h>

int main(int argc, char *argv[]) {
    if (argc < 3) {
        printf("Usage: %s <phys_addr> <offset>\n", argv[0]);
        return 0;
    }

    off_t offset = strtoul(argv[1], NULL, 0);
    size_t len = strtoul(argv[2], NULL, 0);

    // Truncate offset to a multiple of the page size, or mmap will fail.
    size_t pagesize = sysconf(_SC_PAGE_SIZE);
    off_t page_base = (offset / pagesize) * pagesize;
    off_t page_offset = offset - page_base;

    int fd = open("/dev/mem", O_SYNC);
    unsigned char *mem = mmap(NULL, page_offset + len, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, page_base);
    if (mem == MAP_FAILED) {
        perror("Can't map memory");
        return -1;
    }

    size_t i;
    for (i = 0; i < len; ++i)
        printf("%02x ", (int)mem[page_offset + i]);

    return 0;
}

Loan sent Access to physical address from user space

0
source

Source: https://habr.com/ru/post/1674484/


All Articles