* Interrupt the cpus that are executing in the guest context. * This will force the vcpu to exit and the cached EPT mappings * will be invalidated by the host before the next vmresume. */
| 2850 | * will be invalidated by the host before the next vmresume. |
| 2851 | */ |
| 2852 | static __inline void |
| 2853 | pmap_invalidate_ept(pmap_t pmap) |
| 2854 | { |
| 2855 | smr_seq_t goal; |
| 2856 | int ipinum; |
| 2857 | |
| 2858 | sched_pin(); |
| 2859 | KASSERT(!CPU_ISSET(curcpu, &pmap->pm_active), |
| 2860 | ("pmap_invalidate_ept: absurd pm_active")); |
| 2861 | |
| 2862 | /* |
| 2863 | * The TLB mappings associated with a vcpu context are not |
| 2864 | * flushed each time a different vcpu is chosen to execute. |
| 2865 | * |
| 2866 | * This is in contrast with a process's vtop mappings that |
| 2867 | * are flushed from the TLB on each context switch. |
| 2868 | * |
| 2869 | * Therefore we need to do more than just a TLB shootdown on |
| 2870 | * the active cpus in 'pmap->pm_active'. To do this we keep |
| 2871 | * track of the number of invalidations performed on this pmap. |
| 2872 | * |
| 2873 | * Each vcpu keeps a cache of this counter and compares it |
| 2874 | * just before a vmresume. If the counter is out-of-date an |
| 2875 | * invept will be done to flush stale mappings from the TLB. |
| 2876 | * |
| 2877 | * To ensure that all vCPU threads have observed the new counter |
| 2878 | * value before returning, we use SMR. Ordering is important here: |
| 2879 | * the VMM enters an SMR read section before loading the counter |
| 2880 | * and after updating the pm_active bit set. Thus, pm_active is |
| 2881 | * a superset of active readers, and any reader that has observed |
| 2882 | * the goal has observed the new counter value. |
| 2883 | */ |
| 2884 | atomic_add_long(&pmap->pm_eptgen, 1); |
| 2885 | |
| 2886 | goal = smr_advance(pmap->pm_eptsmr); |
| 2887 | |
| 2888 | /* |
| 2889 | * Force the vcpu to exit and trap back into the hypervisor. |
| 2890 | */ |
| 2891 | ipinum = pmap->pm_flags & PMAP_NESTED_IPIMASK; |
| 2892 | ipi_selected(pmap->pm_active, ipinum); |
| 2893 | sched_unpin(); |
| 2894 | |
| 2895 | /* |
| 2896 | * Ensure that all active vCPUs will observe the new generation counter |
| 2897 | * value before executing any more guest instructions. |
| 2898 | */ |
| 2899 | smr_wait(pmap->pm_eptsmr, goal); |
| 2900 | } |
| 2901 | |
| 2902 | static cpuset_t |
| 2903 | pmap_invalidate_cpu_mask(pmap_t pmap) |
no test coverage detected