forked from Bananymous/banan-os
Kernel: Stack pointer is validated when updated
This allows us not to fail stack pointer when in syscall since interrupts use their own stack
This commit is contained in:
parent
3aa0eeb4a3
commit
be14a6c239
|
@ -4,6 +4,7 @@ SECTIONS
|
||||||
{
|
{
|
||||||
. = 0x00100000;
|
. = 0x00100000;
|
||||||
|
|
||||||
|
g_kernel_start = .;
|
||||||
.text BLOCK(4K) : ALIGN(4K)
|
.text BLOCK(4K) : ALIGN(4K)
|
||||||
{
|
{
|
||||||
*(.multiboot)
|
*(.multiboot)
|
||||||
|
@ -11,9 +12,7 @@ SECTIONS
|
||||||
}
|
}
|
||||||
.rodata BLOCK(4K) : ALIGN(4K)
|
.rodata BLOCK(4K) : ALIGN(4K)
|
||||||
{
|
{
|
||||||
g_rodata_start = .;
|
|
||||||
*(.rodata.*)
|
*(.rodata.*)
|
||||||
g_rodata_end = .;
|
|
||||||
}
|
}
|
||||||
.data BLOCK(4K) : ALIGN(4K)
|
.data BLOCK(4K) : ALIGN(4K)
|
||||||
{
|
{
|
||||||
|
|
|
@ -4,6 +4,7 @@ SECTIONS
|
||||||
{
|
{
|
||||||
. = 0x00100000;
|
. = 0x00100000;
|
||||||
|
|
||||||
|
g_kernel_start = .;
|
||||||
.text BLOCK(4K) : ALIGN(4K)
|
.text BLOCK(4K) : ALIGN(4K)
|
||||||
{
|
{
|
||||||
*(.multiboot)
|
*(.multiboot)
|
||||||
|
@ -11,9 +12,7 @@ SECTIONS
|
||||||
}
|
}
|
||||||
.rodata BLOCK(4K) : ALIGN(4K)
|
.rodata BLOCK(4K) : ALIGN(4K)
|
||||||
{
|
{
|
||||||
g_rodata_start = .;
|
|
||||||
*(.rodata.*)
|
*(.rodata.*)
|
||||||
g_rodata_end = .;
|
|
||||||
}
|
}
|
||||||
.data BLOCK(4K) : ALIGN(4K)
|
.data BLOCK(4K) : ALIGN(4K)
|
||||||
{
|
{
|
||||||
|
|
|
@ -10,9 +10,9 @@ namespace Kernel
|
||||||
{
|
{
|
||||||
|
|
||||||
template<typename T1 = void*, typename T2 = void*, typename T3 = void*>
|
template<typename T1 = void*, typename T2 = void*, typename T3 = void*>
|
||||||
inline int syscall(int syscall, T1 arg1 = nullptr, T2 arg2 = nullptr, T3 arg3 = nullptr)
|
inline long syscall(int syscall, T1 arg1 = nullptr, T2 arg2 = nullptr, T3 arg3 = nullptr)
|
||||||
{
|
{
|
||||||
int ret;
|
long ret;
|
||||||
asm volatile("int $0x80" : "=a"(ret) : "a"(syscall), "b"((uintptr_t)arg1), "c"((uintptr_t)arg2), "d"((uintptr_t)arg3) : "memory");
|
asm volatile("int $0x80" : "=a"(ret) : "a"(syscall), "b"((uintptr_t)arg1), "c"((uintptr_t)arg2), "d"((uintptr_t)arg3) : "memory");
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,7 +33,7 @@ namespace Kernel
|
||||||
|
|
||||||
pid_t tid() const { return m_tid; }
|
pid_t tid() const { return m_tid; }
|
||||||
|
|
||||||
void set_rsp(uintptr_t rsp) { m_rsp = rsp; }
|
void set_rsp(uintptr_t rsp) { m_rsp = rsp; validate_stack(); }
|
||||||
void set_rip(uintptr_t rip) { m_rip = rip; }
|
void set_rip(uintptr_t rip) { m_rip = rip; }
|
||||||
uintptr_t rsp() const { return m_rsp; }
|
uintptr_t rsp() const { return m_rsp; }
|
||||||
uintptr_t rip() const { return m_rip; }
|
uintptr_t rip() const { return m_rip; }
|
||||||
|
@ -49,9 +49,13 @@ namespace Kernel
|
||||||
Process& process();
|
Process& process();
|
||||||
bool has_process() const { return m_process; }
|
bool has_process() const { return m_process; }
|
||||||
|
|
||||||
|
void set_in_syscall(bool b) { m_in_syscall = b; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Thread(pid_t tid, Process*);
|
Thread(pid_t tid, Process*);
|
||||||
|
|
||||||
|
void validate_stack() const { if (!m_in_syscall) ASSERT(stack_base() <= m_rsp && m_rsp <= stack_base() + stack_size()); }
|
||||||
|
|
||||||
BAN::ErrorOr<void> initialize(entry_t, void*);
|
BAN::ErrorOr<void> initialize(entry_t, void*);
|
||||||
void on_exit();
|
void on_exit();
|
||||||
|
|
||||||
|
@ -63,6 +67,7 @@ namespace Kernel
|
||||||
const pid_t m_tid { 0 };
|
const pid_t m_tid { 0 };
|
||||||
State m_state { State::NotStarted };
|
State m_state { State::NotStarted };
|
||||||
Process* m_process { nullptr };
|
Process* m_process { nullptr };
|
||||||
|
bool m_in_syscall { false };
|
||||||
|
|
||||||
friend class Scheduler;
|
friend class Scheduler;
|
||||||
};
|
};
|
||||||
|
|
|
@ -45,7 +45,8 @@ namespace Kernel
|
||||||
[](void* entry_func)
|
[](void* entry_func)
|
||||||
{
|
{
|
||||||
Thread& current = Thread::current();
|
Thread& current = Thread::current();
|
||||||
Process::current().m_mmu->map_range(current.stack_base(), current.stack_size(), MMU::Flags::UserSupervisor | MMU::Flags::ReadWrite | MMU::Flags::Present);
|
current.process().m_mmu->map_range(current.stack_base(), current.stack_size(), MMU::Flags::UserSupervisor | MMU::Flags::ReadWrite | MMU::Flags::Present);
|
||||||
|
current.process().m_mmu->load();
|
||||||
current.jump_userspace((uintptr_t)entry_func);
|
current.jump_userspace((uintptr_t)entry_func);
|
||||||
ASSERT_NOT_REACHED();
|
ASSERT_NOT_REACHED();
|
||||||
}, (void*)entry
|
}, (void*)entry
|
||||||
|
|
|
@ -158,8 +158,6 @@ namespace Kernel
|
||||||
current.set_rip(rip);
|
current.set_rip(rip);
|
||||||
current.set_rsp(rsp);
|
current.set_rsp(rsp);
|
||||||
|
|
||||||
ASSERT(current.stack_base() <= rsp && rsp <= current.stack_base() + current.stack_size());
|
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -10,29 +10,29 @@ namespace Kernel
|
||||||
Process::current().exit();
|
Process::current().exit();
|
||||||
}
|
}
|
||||||
|
|
||||||
int sys_read(int fd, void* buffer, size_t size)
|
long sys_read(int fd, void* buffer, size_t size)
|
||||||
{
|
{
|
||||||
auto res = Process::current().read(fd, buffer, size);
|
auto res = Process::current().read(fd, buffer, size);
|
||||||
if (res.is_error())
|
if (res.is_error())
|
||||||
return res.error().get_error_code();
|
return res.error().get_error_code();
|
||||||
return 0;
|
return res.value();
|
||||||
}
|
}
|
||||||
|
|
||||||
int sys_write(int fd, const void* buffer, size_t size)
|
long sys_write(int fd, const void* buffer, size_t size)
|
||||||
{
|
{
|
||||||
auto res = Process::current().write(fd, buffer, size);
|
auto res = Process::current().write(fd, buffer, size);
|
||||||
if (res.is_error())
|
if (res.is_error())
|
||||||
return res.error().get_error_code();
|
return res.error().get_error_code();
|
||||||
return 0;
|
return res.value();
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" int cpp_syscall_handler(int syscall, void* arg1, void* arg2, void* arg3)
|
extern "C" long cpp_syscall_handler(int syscall, void* arg1, void* arg2, void* arg3)
|
||||||
{
|
{
|
||||||
(void)arg1;
|
Thread::current().set_in_syscall(true);
|
||||||
(void)arg2;
|
|
||||||
(void)arg3;
|
|
||||||
|
|
||||||
int ret = 0;
|
asm volatile("sti");
|
||||||
|
|
||||||
|
long ret = 0;
|
||||||
switch (syscall)
|
switch (syscall)
|
||||||
{
|
{
|
||||||
case SYS_EXIT:
|
case SYS_EXIT:
|
||||||
|
@ -50,6 +50,10 @@ namespace Kernel
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
asm volatile("cli");
|
||||||
|
|
||||||
|
Thread::current().set_in_syscall(false);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -99,12 +99,12 @@ namespace BAN::Formatter
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" uintptr_t g_rodata_start;
|
|
||||||
extern "C" uintptr_t g_rodata_end;
|
|
||||||
|
|
||||||
extern "C" uintptr_t g_userspace_start;
|
extern "C" uintptr_t g_userspace_start;
|
||||||
extern "C" uintptr_t g_userspace_end;
|
extern "C" uintptr_t g_userspace_end;
|
||||||
|
|
||||||
|
extern "C" uintptr_t g_kernel_start;
|
||||||
|
extern "C" uintptr_t g_kernel_end;
|
||||||
|
|
||||||
extern void userspace_entry();
|
extern void userspace_entry();
|
||||||
static void jump_userspace();
|
static void jump_userspace();
|
||||||
|
|
||||||
|
@ -213,7 +213,7 @@ static void jump_userspace()
|
||||||
using namespace Kernel;
|
using namespace Kernel;
|
||||||
|
|
||||||
MMU::get().map_range((uintptr_t)&g_userspace_start, (uintptr_t)&g_userspace_end - (uintptr_t)&g_userspace_start, MMU::Flags::UserSupervisor | MMU::Flags::Present);
|
MMU::get().map_range((uintptr_t)&g_userspace_start, (uintptr_t)&g_userspace_end - (uintptr_t)&g_userspace_start, MMU::Flags::UserSupervisor | MMU::Flags::Present);
|
||||||
MMU::get().map_range((uintptr_t)&g_rodata_start, (uintptr_t)&g_rodata_end - (uintptr_t)&g_rodata_start, MMU::Flags::UserSupervisor | MMU::Flags::Present);
|
MMU::get().map_range((uintptr_t)&g_kernel_start, (uintptr_t)&g_kernel_end - (uintptr_t)&g_kernel_start, MMU::Flags::UserSupervisor | MMU::Flags::Present);
|
||||||
|
|
||||||
MUST(Process::create_userspace(userspace_entry));
|
MUST(Process::create_userspace(userspace_entry));
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,5 +8,13 @@
|
||||||
USERSPACE void userspace_entry()
|
USERSPACE void userspace_entry()
|
||||||
{
|
{
|
||||||
Kernel::syscall(SYS_WRITE, STDOUT_FILENO, "Hello World!", 12);
|
Kernel::syscall(SYS_WRITE, STDOUT_FILENO, "Hello World!", 12);
|
||||||
|
|
||||||
|
char buffer[128];
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
long n_read = Kernel::syscall(SYS_READ, STDIN_FILENO, buffer, sizeof(buffer));
|
||||||
|
Kernel::syscall(SYS_WRITE, STDOUT_FILENO, buffer, n_read);
|
||||||
|
}
|
||||||
|
|
||||||
Kernel::syscall(SYS_EXIT);
|
Kernel::syscall(SYS_EXIT);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue