fix (proc): made threads working in isolated process setup

This commit is contained in:
antifallobst 2023-03-08 01:01:12 +01:00
parent 35783e6538
commit c4d09a17ee
6 changed files with 60 additions and 16 deletions

View File

@ -29,13 +29,17 @@
#define KERNEL_START_ADDRESS (uint64_t)&_kernel_start
#define KERNEL_END_ADDRESS (uint64_t)&_kernel_end
#define MEM_REGION_THREAD_OFFSET 0x100000000
#define MEM_REGION_PROCESS 0x0000000000000000
#define MEM_REGION_PROCESS_EXEC 0x0000010000000000
#define MEM_REGION_PROCESS_THREAD_DATA 0x0000010100000000
#define MEM_REGION_PROCESS_THREAD_BASE 0x0000010100000000
#define MEM_REGION_KERNEL 0xFFFF800000000000
#define MEM_REGION_KERNEL_STACK_DUMMY 0xFFFFF00000000000 // size 0x4000
#define MEM_REGION_KERNEL_HEAP 0xFFFFF80000000000
#define MEM_REGION_KERNEL_THREAD_BASE 0xFFFFFF0000000000
#define MEM_REGION_KERNEL_EXEC 0xFFFFFFFF80000000
#define MEM_REGION_KERNEL_HEAP 0xFFFFFFFFF0000000
extern uint64_t _kernel_start;
extern uint64_t _kernel_end;

View File

