Elmys
Elmys

Reputation: 21

Retrieving the physical addresses of all the pages of a virtual memory buffer

I am currently trying to find the physical addresses of all the pages linked to a virtual buffer.

For example if I allocate a buffer of 8kb in virtual memory and that in terms of physical memory it allocates me 2 pages (in the case where the pages are 4kb and everything goes well), I would like to find the physical address of these 2 pages. As if I had allocated them with get_free_pages.

For that I realized this little piece of code by looking at the functions which was at my disposal in the kernel :

void *vbuffer;
struct page *page_list;
unsigned long current_page_addr;

/* Allocate virtual memory buffer */
vbuffer = vmalloc(size);

/* Get pages list from the previously allocated virtual buffer */
page_list = vmalloc_to_page(vbuffer);

do {

    current_page_addr = page_to_phys(page_list);
    page_list = page_list->next;

} while(page_list != NULL);

My question is therefore to know if my code is correct and actually allows me to retrieve my physical addresses of the pages in my current_page_addr variable. Also if I am using the right way or if there is a better way, thank you.

Upvotes: 1

Views: 475

Answers (1)

Ian Abbott
Ian Abbott

Reputation: 17403

I don't think the pages for the vmalloced region are in a list. vmalloc_to_page returns the page corresponding to a virtual address mapped in the vmalloc region, if the page exists. So to find the pages corresponding to the memory allocated by vmalloc or vzalloc, start with the returned address for the first page, and increment the address by PAGE_SIZE for each subsequent page.

void *vbuffer;
struct page *page;
unsigned long current_page_addr;

/* Allocate virtual memory buffer */
vbuffer = vmalloc(size);
if (vbuffer == NULL) {
    goto error;
}

for (size_t offset = 0; offset < size; offset += PAGE_SIZE) {
    page = vmalloc_to_page(vbuffer + offset);
    current_page_addr = page_to_phys(page);
}

Upvotes: 1

Related Questions