Skip to content

Commit

Permalink
Merge branch 'x86-fixes-for-linus' of git://git.kernel.org/pub/scm/li…
Browse files Browse the repository at this point in the history
…nux/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
  • Loading branch information
Linus Torvalds committed Dec 20, 2008
2 parents 9a1d103 + 280a9ca commit e6a997e
Show file tree
Hide file tree
Showing 6 changed files with 30 additions and 14 deletions.
5 changes: 3 additions & 2 deletions arch/x86/kernel/amd_iommu.c
Original file line number Diff line number Diff line change
Expand Up @@ -235,8 +235,9 @@ static int iommu_completion_wait(struct amd_iommu *iommu)
status &= ~MMIO_STATUS_COM_WAIT_INT_MASK;
writel(status, iommu->mmio_base + MMIO_STATUS_OFFSET);

if (unlikely((i == EXIT_LOOP_COUNT) && printk_ratelimit()))
printk(KERN_WARNING "AMD IOMMU: Completion wait loop failed\n");
if (unlikely(i == EXIT_LOOP_COUNT))
panic("AMD IOMMU: Completion wait loop failed\n");

out:
spin_unlock_irqrestore(&iommu->lock, flags);

Expand Down
7 changes: 6 additions & 1 deletion arch/x86/kernel/amd_iommu_init.c
Original file line number Diff line number Diff line change
Expand Up @@ -427,6 +427,10 @@ static u8 * __init alloc_command_buffer(struct amd_iommu *iommu)
memcpy_toio(iommu->mmio_base + MMIO_CMD_BUF_OFFSET,
&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);

return cmd_buf;
Expand Down Expand Up @@ -1074,7 +1078,8 @@ int __init amd_iommu_init(void)
goto free;

/* 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));
if (amd_iommu_rlookup_table == NULL)
goto free;
Expand Down
3 changes: 0 additions & 3 deletions arch/x86/kernel/cpu/mcheck/mce_64.c
Original file line number Diff line number Diff line change
Expand Up @@ -510,12 +510,9 @@ static void __cpuinit mce_cpu_features(struct cpuinfo_x86 *c)
*/
void __cpuinit mcheck_init(struct cpuinfo_x86 *c)
{
static cpumask_t mce_cpus = CPU_MASK_NONE;

mce_cpu_quirks(c);

if (mce_dont_init ||
cpu_test_and_set(smp_processor_id(), mce_cpus) ||
!mce_available(c))
return;

Expand Down
19 changes: 14 additions & 5 deletions arch/x86/kernel/microcode_core.c
Original file line number Diff line number Diff line change
Expand Up @@ -272,13 +272,18 @@ static struct attribute_group mc_attr_group = {
.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;

mutex_lock(&microcode_mutex);
microcode_ops->microcode_fini_cpu(cpu);
uci->valid = 0;
}

static void microcode_fini_cpu(int cpu)
{
mutex_lock(&microcode_mutex);
__microcode_fini_cpu(cpu);
mutex_unlock(&microcode_mutex);
}

Expand Down Expand Up @@ -306,12 +311,16 @@ static int microcode_resume_cpu(int cpu)
* to this cpu (a bit of paranoia):
*/
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;
}

if (memcmp(&nsig, &uci->cpu_sig, sizeof(nsig))) {
microcode_fini_cpu(cpu);
if ((nsig.sig != uci->cpu_sig.sig) || (nsig.pf != uci->cpu_sig.pf)) {
__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? */
return 1;
}
Expand Down
6 changes: 6 additions & 0 deletions arch/x86/kernel/microcode_intel.c
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,7 @@ static DEFINE_SPINLOCK(microcode_update_lock);
static int collect_cpu_info(int cpu_num, struct cpu_signature *csig)
{
struct cpuinfo_x86 *c = &cpu_data(cpu_num);
unsigned long flags;
unsigned int val[2];

memset(csig, 0, sizeof(*csig));
Expand All @@ -174,11 +175,16 @@ static int collect_cpu_info(int cpu_num, struct cpu_signature *csig)
csig->pf = 1 << ((val[1] >> 18) & 7);
}

/* serialize access to the physical write to MSR 0x79 */
spin_lock_irqsave(&microcode_update_lock, flags);

wrmsr(MSR_IA32_UCODE_REV, 0, 0);
/* see notes above for revision 1.07. Apparent chip bug */
sync_core();
/* get the current revision from MSR 0x8B */
rdmsr(MSR_IA32_UCODE_REV, val[0], csig->rev);
spin_unlock_irqrestore(&microcode_update_lock, flags);

pr_debug("microcode: collect_cpu_info : sig=0x%x, pf=0x%x, rev=0x%x\n",
csig->sig, csig->pf, csig->rev);

Expand Down
4 changes: 1 addition & 3 deletions arch/x86/kernel/pci-gart_64.c
Original file line number Diff line number Diff line change
Expand Up @@ -745,10 +745,8 @@ void __init gart_iommu_init(void)
unsigned long scratch;
long i;

if (cache_k8_northbridges() < 0 || num_k8_northbridges == 0) {
printk(KERN_INFO "PCI-GART: No AMD GART found.\n");
if (cache_k8_northbridges() < 0 || num_k8_northbridges == 0)
return;
}

#ifndef CONFIG_AGP_AMD64
no_agp = 1;
Expand Down

0 comments on commit e6a997e

Please sign in to comment.