diff --git a/Kernel/Arch/x86/DescriptorTable.h b/Kernel/Arch/x86/DescriptorTable.h index 51585279a3..907dd5f998 100644 --- a/Kernel/Arch/x86/DescriptorTable.h +++ b/Kernel/Arch/x86/DescriptorTable.h @@ -28,8 +28,9 @@ static_assert(GDT_SELECTOR_CODE0 + 24 == GDT_SELECTOR_DATA3); // SS3 = CS0 + 32 #else # define GDT_SELECTOR_CODE0 0x08 # define GDT_SELECTOR_CODE3 0x10 -# define GDT_SELECTOR_TSS 0x18 -# define GDT_SELECTOR_TSS_PART2 0x20 +# define GDT_SELECTOR_DATA3 0x18 +# define GDT_SELECTOR_TSS 0x20 +# define GDT_SELECTOR_TSS_PART2 0x28 #endif namespace Kernel { diff --git a/Kernel/Arch/x86/common/Processor.cpp b/Kernel/Arch/x86/common/Processor.cpp index 48b9bbef7b..f608713c78 100644 --- a/Kernel/Arch/x86/common/Processor.cpp +++ b/Kernel/Arch/x86/common/Processor.cpp @@ -1070,6 +1070,7 @@ UNMAP_AFTER_INIT void Processor::gdt_init() #else write_raw_gdt_entry(GDT_SELECTOR_CODE0, 0x0000ffff, 0x00af9a00); // code0 write_raw_gdt_entry(GDT_SELECTOR_CODE3, 0x0000ffff, 0x00affa00); // code3 + write_raw_gdt_entry(GDT_SELECTOR_DATA3, 0x0000ffff, 0x008ff200); // data3 #endif #if ARCH(I386) diff --git a/Kernel/Arch/x86/x86_64/Processor.cpp b/Kernel/Arch/x86/x86_64/Processor.cpp index 104202cb95..00fd7a25eb 100644 --- a/Kernel/Arch/x86/x86_64/Processor.cpp +++ b/Kernel/Arch/x86/x86_64/Processor.cpp @@ -115,8 +115,13 @@ u32 Processor::init_context(Thread& thread, bool leave_crit) iretframe.rflags = regs.rflags; iretframe.rip = regs.rip; iretframe.cs = regs.cs; - iretframe.userspace_rsp = kernel_stack_top; - iretframe.userspace_ss = 0; + if (return_to_user) { + iretframe.userspace_rsp = regs.rsp; + iretframe.userspace_ss = GDT_SELECTOR_DATA3 | 3; + } else { + iretframe.userspace_rsp = kernel_stack_top; + iretframe.userspace_ss = 0; + } // make space for a trap frame stack_top -= sizeof(TrapFrame); diff --git a/Kernel/VM/PageDirectory.cpp b/Kernel/VM/PageDirectory.cpp index e4b8cd5d45..5bc2da0f6d 100644 --- a/Kernel/VM/PageDirectory.cpp +++ b/Kernel/VM/PageDirectory.cpp @@ -95,7 +95,7 @@ PageDirectory::PageDirectory(const RangeAllocator* parent_range_allocator) #if ARCH(X86_64) { auto& table = *(PageDirectoryPointerTable*)MM.quickmap_page(*m_pml4t); - table.raw[0] = (FlatPtr)m_directory_table->paddr().as_ptr() | 3; + table.raw[0] = (FlatPtr)m_directory_table->paddr().as_ptr() | 7; MM.unquickmap_page(); } #endif @@ -108,10 +108,10 @@ PageDirectory::PageDirectory(const RangeAllocator* parent_range_allocator) table.raw[2] = (FlatPtr)m_directory_pages[2]->paddr().as_ptr() | 1; table.raw[3] = (FlatPtr)m_directory_pages[3]->paddr().as_ptr() | 1; #else - table.raw[0] = (FlatPtr)m_directory_pages[0]->paddr().as_ptr() | 3; - table.raw[1] = (FlatPtr)m_directory_pages[1]->paddr().as_ptr() | 3; - table.raw[2] = (FlatPtr)m_directory_pages[2]->paddr().as_ptr() | 3; - table.raw[3] = (FlatPtr)m_directory_pages[3]->paddr().as_ptr() | 3; + table.raw[0] = (FlatPtr)m_directory_pages[0]->paddr().as_ptr() | 7; + table.raw[1] = (FlatPtr)m_directory_pages[1]->paddr().as_ptr() | 7; + table.raw[2] = (FlatPtr)m_directory_pages[2]->paddr().as_ptr() | 7; + table.raw[3] = (FlatPtr)m_directory_pages[3]->paddr().as_ptr() | 7; #endif // 2 ** MAXPHYADDR - 1