diff --git a/kernel/vm.c b/kernel/vm.c
index e0bc728..b2bfe2c 100644
--- a/kernel/vm.c
+++ b/kernel/vm.c
@@ -99,6 +99,9 @@ walkaddr(pagetable_t pagetable, uint64 va)
   pte_t *pte;
   uint64 pa;
 
+  if(va >= MAXVA)
+    return 0;
+
   pte = walk(pagetable, va, 0);
   if(pte == 0)
     return 0;
@@ -408,7 +411,7 @@ copyinstr(pagetable_t pagetable, char *dst, uint64 srcva, uint64 max)
   int got_null = 0;
 
   while(got_null == 0 && max > 0){
-    va0 = (uint)PGROUNDDOWN(srcva);
+    va0 = PGROUNDDOWN(srcva);
     pa0 = walkaddr(pagetable, va0);
     if(pa0 == 0)
       return -1;
diff --git a/user/usertests.c b/user/usertests.c
index 0042fe7..7da62d1 100644
--- a/user/usertests.c
+++ b/user/usertests.c
@@ -1908,6 +1908,18 @@ stacktest(char *s)
     exit(xstatus);
 }
 
+// copyinstr() used to cast the virtual page address to uint,
+// which (with certain wild system call arguments) could
+// result in a kernel page fault.
+void
+pgbug(char *s)
+{
+  char *argv[1];
+  argv[0] = 0;
+  exec((char*)0xeaeb0b5b00002f5e, argv);
+  exit(0);
+}
+
 // run each test in its own process. run returns 1 if child's exit()
 // indicates success.
 int
@@ -1945,6 +1957,7 @@ main(int argc, char *argv[])
     void (*f)(char *);
     char *s;
   } tests[] = {
+    {pgbug, "pgbug" },
     {reparent, "reparent" },
     {twochildren, "twochildren"},
     {forkfork, "forkfork"},