new: 初步完成了mmio地址空间自动分配(未测试)

bugfix: mmio虚拟地址分配的bug
This commit is contained in:
fslongjin 2022-08-20 01:05:15 +08:00
parent 05477932de
commit 0223232f3f
14 changed files with 317 additions and 56 deletions

View File

@ -127,7 +127,8 @@
"vfs.h": "c", "vfs.h": "c",
"current.h": "c", "current.h": "c",
"proc-types.h": "c", "proc-types.h": "c",
"traceback.h": "c" "traceback.h": "c",
"bitcount.h": "c"
}, },
"C_Cpp.errorSquiggles": "Enabled", "C_Cpp.errorSquiggles": "Enabled",
"esbonio.sphinx.confDir": "" "esbonio.sphinx.confDir": ""

View File

@ -222,7 +222,7 @@ DragonOS支持对物理页的直接操作
  要取消映射的地址空间的长度   要取消映射的地址空间的长度
### `mm_unmap(virt_addr, length)` ### `mm_unmap_addr(virt_addr, length)`
#### 描述 #### 描述

View File

@ -983,7 +983,7 @@ failed_free_dyn:; // 释放动态申请的内存
failed:; failed:;
io_mfence(); io_mfence();
// 取消地址映射 // 取消地址映射
mm_unmap(xhci_hc[cid].vbase, 65536); mm_unmap_addr(xhci_hc[cid].vbase, 65536);
io_mfence(); io_mfence();
// 清空数组 // 清空数组
memset((void *)&xhci_hc[cid], 0, sizeof(struct xhci_host_controller_t)); memset((void *)&xhci_hc[cid], 0, sizeof(struct xhci_host_controller_t));

View File

@ -57,8 +57,16 @@ int __anon_vma_add(struct anon_vma_t *anon_vma, struct vm_area_struct *vma);
/** /**
* @brief anon_vma的管理范围中删除指定的vma * @brief anon_vma的管理范围中删除指定的vma
* () * (anon_vma加锁)
* @param vma anon_vma管理的vma结构体 * @param vma anon_vma管理的vma结构体
* @return int * @return int
*/ */
int __anon_vma_del(struct vm_area_struct *vma); int __anon_vma_del(struct vm_area_struct *vma);
/**
* @brief mmio对应的页结构体
*
* @param paddr
* @return struct Page* page
*/
struct Page* __create_mmio_page_struct(uint64_t paddr);

View File

@ -1,5 +1,6 @@
#include "mm.h" #include "mm.h"
#include "mm-types.h" #include "mm-types.h"
#include "mmio.h"
#include "slab.h" #include "slab.h"
#include <common/printk.h> #include <common/printk.h>
#include <common/kprint.h> #include <common/kprint.h>
@ -228,6 +229,7 @@ void mm_init()
// 初始化slab内存池 // 初始化slab内存池
slab_init(); slab_init();
page_table_init(); page_table_init();
mmio_init();
} }
/** /**
@ -620,3 +622,19 @@ uint64_t mm_do_brk(uint64_t old_brk_end_addr, int64_t offset)
} }
return end_addr; return end_addr;
} }
/**
* @brief mmio对应的页结构体
*
* @param paddr
* @return struct Page* page
*/
struct Page *__create_mmio_page_struct(uint64_t paddr)
{
struct Page *p = (struct Page *)kzalloc(sizeof(struct Page), 0);
if (p == NULL)
return NULL;
p->addr_phys = paddr;
page_init(p, PAGE_DEVICE);
return p;
}

View File

