WARNING - OLD ARCHIVES

This is an archived copy of the Xen.org mailing list, which we have preserved to ensure that existing links to archives are not broken. The live archive, which contains the latest emails, can be found at http://lists.xen.org/
   
 
 
Xen 
 
Home Products Support Community News
 
   
 

xen-devel

[Xen-devel] [PATCH] add pvrdtscp tsc_mode support for hvm

To: "Xen-Devel (E-mail)" <xen-devel@xxxxxxxxxxxxxxxxxxx>
Subject: [Xen-devel] [PATCH] add pvrdtscp tsc_mode support for hvm
From: Dan Magenheimer <dan.magenheimer@xxxxxxxxxx>
Date: Wed, 16 Dec 2009 17:43:22 -0800 (PST)
Cc: Andre Przywara <andre.przywara@xxxxxxx>
Delivery-date: Wed, 16 Dec 2009 17:44:11 -0800
Envelope-to: www-data@xxxxxxxxxxxxxxxxxxx
List-help: <mailto:xen-devel-request@lists.xensource.com?subject=help>
List-id: Xen developer discussion <xen-devel.lists.xensource.com>
List-post: <mailto:xen-devel@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/mailman/listinfo/xen-devel>, <mailto:xen-devel-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/mailman/listinfo/xen-devel>, <mailto:xen-devel-request@lists.xensource.com?subject=unsubscribe>
Sender: xen-devel-bounces@xxxxxxxxxxxxxxxxxxx
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
<Prev in Thread] Current Thread [Next in Thread>