summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHanjie Wu <hanjiew@andrew.cmu.edu>2023-04-23 02:02:46 -0400
committerHanjie Wu <hanjiew@andrew.cmu.edu>2023-04-23 02:02:46 -0400
commitf33b6e947b7d61b62e28983fcc54a08f15fca509 (patch)
tree0a67a35638d6b8baa6a98647726adc643c99c67d
parentaeb97c4547e79f6875eb641d2420b89ade8c5337 (diff)
syscall
-rw-r--r--kern/hvcall.c27
-rw-r--r--kern/inc/pv.h2
-rw-r--r--kern/pv.c6
-rw-r--r--kern/syscall_asm.S6
4 files changed, 27 insertions, 14 deletions
diff --git a/kern/hvcall.c b/kern/hvcall.c
index d8dfeed..9e348bd 100644
--- a/kern/hvcall.c
+++ b/kern/hvcall.c
@@ -52,16 +52,31 @@ static void hvcall_print_at(stack_frame_t* f);
static void hvcall_refpd(int ref);
static void hvcall_loadpd(stack_frame_t* f);
-// 0: not pv, 1: processed
-int handle_pv_syscall(stack_frame_t* f, int index) {
- if (get_current()->process->pv == NULL) {
- return 0;
+// 0: processed
+int pv_handle_syscall(stack_frame_t* f, int index) {
+ thread_t* t = get_current();
+ pv_t* pv = t->process->pv;
+ if (pv == NULL) {
+ return -1;
}
if (f->eip >= USER_MEM_START) {
- // inject interrupt
- return 1;
+ pv_idt_entry_t* idt = pv_classify_interrupt(pv, index);
+ if (idt->eip == 0) {
+ goto no_idt_handler;
+ }
+ if (idt->desc != VIDT_DPL_3) {
+ idt = &pv->vidt.fault[SWEXN_CAUSE_PROTFAULT - PV_FAULT_START];
+ if (idt->eip == 0) {
+ goto no_idt_handler;
+ }
+ }
+ do_inject_irq(t, pv, f, 0, idt->eip);
+ return 0;
}
pv_die("Syscall is not allowed for PV kernels");
+
+no_idt_handler:
+ pv_die("No interrupt handler installed");
return 1;
}
diff --git a/kern/inc/pv.h b/kern/inc/pv.h
index eeecd47..b73fe3e 100644
--- a/kern/inc/pv.h
+++ b/kern/inc/pv.h
@@ -130,6 +130,8 @@ 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);
+
typedef struct pv_frame_s {
reg_t cr2;
reg_t error_code;
diff --git a/kern/pv.c b/kern/pv.c
index 02b0ae9..c8c7f1d 100644
--- a/kern/pv.c
+++ b/kern/pv.c
@@ -270,11 +270,7 @@ no_idt_handler:
pv_die("No interrupt handler installed");
}
-static inline void do_inject_irq(thread_t* t,
- pv_t* pv,
- stack_frame_t* f,
- int arg,
- va_t eip) {
+void do_inject_irq(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;
diff --git a/kern/syscall_asm.S b/kern/syscall_asm.S
index 5d63a39..ca1c5a5 100644
--- a/kern/syscall_asm.S
+++ b/kern/syscall_asm.S
@@ -28,10 +28,10 @@ sys_\name:
cld
push $\index
push %esp
- call handle_pv_syscall
+ call pv_handle_syscall
add $0x8, %esp
test %eax, %eax
- jne return_to_user
+ je return_to_user
push %esp
call sys_\name\()_real
add $0x4, %esp
@@ -100,7 +100,7 @@ sys_\name:
cld
push $\index
push %esp
- call handle_pv_syscall
+ call pv_handle_syscall
add $0x8, %esp
jmp return_to_user /* check pending exit before iret */
.endm