kernel: Separate a thread's page directory into two
All checks were successful
continuous-integration/drone/pr Build is passing
All checks were successful
continuous-integration/drone/pr Build is passing
The self directory, and the active directory. The active directory is the one the thread is currently using, and the self directory is the one the thread owns. This lets us keep track of both, which fixes ext2 executables crashing the system.
This commit is contained in:
parent
868213bb85
commit
8fc58c70f7
@ -146,7 +146,7 @@ namespace ATA
|
||||
{
|
||||
if (drive == m_current_drive) return;
|
||||
|
||||
u8 value = (drive << 4) | 0xa0;
|
||||
u8 value = (u8)(drive << 4) | 0xa0;
|
||||
write_register(Register::DriveSelect, value);
|
||||
|
||||
delay_400ns();
|
||||
|
@ -70,7 +70,7 @@ Result<u64> sys_execve(Registers* regs, SyscallArgs args)
|
||||
kdbgln("exec: attempting to replace current image with %s", path.chars());
|
||||
#endif
|
||||
|
||||
auto guard = make_scope_guard([current] { MMU::switch_page_directory(current->directory); });
|
||||
auto guard = make_scope_guard([current] { MMU::switch_page_directory(current->self_directory); });
|
||||
|
||||
auto image = TRY(ThreadImage::try_load_from_elf(inode));
|
||||
|
||||
@ -99,7 +99,7 @@ Result<u64> sys_execve(Registers* regs, SyscallArgs args)
|
||||
}
|
||||
}
|
||||
|
||||
MMU::delete_userspace_page_directory(current->directory);
|
||||
MMU::delete_userspace_page_directory(current->self_directory);
|
||||
|
||||
if (VFS::is_setuid(inode)) current->auth.euid = current->auth.suid = inode->uid();
|
||||
if (VFS::is_setgid(inode)) current->auth.egid = current->auth.sgid = inode->gid();
|
||||
@ -108,7 +108,7 @@ Result<u64> sys_execve(Registers* regs, SyscallArgs args)
|
||||
|
||||
image->apply(current);
|
||||
|
||||
MMU::switch_page_directory(current->directory);
|
||||
MMU::switch_page_directory(current->self_directory);
|
||||
|
||||
current->set_arguments(user_argc, user_argv, user_envc, user_envp);
|
||||
|
||||
@ -123,7 +123,7 @@ Result<u64> sys_fork(Registers* regs, SyscallArgs)
|
||||
{
|
||||
auto current = Scheduler::current();
|
||||
|
||||
auto guard = make_scope_guard([current] { MMU::switch_page_directory(current->directory); });
|
||||
auto guard = make_scope_guard([current] { MMU::switch_page_directory(current->self_directory); });
|
||||
|
||||
memcpy(¤t->regs, regs, sizeof(*regs));
|
||||
|
||||
|
@ -191,7 +191,7 @@ namespace Scheduler
|
||||
}
|
||||
}
|
||||
|
||||
if (!thread->is_kernel) MMU::delete_userspace_page_directory(thread->directory);
|
||||
if (!thread->is_kernel) MMU::delete_userspace_page_directory(thread->self_directory);
|
||||
|
||||
delete thread;
|
||||
|
||||
@ -236,8 +236,8 @@ namespace Scheduler
|
||||
switch_context(old_thread, new_thread, regs);
|
||||
if (!old_thread->is_kernel) old_thread->fp_data.save();
|
||||
if (MMU::get_page_directory() != MMU::kernel_page_directory())
|
||||
old_thread->directory = MMU::get_page_directory();
|
||||
if (new_thread->directory) MMU::switch_page_directory(new_thread->directory);
|
||||
old_thread->active_directory = MMU::get_page_directory();
|
||||
if (new_thread->active_directory) MMU::switch_page_directory(new_thread->active_directory);
|
||||
if (!new_thread->is_kernel)
|
||||
{
|
||||
CPU::switch_kernel_stack(new_thread->kernel_stack.top());
|
||||
|
@ -97,7 +97,8 @@ struct Thread : public LinkedListNode<Thread>
|
||||
Thread* parent { nullptr };
|
||||
Option<pid_t> child_being_waited_for = {};
|
||||
|
||||
PageDirectory* directory;
|
||||
PageDirectory* self_directory;
|
||||
PageDirectory* active_directory { nullptr };
|
||||
|
||||
[[noreturn]] void exit_and_signal_parent(u8 status);
|
||||
|
||||
|
@ -69,7 +69,7 @@ Result<OwnedPtr<ThreadImage>> ThreadImage::clone_from_thread(Thread* parent)
|
||||
|
||||
auto vm_allocator = TRY(parent->vm_allocator->clone());
|
||||
|
||||
auto new_directory = TRY(MMU::clone_userspace_page_directory(parent->directory));
|
||||
auto new_directory = TRY(MMU::clone_userspace_page_directory(parent->self_directory));
|
||||
|
||||
const ELFData data = { .entry = parent->ip() };
|
||||
|
||||
@ -124,7 +124,8 @@ void ThreadImage::apply(Thread* thread)
|
||||
thread->stack = m_user_stack;
|
||||
thread->set_sp(align_down<16>(m_sp));
|
||||
|
||||
thread->directory = m_directory;
|
||||
thread->self_directory = m_directory;
|
||||
thread->active_directory = m_directory;
|
||||
|
||||
thread->vm_allocator = move(m_vm_allocator);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user