I'm starting to play with implementing softtsc for
PV guests, but am not adequately familiar with the low
level x86 instruction set or emulation code in Xen.
The attached patch seems to work fine for awhile.
Dom0 begins the boot process and the printk added
to traps.c observes more than 256K TSC traps (mostly
in the BogoMIPS calculation) and continues on loading
drivers etc but eventually freezes after:
device-mapper: ioctl: 4.7.0-ioctl (2006-06-24) initialised: dm-devel@xxxxxxxxxx
kjournald starting. Commit interval 5 seconds
EXT3-fs: mounted filesystem with ordered data mode.
Any ideas on what might be stopping the dom0 boot?
Possibly related, the code added to pv_guest_cr4_fixup()
in domain.c DOES catch a couple of attempts early in
boot by Linux trying to enable X86_CR4_TSD. Yet
the code handling RDTSC in emulate_privileged_op()
in traps.c doesn't appear to ever result in a call
to do_guest_trap(). Is this a bug at least on OS's
that do care about seeing rdtsc attempts by apps trapped?
Thanks,
Dan
diff -r 5619bed51ec4 xen/arch/x86/domain.c
--- a/xen/arch/x86/domain.c Fri Aug 14 17:26:23 2009 +0100
+++ b/xen/arch/x86/domain.c Fri Aug 21 15:33:36 2009 -0600
@@ -569,12 +569,13 @@ unsigned long pv_guest_cr4_fixup(unsigne
{
unsigned long hv_cr4_mask, hv_cr4 = real_cr4_to_pv_guest_cr4(read_cr4());
- hv_cr4_mask = ~X86_CR4_TSD;
+ hv_cr4_mask = (opt_softtsc ? ~0L : ~X86_CR4_TSD);
if ( cpu_has_de )
hv_cr4_mask &= ~X86_CR4_DE;
if ( (guest_cr4 & hv_cr4_mask) != (hv_cr4 & hv_cr4_mask) )
- gdprintk(XENLOG_WARNING,
+// gdprintk(XENLOG_WARNING,
+printk("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
"Attempt to change CR4 flags %08lx -> %08lx\n",
hv_cr4, guest_cr4);
diff -r 5619bed51ec4 xen/arch/x86/hvm/hvm.c
--- a/xen/arch/x86/hvm/hvm.c Fri Aug 14 17:26:23 2009 +0100
+++ b/xen/arch/x86/hvm/hvm.c Fri Aug 21 15:33:36 2009 -0600
@@ -61,8 +61,7 @@ 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);
+extern int opt_softtsc;
struct hvm_function_table hvm_funcs __read_mostly;
diff -r 5619bed51ec4 xen/arch/x86/time.c
--- a/xen/arch/x86/time.c Fri Aug 14 17:26:23 2009 +0100
+++ b/xen/arch/x86/time.c Fri Aug 21 15:33:36 2009 -0600
@@ -34,6 +34,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
diff -r 5619bed51ec4 xen/arch/x86/traps.c
--- a/xen/arch/x86/traps.c Fri Aug 14 17:26:23 2009 +0100
+++ b/xen/arch/x86/traps.c Fri Aug 21 15:33:36 2009 -0600
@@ -2266,6 +2266,12 @@ static int emulate_privileged_op(struct
}
case 0x31: /* RDTSC */
+{
+static unsigned long count = 0;
+++count;
+if (!(count & (count-1)))
+printk("TSC:%lu\n",count);
+}
rdtsc(regs->eax, regs->edx);
break;
diff -r 5619bed51ec4 xen/arch/x86/x86_emulate/x86_emulate.c
--- a/xen/arch/x86/x86_emulate/x86_emulate.c Fri Aug 14 17:26:23 2009 +0100
+++ b/xen/arch/x86/x86_emulate/x86_emulate.c Fri Aug 21 15:33:36 2009 -0600
@@ -47,6 +47,8 @@
#define Mov (1<<7)
/* All operands are implicit in the opcode. */
#define ImplicitOps (DstImplicit|SrcImplicit)
+
+extern int opt_softtsc;
static uint8_t opcode_table[256] = {
/* 0x00 - 0x07 */
@@ -3714,10 +3716,12 @@ x86_emulate(
case 0x31: /* rdtsc */ {
unsigned long cr4;
uint64_t val;
+printk("DJM: RDTSC in x86_emulate\n");
fail_if(ops->read_cr == NULL);
if ( (rc = ops->read_cr(4, &cr4, ctxt)) )
goto done;
- generate_exception_if((cr4 & CR4_TSD) && !mode_ring0(), EXC_GP, 0);
+ if ( !opt_softtsc )
+ generate_exception_if((cr4 & CR4_TSD) && !mode_ring0(), EXC_GP, 0);
fail_if(ops->read_msr == NULL);
if ( (rc = ops->read_msr(MSR_TSC, &val, ctxt)) != 0 )
goto done;
diff -r 5619bed51ec4 xen/include/asm-x86/domain.h
--- a/xen/include/asm-x86/domain.h Fri Aug 14 17:26:23 2009 +0100
+++ b/xen/include/asm-x86/domain.h Fri Aug 21 15:33:36 2009 -0600
@@ -2,6 +2,7 @@
#define __ASM_DOMAIN_H__
#include <xen/config.h>
+#include <xen/mm.h>
#include <xen/mm.h>
#include <asm/hvm/vcpu.h>
#include <asm/hvm/domain.h>
@@ -426,10 +427,12 @@ 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. */
+extern int opt_softtsc;
#define pv_guest_cr4_to_real_cr4(c) \
- (((c) | (mmu_cr4_features & (X86_CR4_PGE | X86_CR4_PSE))) & ~X86_CR4_DE)
+ ((((c) | (mmu_cr4_features & (X86_CR4_PGE | X86_CR4_PSE))) & ~X86_CR4_DE) \
+ | (opt_softtsc ? X86_CR4_TSD : 0))
#define real_cr4_to_pv_guest_cr4(c) \
- ((c) & ~(X86_CR4_PGE | X86_CR4_PSE))
+ ((c) & ~(X86_CR4_PGE | X86_CR4_PSE | (opt_softtsc ? X86_CR4_TSD : 0)))
void domain_cpuid(struct domain *d,
unsigned int input,
_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-devel
|