@ -26,9 +26,13 @@
#include "utils/stdtypes.h"
#include "utils/string.h"
#include "utils/bitmap.h"
#include "mm/page_map.h"
#include "drivers/elf/elf.h"
#define MAX_THREADS_PER_PROCESS 64
#define THREAD_ID_INVALID (-1)
typedef uint32_t pid_t;
typedef enum {
@ -48,6 +52,7 @@ struct process_T {
uint32_t num_threads;
void* threads;
bitmap_T thread_ids;
process_T* parent;
process_T* childs;
@ -55,9 +60,11 @@ struct process_T {
process_T* next;
};
void process_kernel_spawn (elf_executable_T* executable);
pid_t process_spawn (pid_t parent, string_t name, elf_executable_T* executable, void* buffer);
void process_kill_pid (pid_t pid);
void process_kill (process_T* process);
void process_kernel_spawn (elf_executable_T* executable);
pid_t process_spawn (pid_t parent, string_t name, elf_executable_T* executable, void* buffer);
int32_t process_get_thread_id (process_T* process);
void process_clear_thread_id (process_T* process, uint32_t id);
void process_kill_pid (pid_t pid);
void process_kill (process_T* process);
#endif //NOX_PROCESS_H

View File

@ -42,6 +42,7 @@ struct thread_T{
thread_T* local_prev;
thread_T* local_next;
uint32_t local_id;
};

View File

@ -47,6 +47,7 @@ pid_t process_spawn(pid_t parent, string_t name, elf_executable_T* executable, v
process_T* process = memory_allocate(sizeof(process_T));
process->num_threads = 0;
process->threads = NULL;
process->thread_ids = bitmap_init(MAX_THREADS_PER_PROCESS);
process->parent = scheduler_get_process(parent);
process->executable = executable;
@ -60,6 +61,20 @@ pid_t process_spawn(pid_t parent, string_t name, elf_executable_T* executable, v
return scheduler_register_process(process);
}
int32_t process_get_thread_id(process_T* process) {
for (int i = 0; i < MAX_THREADS_PER_PROCESS; i++) {
if (!bitmap_get(&process->thread_ids, i)) {
bitmap_set(&process->thread_ids, i, true);
return i;
}
}
return THREAD_ID_INVALID;
}
void process_clear_thread_id(process_T* process, uint32_t id) {
bitmap_set(&process->thread_ids, id, false);
}
void process_kill_pid(pid_t pid) {
process_kill(scheduler_get_process(pid));
}
@ -69,6 +84,7 @@ void process_kill(process_T* process) {
elf_executable_destruct(process->executable);
page_map_destruct(process->page_map);
bitmap_destruct(&process->thread_ids);
memory_free(process);
}

View File

@ -324,7 +324,7 @@ cpu_state_T* scheduler_switch_context(cpu_state_T* state) {
}
// dirty map 0x0000010000000000 <--> 0x0000020000000000
for (int i = 1; i < 4; i++) {
for (int i = 2; i < 5; i++) {
g_kernel_page_map->entries[i] = new_thread->process->page_map->entries[i];
}

View File

@ -35,18 +35,31 @@ thread_T* thread_spawn(pid_t process, void* function) {
thread->process = scheduler_get_process(process);
if (thread->process == NULL) {
memory_free(thread);
log(LOG_WARNING, "<Thread> failed to spawn thread for process %d (invalid pid)", process);
return NULL;
}
int32_t id = process_get_thread_id(thread->process);
if (id == THREAD_ID_INVALID) {
memory_free(thread);
log(LOG_WARNING, "<Thread> failed to spawn thread for process %d (no free thread id)", process);
return NULL;
}
thread->local_id = (uint32_t)id;
uint8_t* base = (uint8_t*)((process == PROCESS_KERNEL ? MEM_REGION_KERNEL_THREAD_BASE : MEM_REGION_PROCESS_THREAD_BASE) + (MEM_REGION_THREAD_OFFSET * thread->local_id));
log(LOG_DEBUG, "spawning thread with base address: 0x%x", base);
thread->cpu_time = 0;
thread->stack_size = PFRAME_SIZE * 4;
thread->stack = MEM_REGION_PROCESS_THREAD_DATA;
thread->stack = base;
for (int i = 0; i < 4; i++) {
void* physical_address = pframe_request();
page_map_map_memory(thread->process->page_map, MEM_REGION_PROCESS_THREAD_DATA + (i * PFRAME_SIZE), physical_address, PM_FLAG_READ_WRITE);
page_map_map_memory(g_kernel_page_map, MEM_REGION_PROCESS_THREAD_DATA + (i * PFRAME_SIZE), physical_address, PM_FLAG_READ_WRITE);
page_map_map_memory(thread->process->page_map, &base[i * PFRAME_SIZE], physical_address, PM_FLAG_READ_WRITE);
page_map_map_memory(g_kernel_page_map, MEM_REGION_KERNEL_STACK_DUMMY + i * PFRAME_SIZE, physical_address, PM_FLAG_READ_WRITE);
}
cpu_state_T state = {
@ -67,16 +80,14 @@ thread_T* thread_spawn(pid_t process, void* function) {
.ss = GDT_SELECTOR_KERNEL_DATA
};
memory_copy(&state, thread->stack + (thread->stack_size - sizeof(cpu_state_T)), sizeof(cpu_state_T));
memory_copy(&state, MEM_REGION_KERNEL_STACK_DUMMY + (thread->stack_size - sizeof(cpu_state_T)), sizeof(cpu_state_T));
thread->state = thread->stack + (thread->stack_size - sizeof(cpu_state_T));
for (int i = 0; i < 4; i++) {
page_map_unmap_memory(g_kernel_page_map, MEM_REGION_PROCESS_THREAD_DATA + (PFRAME_SIZE * i));
page_map_unmap_memory(g_kernel_page_map, MEM_REGION_KERNEL_STACK_DUMMY + i * PFRAME_SIZE);
}
page_map_dump_info(thread->process->page_map);
return scheduler_register_thread(thread);
}
@ -85,6 +96,7 @@ thread_T* thread_spawn_from_state(pid_t process, cpu_state_T* state) {
thread->process = scheduler_get_process(process);
if (thread->process == NULL) {
memory_free(thread);
log(LOG_WARNING, "<Thread> failed to spawn thread for process %d (invalid pid)", process);
return NULL;
}
@ -109,11 +121,15 @@ void thread_pause(thread_T* thread) {
void thread_kill(thread_T* thread) {
scheduler_kill_thread(thread);
process_clear_thread_id(thread->process, thread->local_id);
uint8_t* base = (uint8_t*)((thread->process->id == PROCESS_KERNEL ? MEM_REGION_KERNEL_THREAD_BASE : MEM_REGION_PROCESS_THREAD_BASE) + (MEM_REGION_THREAD_OFFSET * thread->local_id));
if (thread->stack != NULL) {
for (int i = 0; i < 4; i++) {
void* pframe = page_map_get_physical_address(thread->process->page_map, MEM_REGION_PROCESS_THREAD_DATA + (PFRAME_SIZE * i));
void* pframe = page_map_get_physical_address(thread->process->page_map, &base[PFRAME_SIZE * i]);
pframe_free(pframe);
page_map_unmap_memory(thread->process->page_map, MEM_REGION_PROCESS_THREAD_DATA + (PFRAME_SIZE * i));
page_map_unmap_memory(thread->process->page_map, &base[PFRAME_SIZE * i]);
}
}