@ -441,7 +441,7 @@ void mm_unmap_proc_table(ul proc_page_table_addr, bool is_phys, ul virt_addr_sta
* @param virt_addr * @param virt_addr
* @param length * @param length
*/ */
#define mm_unmap(virt_addr, length) ({ \ #define mm_unmap_addr(virt_addr, length) ({ \
mm_unmap_proc_table((uint64_t)get_CR3(), true, virt_addr, length); \ mm_unmap_proc_table((uint64_t)get_CR3(), true, virt_addr, length); \
}) })
@ -467,6 +467,17 @@ int mm_create_vma(struct mm_struct *mm, uint64_t vaddr, uint64_t length, vm_flag
*/ */
int mm_map_vma(struct vm_area_struct *vma, uint64_t paddr); int mm_map_vma(struct vm_area_struct *vma, uint64_t paddr);
/**
* @brief vma
*
* @param mm
* @param vaddr
* @param length
* @param paddr
* @return int
*/
int mm_map(struct mm_struct *mm, uint64_t vaddr, uint64_t length, uint64_t paddr);
/** /**
* @brief vma的映射 * @brief vma的映射
* *
@ -475,7 +486,18 @@ int mm_map_vma(struct vm_area_struct *vma, uint64_t paddr);
* @param paddr * @param paddr
* @return int * @return int
*/ */
int mm_umap_vma(struct mm_struct *mm, struct vm_area_struct *vma, uint64_t *paddr); int mm_unmap_vma(struct mm_struct *mm, struct vm_area_struct *vma, uint64_t *paddr);
/**
* @brief vma中存在
*
* @param mm
* @param vaddr
* @param length
* @param destroy vma结构体
* @return int
*/
int mm_unmap(struct mm_struct *mm, uint64_t vaddr, uint64_t length, bool destroy);
/** /**
* @brief 2M页() * @brief 2M页()

View File

@ -326,7 +326,6 @@ int mm_create_vma(struct mm_struct *mm, uint64_t vaddr, uint64_t length, vm_flag
vma->vm_flags = vm_flags; vma->vm_flags = vm_flags;
vma->vm_start = vaddr; vma->vm_start = vaddr;
vma->vm_end = vaddr + length; vma->vm_end = vaddr + length;
// 将VMA加入mm的链表 // 将VMA加入mm的链表
retval = vma_insert(mm, vma); retval = vma_insert(mm, vma);
if (retval == -EEXIST) // 之前已经存在了相同的vma直接返回 if (retval == -EEXIST) // 之前已经存在了相同的vma直接返回
@ -335,6 +334,7 @@ int mm_create_vma(struct mm_struct *mm, uint64_t vaddr, uint64_t length, vm_flag
kfree(vma); kfree(vma);
return -EEXIST; return -EEXIST;
} }
if (res_vma != NULL)
*res_vma = vma; *res_vma = vma;
return 0; return 0;
} }
@ -350,7 +350,12 @@ int mm_map_vma(struct vm_area_struct *vma, uint64_t paddr)
{ {
int retval = 0; int retval = 0;
// 获取物理地址对应的页面 // 获取物理地址对应的页面
struct Page *pg = Phy_to_2M_Page(paddr); struct Page *pg;
if (vma->vm_flags & VM_IO) // 对于mmio的内存创建新的page结构体
pg = __create_mmio_page_struct(paddr);
else
pg = Phy_to_2M_Page(paddr);
if (unlikely(pg->anon_vma == NULL)) // 若页面不存在anon_vma则为页面创建anon_vma if (unlikely(pg->anon_vma == NULL)) // 若页面不存在anon_vma则为页面创建anon_vma
{ {
spin_lock(&pg->op_lock); spin_lock(&pg->op_lock);
@ -400,8 +405,13 @@ int mm_map_vma(struct vm_area_struct *vma, uint64_t paddr)
if (unlikely(retval != 0)) if (unlikely(retval != 0))
goto failed; goto failed;
} }
// 计算当前vma的起始地址在对应的物理页中的偏移量
if (vma->vm_flags & VM_IO)
vma->page_offset = 0;
else
{ // 计算当前vma的起始地址在对应的物理页中的偏移量
vma->page_offset = paddr - (paddr & PAGE_2M_MASK); vma->page_offset = paddr - (paddr & PAGE_2M_MASK);
}
flush_tlb(); flush_tlb();
return 0; return 0;
failed:; failed:;
@ -409,6 +419,46 @@ failed:;
return retval; return retval;
} }
/**
* @brief vma
*
* @param mm
* @param vaddr
* @param length
* @param paddr
* @return int
*/
int mm_map(struct mm_struct *mm, uint64_t vaddr, uint64_t length, uint64_t paddr)
{
int retval = 0;
for (uint64_t mapped = 0; mapped < length;)
{
struct vm_area_struct *vma = vma_find(mm, vaddr + mapped);
if (unlikely(vma == NULL))
{
kerror("Map addr failed: vma not found. At address: %#018lx, pid=%ld", vaddr + mapped, current_pcb->pid);
return -EINVAL;
}
if (unlikely(vma->vm_start != (vaddr + mapped)))
{
kerror("Map addr failed: addr_start is not equal to current: %#018lx.", vaddr + mapped);
return -EINVAL;
}
retval = mm_map_vma(vma, paddr + mapped);
if (unlikely(retval != 0))
goto failed;
mapped += vma->vm_end - vma->vm_start;
}
return 0;
failed:;
kerror("Map addr failed.");
return retval;
}
/** /**
* @brief vma的映射 * @brief vma的映射
* *
@ -417,15 +467,70 @@ failed:;
* @param paddr * @param paddr
* @return int * @return int
*/ */
int mm_umap_vma(struct mm_struct *mm, struct vm_area_struct *vma, uint64_t *paddr) int mm_unmap_vma(struct mm_struct *mm, struct vm_area_struct *vma, uint64_t *paddr)
{ {
// 确保vma对应的mm与指定的mm相一致 // 确保vma对应的mm与指定的mm相一致
if (unlikely(vma->vm_mm != mm)) if (unlikely(vma->vm_mm != mm))
return -EINVAL; return -EINVAL;
struct anon_vma_t *anon = vma->anon_vma;
if (paddr != NULL) if (paddr != NULL)
*paddr = __mm_get_paddr(mm, vma->vm_start); *paddr = __mm_get_paddr(mm, vma->vm_start);
if (anon == NULL)
kwarn("anon is NULL");
semaphore_down(&anon->sem);
mm_unmap_proc_table((uint64_t)mm->pgd, true, vma->vm_start, vma->vm_end - vma->vm_start); mm_unmap_proc_table((uint64_t)mm->pgd, true, vma->vm_start, vma->vm_end - vma->vm_start);
__anon_vma_del(vma);
/** todo: 这里应该会存在bug应修复。
* anon_vma的等待队列上有其他的进程anon_vma被释放
*
*/
list_init(&vma->anon_vma_list);
semaphore_up(&anon->sem);
return 0; return 0;
} }
/**
* @brief vma中存在
*
* @param mm
* @param vaddr
* @param length
* @param destroy vma结构体
* @return int
*/
int mm_unmap(struct mm_struct *mm, uint64_t vaddr, uint64_t length, bool destroy)
{
int retval = 0;
for (uint64_t unmapped = 0; unmapped < length;)
{
struct vm_area_struct *vma = vma_find(mm, vaddr + unmapped);
if (unlikely(vma == NULL))
{
kerror("Unmap addr failed: vma not found. At address: %#018lx, pid=%ld", vaddr + unmapped, current_pcb->pid);
return -EINVAL;
}
if (unlikely(vma->vm_start != (vaddr + unmapped)))
{
kerror("Unmap addr failed: addr_start is not equal to current: %#018lx.", vaddr + unmapped);
return -EINVAL;
}
if (vma->anon_vma != NULL)
mm_unmap_vma(mm, vma, NULL);
unmapped += vma->vm_end - vma->vm_start;
// 释放vma结构体
if (destroy)
{
vm_area_del(vma);
vm_area_free(vma);
}
}
return 0;
failed:;
kerror("Unmap addr failed.");
return retval;
}

View File

@ -45,16 +45,6 @@ static __always_inline struct __mmio_buddy_addr_region *__mmio_buddy_create_regi
return region; return region;
} }
/**
* @brief address region结构体
*
* @param region
*/
static __always_inline void __release_addr_region(struct __mmio_buddy_addr_region *region)
{
kfree(region);
}
/** /**
* @brief (2^exp) * @brief (2^exp)
* *
@ -84,9 +74,10 @@ static __always_inline int __buddy_merge_blocks(struct __mmio_buddy_addr_region
return -EINVAL; return -EINVAL;
// === 是一对伙伴,将他们合并 // === 是一对伙伴,将他们合并
// __mmio_pool.free_regions[__exp2index(exp)].num_free -=2; // 减少计数的工作应在该函数外完成
// 释放y // 释放y
__release_addr_region(y); __mmio_buddy_release_addr_region(y);
// 插入x // 插入x
__buddy_add_region_obj(__exp2index(exp + 1), x); __buddy_add_region_obj(__exp2index(exp + 1), x);
@ -101,7 +92,7 @@ static __always_inline int __buddy_merge_blocks(struct __mmio_buddy_addr_region
*/ */
static __always_inline struct __mmio_buddy_addr_region *__buddy_pop_region(int exp) static __always_inline struct __mmio_buddy_addr_region *__buddy_pop_region(int exp)
{ {
if (unlikely(&__mmio_pool.free_regions[__exp2index(exp)].list_head)) if (unlikely(list_empty(&__mmio_pool.free_regions[__exp2index(exp)].list_head)))
return NULL; return NULL;
struct __mmio_buddy_addr_region *r = container_of(list_next(&__mmio_pool.free_regions[__exp2index(exp)].list_head), struct __mmio_buddy_addr_region, list); struct __mmio_buddy_addr_region *r = container_of(list_next(&__mmio_pool.free_regions[__exp2index(exp)].list_head), struct __mmio_buddy_addr_region, list);
list_del(&r->list); list_del(&r->list);
@ -176,7 +167,7 @@ static void __buddy_merge(int exp)
* @param exp (2^exp) * @param exp (2^exp)
* @return struct __mmio_buddy_addr_region* NULL * @return struct __mmio_buddy_addr_region* NULL
*/ */
static struct __mmio_buddy_addr_region *__buddy_query_addr_region(int exp) struct __mmio_buddy_addr_region *mmio_buddy_query_addr_region(int exp)
{ {
if (exp >= MMIO_BUDDY_MAX_EXP) if (exp >= MMIO_BUDDY_MAX_EXP)
return NULL; return NULL;
@ -223,7 +214,7 @@ has_block:; // 有可用的内存块,分配
* @param exp 2^exp * @param exp 2^exp
* @return int * @return int
*/ */
static __always_inline int __buddy_give_back(uint64_t vaddr, int exp) int __mmio_buddy_give_back(uint64_t vaddr, int exp)
{ {
// 确保内存对齐低位都要为0 // 确保内存对齐低位都要为0
if (vaddr & ((1UL << exp) - 1)) if (vaddr & ((1UL << exp) - 1))
@ -255,6 +246,5 @@ void mmio_buddy_init()
uint32_t cnt_1g_blocks = (MMIO_TOP - MMIO_BASE) / PAGE_1G_SIZE; uint32_t cnt_1g_blocks = (MMIO_TOP - MMIO_BASE) / PAGE_1G_SIZE;
uint64_t vaddr_base = MMIO_BASE; uint64_t vaddr_base = MMIO_BASE;
for (uint32_t i = 0; i < cnt_1g_blocks; ++i, vaddr_base += PAGE_1G_SIZE) for (uint32_t i = 0; i < cnt_1g_blocks; ++i, vaddr_base += PAGE_1G_SIZE)
__buddy_give_back(vaddr_base, PAGE_1G_SHIFT); __mmio_buddy_give_back(vaddr_base, PAGE_1G_SHIFT);
} }

View File

@ -3,6 +3,7 @@
#include <common/glib.h> #include <common/glib.h>
#include "mm-types.h" #include "mm-types.h"
#include "mm.h" #include "mm.h"
#include "slab.h"
#define MMIO_BUDDY_MAX_EXP PAGE_1G_SHIFT #define MMIO_BUDDY_MAX_EXP PAGE_1G_SHIFT
#define MMIO_BUDDY_MIN_EXP PAGE_4K_SHIFT #define MMIO_BUDDY_MIN_EXP PAGE_4K_SHIFT
@ -44,8 +45,35 @@ struct mmio_buddy_mem_pool
struct __mmio_free_region_list free_regions[MMIO_BUDDY_REGION_COUNT]; struct __mmio_free_region_list free_regions[MMIO_BUDDY_REGION_COUNT];
}; };
/**
* @brief address region结构体
*
* @param region
*/
static __always_inline void __mmio_buddy_release_addr_region(struct __mmio_buddy_addr_region *region)
{
kfree(region);
}
/**
* @brief buddy
*
* @param vaddr
* @param exp 2^exp
* @return int
*/
int __mmio_buddy_give_back(uint64_t vaddr, int exp);
/** /**
* @brief mmio的伙伴系统 * @brief mmio的伙伴系统
* *
*/ */
void mmio_buddy_init(); void mmio_buddy_init();
/**
* @brief buddy中申请一块指定大小的内存区域
*
* @param exp (2^exp)
* @return struct __mmio_buddy_addr_region* NULL
*/
struct __mmio_buddy_addr_region *mmio_buddy_query_addr_region(int exp);

View File

@ -1,5 +1,6 @@
#include "mmio.h" #include "mmio.h"
#include "mmio-buddy.h" #include "mmio-buddy.h"
#include <common/math.h>
void mmio_init() void mmio_init()
{ {
@ -10,15 +11,65 @@ void mmio_init()
* @brief mmio区域vma绑定到initial_mm * @brief mmio区域vma绑定到initial_mm
* *
* @param size mmio区域的大小 * @param size mmio区域的大小
* @param length mmio区域长度
* @param vm_flags vma设置成的标志 * @param vm_flags vma设置成的标志
* @param res_vaddr - * @param res_vaddr -
* @param res_length - * @param res_length -
* @return int * @return int
*/ */
int mmio_create(uint32_t size, uint64_t length, vm_flags_t vm_flags, uint64_t * res_vaddr, uint64_t *res_length) int mmio_create(uint32_t size, vm_flags_t vm_flags, uint64_t *res_vaddr, uint64_t *res_size)
{
int retval = 0;
// 申请的内存超过允许的最大大小
if (unlikely(size > PAGE_1G_SIZE || size == 0))
return -EPERM;
// 计算要从buddy中申请地址空间大小(按照2的n次幂来对齐)
int size_exp = 31 - __clz(size);
if (size_exp < PAGE_4K_SHIFT)
{
size_exp = PAGE_4K_SHIFT;
size = PAGE_4K_SIZE;
}
else if (size & (~(1 << size_exp)))
{
++size_exp;
size = 1 << size_exp;
}
// 申请内存
struct __mmio_buddy_addr_region *buddy_region = mmio_buddy_query_addr_region(size_exp);
if (buddy_region == NULL) // 没有空闲的mmio空间了
return -ENOMEM;
*res_vaddr = buddy_region->vaddr;
*res_size = size;
// 释放region
__mmio_buddy_release_addr_region(buddy_region);
// ====创建vma===
// 设置vma flags
vm_flags |= (VM_IO | VM_DONTCOPY);
uint64_t len_4k = size % PAGE_2M_SIZE;
uint64_t len_2m = size - len_4k;
// 先创建2M的vma然后创建4k的
for (uint32_t i = 0; i < len_2m; i += PAGE_2M_SIZE)
{ {
retval = mm_create_vma(&initial_mm, buddy_region->vaddr + i, PAGE_2M_SIZE, vm_flags, NULL, NULL);
if (unlikely(retval != 0))
goto failed;
}
for (uint32_t i = len_2m; i < size; i += PAGE_4K_SIZE)
{
retval = mm_create_vma(&initial_mm, buddy_region->vaddr + i, PAGE_4K_SIZE, vm_flags, NULL, NULL);
if (unlikely(retval != 0))
goto failed;
}
return 0;
failed:;
kerror("failed to create mmio vma. pid=%d", current_pcb->pid);
// todo: 当失败时将已创建的vma删除
return retval;
} }
/** /**
@ -30,5 +81,38 @@ int mmio_create(uint32_t size, uint64_t length, vm_flags_t vm_flags, uint64_t *
*/ */
int mmio_release(uint64_t vaddr, uint64_t length) int mmio_release(uint64_t vaddr, uint64_t length)
{ {
int retval = 0;
// 先将这些区域都unmap了
mm_unmap(&initial_mm, vaddr, length, false);
// 将这些区域加入buddy
for (uint64_t i = 0; i < length;)
{
struct vm_area_struct *vma = vma_find(&initial_mm, vaddr + i);
if (unlikely(vma == NULL))
{
kerror("mmio_release failed: vma not found. At address: %#018lx, pid=%ld", vaddr + i, current_pcb->pid);
return -EINVAL;
}
if (unlikely(vma->vm_start != (vaddr + i)))
{
kerror("mmio_release failed: addr_start is not equal to current: %#018lx.", vaddr + i);
return -EINVAL;
}
// 往buddy中插入内存块
retval = __mmio_buddy_give_back(vma->vm_start, 31 - __clz(vma->vm_end - vma->vm_start));
i += vma->vm_end - vma->vm_start;
// 释放vma结构体
vm_area_del(vma);
vm_area_free(vma);
if (unlikely(retval != 0))
goto give_back_failed;
}
return 0;
give_back_failed:;
kerror("mmio_release give_back failed: ");
return retval;
} }

View File

@ -7,19 +7,18 @@ void mmio_init();
* @brief mmio区域vma绑定到initial_mm * @brief mmio区域vma绑定到initial_mm
* *
* @param size mmio区域的大小 * @param size mmio区域的大小
* @param length mmio区域长度
* @param vm_flags vma设置成的标志 * @param vm_flags vma设置成的标志
* @param res_vaddr - * @param res_vaddr -
* @param res_length - * @param res_length -
* @return int * @return int
*/ */
int mmio_create(uint32_t size, uint64_t length, vm_flags_t vm_flags, uint64_t * res_vaddr, uint64_t *res_length); int mmio_create(uint32_t size, vm_flags_t vm_flags, uint64_t * res_vaddr, uint64_t *res_size);
/** /**
* @brief mmio的映射并将地址空间归还到buddy中 * @brief mmio的映射并将地址空间归还到buddy中
* *
* @param vaddr * @param vaddr
* @param length * @param size
* @return int * @return int
*/ */
int mmio_release(uint64_t vaddr, uint64_t length); int mmio_release(uint64_t vaddr, uint64_t size);

View File

@ -229,7 +229,7 @@ int __anon_vma_free(struct anon_vma_t *anon_vma)
/** /**
* @brief anon_vma的管理范围中删除指定的vma * @brief anon_vma的管理范围中删除指定的vma
* () * (anon_vma加锁)
* @param vma anon_vma管理的vma结构体 * @param vma anon_vma管理的vma结构体
* @return int * @return int
*/ */
@ -240,16 +240,20 @@ int __anon_vma_del(struct vm_area_struct *vma)
return -EINVAL; return -EINVAL;
list_del(&vma->anon_vma_list); list_del(&vma->anon_vma_list);
semaphore_down(&vma->anon_vma->sem);
atomic_dec(&vma->anon_vma->ref_count); atomic_dec(&vma->anon_vma->ref_count);
// 若当前anon_vma的引用计数归零则意味着可以释放内存页
if (unlikely(atomic_read(&vma->anon_vma->ref_count) == 0)) // 应当释放该anon_vma if (unlikely(atomic_read(&vma->anon_vma->ref_count) == 0)) // 应当释放该anon_vma
{ {
// 若页面结构体是mmio创建的则释放页面结构体
if (vma->anon_vma->page->attr & PAGE_DEVICE)
kfree(vma->anon_vma->page);
else
free_pages(vma->anon_vma->page, 1);
__anon_vma_free(vma->anon_vma); __anon_vma_free(vma->anon_vma);
// 释放了anon_vma之后清理当前vma的关联数据 }
// 清理当前vma的关联数据
vma->anon_vma = NULL; vma->anon_vma = NULL;
list_init(&vma->anon_vma_list); list_init(&vma->anon_vma_list);
} }
else
semaphore_up(&vma->anon_vma->sem);
}

View File

@ -22,6 +22,8 @@
#include <ktest/ktest.h> #include <ktest/ktest.h>
#include <mm/mmio.h>
// #pragma GCC push_options // #pragma GCC push_options
// #pragma GCC optimize("O0") // #pragma GCC optimize("O0")
@ -921,7 +923,7 @@ uint64_t process_copy_mm(uint64_t clone_flags, struct process_control_block *pcb
struct vm_area_struct *vma = current_pcb->mm->vmas; struct vm_area_struct *vma = current_pcb->mm->vmas;
while (vma != NULL) while (vma != NULL)
{ {
if (vma->vm_end > USER_MAX_LINEAR_ADDR) if (vma->vm_end > USER_MAX_LINEAR_ADDR || vma->vm_flags & VM_DONTCOPY)
{ {
vma = vma->vm_next; vma = vma->vm_next;
continue; continue;
@ -997,19 +999,19 @@ uint64_t process_exit_mm(struct process_control_block *pcb)
struct vm_area_struct *vma = pcb->mm->vmas; struct vm_area_struct *vma = pcb->mm->vmas;
while (vma != NULL) while (vma != NULL)
{ {
struct vm_area_struct *cur_vma = vma; struct vm_area_struct *cur_vma = vma;
vma = cur_vma->vm_next; vma = cur_vma->vm_next;
uint64_t pa; uint64_t pa;
mm_umap_vma(pcb->mm, cur_vma, &pa); // kdebug("vm start=%#018lx, sem=%d", cur_vma->vm_start, cur_vma->anon_vma->sem.counter);
mm_unmap_vma(pcb->mm, cur_vma, &pa);
uint64_t size = (cur_vma->vm_end - cur_vma->vm_start); uint64_t size = (cur_vma->vm_end - cur_vma->vm_start);
// 释放内存 // 释放内存
switch (size) switch (size)
{ {
case PAGE_2M_SIZE:
free_pages(Phy_to_2M_Page(pa), 1);
break;
case PAGE_4K_SIZE: case PAGE_4K_SIZE:
kfree(phys_2_virt(pa)); kfree(phys_2_virt(pa));
break; break;
@ -1017,7 +1019,7 @@ uint64_t process_exit_mm(struct process_control_block *pcb)
break; break;
} }
vm_area_del(cur_vma); vm_area_del(cur_vma);
kfree(cur_vma); vm_area_free(cur_vma);
} }
// 释放顶层页表 // 释放顶层页表

View File

@ -18,7 +18,7 @@
#include <common/wait_queue.h> #include <common/wait_queue.h>
#include <mm/mm-types.h> #include <mm/mm-types.h>
#if ARCH(X86_64) #if ARCH(I386) || ARCH(X86_64)
#include <arch/x86_64/current.h> #include <arch/x86_64/current.h>
#else #else
#error Unsupported architecture! #error Unsupported architecture!