hypervisor/arch/x86/guest/vmexit.c
static int32_t xsetbv_vmexit_handler(struct acrn_vcpu *vcpu)
{
	int32_t idx;
	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;
		} else {
			/* to access XCR0,'ecx' should be 0 */
			if ((vcpu_get_gpreg(vcpu, CPU_REG_RCX) & 0xffffffffUL) != 0UL) {
				vcpu_inject_gp(vcpu, 0U);
			} else {
				val64 = (vcpu_get_gpreg(vcpu, CPU_REG_RAX) & 0xffffffffUL) |
						(vcpu_get_gpreg(vcpu, CPU_REG_RDX) << 32U);

				/* bit 0(x87 state) of XCR0 can't be cleared */
				if ((val64 & 0x01UL) == 0UL) {
					vcpu_inject_gp(vcpu, 0U);
				} else if ((val64 & XCR0_RESERVED_BITS) != 0UL) {
					vcpu_inject_gp(vcpu, 0U);
				} else {
					/*
					 * XCR0[2:1] (SSE state & AVX state) can't not be
					 * set to 10b as it is necessary to set both bits
					 * to use AVX instructions.
					 */
					if ((val64 & (XCR0_SSE | XCR0_AVX)) == XCR0_AVX) {
						vcpu_inject_gp(vcpu, 0U);
					} else {
						/*
						 * SDM Vol.1 13-4, XCR0[4:3] are associated with MPX state,
						 * Guest should not set these two bits without MPX support.
						 */
						if ((val64 & (XCR0_BNDREGS | XCR0_BNDCSR)) != 0UL) {
							vcpu_inject_gp(vcpu, 0U);
						} else {
							write_xcr(0, val64);
						}
					}
				}
			}
		}
	}

	return ret;
}
/*
 * XSETBV instruction set's the XCR0 that is used to tell for which
 * components states can be saved on a context switch using xsave.
 *
 * According to SDM vol3 25.1.1:
 * Invalid-opcode exception (UD) and faults based on privilege level (include
 * virtual-8086 mode previleged instructions are not recognized) have higher
 * priority than VM exit.
 *
 * We don't need to handle those case here because we depends on VMX to handle
 * them.
 */
XSETBV instruction set's the XCR0 that is used to tell for which
components states can be saved on a context switch using xsave.

According to SDM vol3 25.1.1:
Invalid-opcode exception (UD) and faults based on privilege level (include
virtual-8086 mode previleged instructions are not recognized) have higher
priority than VM exit.

We don't need to handle those case here because we depends on VMX to handle
them.
XSETBV instruction set ' s the XCR0 that is used to tell for which components states can be saved on a context switch using xsave . According to SDM vol3 25 . 1 . 1 : Invalid - opcode exception ( UD ) and faults based on privilege level ( include virtual - 8086 mode previleged instructions are not recognized ) have higher priority than VM exit . We don ' t need to handle those case here because we depends on VMX to handle them .
static int32_t xsetbv_vmexit_handler(struct acrn_vcpu *vcpu)
{
	int32_t idx;
	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;
		} else {
			if ((vcpu_get_gpreg(vcpu, CPU_REG_RCX) & 0xffffffffUL) != 0UL) {
				vcpu_inject_gp(vcpu, 0U);
			} else {
				val64 = (vcpu_get_gpreg(vcpu, CPU_REG_RAX) & 0xffffffffUL) |
						(vcpu_get_gpreg(vcpu, CPU_REG_RDX) << 32U);
				if ((val64 & 0x01UL) == 0UL) {
					vcpu_inject_gp(vcpu, 0U);
				} else if ((val64 & XCR0_RESERVED_BITS) != 0UL) {
					vcpu_inject_gp(vcpu, 0U);
				} else {
					if ((val64 & (XCR0_SSE | XCR0_AVX)) == XCR0_AVX) {
						vcpu_inject_gp(vcpu, 0U);
					} else {
						if ((val64 & (XCR0_BNDREGS | XCR0_BNDCSR)) != 0UL) {
							vcpu_inject_gp(vcpu, 0U);
						} else {
							write_xcr(0, val64);
						}
					}
				}
			}
		}
	}
	return ret;
}
static int32_t xsetbv_vmexit_handler ( struct acrn_vcpu * vcpu ) { int32_t idx ; 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 ; } else { if ( ( vcpu_get_gpreg ( vcpu , CPU_REG_RCX ) & 0xffffffffUL ) != 0UL ) { vcpu_inject_gp ( vcpu , 0U ) ; } else { val64 = ( vcpu_get_gpreg ( vcpu , CPU_REG_RAX ) & 0xffffffffUL ) | ( vcpu_get_gpreg ( vcpu , CPU_REG_RDX ) << 32U ) ; if ( ( val64 & 0x01UL ) == 0UL ) { vcpu_inject_gp ( vcpu , 0U ) ; } else if ( ( val64 & XCR0_RESERVED_BITS ) != 0UL ) { vcpu_inject_gp ( vcpu , 0U ) ; } else { if ( ( val64 & ( XCR0_SSE | XCR0_AVX ) ) == XCR0_AVX ) { vcpu_inject_gp ( vcpu , 0U ) ; } else { if ( ( val64 & ( XCR0_BNDREGS | XCR0_BNDCSR ) ) != 0UL ) { vcpu_inject_gp ( vcpu , 0U ) ; } else { write_xcr ( 0 , val64 ) ; } } } } } } return ret ; }
XSETBV instruction set's the XCR0 that is used to tell for which
 components states can be saved on a context switch using xsave.
XSETBV instruction set ' s the XCR0 that is used to tell for which components states can be saved on a context switch using xsave .
/* to access XCR0,'ecx' should be 0 */ /* bit 0(x87 state) of XCR0 can't be cleared */ /*
					 * XCR0[2:1] (SSE state & AVX state) can't not be
					 * set to 10b as it is necessary to set both bits
					 * to use AVX instructions.
					 */ /*
						 * SDM Vol.1 13-4, XCR0[4:3] are associated with MPX state,
						 * Guest should not set these two bits without MPX support.
						 */