| 1802 | } |
| 1803 | |
| 1804 | static void |
| 1805 | svm_pmap_activate(struct svm_softc *sc, int vcpuid, pmap_t pmap) |
| 1806 | { |
| 1807 | struct svm_vcpu *vcpustate; |
| 1808 | struct vmcb_ctrl *ctrl; |
| 1809 | long eptgen; |
| 1810 | int cpu; |
| 1811 | bool alloc_asid; |
| 1812 | |
| 1813 | cpu = curcpu; |
| 1814 | CPU_SET_ATOMIC(cpu, &pmap->pm_active); |
| 1815 | smr_enter(pmap->pm_eptsmr); |
| 1816 | |
| 1817 | vcpustate = svm_get_vcpu(sc, vcpuid); |
| 1818 | ctrl = svm_get_vmcb_ctrl(sc, vcpuid); |
| 1819 | |
| 1820 | /* |
| 1821 | * The TLB entries associated with the vcpu's ASID are not valid |
| 1822 | * if either of the following conditions is true: |
| 1823 | * |
| 1824 | * 1. The vcpu's ASID generation is different than the host cpu's |
| 1825 | * ASID generation. This happens when the vcpu migrates to a new |
| 1826 | * host cpu. It can also happen when the number of vcpus executing |
| 1827 | * on a host cpu is greater than the number of ASIDs available. |
| 1828 | * |
| 1829 | * 2. The pmap generation number is different than the value cached in |
| 1830 | * the 'vcpustate'. This happens when the host invalidates pages |
| 1831 | * belonging to the guest. |
| 1832 | * |
| 1833 | * asidgen eptgen Action |
| 1834 | * mismatch mismatch |
| 1835 | * 0 0 (a) |
| 1836 | * 0 1 (b1) or (b2) |
| 1837 | * 1 0 (c) |
| 1838 | * 1 1 (d) |
| 1839 | * |
| 1840 | * (a) There is no mismatch in eptgen or ASID generation and therefore |
| 1841 | * no further action is needed. |
| 1842 | * |
| 1843 | * (b1) If the cpu supports FlushByAsid then the vcpu's ASID is |
| 1844 | * retained and the TLB entries associated with this ASID |
| 1845 | * are flushed by VMRUN. |
| 1846 | * |
| 1847 | * (b2) If the cpu does not support FlushByAsid then a new ASID is |
| 1848 | * allocated. |
| 1849 | * |
| 1850 | * (c) A new ASID is allocated. |
| 1851 | * |
| 1852 | * (d) A new ASID is allocated. |
| 1853 | */ |
| 1854 | |
| 1855 | alloc_asid = false; |
| 1856 | eptgen = atomic_load_long(&pmap->pm_eptgen); |
| 1857 | ctrl->tlb_ctrl = VMCB_TLB_FLUSH_NOTHING; |
| 1858 | |
| 1859 | if (vcpustate->asid.gen != asid[cpu].gen) { |
| 1860 | alloc_asid = true; /* (c) and (d) */ |
| 1861 | } else if (vcpustate->eptgen != eptgen) { |
no test coverage detected