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-changelog

[Xen-changelog] [xen-unstable] x86: softtsc for PV domains

To: xen-changelog@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-changelog] [xen-unstable] x86: softtsc for PV domains
From: Xen patchbot-unstable <patchbot-unstable@xxxxxxxxxxxxxxxxxxx>
Date: Thu, 27 Aug 2009 03:30:14 -0700
Delivery-date: Thu, 27 Aug 2009 03:30:29 -0700
Envelope-to: www-data@xxxxxxxxxxxxxxxxxxx
List-help: <mailto:xen-changelog-request@lists.xensource.com?subject=help>
List-id: BK change log <xen-changelog.lists.xensource.com>
List-post: <mailto:xen-changelog@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=unsubscribe>
Reply-to: xen-devel@xxxxxxxxxxxxxxxxxxx
Sender: xen-changelog-bounces@xxxxxxxxxxxxxxxxxxx
# HG changeset patch
# User Keir Fraser <keir.fraser@xxxxxxxxxx>
# Date 1251368734 -3600
# Node ID e8004f6c254a5778b50babd527e74208981640b9
# Parent  b63b1db5b388ef92bc1ecd709ddb0d357cf2d6b7
x86: softtsc for PV domains

Implement softtsc (TSC emulation) for userland code in PV domains.  It
currently is tied to the existing "softtsc" Xen boot option (which
does the same thing but for HVM domains).  Later it should be tied to
a vm.cfg option, but this is sufficient for now to obtain performance
degradation data for PV environments that heavily utilize rdtsc.  To
record emulation frequency, use debug-key "s".

Signed-off-by: Dan Magenheimer <dan.magenheimer@xxxxxxxxxx>
Signed-off-by: Keir Fraser <keir.fraser@xxxxxxxxxx>
---
 xen/arch/x86/domain.c             |    6 +++-
 xen/arch/x86/hvm/hvm.c            |    3 --
 xen/arch/x86/time.c               |   55 ++++++++++++++++++++++++++++++++++++++
 xen/arch/x86/traps.c              |   16 ++++++-----
 xen/include/asm-x86/domain.h      |   15 ++++++++--
 xen/include/asm-x86/hvm/support.h |    1 
 xen/include/asm-x86/time.h        |    3 ++
 7 files changed, 84 insertions(+), 15 deletions(-)

diff -r b63b1db5b388 -r e8004f6c254a xen/arch/x86/domain.c
--- a/xen/arch/x86/domain.c     Thu Aug 27 10:13:13 2009 +0100
+++ b/xen/arch/x86/domain.c     Thu Aug 27 11:25:34 2009 +0100
@@ -516,6 +516,10 @@ int arch_domain_create(struct domain *d,
         d->arch.cpuids[i].input[1] = XEN_CPUID_INPUT_UNUSED;
     }
 
+    /* For now, per-domain SoftTSC status is taken from global boot param. */
+    d->arch.vtsc = opt_softtsc;
+    spin_lock_init(&d->arch.vtsc_lock);
+
     return 0;
 
  fail:
