From 7da0a81c0e1ecc582c580ae0769e5cc8fce220bc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Axel=20D=C3=B6rfler?= Date: Thu, 22 May 2008 12:33:30 +0000 Subject: [PATCH] =?UTF-8?q?Patch=20by=20Jan=20Kl=C3=B6tzke=20(with=20addit?= =?UTF-8?q?ional=20TODO=20comments):=20*=20Add=20a=20"fault=5Fcallback"=20?= =?UTF-8?q?to=20the=20thread=20structure=20which=20is=20called=20when=20a?= =?UTF-8?q?=20=20=20unhandled=20page=20fault=20happens=20in=20user=20space?= =?UTF-8?q?.=20A=20SIGSEGV=20will=20only=20be=20sent=20=20=20if=20the=20ca?= =?UTF-8?q?llback=20returns=20"true".?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@25609 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- headers/private/kernel/thread_types.h | 11 ++++++++++- src/system/kernel/vm/vm.cpp | 9 +++++++-- 2 files changed, 17 insertions(+), 3 deletions(-) diff --git a/headers/private/kernel/thread_types.h b/headers/private/kernel/thread_types.h index 2088f8c98a..83ccfe30fe 100644 --- a/headers/private/kernel/thread_types.h +++ b/headers/private/kernel/thread_types.h @@ -224,6 +224,9 @@ struct team { typedef int32 (*thread_entry_func)(thread_func, void *); +typedef bool (*page_fault_callback)(addr_t address, addr_t faultAddress, + bool isWrite); + struct thread { int32 flags; // summary of events relevant in interrupt // handlers (signals pending, user debugging @@ -275,7 +278,13 @@ struct thread { cbuf *buffer; } msg; - addr_t fault_handler; + union { + addr_t fault_handler; + page_fault_callback fault_callback; + // TODO: this is a temporary field used for the vm86 implementation + // and should be removed again when that one is moved into the + // kernel entirely. + }; int32 page_faults_allowed; /* this field may only stay in debug builds in the future */ diff --git a/src/system/kernel/vm/vm.cpp b/src/system/kernel/vm/vm.cpp index b6e8a5f81c..b26e4b946f 100644 --- a/src/system/kernel/vm/vm.cpp +++ b/src/system/kernel/vm/vm.cpp @@ -3864,8 +3864,13 @@ vm_page_fault(addr_t address, addr_t faultAddress, bool isWrite, bool isUser, release_sem_etc(addressSpace->sem, READ_COUNT, 0); vm_put_address_space(addressSpace); #endif - if (user_debug_exception_occurred(B_SEGMENT_VIOLATION, SIGSEGV)) - send_signal(team_get_current_team_id(), SIGSEGV); + struct thread *thread = thread_get_current_thread(); + // TODO: the fault_callback is a temporary solution for vm86 + if (thread->fault_callback == NULL + || thread->fault_callback(address, faultAddress, isWrite)) { + if (user_debug_exception_occurred(B_SEGMENT_VIOLATION, SIGSEGV)) + send_signal(team_get_current_team_id(), SIGSEGV); + } } }