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; | ||||
| 
 | ||||
| 	g_kernel_start = .; | ||||
| 	.text BLOCK(4K) : ALIGN(4K) | ||||
| 	{ | ||||
| 		*(.multiboot) | ||||
|  | @ -11,9 +12,7 @@ SECTIONS | |||
| 	} | ||||
| 	.rodata BLOCK(4K) : ALIGN(4K) | ||||
| 	{ | ||||
| 		g_rodata_start = .; | ||||
| 		*(.rodata.*) | ||||
| 		g_rodata_end = .; | ||||
| 	} | ||||
| 	.data BLOCK(4K) : ALIGN(4K) | ||||
| 	{ | ||||
|  |  | |||
|  | @ -4,6 +4,7 @@ SECTIONS | |||
| { | ||||
| 	. = 0x00100000; | ||||
| 
 | ||||
| 	g_kernel_start = .; | ||||
| 	.text BLOCK(4K) : ALIGN(4K) | ||||
| 	{ | ||||
| 		*(.multiboot) | ||||
|  | @ -11,9 +12,7 @@ SECTIONS | |||
| 	} | ||||
| 	.rodata BLOCK(4K) : ALIGN(4K) | ||||
| 	{ | ||||
| 		g_rodata_start = .; | ||||
| 		*(.rodata.*) | ||||
| 		g_rodata_end = .; | ||||
| 	} | ||||
| 	.data BLOCK(4K) : ALIGN(4K) | ||||
| 	{ | ||||
|  |  | |||
|  | @ -10,9 +10,9 @@ namespace Kernel | |||
| { | ||||
| 
 | ||||
| 	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"); | ||||
| 		return ret; | ||||
| 	} | ||||
|  |  | |||
|  | @ -33,7 +33,7 @@ namespace Kernel | |||
| 
 | ||||
| 		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; } | ||||
| 		uintptr_t rsp() const { return m_rsp; } | ||||
| 		uintptr_t rip() const { return m_rip; } | ||||
|  | @ -49,9 +49,13 @@ namespace Kernel | |||
| 		Process& process(); | ||||
| 		bool has_process() const { return m_process; } | ||||
| 
 | ||||
| 		void set_in_syscall(bool b) { m_in_syscall = b; } | ||||
| 
 | ||||
| 	private: | ||||
| 		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*); | ||||
| 		void on_exit(); | ||||
| 		 | ||||
|  | @ -63,6 +67,7 @@ namespace Kernel | |||
| 		const pid_t	m_tid			{ 0 }; | ||||
| 		State		m_state			{ State::NotStarted }; | ||||
| 		Process*	m_process		{ nullptr }; | ||||
| 		bool		m_in_syscall	{ false }; | ||||
| 
 | ||||
| 		friend class Scheduler; | ||||
| 	}; | ||||
|  |  | |||
|  | @ -45,7 +45,8 @@ namespace Kernel | |||
| 			[](void* entry_func) | ||||
| 			{ | ||||
| 				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); | ||||
| 				ASSERT_NOT_REACHED(); | ||||
| 			}, (void*)entry | ||||
|  |  | |||
|  | @ -158,8 +158,6 @@ namespace Kernel | |||
| 		current.set_rip(rip); | ||||
| 		current.set_rsp(rsp); | ||||
| 
 | ||||
| 		ASSERT(current.stack_base() <= rsp && rsp <= current.stack_base() + current.stack_size()); | ||||
| 
 | ||||
| 		return false; | ||||
| 	} | ||||
| 
 | ||||
|  |  | |||
|  | @ -10,29 +10,29 @@ namespace Kernel | |||
| 		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); | ||||
| 		if (res.is_error()) | ||||
| 			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); | ||||
| 		if (res.is_error()) | ||||
| 			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; | ||||
| 		(void)arg2; | ||||
| 		(void)arg3; | ||||
| 		Thread::current().set_in_syscall(true); | ||||
| 
 | ||||
| 		int ret = 0; | ||||
| 		asm volatile("sti"); | ||||
| 
 | ||||
| 		long ret = 0; | ||||
| 		switch (syscall) | ||||
| 		{ | ||||
| 		case SYS_EXIT: | ||||
|  | @ -50,6 +50,10 @@ namespace Kernel | |||
| 			break; | ||||
| 		} | ||||
| 
 | ||||
| 		asm volatile("cli"); | ||||
| 
 | ||||
| 		Thread::current().set_in_syscall(false); | ||||
| 
 | ||||
| 		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_end; | ||||
| 
 | ||||
| extern "C" uintptr_t g_kernel_start; | ||||
| extern "C" uintptr_t g_kernel_end; | ||||
| 
 | ||||
| extern void userspace_entry(); | ||||
| static void jump_userspace(); | ||||
| 
 | ||||
|  | @ -213,7 +213,7 @@ static void jump_userspace() | |||
| 	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_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)); | ||||
| } | ||||
|  |  | |||
|  | @ -8,5 +8,13 @@ | |||
| USERSPACE void userspace_entry() | ||||
| { | ||||
| 	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); | ||||
| } | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue