Is it possible to make CPU raise page fault when kernel tries to write into kernel read-only page? I looked through Intel manuals:0-Mapping-Trick
The TCB (Thread Control Block) array with its 256k entries of 2 kByte each requires 512 MB of memory. For obvious reasons, the microkernel should not claim 512 MB of physical memory from the start on but should rather grow only on demand. Thus the TCB array is allocated only in virtual memory. The first access to a page in the TCB array will cause a pagefault, which is handled specially by the kernel:
* on reads, a shared 0-filled page (the so-called "0-page") is mapped read-only; this allows the access to complete after pagefault resolution and guarantees that the mandatory thread ID validation fails (thread ID 0 is reserved by the kernel and represents no thread at all (the nilthread ID))
* on writes, a newly allocated 0-filled page is mapped writable; this guarantees that all TCBs on the page are initialized with an invalid thread ID (0), so that future access still correctly report them as invalid while allowing to fill in TCB data should a new thread be created
This is a variant of the copy-on-write scheme, which saves memory even if a malicious user-level thread probes every thread ID in the system; there will only be a single physical frame mapped multiple times into the TCB array. The initial pagefaults can be avoided by premapping the 0-filled page to back the whole TCB array. Afterwards, only the first TCB modification on each page will cause a pagefault.
So, I can't make 486 to raise page fault when supervisor tries to write into SUPERVISOR (not user!) read-only page.Intel 486 Programmer's Reference Manual, 1992
4.1.3 Control Registers:
"WP (Write Protect, bit 16)
When set, this bit write-protects user-level pages against supervisor-level writes. When
this bit is clear, read-only user-level pages can be written by a supervisor process. This
feature is useful for implementing the copy-on-write method of creating a new process
(forking) used by some operating systems, such as UNIX".
6.8.1.2 TYPE CHECKING:
"Unlike the Intel386 DX processor, the Intel486 processor allows user-mode pages to be
write-protected against supervisor mode access. Setting the WP bit in the CR0 register
enables supervisor-mode sensitivity to user-mode, write-protected pages. This feature is
useful for implementing the copy-on-write strategy used by some operating systems, such
as UNIX, for task creation"
Hmm, no mentions about user pages...Pentium Processor Family Developer’s Manual Volume 3, 1995:
10.1.3. Control Registers:
"WP (Write Protect, bit 16 of CR0)
When set, this bit write-protects pages against supervisor-level writes. When this bit is clear,
read-only pages can be written by a supervisor process"
12.8.1.2. TYPE CHECKING:
"Setting the WP bit in the CR0 register enables supervisor-mode sensitivity to write-protected
pages"
Also, no mentions about user pages... So, I can make Pentium+ raise page fault when supervisor tries to write into SUPERVISOR READ-ONLY pages.Intel 64 and IA-32 Architectures Software Developers Manual, 2012:
5.11.3 Page Type:
"Starting with the P6 family, Intel processors allow user-mode pages to be write-protected against supervisor-mode access. Setting CR0.WP = 1 enables supervisor-mode sensitivity to write protected pages. If CR0.WP = 1, readonly pages are not writable from any privilege level. This supervisor write-protect feature is useful for implementing a “copy-on-write” strategy used by some operating systems, such as UNIX*, for task creation"
Damn! Why? Why, only for user level pages?From BOCHS source, bochs/cpu/paging.cc:
CR0:
37 // bit 31: PG, Paging (386+)
38 // bit 16: WP, Write Protect (486+)
39 // 0: allow supervisor level writes into user level RO pages
40 // 1: inhibit supervisor level writes into user level RO pages
41 //
Last: I tried in Bochs to set WP in CR0 and in kernel mode to write into read-only kernel page... NO PAGE FAULT.