Sebuah thread dapat mengalami fault pada virtual address lalu tetap terblokir sementara thread atau proses userspace lain menentukan state page yang membuat akses tersebut dapat dilanjutkan. userfaultfd menyediakan batas ini dengan mengubah page fault terpilih menjadi message pada file descriptor dan memasangkan message tersebut dengan ioctl untuk menyelesaikan fault.
Mekanisme ini tidak menggantikan page-fault machinery milik kernel. Kontrol userspace disisipkan pada range dan kelas fault yang didaftarkan, sementara kernel tetap memiliki page table, pemblokiran fault, dan transisi yang membuat page dapat diakses kembali.
Registrasi memilih kelas fault
userfaultfd yang baru dibuat harus lebih dulu menegosiasikan API melalui UFFDIO_API. Userspace kemudian mendaftarkan range virtual address dengan UFFDIO_REGISTER dan memilih satu atau beberapa mode yang didukung.
Tiga mode yang mapan merepresentasikan state memori yang berbeda:
UFFDIO_REGISTER_MODE_MISSINGmelaporkan akses ke page yang tidak ada pada mapping terdaftar.UFFDIO_REGISTER_MODE_MINORmelaporkan minor fault ketika backing content sudah ada tetapi page-table entry yang sesuai belum terpasang.UFFDIO_REGISTER_MODE_WPmelaporkan penulisan ke page yang berada di bawah write protection userfaultfd.
Ketersediaan mode bergantung pada dukungan kernel dan tipe memori. Negosiasi feature dan bit mask ioctl yang dikembalikan untuk range terdaftar karena itu merupakan bagian dari interface, bukan sekadar petunjuk capability opsional.
Fault menjadi event pada descriptor
Ketika fault terdaftar terjadi, thread yang memicu fault dihentikan dan sebuah event tersedia untuk dibaca dari userfaultfd. Manager membaca struct uffd_msg dan menerima alamat fault beserta flag yang mendeskripsikan event.
Pemisahan ini membuat thread yang memicu akses memori berbeda dari kode yang menyediakan atau melepaskan page. Manager dapat berjalan pada thread lain, dan userfaultfd juga dapat dikirim melalui Unix domain socket ke manager eksternal.
Descriptor dapat dipantau dengan poll(), select(), atau epoll() ketika dikonfigurasi untuk operasi nonblocking. Sifat ini memungkinkan penanganan page fault masuk ke event loop bersama pekerjaan berbasis descriptor lain tanpa memerlukan signal handler pada thread yang mengalami fault.
Missing fault memerlukan isi page
Pada missing mode, fault tidak selesai hanya karena notifikasinya dibaca. Userspace harus menyediakan state yang memungkinkan akses dilanjutkan.
UFFDIO_COPY menyalin content yang disediakan ke range fault dan memasang page hasilnya secara atomik terhadap resolusi fault. UFFDIO_ZEROPAGE menyediakan page berisi nol pada kondisi operasi tersebut didukung.
Sifat atomik penting pada batas publikasi: thread lain tidak mengamati page yang baru terisi sebagian melalui operasi resolusi. Thread tersebut terus mengalami fault sampai page selesai dipasang.
Perilaku ini mendukung demand population ketika isi page berasal dari checkpoint image, remote store, representasi terkompresi, atau sumber lain yang dikelola aplikasi. Kernel menyediakan protokol pemblokiran dan pemasangan; kebijakan untuk memperoleh byte tetap berada di userspace.
Minor fault bekerja pada backing page yang sudah ada
Minor mode mencakup state berbeda. Backing page sudah tersedia, tetapi mapping yang mengalami fault belum memiliki page-table state yang diperlukan untuk mengaksesnya.
Untuk mapping shmem atau hugetlbfs yang didukung, manager dapat memodifikasi backing page melalui mapping lain sebelum menyelesaikan event. UFFDIO_CONTINUE kemudian memasang mapping state yang diperlukan agar akses yang terblokir dapat berjalan kembali.
Perbedaan ini membuat minor fault secara material berbeda dari missing fault. UFFDIO_COPY membuat atau mengisi state yang hilang; UFFDIO_CONTINUE mengekspos backing content yang sudah tersedia.
Write protection membuat penulisan dapat diamati
Write-protect mode memungkinkan userspace menandai page dengan UFFDIO_WRITEPROTECT. Penulisan berikutnya ke page yang diproteksi menghasilkan page-fault event dengan UFFD_PAGEFAULT_FLAG_WP, dan thread penulis tetap terblokir sampai proteksi dilepas atau resolusi lain yang berlaku terjadi.
Mekanisme ini membentuk batas dirty tracking yang sinkron. Manager dapat mengamati penulisan pertama yang diproteksi sebelum mengizinkannya berlanjut, berguna ketika state memori harus dilacak selama fase checkpoint atau migrasi.
Dukungan write-protect berbeda pada anonymous memory, shmem, dan hugetlbfs serta memperoleh feature bit tambahan dari waktu ke waktu. Kode yang bergantung pada perilaku tertentu harus menegosiasikan capability UFFD_FEATURE_* terkait, bukan menyimpulkan dukungan hanya dari keberadaan system call.
Resolusi fault dan wakeup dapat dipisahkan
Ioctl resolusi secara normal membangunkan fault yang terblokir pada range terkait. Beberapa operasi juga menyediakan mode DONTWAKE, sehingga page state dapat disiapkan tanpa langsung melepaskan thread yang menunggu.
Pemisahan tersebut memungkinkan batching: manager dapat menyelesaikan beberapa page lalu melakukan operasi wake setelah transisi state yang lebih besar selesai. Konsekuensinya, correctness tidak dapat direduksi menjadi satu loop pembacaan event. Page state, resolusi, dan wakeup merupakan bagian protokol yang terpisah.
Perubahan concurrent memerlukan perhatian serupa. Mapping dapat di-unmap, di-remap, atau dihapus ketika manager eksternal sedang bekerja. Event non-page-fault opsional dapat melaporkan perubahan virtual memory tertentu, tetapi aplikasi tetap memerlukan sinkronisasi yang sesuai dengan model ownership-nya.
Akses ke userfaultfd sensitif terhadap keamanan
Secara historis, fault yang berasal dari akses kernel membuat userfaultfd tanpa pembatasan berguna dalam teknik eksploitasi kernel. Linux karena itu membedakan jalur pembuatan yang dibatasi.
userfaultfd(UFFD_USER_MODE_ONLY) membuat descriptor yang terbatas pada fault yang berasal dari userspace. Penanganan yang lebih luas melalui system call tunduk pada capability atau kebijakan sistem. Linux juga menyediakan /dev/userfaultfd pada sistem yang mengaktifkannya, sehingga permission filesystem dapat mengontrol akses untuk membuat object userfaultfd.
Kontrol ini menentukan pihak yang boleh membuat kanal pengelolaan fault; kontrol tersebut tidak otomatis membuat manager tepercaya. Manager yang menyediakan isi page keliru atau gagal menyelesaikan fault dapat menahan eksekusi atau merusak state aplikasi yang dikontrolnya.
Batasnya adalah mediasi page fault, bukan pengganti paging umum
userfaultfd memiliki lingkup sempit yang berguna. Mekanisme ini mengubah virtual-memory fault terpilih menjadi event descriptor, memblokir thread pengakses pada batas tersebut, lalu menyediakan operasi eksplisit untuk memublikasikan page state atau mengubah proteksi.
Kernel mempertahankan page-table transition dan wakeup machinery, sementara userspace mengontrol keputusan kebijakan terpilih. Pembagian ini mendukung post-copy migration, lazy restore, application-managed paging, dan synchronous write tracking tanpa memindahkan seluruh subsistem virtual memory ke userspace.