md.jamal
md.jamal

Reputation: 4547

Why the addresses returned by vmalloc cannot be translated to physical address

I am trying to understand the memory management in Linux. In case of vmalloc I found this

Addresses returned cannot be translated into physical ones or into bus addresses, because you cannot assert that the memory is physically contiguous.

When i call virt_to_phys(), I get an address.

Do you mean the return value of virt_to_phys is incorrect

#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/vmalloc.h>
#include <linux/moduleparam.h>

MODULE_LICENSE("GPL");

static char *ptr;
int alloc_size = 4096*1234;


static int test_hello_init(void)
{
    ptr = vmalloc(alloc_size);
    if(!ptr) {
        /* handle error */
        pr_err("memory allocation failed\n");
        return -ENOMEM;
    } else {
        int i;
        for (i = 0; i < 1234; i++) {
            pr_info("Page Index:%d\tPhysical address:%px\t Virtual Address:%llx\n", 
                    i, ptr+(4096*i), virt_to_phys(ptr+(4096*i)));
        }
    }

    return 0;
}

static void test_hello_exit(void)
{
    vfree(ptr);
    pr_info("Memory freed\n");

}

module_init(test_hello_init);
module_exit(test_hello_exit);

dmesg:

[26472.440426] Page Index:1217  Physical address:ffffa1f544336000    Virtual Address:12ce44336000
[26472.440427] Page Index:1218  Physical address:ffffa1f544337000    Virtual Address:12ce44337000
[26472.440427] Page Index:1219  Physical address:ffffa1f544338000    Virtual Address:12ce44338000
[26472.440428] Page Index:1220  Physical address:ffffa1f544339000    Virtual Address:12ce44339000
[26472.440428] Page Index:1221  Physical address:ffffa1f54433a000    Virtual Address:12ce4433a000
[26472.440428] Page Index:1222  Physical address:ffffa1f54433b000    Virtual Address:12ce4433b000
[26472.440429] Page Index:1223  Physical address:ffffa1f54433c000    Virtual Address:12ce4433c000
[26472.440429] Page Index:1224  Physical address:ffffa1f54433d000    Virtual Address:12ce4433d000
[26472.440429] Page Index:1225  Physical address:ffffa1f54433e000    Virtual Address:12ce4433e000
[26472.440430] Page Index:1226  Physical address:ffffa1f54433f000    Virtual Address:12ce4433f000
[26472.440430] Page Index:1227  Physical address:ffffa1f544340000    Virtual Address:12ce44340000
[26472.440430] Page Index:1228  Physical address:ffffa1f544341000    Virtual Address:12ce44341000
[26472.440431] Page Index:1229  Physical address:ffffa1f544342000    Virtual Address:12ce44342000
[26472.440431] Page Index:1230  Physical address:ffffa1f544343000    Virtual Address:12ce44343000
[26472.440431] Page Index:1231  Physical address:ffffa1f544344000    Virtual Address:12ce44344000
[26472.440432] Page Index:1232  Physical address:ffffa1f544345000    Virtual Address:12ce44345000
[26472.440432] Page Index:1233  Physical address:ffffa1f544346000    Virtual Address:12ce44346000

Upvotes: 0

Views: 1156

Answers (1)

Brendan
Brendan

Reputation: 37220

Physical memory is split up into many pages, where each page might be a 4 KiB area; and the physical pages are mapped into virtual memory wherever the kernel feels like it.

For vmalloc(); the kernel allocates "random" (non-consecutive) physical pages and maps them at consecutive virtual addresses. You can convert the address returned by vmalloc() into a physical address, but it will only be a physical address within the first page and won't have anything to do with the physical address of the next page or any other page.

You can convert the virtual address of each separate page into a physical address. E.g. if you use vmalloc() to allocate 1234 pages; then (using a loop like "for(virtual_address = start; virtual_addresss < end; virtual_address += PAGE_SIZE) {) you can find 1234 completely unrelated physical addresses.

Upvotes: 2

Related Questions