Skip to content

Commit f341ce7

Browse files
authored
Merge pull request #228 from devnexen/userfaultfd_handling_update
update userfaultfd handling.
2 parents e4d1a35 + d631286 commit f341ce7

1 file changed

Lines changed: 29 additions & 3 deletions

File tree

src/iso_alloc_sanity.c

Lines changed: 29 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -142,19 +142,37 @@ struct uffdio_api _uffd_api;
142142
int64_t _uf_fd;
143143

144144
INTERNAL_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

Comments
 (0)