@@ -142,19 +142,37 @@ struct uffdio_api _uffd_api;
142142int64_t _uf_fd ;
143143
144144INTERNAL_HIDDEN void _iso_alloc_setup_userfaultfd (void ) {
145- _uf_fd = syscall (__NR_userfaultfd , O_CLOEXEC | O_NONBLOCK );
145+ int flags = O_CLOEXEC | O_NONBLOCK ;
146+
147+ #ifdef UFFD_USER_MODE_ONLY
148+ /* Below, the syscall fails not necessarily because lack of kernel support.
149+ * By default, the `unprivileged_userfaultfd` flag is disabled.
150+ * From Linux 5.11 however, we can handle pages registered from the user-space. */
151+ flags |= UFFD_USER_MODE_ONLY ;
152+ #endif
153+ _uf_fd = syscall (__NR_userfaultfd , flags );
146154
147155 if (_uf_fd == ERR ) {
148- LOG_AND_ABORT ("This kernel does not support userfaultfd" );
156+ LOG_AND_ABORT ("This kernel does not support userfaultfd or is disallowed in the user-space " );
149157 }
150158
151159 _uffd_api .api = UFFD_API ;
152160 _uffd_api .features = 0 ;
153161
162+ #if THREAD_SUPPORT
163+ _uffd_api .features |= UFFD_FEATURE_THREAD_ID ;
164+ #endif
165+
154166 if (ioctl (_uf_fd , UFFDIO_API , & _uffd_api ) == ERR ) {
155167 LOG_AND_ABORT ("Failed to setup userfaultfd with ioctl" );
156168 }
157169
170+ #if THREAD_SUPPORT
171+ if (!(_uffd_api .features & UFFD_FEATURE_THREAD_ID )) {
172+ LOG_AND_ABORT ("Failed to setup userfaultfd with thread id report" );
173+ }
174+ #endif
175+
158176 if (_page_fault_thread == 0 ) {
159177 int32_t s = pthread_create (& _page_fault_thread , NULL , _page_fault_thread_handler , NULL );
160178
@@ -220,8 +238,12 @@ INTERNAL_HIDDEN void *_page_fault_thread_handler(void *unused) {
220238 reg .range .len = g_page_size ;
221239 }
222240
223- if ((ioctl (_uf_fd , UFFDIO_UNREGISTER , & reg .range )) == ERR ) {
241+ if (UNLIKELY ((ioctl (_uf_fd , UFFDIO_UNREGISTER , & reg .range )) == ERR )) {
242+ #if THREAD_SUPPORT
243+ LOG_AND_ABORT ("Failed to unregister address %p, thread %u" , umsg .arg .pagefault .address , umsg .arg .pagefault .feat .ptid );
244+ #else
224245 LOG_AND_ABORT ("Failed to unregister address %p" , umsg .arg .pagefault .address );
246+ #endif
225247 }
226248
227249 UNLOCK_SANITY_CACHE ();
@@ -230,7 +252,11 @@ INTERNAL_HIDDEN void *_page_fault_thread_handler(void *unused) {
230252
231253 /* Detects a read of an uninitialized page */
232254 if ((umsg .arg .pagefault .flags & UFFD_PAGEFAULT_FLAG_WRITE ) == 0 ) {
255+ #ifdef THREAD_SUPPORT
256+ LOG_AND_ABORT ("Uninitialized read detected on page %p, thread %u" , umsg .arg .pagefault .address , umsg .arg .pagefault .feat .ptid );
257+ #else
233258 LOG_AND_ABORT ("Uninitialized read detected on page %p" , umsg .arg .pagefault .address );
259+ #endif
234260 }
235261
236262 UNLOCK_SANITY_CACHE ();
0 commit comments