[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] Disable C1 clock ramping on AMD 8th gen CPUs.
# HG changeset patch # User kaf24@xxxxxxxxxxxxxxxxxxxx # Node ID eb6d2472ea1ac1275b2382735959217d26cc7933 # Parent 34f6a1efe52d8c5c722a2d423a0b26b469540a3a Disable C1 clock ramping on AMD 8th gen CPUs. This reverts a previous changeset that removed this code. It is currently required for good TSC behaviour in SVM (fully virtualised) guests. Signed-off-by: Keir Fraser <keir@xxxxxxxxxxxxx> diff -r 34f6a1efe52d -r eb6d2472ea1a xen/arch/x86/cpu/amd.c --- a/xen/arch/x86/cpu/amd.c Fri Feb 17 18:35:38 2006 +++ b/xen/arch/x86/cpu/amd.c Fri Feb 17 19:41:30 2006 @@ -41,6 +41,62 @@ extern void vide(void); __asm__(".text\n.align 4\nvide: ret"); + +/* Can this system suffer from TSC drift due to C1 clock ramping? */ +static int c1_ramping_may_cause_clock_drift(struct cpuinfo_x86 *c) +{ + if (c->x86 < 0xf) { + /* + * TSC drift doesn't exist on 7th Gen or less + * However, OS still needs to consider effects + * of P-state changes on TSC + */ + return 0; + } else if (cpuid_edx(0x80000007) & (1<<8)) { + /* + * CPUID.AdvPowerMgmtInfo.TscInvariant + * EDX bit 8, 8000_0007 + * Invariant TSC on 8th Gen or newer, use it + * (assume all cores have invariant TSC) + */ + return 0; + } + return 1; +} + +/* PCI access functions. Should be safe to use 0xcf8/0xcfc port accesses here. */ +static u8 pci_read_byte(u32 bus, u32 dev, u32 fn, u32 reg) +{ + outl((1U<<31) | (bus << 16) | (dev << 11) | (fn << 8) | (reg & ~3), 0xcf8); + return inb(0xcfc + (reg & 3)); +} + +static void pci_write_byte(u32 bus, u32 dev, u32 fn, u32 reg, u8 val) +{ + outl((1U<<31) | (bus << 16) | (dev << 11) | (fn << 8) | (reg & ~3), 0xcf8); + outb(val, 0xcfc + (reg & 3)); +} + +/* + * Disable C1-Clock ramping if enabled in PMM7.CpuLowPwrEnh on 8th-generation + * cores only. Assume BIOS has setup all Northbridges equivalently. + */ +static void disable_c1_ramping(void) +{ + u8 pmm7; + int node; + + for (node=0; node < NR_CPUS; node++) { + /* PMM7: bus=0, dev=0x18+node, function=0x3, register=0x87. */ + pmm7 = pci_read_byte(0, 0x18+node, 0x3, 0x87); + /* Invalid read means we've updated every Northbridge. */ + if (pmm7 == 0xFF) + break; + pmm7 &= 0xFC; /* clear pmm7[1:0] */ + pci_write_byte(0, 0x18+node, 0x3, 0x87, pmm7); + printk ("AMD: Disabling C1 Clock Ramping Node #%x\n", node); + } +} static void __init init_amd(struct cpuinfo_x86 *c) { @@ -274,6 +330,10 @@ cpu, c->x86_max_cores, cpu_core_id[cpu]); } #endif + + /* Prevent TSC drift in non single-processor, single-core platforms. */ + if ((smp_processor_id() == 1) && c1_ramping_may_cause_clock_drift(c)) + disable_c1_ramping(); start_svm(); } _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |