Changeset View
Standalone View
sys/amd64/amd64/pmap.c
- This file is larger than 256 KB, so syntax highlighting is disabled by default.
Show First 20 Lines • Show All 2,687 Lines • ▼ Show 20 Lines | pmap_update_pde_invalidate(pmap_t pmap, vm_offset_t va, pd_entry_t newpde) | ||||
else { | else { | ||||
/* | /* | ||||
* Promotion: flush every 4KB page mapping from the TLB, | * Promotion: flush every 4KB page mapping from the TLB, | ||||
* including any global (PG_G) mappings. | * including any global (PG_G) mappings. | ||||
*/ | */ | ||||
invltlb_glob(); | invltlb_glob(); | ||||
} | } | ||||
} | } | ||||
#ifdef SMP | |||||
/* | /* | ||||
* For SMP, these functions have to use the IPI mechanism for coherence. | * The amd64 pmap uses different approaches to TLB invalidation | ||||
* depending on the kernel configuration, available hardware features, | |||||
markj: I would qualify a bit more: "depending on the kernel configuration, and on available hardware… | |||||
* and known hardware errata. The kernel configuration option that | |||||
* has the greatest operational impact on TLB invalidation is PTI, | |||||
Done Inline ActionsI would drop the last sentence of this paragraph, i.e., the sentence "For SMP, ...", and then merge this paragraph with the next one. (The use of IPIs comes up below. Here, I think it is lower level than the rest of this new combined paragraph.) alc: I would drop the last sentence of this paragraph, i.e., the sentence "For SMP, ...", and then… | |||||
* which is enabled automatically on affected Intel CPUs. The most | |||||
Done Inline ActionsThis line is missing an "*". alc: This line is missing an "*". | |||||
* impactful hardware features are first PCID, and then INVPCID | |||||
Done Inline ActionsImpact on what? Performance? How TLB invalidation is performed? alc: Impact on what? Performance? How TLB invalidation is performed? | |||||
Done Inline ActionsI said 'high operational impact' there. It is explained below, at this point intent is only to note to reader that PTI changes a lot. What specifically is changed comparing for !PTI, is described later. kib: I said 'high operational impact' there. It is explained below, at this point intent is only to… | |||||
Done Inline Actions"The kernel configuration option that has the greatest operational impact on TLB invalidation is PTI, which ... alc: "The kernel configuration option that has the greatest operational impact on TLB invalidation… | |||||
Done Inline Actions"mainly" -> "first" alc: "mainly" -> "first" | |||||
* instruction presence. PCID usage is quite different for PTI | |||||
Done Inline ActionsIt's not immediately clear how this sentence relates to PCID vs. non-PCID. markj: It's not immediately clear how this sentence relates to PCID vs. non-PCID. | |||||
Done Inline ActionsMoved after the first introduction sentence. kib: Moved after the first introduction sentence. | |||||
Done Inline Actions"CPUs. The most impactful hardware ... alc: "CPUs. The most impactful hardware ... | |||||
* vs. non-PTI. | |||||
Done Inline Actions"The amd64 pmap uses different approaches to TLB invalidation depending on the kernel configuration, available hardware features, and known hardware errata. alc: "The amd64 pmap uses different approaches to TLB invalidation depending on the kernel… | |||||
* | * | ||||
Done Inline ActionsI'm not sure what this sentence is really meant to say. Literally, it seems to be stating the obvious: That PCID usage is quite different when you don't have hardware PCID support. alc: I'm not sure what this sentence is really meant to say. Literally, it seems to be stating the… | |||||
Done Inline ActionsTypo: I mean PTI vs. non-PTI. kib: Typo: I mean PTI vs. non-PTI. | |||||
Done Inline ActionsPTI is the kernel configuration option that most affects alc: PTI is the kernel configuration option that most affects | |||||
Done Inline ActionsSorry, I cannot get sense of this comment. kib: Sorry, I cannot get sense of this comment. | |||||
Done Inline ActionsI think that this was the start of a comment that I intended to delete because it was superseded by another comment. alc: I think that this was the start of a comment that I intended to delete because it was… | |||||
* N.B.: Before calling any of the following TLB invalidation functions, | * * Kernel Page Table Isolation (PTI or KPTI) is used to mitigate | ||||
* the calling processor must ensure that all stores updating a non- | * the Meltdown bug in some Intel CPUs. Under PTI, each user address | ||||
Done Inline Actions"user address space" markj: "user address space" | |||||
Done Inline Actions-> "the Meltdown bug ..." Remove the stray space between PTI and the subsequent comma. alc: -> "the Meltdown bug ..."
Remove the stray space between PTI and the subsequent comma. | |||||
* kernel page table are globally performed. Otherwise, another | * space is served by two page tables, user and kernel. The user | ||||
Done Inline Actions"a trampoline is needed" markj: "a trampoline is needed" | |||||
Done Inline Actions"The user ... and a kernel trampoline. The kernel trampoline includes the entirety of the kernel text but only the kernel data that is needed to switch ... alc: "The user ... and a kernel trampoline. The kernel trampoline includes the entirety of the… | |||||
* processor could cache an old, pre-update entry without being | * page table only maps user space and a kernel trampoline. The | ||||
* invalidated. This can happen one of two ways: (1) The pmap becomes | * kernel trampoline includes the entirety of the kernel text but | ||||
Done Inline Actions"The kernel page table maps the user and kernel address spaces in their entirety. It is identical to the per-process page table allocated in non-PTI ... alc: "The kernel page table maps the user and kernel address spaces in their entirety. It is… | |||||
* active on another processor after its pm_active field is checked by | * only the kernel data that is needed to switch from user to kernel | ||||
* one of the following functions but before a store updating the page | * mode. The kernel page table maps the user and kernel address | ||||
Done Inline ActionsPerhaps s/work around/mitigate/ markj: Perhaps s/work around/mitigate/ | |||||
Done Inline ActionsI would open the paragraph with this sentence. alc: I would open the paragraph with this sentence. | |||||
* table is globally performed. (2) The pmap becomes active on another | * spaces in their entirety. It is identical to the per-process | ||||
* processor before its pm_active field is checked but due to | * page table used in non-PTI mode. | ||||
Done Inline Actions"allocated" -> "used" alc: "allocated" -> "used" | |||||
* speculative loads one of the following functions stills reads the | |||||
* pmap as inactive on the other processor. | |||||
* | * | ||||
* The kernel page table is exempt because its pm_active field is | * User page tables are only used when the CPU is in user mode. | ||||
Done Inline Actions-> "... that the user space ..." I would drop the "s" at the end of "kernel page tables". alc: -> "... that the user space ..."
I would drop the "s" at the end of "kernel page tables". | |||||
* immutable. The kernel page table is always active on every | * Consequently, some TLB invalidations can be postponed until the | ||||
Done Inline Actions"the switch from kernel mode to user mode" markj: "the switch from kernel mode to user mode" | |||||
Done Inline ActionsI would take it for granted that TLB coherence must be maintained. Is the real point that you're trying to make here that these TLB invalidations can't be deferred, unlike the user page table ones mentioned below? If so, I think that this paragraph would be clearer if you swapped the order of the sentences, that is, talk about the user page table first. alc: I would take it for granted that TLB coherence must be maintained. Is the real point that… | |||||
* processor. | * switch from kernel to user mode. In contrast, the user | ||||
Done Inline Actions"... when the CPU is in user mode. Consequently, some TLB invalidations ... alc: "... when the CPU is in user mode. Consequently, some TLB invalidations ... | |||||
Done Inline ActionsCan shorten to: "... from kernel to user mode." alc: Can shorten to: "... from kernel to user mode." | |||||
* space part of the kernel page table is used for copyout(9), so | |||||
* TLB invalidations on this page table cannot be similarly postponed. | |||||
Done Inline Actions"... mode. In contrast, the user space part of the kernel page table is used for copyout(9), so TLB invalidations on this page table cannot be postponed." alc: "... mode. In contrast, the user space part of the kernel page table is used for copyout(9)… | |||||
Done Inline Actions-> "... be similarly postponed. alc: -> "... be similarly postponed. | |||||
* | |||||
Done Inline Actions"for the user mode page tables" markj: "for the user mode page tables" | |||||
Done Inline Actions"The existence of a user mode page table ..." alc: "The existence of a user mode page table ..." | |||||
* The existence of a user mode page table for the given pmap is | |||||
Done Inline Actions"by a pm_ucr3 value that differs from ..., in which case pm_ucr3 contains alc: "by a pm_ucr3 value that differs from ..., in which case pm_ucr3 contains | |||||
* indicated by a pm_ucr3 value that differs from PMAP_NO_CR3, in | |||||
Done Inline Actions"... for the user mode page table's root. alc: "... for the user mode page table's root. | |||||
Done Inline Actions"... by a pm_ucr3 alc: "... by a pm_ucr3 | |||||
* which case pm_ucr3 contains the %cr3 register value for the user | |||||
* mode page table's root. | |||||
Done Inline Actions"... which CPUs currently have the pmap active. A CPU's bit is set on ... alc: "... which CPUs currently have the pmap active. A CPU's bit is set on ... | |||||
* | |||||
* * The pm_active bitmask indicates which CPUs currently have the | |||||
Done Inline ActionsTypo, "necessarily" markj: Typo, "necessarily" | |||||
Done Inline Actions"... For the kernel page table, the pm_active field alc: "... For the kernel page table, the pm_active field | |||||
* pmap active. A CPU's bit is set on context switch to the pmap, and | |||||
Done Inline Actions-> "... switch to the pmap, and ..." alc: -> "... switch to the pmap, and ..." | |||||
* cleared on switching off this CPU. For the kernel page table, | |||||
* the pm_active field is immutable and contains all CPUs. The | |||||
Done Inline ActionsI would s/some pmap TLB entries/virtual addresses/, since it is IMO a bit more clear and since Intel explicitly refers to "paging structure" caches as well. markj: I would s/some pmap TLB entries/virtual addresses/, since it is IMO a bit more clear and since… | |||||
Done Inline Actions"present in hardware" -> "in use by the hardware" alc: "present in hardware" -> "in use by the hardware" | |||||
* kernel page table is always logically active on every processor, | |||||
* but not necessarily in use by the hardware, e.g., in PTI mode. | |||||
Done Inline ActionsAdd comma, -> "..., e.g., ..." alc: Add comma, -> "..., e.g., ..." | |||||
* | |||||
Done Inline Actions"..., the pmap sends ... alc: "..., the pmap sends ... | |||||
* When requesting invalidation of virtual addresses with | |||||
Done Inline Actions"prepared to handle the race"? markj: "prepared to handle the race"? | |||||
Done Inline Actions"... recorded as active in pm_active. Updates to and reads from pm_active are not synchronized, and so they may race with each other. Shootdown handlers ... alc: "... recorded as active in pm_active. Updates to and reads from pm_active are not synchronized… | |||||
* pmap_invalidate_XXX() functions, the pmap sends shootdown IPIs to | |||||
* all CPUs recorded as active in pm_active. Updates to and reads | |||||
Done Inline ActionsFor consistency, add another space after the period. alc: For consistency, add another space after the period. | |||||
* from pm_active are not synchronized, and so they may race with | |||||
* each other. Shootdown handlers are prepared to handle the race. | |||||
* | |||||
* * PCID is an optional feature of the long mode x86 MMU where TLB | |||||
Done Inline Actions"... to. This feature provides a limited namespace ..." (The text that follows uses "PCID" to refer to a "Process ID" so I want to stop using it to refer to the feature.) alc: "... to. This feature provides a limited namespace ..."
(The text that follows uses "PCID" to… | |||||
* entries are tagged with the 'Process ID' of the address space | |||||
Done Inline Actions"... 12 bits, supporting 4095 simultaneous IDs total. alc: "... 12 bits, supporting 4095 simultaneous IDs total. | |||||
* they belong to. This feature provides a limited namespace for | |||||
* process identifiers, 12 bits, supporting 4095 simultaneous IDs | |||||
Done Inline ActionsTypo, "cannot not". Should be "cannot be"? markj: Typo, "cannot not". Should be "cannot be"? | |||||
Done Inline Actions"Allocation of a PCID to a pmap ... alc: "Allocation of a PCID to a pmap ... | |||||
* total. | |||||
Done Inline Actions"section 15.12, "Other TLB Consistency Algorithms", of Vahalia's book "Unix Internals". alc: "section 15.12, "Other TLB Consistency Algorithms", of Vahalia's book "Unix Internals". | |||||
* | |||||
Done Inline Actions"Instead, a per-CPU, per-pmap PCID is assigned when a CPU is about to start caching TLB entries from a pmap, i.e., ..." markj: "Instead, a per-CPU, per-pmap PCID is assigned when a CPU is about to start caching TLB entries… | |||||
Done Inline Actions"A PCID cannot ... whole lifetime of a pmap in ... alc: "A PCID cannot ... whole lifetime of a pmap in ... | |||||
* Allocation of a PCID to a pmap is done by an algorithm described | |||||
* in section 15.12, "Other TLB Consistency Algorithms", of | |||||
Done Inline Actions"when the CPU ... alc: "when the CPU ... | |||||
* Vahalia's book "Unix Internals". A PCID cannot be allocated for | |||||
* the whole lifetime of a pmap in pmap_pinit() due to the limited | |||||
Done Inline Actions"switch that activates ... alc: "switch that activates ... | |||||
* namespace. Instead, a per-CPU, per-pmap PCID is assigned when | |||||
Done Inline ActionsI think it could be written a bit clearer: "The PCID allocator maintains a per-CPU, per-pmap generation count pm_gen which is incremented each time a new PCID is allocated. markj: I think it could be written a bit clearer: "The PCID allocator maintains a per-CPU, per-pmap… | |||||
* the CPU is about to start caching TLB entries from a pmap, | |||||
Done Inline Actions"the generation counters for the pmap", since each pmap maintains a generation for each CPU. markj: "the generation counters for the pmap", since each pmap maintains a generation for each CPU. | |||||
* i.e., on the context switch that activates the pmap on the CPU. | |||||
Done Inline ActionsAdd comma, -> "i.e., ..." alc: Add comma, -> "i.e., ..." | |||||
* | |||||
Done Inline Actions"On invalidation" -> "On TLB invalidation" and "is" -> "are" alc: "On invalidation" -> "On TLB invalidation"
and
"is" -> "are" | |||||
* The PCID allocator maintains a per-CPU, per-pmap generation | |||||
Done Inline Actions"... that the previously allocated ..." alc: "... that the previously allocated ..." | |||||
* count, pm_gen, which is incremented each time a new PCID is | |||||
Done Inline Actions"... count, pm_gen, which is ... alc: "... count, pm_gen, which is ... | |||||
* allocated. On TLB invalidation, the generation counters for the | |||||
* pmap are zeroed, which signals the context switch code that the | |||||
Done Inline Actions"Consequently, if a pmap is inactive on a CPU, then a TLB shootdown for that pmap and CPU can be initiated by an ordinary memory access to reset the target CPU's generation count within the pmap. The CPU initiating the TLB shootdown does not need to send an IPI to the target CPU. alc: "Consequently, if a pmap is inactive on a CPU, then a TLB shootdown for that pmap and CPU can… | |||||
* previously allocated PCID is no longer valid. Effectively, | |||||
Done Inline Actions"... valid. Effectively, zeroing any of these counters triggers a TLB shootdown ... alc: "... valid. Effectively, zeroing any of these counters triggers a TLB shootdown ... | |||||
* zeroing any of these counters triggers a TLB shootdown for the | |||||
* given cpu/address space, due to the allocation of a new PCID. | |||||
Done Inline ActionsFor consistency, "user mode" alc: For consistency, "user mode" | |||||
Done Inline Actions"of a new ... alc: "of a new ... | |||||
Done Inline ActionsFor consistency, "cpu" -> "CPU" alc: For consistency, "cpu" -> "CPU" | |||||
* | |||||
Done Inline Actions"A user PCID ... alc: "A user PCID ... | |||||
* Zeroing can be performed remotely. Consequently, if a pmap is | |||||
Done Inline Actions"... bit, 11, to ... alc: "... bit, 11, to ... | |||||
* inactive on a CPU, then a TLB shootdown for that pmap and CPU can | |||||
* be initiated by an ordinary memory access to reset the target | |||||
Done Inline Actions"Userspace" -> "User space" alc: "Userspace" -> "User space"
and
"usermode" -> "user mode" | |||||
* CPU's generation count within the pmap. The CPU initiating the | |||||
* TLB shootdown does not need to send an IPI to the target CPU. | |||||
Done Inline Actions"... clearing bit 63 of the loaded ..." alc: "... clearing bit 63 of the loaded ..." | |||||
* | |||||
Done Inline Actions"usermode" -> "user mode" Also, can you clarify whether this is a "total invalidation" for one pmap or all pmaps on that CPU. alc: "usermode" -> "user mode"
Also, can you clarify whether this is a "total invalidation" for one… | |||||
* * PTI + PCID. The available PCIDs are divided into two sets: PCIDs | |||||
Done Inline Actions-> "... in the user ..." alc: -> "... in the user ..." | |||||
* for complete (kernel) page tables, and PCIDs for user mode page | |||||
* tables. A user PCID value is obtained from the kernel PCID value | |||||
* by setting the highest bit, 11, to 1 (0x800 == PMAP_PCID_USER_PT). | |||||
* | |||||
Done Inline ActionsINVTLB? alc: INVTLB? | |||||
* User space page tables are activated on return to user mode, by | |||||
* loading pm_ucr3 into %cr3. If the PCPU(ucr3_load_mask) requests | |||||
* clearing bit 63 of the loaded ucr3, this effectively causes | |||||
Done Inline Actions-> "If the INVPCID ... alc: -> "If the INVPCID ... | |||||
Done Inline ActionsDrop the first "the": "clearing bit 63 ... alc: Drop the first "the": "clearing bit 63 ... | |||||
* complete invalidation of the user mode TLB entries for the | |||||
Done Inline Actions-> "from the kernel page table. alc: -> "from the kernel page table. | |||||
Done Inline Actions-> "... TLB entries for ..." alc: -> "... TLB entries for ..." | |||||
* current pmap. In which case, local invalidations of individual | |||||
Done Inline ActionsCan we change "If ucr3_load_mask is set, then local ..." to "In which case, local ..."? alc: Can we change "If ucr3_load_mask is set, then local ..." to "In which case, local ..."? | |||||
* pages in the user page table are skipped. | |||||
Done Inline Actions-> "... The kernel reserves ... alc: -> "... The kernel reserves ... | |||||
* | |||||
Done Inline Actions"usermode" -> "user mode" alc: "usermode" -> "user mode"
| |||||
* * Local invalidation, all modes. If the requested invalidation is | |||||
Done Inline Actions-> "... A context switch allocates a new ... alc: -> "... A context switch allocates a new ... | |||||
* for a specific address or the total invalidation of a currently | |||||
Done Inline Actions-> "the recorded PCID is zero or the recorded generation does not match the CPU's alc: -> "the recorded PCID is zero or the recorded generation does not match the CPU's | |||||
Done Inline Actions"modes. If the requested invalidation is for a specific address or the total invalidation of a currently active pmap, then the TLB is flushed using INVLPG for a kernel page table, and ..." I feel like there is a missing qualifying phrase at the end of INVPCID(INVPCID_CTXGLOB)/invltlb_glob(). alc: "modes. If the requested invalidation is for a specific address or the total invalidation of a… | |||||
* active pmap, then the TLB is flushed using INVLPG for a kernel | |||||
Done Inline Actions-> "..., effectively flushing the TLB ... alc: -> "..., effectively flushing the TLB ... | |||||
* page table, and INVPCID(INVPCID_CTXGLOB)/invltlb_glob() for a | |||||
* user space page table(s). | |||||
Done Inline ActionsWe rarely use the word "process" in this comment. Can we say, "user space", instead? alc: We rarely use the word "process" in this comment. Can we say, "user space", instead? | |||||
* | |||||
* If the INVPCID instruction is available, it is used to flush entries | |||||
* from the kernel page table. | |||||
* | |||||
* * mode: PTI disabled, PCID present. The kernel reserves PCID 0 for its | |||||
* address space, all other 4095 PCIDs are used for user mode spaces | |||||
* as described above. A context switch allocates a new PCID if | |||||
* the recorded PCID is zero or the recorded generation does not match | |||||
* the CPU's generation, effectively flushing the TLB for this address space. | |||||
* Total remote invalidation is performed by zeroing pm_gen for all CPUs. | |||||
* local user page: INVLPG | |||||
* local kernel page: INVLPG | |||||
* local user total: INVPCID(CTX) | |||||
* local kernel total: INVPCID(CTXGLOB) or invltlb_glob() | |||||
Done Inline ActionsI think that all of the entries of this form would be clearer if written as "remote user page, inactive pmap:" Otherwise, it reads like the page must be inactive. alc: I think that all of the entries of this form would be clearer if written as "remote user page… | |||||
* remote user page, inactive pmap: zero pm_gen | |||||
* remote user page, active pmap: zero pm_gen + IPI:INVLPG | |||||
Done Inline ActionsHere is a technical question as opposed to one about wording: Given the IPI:INVLPG why is pm_gen zeroed? Is this because of aforementioned pm_active race? alc: Here is a technical question as opposed to one about wording: Given the IPI:INVLPG why is… | |||||
Done Inline ActionsYes, due to a possibility to lost the race and have the target pmap no longer active. I believe that the recent fix where pm_gen zeroing was misplaced and this caused observable issues proves the point. kib: Yes, due to a possibility to lost the race and have the target pmap no longer active.
I… | |||||
Done Inline ActionsThen, I would add a parenthetical comment on the next line: "(Both actions are required to handle the aforementioned pm_active races.)" alc: Then, I would add a parenthetical comment on the next line: "(Both actions are required to… | |||||
* (Both actions are required to handle the aforementioned pm_active races.) | |||||
* remote kernel page: IPI:INVLPG | |||||
* remote user total, inactive pmap: zero pm_gen | |||||
* remote user total, active pmap: zero pm_gen + IPI:(INVPCID(CTX) or | |||||
* reload %cr3) | |||||
* (See note above about pm_active races.) | |||||
* remote kernel total: IPI:(INVPCID(CTXGLOB) or invltlb_glob()) | |||||
* | |||||
* PTI enabled, PCID present. | |||||
* local user page: INVLPG for kpt, INVPCID(ADDR) or (INVLPG for ucr3) | |||||
* for upt | |||||
* local kernel page: INVLPG | |||||
* local user total: INVPCID(CTX) or reload %cr3 for kpt, clear PCID_SAVE | |||||
* on loading UCR3 into %cr3 for upt | |||||
* local kernel total: INVPCID(CTXGLOB) or invltlb_glob() | |||||
* remote user page, inactive pmap: zero pm_gen | |||||
* remote user page, active pmap: zero pm_gen + IPI:(INVLPG for kpt, | |||||
* INVPCID(ADDR) for upt) | |||||
* remote kernel page: IPI:INVLPG | |||||
* remote user total, inactive pmap: zero pm_gen | |||||
* remote user total, active pmap: zero pm_gen + IPI:(INVPCID(CTX) for kpt, | |||||
* clear PCID_SAVE on loading UCR3 into $cr3 for upt) | |||||
* remote kernel total: IPI:(INVPCID(CTXGLOB) or invltlb_glob()) | |||||
Done Inline Actions"usermode" -> "user mode" alc: "usermode" -> "user mode" | |||||
* | |||||
Done Inline Actions-> "... for the user page table. alc: -> "... for the user page table. | |||||
* No PCID. | |||||
* local user page: INVLPG | |||||
* local kernel page: INVLPG | |||||
* local user total: reload %cr3 | |||||
* local kernel total: invltlb_glob() | |||||
* remote user page, inactive pmap: - | |||||
* remote user page, active pmap: IPI:INVLPG | |||||
* remote kernel page: IPI:INVLPG | |||||
* remote user total, inactive pmap: - | |||||
* remote user total, active pmap: IPI:(reload %cr3) | |||||
* remote kernel total: IPI:invltlb_glob() | |||||
* Since on return to user mode, the reload of %cr3 with ucr3 causes | |||||
* TLB invalidation, no specific action is required for user page table. | |||||
* | |||||
Done Inline ActionsAre you planning to replace this? alc: Are you planning to replace this? | |||||
Done Inline ActionsNot in this change. I plan to write about generation, emulation of A/D. Might be mention different format of EPT tables. For SVM, something should be also noted. kib: Not in this change.
I plan to write about generation, emulation of A/D. Might be mention… | |||||
* EPT. EPT pmaps do not map KVA, all mappings are userspace. | |||||
* XXX TODO | |||||
Done Inline ActionsCalling it "a trick" begs the question, "a trick for what?" I would just define what it is here. In other words, say, "Under kernel ... KPTI) each user ..." alc: Calling it "a trick" begs the question, "a trick for what?" I would just define what it is… | |||||
*/ | */ | ||||
#ifdef SMP | |||||
/* | /* | ||||
* Interrupt the cpus that are executing in the guest context. | * Interrupt the cpus that are executing in the guest context. | ||||
* This will force the vcpu to exit and the cached EPT mappings | * This will force the vcpu to exit and the cached EPT mappings | ||||
* will be invalidated by the host before the next vmresume. | * will be invalidated by the host before the next vmresume. | ||||
*/ | */ | ||||
static __inline void | static __inline void | ||||
pmap_invalidate_ept(pmap_t pmap) | pmap_invalidate_ept(pmap_t pmap) | ||||
{ | { | ||||
▲ Show 20 Lines • Show All 8,712 Lines • Show Last 20 Lines |
I would qualify a bit more: "depending on the kernel configuration, and on available hardware features and known errata."