diff options
Diffstat (limited to 'kern/inc/pv.h')
| -rw-r--r-- | kern/inc/pv.h | 76 |
1 files changed, 73 insertions, 3 deletions
diff --git a/kern/inc/pv.h b/kern/inc/pv.h index 7cd8c50..550446c 100644 --- a/kern/inc/pv.h +++ b/kern/inc/pv.h @@ -1,8 +1,12 @@ #ifndef _PV_H_ #define _PV_H_ +#include <stdlib.h> + #include <common_kern.h> #include <elf/elf_410.h> +#include <ureg.h> +#include <x86/eflags.h> #include <x86/idt.h> #include <x86/seg.h> @@ -19,7 +23,7 @@ #define SEGSEL_PV_FS (SEGSEL_SPARE3 | SEGSEL_RPL3) #define SEGSEL_PV_FS_IDX SEGSEL_SPARE3_IDX -#define PV_VM_LIMIT (~(USER_MEM_START - 1)) +#define PV_VM_LIMIT (va_t)(~(USER_MEM_START - 1)) #define PV_DEFAULT_SIZE 24 #define PV_MINIMUM_SIZE 20 @@ -27,18 +31,40 @@ typedef struct pv_pd_s { int refcount; queue_t pv_link; + pa_t guest_pd; + int wp; pa_t cr3; pa_t user_cr3; } pv_pd_t; +#define VIDT_DPL_0 0 +#define VIDT_DPL_3 3 +#define VIDT_DPL_MASK 3 + typedef struct pv_idt_entry_s { va_t eip; - int dpl; + int desc; } pv_idt_entry_t; -typedef pv_idt_entry_t pv_idt_t[IDT_ENTS]; +#define PV_FAULT_START 0 +#define PV_FAULT_END 20 +#define PV_IRQ_START 32 +#define PV_IRQ_END 34 +#define PV_SYSCALL_1_START 65 +#define PV_SYSCALL_1_END 117 +#define PV_SYSCALL_2_START 128 +#define PV_SYSCALL_2_END 135 + +typedef struct pv_idt_s { + pv_idt_entry_t fault[PV_FAULT_END - PV_FAULT_START]; + pv_idt_entry_t irq[PV_IRQ_END - PV_IRQ_START]; + pv_idt_entry_t syscall_1[PV_SYSCALL_1_END - PV_SYSCALL_1_START]; + pv_idt_entry_t syscall_2[PV_SYSCALL_2_END - PV_SYSCALL_2_START]; +} pv_idt_t; typedef struct pv_s { + int n_pages; + pa_t mem_base; int vif; pv_pd_t* active_shadow_pd; queue_t* shadow_pds; @@ -58,6 +84,50 @@ thread_t* create_pv_process(thread_t* t, char* exe, va_size_t mem_size); +static inline void pv_mask_interrupt(pv_t* pv) { + pv->vif = 0; +} + +static inline void pv_unmask_interrupt(pv_t* pv) { + pv->vif = EFL_IF; +} + +static inline pv_idt_entry_t* pv_classify_interrupt(pv_t* pv, int index) { + if (index >= PV_FAULT_START && index < PV_FAULT_END) { + return &pv->vidt.fault[index - PV_FAULT_START]; + } + if (index >= PV_IRQ_START && index < PV_IRQ_END) { + return &pv->vidt.irq[index - PV_IRQ_START]; + } + if (index >= PV_SYSCALL_1_START && index < PV_SYSCALL_1_END) { + return &pv->vidt.syscall_1[index - PV_SYSCALL_1_START]; + } + if (index >= PV_SYSCALL_2_START && index < PV_SYSCALL_2_END) { + return &pv->vidt.syscall_2[index - PV_SYSCALL_2_START]; + } + return NULL; +} + void destroy_pv(pv_t* pv); +void pv_die(char* reason); + +void pv_switch_mode(process_t* p, int kernelmode); + +void select_pv_pd(process_t* p, pv_pd_t* pv_pd); + +void pv_handle_fault(ureg_t* frame, thread_t* t); + +struct stack_frame_s; +typedef struct stack_frame_s stack_frame_t; +int pv_inject_interrupt(stack_frame_t* f, int index, int arg); + +typedef struct pv_frame_s { + reg_t cr2; + reg_t error_code; + reg_t eip; + reg_t vcs; + reg_t eflags; +} pv_frame_t; + #endif |
