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

Commit 3bab1f5d authored by Avi Kivity's avatar Avi Kivity Committed by Linus Torvalds
Browse files

[PATCH] KVM: Move common msr handling to arch independent code



Signed-off-by: default avatarAvi Kivity <avi@qumranet.com>
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent 671d6564
Loading
Loading
Loading
Loading
+2 −3
Original line number Original line Diff line number Diff line
@@ -374,9 +374,8 @@ void set_cr4(struct kvm_vcpu *vcpu, unsigned long cr0);
void set_cr8(struct kvm_vcpu *vcpu, unsigned long cr0);
void set_cr8(struct kvm_vcpu *vcpu, unsigned long cr0);
void lmsw(struct kvm_vcpu *vcpu, unsigned long msw);
void lmsw(struct kvm_vcpu *vcpu, unsigned long msw);


#ifdef CONFIG_X86_64
int kvm_get_msr_common(struct kvm_vcpu *vcpu, u32 msr, u64 *pdata);
void set_efer(struct kvm_vcpu *vcpu, u64 efer);
int kvm_set_msr_common(struct kvm_vcpu *vcpu, u32 msr, u64 data);
#endif


void fx_init(struct kvm_vcpu *vcpu);
void fx_init(struct kvm_vcpu *vcpu);


+69 −2
Original line number Original line Diff line number Diff line
@@ -1103,6 +1103,47 @@ void realmode_set_cr(struct kvm_vcpu *vcpu, int cr, unsigned long val,
	}
	}
}
}


int kvm_get_msr_common(struct kvm_vcpu *vcpu, u32 msr, u64 *pdata)
{
	u64 data;

	switch (msr) {
	case 0xc0010010: /* SYSCFG */
	case 0xc0010015: /* HWCR */
	case MSR_IA32_PLATFORM_ID:
	case MSR_IA32_P5_MC_ADDR:
	case MSR_IA32_P5_MC_TYPE:
	case MSR_IA32_MC0_CTL:
	case MSR_IA32_MCG_STATUS:
	case MSR_IA32_MCG_CAP:
	case MSR_IA32_MC0_MISC:
	case MSR_IA32_MC0_MISC+4:
	case MSR_IA32_MC0_MISC+8:
	case MSR_IA32_MC0_MISC+12:
	case MSR_IA32_MC0_MISC+16:
	case MSR_IA32_UCODE_REV:
		/* MTRR registers */
	case 0xfe:
	case 0x200 ... 0x2ff:
		data = 0;
		break;
	case MSR_IA32_APICBASE:
		data = vcpu->apic_base;
		break;
#ifdef CONFIG_X86_64
	case MSR_EFER:
		data = vcpu->shadow_efer;
		break;
#endif
	default:
		printk(KERN_ERR "kvm: unhandled rdmsr: 0x%x\n", msr);
		return 1;
	}
	*pdata = data;
	return 0;
}
EXPORT_SYMBOL_GPL(kvm_get_msr_common);

/*
/*
 * Reads an msr value (of 'msr_index') into 'pdata'.
 * Reads an msr value (of 'msr_index') into 'pdata'.
 * Returns 0 on success, non-0 otherwise.
 * Returns 0 on success, non-0 otherwise.
@@ -1115,7 +1156,7 @@ static int get_msr(struct kvm_vcpu *vcpu, u32 msr_index, u64 *pdata)


#ifdef CONFIG_X86_64
#ifdef CONFIG_X86_64


void set_efer(struct kvm_vcpu *vcpu, u64 efer)
static void set_efer(struct kvm_vcpu *vcpu, u64 efer)
{
{
	if (efer & EFER_RESERVED_BITS) {
	if (efer & EFER_RESERVED_BITS) {
		printk(KERN_DEBUG "set_efer: 0x%llx #GP, reserved bits\n",
		printk(KERN_DEBUG "set_efer: 0x%llx #GP, reserved bits\n",
@@ -1138,10 +1179,36 @@ void set_efer(struct kvm_vcpu *vcpu, u64 efer)


	vcpu->shadow_efer = efer;
	vcpu->shadow_efer = efer;
}
}
EXPORT_SYMBOL_GPL(set_efer);


#endif
#endif


int kvm_set_msr_common(struct kvm_vcpu *vcpu, u32 msr, u64 data)
{
	switch (msr) {
#ifdef CONFIG_X86_64
	case MSR_EFER:
		set_efer(vcpu, data);
		break;
#endif
	case MSR_IA32_MC0_STATUS:
		printk(KERN_WARNING "%s: MSR_IA32_MC0_STATUS 0x%llx, nop\n",
		       __FUNCTION__, data);
		break;
	case MSR_IA32_UCODE_REV:
	case MSR_IA32_UCODE_WRITE:
	case 0x200 ... 0x2ff: /* MTRRs */
		break;
	case MSR_IA32_APICBASE:
		vcpu->apic_base = data;
		break;
	default:
		printk(KERN_ERR "kvm: unhandled wrmsr: 0x%x\n", msr);
		return 1;
	}
	return 0;
}
EXPORT_SYMBOL_GPL(kvm_set_msr_common);

