Fix bug in system call "fork"
- issues: memory leak
This commit is contained in:
parent
d4d7ff3aec
commit
a27150b923
5 changed files with 23 additions and 25 deletions
|
@ -42,8 +42,6 @@ static inline int jump_to_user_code(uint32_t ep, uint32_t stack)
|
|||
return 0;
|
||||
}
|
||||
|
||||
int jump_to_child(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -27,10 +27,10 @@
|
|||
#include <asm/page.h>
|
||||
|
||||
gdt_ptr_t gp;
|
||||
static tss_t task_state_segments[MAX_TASKS] __attribute__ ((aligned (4096)));
|
||||
static tss_t task_state_segments[MAX_TASKS] __attribute__ ((aligned (PAGE_SIZE)));
|
||||
static unsigned char kstacks[MAX_TASKS][KERNEL_STACK_SIZE] __attribute__ ((aligned (PAGE_SIZE)));
|
||||
// currently, our kernel has full access to the ioports
|
||||
static gdt_entry_t gdt[GDT_ENTRIES] = {[0 ... GDT_ENTRIES-1] = {0, 0, 0, 0, 0, 0}};
|
||||
static unsigned char kstacks[MAX_TASKS][KERNEL_STACK_SIZE];
|
||||
unsigned char* default_stack_pointer = kstacks[0] + KERNEL_STACK_SIZE - sizeof(size_t);
|
||||
|
||||
/*
|
||||
|
@ -66,27 +66,28 @@ int arch_fork(task_t* task)
|
|||
id = task->id;
|
||||
|
||||
memcpy(task_state_segments+id, task_state_segments+curr_task->id, sizeof(tss_t));
|
||||
memcpy(kstacks[id], kstacks[curr_task->id], KERNEL_STACK_SIZE);
|
||||
task_state_segments[id].cr3 = (uint32_t) (virt_to_phys((size_t)task->pgd));
|
||||
task_state_segments[id].eflags = read_eflags();
|
||||
task_state_segments[id].esp0 = (uint32_t) kstacks[id] + KERNEL_STACK_SIZE - sizeof(size_t);
|
||||
|
||||
asm volatile ("pusha" ::: "%esp");
|
||||
|
||||
memcpy(kstacks[id], kstacks[curr_task->id], KERNEL_STACK_SIZE);
|
||||
|
||||
asm volatile("mov %%esp, %0" : "=r"(task_state_segments[id].esp));
|
||||
if (id > curr_task->id)
|
||||
task_state_segments[id].esp += (id - curr_task->id) * KERNEL_STACK_SIZE;
|
||||
else
|
||||
task_state_segments[id].esp -= (curr_task->id - id) * KERNEL_STACK_SIZE;
|
||||
task_state_segments[id].esp -= (uint32_t) kstacks[curr_task->id];
|
||||
task_state_segments[id].esp += (uint32_t) kstacks[id];
|
||||
|
||||
asm volatile ("pusha");
|
||||
asm volatile ("pop %%eax" : "=a"(task_state_segments[id].edi));
|
||||
asm volatile ("pop %%eax" : "=a"(task_state_segments[id].esi));
|
||||
asm volatile ("pop %%eax" : "=a"(task_state_segments[id].ebp));
|
||||
asm volatile ("add $4, %%esp" ::: "%esp");
|
||||
asm volatile ("pop %%eax" : "=a"(task_state_segments[id].ebx));
|
||||
asm volatile ("pop %%eax" : "=a"(task_state_segments[id].edx));
|
||||
asm volatile ("pop %%eax" : "=a"(task_state_segments[id].ecx));
|
||||
asm volatile ("pop %%eax" : "=a"(task_state_segments[id].eax));
|
||||
|
||||
// This will be the entry point for the new task.
|
||||
task_state_segments[id].eip = read_eip();
|
||||
|
||||
kputs("A\n");
|
||||
asm volatile ("popa" ::: "%esp");
|
||||
kputs("B\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -84,7 +84,7 @@ inline static size_t copy_page_table(uint32_t pgd_index, page_table_t* pgt, int*
|
|||
(*counter)++;
|
||||
|
||||
for(i=0; i<1024; i++) {
|
||||
if (pgt->entries[i] & 0xFFFFF000) {
|
||||
if (pgt->entries[i]) {
|
||||
phyaddr = get_page();
|
||||
if (!phyaddr)
|
||||
continue;
|
||||
|
@ -170,13 +170,12 @@ int create_pgd(task_t* task, int copy)
|
|||
|
||||
if (copy) {
|
||||
for (i=KERNEL_SPACE/(1024*PAGE_SIZE); i<1024; i++) {
|
||||
if (!(curr_task->pgd->entries[i] & 0xFFFFF000))
|
||||
if (!(curr_task->pgd->entries[i]))
|
||||
continue;
|
||||
|
||||
kprintf("i %d\n", i);
|
||||
phyaddr = copy_page_table(i, (page_table_t*) ((KERNEL_SPACE - 1024*PAGE_SIZE + i*PAGE_SIZE) & 0xFFFFF000), &counter);
|
||||
if (phyaddr)
|
||||
pgd->entries[i] = phyaddr | (pgt_container->entries[i] & 0x00000FFF);
|
||||
pgd->entries[i] = (phyaddr & 0xFFFFF000) | (curr_task->pgd->entries[i] & 0xFFF);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -520,7 +519,7 @@ int print_paging_tree(size_t viraddr)
|
|||
|
||||
static void pagefault_handler(struct state *s)
|
||||
{
|
||||
kprintf("PAGE FAULT: Task %u got page fault at %p (irq 0x%x)\n", per_core(current_task)->id, read_cr2(), s->int_no);
|
||||
kprintf("PAGE FAULT: Task %u got page fault at %p (irq %d)\n", per_core(current_task)->id, read_cr2(), s->int_no);
|
||||
kprintf("Register state: eax = 0x%x, ebx = 0x%x, ecx = 0x%x, edx = 0x%x, edi = 0x%x, esi = 0x%x, ebp = 0x%x, esp = 0x%x\n",
|
||||
s->eax, s->ebx, s->ecx, s->edx, s->edi, s->esi, s->ebp, s->esp);
|
||||
|
||||
|
|
|
@ -219,7 +219,7 @@ int sys_fork(void)
|
|||
if (parent != per_core(current_task))
|
||||
return 0; // Oh, the new child! => leave function
|
||||
|
||||
if (ret >= 0) {
|
||||
if (!ret) {
|
||||
task_table[i].status = TASK_READY;
|
||||
ret = i;
|
||||
}
|
||||
|
|
|
@ -109,11 +109,11 @@ int test_init(void)
|
|||
mailbox_int32_init(&mbox);
|
||||
|
||||
create_kernel_task(NULL, foo, "Hello from foo1\n");
|
||||
create_kernel_task(NULL, join_test, NULL);
|
||||
//create_kernel_task(NULL, join_test, NULL);
|
||||
//create_kernel_task(NULL, producer, NULL);
|
||||
//create_kernel_task(NULL, consumer, NULL);
|
||||
create_user_task(NULL, 8192, "/bin/hello", 1, argv);
|
||||
//create_user_task(NULL, 8192, "/bin/tests", 1, argv);
|
||||
//create_user_task(NULL, 8192, "/bin/hello", 1, argv);
|
||||
create_user_task(NULL, 8192, "/bin/tests", 1, argv);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue