Finish lab 5.
This commit is contained in:
@@ -289,7 +289,7 @@ region_alloc(struct Env *e, void *va, size_t len)
|
||||
// You should round va down, and round (va + len) up.
|
||||
// (Watch out for corner-cases!)
|
||||
va = ROUNDDOWN(va, PGSIZE);
|
||||
size_t count = ROUNDUP(len, PGSIZE) / PGSIZE;
|
||||
size_t count = ROUNDUP(len, PGSIZE) / PGSIZE + 1;
|
||||
struct PageInfo* p;
|
||||
|
||||
while(count--) {
|
||||
@@ -393,6 +393,10 @@ env_create(uint8_t *binary, enum EnvType type)
|
||||
if(env_alloc(&new_env, 0) < 0)
|
||||
panic("Failed to allocate environment");
|
||||
new_env->env_type = type;
|
||||
|
||||
if(type == ENV_TYPE_FS)
|
||||
new_env->env_tf.tf_eflags |= FL_IOPL_3;
|
||||
|
||||
load_icode(new_env, binary);
|
||||
}
|
||||
|
||||
|
||||
@@ -116,6 +116,11 @@ sys_env_set_status(envid_t envid, int status)
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define SYS_CHECKPERMS(perm) \
|
||||
((((perm) & (PTE_P | PTE_U)) == (PTE_P | PTE_U)) && \
|
||||
(((perm) & ~(PTE_P | PTE_U | PTE_W | PTE_AVAIL)) == 0))
|
||||
#define SYS_CHECKADDR(addr) (((uintptr_t) (addr) < UTOP) && ((uintptr_t) (addr) % PGSIZE == 0))
|
||||
|
||||
// Set envid's trap frame to 'tf'.
|
||||
// tf is modified to make sure that user environments always run at code
|
||||
// protection level 3 (CPL 3), interrupts enabled, and IOPL of 0.
|
||||
@@ -129,7 +134,19 @@ sys_env_set_trapframe(envid_t envid, struct Trapframe *tf)
|
||||
// LAB 5: Your code here.
|
||||
// Remember to check whether the user has supplied us with a good
|
||||
// address!
|
||||
panic("sys_env_set_trapframe not implemented");
|
||||
int r;
|
||||
struct Env* chenv;
|
||||
SYS_CHECKADDR(tf);
|
||||
|
||||
if((r = envid2env(envid, &chenv, true)) < 0)
|
||||
return r;
|
||||
|
||||
tf->tf_cs |= 3;
|
||||
tf->tf_eflags &= ~(FL_IOPL_3);
|
||||
tf->tf_eflags |= FL_IF;
|
||||
|
||||
chenv->env_tf = *tf;
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Set the page fault upcall for 'envid' by modifying the corresponding struct
|
||||
@@ -150,11 +167,6 @@ sys_env_set_pgfault_upcall(envid_t envid, void *func)
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define SYS_CHECKPERMS(perm) \
|
||||
((((perm) & (PTE_P | PTE_U)) == (PTE_P | PTE_U)) && \
|
||||
(((perm) & ~(PTE_P | PTE_U | PTE_W | PTE_AVAIL)) == 0))
|
||||
#define SYS_CHECKADDR(addr) (((uintptr_t) (addr) < UTOP) && ((uintptr_t) (addr) % PGSIZE == 0))
|
||||
|
||||
// Allocate a page of memory and map it at 'va' with permission
|
||||
// 'perm' in the address space of 'envid'.
|
||||
// The page's contents are set to 0.
|
||||
@@ -408,6 +420,8 @@ syscall(uint32_t syscallno, uint32_t a1, uint32_t a2, uint32_t a3, uint32_t a4,
|
||||
return sys_ipc_try_send(a1, a2, (void*) a3, a4);
|
||||
case SYS_ipc_recv:
|
||||
return sys_ipc_recv((void*) a1);
|
||||
case SYS_env_set_trapframe:
|
||||
return sys_env_set_trapframe(a1, (void*) a2);
|
||||
default:
|
||||
return -E_INVAL;
|
||||
}
|
||||
|
||||
@@ -260,6 +260,12 @@ trap_dispatch(struct Trapframe *tf)
|
||||
} else if (tf->tf_trapno == IRQ_OFFSET + IRQ_TIMER) {
|
||||
lapic_eoi();
|
||||
sched_yield();
|
||||
} else if (tf->tf_trapno == IRQ_OFFSET + IRQ_KBD) {
|
||||
kbd_intr();
|
||||
return;
|
||||
} else if (tf->tf_trapno == IRQ_OFFSET + IRQ_SERIAL) {
|
||||
serial_intr();
|
||||
return;
|
||||
}
|
||||
|
||||
// Handle spurious interrupts
|
||||
@@ -360,6 +366,8 @@ page_fault_handler(struct Trapframe *tf)
|
||||
// Handle kernel-mode page faults.
|
||||
|
||||
// LAB 3: Your code here.
|
||||
if(!curenv)
|
||||
panic("kernel-level page fault, va %p, eip %p", fault_va, tf->tf_eip);
|
||||
|
||||
// We've already handled kernel-mode exceptions, so if we get here,
|
||||
// the page fault happened in user mode.
|
||||
|
||||
Reference in New Issue
Block a user