diff options
Diffstat (limited to 'kernel/include/arch/x86_64/scheduling.hpp')
| -rw-r--r-- | kernel/include/arch/x86_64/scheduling.hpp | 460 |
1 files changed, 0 insertions, 460 deletions
diff --git a/kernel/include/arch/x86_64/scheduling.hpp b/kernel/include/arch/x86_64/scheduling.hpp deleted file mode 100644 index 90e0336..0000000 --- a/kernel/include/arch/x86_64/scheduling.hpp +++ /dev/null @@ -1,460 +0,0 @@ - -#include <cstdint> - -#pragma once - -#include <arch/x86_64/syscalls/signal.hpp> - -#include <arch/x86_64/interrupts/idt.hpp> -#include <generic/vfs/vfs.hpp> - -#include <etc/logging.hpp> - -#include <generic/locks/spinlock.hpp> - -#include <atomic> - -#define PROCESS_STATE_NONE 0 -#define PROCESS_STATE_KILLED 1 -#define PROCESS_STATE_RUNNING 2 -#define PROCESS_STATE_ZOMBIE 3 - -#define WNOHANG 1 /* Don't block waiting. */ -#define WUNTRACED 2 /* Report status of stopped children. */ - -#define MIN2(a, b) ((a) < (b) ? (a) : (b)) -#define MAX2(a, b) ((a) > (b) ? (a) : (b)) - -extern "C" void yield(); - -#define PREPARE_SIGNAL(proc) if(proc->sig->is_not_empty_sigset(&proc->current_sigset) && 1) -#define PROCESS_SIGNAL(proc) yield(); - -typedef struct { - unsigned char e_ident[16]; - uint16_t e_type; - uint16_t e_machine; - uint32_t e_version; - uint64_t e_entry; - uint64_t e_phoff; - uint64_t e_shoff; - uint32_t e_flags; - uint16_t e_ehsize; - uint16_t e_phentsize; - uint16_t e_phnum; - uint16_t e_shentsize; - uint16_t e_shnum; - uint16_t e_shstrndx; -} __attribute__((packed)) elfheader_t; - -typedef struct { - uint32_t p_type; - uint32_t p_flags; - uint64_t p_offset; - uint64_t p_vaddr; - uint64_t p_paddr; - uint64_t p_filesz; - uint64_t p_memsz; - uint64_t p_align; -} __attribute__((packed)) elfprogramheader_t; - -typedef struct { - std::uint64_t interp_entry; - std::uint64_t real_entry; - std::uint64_t phdr; - std::uint64_t phnum; - std::uint64_t phentsize; - int status; - std::uint64_t interp_base; - std::uint64_t base; -} elfloadresult_t; - -#define REG_R8 0 -#define REG_R9 1 -#define REG_R10 2 -#define REG_R11 3 -#define REG_R12 4 -#define REG_R13 5 -#define REG_R14 6 -#define REG_R15 7 -#define REG_RDI 8 -#define REG_RSI 9 -#define REG_RBP 10 -#define REG_RBX 11 -#define REG_RDX 12 -#define REG_RAX 13 -#define REG_RCX 14 -#define REG_RSP 15 -#define REG_RIP 16 -#define REG_EFL 17 -#define REG_CSGSFS 18 -#define REG_ERR 19 -#define REG_TRAPNO 20 -#define REG_OLDMASK 21 -#define REG_CR2 22 - -inline void mcontext_to_int_frame(mcontext_t* out, int_frame_t* src) { - src->r8 = out->gregs[REG_R8]; - src->r9 = out->gregs[REG_R9]; - src->r10 = out->gregs[REG_R10]; - src->r11 = out->gregs[REG_R11]; - src->r12 = out->gregs[REG_R12]; - src->r13 = out->gregs[REG_R13]; - src->r14 = out->gregs[REG_R14]; - src->r15 = out->gregs[REG_R15]; - src->rdi = out->gregs[REG_RDI]; - src->rsi = out->gregs[REG_RSI]; - src->rbp = out->gregs[REG_RBP]; - src->rbx = out->gregs[REG_RBX]; - src->rdx = out->gregs[REG_RDX]; - src->rax = out->gregs[REG_RAX]; - src->rcx = out->gregs[REG_RCX]; - src->rsp = out->gregs[REG_RSP]; - src->rip = out->gregs[REG_RIP]; - src->rflags = out->gregs[REG_EFL]; - src->cs = out->gregs[REG_CSGSFS]; // todo: implement SMEP - src->ss = out->gregs[REG_ERR]; // why not - if(src->cs > 0x30) { - Log::SerialDisplay(LEVEL_MESSAGE_FAIL,"broken src->cs for mcontext to int frame"); - asm volatile("hlt"); - } -} - -inline void int_frame_to_mcontext(int_frame_t* src, mcontext_t* out) { - out->gregs[REG_R8] = src->r8; - out->gregs[REG_R9] = src->r9; - out->gregs[REG_R10] = src->r10; - out->gregs[REG_R11] = src->r11; - out->gregs[REG_R12] = src->r12; - out->gregs[REG_R13] = src->r13; - out->gregs[REG_R14] = src->r14; - out->gregs[REG_R15] = src->r15; - out->gregs[REG_RDI] = src->rdi; - out->gregs[REG_RSI] = src->rsi; - out->gregs[REG_RBP] = src->rbp; - out->gregs[REG_RBX] = src->rbx; - out->gregs[REG_RDX] = src->rdx; - out->gregs[REG_RAX] = src->rax; - out->gregs[REG_RCX] = src->rcx; - out->gregs[REG_RSP] = src->rsp; - out->gregs[REG_RIP] = src->rip; - out->gregs[REG_EFL] = src->rflags; - out->gregs[REG_CSGSFS] = src->cs; - out->gregs[REG_ERR] = src->ss; - if(!src->cs > 0x30) { - Log::SerialDisplay(LEVEL_MESSAGE_FAIL,"broken src->cs for int frame to mcontext"); - asm volatile("hlt"); - } - - /* Other registers must be untouched (not implemented) */ -} - -enum ELF_Type { - PT_NULL, - PT_LOAD, - PT_DYNAMIC, - PT_INTERP, - PT_NOTE, - PT_SHLIB, - PT_PHDR, - PT_LOPROC=0x70000000, //reserved - PT_HIPROC=0x7FFFFFFF //reserved -}; - -typedef enum { - ET_NONE = 0, - ET_REL = 1, - ET_EXEC = 2, - ET_DYN = 3, - ET_CORE = 4, - ET_LOPROC = 0xff00, - ET_HIPROC = 0xffff -} obj_type_t; - -typedef enum { - AT_NULL = 0, - AT_IGNORE = 1, - AT_EXECFD = 2, - AT_PHDR = 3, - AT_PHENT = 4, - AT_PHNUM = 5, - AT_PAGESZ = 6, - AT_BASE = 7, - AT_FLAGS = 8, - AT_ENTRY = 9, - AT_NOTELF = 10, - AT_UID = 11, - AT_EUID = 12, - AT_GID = 13, - AT_EGID = 14, - AT_PLATFORM = 15, - AT_HWCAP = 16, - AT_CLKTCK = 17, - AT_SECURE = 23, - AT_BASE_PLATFORM = 24, - AT_RANDOM = 25, - AT_HWCAP2 = 26, - AT_RSEQ_FEATURE_SIZE = 27, - AT_RSEQ_ALIGN = 28, - AT_HWCAP3 = 29, - AT_HWCAP4 = 30, - AT_EXECFN = 31 -} auxv_t; - -extern "C" void schedulingScheduleAndChangeStack(std::uint64_t stack, int_frame_t* ctx); -extern "C" void schedulingSchedule(int_frame_t* ctx); -extern "C" void schedulingEnter(); -extern "C" void schedulingEnd(int_frame_t* ctx); - -typedef struct { - int64_t d_tag; - union { - uint64_t d_val; - uint64_t d_ptr; - } d_un; -} Elf64_Dyn; - -#define DT_NULL 0 -#define DT_NEEDED 1 -#define DT_STRTAB 5 -#define DT_SYMTAB 6 -#define DT_STRSZ 10 - -typedef uint64_t u64; - -# define CSIGNAL 0x000000ff /* Signal mask to be sent at exit. */ -# define CLONE_VM 0x00000100 /* Set if VM shared between processes. */ -# define CLONE_FS 0x00000200 /* Set if fs info shared between processes. */ -# define CLONE_FILES 0x00000400 /* Set if open files shared between processes. */ -# define CLONE_SIGHAND 0x00000800 /* Set if signal handlers shared. */ -# define CLONE_PIDFD 0x00001000 /* Set if a pidfd should be placed - in parent. */ -# define CLONE_PTRACE 0x00002000 /* Set if tracing continues on the child. */ -# define CLONE_VFORK 0x00004000 /* Set if the parent wants the child to - wake it up on mm_release. */ -# define CLONE_PARENT 0x00008000 /* Set if we want to have the same - parent as the cloner. */ -# define CLONE_THREAD 0x00010000 /* Set to add to same thread group. */ -# define CLONE_NEWNS 0x00020000 /* Set to create new namespace. */ -# define CLONE_SYSVSEM 0x00040000 /* Set to shared SVID SEM_UNDO semantics. */ -# define CLONE_SETTLS 0x00080000 /* Set TLS info. */ -# define CLONE_PARENT_SETTID 0x00100000 /* Store TID in userlevel buffer - before MM copy. */ -# define CLONE_CHILD_CLEARTID 0x00200000 /* Register exit futex and memory - location to clear. */ -# define CLONE_DETACHED 0x00400000 /* Create clone detached. */ -# define CLONE_UNTRACED 0x00800000 /* Set if the tracing process can't - force CLONE_PTRACE on this clone. */ -# define CLONE_CHILD_SETTID 0x01000000 /* Store TID in userlevel buffer in - the child. */ -# define CLONE_NEWCGROUP 0x02000000 /* New cgroup namespace. */ -# define CLONE_NEWUTS 0x04000000 /* New utsname group. */ -# define CLONE_NEWIPC 0x08000000 /* New ipcs. */ -# define CLONE_NEWUSER 0x10000000 /* New user namespace. */ -# define CLONE_NEWPID 0x20000000 /* New pid namespace. */ -# define CLONE_NEWNET 0x40000000 /* New network namespace. */ -# define CLONE_IO 0x80000000 /* Clone I/O context. */ - -struct clone_args { - u64 flags; /* Flags bit mask */ - u64 pidfd; /* Where to store PID file descriptor - (int *) */ - u64 child_tid; /* Where to store child TID, - in child's memory (pid_t *) */ - u64 parent_tid; /* Where to store child TID, - in parent's memory (pid_t *) */ - u64 exit_signal; /* Signal to deliver to parent on - child termination */ - u64 stack; /* Pointer to lowest byte of stack */ - u64 stack_size; /* Size of stack */ - u64 tls; /* Location of new TLS */ - u64 set_tid; /* Pointer to a pid_t array - (since Linux 5.5) */ - u64 set_tid_size; /* Number of elements in set_tid - (since Linux 5.5) */ - u64 cgroup; /* File descriptor for target cgroup - of child (since Linux 5.7) */ -}; - -struct stimeval { - long long tv_sec; /* seconds */ - long long tv_usec; /* microseconds */ -}; - - -struct itimerval { - struct stimeval it_interval; /* следующее значение */ - struct stimeval it_value; /* текущее значение */ -}; - -#define ITIMER_REAL 0 -#define ITIMER_VIRTUAL 1 -#define ITIMER_PROF 2 - -namespace arch { - namespace x86_64 { - - struct sigset_list { - int sig; - sigset_t sigset; - sigset_list* next; - }; - - typedef struct process { - std::uint32_t id; - std::uint8_t status; - std::uint8_t waitpid_state; - - std::uint64_t original_cr3; - int_frame_t ctx; - int_frame_t sig_ctx; - - int_frame_t* sys_ctx; - - std::atomic<int> target_cpu; - - std::uint64_t fs_base; - - locks::spinlock lock; - locks::spinlock kill_lock; /* Never should be setup by not kill() function */ - - locks::spinlock _3rd_kill_lock; - locks::spinlock futex_lock; - - locks::spinlock fd_lock; - - itimerval itimer; - std::int64_t next_alarm; - - itimerval vitimer; - std::int64_t virt_timer; - - itimerval proftimer; - std::int64_t prof_timer; - - sigset_t current_sigset; - sigset_t temp_sigset; - int is_restore_sigset; - - void* sig_handlers[36]; - void* ret_handlers[36]; - int sig_flags[36]; - - std::atomic<int> is_execd; - - sigset_t sigsets[36]; - stack_t altstack; - - std::uint8_t is_sig_real; - std::uint32_t alloc_fd; - std::uint32_t* fd_ptr; - - std::uint64_t old_stack; - - int is_shared_fd; - - std::uint32_t reversedforid; - std::uint32_t* vmm_id; - - userspace_fd_t* fd_pool; - vfs::passingfd_manager* pass_fd; - signalmanager* sig; - - sigtrace* sigtrace_obj; - - int is_cloexec; - - void* fd; - - char* vmm_start; - char* vmm_end; - - char* sse_ctx; - char* cwd; - char* name; - - int sys; - - int prio; - - std::uint64_t ts; - - int exit_code; - int is_cloned; - std::uint64_t* original_cr3_pointer; - - std::uint64_t time_start; - - std::uint64_t futex; - std::uint64_t syscall_stack; - std::uint64_t user_stack; - - std::uint64_t create_timestamp; - std::uint64_t exit_timestamp; - - std::uint64_t thread_group; // just parent pid - - std::uint32_t parent_id; - std::uint32_t exit_signal; - - int* tidptr; - int uid; - - int debug0; - int debug1; - - int is_debug; - - int sex_abort; - - struct process* next; - - } process_t; - - inline void update_time(itimerval* itimer, std::int64_t* output, int is_tsc) { - if(itimer->it_value.tv_sec != 0 || itimer->it_value.tv_usec != 0) { - *output = (itimer->it_value.tv_usec) + (itimer->it_value.tv_sec * (1000*1000)) + (is_tsc ? drivers::tsc::currentus() : 0); - } else if(itimer->it_interval.tv_sec != 0 || itimer->it_interval.tv_usec != 0) { - *output = (itimer->it_interval.tv_usec) + (itimer->it_interval.tv_sec * (1000*1000)) + (is_tsc ? drivers::tsc::currentus() : 0); - } - } - - inline sigset_t* get_sigset_from_list(process_t* proc, int sig) { - - return 0; - } - - inline void free_sigset_from_list(process_t* proc) { - return; - } - -static_assert(sizeof(process_t) < 4096,"process_t is bigger than page size"); - - typedef struct process_queue_run_list { - struct process_queue_run_list* next; - process_t* proc; - char is_used; - } process_queue_run_list_t; - - class scheduling { - public: - static void init(); - static process_t* create(); - static process_t* fork(process_t* proc,int_frame_t* ctx); - static process_t* clone(process_t* proc,int_frame_t* ctx); - static process_t* clone3(process_t* proc, clone_args* clarg, int_frame_t* ctx); - static process_t* by_pid(int pid); - static void create_kernel_thread(void (*func)(void*),void* arg); - static void kill(process_t* proc); - static void wakeup(process_t* proc); - static int futexwake(process_t* proc, int* lock, int num_to_wake); - static void futexwait(process_t* proc, int* lock, int val, int* original_lock, std::uint64_t ts); - static int loadelf(process_t* proc,char* path,char** argv,char** envp,int free_mem); - static process_t* head_proc_(); - - static void sigreturn(process_t* proc); - - }; - } -} - |
