Specifying memory protections at allocation time to, say, read-only may appear to be a pretty useless thing to do: how would you then initialize that memory to some meaningful content? Well, think about it – guard pages are the perfect use case for this scenario (similar to the redzone pages that the SLUB layer keeps when in debug mode); it is useful indeed.
What if we wanted read-only pages for some purpose other than guard pages? Well, instead of using __vmalloc(), we might avail of some alternate means: perhaps memory mapping some kernel memory into user space via an mmap() method, and using the mprotect(2) system call from a user space app to set up appropriate protections (or even setting up protections through well-known and tested LSM frameworks, such as SELinux, AppArmor, Integrity, and so on).
We conclude this section with a quick comparison between the typical kernel memory allocator APIs: kmalloc() and...