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