Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

whats the purpose of x86 cr0 WP bit?

in x86 CPU, there is control register number 0. the 16'th bit of this register indicates "Write Protection" setting. if this bit is cleared, CPU is able to overwrite Read Only data. (configured in page table entry) in memory. if this bit is set, CPU can not overwrite RO data in memory.

what I am curious is "what is the original purpose of this bit??" "why does x86 CPU need this??"

like image 602
daehee Avatar asked Mar 07 '13 15:03

daehee


People also ask

Which control register is reserved?

According to the Intel Systems Programming Manual (section 2-13), the CR1 control register is "Reserved". That is, the kernel manipulating control register CR1 results in undefined behavior. As the articles indicates, there are also CR2, CR3, CR4 and CR8 control registers, though they are not reserved.


2 Answers

Quoting from Intel® 64 and IA-32 Architectures Software Developer’s Manual Volume 3A pg. 2-15 (Emphasis mine):

WP Write Protect (bit 16 of CR0) — When set, inhibits supervisor-level procedures from writing into readonly pages; when clear, allows supervisor-level procedures to write into read-only pages (regardless of the U/S bit setting; see Section 4.1.3 and Section 4.6). This flag facilitates implementation of the copy-on-write method of creating a new process (forking) used by operating systems such as UNIX.

Update: Looking at wikipedia on fork():

Whenever a process (parent or child) modifies a page, a separate copy of that particular page alone is made for that process (parent or child) which performed the modification.

This is at the core of copy-on-write, but presents a problem when the modification is done by the kernel (such as when the write occurs as a result of syscall - think read()).

From 4.1.3:

CR0.WP allows pages to be protected from supervisor-mode writes. If CR0.WP = 0, supervisor-mode write accesses are allowed to linear addresses with read-only access rights; if CR0.WP = 1, they are not. (User-mode write accesses are never allowed to linear addresses with read-only access rights, regardless of the value of CR0.WP.)

By setting CR0.WP = 1 the kernel will be notified (with a page-fault) when it modifies read-only user pages and can perform the copy-on-write operation before proceeding with the page modification.

like image 141
user786653 Avatar answered Oct 14 '22 05:10

user786653


WP=1 is the default. It enables traps when kernel writes to a read only (write protected) user (U) page, so the kernel can check whether it is a COW page (so it knows that another copy of the page needs to be created that is not COW), otherwise it would have to check every single memory address it is accessing or it would break COW by making the change visible to other processes that map the memory.

WP can be set to 0 (but it wants to make sure interrupts are disabled / masked during this handling, so that control can't be taken away by code executing that is unaware of this condition). This allows a write protected cr3 page to be unwriteprotected (because when you unset the write bit in its recursive PML4 entry to itself, nothing can be done about it until you WP = 0, otherwise it will keep causing a trap)

like image 34
Lewis Kelsey Avatar answered Oct 14 '22 06:10

Lewis Kelsey