Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 4c2161ae authored by Joerg Roedel's avatar Joerg Roedel Committed by Avi Kivity
Browse files

KVM: SVM: consolidate nested_svm_exit_handled



When caching guest intercepts there is no need anymore for the
nested_svm_exit_handled_real function. So move its code into
nested_svm_exit_handled.

Signed-off-by: default avatarJoerg Roedel <joerg.roedel@amd.com>
Acked-by: default avatarAlexander Graf <agraf@suse.de>
Signed-off-by: default avatarAvi Kivity <avi@redhat.com>
parent aad42c64
Loading
Loading
Loading
Loading
+49 −60
Original line number Diff line number Diff line
@@ -1456,15 +1456,58 @@ static int nested_svm_do(struct vcpu_svm *svm,
	return retval;
}

static int nested_svm_exit_handled_real(struct vcpu_svm *svm,
					void *arg1,
					void *arg2,
static int nested_svm_exit_handled_msr(struct vcpu_svm *svm,
				       void *arg1, void *arg2,
				       void *opaque)
{
	bool kvm_overrides = *(bool *)opaque;
	struct vmcb *nested_vmcb = (struct vmcb *)arg1;
	u8 *msrpm = (u8 *)arg2;
	u32 t0, t1;
	u32 msr = svm->vcpu.arch.regs[VCPU_REGS_RCX];
	u32 param = svm->vmcb->control.exit_info_1 & 1;

	if (!(nested_vmcb->control.intercept & (1ULL << INTERCEPT_MSR_PROT)))
		return 0;

	switch (msr) {
	case 0 ... 0x1fff:
		t0 = (msr * 2) % 8;
		t1 = msr / 8;
		break;
	case 0xc0000000 ... 0xc0001fff:
		t0 = (8192 + msr - 0xc0000000) * 2;
		t1 = (t0 / 8);
		t0 %= 8;
		break;
	case 0xc0010000 ... 0xc0011fff:
		t0 = (16384 + msr - 0xc0010000) * 2;
		t1 = (t0 / 8);
		t0 %= 8;
		break;
	default:
		return 1;
		break;
	}
	if (msrpm[t1] & ((1 << param) << t0))
		return 1;

	return 0;
}

static int nested_svm_exit_handled(struct vcpu_svm *svm, bool kvm_override)
{
	u32 exit_code = svm->vmcb->control.exit_code;

	if (kvm_overrides) {
	switch (svm->vmcb->control.exit_code) {
	case SVM_EXIT_MSR:
		return nested_svm_do(svm, svm->nested.vmcb,
				     svm->nested.vmcb_msrpm, NULL,
				     nested_svm_exit_handled_msr);
	default:
		break;
	}

	if (kvm_override) {
		switch (exit_code) {
		case SVM_EXIT_INTR:
		case SVM_EXIT_NMI:
@@ -1526,60 +1569,6 @@ static int nested_svm_exit_handled_real(struct vcpu_svm *svm,
	return 0;
}

static int nested_svm_exit_handled_msr(struct vcpu_svm *svm,
				       void *arg1, void *arg2,
				       void *opaque)
{
	struct vmcb *nested_vmcb = (struct vmcb *)arg1;
	u8 *msrpm = (u8 *)arg2;
        u32 t0, t1;
	u32 msr = svm->vcpu.arch.regs[VCPU_REGS_RCX];
	u32 param = svm->vmcb->control.exit_info_1 & 1;

	if (!(nested_vmcb->control.intercept & (1ULL << INTERCEPT_MSR_PROT)))
		return 0;

	switch(msr) {
	case 0 ... 0x1fff:
		t0 = (msr * 2) % 8;
		t1 = msr / 8;
		break;
	case 0xc0000000 ... 0xc0001fff:
		t0 = (8192 + msr - 0xc0000000) * 2;
		t1 = (t0 / 8);
		t0 %= 8;
		break;
	case 0xc0010000 ... 0xc0011fff:
		t0 = (16384 + msr - 0xc0010000) * 2;
		t1 = (t0 / 8);
		t0 %= 8;
		break;
	default:
		return 1;
		break;
	}
	if (msrpm[t1] & ((1 << param) << t0))
		return 1;

	return 0;
}

static int nested_svm_exit_handled(struct vcpu_svm *svm, bool kvm_override)
{
	bool k = kvm_override;

	switch (svm->vmcb->control.exit_code) {
	case SVM_EXIT_MSR:
		return nested_svm_do(svm, svm->nested.vmcb,
				     svm->nested.vmcb_msrpm, NULL,
				     nested_svm_exit_handled_msr);
	default: break;
	}

	return nested_svm_do(svm, svm->nested.vmcb, 0, &k,
			     nested_svm_exit_handled_real);
}

static inline void copy_vmcb_control_area(struct vmcb *dst_vmcb, struct vmcb *from_vmcb)
{
	struct vmcb_control_area *dst  = &dst_vmcb->control;