[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[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@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;

Attachment: hvm-pvrdtscp.patch
Description: Binary data

_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-devel

 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.