At 10:41 +0100 on 22 Apr (1271932883), Qing He wrote:
> L2 TSC needs special handling, either rdtsc exiting is
> turned on or off
Looks OK to me, but I'm a bit behind on some of the recent changes to
TSC handling.
Tim.
> Signed-off-by: Qing He <qing.he@xxxxxxxxx>
>
> ---
> arch/x86/hvm/vmx/nest.c | 31 +++++++++++++++++++++++++++++++
> arch/x86/hvm/vmx/vmx.c | 4 ++++
> include/asm-x86/hvm/vmx/nest.h | 2 ++
> 3 files changed, 37 insertions(+)
>
> diff -r 2f9ba6dbbe62 -r 2332586ff957 xen/arch/x86/hvm/vmx/nest.c
> --- a/xen/arch/x86/hvm/vmx/nest.c Thu Apr 22 22:30:09 2010 +0800
> +++ b/xen/arch/x86/hvm/vmx/nest.c Thu Apr 22 22:30:09 2010 +0800
> @@ -533,6 +533,18 @@
> * Nested VMX context switch
> */
>
> +u64 vmx_nest_get_tsc_offset(struct vcpu *v)
> +{
> + u64 offset = 0;
> + struct vmx_nest_struct *nest = &v->arch.hvm_vmx.nest;
> +
> + if ( __get_vvmcs(nest->vvmcs, CPU_BASED_VM_EXEC_CONTROL) &
> + CPU_BASED_USE_TSC_OFFSETING )
> + offset = __get_vvmcs(nest->vvmcs, TSC_OFFSET);
> +
> + return offset;
> +}
> +
> static unsigned long vmcs_gstate_field[] = {
> /* 16 BITS */
> GUEST_ES_SELECTOR,
> @@ -715,6 +727,8 @@
> hvm_set_cr4(__get_vvmcs(nest->vvmcs, GUEST_CR4));
> hvm_set_cr3(__get_vvmcs(nest->vvmcs, GUEST_CR3));
>
> + hvm_funcs.set_tsc_offset(v, v->arch.hvm_vcpu.cache_tsc_offset);
> +
> vvmcs_to_shadow(nest->vvmcs, VM_ENTRY_INTR_INFO);
> vvmcs_to_shadow(nest->vvmcs, VM_ENTRY_EXCEPTION_ERROR_CODE);
> vvmcs_to_shadow(nest->vvmcs, VM_ENTRY_INSTRUCTION_LEN);
> @@ -837,6 +851,8 @@
> hvm_set_cr4(__get_vvmcs(nest->vvmcs, HOST_CR4));
> hvm_set_cr3(__get_vvmcs(nest->vvmcs, HOST_CR3));
>
> + hvm_funcs.set_tsc_offset(v, v->arch.hvm_vcpu.cache_tsc_offset);
> +
> __set_vvmcs(nest->vvmcs, VM_ENTRY_INTR_INFO, 0);
> }
>
> @@ -1116,6 +1132,21 @@
>
> if ( control_bit_for_reason[i].bit & ctrl )
> nest->vmexit_pending = 1;
> + else if ( exit_reason == EXIT_REASON_RDTSC )
> + {
> + uint64_t tsc;
> +
> + /*
> + * rdtsc can't be handled normally in the L0 handler
> + * if L1 doesn't want it
> + */
> + tsc = hvm_get_guest_tsc(v);
> + tsc += __get_vvmcs(nest->vvmcs, TSC_OFFSET);
> + regs->eax = (uint32_t)tsc;
> + regs->edx = (uint32_t)(tsc >> 32);
> +
> + bypass_l0 = 1;
> + }
>
> break;
> }
> diff -r 2f9ba6dbbe62 -r 2332586ff957 xen/arch/x86/hvm/vmx/vmx.c
> --- a/xen/arch/x86/hvm/vmx/vmx.c Thu Apr 22 22:30:09 2010 +0800
> +++ b/xen/arch/x86/hvm/vmx/vmx.c Thu Apr 22 22:30:09 2010 +0800
> @@ -974,6 +974,10 @@
> static void vmx_set_tsc_offset(struct vcpu *v, u64 offset)
> {
> vmx_vmcs_enter(v);
> +
> + if ( v->arch.hvm_vcpu.in_nesting )
> + offset += vmx_nest_get_tsc_offset(v);
> +
> __vmwrite(TSC_OFFSET, offset);
> #if defined (__i386__)
> __vmwrite(TSC_OFFSET_HIGH, offset >> 32);
> diff -r 2f9ba6dbbe62 -r 2332586ff957 xen/include/asm-x86/hvm/vmx/nest.h
> --- a/xen/include/asm-x86/hvm/vmx/nest.h Thu Apr 22 22:30:09 2010 +0800
> +++ b/xen/include/asm-x86/hvm/vmx/nest.h Thu Apr 22 22:30:09 2010 +0800
> @@ -69,6 +69,8 @@
> unsigned long value);
> void vmx_nest_update_exception_bitmap(struct vcpu *v, unsigned long value);
>
> +u64 vmx_nest_get_tsc_offset(struct vcpu *v);
> +
> void vmx_nest_idtv_handling(void);
>
> int vmx_nest_l2_vmexit_handler(struct cpu_user_regs *regs,
>
> _______________________________________________
> Xen-devel mailing list
> Xen-devel@xxxxxxxxxxxxxxxxxxx
> http://lists.xensource.com/xen-devel
--
Tim Deegan <Tim.Deegan@xxxxxxxxxx>
Principal Software Engineer, XenServer Engineering
Citrix Systems UK Ltd. (Company #02937203, SL9 0BG)
_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-devel
|