void vmx_set_cr0(struct kvm_vcpu *vcpu, unsigned long cr0)
{
	struct vcpu_vmx *vmx = to_vmx(vcpu);
	unsigned long hw_cr0, old_cr0_pg;
	u32 tmp;

	old_cr0_pg = kvm_read_cr0_bits(vcpu, X86_CR0_PG);

	hw_cr0 = (cr0 & ~KVM_VM_CR0_ALWAYS_OFF);
	if (is_unrestricted_guest(vcpu))
		hw_cr0 |= KVM_VM_CR0_ALWAYS_ON_UNRESTRICTED_GUEST;
	else {
		hw_cr0 |= KVM_VM_CR0_ALWAYS_ON;
		if (!enable_ept)
			hw_cr0 |= X86_CR0_WP;

		if (vmx->rmode.vm86_active && (cr0 & X86_CR0_PE))
			enter_pmode(vcpu);

		if (!vmx->rmode.vm86_active && !(cr0 & X86_CR0_PE))
			enter_rmode(vcpu);
	}

	vmcs_writel(CR0_READ_SHADOW, cr0);
	vmcs_writel(GUEST_CR0, hw_cr0);
	vcpu->arch.cr0 = cr0;
	kvm_register_mark_available(vcpu, VCPU_EXREG_CR0);

#ifdef CONFIG_X86_64
	if (vcpu->arch.efer & EFER_LME) {
		if (!old_cr0_pg && (cr0 & X86_CR0_PG))
			enter_lmode(vcpu);
		else if (old_cr0_pg && !(cr0 & X86_CR0_PG))
			exit_lmode(vcpu);
	}
#endif

	if (enable_ept && !is_unrestricted_guest(vcpu)) {
		/*
		 * Ensure KVM has an up-to-date snapshot of the guest's CR3.  If
		 * the below code _enables_ CR3 exiting, vmx_cache_reg() will
		 * (correctly) stop reading vmcs.GUEST_CR3 because it thinks
		 * KVM's CR3 is installed.
		 */
		if (!kvm_register_is_available(vcpu, VCPU_EXREG_CR3))
			vmx_cache_reg(vcpu, VCPU_EXREG_CR3);

		/*
		 * When running with EPT but not unrestricted guest, KVM must
		 * intercept CR3 accesses when paging is _disabled_.  This is
		 * necessary because restricted guests can't actually run with
		 * paging disabled, and so KVM stuffs its own CR3 in order to
		 * run the guest when identity mapped page tables.
		 *
		 * Do _NOT_ check the old CR0.PG, e.g. to optimize away the
		 * update, it may be stale with respect to CR3 interception,
		 * e.g. after nested VM-Enter.
		 *
		 * Lastly, honor L1's desires, i.e. intercept CR3 loads and/or
		 * stores to forward them to L1, even if KVM does not need to
		 * intercept them to preserve its identity mapped page tables.
		 */
		if (!(cr0 & X86_CR0_PG)) {
			exec_controls_setbit(vmx, CR3_EXITING_BITS);
		} else if (!is_guest_mode(vcpu)) {
			exec_controls_clearbit(vmx, CR3_EXITING_BITS);
		} else {
			tmp = exec_controls_get(vmx);
			tmp &= ~CR3_EXITING_BITS;
			tmp |= get_vmcs12(vcpu)->cpu_based_vm_exec_control & CR3_EXITING_BITS;
			exec_controls_set(vmx, tmp);
		}

		/* Note, vmx_set_cr4() consumes the new vcpu->arch.cr0. */
		if ((old_cr0_pg ^ cr0) & X86_CR0_PG)
			vmx_set_cr4(vcpu, kvm_read_cr4(vcpu));

		/*
		 * When !CR0_PG -> CR0_PG, vcpu->arch.cr3 becomes active, but
		 * GUEST_CR3 is still vmx->ept_identity_map_addr if EPT + !URG.
		 */
		if (!(old_cr0_pg & X86_CR0_PG) && (cr0 & X86_CR0_PG))
			kvm_register_mark_dirty(vcpu, VCPU_EXREG_CR3);
	}

	/* depends on vcpu->arch.cr0 to be set to a new value */
	vmx->emulation_required = vmx_emulation_required(vcpu);
}
void vmx_set_cr0(struct kvm_vcpu *vcpu, unsigned long cr0)
{
	struct vcpu_vmx *vmx = to_vmx(vcpu);
	unsigned long hw_cr0, old_cr0_pg;
	u32 tmp;

	old_cr0_pg = kvm_read_cr0_bits(vcpu, X86_CR0_PG);

	hw_cr0 = (cr0 & ~KVM_VM_CR0_ALWAYS_OFF);
	if (is_unrestricted_guest(vcpu))
		hw_cr0 |= KVM_VM_CR0_ALWAYS_ON_UNRESTRICTED_GUEST;
	else {
		hw_cr0 |= KVM_VM_CR0_ALWAYS_ON;
		if (!enable_ept)
			hw_cr0 |= X86_CR0_WP;

		if (vmx->rmode.vm86_active && (cr0 & X86_CR0_PE))
			enter_pmode(vcpu);

		if (!vmx->rmode.vm86_active && !(cr0 & X86_CR0_PE))
			enter_rmode(vcpu);
	}

	vmcs_writel(CR0_READ_SHADOW, cr0);
	vmcs_writel(GUEST_CR0, hw_cr0);
	vcpu->arch.cr0 = cr0;
	kvm_register_mark_available(vcpu, VCPU_EXREG_CR0);

#ifdef CONFIG_X86_64
	if (vcpu->arch.efer & EFER_LME) {
		if (!old_cr0_pg && (cr0 & X86_CR0_PG))
			enter_lmode(vcpu);
		else if (old_cr0_pg && !(cr0 & X86_CR0_PG))
			exit_lmode(vcpu);
	}
#endif

	if (enable_ept && !is_unrestricted_guest(vcpu)) {
		 
		if (!kvm_register_is_available(vcpu, VCPU_EXREG_CR3))
			vmx_cache_reg(vcpu, VCPU_EXREG_CR3);

		 
		if (!(cr0 & X86_CR0_PG)) {
			exec_controls_setbit(vmx, CR3_EXITING_BITS);
		} else if (!is_guest_mode(vcpu)) {
			exec_controls_clearbit(vmx, CR3_EXITING_BITS);
		} else {
			tmp = exec_controls_get(vmx);
			tmp &= ~CR3_EXITING_BITS;
			tmp |= get_vmcs12(vcpu)->cpu_based_vm_exec_control & CR3_EXITING_BITS;
			exec_controls_set(vmx, tmp);
		}

		 
		if ((old_cr0_pg ^ cr0) & X86_CR0_PG)
			vmx_set_cr4(vcpu, kvm_read_cr4(vcpu));

		 
		if (!(old_cr0_pg & X86_CR0_PG) && (cr0 & X86_CR0_PG))
			kvm_register_mark_dirty(vcpu, VCPU_EXREG_CR3);
	}

	 
	vmx->emulation_required = vmx_emulation_required(vcpu);
}