# HG changeset patch
# User Keir Fraser <keir.fraser@xxxxxxxxxx>
# Date 1261030922 0
# Node ID c16a1d988ebcf0676b5a00218713040575c5bdb3
# Parent 7c85a4aa17fe8cb3ee5ad00ed02fbc85a70f1728
hvm: handle PVRDTSCP mode
Signed-off-by: Dan Magenheimer <dan.magenheimer@xxxxxxxxxx>
---
xen/arch/x86/hvm/hvm.c | 12 +++++++++---
xen/arch/x86/hvm/svm/svm.c | 7 ++++++-
xen/arch/x86/hvm/svm/vmcb.c | 8 +++++---
xen/arch/x86/hvm/vmx/vmx.c | 4 ++--
xen/include/asm-x86/hvm/hvm.h | 6 ++++++
5 files changed, 28 insertions(+), 9 deletions(-)
diff -r 7c85a4aa17fe -r c16a1d988ebc xen/arch/x86/hvm/hvm.c
--- a/xen/arch/x86/hvm/hvm.c Wed Dec 16 22:26:38 2009 +0000
+++ b/xen/arch/x86/hvm/hvm.c Thu Dec 17 06:22:02 2009 +0000
@@ -478,7 +478,7 @@ static int hvm_save_cpu_ctxt(struct doma
/* Architecture-specific vmcs/vmcb bits */
hvm_funcs.save_cpu_ctxt(v, &ctxt);
- ctxt.msr_tsc_aux = v->arch.hvm_vcpu.msr_tsc_aux;
+ ctxt.msr_tsc_aux = hvm_msr_tsc_aux(v);
hvm_get_segment_register(v, x86_seg_idtr, &seg);
ctxt.idtr_limit = seg.limit;
@@ -1898,6 +1898,11 @@ void hvm_cpuid(unsigned int input, unsig
}
}
break;
+ case 0x80000001:
+ /* Don't expose RDTSCP feature when in PVRDTSCP mode. */
+ if ( v->domain->arch.tsc_mode == TSC_MODE_PVRDTSCP )
+ *edx &= ~bitmaskof(X86_FEATURE_RDTSCP);
+ break;
}
}
@@ -1934,7 +1939,7 @@ int hvm_msr_read_intercept(struct cpu_us
break;
case MSR_TSC_AUX:
- msr_content = v->arch.hvm_vcpu.msr_tsc_aux;
+ msr_content = hvm_msr_tsc_aux(v);
break;
case MSR_IA32_APICBASE:
@@ -2031,7 +2036,8 @@ int hvm_msr_write_intercept(struct cpu_u
case MSR_TSC_AUX:
v->arch.hvm_vcpu.msr_tsc_aux = (uint32_t)msr_content;
- if ( cpu_has_rdtscp )
+ if ( cpu_has_rdtscp
+ && (v->domain->arch.tsc_mode != TSC_MODE_PVRDTSCP) )
wrmsrl(MSR_TSC_AUX, (uint32_t)msr_content);
break;
diff -r 7c85a4aa17fe -r c16a1d988ebc xen/arch/x86/hvm/svm/svm.c
--- a/xen/arch/x86/hvm/svm/svm.c Wed Dec 16 22:26:38 2009 +0000
+++ b/xen/arch/x86/hvm/svm/svm.c Thu Dec 17 06:22:02 2009 +0000
@@ -674,6 +674,9 @@ static void svm_ctxt_switch_to(struct vc
svm_vmsave(root_vmcb[cpu]);
svm_vmload(v->arch.hvm_svm.vmcb);
+
+ if ( cpu_has_rdtscp )
+ wrmsrl(MSR_TSC_AUX, hvm_msr_tsc_aux(v));
}
static void svm_do_resume(struct vcpu *v)
@@ -1457,11 +1460,13 @@ asmlinkage void svm_vmexit_handler(struc
hvm_triple_fault();
break;
+ case VMEXIT_RDTSCP:
+ regs->ecx = hvm_msr_tsc_aux(v);
+ /* fall through */
case VMEXIT_RDTSC:
svm_vmexit_do_rdtsc(regs);
break;
- case VMEXIT_RDTSCP:
case VMEXIT_MONITOR:
case VMEXIT_MWAIT:
case VMEXIT_VMRUN:
diff -r 7c85a4aa17fe -r c16a1d988ebc xen/arch/x86/hvm/svm/vmcb.c
--- a/xen/arch/x86/hvm/svm/vmcb.c Wed Dec 16 22:26:38 2009 +0000
+++ b/xen/arch/x86/hvm/svm/vmcb.c Thu Dec 17 06:22:02 2009 +0000
@@ -126,9 +126,8 @@ static int construct_vmcb(struct vcpu *v
GENERAL2_INTERCEPT_VMRUN | GENERAL2_INTERCEPT_VMMCALL |
GENERAL2_INTERCEPT_VMLOAD | GENERAL2_INTERCEPT_VMSAVE |
GENERAL2_INTERCEPT_STGI | GENERAL2_INTERCEPT_CLGI |
- GENERAL2_INTERCEPT_SKINIT | GENERAL2_INTERCEPT_RDTSCP |
- GENERAL2_INTERCEPT_WBINVD | GENERAL2_INTERCEPT_MONITOR |
- GENERAL2_INTERCEPT_MWAIT;
+ GENERAL2_INTERCEPT_SKINIT | GENERAL2_INTERCEPT_MWAIT |
+ GENERAL2_INTERCEPT_WBINVD | GENERAL2_INTERCEPT_MONITOR;
/* Intercept all debug-register writes. */
vmcb->dr_intercepts = ~0u;
@@ -165,7 +164,10 @@ static int construct_vmcb(struct vcpu *v
/* TSC. */
vmcb->tsc_offset = 0;
if ( v->domain->arch.vtsc )
+ {
vmcb->general1_intercepts |= GENERAL1_INTERCEPT_RDTSC;
+ vmcb->general2_intercepts |= GENERAL2_INTERCEPT_RDTSCP;
+ }
/* Guest EFER. */
v->arch.hvm_vcpu.guest_efer = 0;
diff -r 7c85a4aa17fe -r c16a1d988ebc xen/arch/x86/hvm/vmx/vmx.c
--- a/xen/arch/x86/hvm/vmx/vmx.c Wed Dec 16 22:26:38 2009 +0000
+++ b/xen/arch/x86/hvm/vmx/vmx.c Thu Dec 17 06:22:02 2009 +0000
@@ -337,7 +337,7 @@ static void vmx_restore_guest_msrs(struc
}
if ( cpu_has_rdtscp )
- wrmsrl(MSR_TSC_AUX, v->arch.hvm_vcpu.msr_tsc_aux);
+ wrmsrl(MSR_TSC_AUX, hvm_msr_tsc_aux(v));
}
#else /* __i386__ */
@@ -2495,7 +2495,7 @@ asmlinkage void vmx_vmexit_handler(struc
vmx_invlpg_intercept(exit_qualification);
break;
case EXIT_REASON_RDTSCP:
- regs->ecx = v->arch.hvm_vcpu.msr_tsc_aux;
+ regs->ecx = hvm_msr_tsc_aux(v);
/* fall through */
case EXIT_REASON_RDTSC:
inst_len = __get_instruction_length();
diff -r 7c85a4aa17fe -r c16a1d988ebc xen/include/asm-x86/hvm/hvm.h
--- a/xen/include/asm-x86/hvm/hvm.h Wed Dec 16 22:26:38 2009 +0000
+++ b/xen/include/asm-x86/hvm/hvm.h Thu Dec 17 06:22:02 2009 +0000
@@ -333,4 +333,10 @@ int hvm_debug_op(struct vcpu *v, int32_t
bool_t hvm_hap_nested_page_fault(unsigned long gfn);
+#define hvm_msr_tsc_aux(v) ({ \
+ struct domain *__d = (v)->domain; \
+ (__d->arch.tsc_mode == TSC_MODE_PVRDTSCP) \
+ ? (u32)__d->arch.incarnation : (u32)(v)->arch.hvm_vcpu.msr_tsc_aux; \
+})
+
#endif /* __ASM_X86_HVM_HVM_H__ */
_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog
|