mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2024-09-20 09:49:15 +03:00
Kernel: Fix GDT and segment selectors to make userland work on x86_64
Userland faulted on the very first instruction before because the PML4T/PDPT/etc. weren't marked as user-accessible. For some reason x86 doesn't care about that. Also, we need to provide an appropriate userspace stack segment selector to iretq.
This commit is contained in:
parent
04fc7d708c
commit
b5aad1c81d
Notes:
sideshowbarker
2024-07-18 11:23:01 +09:00
Author: https://github.com/gunnarbeutner Commit: https://github.com/SerenityOS/serenity/commit/b5aad1c81d1 Pull-request: https://github.com/SerenityOS/serenity/pull/8301
@ -28,8 +28,9 @@ static_assert(GDT_SELECTOR_CODE0 + 24 == GDT_SELECTOR_DATA3); // SS3 = CS0 + 32
|
|||||||
#else
|
#else
|
||||||
# define GDT_SELECTOR_CODE0 0x08
|
# define GDT_SELECTOR_CODE0 0x08
|
||||||
# define GDT_SELECTOR_CODE3 0x10
|
# define GDT_SELECTOR_CODE3 0x10
|
||||||
# define GDT_SELECTOR_TSS 0x18
|
# define GDT_SELECTOR_DATA3 0x18
|
||||||
# define GDT_SELECTOR_TSS_PART2 0x20
|
# define GDT_SELECTOR_TSS 0x20
|
||||||
|
# define GDT_SELECTOR_TSS_PART2 0x28
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
namespace Kernel {
|
namespace Kernel {
|
||||||
|
@ -1070,6 +1070,7 @@ UNMAP_AFTER_INIT void Processor::gdt_init()
|
|||||||
#else
|
#else
|
||||||
write_raw_gdt_entry(GDT_SELECTOR_CODE0, 0x0000ffff, 0x00af9a00); // code0
|
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_CODE3, 0x0000ffff, 0x00affa00); // code3
|
||||||
|
write_raw_gdt_entry(GDT_SELECTOR_DATA3, 0x0000ffff, 0x008ff200); // data3
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if ARCH(I386)
|
#if ARCH(I386)
|
||||||
|
@ -115,8 +115,13 @@ u32 Processor::init_context(Thread& thread, bool leave_crit)
|
|||||||
iretframe.rflags = regs.rflags;
|
iretframe.rflags = regs.rflags;
|
||||||
iretframe.rip = regs.rip;
|
iretframe.rip = regs.rip;
|
||||||
iretframe.cs = regs.cs;
|
iretframe.cs = regs.cs;
|
||||||
|
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_rsp = kernel_stack_top;
|
||||||
iretframe.userspace_ss = 0;
|
iretframe.userspace_ss = 0;
|
||||||
|
}
|
||||||
|
|
||||||
// make space for a trap frame
|
// make space for a trap frame
|
||||||
stack_top -= sizeof(TrapFrame);
|
stack_top -= sizeof(TrapFrame);
|
||||||
|
@ -95,7 +95,7 @@ PageDirectory::PageDirectory(const RangeAllocator* parent_range_allocator)
|
|||||||
#if ARCH(X86_64)
|
#if ARCH(X86_64)
|
||||||
{
|
{
|
||||||
auto& table = *(PageDirectoryPointerTable*)MM.quickmap_page(*m_pml4t);
|
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();
|
MM.unquickmap_page();
|
||||||
}
|
}
|
||||||
#endif
|
#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[2] = (FlatPtr)m_directory_pages[2]->paddr().as_ptr() | 1;
|
||||||
table.raw[3] = (FlatPtr)m_directory_pages[3]->paddr().as_ptr() | 1;
|
table.raw[3] = (FlatPtr)m_directory_pages[3]->paddr().as_ptr() | 1;
|
||||||
#else
|
#else
|
||||||
table.raw[0] = (FlatPtr)m_directory_pages[0]->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() | 3;
|
table.raw[1] = (FlatPtr)m_directory_pages[1]->paddr().as_ptr() | 7;
|
||||||
table.raw[2] = (FlatPtr)m_directory_pages[2]->paddr().as_ptr() | 3;
|
table.raw[2] = (FlatPtr)m_directory_pages[2]->paddr().as_ptr() | 7;
|
||||||
table.raw[3] = (FlatPtr)m_directory_pages[3]->paddr().as_ptr() | 3;
|
table.raw[3] = (FlatPtr)m_directory_pages[3]->paddr().as_ptr() | 7;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// 2 ** MAXPHYADDR - 1
|
// 2 ** MAXPHYADDR - 1
|
||||||
|
Loading…
Reference in New Issue
Block a user