Patch by Jan Klötzke (with additional TODO comments):
* Add a "fault_callback" to the thread structure which is called when a unhandled page fault happens in user space. A SIGSEGV will only be sent if the callback returns "true". git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@25609 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -224,6 +224,9 @@ struct team {
|
|||||||
|
|
||||||
typedef int32 (*thread_entry_func)(thread_func, void *);
|
typedef int32 (*thread_entry_func)(thread_func, void *);
|
||||||
|
|
||||||
|
typedef bool (*page_fault_callback)(addr_t address, addr_t faultAddress,
|
||||||
|
bool isWrite);
|
||||||
|
|
||||||
struct thread {
|
struct thread {
|
||||||
int32 flags; // summary of events relevant in interrupt
|
int32 flags; // summary of events relevant in interrupt
|
||||||
// handlers (signals pending, user debugging
|
// handlers (signals pending, user debugging
|
||||||
@@ -275,7 +278,13 @@ struct thread {
|
|||||||
cbuf *buffer;
|
cbuf *buffer;
|
||||||
} msg;
|
} 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;
|
int32 page_faults_allowed;
|
||||||
/* this field may only stay in debug builds in the future */
|
/* this field may only stay in debug builds in the future */
|
||||||
|
|
||||||
|
|||||||
@@ -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);
|
release_sem_etc(addressSpace->sem, READ_COUNT, 0);
|
||||||
vm_put_address_space(addressSpace);
|
vm_put_address_space(addressSpace);
|
||||||
#endif
|
#endif
|
||||||
if (user_debug_exception_occurred(B_SEGMENT_VIOLATION, SIGSEGV))
|
struct thread *thread = thread_get_current_thread();
|
||||||
send_signal(team_get_current_team_id(), SIGSEGV);
|
// 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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user