/*
/*
 * Writes msr value into into the appropriate "register".
 * Writes msr value into into the appropriate "register".
 * Returns 0 on success, non-0 otherwise.
 * Returns 0 on success, non-0 otherwise.
+2 −45
Original line number Original line Diff line number Diff line
@@ -1068,25 +1068,6 @@ static int emulate_on_interception(struct kvm_vcpu *vcpu, struct kvm_run *kvm_ru
static int svm_get_msr(struct kvm_vcpu *vcpu, unsigned ecx, u64 *data)
static int svm_get_msr(struct kvm_vcpu *vcpu, unsigned ecx, u64 *data)
{
{
	switch (ecx) {
	switch (ecx) {
	case 0xc0010010: /* SYSCFG */
	case 0xc0010015: /* HWCR */
	case MSR_IA32_PLATFORM_ID:
	case MSR_IA32_P5_MC_ADDR:
	case MSR_IA32_P5_MC_TYPE:
	case MSR_IA32_MC0_CTL:
	case MSR_IA32_MCG_STATUS:
	case MSR_IA32_MCG_CAP:
	case MSR_IA32_MC0_MISC:
	case MSR_IA32_MC0_MISC+4:
	case MSR_IA32_MC0_MISC+8:
	case MSR_IA32_MC0_MISC+12:
	case MSR_IA32_MC0_MISC+16:
	case MSR_IA32_UCODE_REV:
		/* MTRR registers */
	case 0xfe:
	case 0x200 ... 0x2ff:
		*data = 0;
		break;
	case MSR_IA32_TIME_STAMP_COUNTER: {
	case MSR_IA32_TIME_STAMP_COUNTER: {
		u64 tsc;
		u64 tsc;


@@ -1094,12 +1075,6 @@ static int svm_get_msr(struct kvm_vcpu *vcpu, unsigned ecx, u64 *data)
		*data = vcpu->svm->vmcb->control.tsc_offset + tsc;
		*data = vcpu->svm->vmcb->control.tsc_offset + tsc;
		break;
		break;
	}
	}
	case MSR_EFER:
		*data = vcpu->shadow_efer;
		break;
	case MSR_IA32_APICBASE:
		*data = vcpu->apic_base;
		break;
	case MSR_K6_STAR:
	case MSR_K6_STAR:
		*data = vcpu->svm->vmcb->save.star;
		*data = vcpu->svm->vmcb->save.star;
		break;
		break;
