%patch Index: xen-3.2-testing/xen/arch/x86/hvm/svm/svm.c =================================================================== --- xen-3.2-testing.orig/xen/arch/x86/hvm/svm/svm.c 2008-02-09 21:24:22.000000000 -0500 +++ xen-3.2-testing/xen/arch/x86/hvm/svm/svm.c 2008-02-09 21:24:32.000000000 -0500 @@ -50,6 +50,7 @@ #include #include #include +#include u32 svm_feature_flags; @@ -73,6 +74,7 @@ /* vmcb used for extended host state */ static void *root_vmcb[NR_CPUS] __read_mostly; + static void inline __update_guest_eip( struct cpu_user_regs *regs, unsigned int inst_len) { @@ -882,7 +884,7 @@ .set_tsc_offset = svm_set_tsc_offset, .inject_exception = svm_inject_exception, .init_hypercall_page = svm_init_hypercall_page, - .event_pending = svm_event_pending + .event_pending = svm_event_pending, }; int start_svm(struct cpuinfo_x86 *c) @@ -1044,6 +1046,7 @@ HVMTRACE_3D(CPUID, v, input, ((uint64_t)eax << 32) | ebx, ((uint64_t)ecx << 32) | edx); + ext_intercept_do_cpuid(input, regs); inst_len = __get_instruction_length(v, INSTR_CPUID, NULL); __update_guest_eip(regs, inst_len); } @@ -1739,6 +1742,11 @@ /* is it a read? */ if (vmcb->exitinfo1 == 0) { + if (ext_intercept_do_msr_read(ecx, regs)) + { + goto done; + } + switch (ecx) { case MSR_IA32_TSC: msr_content = hvm_get_guest_time(v); @@ -1829,6 +1837,11 @@ } else { + if (ext_intercept_do_msr_write(ecx, regs)) + { + goto done_1; + } + msr_content = (u32)regs->eax | ((u64)regs->edx << 32); hvmtrace_msr_write(v, ecx, msr_content); @@ -1889,6 +1902,7 @@ } break; } +done_1: inst_len = __get_instruction_length(v, INSTR_WRMSR, NULL); } Index: xen-3.2-testing/xen/arch/x86/hvm/vmx/vmx.c =================================================================== --- xen-3.2-testing.orig/xen/arch/x86/hvm/vmx/vmx.c 2008-02-09 21:24:22.000000000 -0500 +++ xen-3.2-testing/xen/arch/x86/hvm/vmx/vmx.c 2008-02-09 21:24:32.000000000 -0500 @@ -50,6 +50,7 @@ #include #include #include +#include enum handler_return { HNDL_done, HNDL_unhandled, HNDL_exception_raised }; @@ -62,6 +63,7 @@ static void vmx_update_guest_cr(struct vcpu *v, unsigned int cr); static void vmx_update_guest_efer(struct vcpu *v); + static int vmx_domain_initialise(struct domain *d) { return vmx_alloc_vlapic_mapping(d); @@ -1238,7 +1240,8 @@ unsigned int count = *ecx; #ifdef VMXASSIST - if ( input == 0x40000003 ) + if (( input == 0x40000003 ) && + (vmx_guest_x86_mode(current) == 0)) { /* * NB. Unsupported interface for private use of VMXASSIST only. @@ -1319,12 +1322,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); @@ -1332,6 +1336,7 @@ regs->ebx = ebx; regs->ecx = ecx; regs->edx = edx; + ext_intercept_do_cpuid(input, regs); } #define CASE_GET_REG_P(REG, reg) \ @@ -2316,6 +2321,9 @@ HVM_DBG_LOG(DBG_LEVEL_1, "ecx=%x", ecx); + if (ext_intercept_do_msr_read(ecx, regs)) + goto done; + switch ( ecx ) { case MSR_IA32_TSC: @@ -2499,6 +2507,9 @@ HVM_DBG_LOG(DBG_LEVEL_1, "ecx=%x, eax=%x, edx=%x", ecx, (u32)regs->eax, (u32)regs->edx); + if (ext_intercept_do_msr_write(ecx, regs)) + return 1; + msr_content = (u32)regs->eax | ((u64)regs->edx << 32); hvmtrace_msr_write(v, ecx, msr_content); Index: xen-3.2-testing/xen/include/asm-x86/hvm/domain.h =================================================================== --- xen-3.2-testing.orig/xen/include/asm-x86/hvm/domain.h 2008-02-09 21:24:22.000000000 -0500 +++ xen-3.2-testing/xen/include/asm-x86/hvm/domain.h 2008-02-09 21:24:32.000000000 -0500 @@ -73,6 +73,10 @@ /* Pass-through */ struct hvm_iommu hvm_iommu; + /* Hvm extension handle */ + void *ext_handle; /* will be NULL on creation (memset)*/ + struct extension_intercept_vector *ext_vector; + }; #endif /* __ASM_X86_HVM_DOMAIN_H__ */ Index: xen-3.2-testing/xen/include/public/hvm/params.h =================================================================== --- xen-3.2-testing.orig/xen/include/public/hvm/params.h 2008-02-09 21:24:22.000000000 -0500 +++ xen-3.2-testing/xen/include/public/hvm/params.h 2008-02-09 21:24:32.000000000 -0500 @@ -50,10 +50,12 @@ #define HVM_PARAM_BUFIOREQ_PFN 6 +#define HVM_PARAM_EXTEND_HYPERVISOR 7 + #ifdef __ia64__ -#define HVM_PARAM_NVRAM_FD 7 -#define HVM_PARAM_VHPT_SIZE 8 -#define HVM_PARAM_BUFPIOREQ_PFN 9 +#define HVM_PARAM_NVRAM_FD 8 +#define HVM_PARAM_VHPT_SIZE 9 +#define HVM_PARAM_BUFPIOREQ_PFN 10 #endif /* @@ -75,12 +77,13 @@ * Missed interrupts are collapsed together and delivered as one 'late tick'. * Guest time always tracks wallclock (i.e., real) time. */ -#define HVM_PARAM_TIMER_MODE 10 +//KYS Check the modifications done to this file +#define HVM_PARAM_TIMER_MODE 11 #define HVMPTM_delay_for_missed_ticks 0 #define HVMPTM_no_delay_for_missed_ticks 1 #define HVMPTM_no_missed_ticks_pending 2 #define HVMPTM_one_missed_tick_pending 3 -#define HVM_NR_PARAMS 11 +#define HVM_NR_PARAMS 12 #endif /* __XEN_PUBLIC_HVM_PARAMS_H__ */ Index: xen-3.2-testing/xen/arch/x86/hvm/Makefile =================================================================== --- xen-3.2-testing.orig/xen/arch/x86/hvm/Makefile 2008-02-09 21:24:22.000000000 -0500 +++ xen-3.2-testing/xen/arch/x86/hvm/Makefile 2008-02-09 21:24:32.000000000 -0500 @@ -1,5 +1,6 @@ subdir-y += svm subdir-y += vmx +subdir-y += hvm_ext obj-y += hvm.o obj-y += i8254.o Index: xen-3.2-testing/xen/arch/x86/hvm/hvm.c =================================================================== --- xen-3.2-testing.orig/xen/arch/x86/hvm/hvm.c 2008-02-09 21:24:22.000000000 -0500 +++ xen-3.2-testing/xen/arch/x86/hvm/hvm.c 2008-02-09 21:37:20.000000000 -0500 @@ -42,6 +42,7 @@ #include #include #include +#include #include #include #include @@ -118,6 +119,7 @@ rtc_migrate_timers(v); hpet_migrate_timers(v); pt_migrate(v); + ext_intercept_do_migrate_timers(v); } void hvm_do_resume(struct vcpu *v) @@ -279,6 +281,7 @@ void hvm_domain_destroy(struct domain *d) { + ext_intercept_domain_destroy(d); hvm_funcs.domain_destroy(d); vioapic_deinit(d); hvm_destroy_cacheattr_region_list(d); @@ -447,8 +450,14 @@ { int rc; + if ((rc = ext_intercept_vcpu_initialize(v)) != 0) + goto fail1; + if ( (rc = vlapic_init(v)) != 0 ) + { + ext_intercept_vcpu_destroy(v); goto fail1; + } if ( (rc = hvm_funcs.vcpu_initialise(v)) != 0 ) goto fail2; @@ -496,12 +505,14 @@ hvm_funcs.vcpu_destroy(v); fail2: vlapic_destroy(v); + ext_intercept_vcpu_destroy(v); fail1: return rc; } void hvm_vcpu_destroy(struct vcpu *v) { + ext_intercept_vcpu_destroy(v); vlapic_destroy(v); hvm_funcs.vcpu_destroy(v); @@ -1573,6 +1584,10 @@ case 0: break; } + if (ext_intercept_do_hypercall(regs)) + { + return HVM_HCALL_completed; + } if ( (eax >= NR_hypercalls) || !hvm_hypercall32_table[eax] ) { @@ -1964,6 +1979,9 @@ if ( a.value > HVMPTM_one_missed_tick_pending ) goto param_fail; break; + case HVM_PARAM_EXTEND_HYPERVISOR: + if (hvm_ext_bind(d, (int)a.value)) + goto param_fail; } d->arch.hvm_domain.params[a.index] = a.value; rc = 0; Index: xen-3.2-testing/xen/arch/x86/x86_64/asm-offsets.c =================================================================== --- xen-3.2-testing.orig/xen/arch/x86/x86_64/asm-offsets.c 2008-02-09 21:24:22.000000000 -0500 +++ xen-3.2-testing/xen/arch/x86/x86_64/asm-offsets.c 2008-02-09 21:24:32.000000000 -0500 @@ -146,4 +146,7 @@ BLANK(); OFFSET(CPUINFO_ext_features, struct cpuinfo_x86, x86_capability[1]); + BLANK(); + + OFFSET(DOM_ext_vector, struct domain, arch.hvm_domain.ext_vector); } Index: xen-3.2-testing/xen/arch/x86/hvm/vmx/x86_64/exits.S =================================================================== --- xen-3.2-testing.orig/xen/arch/x86/hvm/vmx/x86_64/exits.S 2008-02-09 21:24:22.000000000 -0500 +++ xen-3.2-testing/xen/arch/x86/hvm/vmx/x86_64/exits.S 2008-02-09 21:24:32.000000000 -0500 @@ -112,6 +112,14 @@ ALIGN ENTRY(vmx_asm_do_vmentry) GET_CURRENT(%rbx) + mov VCPU_domain(%rbx),%rax + mov DOM_ext_vector(%rax),%rdx + test %rdx,%rdx + je vmx_no_ext_vector + sti + callq *(%rdx) +vmx_no_ext_vector: + cli # tests must not race interrupts movl VCPU_processor(%rbx),%eax Index: xen-3.2-testing/xen/arch/x86/hvm/svm/x86_64/exits.S =================================================================== --- xen-3.2-testing.orig/xen/arch/x86/hvm/svm/x86_64/exits.S 2008-02-09 21:24:22.000000000 -0500 +++ xen-3.2-testing/xen/arch/x86/hvm/svm/x86_64/exits.S 2008-02-09 21:24:32.000000000 -0500 @@ -37,6 +37,14 @@ ENTRY(svm_asm_do_resume) GET_CURRENT(%rbx) + mov VCPU_domain(%rbx),%rax + mov DOM_ext_vector(%rax),%rdx + test %rdx,%rdx + je svm_no_ext_vector + sti + callq *(%rdx) +svm_no_ext_vector: + CLGI movl VCPU_processor(%rbx),%eax Index: xen-3.2-testing/xen/arch/x86/hvm/save.c =================================================================== --- xen-3.2-testing.orig/xen/arch/x86/hvm/save.c 2008-02-09 21:24:22.000000000 -0500 +++ xen-3.2-testing/xen/arch/x86/hvm/save.c 2008-02-09 21:24:32.000000000 -0500 @@ -23,6 +23,8 @@ #include #include +#include +#include void arch_hvm_save(struct domain *d, struct hvm_save_header *hdr) { @@ -31,8 +33,7 @@ /* Save some CPUID bits */ cpuid(1, &eax, &ebx, &ecx, &edx); hdr->cpuid = eax; - - hdr->pad0 = 0; + hdr->ext_id = d->arch.hvm_domain.params[HVM_PARAM_EXTEND_HYPERVISOR]; } int arch_hvm_load(struct domain *d, struct hvm_save_header *hdr) @@ -61,6 +62,9 @@ /* VGA state is not saved/restored, so we nobble the cache. */ d->arch.hvm_domain.stdvga.cache = 0; + d->arch.hvm_domain.params[HVM_PARAM_EXTEND_HYPERVISOR] = hdr->ext_id; + if (hvm_ext_bind(d, hdr->ext_id)) + return -1; return 0; } Index: xen-3.2-testing/xen/include/public/arch-x86/hvm/save.h =================================================================== --- xen-3.2-testing.orig/xen/include/public/arch-x86/hvm/save.h 2008-02-09 21:24:22.000000000 -0500 +++ xen-3.2-testing/xen/include/public/arch-x86/hvm/save.h 2008-02-09 21:24:32.000000000 -0500 @@ -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 ext_id; /* extension ID */ }; DECLARE_HVM_SAVE_TYPE(HEADER, 1, struct hvm_save_header); @@ -422,9 +422,30 @@ DECLARE_HVM_SAVE_TYPE(MTRR, 14, struct hvm_hw_mtrr); +struct hvm_ns_veridian_dom { + uint64_t guestid_msr; + uint64_t hypercall_msr; + uint32_t long_mode; + uint32_t pad0; +}; +DECLARE_HVM_SAVE_TYPE(NS_VERIDIAN_DOM, 15, struct hvm_ns_veridian_dom); + +struct hvm_ns_veridian_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(NS_VERIDIAN_CPU, 16, struct hvm_ns_veridian_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__ */