2 * Copyright 2014, Paweł Dziepak, pdziepak@quarnos.org.
3 * Distributed under the terms of the MIT License.
5 #ifndef _KERNEL_ARCH_GENERIC_USER_MEMORY_H
6 #define _KERNEL_ARCH_GENERIC_USER_MEMORY_H
20 struct FaultHandlerGuard
{
23 ASSERT(thread_get_current_thread()->fault_handler
== nullptr);
24 thread_get_current_thread()->fault_handler
= HandleFault
;
25 std::atomic_signal_fence(std::memory_order_acq_rel
);
31 std::atomic_signal_fence(std::memory_order_acq_rel
);
32 thread_get_current_thread()->fault_handler
= nullptr;
36 [[noreturn
]] static void HandleFault()
38 longjmp(thread_get_current_thread()->fault_handler_state
, 1);
43 template<typename Function
>
44 bool user_access(Function function
)
46 FaultHandlerGuard guard
;
47 // TODO: try { } catch (...) { } would be much nicer, wouldn't it?
48 // And faster... And world wouldn't end in a terrible disaster if function()
49 // or anything it calls created on stack an object with non-trivial
51 auto fail
= setjmp(thread_get_current_thread()->fault_handler_state
);
61 arch_cpu_user_memcpy(void* src
, const void* dst
, size_t n
)
63 return user_access([=] { memcpy(src
, dst
, n
); }) ? B_OK
: B_ERROR
;
68 arch_cpu_user_memset(void* src
, char v
, size_t n
)
70 return user_access([=] { memset(src
, v
, n
); }) ? B_OK
: B_ERROR
;
75 arch_cpu_user_strlcpy(char* src
, const char* dst
, size_t n
)
78 return user_access([=, &result
] { result
= strlcpy(src
, dst
, n
); })
84 #endif // _KERNEL_ARCH_GENERIC_USER_MEMORY_H