Skip to content

vmalloc() and vmap()

Purpose

vmalloc() allocates virtually contiguous kernel memory.

Unlike kmalloc(), which allocates physically contiguous memory, vmalloc() maps independently allocated physical pages into a contiguous virtual address range.


#include <linux/vmalloc.h>

APIs

vmalloc()

Allocates virtually contiguous kernel memory.

void *vmalloc(unsigned long size);

Parameters

Parameter Description
size Number of bytes to allocate.

Return Value

Returns a virtual address on success, or NULL on failure.

Example

void *buffer;

buffer = vmalloc(PAGE_SIZE * 4);
if (!buffer)
    return -ENOMEM;

/* Use the buffer */

vfree(buffer);

vzalloc()

Allocates virtually contiguous memory and initializes the entire region to zero.

void *vzalloc(unsigned long size);

Equivalent to:

vmalloc()
+
memset(..., 0, size)

vfree()

Releases memory previously allocated by vmalloc() or vzalloc().

void vfree(const void *addr);

Example:

vfree(buffer);
buffer = NULL;

vmap()

Creates a virtually contiguous mapping for an existing array of physical pages.

Unlike vmalloc(), vmap() does not allocate backing pages. The caller provides an array of struct page *.

The Linux kernel provides additional mapping flags and page protection attributes. In the learning labs, these parameters are simplified to focus on the virtual mapping mechanism.

void *vmap(struct page **pages,
           unsigned int count,
           unsigned long flags,
           pgprot_t prot);

Parameters

Parameter Description
pages Array of backing physical pages.
count Number of pages.
flags Mapping flags.
prot Page protection attributes.

Return Value

Returns a virtually contiguous address on success, or NULL on failure.

Example

struct page *pages[4];
void *addr;

addr = vmap(pages, 4, VM_MAP, PAGE_KERNEL);

if (!addr)
    return -ENOMEM;

/* Access mapped memory */

vunmap(addr);

vunmap()

Removes a mapping created by vmap().

void vunmap(const void *addr);

Unlike vfree(), vunmap() only removes the virtual mapping. The backing pages remain owned by the caller.

Example

vunmap(addr);

/* Caller releases backing pages separately. */

vmalloc_to_page()

Translates a virtual address within a vmalloc area to its backing physical page.

struct page *vmalloc_to_page(const void *addr);

Parameters

Parameter Description
addr Address within a vmalloc allocation.

Return Value

Returns the backing struct page, or NULL if the address is invalid.

Example

struct page *page;
unsigned long pfn;

page = vmalloc_to_page(buffer);

if (page) {
    pfn = page_to_pfn(page);

    pr_info("PFN = %lu\n", pfn);
}

Notes

  • vmalloc() allocates backing pages and creates a virtual mapping.
  • vfree() removes the mapping and releases the backing pages.
  • vmap() creates a virtual mapping for existing pages.
  • vunmap() removes only the virtual mapping.
  • The caller remains responsible for releasing pages supplied to vmap().
  • vmalloc() may sleep and must not be used in atomic context.

vmalloc() vs kmalloc()

Feature kmalloc() vmalloc() vmap()
Virtual Address Contiguous Contiguous Contiguous
Physical Memory Contiguous Not required Existing pages
Backing Allocation SLUB Buddy + Virtual Mapping Caller
Frees Pages kfree() vfree() Caller
Suitable for DMA Yes Generally No Depends on backing pages
Allocation Speed Faster Slower Faster than vmalloc()

Common Usage Pattern

vmalloc()

void *buf;

buf = vmalloc(size);

...

vfree(buf);

vmap()

struct page *pages[N];
void *addr;

addr = vmap(pages, N, ...);

...

vunmap(addr);

...

free_pages(...);