Dan Magenheimer
2009-Dec-17 01:43 UTC
[Xen-devel] [PATCH] add pvrdtscp tsc_mode support for hvm
When tsc_mode is pvrdtscp, tsc_aux is handled differently. Also added some code for AMD svm pvrdtscp support... needs more work I think. There may also be a better way to handle tscmode in the x86_emulate.c code (but this code seems to live in a different universe and adding the extra callout seemed to work). Signed-off-by: Dan Magenheimer <dan.magenheimer@oracle.com> diff -r 7c85a4aa17fe xen/arch/x86/hvm/emulate.c --- a/xen/arch/x86/hvm/emulate.c Wed Dec 16 22:26:38 2009 +0000 +++ b/xen/arch/x86/hvm/emulate.c Wed Dec 16 18:41:08 2009 -0700 @@ -16,6 +16,7 @@ #include <xen/paging.h> #include <xen/trace.h> #include <asm/event.h> +#include <asm/time.h> #include <asm/hvm/emulate.h> #include <asm/hvm/hvm.h> #include <asm/hvm/trace.h> @@ -927,6 +928,18 @@ static int hvmemul_invlpg( return rc; } +static int hvmemul_tscmode( + uint64_t *tsc_aux, + struct x86_emulate_ctxt *ctxt) +{ + struct domain *d = current->domain; + + if ( d->arch.tsc_mode != TSC_MODE_PVRDTSCP ) + return -1; + *tsc_aux = d->arch.incarnation; + return 0; +} + static const struct x86_emulate_ops hvm_emulate_ops = { .read = hvmemul_read, .insn_fetch = hvmemul_insn_fetch, @@ -949,7 +962,8 @@ static const struct x86_emulate_ops hvm_ .inject_sw_interrupt = hvmemul_inject_sw_interrupt, .get_fpu = hvmemul_get_fpu, .put_fpu = hvmemul_put_fpu, - .invlpg = hvmemul_invlpg + .invlpg = hvmemul_invlpg, + .tscmode = hvmemul_tscmode }; int hvm_emulate_one( diff -r 7c85a4aa17fe 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 Wed Dec 16 18:41:08 2009 -0700 @@ -47,6 +47,7 @@ #include <asm/traps.h> #include <asm/mc146818rtc.h> #include <asm/spinlock.h> +#include <asm/time.h> #include <asm/hvm/hvm.h> #include <asm/hvm/vpt.h> #include <asm/hvm/support.h> @@ -478,7 +479,9 @@ 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 = (d->arch.tsc_mode == TSC_MODE_PVRDTSCP) ? + d->arch.incarnation : + v->arch.hvm_vcpu.msr_tsc_aux; hvm_get_segment_register(v, x86_seg_idtr, &seg); ctxt.idtr_limit = seg.limit; @@ -655,7 +658,9 @@ static int hvm_load_cpu_ctxt(struct doma if ( hvm_funcs.load_cpu_ctxt(v, &ctxt) < 0 ) return -EINVAL; - v->arch.hvm_vcpu.msr_tsc_aux = ctxt.msr_tsc_aux; + v->arch.hvm_vcpu.msr_tsc_aux = (d->arch.tsc_mode == TSC_MODE_PVRDTSCP) ? + d->arch.incarnation : + v->arch.hvm_vcpu.msr_tsc_aux; seg.limit = ctxt.idtr_limit; seg.base = ctxt.idtr_base; @@ -1934,7 +1939,9 @@ int hvm_msr_read_intercept(struct cpu_us break; case MSR_TSC_AUX: - msr_content = v->arch.hvm_vcpu.msr_tsc_aux; + msr_content = (v->domain->arch.tsc_mode == TSC_MODE_PVRDTSCP) ? + v->domain->arch.incarnation : + v->arch.hvm_vcpu.msr_tsc_aux; break; case MSR_IA32_APICBASE: @@ -2030,6 +2037,8 @@ int hvm_msr_write_intercept(struct cpu_u break; case MSR_TSC_AUX: + if ( v->domain->arch.tsc_mode == TSC_MODE_PVRDTSCP ) + break; v->arch.hvm_vcpu.msr_tsc_aux = (uint32_t)msr_content; if ( cpu_has_rdtscp ) wrmsrl(MSR_TSC_AUX, (uint32_t)msr_content); diff -r 7c85a4aa17fe 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 Wed Dec 16 18:41:08 2009 -0700 @@ -918,6 +918,10 @@ static void svm_cpuid_intercept( /* Fix up VLAPIC details. */ if ( vlapic_hw_disabled(vcpu_vlapic(v)) ) __clear_bit(X86_FEATURE_APIC & 31, edx); + + /* don''t expose rdtscp bit to guest when in tsc_mode=pvrdtscp */ + if ( v->domain->arch.tsc_mode == TSC_MODE_PVRDTSCP) + *edx &= ~(bitmaskof(X86_FEATURE_RDTSCP)); } HVMTRACE_5D (CPUID, input, *eax, *ebx, *ecx, *edx); @@ -1457,11 +1461,15 @@ asmlinkage void svm_vmexit_handler(struc hvm_triple_fault(); break; + case VMEXIT_RDTSCP: + regs->ecx = (v->domain->arch.tsc_mode == TSC_MODE_PVRDTSCP) ? + v->domain->arch.incarnation : + 0; /* FIXME handle v->arch.hvm_vcpu.msr_tsc_aux? */ + /* 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 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 Wed Dec 16 18:41:08 2009 -0700 @@ -37,6 +37,7 @@ #include <asm/spinlock.h> #include <asm/paging.h> #include <asm/p2m.h> +#include <asm/time.h> #include <asm/hvm/emulate.h> #include <asm/hvm/hvm.h> #include <asm/hvm/support.h> @@ -337,7 +338,9 @@ 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, (v->domain->arch.tsc_mode == TSC_MODE_PVRDTSCP) ? + v->domain->arch.incarnation : + v->arch.hvm_vcpu.msr_tsc_aux); } #else /* __i386__ */ @@ -1512,6 +1515,10 @@ static void vmx_cpuid_intercept( *edx |= bitmaskof(X86_FEATURE_SYSCALL); else *edx &= ~(bitmaskof(X86_FEATURE_SYSCALL)); + + /* don''t expose rdtscp bit to guest when in tsc_mode=pvrdtscp */ + if ( v->domain->arch.tsc_mode == TSC_MODE_PVRDTSCP) + *edx &= ~(bitmaskof(X86_FEATURE_RDTSCP)); break; } @@ -2495,7 +2502,9 @@ 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 = (v->domain->arch.tsc_mode == TSC_MODE_PVRDTSCP) ? + v->domain->arch.incarnation : + v->arch.hvm_vcpu.msr_tsc_aux; /* fall through */ case EXIT_REASON_RDTSC: inst_len = __get_instruction_length(); diff -r 7c85a4aa17fe xen/arch/x86/x86_emulate/x86_emulate.c --- a/xen/arch/x86/x86_emulate/x86_emulate.c Wed Dec 16 22:26:38 2009 +0000 +++ b/xen/arch/x86/x86_emulate/x86_emulate.c Wed Dec 16 18:41:08 2009 -0700 @@ -3508,7 +3508,8 @@ x86_emulate( { uint64_t tsc_aux; fail_if(ops->read_msr == NULL); - if ( (rc = ops->read_msr(MSR_TSC_AUX, &tsc_aux, ctxt)) != 0 ) + if ( ((rc = ops->tscmode(&tsc_aux, ctxt)) != 0 ) && + ((rc = ops->read_msr(MSR_TSC_AUX, &tsc_aux, ctxt)) != 0) ) goto done; _regs.ecx = (uint32_t)tsc_aux; goto rdtsc; diff -r 7c85a4aa17fe xen/arch/x86/x86_emulate/x86_emulate.h --- a/xen/arch/x86/x86_emulate/x86_emulate.h Wed Dec 16 22:26:38 2009 +0000 +++ b/xen/arch/x86/x86_emulate/x86_emulate.h Wed Dec 16 18:41:08 2009 -0700 @@ -359,6 +359,12 @@ struct x86_emulate_ops enum x86_segment seg, unsigned long offset, struct x86_emulate_ctxt *ctxt); + + /* tscmode: handle special casing for certain tsc mode */ + int (*tscmode)( + uint64_t *tsc_aux, + struct x86_emulate_ctxt *ctxt); + }; struct cpu_user_regs; _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
Keir Fraser
2009-Dec-17 06:23 UTC
Re: [Xen-devel] [PATCH] add pvrdtscp tsc_mode support for hvm
On 17/12/2009 01:43, "Dan Magenheimer" <dan.magenheimer@oracle.com> wrote:> When tsc_mode is pvrdtscp, tsc_aux is handled differently. > Also added some code for AMD svm pvrdtscp support... > needs more work I think. > > There may also be a better way to handle tscmode in the > x86_emulate.c code (but this code seems to live in > a different universe and adding the extra callout seemed > to work).I couldn''t see what the tscmode callout was for, so I removed it. I reworked and fixed up the rest of the patch and then applied it as changeset 20657. -- Keir _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
Dan Magenheimer
2009-Dec-17 15:54 UTC
RE: [Xen-devel] [PATCH] add pvrdtscp tsc_mode support for hvm
> > When tsc_mode is pvrdtscp, tsc_aux is handled differently. > > Also added some code for AMD svm pvrdtscp support... > > needs more work I think. > > > > There may also be a better way to handle tscmode in the > > x86_emulate.c code (but this code seems to live in > > a different universe and adding the extra callout seemed > > to work). > > I couldn''t see what the tscmode callout was for, so I removed it.It was only because I couldn''t #include asm/time.h into x86_emulate.c.> I reworked > and fixed up the rest of the patch and then applied it as > changeset 20657.Much nicer. Thanks! _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel