%patch Index: xen-unstable.hg/xen/arch/x86/hvm/svm/svm.c =================================================================== --- xen-unstable.hg.orig/xen/arch/x86/hvm/svm/svm.c 2008-04-04 14:28:26.000000000 -0400 +++ xen-unstable.hg/xen/arch/x86/hvm/svm/svm.c 2008-04-04 14:28:44.000000000 -0400 @@ -50,6 +50,7 @@ #include #include #include +#include u32 svm_feature_flags; @@ -950,7 +951,7 @@ static void svm_vmexit_do_cpuid(struct cpu_user_regs *regs) { - unsigned int eax, ebx, ecx, edx, inst_len; + unsigned int eax, ebx, ecx, edx, inst_len, input; inst_len = __get_instruction_length(current, INSTR_CPUID, NULL); if ( inst_len == 0 ) @@ -960,6 +961,7 @@ ebx = regs->ebx; ecx = regs->ecx; edx = regs->edx; + input = eax; svm_cpuid_intercept(&eax, &ebx, &ecx, &edx); @@ -968,6 +970,7 @@ regs->ecx = ecx; regs->edx = edx; + hyperx_intercept_do_cpuid(input, regs); __update_guest_eip(regs, inst_len); } @@ -984,6 +987,10 @@ struct vcpu *v = current; struct vmcb_struct *vmcb = v->arch.hvm_svm.vmcb; + if (hyperx_intercept_do_msr_read(ecx, regs)) + { + goto done; + } switch ( ecx ) { case MSR_IA32_TSC: @@ -1085,6 +1092,10 @@ msr_content = (u32)regs->eax | ((u64)regs->edx << 32); hvmtrace_msr_write(v, ecx, msr_content); + if (hyperx_intercept_do_msr_write(ecx, regs)) + { + goto done_msr_write; + } switch ( ecx ) { @@ -1141,7 +1152,7 @@ } break; } - +done_msr_write: return X86EMUL_OKAY; gpf: Index: xen-unstable.hg/xen/arch/x86/hvm/vmx/vmx.c =================================================================== --- xen-unstable.hg.orig/xen/arch/x86/hvm/vmx/vmx.c 2008-04-04 14:28:26.000000000 -0400 +++ xen-unstable.hg/xen/arch/x86/hvm/vmx/vmx.c 2008-04-04 14:28:44.000000000 -0400 @@ -49,6 +49,7 @@ #include #include #include +#include enum handler_return { HNDL_done, HNDL_unhandled, HNDL_exception_raised }; @@ -1225,12 +1226,13 @@ static void vmx_do_cpuid(struct cpu_user_regs *regs) { - unsigned int eax, ebx, ecx, edx; + unsigned int eax, ebx, ecx, edx, input; eax = regs->eax; ebx = regs->ebx; ecx = regs->ecx; edx = regs->edx; + input = eax; vmx_cpuid_intercept(&eax, &ebx, &ecx, &edx); @@ -1238,6 +1240,7 @@ regs->ebx = ebx; regs->ecx = ecx; regs->edx = edx; + hyperx_intercept_do_cpuid(input, regs); } static void vmx_dr_access(unsigned long exit_qualification, @@ -1506,6 +1509,9 @@ HVM_DBG_LOG(DBG_LEVEL_1, "ecx=%x", ecx); + if (hyperx_intercept_do_msr_read(ecx, regs)) + goto done; + switch ( ecx ) { case MSR_IA32_TSC: @@ -1699,6 +1705,9 @@ HVM_DBG_LOG(DBG_LEVEL_1, "ecx=%x, eax=%x, edx=%x", ecx, (u32)regs->eax, (u32)regs->edx); + if (hyperx_intercept_do_msr_write(ecx, regs)) + return X86EMUL_OKAY; + msr_content = (u32)regs->eax | ((u64)regs->edx << 32); hvmtrace_msr_write(v, ecx, msr_content); Index: xen-unstable.hg/xen/include/asm-x86/hvm/domain.h =================================================================== --- xen-unstable.hg.orig/xen/include/asm-x86/hvm/domain.h 2008-04-04 14:28:26.000000000 -0400 +++ xen-unstable.hg/xen/include/asm-x86/hvm/domain.h 2008-04-04 14:28:44.000000000 -0400 @@ -79,6 +79,7 @@ #endif bool_t hap_enabled; bool_t qemu_mapcache_invalidate; + void *hyperv_handle; /* will be NULL on creation (memset)*/ }; #endif /* __ASM_X86_HVM_DOMAIN_H__ */ Index: xen-unstable.hg/xen/arch/x86/hvm/Makefile =================================================================== --- xen-unstable.hg.orig/xen/arch/x86/hvm/Makefile 2008-04-04 14:28:26.000000000 -0400 +++ xen-unstable.hg/xen/arch/x86/hvm/Makefile 2008-04-04 14:28:44.000000000 -0400 @@ -1,5 +1,6 @@ subdir-y += svm subdir-y += vmx +subdir-y += hyperv obj-y += emulate.o obj-y += hvm.o Index: xen-unstable.hg/xen/arch/x86/hvm/hvm.c =================================================================== --- xen-unstable.hg.orig/xen/arch/x86/hvm/hvm.c 2008-04-04 14:28:26.000000000 -0400 +++ xen-unstable.hg/xen/arch/x86/hvm/hvm.c 2008-04-04 14:28:44.000000000 -0400 @@ -43,6 +43,7 @@ #include #include #include +#include #include #include #include @@ -156,6 +157,7 @@ rtc_migrate_timers(v); hpet_migrate_timers(v); pt_migrate(v); + hyperx_intercept_do_migrate_timers(v); } void hvm_do_resume(struct vcpu *v) @@ -342,6 +344,7 @@ void hvm_domain_destroy(struct domain *d) { + hyperx_intercept_domain_destroy(d); hvm_funcs.domain_destroy(d); vioapic_deinit(d); hvm_destroy_cacheattr_region_list(d); @@ -625,8 +628,14 @@ { int rc; + if ((rc = hyperx_intercept_vcpu_initialize(v)) != 0) + goto fail1; + if ( (rc = vlapic_init(v)) != 0 ) + { + hyperx_intercept_vcpu_destroy(v); goto fail1; + } if ( (rc = hvm_funcs.vcpu_initialise(v)) != 0 ) goto fail2; @@ -674,12 +683,14 @@ hvm_funcs.vcpu_destroy(v); fail2: vlapic_destroy(v); + hyperx_intercept_vcpu_destroy(v); fail1: return rc; } void hvm_vcpu_destroy(struct vcpu *v) { + hyperx_intercept_vcpu_destroy(v); vlapic_destroy(v); hvm_funcs.vcpu_destroy(v); @@ -1823,6 +1834,10 @@ case 0: break; } + if (hyperx_intercept_do_hypercall(regs)) + { + return HVM_HCALL_completed; + } if ( (eax >= NR_hypercalls) || !hvm_hypercall32_table[eax] ) { @@ -1964,6 +1979,7 @@ vcpu_wake(v); gdprintk(XENLOG_INFO, "AP %d bringup succeeded.\n", vcpuid); + hyperx_intercept_vcpu_up(v); return 0; } @@ -2210,6 +2226,10 @@ if ( a.value > HVMPTM_one_missed_tick_pending ) goto param_fail; break; + case HVM_PARAM_EXTEND_HYPERVISOR: +printk("KYS: EXTEND hypervisor id is %d\n", (int)a.value); + if ((a.value == 1) && hyperv_initialize(d)) + goto param_fail; } d->arch.hvm_domain.params[a.index] = a.value; rc = 0; Index: xen-unstable.hg/xen/arch/x86/hvm/save.c =================================================================== --- xen-unstable.hg.orig/xen/arch/x86/hvm/save.c 2008-04-04 14:28:26.000000000 -0400 +++ xen-unstable.hg/xen/arch/x86/hvm/save.c 2008-04-04 14:28:44.000000000 -0400 @@ -23,6 +23,8 @@ #include #include +#include +#include void arch_hvm_save(struct domain *d, struct hvm_save_header *hdr) { Index: xen-unstable.hg/xen/include/public/arch-x86/hvm/save.h =================================================================== --- xen-unstable.hg.orig/xen/include/public/arch-x86/hvm/save.h 2008-04-04 14:28:26.000000000 -0400 +++ xen-unstable.hg/xen/include/public/arch-x86/hvm/save.h 2008-04-04 14:28:44.000000000 -0400 @@ -38,7 +38,7 @@ uint32_t version; /* File format version */ uint64_t changeset; /* Version of Xen that saved this file */ uint32_t cpuid; /* CPUID[0x01][%eax] on the saving machine */ - uint32_t pad0; + uint32_t pad0; /* extension ID */ }; DECLARE_HVM_SAVE_TYPE(HEADER, 1, struct hvm_save_header); @@ -421,9 +421,30 @@ DECLARE_HVM_SAVE_TYPE(MTRR, 14, struct hvm_hw_mtrr); +struct hvm_hyperv_dom { + uint64_t guestid_msr; + uint64_t hypercall_msr; + uint32_t long_mode; + uint32_t ext_id; +}; +DECLARE_HVM_SAVE_TYPE(HYPERV_DOM, 15, struct hvm_hyperv_dom); + +struct hvm_hyperv_cpu { + uint64_t control_msr; + uint64_t version_msr; + uint64_t sief_msr; + uint64_t simp_msr; + uint64_t eom_msr; + uint64_t int_msr[16]; + struct { + uint64_t config; + uint64_t count; + } timers[4]; +}; +DECLARE_HVM_SAVE_TYPE(HYPERV_CPU, 16, struct hvm_hyperv_cpu); /* * Largest type-code in use */ -#define HVM_SAVE_CODE_MAX 14 +#define HVM_SAVE_CODE_MAX 16 #endif /* __XEN_PUBLIC_HVM_SAVE_X86_H__ */ Index: xen-unstable.hg/xen/include/public/hvm/params.h =================================================================== --- xen-unstable.hg.orig/xen/include/public/hvm/params.h 2008-04-04 14:28:05.000000000 -0400 +++ xen-unstable.hg/xen/include/public/hvm/params.h 2008-04-04 14:30:49.000000000 -0400 @@ -83,7 +83,8 @@ /* Boolean: Enable virtual HPET (high-precision event timer)? (x86-only) */ #define HVM_PARAM_HPET_ENABLED 11 +#define HVM_PARAM_EXTEND_HYPERVISOR 12 -#define HVM_NR_PARAMS 12 +#define HVM_NR_PARAMS 13 #endif /* __XEN_PUBLIC_HVM_PARAMS_H__ */