hv: vmexit: refine xsetbv_vmexit_handler API

From SDM Vol.2C - XSETBV instruction description,
If CR4.OSXSAVE[bit 18] = 0,
execute "XSETBV" instruction will generate #UD exception.

From SDM Vol.3C 25.1.1,#UD exception has priority over VM exits,
So if vCPU execute "XSETBV" instruction when CR4.OSXSAVE[bit 18] = 0,
VM exits won't happen.

While hv inject #GP if vCPU execute "XSETBV" instruction
when CR4.OSXSAVE[bit 18] = 0.
It's a wrong behavior, this patch will fix the bug.

Tracked-On: #4020

Signed-off-by: Junming Liu <junming.liu@intel.com>
Acked-by: Eddie Dong <eddie.dong@intel.com>
This commit is contained in:
Junming Liu 2020-11-25 04:49:33 +08:00 committed by wenlingz
parent 2767eb0d29
commit 56eb859ea4

View File

@ -322,6 +322,13 @@ int32_t cpuid_vmexit_handler(struct acrn_vcpu *vcpu)
* virtual-8086 mode previleged instructions are not recognized) have higher
* priority than VM exit.
*
* According to SDM vol2 - XSETBV instruction description:
* If CR4.OSXSAVE[bit 18] = 0,
* execute "XSETBV" instruction will generate #UD exception.
* So VM exit won't happen with VMX_GUEST_CR4.CR4_OSXSAVE = 0.
* CR4_OSXSAVE bit is controlled by guest (CR4_OSXSAVE bit
* is set as guest expect to see).
*
* We don't need to handle those case here because we depends on VMX to handle
* them.
*/
@ -331,10 +338,6 @@ static int32_t xsetbv_vmexit_handler(struct acrn_vcpu *vcpu)
uint64_t val64;
int32_t ret = 0;
val64 = exec_vmread(VMX_GUEST_CR4);
if ((val64 & CR4_OSXSAVE) == 0UL) {
vcpu_inject_gp(vcpu, 0U);
} else {
idx = vcpu->arch.cur_context;
if (idx >= NR_WORLD) {
ret = -1;
@ -373,7 +376,6 @@ static int32_t xsetbv_vmexit_handler(struct acrn_vcpu *vcpu)
}
}
}
}
return ret;
}