static int cr_trap(struct kvm_vcpu *vcpu)
{
	struct vcpu_svm *svm = to_svm(vcpu);
	unsigned long old_value, new_value;
	unsigned int cr;
	int ret = 0;

	new_value = (unsigned long)svm->vmcb->control.exit_info_1;

	cr = svm->vmcb->control.exit_code - SVM_EXIT_CR0_WRITE_TRAP;
	switch (cr) {
	case 0:
		old_value = kvm_read_cr0(vcpu);
		svm_set_cr0(vcpu, new_value);

		kvm_post_set_cr0(vcpu, old_value, new_value);
		break;
	case 4:
		old_value = kvm_read_cr4(vcpu);
		svm_set_cr4(vcpu, new_value);

		kvm_post_set_cr4(vcpu, old_value, new_value);
		break;
	case 8:
		ret = kvm_set_cr8(vcpu, new_value);
		break;
	default:
		WARN(1, "unhandled CR%d write trap", cr);
		kvm_queue_exception(vcpu, UD_VECTOR);
		return 1;
	}

	return kvm_complete_insn_gp(vcpu, ret);
}
static int cr_trap(struct kvm_vcpu *vcpu)
{
	struct vcpu_svm *svm = to_svm(vcpu);
	unsigned long old_value, new_value;
	unsigned int cr;
	int ret = 0;

	new_value = (unsigned long)svm->vmcb->control.exit_info_1;

	cr = svm->vmcb->control.exit_code - SVM_EXIT_CR0_WRITE_TRAP;
	switch (cr) {
	case 0:
		old_value = kvm_read_cr0(vcpu);
		svm_set_cr0(vcpu, new_value);

		kvm_post_set_cr0(vcpu, old_value, new_value);
		break;
	case 4:
		old_value = kvm_read_cr4(vcpu);
		svm_set_cr4(vcpu, new_value);

		kvm_post_set_cr4(vcpu, old_value, new_value);
		break;
	case 8:
		ret = kvm_set_cr8(vcpu, new_value);
		break;
	default:
		WARN(1, "unhandled CR%d write trap", cr);
		kvm_queue_exception(vcpu, UD_VECTOR);
		return 1;
	}

	return kvm_complete_insn_gp(vcpu, ret);
}