Re: [PATCH 2/3] Add HYPER-V apic access MSRs.

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Wed, Jan 13, 2010 at 04:27:28PM +0200, Avi Kivity wrote:
> On 01/13/2010 03:59 PM, Gleb Natapov wrote:
> >Signed-off-by: Gleb Natapov<gleb@xxxxxxxxxx>
> >Signed-off-by: Vadim Rozenfeld<vrozenfe@xxxxxxxxxx>
> >---
> >  arch/x86/include/asm/kvm_host.h |    2 +
> >  arch/x86/kvm/lapic.c            |   53 +++++++++++++++++++++++++++++++++++++++
> >  arch/x86/kvm/lapic.h            |    8 ++++++
> >  arch/x86/kvm/x86.c              |   34 ++++++++++++++++++++++---
> >  include/linux/kvm.h             |    1 +
> >  5 files changed, 94 insertions(+), 4 deletions(-)
> >
> >diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h
> >index 7bfd468..4d82c52 100644
> >--- a/arch/x86/include/asm/kvm_host.h
> >+++ b/arch/x86/include/asm/kvm_host.h
> >@@ -362,6 +362,8 @@ struct kvm_vcpu_arch {
> >  	/* used for guest single stepping over the given code position */
> >  	u16 singlestep_cs;
> >  	unsigned long singlestep_rip;
> >+	/* fields used by HYPER-V emulation */
> >+	u64 hv_vapic;
> >  };
> >
> >  struct kvm_mem_alias {
> >diff --git a/arch/x86/kvm/lapic.c b/arch/x86/kvm/lapic.c
> >index ba8c045..063963f 100644
> >--- a/arch/x86/kvm/lapic.c
> >+++ b/arch/x86/kvm/lapic.c
> >@@ -1246,3 +1246,56 @@ int kvm_x2apic_msr_read(struct kvm_vcpu *vcpu, u32 msr, u64 *data)
> >
> >  	return 0;
> >  }
> >+
> >+static u32 kvm_hv_vapic_msr2reg(u32 msr)
> >+{
> >+	u32 reg;
> >+	switch (msr) {
> >+	case HV_X64_MSR_EOI:
> >+		reg = APIC_EOI;
> >+		break;
> >+	case HV_X64_MSR_ICR:
> >+		reg = APIC_ICR;
> >+		break;
> >+	case HV_X64_MSR_TPR:
> >+		reg = APIC_TASKPRI;
> >+		break;
> >+	default:
> >+		reg = -1;
> >+		break;
> >+	}
> >+
> >+	return reg;
> >+}
> >+
> >+int kvm_hv_vapic_msr_write(struct kvm_vcpu *vcpu, u32 msr, u64 data)
> >+{
> >+	struct kvm_lapic *apic = vcpu->arch.apic;
> >+	u32 reg = kvm_hv_vapic_msr2reg(msr);
> >+
> >+	if (!irqchip_in_kernel(vcpu->kvm))
> >+		return 1;
> >+
> >+	/* if this is ICR write vector before command */
> >+	if (reg == APIC_ICR)
> >+		apic_reg_write(apic, APIC_ICR2, (u32)(data>>  32));
> >+	return apic_reg_write(apic, reg, (u32)data);
> >+}
> >+
> >+int kvm_hv_vapic_msr_read(struct kvm_vcpu *vcpu, u32 msr, u64 *data)
> >+{
> >+	struct kvm_lapic *apic = vcpu->arch.apic;
> >+	u32 reg = kvm_hv_vapic_msr2reg(msr), low, high = 0;
> >+
> >+	if (!irqchip_in_kernel(vcpu->kvm))
> >+		return 1;
> >+
> >+	if (apic_reg_read(apic, reg, 4,&low))
> >+		return 1;
> >+	if (reg == APIC_ICR)
> >+		apic_reg_read(apic, APIC_ICR2, 4,&high);
> >+
> >+	*data = (((u64)high)<<  32) | low;
> >+
> >+	return 0;
> >+}
> 
> I think it's cleaner to put all this into the (set_msr and get_msr).
> You're just converting register numbers back and forth, while they
> are known at the call site.
> 
I thought about it. It will bring apic internals into x86.c. If you are
OK with that I'll do it like you say.

> >  #endif
> >diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
> >index 6972b2b..e058898 100644
> >--- a/arch/x86/kvm/x86.c
> >+++ b/arch/x86/kvm/x86.c
> >@@ -629,7 +629,8 @@ static u32 msrs_to_save[] = {
> >  	MSR_CSTAR, MSR_KERNEL_GS_BASE, MSR_SYSCALL_MASK, MSR_LSTAR,
> >  #endif
> >  	MSR_IA32_TSC, MSR_IA32_PERF_STATUS, MSR_IA32_CR_PAT, MSR_VM_HSAVE_PA,
> >-	HV_X64_MSR_GUEST_OS_ID, HV_X64_MSR_HYPERCALL
> >+	HV_X64_MSR_GUEST_OS_ID, HV_X64_MSR_HYPERCALL,
> >+	HV_X64_MSR_APIC_ASSIST_PAGE
> >  };
> 
> , at the end.
> 
> >
> >  static unsigned num_msrs_to_save;
> >@@ -1061,10 +1062,30 @@ static int set_msr_hyperv_pw(struct kvm_vcpu *vcpu, u32 msr, u64 data)
> >
> >  static int set_msr_hyperv(struct kvm_vcpu *vcpu, u32 msr, u64 data)
> >  {
> >-	pr_unimpl(vcpu, "HYPER-V unimplemented wrmsr: 0x%x data 0x%llx\n",
> >-		  msr, data);
> >+	switch (msr) {
> >+	case HV_X64_MSR_APIC_ASSIST_PAGE: {
> >+		unsigned long addr;
> >+		vcpu->arch.hv_vapic = data;
> >+		if(!kvm_hv_vapic_enabled(vcpu))
> >+			break;
> 
> Space after if.
Forgot about checkpatch again :(

> 
> >+		addr = gfn_to_hva(vcpu->kvm, data>>
> >+				  HV_X64_MSR_APIC_ASSIST_PAGE_ADDRESS_SHIFT);
> >+		if (kvm_is_error_hva(addr))
> >+			return 1;
> 
> But the spec actually permits addresses outside RAM?
Is says "in GPA space". Not sure how to interpret it. The guest I run
uses address in real RAM.

> 
> >+		memset((void*)addr, 0, PAGE_SIZE);
> 
> clear_user_page()!
> 
Ugh.

> >+		break;
> >+	}
> >+	case HV_X64_MSR_EOI:
> >+	case HV_X64_MSR_ICR:
> >+	case HV_X64_MSR_TPR:
> >+		return kvm_hv_vapic_msr_write(vcpu, msr, data);
> 
> Here, just call the apic function with the known apic register number.
> 
> -- 
> error compiling committee.c: too many arguments to function

--
			Gleb.
--
To unsubscribe from this list: send the line "unsubscribe kvm" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [KVM ARM]     [KVM ia64]     [KVM ppc]     [Virtualization Tools]     [Spice Development]     [Libvirt]     [Libvirt Users]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite Questions]     [Linux Kernel]     [Linux SCSI]     [XFree86]
  Powered by Linux