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@xxxxxxxxxx>
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;
hvm-pvrdtscp.patch
Description: Binary data
_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-devel
|