mirror of
https://git.FreeBSD.org/src.git
synced 2024-12-24 11:29:10 +00:00
Follow-up commit to fix CR0 issues. Maintain
architectural state on CR vmexits by guaranteeing that EFER, CR0 and the VMCS entry controls are all in sync when transitioning to IA-32e mode. Submitted by: Tycho Nightingale (tycho.nightingale <at> plurisbusnetworks.com)
This commit is contained in:
parent
1e53269ac2
commit
80a902ef7d
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=253909
@ -1084,7 +1084,7 @@ static int
|
||||
vmx_emulate_cr_access(struct vmx *vmx, int vcpu, uint64_t exitqual)
|
||||
{
|
||||
int error, cr, vmcs_guest_cr, vmcs_shadow_cr;
|
||||
uint64_t regval, ones_mask, zeros_mask;
|
||||
uint64_t crval, regval, ones_mask, zeros_mask;
|
||||
const struct vmxctx *vmxctx;
|
||||
|
||||
/* We only handle mov to %cr0 or %cr4 at this time */
|
||||
@ -1174,14 +1174,48 @@ vmx_emulate_cr_access(struct vmx *vmx, int vcpu, uint64_t exitqual)
|
||||
error, cr);
|
||||
}
|
||||
|
||||
regval |= ones_mask;
|
||||
regval &= ~zeros_mask;
|
||||
error = vmwrite(vmcs_guest_cr, regval);
|
||||
crval = regval | ones_mask;
|
||||
crval &= ~zeros_mask;
|
||||
error = vmwrite(vmcs_guest_cr, crval);
|
||||
if (error) {
|
||||
panic("vmx_emulate_cr_access: error %d writing cr%d",
|
||||
error, cr);
|
||||
}
|
||||
|
||||
if (cr == 0 && regval & CR0_PG) {
|
||||
uint64_t efer, entry_ctls;
|
||||
|
||||
/*
|
||||
* If CR0.PG is 1 and EFER.LME is 1 then EFER.LMA and
|
||||
* the "IA-32e mode guest" bit in VM-entry control must be
|
||||
* equal.
|
||||
*/
|
||||
error = vmread(VMCS_GUEST_IA32_EFER, &efer);
|
||||
if (error) {
|
||||
panic("vmx_emulate_cr_access: error %d efer read",
|
||||
error);
|
||||
}
|
||||
if (efer & EFER_LME) {
|
||||
efer |= EFER_LMA;
|
||||
error = vmwrite(VMCS_GUEST_IA32_EFER, efer);
|
||||
if (error) {
|
||||
panic("vmx_emulate_cr_access: error %d"
|
||||
" efer write", error);
|
||||
}
|
||||
error = vmread(VMCS_ENTRY_CTLS, &entry_ctls);
|
||||
if (error) {
|
||||
panic("vmx_emulate_cr_access: error %d"
|
||||
" entry ctls read", error);
|
||||
}
|
||||
entry_ctls |= VM_ENTRY_GUEST_LMA;
|
||||
error = vmwrite(VMCS_ENTRY_CTLS, entry_ctls);
|
||||
if (error) {
|
||||
panic("vmx_emulate_cr_access: error %d"
|
||||
" entry ctls write", error);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return (HANDLED);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user