Skip to content
This repository was archived by the owner on Dec 25, 2025. It is now read-only.

Commit b394e81

Browse files
committed
Add User Space Allocator to each Process
1 parent ac90cf6 commit b394e81

File tree

8 files changed

+744
-51
lines changed

8 files changed

+744
-51
lines changed

kernel/include/libs/mutex.hpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,12 @@
33
#include <atomic>
44
#include <cstdint>
55

6-
#include "task/process.hpp"
76
#include "libs/spinlock.hpp"
87

8+
namespace kernel::task {
9+
struct Thread;
10+
}
11+
912
namespace kernel {
1013
class Mutex {
1114
public:

kernel/include/memory/vma.hpp

Lines changed: 52 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,13 @@
11
#pragma once
22

3-
#include <cstdint>
4-
#include <cstddef>
3+
#include "libs/mutex.hpp"
54
#include "libs/spinlock.hpp"
65
#include "memory/pagemap.hpp"
76

7+
namespace kernel::task {
8+
struct Process;
9+
}
10+
811
namespace kernel::memory {
912
struct VmRegion {
1013
uintptr_t start;
@@ -70,6 +73,7 @@ class VirtualMemoryAllocator {
7073
void delete_fixup(VmRegion* x);
7174

7275
void update_node_metadata(VmRegion* x);
76+
void update_path_to_root(VmRegion* x);
7377

7478
VmRegion* predecessor(VmRegion* node);
7579
VmRegion* successor(VmRegion* node);
@@ -91,4 +95,50 @@ class VirtualMemoryAllocator {
9195
VmRegion* cached_cursor = nullptr;
9296
VmRegionAllocator metadata_allocator;
9397
};
98+
99+
class UserAddressSpace {
100+
public:
101+
static constexpr uintptr_t USER_START = 0x1000;
102+
static constexpr uintptr_t USER_END = 0x00007FFFFFFFFFFF;
103+
104+
static void arch_init();
105+
106+
void init(task::Process* proc);
107+
~UserAddressSpace();
108+
109+
void* allocate(size_t size, uint8_t flags = Read | Write);
110+
bool allocate_specific(uintptr_t virt_addr, size_t size, uint8_t flags);
111+
void free(void* ptr);
112+
bool handle_page_fault(uintptr_t fault_addr, size_t error_code);
113+
114+
private:
115+
uintptr_t find_hole(size_t size, size_t alignment);
116+
uintptr_t find_hole(VmRegion* node, size_t size, size_t alignment);
117+
118+
VmRegion* find_region_containing(uintptr_t addr);
119+
bool check_overlap(uintptr_t start, size_t size);
120+
121+
void insert_region(uintptr_t start, size_t size, uint8_t flags, CacheType cache);
122+
void delete_node(VmRegion* z);
123+
124+
void rotate_left(VmRegion* x);
125+
void rotate_right(VmRegion* x);
126+
void insert_fixup(VmRegion* z);
127+
void delete_fixup(VmRegion* x);
128+
129+
void update_node_metadata(VmRegion* x);
130+
void update_path_to_root(VmRegion* x);
131+
132+
VmRegion* predecessor(VmRegion* node);
133+
VmRegion* successor(VmRegion* node);
134+
135+
void free_tree(VmRegion* node);
136+
137+
Mutex mutex;
138+
PageMap* page_map;
139+
task::Process* process;
140+
VmRegion* root;
141+
VmRegion* cached_cursor;
142+
VmRegionAllocator metadata_allocator;
143+
};
94144
} // namespace kernel::memory

kernel/include/task/process.hpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
#include "memory/pagemap.hpp"
55
#include "libs/spinlock.hpp"
66
#include "libs/intrusive_list.hpp"
7+
#include "memory/vma.hpp"
78

89
namespace kernel::cpu {
910
struct PerCpuData;
@@ -67,6 +68,7 @@ struct Process : public IntrusiveListNode<ProcessTag> {
6768

6869
IntrusiveList<Process, ProcessTag> children;
6970
IntrusiveList<Thread, ProcessTag> threads;
71+
memory::UserAddressSpace vma;
7072

7173
int exit_code;
7274

@@ -81,6 +83,4 @@ struct Process : public IntrusiveListNode<ProcessTag> {
8183
private:
8284
static std::atomic<size_t> next_pid;
8385
};
84-
85-
extern Process* kernel_proc;
8686
} // namespace kernel::task
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
#include "cpu/registers.hpp"
2+
#include "hal/interrupt.hpp"
3+
#include "hal/smp_manager.hpp"
4+
#include "libs/log.hpp"
5+
#include "memory/vma.hpp"
6+
#include "hal//interface/interrupt.hpp"
7+
8+
#define PF_PRESENT 0x01
9+
#define PF_WRITE 0x02
10+
#define PF_USER 0x04
11+
#define PF_RESERVED_WRITE 0x08
12+
#define PF_INSTRUCTION_FETCH 0x10
13+
#define PF_PROTECTION_KEY 0x20
14+
#define PF_SHADOW_STACK 0x40
15+
#define PF_SGX 0x8000
16+
17+
namespace kernel::memory {
18+
class PageFaultHandler : public cpu::IInterruptHandler {
19+
public:
20+
const char* name() const {
21+
return "Page Fault Handler!";
22+
}
23+
24+
cpu::IrqStatus handle(cpu::arch::TrapFrame* frame) {
25+
arch::Cr2 cr2 = arch::Cr2::read();
26+
cpu::PerCpuData* cpu = cpu::CpuCoreManager::get().get_current_core();
27+
UserAddressSpace& uas = cpu->curr_thread->owner->vma;
28+
29+
if (!uas.handle_page_fault(cr2.linear_address, frame->error_code)) {
30+
PANIC("Page Fault Not handled");
31+
return cpu::IrqStatus::Unhandled;
32+
}
33+
34+
return cpu::IrqStatus::Handled;
35+
}
36+
};
37+
38+
bool UserAddressSpace::handle_page_fault(uintptr_t fault_addr, size_t error_code) {
39+
LockGuard guard(this->mutex);
40+
41+
VmRegion* region = this->find_region_containing(fault_addr);
42+
43+
LOG_DEBUG("PF Handler Called!");
44+
45+
if (!region) {
46+
return false;
47+
}
48+
49+
if ((error_code & PF_WRITE) && !(region->flags & Write)) {
50+
LOG_ERROR("Write violation!");
51+
return false;
52+
}
53+
54+
if ((error_code & PF_USER) && !(region->flags & User)) {
55+
LOG_ERROR("Privilege violation!");
56+
return false;
57+
}
58+
59+
uintptr_t page_base = fault_addr & ~(PAGE_SIZE_4K - 1);
60+
61+
if (this->page_map->translate(page_base) != 0) {
62+
return true;
63+
}
64+
65+
if (!this->page_map->map(page_base, region->flags, region->cache, PageSize::Size4K)) {
66+
LOG_ERROR("Out of memory!");
67+
return false;
68+
}
69+
70+
return true;
71+
}
72+
73+
void UserAddressSpace::arch_init() {
74+
static PageFaultHandler pf_handler;
75+
cpu::arch::InterruptDispatcher::register_handler(EXCEPTION_PAGE_FAULT, &pf_handler);
76+
}
77+
} // namespace kernel::memory

kernel/src/hal/smp.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
#include "boot/boot.h"
22
#include "hal/smp_manager.hpp"
33
#include "libs/log.hpp"
4+
#include "task/process.hpp"
45

56
namespace kernel::cpu {
67
namespace {

0 commit comments

Comments
 (0)