diff options
Diffstat (limited to 'sys')
-rw-r--r-- | sys/amd64/include/clock.h | 3 | ||||
-rw-r--r-- | sys/amd64/vmm/x86.c | 19 | ||||
-rw-r--r-- | sys/x86/x86/tsc.c | 2 |
3 files changed, 22 insertions, 2 deletions
diff --git a/sys/amd64/include/clock.h b/sys/amd64/include/clock.h index d2602d8..d7f7d82 100644 --- a/sys/amd64/include/clock.h +++ b/sys/amd64/include/clock.h @@ -20,6 +20,9 @@ extern int i8254_max_count; extern uint64_t tsc_freq; extern int tsc_is_invariant; extern int tsc_perf_stat; +#ifdef SMP +extern int smp_tsc; +#endif void i8254_init(void); diff --git a/sys/amd64/vmm/x86.c b/sys/amd64/vmm/x86.c index 13eaaad..fa2eabc 100644 --- a/sys/amd64/vmm/x86.c +++ b/sys/amd64/vmm/x86.c @@ -34,6 +34,7 @@ __FBSDID("$FreeBSD$"); #include <sys/systm.h> #include <sys/cpuset.h> +#include <machine/clock.h> #include <machine/cpufunc.h> #include <machine/md_var.h> #include <machine/specialreg.h> @@ -89,11 +90,27 @@ x86_emulate_cpuid(struct vm *vm, int vcpu_id, case CPUID_8000_0003: case CPUID_8000_0004: case CPUID_8000_0006: - case CPUID_8000_0007: case CPUID_8000_0008: cpuid_count(*eax, *ecx, regs); break; + case CPUID_8000_0007: + cpuid_count(*eax, *ecx, regs); + /* + * If the host TSCs are not synchronized across + * physical cpus then we cannot advertise an + * invariant tsc to a vcpu. + * + * XXX This still falls short because the vcpu + * can observe the TSC moving backwards as it + * migrates across physical cpus. But at least + * it should discourage the guest from using the + * TSC to keep track of time. + */ + if (!smp_tsc) + regs[3] &= ~AMDPM_TSC_INVARIANT; + break; + case CPUID_0000_0001: do_cpuid(1, regs); diff --git a/sys/x86/x86/tsc.c b/sys/x86/x86/tsc.c index 4f67818..0994e9c 100644 --- a/sys/x86/x86/tsc.c +++ b/sys/x86/x86/tsc.c @@ -61,7 +61,7 @@ SYSCTL_INT(_kern_timecounter, OID_AUTO, invariant_tsc, CTLFLAG_RDTUN, TUNABLE_INT("kern.timecounter.invariant_tsc", &tsc_is_invariant); #ifdef SMP -static int smp_tsc; +int smp_tsc; SYSCTL_INT(_kern_timecounter, OID_AUTO, smp_tsc, CTLFLAG_RDTUN, &smp_tsc, 0, "Indicates whether the TSC is safe to use in SMP mode"); TUNABLE_INT("kern.timecounter.smp_tsc", &smp_tsc); |