summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHanjie Wu <hanjiew@andrew.cmu.edu>2023-04-23 04:12:07 -0400
committerHanjie Wu <hanjiew@andrew.cmu.edu>2023-04-23 04:12:07 -0400
commit981a10da84b0b33d7c169566b4faa9093dff6431 (patch)
tree0de48dc7ef997fdbeea31a1e535002c2c443ba34
parentf33b6e947b7d61b62e28983fcc54a08f15fca509 (diff)
fix
-rw-r--r--kern/hvcall.c18
-rw-r--r--kern/inc/pv.h2
-rw-r--r--kern/pv.c14
-rw-r--r--kern/syscall_asm.S4
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;
diff --git a/kern/pv.c b/kern/pv.c
index c8c7f1d..6e245fd 100644
--- a/kern/pv.c
+++ b/kern/pv.c
@@ -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 */