@@ -1127,8 +1102,7 @@ static int svm_get_msr(struct kvm_vcpu *vcpu, unsigned ecx, u64 *data)
		*data = vcpu->svm->vmcb->save.sysenter_esp;
		*data = vcpu->svm->vmcb->save.sysenter_esp;
		break;
		break;
	default:
	default:
		printk(KERN_ERR "kvm: unhandled rdmsr: 0x%x\n", ecx);
		return kvm_get_msr_common(vcpu, ecx, data);
		return 1;
	}
	}
	return 0;
	return 0;
}
}
@@ -1152,15 +1126,6 @@ static int rdmsr_interception(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
static int svm_set_msr(struct kvm_vcpu *vcpu, unsigned ecx, u64 data)
static int svm_set_msr(struct kvm_vcpu *vcpu, unsigned ecx, u64 data)
{
{
	switch (ecx) {
	switch (ecx) {
#ifdef CONFIG_X86_64
	case MSR_EFER:
		set_efer(vcpu, data);
		break;
#endif
	case MSR_IA32_MC0_STATUS:
		printk(KERN_WARNING "%s: MSR_IA32_MC0_STATUS 0x%llx, nop\n"
			    , __FUNCTION__, data);
		break;
	case MSR_IA32_TIME_STAMP_COUNTER: {
	case MSR_IA32_TIME_STAMP_COUNTER: {
		u64 tsc;
		u64 tsc;


@@ -1168,13 +1133,6 @@ static int svm_set_msr(struct kvm_vcpu *vcpu, unsigned ecx, u64 data)
		vcpu->svm->vmcb->control.tsc_offset = data - tsc;
		vcpu->svm->vmcb->control.tsc_offset = data - tsc;
		break;
		break;
	}
	}
	case MSR_IA32_UCODE_REV:
	case MSR_IA32_UCODE_WRITE:
	case 0x200 ... 0x2ff: /* MTRRs */
		break;
	case MSR_IA32_APICBASE:
		vcpu->apic_base = data;
		break;
	case MSR_K6_STAR:
	case MSR_K6_STAR:
		vcpu->svm->vmcb->save.star = data;
		vcpu->svm->vmcb->save.star = data;
		break;
		break;
@@ -1202,8 +1160,7 @@ static int svm_set_msr(struct kvm_vcpu *vcpu, unsigned ecx, u64 data)
		vcpu->svm->vmcb->save.sysenter_esp = data;
		vcpu->svm->vmcb->save.sysenter_esp = data;
		break;
		break;
	default:
	default:
		printk(KERN_ERR "kvm: unhandled wrmsr: %x\n", ecx);
		return kvm_set_msr_common(vcpu, ecx, data);
		return 1;
	}
	}
	return 0;
	return 0;
}
}
+11 −48
Original line number Original line Diff line number Diff line
@@ -344,8 +344,7 @@ static int vmx_get_msr(struct kvm_vcpu *vcpu, u32 msr_index, u64 *pdata)
		data = vmcs_readl(GUEST_GS_BASE);
		data = vmcs_readl(GUEST_GS_BASE);
		break;
		break;
	case MSR_EFER:
	case MSR_EFER:
		data = vcpu->shadow_efer;
		return kvm_get_msr_common(vcpu, msr_index, pdata);
		break;
#endif
#endif
	case MSR_IA32_TIME_STAMP_COUNTER:
	case MSR_IA32_TIME_STAMP_COUNTER:
		data = guest_read_tsc();
		data = guest_read_tsc();
@@ -359,37 +358,14 @@ static int vmx_get_msr(struct kvm_vcpu *vcpu, u32 msr_index, u64 *pdata)
	case MSR_IA32_SYSENTER_ESP:
	case MSR_IA32_SYSENTER_ESP:
		data = vmcs_read32(GUEST_SYSENTER_ESP);
		data = vmcs_read32(GUEST_SYSENTER_ESP);
		break;
		break;
	case 0xc0010010: /* SYSCFG */
	case 0xc0010015: /* HWCR */
	case MSR_IA32_PLATFORM_ID:
	case MSR_IA32_P5_MC_ADDR:
	case MSR_IA32_P5_MC_TYPE:
	case MSR_IA32_MC0_CTL:
	case MSR_IA32_MCG_STATUS:
	case MSR_IA32_MCG_CAP:
	case MSR_IA32_MC0_MISC:
	case MSR_IA32_MC0_MISC+4:
	case MSR_IA32_MC0_MISC+8:
	case MSR_IA32_MC0_MISC+12:
	case MSR_IA32_MC0_MISC+16:
	case MSR_IA32_UCODE_REV:
		/* MTRR registers */
	case 0xfe:
	case 0x200 ... 0x2ff:
		data = 0;
		break;
	case MSR_IA32_APICBASE:
		data = vcpu->apic_base;
		break;
	default:
	default:
		msr = find_msr_entry(vcpu, msr_index);
		msr = find_msr_entry(vcpu, msr_index);
		if (!msr) {
		if (msr) {
			printk(KERN_ERR "kvm: unhandled rdmsr: %x\n", msr_index);
			return 1;
		}
			data = msr->data;
			data = msr->data;
			break;
			break;
		}
		}
		return kvm_get_msr_common(vcpu, msr_index, pdata);
	}


	*pdata = data;
	*pdata = data;
	return 0;
	return 0;
@@ -405,6 +381,8 @@ static int vmx_set_msr(struct kvm_vcpu *vcpu, u32 msr_index, u64 data)
	struct vmx_msr_entry *msr;
	struct vmx_msr_entry *msr;
	switch (msr_index) {
	switch (msr_index) {
#ifdef CONFIG_X86_64
#ifdef CONFIG_X86_64
	case MSR_EFER:
		return kvm_set_msr_common(vcpu, msr_index, data);
	case MSR_FS_BASE:
	case MSR_FS_BASE:
		vmcs_writel(GUEST_FS_BASE, data);
		vmcs_writel(GUEST_FS_BASE, data);
		break;
		break;
@@ -421,32 +399,17 @@ static int vmx_set_msr(struct kvm_vcpu *vcpu, u32 msr_index, u64 data)
	case MSR_IA32_SYSENTER_ESP:
	case MSR_IA32_SYSENTER_ESP:
		vmcs_write32(GUEST_SYSENTER_ESP, data);
		vmcs_write32(GUEST_SYSENTER_ESP, data);
		break;
		break;
#ifdef __x86_64
	case MSR_EFER:
		set_efer(vcpu, data);
		break;
	case MSR_IA32_MC0_STATUS:
		printk(KERN_WARNING "%s: MSR_IA32_MC0_STATUS 0x%llx, nop\n"
			    , __FUNCTION__, data);
		break;
#endif
	case MSR_IA32_TIME_STAMP_COUNTER: {
	case MSR_IA32_TIME_STAMP_COUNTER: {
		guest_write_tsc(data);
		guest_write_tsc(data);
		break;
		break;
	}
	}
	case MSR_IA32_UCODE_REV:
	case MSR_IA32_UCODE_WRITE:
	case 0x200 ... 0x2ff: /* MTRRs */
		break;
	case MSR_IA32_APICBASE:
		vcpu->apic_base = data;
		break;
	default:
	default:
		msr = find_msr_entry(vcpu, msr_index);
		msr = find_msr_entry(vcpu, msr_index);
		if (!msr) {
		if (msr) {
			printk(KERN_ERR "kvm: unhandled wrmsr: 0x%x\n", msr_index);
			msr->data = data;
			return 1;
			break;
		}
		}
		return kvm_set_msr_common(vcpu, msr_index, data);
		msr->data = data;
		msr->data = data;
		break;
		break;
	}
	}