]> git.ameliathe1st.gay Git - voyage-au-centre-des-fichiers.git/commitdiff
Changed processes to save all (general-purpose) registers on syscalls (except for...
authorAmelia Coutard <eliottulio.coutard@gmail.com>
Tue, 1 Aug 2023 04:00:06 +0000 (06:00 +0200)
committerAmelia Coutard <eliottulio.coutard@gmail.com>
Tue, 1 Aug 2023 04:00:06 +0000 (06:00 +0200)
doc.txt
kernel/src/elf64.cpp
kernel/src/kernel.cpp
kernel/src/ring3.S
kernel/src/ring3.cpp
kernel/src/ring3.hpp

diff --git a/doc.txt b/doc.txt
index 75829d0af5b105abe5b911c62c3b390ef146c051..307d7f890b40728c8a95db576931d76768eb17fb 100644 (file)
--- a/doc.txt
+++ b/doc.txt
@@ -12,8 +12,8 @@ isos documentation:
 0000'7FFF'FFFF'0000 ↔ 0000'8000'0000'0000 - stack: 64KiB
 -- Invalid addresses --
 FFFF'8000'0000'0000 ↔ FFFF'C000'0000'0000 - physical memory: 64TiB
-FFFF'C000'0000'0000 ↔ FFFF'C000'1000'0000 - process information table: 256MiB, 2048 processes, 4093 ports/process
-FFFF'C000'1000'0000 ↔ FFFF'FFFF'8000'0000 - unmapped: 64TiB - 2GiB - 128MiB - 64KiB
+FFFF'C000'0000'0000 ↔ ____'____'____'____ - process information table: 2048 processes, 4093 ports/process
+____'____'____'____ ↔ FFFF'FFFF'8000'0000 - unmapped
 FFFF'FFFF'8000'0000 ↔10000'0000'0000'0000 - kernel: 2GiB
 
 ---------------------------
index acc4244d5569ae0a14207987482e89ac3084fb88..c129d075677a1cca90b512fb7494ea5090d23f57 100644 (file)
@@ -33,7 +33,6 @@ void os::elf::load_elf(os::process& result, std::byte* start, std::size_t length
        constexpr std::size_t stack_size = 16 * 0x1000 /* 64KiB */;
        std::byte* const stack = (std::byte*)0x0000'8000'0000'0000 - stack_size;
 
-       result.exists = true;
        result.PML4T = phys_ptr<paging::PML4T>(os::paging::page_allocator.allocate(1).ptr.get_phys_addr());
        result.rip = std::uint64_t(elf_header.entry);
        result.rsp = std::uint64_t(stack + stack_size);
@@ -43,8 +42,6 @@ void os::elf::load_elf(os::process& result, std::byte* start, std::size_t length
        result.r13 = 0;
        result.r14 = 0;
        result.r15 = 0;
-       result.mxcsr = 0;
-       result.x87cw = 0;
 
        // Copy kernel mappings to the new virtual address space.
        memset(result.PML4T->contents, 0, 256 * sizeof(os::paging::PML4E));
index 1fd5a1ca12c793245830d928f4ef2505d23224cf..2035138eeb41ccb04db731557a57725514833997 100644 (file)
@@ -59,6 +59,7 @@ extern "C" void kmain(unsigned long magic, os::phys_ptr<const multiboot2::info_s
 
                os::paging::setup_page(PML4T, (void*)0xFFFF'C000'0000'0000, 1, 0); // The startup module.
 
+               bool module_specified = false;
                for (auto it = multiboot2::next(info); it->type != multiboot2::info::type_t::end; it = multiboot2::next(it)) {
                        switch (it->type) {
                        case multiboot2::info::type_t::memory_map:
@@ -79,7 +80,8 @@ extern "C" void kmain(unsigned long magic, os::phys_ptr<const multiboot2::info_s
                                break;
                        case multiboot2::info::type_t::modules:
                                os::print("{}->{}: {}\n", multiboot2::modules_mod_start(it), multiboot2::modules_mod_end(it), multiboot2::modules_string(it));
-                               os::assert(!os::get_process(0).exists, "Multiple modules specified in the multiboot. This is unsupported.");
+                               os::assert(!module_specified, "Multiple modules specified in the multiboot. This is unsupported.");
+                               module_specified = true;
                                os::elf::load_elf(os::get_process(0),
                                                  (std::byte*)multiboot2::modules_mod_start(it),
                                                  multiboot2::modules_mod_end(it) - multiboot2::modules_mod_start(it),
@@ -89,7 +91,7 @@ extern "C" void kmain(unsigned long magic, os::phys_ptr<const multiboot2::info_s
                        }
                }
 
-               os::assert(os::get_process(0).exists, "No modules specified in the multiboot. This is unsupported.");
+               os::assert(module_specified, "No modules specified in the multiboot. This is unsupported.");
 
                // kernel_start and kernel_end are aligned to 4K by the linker script.
                const os::phys_ptr<os::paging::page> kernel_s = ([]() {
index dd2335451a4519ee7c6e8d7ff5e1760d695a637f..5551cff649ca06c6cff1aacc2b22a32c58c6f1a8 100644 (file)
@@ -37,45 +37,53 @@ load_tss:
 
 .globl syscall_64bit_handler
 syscall_64bit_handler:
-       mov %rax, rax_save
-       movq current_pid, %rax
-       shl $17, %rax # * 0x1000 * 32 (i.e. the size of a process)
-       addq process_struct_table, %rax
-       # %rax now contains the address of the current process struct.
-       movq %rcx, 0x10(%rax) # %rip
-       movq %rbx, 0x18(%rax)
-       movq %rsp, 0x20(%rax)
-       movq %rbp, 0x28(%rax)
-       movq %r12, 0x30(%rax)
-       movq %r13, 0x38(%rax)
-       movq %r14, 0x40(%rax)
-       movq %r15, 0x48(%rax)
-       fstcw 0x58(%rax)
-       # Current process registers have now all been saved.
-       mov rax_save, %rax
-
-       mov %r10, %rcx
+       # Save all registers:
+       .irp reg,rax,rbx,rcx,rdx,rsp,rbp,rsi,rdi,r8,r9,r10,r11,r12,r13,r14,r15
+               mov %\reg, save_reg_tmp_\reg
+       .endr
+       # Setup stack:
+       mov $stack_top, %rsp
+       # Get process data location:
+       mov current_pid, %rdi
+       call get_process
+       # Really save all regs:
+       .irp reg,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15
+               mov save_regs_tmp + \reg * 8, %rbx # Get %r\reg
+               mov %rbx, 8 + \reg * 8(%rax) # And store it.
+       .endr
+       mov save_reg_tmp_rcx, %rbx # Save the rip also.
+       mov %rbx, 0x88(%rax)
+       # Get ready for syscall:
+       mov save_reg_tmp_rdi, %rdi
+       mov save_reg_tmp_rsi, %rsi
+       mov save_reg_tmp_rdx, %rdx
+       mov save_reg_tmp_r10, %rcx # Syscall ABI -> C ABI
+       mov save_reg_tmp_r8, %r8
+       mov save_reg_tmp_r9, %r9
+       mov save_reg_tmp_rax, %rax
        cmp $syscall_n, %rax
-       mov $stack_top, %rsp # Setup stack
        jae incorrect_syscall
        callq *syscalls_call_table(, %rax, 8)
 syscall_end:
-       mov %rax, rax_save
-       movq current_pid, %rax
-       shl $17, %rax # * 0x1000 * 32 (i.e. the size of a process)
-       addq process_struct_table, %rax
-       # %rax now contains the address of the current process struct.
-       movq 0x10(%rax), %rcx # %rip
-       movq 0x18(%rax), %rbx
-       movq 0x20(%rax), %rsp
-       movq 0x28(%rax), %rbp
-       movq 0x30(%rax), %r12
-       movq 0x38(%rax), %r13
-       movq 0x40(%rax), %r14
-       movq 0x48(%rax), %r15
-       fldcw 0x58(%rax)
-       # Current process registers have now all been loaded.
-       mov rax_save, %rax
+       mov %rax, %rbp # Save the return
+       mov %rdx, %rbx # registers.
+       # Get process data location:
+       mov current_pid, %rdi
+       call get_process
+       # Restore all regs:
+       .irp reg,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15
+               mov 8 + \reg * 8(%rax), %rbx # Get %r\reg
+               mov %rbx, save_regs_tmp + \reg * 8 # And restore it.
+       .endr
+       mov %rbp, save_reg_tmp_rax # Restore the return
+       mov %rbx, save_reg_tmp_rdx # registers as well.
+       mov 0x88(%rax), %rbx # Save the rip in place of rcx, because this is sysret.
+       mov %rbx, save_reg_tmp_rcx
+       # Really restore all regs:
+       .irp reg,rax,rbx,rcx,rdx,rsp,rbp,rsi,rdi,r8,r9,r10,r11,r12,r13,r14,r15
+               mov save_reg_tmp_\reg, %\reg
+       .endr
+       # Current process registers have now all been restored.
        sysretq
 incorrect_syscall:
        call syscall_rax_error_handler
@@ -90,4 +98,20 @@ syscalls_call_table:
 process_struct_table: .quad 0xFFFFC00000000000
 
 .section .data
-rax_save: .quad 1
+save_regs_tmp:
+save_reg_tmp_rax: .quad 1
+save_reg_tmp_rbx: .quad 1
+save_reg_tmp_rcx: .quad 1
+save_reg_tmp_rdx: .quad 1
+save_reg_tmp_rsp: .quad 1
+save_reg_tmp_rbp: .quad 1
+save_reg_tmp_rsi: .quad 1
+save_reg_tmp_rdi: .quad 1
+save_reg_tmp_r8: .quad 1
+save_reg_tmp_r9: .quad 1
+save_reg_tmp_r10: .quad 1
+save_reg_tmp_r11: .quad 1
+save_reg_tmp_r12: .quad 1
+save_reg_tmp_r13: .quad 1
+save_reg_tmp_r14: .quad 1
+save_reg_tmp_r15: .quad 1
index 847cbaff2ed5616f348b6c9ba65ba8972853db16..c8b840086d0a2cb4fc31520a14d6834d070bf397 100644 (file)
@@ -69,4 +69,8 @@ extern "C" void os::syscall_rax_error_handler() {
        os::assert(false, "Incorrect %rax for syscall.");
 }
 
+os::process& os::get_process(std::uint64_t pid) {
+       os::assert(pid < 2048, "Invalid pid: {}.\n", pid);
+       return ((process*)0xFFFF'C000'0000'0000)[pid];
+}
 std::uint64_t os::current_pid;
index 7d26636eb441d2ad7c9da03830ea4c8b864a111a..49069bfff03326c3bb19086ce3179165e5c869eb 100644 (file)
@@ -61,31 +61,37 @@ struct port {
 };
 
 struct process {
-       bool exists;
        phys_ptr<paging::PML4T> PML4T;
-       std::uint64_t rip;
+       std::uint64_t rax;
        std::uint64_t rbx;
+       std::uint64_t rcx;
+       std::uint64_t rdx;
        std::uint64_t rsp;
        std::uint64_t rbp;
+       std::uint64_t rsi;
+       std::uint64_t rdi;
+       std::uint64_t r8;
+       std::uint64_t r9;
+       std::uint64_t r10;
+       std::uint64_t r11;
        std::uint64_t r12;
        std::uint64_t r13;
        std::uint64_t r14;
        std::uint64_t r15;
-       std::uint64_t mxcsr; // UNUSED for now.
-       std::uint64_t x87cw;
-       port ports[4093];
+       std::uint64_t rip;
+       port ports[2043];
+       char padding[16];
 };
-static_assert(sizeof(process) == 0x1000 * 32);
+static_assert(sizeof(process) == 4096 * 16);
+static_assert(0xFFFF'C000'0000'0000 + sizeof(process) * 2048 < 0xFFFF'FFFF'8000'0000);
+
+extern "C" process& get_process(std::uint64_t pid);
 
-inline process& get_process(std::uint64_t pid) {
-       os::assert(pid < 2048, "Invalid pid: {}.\n", pid);
-       return ((process*)0xFFFF'C000'0000'0000)[pid];
-}
 inline bool process_exists(std::uint64_t pid) {
-       return pid < 2048 && get_process(pid).exists;
+       return pid < 2048;
 }
 inline bool port_exists(std::uint64_t pid, std::uint64_t port) {
-       return port < 4093 && process_exists(pid) && get_process(pid).ports[port].exists;
+       return port < 2043 && process_exists(pid) && get_process(pid).ports[port].exists;
 }
 
 extern "C" std::uint64_t current_pid;