Skip to content

Commit

Permalink
[PATCH] x86: Allow disabling early pci scans with pci=noearly or disa…
Browse files Browse the repository at this point in the history
…llowing conf1

Some buggy systems can machine check when config space accesses
happen for some non existent devices.  i386/x86-64 do some early
device scans that might trigger this. Allow pci=noearly to disable
this. Also when type 1 is disabling also don't do any early
accesses which are always type1.

This moves the pci= configuration parsing to be a early parameter.
I don't think this can break anything because it only changes
a single global that is only used by PCI.

Cc: gregkh@suse.de
Cc: Trammell Hudson <hudson@osresearch.net>

Signed-off-by: Andi Kleen <ak@suse.de>
  • Loading branch information
Andi Kleen authored and Andi Kleen committed Sep 26, 2006
1 parent 8f60774 commit 0637a70
Show file tree
Hide file tree
Showing 12 changed files with 41 additions and 6 deletions.
6 changes: 5 additions & 1 deletion Documentation/kernel-parameters.txt
Original file line number Diff line number Diff line change
Expand Up @@ -1240,7 +1240,11 @@ running once the system is up.
bootloader. This is currently used on
IXP2000 systems where the bus has to be
configured a certain way for adjunct CPUs.

noearly [X86] Don't do any early type 1 scanning.
This might help on some broken boards which
machine check when some devices' config space
is read. But various workarounds are disabled
and some IOMMU drivers will not work.
pcmv= [HW,PCMCIA] BadgePAD 4

pd. [PARIDE]
Expand Down
6 changes: 5 additions & 1 deletion arch/i386/kernel/acpi/earlyquirk.c
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,11 @@ void __init check_acpi_pci(void)
int num, slot, func;

/* Assume the machine supports type 1. If not it will
always read ffffffff and should not have any side effect. */
always read ffffffff and should not have any side effect.
Actually a few buggy systems can machine check. Allow the user
to disable it by command line option at least -AK */
if (!early_pci_allowed())
return;

/* Poor man's PCI discovery */
for (num = 0; num < 32; num++) {
Expand Down
4 changes: 4 additions & 0 deletions arch/i386/pci/common.c
Original file line number Diff line number Diff line change
Expand Up @@ -242,6 +242,10 @@ char * __devinit pcibios_setup(char *str)
acpi_noirq_set();
return NULL;
}
else if (!strcmp(str, "noearly")) {
pci_probe |= PCI_PROBE_NOEARLY;
return NULL;
}
#ifndef CONFIG_X86_VISWS
else if (!strcmp(str, "usepirqmask")) {
pci_probe |= PCI_USE_PIRQ_MASK;
Expand Down
8 changes: 8 additions & 0 deletions arch/i386/pci/early.c
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
#include <linux/kernel.h>
#include <linux/pci.h>
#include <asm/pci-direct.h>
#include <asm/io.h>
#include "pci.h"

/* Direct PCI access. This is used for PCI accesses in early boot before
the PCI subsystem works. */
Expand Down Expand Up @@ -42,3 +44,9 @@ void write_pci_config(u8 bus, u8 slot, u8 func, u8 offset,
outl(0x80000000 | (bus<<16) | (slot<<11) | (func<<8) | offset, 0xcf8);
outl(val, 0xcfc);
}

int early_pci_allowed(void)
{
return (pci_probe & (PCI_PROBE_CONF1|PCI_PROBE_NOEARLY)) ==
PCI_PROBE_CONF1;
}
1 change: 1 addition & 0 deletions arch/i386/pci/pci.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
#define PCI_PROBE_CONF2 0x0004
#define PCI_PROBE_MMCONF 0x0008
#define PCI_PROBE_MASK 0x000f
#define PCI_PROBE_NOEARLY 0x0010

#define PCI_NO_SORT 0x0100
#define PCI_BIOS_SORT 0x0200
Expand Down
2 changes: 1 addition & 1 deletion arch/x86_64/kernel/aperture.c
Original file line number Diff line number Diff line change
Expand Up @@ -212,7 +212,7 @@ void __init iommu_hole_init(void)
u64 aper_base, last_aper_base = 0;
int valid_agp = 0;

if (iommu_aperture_disabled || !fix_aperture)
if (iommu_aperture_disabled || !fix_aperture || !early_pci_allowed())
return;

printk("Checking aperture...\n");
Expand Down
4 changes: 4 additions & 0 deletions arch/x86_64/kernel/early-quirks.c
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,10 @@ static struct chipset early_qrk[] = {
void __init early_quirks(void)
{
int num, slot, func;

if (!early_pci_allowed())
return;

/* Poor man's PCI discovery */
for (num = 0; num < 32; num++) {
for (slot = 0; slot < 32; slot++) {
Expand Down
3 changes: 3 additions & 0 deletions arch/x86_64/kernel/pci-calgary.c
Original file line number Diff line number Diff line change
Expand Up @@ -924,6 +924,9 @@ void __init detect_calgary(void)
if (swiotlb || no_iommu || iommu_detected)
return;

if (!early_pci_allowed())
return;

specified_table_size = determine_tce_table_size(end_pfn * PAGE_SIZE);

for (bus = 0; bus < MAX_PHB_BUS_NUM; bus++) {
Expand Down
3 changes: 3 additions & 0 deletions arch/x86_64/kernel/vsmp.c
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@ static int __init vsmp_init(void)
void *address;
unsigned int cap, ctl;

if (!early_pci_allowed())
return 0;

/* Check if we are running on a ScaleMP vSMP box */
if ((read_pci_config_16(0, 0x1f, 0, PCI_VENDOR_ID) != PCI_VENDOR_ID_SCALEMP) ||
(read_pci_config_16(0, 0x1f, 0, PCI_DEVICE_ID) != PCI_DEVICE_ID_SCALEMP_VSMP_CTL))
Expand Down
3 changes: 3 additions & 0 deletions arch/x86_64/mm/k8topology.c
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,9 @@ int __init k8_scan_nodes(unsigned long start, unsigned long end)

nodes_clear(nodes_parsed);

if (!early_pci_allowed())
return -1;

nb = find_northbridge();
if (nb < 0)
return nb;
Expand Down
5 changes: 2 additions & 3 deletions drivers/pci/pci.c
Original file line number Diff line number Diff line change
Expand Up @@ -953,13 +953,12 @@ static int __devinit pci_setup(char *str)
}
str = k;
}
return 1;
return 0;
}
early_param("pci", pci_setup);

device_initcall(pci_init);

__setup("pci=", pci_setup);

#if defined(CONFIG_ISA) || defined(CONFIG_EISA)
/* FIXME: Some boxes have multiple ISA bridges! */
struct pci_dev *isa_bridge;
Expand Down
2 changes: 2 additions & 0 deletions include/asm-x86_64/pci-direct.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,6 @@ extern u8 read_pci_config_byte(u8 bus, u8 slot, u8 func, u8 offset);
extern u16 read_pci_config_16(u8 bus, u8 slot, u8 func, u8 offset);
extern void write_pci_config(u8 bus, u8 slot, u8 func, u8 offset, u32 val);

extern int early_pci_allowed(void);

#endif

0 comments on commit 0637a70

Please sign in to comment.