+
+ /* Store the physical address of the page directory into CR3
+ aka PDBR (page directory base register). This activates our
+ new page tables immediately. See [IA32-v2a] "MOV--Move
+ to/from Control Registers" and [IA32-v3] 3.7.5. */
+ asm volatile ("mov %%cr3, %0" :: "r" (vtop (pd)));
+}
+
+/* Returns the currently active page directory. */
+static uint32_t *
+active_pd (void)
+{
+ /* Copy CR3, the page directory base register (PDBR), into
+ `pd'.
+ See [IA32-v2a] "MOV--Move to/from Control Registers" and
+ [IA32-v3] 3.7.5. */
+ uintptr_t pd;
+ asm volatile ("mov %0, %%cr3" : "=r" (pd));
+ return ptov (pd);
+}
+
+/* Seom page table changes can cause the CPU's translation
+ lookaside buffer (TLB) to become out-of-sync with the page
+ table. When this happens, we have to "invalidate" the TLB by
+ re-activating it.
+
+ This function invalidates the TLB if PD is the active page
+ directory. (If PD is not active then its entries are not in
+ the TLB, so there is no need to invalidate anything.) */
+static void
+invalidate_pagedir (uint32_t *pd)
+{
+ if (active_pd () == pd)
+ {
+ /* We cleared a page-table entry in the active page
+ table, so we have to invalidate the TLB. See
+ [IA32-v3], section 3.11. */
+ pagedir_activate (pd);
+ }