Merge branch 'linus' into perfcounters/rename
Merge reason: pull in all the latest code before doing the rename. Signed-off-by: Ingo Molnar <mingo@elte.hu>
This commit is contained in:
@@ -34,7 +34,6 @@
|
||||
#include <asm/mce.h>
|
||||
#include <asm/msr.h>
|
||||
#include <asm/pat.h>
|
||||
#include <linux/smp.h>
|
||||
|
||||
#ifdef CONFIG_X86_LOCAL_APIC
|
||||
#include <asm/uv/uv.h>
|
||||
|
@@ -523,6 +523,21 @@ static const struct dmi_system_id sw_any_bug_dmi_table[] = {
|
||||
},
|
||||
{ }
|
||||
};
|
||||
|
||||
static int acpi_cpufreq_blacklist(struct cpuinfo_x86 *c)
|
||||
{
|
||||
/* http://www.intel.com/Assets/PDF/specupdate/314554.pdf
|
||||
* AL30: A Machine Check Exception (MCE) Occurring during an
|
||||
* Enhanced Intel SpeedStep Technology Ratio Change May Cause
|
||||
* Both Processor Cores to Lock Up when HT is enabled*/
|
||||
if (c->x86_vendor == X86_VENDOR_INTEL) {
|
||||
if ((c->x86 == 15) &&
|
||||
(c->x86_model == 6) &&
|
||||
(c->x86_mask == 8) && smt_capable())
|
||||
return -ENODEV;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
static int acpi_cpufreq_cpu_init(struct cpufreq_policy *policy)
|
||||
@@ -537,6 +552,12 @@ static int acpi_cpufreq_cpu_init(struct cpufreq_policy *policy)
|
||||
|
||||
dprintk("acpi_cpufreq_cpu_init\n");
|
||||
|
||||
#ifdef CONFIG_SMP
|
||||
result = acpi_cpufreq_blacklist(c);
|
||||
if (result)
|
||||
return result;
|
||||
#endif
|
||||
|
||||
data = kzalloc(sizeof(struct acpi_cpufreq_data), GFP_KERNEL);
|
||||
if (!data)
|
||||
return -ENOMEM;
|
||||
|
@@ -605,9 +605,10 @@ static int check_pst_table(struct powernow_k8_data *data, struct pst_s *pst,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void invalidate_entry(struct powernow_k8_data *data, unsigned int entry)
|
||||
static void invalidate_entry(struct cpufreq_frequency_table *powernow_table,
|
||||
unsigned int entry)
|
||||
{
|
||||
data->powernow_table[entry].frequency = CPUFREQ_ENTRY_INVALID;
|
||||
powernow_table[entry].frequency = CPUFREQ_ENTRY_INVALID;
|
||||
}
|
||||
|
||||
static void print_basics(struct powernow_k8_data *data)
|
||||
@@ -854,6 +855,10 @@ static int powernow_k8_cpu_init_acpi(struct powernow_k8_data *data)
|
||||
goto err_out;
|
||||
}
|
||||
|
||||
/* fill in data */
|
||||
data->numps = data->acpi_data.state_count;
|
||||
powernow_k8_acpi_pst_values(data, 0);
|
||||
|
||||
if (cpu_family == CPU_HW_PSTATE)
|
||||
ret_val = fill_powernow_table_pstate(data, powernow_table);
|
||||
else
|
||||
@@ -866,11 +871,8 @@ static int powernow_k8_cpu_init_acpi(struct powernow_k8_data *data)
|
||||
powernow_table[data->acpi_data.state_count].index = 0;
|
||||
data->powernow_table = powernow_table;
|
||||
|
||||
/* fill in data */
|
||||
data->numps = data->acpi_data.state_count;
|
||||
if (cpumask_first(cpu_core_mask(data->cpu)) == data->cpu)
|
||||
print_basics(data);
|
||||
powernow_k8_acpi_pst_values(data, 0);
|
||||
|
||||
/* notify BIOS that we exist */
|
||||
acpi_processor_notify_smm(THIS_MODULE);
|
||||
@@ -914,13 +916,13 @@ static int fill_powernow_table_pstate(struct powernow_k8_data *data,
|
||||
"bad value %d.\n", i, index);
|
||||
printk(KERN_ERR PFX "Please report to BIOS "
|
||||
"manufacturer\n");
|
||||
invalidate_entry(data, i);
|
||||
invalidate_entry(powernow_table, i);
|
||||
continue;
|
||||
}
|
||||
rdmsr(MSR_PSTATE_DEF_BASE + index, lo, hi);
|
||||
if (!(hi & HW_PSTATE_VALID_MASK)) {
|
||||
dprintk("invalid pstate %d, ignoring\n", index);
|
||||
invalidate_entry(data, i);
|
||||
invalidate_entry(powernow_table, i);
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -941,7 +943,6 @@ static int fill_powernow_table_fidvid(struct powernow_k8_data *data,
|
||||
struct cpufreq_frequency_table *powernow_table)
|
||||
{
|
||||
int i;
|
||||
int cntlofreq = 0;
|
||||
|
||||
for (i = 0; i < data->acpi_data.state_count; i++) {
|
||||
u32 fid;
|
||||
@@ -970,7 +971,7 @@ static int fill_powernow_table_fidvid(struct powernow_k8_data *data,
|
||||
/* verify frequency is OK */
|
||||
if ((freq > (MAX_FREQ * 1000)) || (freq < (MIN_FREQ * 1000))) {
|
||||
dprintk("invalid freq %u kHz, ignoring\n", freq);
|
||||
invalidate_entry(data, i);
|
||||
invalidate_entry(powernow_table, i);
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -978,38 +979,17 @@ static int fill_powernow_table_fidvid(struct powernow_k8_data *data,
|
||||
* BIOSs are using "off" to indicate invalid */
|
||||
if (vid == VID_OFF) {
|
||||
dprintk("invalid vid %u, ignoring\n", vid);
|
||||
invalidate_entry(data, i);
|
||||
invalidate_entry(powernow_table, i);
|
||||
continue;
|
||||
}
|
||||
|
||||
/* verify only 1 entry from the lo frequency table */
|
||||
if (fid < HI_FID_TABLE_BOTTOM) {
|
||||
if (cntlofreq) {
|
||||
/* if both entries are the same,
|
||||
* ignore this one ... */
|
||||
if ((freq != powernow_table[cntlofreq].frequency) ||
|
||||
(index != powernow_table[cntlofreq].index)) {
|
||||
printk(KERN_ERR PFX
|
||||
"Too many lo freq table "
|
||||
"entries\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
dprintk("double low frequency table entry, "
|
||||
"ignoring it.\n");
|
||||
invalidate_entry(data, i);
|
||||
continue;
|
||||
} else
|
||||
cntlofreq = i;
|
||||
}
|
||||
|
||||
if (freq != (data->acpi_data.states[i].core_frequency * 1000)) {
|
||||
printk(KERN_INFO PFX "invalid freq entries "
|
||||
"%u kHz vs. %u kHz\n", freq,
|
||||
(unsigned int)
|
||||
(data->acpi_data.states[i].core_frequency
|
||||
* 1000));
|
||||
invalidate_entry(data, i);
|
||||
invalidate_entry(powernow_table, i);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
@@ -34,13 +34,6 @@ detect_hypervisor_vendor(struct cpuinfo_x86 *c)
|
||||
c->x86_hyper_vendor = X86_HYPER_VENDOR_NONE;
|
||||
}
|
||||
|
||||
unsigned long get_hypervisor_tsc_freq(void)
|
||||
{
|
||||
if (boot_cpu_data.x86_hyper_vendor == X86_HYPER_VENDOR_VMWARE)
|
||||
return vmware_get_tsc_khz();
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline void __cpuinit
|
||||
hypervisor_set_feature_bits(struct cpuinfo_x86 *c)
|
||||
{
|
||||
@@ -55,3 +48,10 @@ void __cpuinit init_hypervisor(struct cpuinfo_x86 *c)
|
||||
detect_hypervisor_vendor(c);
|
||||
hypervisor_set_feature_bits(c);
|
||||
}
|
||||
|
||||
void __init init_hypervisor_platform(void)
|
||||
{
|
||||
init_hypervisor(&boot_cpu_data);
|
||||
if (boot_cpu_data.x86_hyper_vendor == X86_HYPER_VENDOR_VMWARE)
|
||||
vmware_platform_setup();
|
||||
}
|
||||
|
@@ -24,6 +24,7 @@
|
||||
#include <linux/dmi.h>
|
||||
#include <asm/div64.h>
|
||||
#include <asm/vmware.h>
|
||||
#include <asm/x86_init.h>
|
||||
|
||||
#define CPUID_VMWARE_INFO_LEAF 0x40000000
|
||||
#define VMWARE_HYPERVISOR_MAGIC 0x564D5868
|
||||
@@ -47,21 +48,29 @@ static inline int __vmware_platform(void)
|
||||
return eax != (uint32_t)-1 && ebx == VMWARE_HYPERVISOR_MAGIC;
|
||||
}
|
||||
|
||||
static unsigned long __vmware_get_tsc_khz(void)
|
||||
static unsigned long vmware_get_tsc_khz(void)
|
||||
{
|
||||
uint64_t tsc_hz;
|
||||
uint32_t eax, ebx, ecx, edx;
|
||||
|
||||
VMWARE_PORT(GETHZ, eax, ebx, ecx, edx);
|
||||
|
||||
if (ebx == UINT_MAX)
|
||||
return 0;
|
||||
tsc_hz = eax | (((uint64_t)ebx) << 32);
|
||||
do_div(tsc_hz, 1000);
|
||||
BUG_ON(tsc_hz >> 32);
|
||||
return tsc_hz;
|
||||
}
|
||||
|
||||
void __init vmware_platform_setup(void)
|
||||
{
|
||||
uint32_t eax, ebx, ecx, edx;
|
||||
|
||||
VMWARE_PORT(GETHZ, eax, ebx, ecx, edx);
|
||||
|
||||
if (ebx != UINT_MAX)
|
||||
x86_platform.calibrate_tsc = vmware_get_tsc_khz;
|
||||
}
|
||||
|
||||
/*
|
||||
* While checking the dmi string infomation, just checking the product
|
||||
* serial key should be enough, as this will always have a VMware
|
||||
@@ -87,12 +96,6 @@ int vmware_platform(void)
|
||||
return 0;
|
||||
}
|
||||
|
||||
unsigned long vmware_get_tsc_khz(void)
|
||||
{
|
||||
BUG_ON(!vmware_platform());
|
||||
return __vmware_get_tsc_khz();
|
||||
}
|
||||
|
||||
/*
|
||||
* VMware hypervisor takes care of exporting a reliable TSC to the guest.
|
||||
* Still, due to timing difference when running on virtual cpus, the TSC can
|
||||
|
Reference in New Issue
Block a user