| 1824 | } |
| 1825 | |
| 1826 | static int |
| 1827 | vmx_emulate_cr0_access(struct vmx *vmx, int vcpu, uint64_t exitqual) |
| 1828 | { |
| 1829 | uint64_t crval, regval; |
| 1830 | |
| 1831 | /* We only handle mov to %cr0 at this time */ |
| 1832 | if ((exitqual & 0xf0) != 0x00) |
| 1833 | return (UNHANDLED); |
| 1834 | |
| 1835 | regval = vmx_get_guest_reg(vmx, vcpu, (exitqual >> 8) & 0xf); |
| 1836 | |
| 1837 | vmcs_write(VMCS_CR0_SHADOW, regval); |
| 1838 | |
| 1839 | crval = regval | cr0_ones_mask; |
| 1840 | crval &= ~cr0_zeros_mask; |
| 1841 | vmcs_write(VMCS_GUEST_CR0, crval); |
| 1842 | |
| 1843 | if (regval & CR0_PG) { |
| 1844 | uint64_t efer, entry_ctls; |
| 1845 | |
| 1846 | /* |
| 1847 | * If CR0.PG is 1 and EFER.LME is 1 then EFER.LMA and |
| 1848 | * the "IA-32e mode guest" bit in VM-entry control must be |
| 1849 | * equal. |
| 1850 | */ |
| 1851 | efer = vmcs_read(VMCS_GUEST_IA32_EFER); |
| 1852 | if (efer & EFER_LME) { |
| 1853 | efer |= EFER_LMA; |
| 1854 | vmcs_write(VMCS_GUEST_IA32_EFER, efer); |
| 1855 | entry_ctls = vmcs_read(VMCS_ENTRY_CTLS); |
| 1856 | entry_ctls |= VM_ENTRY_GUEST_LMA; |
| 1857 | vmcs_write(VMCS_ENTRY_CTLS, entry_ctls); |
| 1858 | } |
| 1859 | } |
| 1860 | |
| 1861 | return (HANDLED); |
| 1862 | } |
| 1863 | |
| 1864 | static int |
| 1865 | vmx_emulate_cr4_access(struct vmx *vmx, int vcpu, uint64_t exitqual) |
no test coverage detected