Skip to content

Commit 1a5dd97

Browse files
committed
修复 x86_64 fork 和 VMA 内存泄漏问题
1 parent a943d10 commit 1a5dd97

File tree

4 files changed

+31
-28
lines changed

4 files changed

+31
-28
lines changed

src/arch/x86_64/mem/page_x64.c

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -20,11 +20,11 @@ page_table_t *page_table_create(page_table_entry_t *entry) {
2020
if (entry->value == 0) {
2121
uint64_t frame = alloc_frames(1);
2222
entry->value = frame | PTE_PRESENT | PTE_WRITEABLE | PTE_USER;
23-
page_table_t *table = (page_table_t *)phys_to_virt(entry->value & PTE_FRAME_MASK);
23+
page_table_t *table = phys_to_virt(entry->value & PTE_FRAME_MASK);
2424
page_table_clear(table);
2525
return table;
2626
}
27-
page_table_t *table = (page_table_t *)phys_to_virt(entry->value & PTE_FRAME_MASK);
27+
page_table_t *table = phys_to_virt(entry->value & PTE_FRAME_MASK);
2828
return table;
2929
}
3030

@@ -45,10 +45,10 @@ void page_map_to(page_directory_t *directory, uint64_t addr, uint64_t frame, uin
4545
}
4646

