第一次vmalloc()得到的地址是0xc0311000,第二次vmalloc()得到的地址0xc0313000,相差0x2000,两个页面,即0xc0312000和0xc0314000是guard page的起始地址。 遍历页表可以发现,guard page的PTE是不存在的,即没有物理页的映射。 步骤2中,访问guard page会触发内核的非法内存访问和log,如下 [ 30.995792] Now accessing ...
guard page在vmalloc的具体实现中,通过在没有设置VM_NO_GUARD标志的情况下,多申请一个PAGE_SIZE的虚拟地址空间来实现。虚拟地址申请成功之后再申请物理页面,完成virtual address与物理页之间的映射。不过,上面的过程没有映射guard page,因此访问guard page会引起缺页异常,为内存越界访问提供了一定保护。...
#define VM_NO_GUARD 0x00000040 /* don't add guard page */ #define VM_KASAN 0x00000080 /* has allocated kasan shadow memory */ vmap_area表示内核空间的vmalloc区域的一个vmalloc,由rb_node和list进行串联。 struct vmap_area { unsigned long va_start;---malloc区的起始地址 unsigned long va_end...
if (!(flags & VM_NO_GUARD)) size += PAGE_SIZE;---加一页作为安全区间 va = alloc_vmap_area(size, align, start, end, node, gfp_mask);---申请一个vmap_area并将其插入vmap_area_root中。 if (IS_ERR(va)) { kfree(area); return NULL; } setup_vmalloc_vm(area, va, flags, caller)...
return__vmalloc_node(size, 1, flags, PAGE_KERNEL, node,__builtin_return_address(0)); } __vmalloc_node_flags()从结点请求分配连续虚拟内存,而__vmalloc_node_flags()则是封装__vmalloc_node()。 【file:/mm/vmalloc.c】 /** * __vmalloc_node - allocate virtually contiguous memory ...
#define VM_NO_GUARD 0x00000040 /* don't add guard page */ #define VM_KASAN 0x00000080 /* has allocated kasan shadow memory */ /* bits [20..32] reserved for arch specific ioremap internals */ 2.2 struct vmap_area struct vmap_area { ...
size=PAGE_ALIGN(size);if(unlikely(!size))returnNULL;/*分配一个vm_struct结构*/area= kzalloc_node(sizeof(*area), gfp_mask &GFP_RECLAIM_MASK, node);if(unlikely(!area))returnNULL;/** We always allocate a guard page.*/size+=PAGE_SIZE;/*分配一块虚拟地址空间*/va=alloc_vmap_area(size,...
VM_NO_GUARD | VM_KASAN| 下图给出了该结构使用方式的一个实例. 其中依次映射了3个(假想的)物理内存页, 在物理内存中的位置分别是1 023、725和7 311. 在虚拟的vmalloc区域中, 内核将其看作起始于VMALLOC_START + 100的一个连续内存区, 大小为3*PAGE_SIZE的内核地址空间,被映射到物理页面725, 1023和7311...
@pages是一个指针,指向page指针的数组,每个数组成员都表示一个映射到这个地址空间的物理页面的实例。 @nr_pages:page指针数据的长度 @phys_addr:仅当用ioremap映射了由物理地址描述的物理内存区域才有效。 注意vm_struct和vm_area_struct是完全不同的,虽然二者都是做虚拟地址空间映射的: ...
* We always allocate a guard page. */ size += PAGE_SIZE;// 多偏移一页,为了防止访问越界,由于多出来的一页并不映射,所以当访问的时候,会引发保护异常. va = alloc_vmap_area(size, align, start, end, node, gfp_mask);// 申请vm_area虚拟地址空间 ...