@@ -1259,7 +1263,7 @@ static void paravirt_ctxt_switch_to(stru
     set_int80_direct_trap(v);
     switch_kernel_stack(v);
 
-    cr4 = pv_guest_cr4_to_real_cr4(v->arch.guest_context.ctrlreg[4]);
+    cr4 = pv_guest_cr4_to_real_cr4(v);
     if ( unlikely(cr4 != read_cr4()) )
         write_cr4(cr4);
 
diff -r b63b1db5b388 -r e8004f6c254a xen/arch/x86/hvm/hvm.c
--- a/xen/arch/x86/hvm/hvm.c    Thu Aug 27 10:13:13 2009 +0100
+++ b/xen/arch/x86/hvm/hvm.c    Thu Aug 27 11:25:34 2009 +0100
@@ -61,9 +61,6 @@ unsigned int opt_hvm_debug_level __read_
 unsigned int opt_hvm_debug_level __read_mostly;
 integer_param("hvm_debug", opt_hvm_debug_level);
 
-int opt_softtsc;
-boolean_param("softtsc", opt_softtsc);
-
 struct hvm_function_table hvm_funcs __read_mostly;
 
 /* I/O permission bitmap is globally shared by all HVM guests. */
diff -r b63b1db5b388 -r e8004f6c254a xen/arch/x86/time.c
--- a/xen/arch/x86/time.c       Thu Aug 27 10:13:13 2009 +0100
+++ b/xen/arch/x86/time.c       Thu Aug 27 11:25:34 2009 +0100
@@ -21,6 +21,7 @@
 #include <xen/smp.h>
 #include <xen/irq.h>
 #include <xen/softirq.h>
+#include <xen/keyhandler.h>
 #include <asm/io.h>
 #include <asm/msr.h>
 #include <asm/mpspec.h>
@@ -34,6 +35,9 @@
 /* opt_clocksource: Force clocksource to one of: pit, hpet, cyclone, acpi. */
 static char opt_clocksource[10];
 string_param("clocksource", opt_clocksource);
+
+int opt_softtsc;
+boolean_param("softtsc", opt_softtsc);
 
 /*
  * opt_consistent_tscs: All TSCs tick at the exact same rate, allowing
@@ -1429,6 +1433,57 @@ struct tm wallclock_time(void)
     return gmtime(seconds);
 }
 
+
+/*
+ * PV SoftTSC Emulation.
+ */
+
+static unsigned long rdtsc_kerncount, rdtsc_usercount;
+
+void pv_soft_rdtsc(struct vcpu *v, struct cpu_user_regs *regs)
+{
+    s_time_t now;
+
+    if ( guest_kernel_mode(v, regs) )
+    {
+        rdtsc_kerncount++;
+        rdtsc(regs->eax, regs->edx);
+    }
+    else
+    { 
+        rdtsc_usercount++;
+        spin_lock(&v->domain->arch.vtsc_lock);
+        now = get_s_time() + v->domain->arch.vtsc_stime_offset;
+        if ( (int64_t)(now - v->domain->arch.vtsc_last) >= 0 )
+            v->domain->arch.vtsc_last = now;
+        else
+            now = v->domain->arch.vtsc_last;
+        spin_unlock(&v->domain->arch.vtsc_lock);
+        regs->eax = (uint32_t)now;
+        regs->edx = (uint32_t)(now >> 32);
+    }
+}
+
+static void dump_softtsc(unsigned char key)
+{
+    printk("softtsc count: %lu kernel, %lu user\n",
+           rdtsc_kerncount, rdtsc_usercount);
+}
+
+static struct keyhandler dump_softtsc_keyhandler = {
+    .diagnostic = 1,
+    .u.fn = dump_softtsc,
+    .desc = "dump softtsc stats"
+};
+
+static int __init setup_dump_softtsc(void)
+{
+    if ( opt_softtsc )
+        register_keyhandler('s', &dump_softtsc_keyhandler);
+    return 0;
+}
+__initcall(setup_dump_softtsc);
+
 /*
  * Local variables:
  * mode: C
diff -r b63b1db5b388 -r e8004f6c254a xen/arch/x86/traps.c
--- a/xen/arch/x86/traps.c      Thu Aug 27 10:13:13 2009 +0100
+++ b/xen/arch/x86/traps.c      Thu Aug 27 11:25:34 2009 +0100
@@ -2005,12 +2005,15 @@ static int emulate_privileged_op(struct 
     goto fail;
 
  twobyte_opcode:
-    /* Two-byte opcodes only emulated from guest kernel. */
-    if ( !guest_kernel_mode(v, regs) )
+    /*
+     * All two-byte opcodes, except RDTSC (0x31) are executable only from
+     * guest kernel mode (virtual ring 0).
+     */
+    opcode = insn_fetch(u8, code_base, eip, code_limit);
+    if ( !guest_kernel_mode(v, regs) &&
+         !((opcode == 0x31) && v->domain->arch.vtsc) )
         goto fail;
 
-    /* Privileged (ring 0) instructions. */
-    opcode = insn_fetch(u8, code_base, eip, code_limit);
     if ( lock && (opcode & ~3) != 0x20 )
         goto fail;
     switch ( opcode )
@@ -2127,8 +2130,7 @@ static int emulate_privileged_op(struct 
 
         case 4: /* Write CR4 */
             v->arch.guest_context.ctrlreg[4] = pv_guest_cr4_fixup(*reg);
-            write_cr4(pv_guest_cr4_to_real_cr4(
-                v->arch.guest_context.ctrlreg[4]));
+            write_cr4(pv_guest_cr4_to_real_cr4(v));
             break;
 
         default:
@@ -2266,7 +2268,7 @@ static int emulate_privileged_op(struct 
     }
 
     case 0x31: /* RDTSC */
-        rdtsc(regs->eax, regs->edx);
+        pv_soft_rdtsc(v, regs);
         break;
 
     case 0x32: /* RDMSR */
diff -r b63b1db5b388 -r e8004f6c254a xen/include/asm-x86/domain.h
--- a/xen/include/asm-x86/domain.h      Thu Aug 27 10:13:13 2009 +0100
+++ b/xen/include/asm-x86/domain.h      Thu Aug 27 11:25:34 2009 +0100
@@ -299,6 +299,12 @@ struct arch_domain
 
     /* For Guest vMCA handling */
     struct domain_mca_msrs vmca_msrs;
+
+    /* SoftTSC emulation */
+    bool_t vtsc;
+    s_time_t vtsc_last;
+    spinlock_t vtsc_lock;
+    int64_t vtsc_stime_offset;
 } __cacheline_aligned;
 
 #define has_arch_pdevs(d)    (!list_empty(&(d)->arch.pdev_list))
@@ -426,10 +432,13 @@ unsigned long pv_guest_cr4_fixup(unsigne
 unsigned long pv_guest_cr4_fixup(unsigned long guest_cr4);
 
 /* Convert between guest-visible and real CR4 values. */
-#define pv_guest_cr4_to_real_cr4(c) \
-    (((c) | (mmu_cr4_features & (X86_CR4_PGE | X86_CR4_PSE))) & ~X86_CR4_DE)
+#define pv_guest_cr4_to_real_cr4(v)                         \
+    (((v)->arch.guest_context.ctrlreg[4]                    \
+      | (mmu_cr4_features & (X86_CR4_PGE | X86_CR4_PSE))    \
+      | ((v)->domain->arch.vtsc ? X86_CR4_TSD : 0))         \
+      & ~X86_CR4_DE)
 #define real_cr4_to_pv_guest_cr4(c) \
-    ((c) & ~(X86_CR4_PGE | X86_CR4_PSE))
+    ((c) & ~(X86_CR4_PGE | X86_CR4_PSE | X86_CR4_TSD))
 
 void domain_cpuid(struct domain *d,
                   unsigned int  input,
diff -r b63b1db5b388 -r e8004f6c254a xen/include/asm-x86/hvm/support.h
--- a/xen/include/asm-x86/hvm/support.h Thu Aug 27 10:13:13 2009 +0100
+++ b/xen/include/asm-x86/hvm/support.h Thu Aug 27 11:25:34 2009 +0100
@@ -126,7 +126,6 @@ void hvm_hlt(unsigned long rflags);
 void hvm_hlt(unsigned long rflags);
 void hvm_triple_fault(void);
 
-extern int opt_softtsc;
 void hvm_rdtsc_intercept(struct cpu_user_regs *regs);
 
 /* These functions all return X86EMUL return codes. */
diff -r b63b1db5b388 -r e8004f6c254a xen/include/asm-x86/time.h
--- a/xen/include/asm-x86/time.h        Thu Aug 27 10:13:13 2009 +0100
+++ b/xen/include/asm-x86/time.h        Thu Aug 27 11:25:34 2009 +0100
@@ -41,4 +41,7 @@ uint64_t acpi_pm_tick_to_ns(uint64_t tic
 uint64_t acpi_pm_tick_to_ns(uint64_t ticks);
 uint64_t ns_to_acpi_pm_tick(uint64_t ns);
 
+extern int opt_softtsc;
+void pv_soft_rdtsc(struct vcpu *v, struct cpu_user_regs *regs);
+
 #endif /* __X86_TIME_H__ */

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

<Prev in Thread] Current Thread [Next in Thread>
  • [Xen-changelog] [xen-unstable] x86: softtsc for PV domains, Xen patchbot-unstable <=