From 6c30bf2667c88a4079490d100dfded172925520f Mon Sep 17 00:00:00 2001 From: Alexander Boettcher Date: Wed, 7 Oct 2015 15:16:03 +0200 Subject: [PATCH] nova: interpret write page fault correctly Fixes #1722 --- repos/base-nova/src/core/include/ipc_pager.h | 25 +++++++++++--------- repos/base-nova/src/core/ipc_pager.cc | 21 +--------------- repos/base-nova/src/core/platform.cc | 7 +++--- 3 files changed, 19 insertions(+), 34 deletions(-) diff --git a/repos/base-nova/src/core/include/ipc_pager.h b/repos/base-nova/src/core/include/ipc_pager.h index e71b810877..2a71a8cb33 100644 --- a/repos/base-nova/src/core/include/ipc_pager.h +++ b/repos/base-nova/src/core/include/ipc_pager.h @@ -77,21 +77,24 @@ namespace Genode { { private: - /** - * Page-fault type - */ - enum Pf_type { - TYPE_READ = 0x4, - TYPE_WRITE = 0x2, - TYPE_EXEC = 0x1, - }; - addr_t _fault_ip; addr_t _fault_addr; - Pf_type _fault_type; + uint8_t _fault_type; public: + /* + * Intel manual: 6.15 EXCEPTION AND INTERRUPT REFERENCE + * Interrupt 14—Page-Fault Exception (#PF) + */ + enum { + ERR_I = 1 << 4, + ERR_R = 1 << 3, + ERR_U = 1 << 2, + ERR_W = 1 << 1, + ERR_P = 1 << 0, + }; + /** * Wait for page-fault info * @@ -123,7 +126,7 @@ namespace Genode { /** * Return true if fault was a write fault */ - bool is_write_fault() const { return _fault_type == TYPE_WRITE; } + bool is_write_fault() const { return _fault_type & ERR_W; } /** * Return true if last fault was an exception diff --git a/repos/base-nova/src/core/ipc_pager.cc b/repos/base-nova/src/core/ipc_pager.cc index dd49d7454a..31cf213a9c 100644 --- a/repos/base-nova/src/core/ipc_pager.cc +++ b/repos/base-nova/src/core/ipc_pager.cc @@ -21,24 +21,8 @@ #include -enum { verbose_page_fault = false }; - using namespace Genode; -/** - * Print page-fault information in a human-readable form - */ -inline void print_page_fault(unsigned type, addr_t addr, addr_t ip) -{ - enum { TYPE_READ = 0x4, TYPE_WRITE = 0x2, TYPE_EXEC = 0x1, }; - printf("page (%s%s%s) fault at fault_addr=%lx, fault_ip=%lx\n", - type & TYPE_READ ? "r" : "-", - type & TYPE_WRITE ? "w" : "-", - type & TYPE_EXEC ? "x" : "-", - addr, ip); -} - - void Ipc_pager::wait_for_fault() { /* @@ -47,12 +31,9 @@ void Ipc_pager::wait_for_fault() * page-fault information from our UTCB. */ Nova::Utcb *utcb = (Nova::Utcb *)Thread_base::myself()->utcb(); - _fault_type = (Pf_type)utcb->qual[0]; + _fault_type = utcb->qual[0]; _fault_addr = utcb->qual[1]; _fault_ip = utcb->ip; - - if (verbose_page_fault) - print_page_fault(_fault_type, _fault_addr, _fault_ip); } diff --git a/repos/base-nova/src/core/platform.cc b/repos/base-nova/src/core/platform.cc index 1c8574c039..f7a11f0888 100644 --- a/repos/base-nova/src/core/platform.cc +++ b/repos/base-nova/src/core/platform.cc @@ -17,14 +17,15 @@ #include #include #include +#include +#include /* core includes */ #include #include #include #include -#include -#include +#include /* NOVA includes */ #include @@ -115,7 +116,7 @@ static void page_fault_handler() addr_t pf_type = utcb->qual[0]; print_page_fault("\nPAGE-FAULT IN CORE", pf_addr, pf_ip, - (Genode::Rm_session::Fault_type)pf_type, 0); + (pf_type & Ipc_pager::ERR_W) ? Rm_session::WRITE_FAULT : Rm_session::READ_FAULT, 0); /* dump stack trace */ struct Core_img