summaryrefslogtreecommitdiff
path: root/sys/arch/amd64
diff options
context:
space:
mode:
authorOwain Ainsworth <oga@cvs.openbsd.org>2009-01-27 15:34:00 +0000
committerOwain Ainsworth <oga@cvs.openbsd.org>2009-01-27 15:34:00 +0000
commit11466d531552c18807f1cc97f9472dad7f12992d (patch)
tree0b52928b3de9edf5ca28e95aaa55791a5be04db0 /sys/arch/amd64
parentdb37bb7d79d37d659536a1dac53f5bab5c1ff67a (diff)
Switch the amd64 PCI_CONF_LOCK from being a simplelock and splhigh to a
mutex with ipl set to IPL_HIGH. While i'm here, unify the code with i386, by giving the same lock to the i386 code. This lock is mostly for MP, but could actually prevent a race where a process is doing pci_conf_{read,write}, and then an interrupt fire and also does pci_conf_{read,write}. Since this is a two stage process, the interrupt could race with the one, causing the value to the written to the wrong place, or the wrong value to be written. Tested by many. "go ahead" kettenis@.
Diffstat (limited to 'sys/arch/amd64')
-rw-r--r--sys/arch/amd64/pci/pci_machdep.c28
1 files changed, 10 insertions, 18 deletions
diff --git a/sys/arch/amd64/pci/pci_machdep.c b/sys/arch/amd64/pci/pci_machdep.c
index 85a4b1013b1..a11c8cd2ebe 100644
--- a/sys/arch/amd64/pci/pci_machdep.c
+++ b/sys/arch/amd64/pci/pci_machdep.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: pci_machdep.c,v 1.20 2008/12/28 18:26:53 kettenis Exp $ */
+/* $OpenBSD: pci_machdep.c,v 1.21 2009/01/27 15:33:59 oga Exp $ */
/* $NetBSD: pci_machdep.c,v 1.3 2003/05/07 21:33:58 fvdl Exp $ */
/*-
@@ -105,22 +105,16 @@
int pci_mode = -1;
-#if defined(MULTIPROCESSOR) && 0
-struct simplelock pci_conf_slock = SIMPLELOCK_INITIALIZER;
-#else
-struct simplelock pci_conf_slock = { 0 };
-#endif
+struct mutex pci_conf_lock = MUTEX_INITIALIZER(IPL_HIGH);
-#define PCI_CONF_LOCK(s) \
+#define PCI_CONF_LOCK() \
do { \
- (s) = splhigh(); \
- simple_lock(&pci_conf_slock); \
+ mtx_enter(&pci_conf_lock); \
} while (0)
-#define PCI_CONF_UNLOCK(s) \
+#define PCI_CONF_UNLOCK() \
do { \
- simple_unlock(&pci_conf_slock); \
- splx((s)); \
+ mtx_leave(&pci_conf_lock); \
} while (0)
#define PCI_MODE1_ENABLE 0x80000000UL
@@ -258,9 +252,8 @@ pcireg_t
pci_conf_read(pci_chipset_tag_t pc, pcitag_t tag, int reg)
{
pcireg_t data;
- int s;
- PCI_CONF_LOCK(s);
+ PCI_CONF_LOCK();
switch (pci_mode) {
case 1:
outl(PCI_MODE1_ADDRESS_REG, tag.mode1 | reg);
@@ -276,7 +269,7 @@ pci_conf_read(pci_chipset_tag_t pc, pcitag_t tag, int reg)
default:
panic("pci_conf_read: mode not configured");
}
- PCI_CONF_UNLOCK(s);
+ PCI_CONF_UNLOCK();
return data;
}
@@ -284,9 +277,8 @@ pci_conf_read(pci_chipset_tag_t pc, pcitag_t tag, int reg)
void
pci_conf_write(pci_chipset_tag_t pc, pcitag_t tag, int reg, pcireg_t data)
{
- int s;
- PCI_CONF_LOCK(s);
+ PCI_CONF_LOCK();
switch (pci_mode) {
case 1:
outl(PCI_MODE1_ADDRESS_REG, tag.mode1 | reg);
@@ -302,7 +294,7 @@ pci_conf_write(pci_chipset_tag_t pc, pcitag_t tag, int reg, pcireg_t data)
default:
panic("pci_conf_write: mode not configured");
}
- PCI_CONF_UNLOCK(s);
+ PCI_CONF_UNLOCK();
}
int