4747
void unmap_page(page_directory_t *directory, uint64_t vaddr) {
48-
uint64_t l4_index = (((vaddr >> 39)) & 0x1FF);
49-
uint64_t l3_index = (((vaddr >> 30)) & 0x1FF);
50-
uint64_t l2_index = (((vaddr >> 21)) & 0x1FF);
51-
uint64_t l1_index = (((vaddr >> 12)) & 0x1FF);
48+
uint64_t l4_index = (vaddr >> 39) & 0x1FF;
49+
uint64_t l3_index = (vaddr >> 30) & 0x1FF;
50+
uint64_t l2_index = (vaddr >> 21) & 0x1FF;
51+
uint64_t l1_index = (vaddr >> 12) & 0x1FF;
5252

5353
page_table_t *l4_table = directory->table;
5454
page_table_t *l3_table = phys_to_virt((&(l4_table->entries[l4_index]))->value & PTE_FRAME_MASK);
@@ -100,7 +100,7 @@ static page_table_t *copy_page_table_recursive(page_table_t *source_table, int l
100100

101101
uint64_t arch_virt_to_phys(uint64_t va) {
102102
uint64_t pml4_phys = get_cr3();
103-
uint64_t *pml4 = (uint64_t *)phys_to_virt(pml4_phys);
103+
uint64_t *pml4 = phys_to_virt(pml4_phys);
104104

105105
size_t pml4_idx = (va >> 39) & ENTRY_MASK;
106106
size_t pdpt_idx = (va >> 30) & ENTRY_MASK;
@@ -110,12 +110,12 @@ uint64_t arch_virt_to_phys(uint64_t va) {
110110

111111
uint64_t pml4e = pml4[pml4_idx];
112112
if (!(pml4e & PTE_PRESENT)) return 0; // not mapped
113-
uint64_t *pdpt = (uint64_t *)phys_to_virt(pml4e & PAGE_MASK);
113+
uint64_t *pdpt = phys_to_virt(pml4e & PAGE_MASK);
114114

115115
uint64_t pdpte = pdpt[pdpt_idx];
116116
if (!(pdpte & PTE_PRESENT)) return 0;
117117
if (pdpte & PTE_HUGE) { return (pdpte & ~((1ULL << 30) - 1)) + (va & ((1ULL << 30) - 1)); }
118-
uint64_t *pd = (uint64_t *)phys_to_virt(pdpte & PAGE_MASK);
118+
uint64_t *pd = phys_to_virt(pdpte & PAGE_MASK);
119119

120120
uint64_t pde = pd[pd_idx];
121121
if (!(pde & PTE_PRESENT)) return 0;
@@ -212,7 +212,7 @@ void arch_page_setup_l2() {
212212
}
213213

214214
void arch_page_setup() {
215-
page_table_t *kernel_page_table = (page_table_t *)phys_to_virt(get_cr3());
215+
page_table_t *kernel_page_table = phys_to_virt(get_cr3());
216216
kernel_page_dir = (page_directory_t){.table = kernel_page_table};
217217
double_fault_page = get_cr3();
218218
}

src/arch/x86_64/task/prsys_x64.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,9 @@ static uint64_t process_fork(struct syscall_regs *reg, bool is_vfork, uint64_t u
3131
return -ENOMEM;
3232
}
3333
tcb_t parent_task = get_current_task();
34-
tcb_t new_task = (tcb_t)malloc(STACK_SIZE);
34+
tcb_t new_task = malloc(STACK_SIZE);
3535
if (new_task == NULL) {
36+
vma_manager_exit_cleanup(&new_pcb->vma_manager);
3637
free(new_pcb->name);
3738
free(new_pcb);
3839
return SYSCALL_FAULT_(ENOMEM);

src/arch/x86_64/task/sched_x64.c

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -329,9 +329,7 @@ _Noreturn void arch_switch_to_user_mode() {
329329
vma_t *region =
330330
vma_find_intersection(&process->vma_manager, get_current_task()->context.user_stack,
331331
get_current_task()->context.user_stack_top);
332-
if (!region) {
333-
vma_insert(&process->vma_manager, stack_vma);
334-
}
332+
if (!region) { vma_insert(&process->vma_manager, stack_vma); }
335333

336334
if (is_dynamic((Elf64_Ehdr *)data)) {
337335
uint64_t linker_start = UINT64_MAX;
@@ -375,7 +373,7 @@ _Noreturn void arch_switch_to_user_mode() {
375373
} else
376374
rsp = build_user_stack(get_current_task(), rsp, (uint64_t)entry, 0, NULL, 0, data,
377375
load_start);
378-
376+
free(data);
379377
arch_close_interrupt();
380378
__asm__ volatile("mov %0, %%es\n"
381379
"mov %0, %%ds\n"

src/mem/page.c

Lines changed: 17 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
#include "mem/page.h"
2-
#include "mem/frame.h"
2+
#include "kasan.h"
33
#include "lock.h"
4+
#include "mem/frame.h"
45
#include "task/smp.h"
56
#include "task/task.h"
6-
#include "kasan.h"
77

8-
page_directory_t kernel_page_dir;
8+
page_directory_t kernel_page_dir;
99

1010
page_directory_t *get_kernel_pagedir() {
1111
return &kernel_page_dir;
@@ -25,11 +25,15 @@ void page_map_range(page_directory_t *directory, uint64_t addr, uint64_t frame,
2525
uint64_t var = addr + i;
2626
page_map_to(directory, var, frame + i, flags);
2727
}
28+
#if KASAN_CHECK
2829
kasan_unpoison((void *)addr, length);
30+
#endif
2931
}
3032

3133
void unmap_page_range(page_directory_t *directory, uint64_t vaddr, uint64_t size) {
34+
#if KASAN_CHECK
3235
kasan_poison((void *)vaddr, size);
36+
#endif
3337
for (uint64_t va = vaddr; va < vaddr + size; va += PAGE_SIZE) {
3438
unmap_page(directory, va);
3539
}
@@ -40,17 +44,19 @@ uint64_t page_alloc_random(page_directory_t *directory, uint64_t length, uint64_
4044
size_t p = length / PAGE_SIZE;
4145
uint64_t addr = alloc_frames(p == 0 ? 1 : p);
4246
for (uint64_t i = 0; i < length; i += 0x1000) {
43-
uint64_t var = (uint64_t)addr + i;
47+
uint64_t var = addr + i;
4448
page_map_to(directory, var, var, flags);
4549
}
50+
#if KASAN_CHECK
4651
kasan_unpoison((void *)addr, length);
52+
#endif
4753
return addr;
4854
}
4955

5056
void page_map_range_to_random(page_directory_t *directory, uint64_t addr, uint64_t length,
5157
uint64_t flags) {
5258
for (uint64_t i = 0; i < length; i += 0x1000) {
53-
uint64_t var = (uint64_t)addr + i;
59+
uint64_t var = addr + i;
5460
page_map_to(directory, var, alloc_frames(1), flags);
5561
}
5662
}
@@ -65,17 +71,15 @@ uint64_t map_change_attribute_range(page_directory_t *directory, uint64_t vaddr,
6571
}
6672

6773
void switch_page_directory(page_directory_t *dir) {
68-
if (arch_current_cpu()) {
69-
arch_current_cpu()->directory = dir;
70-
}
74+
if (arch_current_cpu()) { arch_current_cpu()->directory = dir; }
7175
switch_page_directory0(dir);
7276
}
7377

74-
page_directory_t *switch_context_directory(page_directory_t *directory){
78+
page_directory_t *switch_context_directory(page_directory_t *directory) {
7579
tcb_t thread = get_current_task();
76-
if(thread == NULL) return NULL;
80+
if (thread == NULL) return NULL;
7781
arch_close_interrupt();
78-
page_directory_t *ret = thread->process->directory;
82+
page_directory_t *ret = thread->process->directory;
7983
thread->process->directory = directory;
8084
switch_page_directory(directory);
8185
arch_open_interrupt();
@@ -84,10 +88,10 @@ page_directory_t *switch_context_directory(page_directory_t *directory){
8488

8589
page_directory_t *get_current_directory() {
8690
cpu_local_t *local = arch_current_cpu();
87-
if(local == NULL) return get_kernel_pagedir();
91+
if (local == NULL) return get_kernel_pagedir();
8892
return local->directory;
8993
}
9094

91-
void init_page(){
95+
void init_page() {
9296
arch_page_setup();
9397
}

0 commit comments

Comments
 (0)