aboutsummaryrefslogtreecommitdiff
path: root/kernel/features
diff options
context:
space:
mode:
authorMarvin Borner2021-04-10 00:26:39 +0200
committerMarvin Borner2021-04-10 00:26:39 +0200
commit9655593d80e23d2ea3c091e3187e8e47b278bc3d (patch)
treef618723fd9d457147f4663d2d4990f69fabb2d48 /kernel/features
parenteeb88df1d501ccec4737c18dddb7ca0a1176304f (diff)
Gave procs own kernel stack (TSS)
Diffstat (limited to 'kernel/features')
-rw-r--r--kernel/features/load.c31
-rw-r--r--kernel/features/mm.c8
-rw-r--r--kernel/features/proc.c2
3 files changed, 31 insertions, 10 deletions
diff --git a/kernel/features/load.c b/kernel/features/load.c
index df01e04..02c02ae 100644
--- a/kernel/features/load.c
+++ b/kernel/features/load.c
@@ -145,7 +145,8 @@ res elf_load(const char *name, struct proc *proc)
/* } */
// Remap readonly sections
- if (!(section.flags & ELF_SECTION_FLAG_WRITE)) {
+ if (!(section.flags & ELF_SECTION_FLAG_WRITE) && section.addr &&
+ memory_is_user((void *)section.addr)) {
struct memory_range range =
memory_range_around(section.addr + rand_off, section.size);
virtual_remap_readonly(proc->page_dir, range);
@@ -158,14 +159,26 @@ res elf_load(const char *name, struct proc *proc)
stac();
- // Allocate stack with readonly lower and upper page boundary
- u32 stack = PAGE_SIZE + (u32)memory_alloc(proc->page_dir, PROC_STACK_SIZE + 2 * PAGE_SIZE,
- MEMORY_USER | MEMORY_CLEAR);
- virtual_remap_readonly(proc->page_dir, memory_range(stack - PAGE_SIZE, PAGE_SIZE));
- virtual_remap_readonly(proc->page_dir, memory_range(stack + PROC_STACK_SIZE, PAGE_SIZE));
-
- proc->regs.ebp = stack + PROC_STACK_SIZE;
- proc->regs.useresp = stack + PROC_STACK_SIZE;
+ // Allocate user stack with readonly lower and upper page boundary
+ u32 user_stack =
+ PAGE_SIZE + (u32)memory_alloc(proc->page_dir, PROC_STACK_SIZE + 2 * PAGE_SIZE,
+ MEMORY_USER | MEMORY_CLEAR);
+ virtual_remap_readonly(proc->page_dir, memory_range(user_stack - PAGE_SIZE, PAGE_SIZE));
+ virtual_remap_readonly(proc->page_dir,
+ memory_range(user_stack + PROC_STACK_SIZE, PAGE_SIZE));
+
+ // Allocate kernel stack with readonly lower and upper page boundary
+ u32 kernel_stack =
+ PAGE_SIZE +
+ (u32)memory_alloc(proc->page_dir, PROC_STACK_SIZE + 2 * PAGE_SIZE, MEMORY_CLEAR);
+ virtual_remap_readonly(proc->page_dir, memory_range(kernel_stack - PAGE_SIZE, PAGE_SIZE));
+ virtual_remap_readonly(proc->page_dir,
+ memory_range(kernel_stack + PROC_STACK_SIZE, PAGE_SIZE));
+
+ proc->user_stack = user_stack + PROC_STACK_SIZE;
+ proc->kernel_stack = kernel_stack + PROC_STACK_SIZE;
+ proc->regs.ebp = proc->user_stack;
+ proc->regs.useresp = proc->user_stack;
proc->regs.eip = header.entry + rand_off;
proc->entry = header.entry + rand_off;
diff --git a/kernel/features/mm.c b/kernel/features/mm.c
index 466e448..0972ab3 100644
--- a/kernel/features/mm.c
+++ b/kernel/features/mm.c
@@ -677,8 +677,11 @@ void memory_user_hook(void)
}
}
-CLEAR void memory_install(struct mem_info *mem_info, struct vid_info *vid_info)
+CLEAR void memory_install(struct boot_info *boot)
{
+ struct mem_info *mem_info = boot->mem;
+ struct vid_info *vid_info = boot->vid;
+
for (struct mmap_boot *p = mem_info->start; (u32)(p - mem_info->start) < mem_info->size;
p++) {
if (p->hbase || !p->acpi || !p->type)
@@ -731,6 +734,9 @@ CLEAR void memory_install(struct mem_info *mem_info, struct vid_info *vid_info)
MEMORY_NONE);
fb_map_buffer(virtual_kernel_dir(), vid_info);
+ // Map TSS
+ memory_map_identity(&kernel_dir, memory_range_around(boot->tss, 0x1000), MEMORY_NONE);
+
// Unmap NULL byte/page
struct memory_range zero = memory_range(0, PAGE_SIZE);
virtual_free(&kernel_dir, zero);
diff --git a/kernel/features/proc.c b/kernel/features/proc.c
index 479427c..d5bf2e6 100644
--- a/kernel/features/proc.c
+++ b/kernel/features/proc.c
@@ -54,6 +54,7 @@ HOT FLATTEN void scheduler(struct regs *regs)
current = idle_proc;
}
+ tss_set_stack(0x10, PROC(current)->kernel_stack);
memory_switch_dir(PROC(current)->page_dir);
memcpy(regs, &PROC(current)->regs, sizeof(*regs));
@@ -581,6 +582,7 @@ NORETURN void proc_init(void)
// We'll shortly jump to usermode. Clear and protect every secret!
memory_user_hook();
+ tss_set_stack(0x10, init->kernel_stack);
memory_switch_dir(init->page_dir);
printf("Jumping to userspace!\n");