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