%patch Index: xen-3.2.1-testing/xen/arch/x86/hvm/svm/svm.c =================================================================== --- xen-3.2.1-testing.orig/xen/arch/x86/hvm/svm/svm.c +++ xen-3.2.1-testing/xen/arch/x86/hvm/svm/svm.c @@ -50,6 +50,7 @@ #include #include #include +#include u32 svm_feature_flags; @@ -73,6 +74,7 @@ static void *hsa[NR_CPUS] __read_mostly; /* 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) { @@ -883,7 +885,7 @@ static struct hvm_function_table svm_fun .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) @@ -1034,6 +1036,7 @@ static void svm_vmexit_do_cpuid(struct v 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); } @@ -1736,6 +1739,11 @@ static void svm_do_msr_access( /* 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); @@ -1826,6 +1834,11 @@ static void svm_do_msr_access( } 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); @@ -1886,6 +1899,7 @@ static void svm_do_msr_access( } break; } +done_1: inst_len = __get_instruction_length(v, INSTR_WRMSR, NULL); } Index: xen-3.2.1-testing/xen/arch/x86/hvm/vmx/vmx.c =================================================================== --- xen-3.2.1-testing.orig/xen/arch/x86/hvm/vmx/vmx.c +++ xen-3.2.1-testing/xen/arch/x86/hvm/vmx/vmx.c @@ -49,6 +49,7 @@ #include #include #include +#include enum handler_return { HNDL_done, HNDL_unhandled, HNDL_exception_raised }; @@ -61,6 +62,7 @@ static void vmx_install_vlapic_mapping(s 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); @@ -1248,7 +1250,8 @@ void vmx_cpuid_intercept( 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 @@ void vmx_cpuid_intercept( 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 @@ static void vmx_do_cpuid(struct cpu_user 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 @@ int vmx_msr_read_intercept(struct cpu_us 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 @@ int vmx_msr_write_intercept(struct cpu_u 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.1-testing/xen/include/asm-x86/hvm/domain.h =================================================================== --- xen-3.2.1-testing.orig/xen/include/asm-x86/hvm/domain.h +++ xen-3.2.1-testing/xen/include/asm-x86/hvm/domain.h @@ -74,6 +74,10 @@ struct hvm_domain { /* 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; + bool_t hap_enabled; }; Index: xen-3.2.1-testing/xen/include/public/hvm/params.h =================================================================== --- xen-3.2.1-testing.orig/xen/include/public/hvm/params.h +++ xen-3.2.1-testing/xen/include/public/hvm/params.h @@ -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,15 +77,16 @@ * 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 /* Boolean: Enable virtual HPET (high-precision event timer)? (x86-only) */ -#define HVM_PARAM_HPET_ENABLED 11 +#define HVM_PARAM_HPET_ENABLED 12 -#define HVM_NR_PARAMS 12 +#define HVM_NR_PARAMS 13 #endif /* __XEN_PUBLIC_HVM_PARAMS_H__ */ Index: xen-3.2.1-testing/tools/python/xen/xend/XendConstants.py =================================================================== --- xen-3.2.1-testing.orig/tools/python/xen/xend/XendConstants.py +++ xen-3.2.1-testing/tools/python/xen/xend/XendConstants.py @@ -43,11 +43,12 @@ HVM_PARAM_STORE_EVTCHN = 2 HVM_PARAM_PAE_ENABLED = 4 HVM_PARAM_IOREQ_PFN = 5 HVM_PARAM_BUFIOREQ_PFN = 6 -HVM_PARAM_NVRAM_FD = 7 -HVM_PARAM_VHPT_SIZE = 8 -HVM_PARAM_BUFPIOREQ_PFN = 9 -HVM_PARAM_TIMER_MODE = 10 -HVM_PARAM_HPET_ENABLED = 11 +HVM_PARAM_EXTEND_HYPERVISOR = 7 +HVM_PARAM_NVRAM_FD = 8 +HVM_PARAM_VHPT_SIZE = 9 +HVM_PARAM_BUFPIOREQ_PFN = 10 +HVM_PARAM_TIMER_MODE = 11 +HVM_PARAM_HPET_ENABLED = 12 restart_modes = [ "restart", Index: xen-3.2.1-testing/xen/arch/x86/hvm/Makefile =================================================================== --- xen-3.2.1-testing.orig/xen/arch/x86/hvm/Makefile +++ xen-3.2.1-testing/xen/arch/x86/hvm/Makefile @@ -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.1-testing/xen/arch/x86/hvm/hvm.c =================================================================== --- xen-3.2.1-testing.orig/xen/arch/x86/hvm/hvm.c +++ xen-3.2.1-testing/xen/arch/x86/hvm/hvm.c @@ -42,6 +42,7 @@ #include #include #include +#include #include #include #include @@ -103,6 +104,7 @@ void hvm_migrate_timers(struct vcpu *v) rtc_migrate_timers(v); hpet_migrate_timers(v); pt_migrate(v); + ext_intercept_do_migrate_timers(v); } void hvm_do_resume(struct vcpu *v) @@ -266,6 +268,7 @@ void hvm_domain_relinquish_resources(str 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); @@ -434,8 +437,14 @@ int hvm_vcpu_initialise(struct vcpu *v) { 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; @@ -483,12 +492,14 @@ int hvm_vcpu_initialise(struct vcpu *v) 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); @@ -1598,6 +1609,10 @@ int hvm_do_hypercall(struct cpu_user_reg case 0: break; } + if (ext_intercept_do_hypercall(regs)) + { + return HVM_HCALL_completed; + } if ( (eax >= NR_hypercalls) || !hvm_hypercall32_table[eax] ) { @@ -1752,6 +1767,7 @@ int hvm_bringup_ap(int vcpuid, int tramp vcpu_wake(v); gdprintk(XENLOG_INFO, "AP %d bringup succeeded.\n", vcpuid); + ext_intercept_vcpu_up(v); return 0; } @@ -1989,6 +2005,9 @@ long do_hvm_op(unsigned long op, XEN_GUE 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.1-testing/xen/arch/x86/x86_64/asm-offsets.c =================================================================== --- xen-3.2.1-testing.orig/xen/arch/x86/x86_64/asm-offsets.c +++ xen-3.2.1-testing/xen/arch/x86/x86_64/asm-offsets.c @@ -148,4 +148,7 @@ void __dummy__(void) 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.1-testing/xen/arch/x86/hvm/vmx/x86_64/exits.S =================================================================== --- xen-3.2.1-testing.orig/xen/arch/x86/hvm/vmx/x86_64/exits.S +++ xen-3.2.1-testing/xen/arch/x86/hvm/vmx/x86_64/exits.S @@ -112,6 +112,14 @@ vmx_process_softirqs: 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.1-testing/xen/arch/x86/hvm/svm/x86_64/exits.S =================================================================== --- xen-3.2.1-testing.orig/xen/arch/x86/hvm/svm/x86_64/exits.S +++ xen-3.2.1-testing/xen/arch/x86/hvm/svm/x86_64/exits.S @@ -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.1-testing/xen/arch/x86/hvm/save.c =================================================================== --- xen-3.2.1-testing.orig/xen/arch/x86/hvm/save.c +++ xen-3.2.1-testing/xen/arch/x86/hvm/save.c @@ -23,6 +23,8 @@ #include #include +#include +#include void arch_hvm_save(struct domain *d, struct hvm_save_header *hdr) { @@ -31,8 +33,7 @@ void arch_hvm_save(struct domain *d, str /* 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 @@ int arch_hvm_load(struct domain *d, stru /* 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.1-testing/xen/include/public/arch-x86/hvm/save.h =================================================================== --- xen-3.2.1-testing.orig/xen/include/public/arch-x86/hvm/save.h +++ xen-3.2.1-testing/xen/include/public/arch-x86/hvm/save.h @@ -38,7 +38,7 @@ struct hvm_save_header { 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 @@ struct hvm_hw_mtrr { 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__ */