armv8: Pass correct page fault cause
authorDaniel Schwyn <daniel.schwyn@inf.ethz.ch>
Fri, 22 Nov 2019 14:36:57 +0000 (15:36 +0100)
committerDaniel Schwyn <daniel.schwyn@inf.ethz.ch>
Fri, 22 Nov 2019 15:31:39 +0000 (16:31 +0100)
Signed-off-by: Daniel Schwyn <daniel.schwyn@inf.ethz.ch>

kernel/arch/armv8/exn.c
lib/barrelfish/dispatch.c

index 31e24ad..0a80c19 100644 (file)
@@ -38,7 +38,7 @@ void handle_user_page_fault(lvaddr_t                fault_address,
 
     assert(dcb_current->disp_cte.cap.type == ObjType_Frame);
 
-    printk(LOG_WARN, "user page fault%s in '%.*s': addr %"PRIxLVADDR
+    printk(LOG_DEBUG, "user page fault%s in '%.*s': addr %"PRIxLVADDR
                       " IP %"PRIxPTR"\n",
            disabled ? " WHILE DISABLED" : "", DISP_NAME_LEN,
            disp->d.name, fault_address, saved_pc);
@@ -78,7 +78,7 @@ void handle_user_page_fault(lvaddr_t                fault_address,
 
         resume_area->named.x0   = disp_gen->udisp;
         resume_area->named.x1   = fault_address;
-        resume_area->named.x2   = 0;
+        resume_area->named.x2   = armv8_ESR_EL1_rd(NULL);
         resume_area->named.x3   = saved_pc;
         /* Why does the kernel do this? */
         resume_area->named.x10  = disp->got_base;
@@ -89,8 +89,6 @@ void handle_user_page_fault(lvaddr_t                fault_address,
 
         // Upcall user to save area
         disp->d.disabled = true;
-               printk(LOG_WARN, "page fault at %p calling handler %p\n",
-               fault_address, handler);
     }
 }
 
index 4190d5c..43b41d0 100644 (file)
@@ -345,6 +345,25 @@ void disp_pagefault(dispatcher_handle_t handle, lvaddr_t fault_address,
     } else {
         fault_type = PAGEFLT_READ;
     }
+#elif defined(__ARM_ARCH_8A__)
+    const uintptr_t EC_IABT            = 0x20;
+    const uintptr_t EC_DABT            = 0x24;
+    const uintptr_t ISS_WRITE_NOT_READ = (1 << 6);
+
+    uintptr_t ec = error >> 26;
+
+    if (ec == EC_IABT) {
+        fault_type = PAGEFLT_EXEC;
+    }
+    else if ((ec == EC_DABT) && (error & ISS_WRITE_NOT_READ)) {
+        fault_type = PAGEFLT_WRITE;
+    }
+    else if (ec == EC_DABT) {
+        fault_type = PAGEFLT_READ;
+    }
+    else {
+        fault_type = PAGEFLT_NULL;
+    }
 #else
     assert_print("Warning: don't know how to determine fault type on this arch!\n");
     fault_type = PAGEFLT_NULL;