Merge branch 'x86-fixes-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip
* 'x86-fixes-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip: x86: fix resume (S2R) broken by Intel microcode module, on A110L x86 gart: don't complain if no AMD GART found AMD IOMMU: panic if completion wait loop fails AMD IOMMU: set cmd buffer pointers to zero manually x86: re-enable MCE on secondary CPUS after suspend/resume AMD IOMMU: allocate rlookup_table with __GFP_ZERO
This commit is contained in:
@@ -235,8 +235,9 @@ static int iommu_completion_wait(struct amd_iommu *iommu)
|
|||||||
status &= ~MMIO_STATUS_COM_WAIT_INT_MASK;
|
status &= ~MMIO_STATUS_COM_WAIT_INT_MASK;
|
||||||
writel(status, iommu->mmio_base + MMIO_STATUS_OFFSET);
|
writel(status, iommu->mmio_base + MMIO_STATUS_OFFSET);
|
||||||
|
|
||||||
if (unlikely((i == EXIT_LOOP_COUNT) && printk_ratelimit()))
|
if (unlikely(i == EXIT_LOOP_COUNT))
|
||||||
printk(KERN_WARNING "AMD IOMMU: Completion wait loop failed\n");
|
panic("AMD IOMMU: Completion wait loop failed\n");
|
||||||
|
|
||||||
out:
|
out:
|
||||||
spin_unlock_irqrestore(&iommu->lock, flags);
|
spin_unlock_irqrestore(&iommu->lock, flags);
|
||||||
|
|
||||||
|
@@ -427,6 +427,10 @@ static u8 * __init alloc_command_buffer(struct amd_iommu *iommu)
|
|||||||
memcpy_toio(iommu->mmio_base + MMIO_CMD_BUF_OFFSET,
|
memcpy_toio(iommu->mmio_base + MMIO_CMD_BUF_OFFSET,
|
||||||
&entry, sizeof(entry));
|
&entry, sizeof(entry));
|
||||||
|
|
||||||
|
/* set head and tail to zero manually */
|
||||||
|
writel(0x00, iommu->mmio_base + MMIO_CMD_HEAD_OFFSET);
|
||||||
|
writel(0x00, iommu->mmio_base + MMIO_CMD_TAIL_OFFSET);
|
||||||
|
|
||||||
iommu_feature_enable(iommu, CONTROL_CMDBUF_EN);
|
iommu_feature_enable(iommu, CONTROL_CMDBUF_EN);
|
||||||
|
|
||||||
return cmd_buf;
|
return cmd_buf;
|
||||||
@@ -1074,7 +1078,8 @@ int __init amd_iommu_init(void)
|
|||||||
goto free;
|
goto free;
|
||||||
|
|
||||||
/* IOMMU rlookup table - find the IOMMU for a specific device */
|
/* IOMMU rlookup table - find the IOMMU for a specific device */
|
||||||
amd_iommu_rlookup_table = (void *)__get_free_pages(GFP_KERNEL,
|
amd_iommu_rlookup_table = (void *)__get_free_pages(
|
||||||
|
GFP_KERNEL | __GFP_ZERO,
|
||||||
get_order(rlookup_table_size));
|
get_order(rlookup_table_size));
|
||||||
if (amd_iommu_rlookup_table == NULL)
|
if (amd_iommu_rlookup_table == NULL)
|
||||||
goto free;
|
goto free;
|
||||||
|
@@ -510,12 +510,9 @@ static void __cpuinit mce_cpu_features(struct cpuinfo_x86 *c)
|
|||||||
*/
|
*/
|
||||||
void __cpuinit mcheck_init(struct cpuinfo_x86 *c)
|
void __cpuinit mcheck_init(struct cpuinfo_x86 *c)
|
||||||
{
|
{
|
||||||
static cpumask_t mce_cpus = CPU_MASK_NONE;
|
|
||||||
|
|
||||||
mce_cpu_quirks(c);
|
mce_cpu_quirks(c);
|
||||||
|
|
||||||
if (mce_dont_init ||
|
if (mce_dont_init ||
|
||||||
cpu_test_and_set(smp_processor_id(), mce_cpus) ||
|
|
||||||
!mce_available(c))
|
!mce_available(c))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@@ -272,13 +272,18 @@ static struct attribute_group mc_attr_group = {
|
|||||||
.name = "microcode",
|
.name = "microcode",
|
||||||
};
|
};
|
||||||
|
|
||||||
static void microcode_fini_cpu(int cpu)
|
static void __microcode_fini_cpu(int cpu)
|
||||||
{
|
{
|
||||||
struct ucode_cpu_info *uci = ucode_cpu_info + cpu;
|
struct ucode_cpu_info *uci = ucode_cpu_info + cpu;
|
||||||
|
|
||||||
mutex_lock(µcode_mutex);
|
|
||||||
microcode_ops->microcode_fini_cpu(cpu);
|
microcode_ops->microcode_fini_cpu(cpu);
|
||||||
uci->valid = 0;
|
uci->valid = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void microcode_fini_cpu(int cpu)
|
||||||
|
{
|
||||||
|
mutex_lock(µcode_mutex);
|
||||||
|
__microcode_fini_cpu(cpu);
|
||||||
mutex_unlock(µcode_mutex);
|
mutex_unlock(µcode_mutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -306,12 +311,16 @@ static int microcode_resume_cpu(int cpu)
|
|||||||
* to this cpu (a bit of paranoia):
|
* to this cpu (a bit of paranoia):
|
||||||
*/
|
*/
|
||||||
if (microcode_ops->collect_cpu_info(cpu, &nsig)) {
|
if (microcode_ops->collect_cpu_info(cpu, &nsig)) {
|
||||||
microcode_fini_cpu(cpu);
|
__microcode_fini_cpu(cpu);
|
||||||
|
printk(KERN_ERR "failed to collect_cpu_info for resuming cpu #%d\n",
|
||||||
|
cpu);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (memcmp(&nsig, &uci->cpu_sig, sizeof(nsig))) {
|
if ((nsig.sig != uci->cpu_sig.sig) || (nsig.pf != uci->cpu_sig.pf)) {
|
||||||
microcode_fini_cpu(cpu);
|
__microcode_fini_cpu(cpu);
|
||||||
|
printk(KERN_ERR "cached ucode doesn't match the resuming cpu #%d\n",
|
||||||
|
cpu);
|
||||||
/* Should we look for a new ucode here? */
|
/* Should we look for a new ucode here? */
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@@ -155,6 +155,7 @@ static DEFINE_SPINLOCK(microcode_update_lock);
|
|||||||
static int collect_cpu_info(int cpu_num, struct cpu_signature *csig)
|
static int collect_cpu_info(int cpu_num, struct cpu_signature *csig)
|
||||||
{
|
{
|
||||||
struct cpuinfo_x86 *c = &cpu_data(cpu_num);
|
struct cpuinfo_x86 *c = &cpu_data(cpu_num);
|
||||||
|
unsigned long flags;
|
||||||
unsigned int val[2];
|
unsigned int val[2];
|
||||||
|
|
||||||
memset(csig, 0, sizeof(*csig));
|
memset(csig, 0, sizeof(*csig));
|
||||||
@@ -174,11 +175,16 @@ static int collect_cpu_info(int cpu_num, struct cpu_signature *csig)
|
|||||||
csig->pf = 1 << ((val[1] >> 18) & 7);
|
csig->pf = 1 << ((val[1] >> 18) & 7);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* serialize access to the physical write to MSR 0x79 */
|
||||||
|
spin_lock_irqsave(µcode_update_lock, flags);
|
||||||
|
|
||||||
wrmsr(MSR_IA32_UCODE_REV, 0, 0);
|
wrmsr(MSR_IA32_UCODE_REV, 0, 0);
|
||||||
/* see notes above for revision 1.07. Apparent chip bug */
|
/* see notes above for revision 1.07. Apparent chip bug */
|
||||||
sync_core();
|
sync_core();
|
||||||
/* get the current revision from MSR 0x8B */
|
/* get the current revision from MSR 0x8B */
|
||||||
rdmsr(MSR_IA32_UCODE_REV, val[0], csig->rev);
|
rdmsr(MSR_IA32_UCODE_REV, val[0], csig->rev);
|
||||||
|
spin_unlock_irqrestore(µcode_update_lock, flags);
|
||||||
|
|
||||||
pr_debug("microcode: collect_cpu_info : sig=0x%x, pf=0x%x, rev=0x%x\n",
|
pr_debug("microcode: collect_cpu_info : sig=0x%x, pf=0x%x, rev=0x%x\n",
|
||||||
csig->sig, csig->pf, csig->rev);
|
csig->sig, csig->pf, csig->rev);
|
||||||
|
|
||||||
|
@@ -745,10 +745,8 @@ void __init gart_iommu_init(void)
|
|||||||
unsigned long scratch;
|
unsigned long scratch;
|
||||||
long i;
|
long i;
|
||||||
|
|
||||||
if (cache_k8_northbridges() < 0 || num_k8_northbridges == 0) {
|
if (cache_k8_northbridges() < 0 || num_k8_northbridges == 0)
|
||||||
printk(KERN_INFO "PCI-GART: No AMD GART found.\n");
|
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
|
|
||||||
#ifndef CONFIG_AGP_AMD64
|
#ifndef CONFIG_AGP_AMD64
|
||||||
no_agp = 1;
|
no_agp = 1;
|
||||||
|
Reference in New Issue
Block a user