diff options
| author | Hanjie Wu <hanjiew@andrew.cmu.edu> | 2023-04-23 04:12:07 -0400 |
|---|---|---|
| committer | Hanjie Wu <hanjiew@andrew.cmu.edu> | 2023-04-23 04:12:07 -0400 |
| commit | 981a10da84b0b33d7c169566b4faa9093dff6431 (patch) | |
| tree | 0de48dc7ef997fdbeea31a1e535002c2c443ba34 | |
| parent | f33b6e947b7d61b62e28983fcc54a08f15fca509 (diff) | |
fix
| -rw-r--r-- | kern/hvcall.c | 18 | ||||
| -rw-r--r-- | kern/inc/pv.h | 2 | ||||
| -rw-r--r-- | kern/pv.c | 14 | ||||
| -rw-r--r-- | kern/syscall_asm.S | 4 |
4 files changed, 23 insertions, 15 deletions
diff --git a/kern/hvcall.c b/kern/hvcall.c index 9e348bd..fb5eb95 100644 --- a/kern/hvcall.c +++ b/kern/hvcall.c @@ -53,7 +53,7 @@ static void hvcall_refpd(int ref); static void hvcall_loadpd(stack_frame_t* f); // 0: processed -int pv_handle_syscall(stack_frame_t* f, int index) { +int pv_handle_syscall(int index, stack_frame_t* f) { thread_t* t = get_current(); pv_t* pv = t->process->pv; if (pv == NULL) { @@ -70,7 +70,7 @@ int pv_handle_syscall(stack_frame_t* f, int index) { goto no_idt_handler; } } - do_inject_irq(t, pv, f, 0, idt->eip); + pv_inject_interrupt(t, pv, f, 0, idt->eip); return 0; } pv_die("Syscall is not allowed for PV kernels"); @@ -456,8 +456,9 @@ static void hvcall_adjustpg(stack_frame_t* f) { if (pt_pa == BAD_PA) { goto alloc_pt_fail; } - *pde = (pt_pa | new_pde); memset((void*)map_phys_page(pt_pa, NULL), 0, PAGE_SIZE); + map_phys_page(pv_pd->cr3, NULL); + *pde = (pt_pa | new_pde); } page_directory_t* user_pd = (page_directory_t*)map_phys_page(pv_pd->user_cr3, NULL); @@ -470,8 +471,9 @@ static void hvcall_adjustpg(stack_frame_t* f) { if (user_pt_pa == BAD_PA) { goto alloc_pt_fail; } - *user_pde = (user_pt_pa | new_pde); memset((void*)map_phys_page(user_pt_pa, NULL), 0, PAGE_SIZE); + map_phys_page(pv_pd->user_cr3, NULL); + *user_pde = (user_pt_pa | new_pde); } pa_t old_pt_pa = get_page_table(old_pde); if (old_pt_pa >= mem_limit) { @@ -519,7 +521,7 @@ static void hvcall_adjustpg(stack_frame_t* f) { (*user_pt)[get_pt_index(addr)] = user_pte; } restore_if(old_if); - invlpg(addr); + invlpg(addr + USER_MEM_START); return; bad_pt: @@ -541,12 +543,12 @@ static void hvcall_print(stack_frame_t* f) { if (copy_from_user(esp, sizeof(int), &len) != 0) { goto read_arg_fail; } - if (copy_from_user(esp + sizeof(va_t), sizeof(va_t), &base) != 0) { - goto read_arg_fail; - } if (len < 0) { goto bad_length; } + if (copy_from_user(esp + sizeof(va_t), sizeof(va_t), &base) != 0) { + goto read_arg_fail; + } mutex_lock(&console_lock); int result = print_buf_from_user(base, len); mutex_unlock(&console_lock); diff --git a/kern/inc/pv.h b/kern/inc/pv.h index b73fe3e..123a127 100644 --- a/kern/inc/pv.h +++ b/kern/inc/pv.h @@ -130,7 +130,7 @@ int pv_inject_irq(stack_frame_t* f, int index, int arg); void pv_check_pending_irq(stack_frame_t* f); -void do_inject_irq(thread_t* t, pv_t* pv, stack_frame_t* f, int arg, va_t eip); +void pv_inject_interrupt(thread_t* t, pv_t* pv, stack_frame_t* f, int arg, va_t eip); typedef struct pv_frame_s { reg_t cr2; @@ -270,13 +270,18 @@ no_idt_handler: pv_die("No interrupt handler installed"); } -void do_inject_irq(thread_t* t, pv_t* pv, stack_frame_t* f, int arg, va_t eip) { +void pv_inject_interrupt(thread_t* t, + pv_t* pv, + stack_frame_t* f, + int arg, + va_t eip) { reg_t new_esp; pv_frame_t pv_f; pv_f.cr2 = 0; pv_f.error_code = arg; pv_f.eip = f->eip; - pv_f.eflags = f->eflags; + pv_f.eflags = + (pv->vif != 0 ? (f->eflags | EFL_IF) : (f->eflags & (~EFL_IF))); if (f->eip >= USER_MEM_START) { pv_switch_mode(t->process, 1); reg_t esp0 = pv->vesp0; @@ -325,7 +330,7 @@ int pv_inject_irq(stack_frame_t* f, int index, int arg) { if (idt->eip == 0) { goto no_idt_handler; } - do_inject_irq(t, pv, f, arg, idt->eip); + pv_inject_interrupt(t, pv, f, arg, idt->eip); return 0; no_idt_handler: @@ -347,7 +352,8 @@ void pv_check_pending_irq(stack_frame_t* f) { if (vidt->irq[i].eip == 0) { goto no_idt_handler; } - do_inject_irq(t, pv, f, vidt->pending_irq[i].arg, vidt->irq[i].eip); + pv_inject_interrupt(t, pv, f, vidt->pending_irq[i].arg, + vidt->irq[i].eip); vidt->pending_irq[i].pending = 0; restore_if(old_if); return; diff --git a/kern/syscall_asm.S b/kern/syscall_asm.S index ca1c5a5..f3b3552 100644 --- a/kern/syscall_asm.S +++ b/kern/syscall_asm.S @@ -26,8 +26,8 @@ sys_\name: mov $SEGSEL_KERNEL_FS, %eax mov %ax, %fs cld - push $\index push %esp + push $\index call pv_handle_syscall add $0x8, %esp test %eax, %eax @@ -98,8 +98,8 @@ sys_\name: mov $SEGSEL_KERNEL_FS, %eax mov %ax, %fs cld - push $\index push %esp + push $\index call pv_handle_syscall add $0x8, %esp jmp return_to_user /* check pending exit before iret */ |
