summaryrefslogtreecommitdiffstats
path: root/sys/ia64
diff options
context:
space:
mode:
authormarcel <marcel@FreeBSD.org>2010-03-22 03:06:11 +0000
committermarcel <marcel@FreeBSD.org>2010-03-22 03:06:11 +0000
commit6b762ecd8b1f98319d288d3bd46afc5c624a5076 (patch)
tree17794085b5635fcb305c7bb369a2869c09534af6 /sys/ia64
parentd5582bd6012d80fa65782ce116e963c3e943aba7 (diff)
downloadFreeBSD-src-6b762ecd8b1f98319d288d3bd46afc5c624a5076.zip
FreeBSD-src-6b762ecd8b1f98319d288d3bd46afc5c624a5076.tar.gz
Disable interrupts when calling into SAL for PCI configuration
cycles. This serves 2 purposes: 1. It prevents preemption and CPU migration while running SAL code. 2. It reduces the chance of stack overflows: we're supposed to enter SAL with at least 16KB of either memory- or register stack space, which we can't do without switching to a different stack.
Diffstat (limited to 'sys/ia64')
-rw-r--r--sys/ia64/pci/pci_cfgreg.c11
1 files changed, 8 insertions, 3 deletions
diff --git a/sys/ia64/pci/pci_cfgreg.c b/sys/ia64/pci/pci_cfgreg.c
index 4858d94..00d8397 100644
--- a/sys/ia64/pci/pci_cfgreg.c
+++ b/sys/ia64/pci/pci_cfgreg.c
@@ -28,6 +28,7 @@
*/
#include <sys/param.h>
+#include <machine/cpufunc.h>
#include <machine/pci_cfgreg.h>
#include <machine/sal.h>
@@ -66,6 +67,7 @@ uint32_t
pci_cfgregread(int bus, int slot, int func, int reg, int len)
{
struct ia64_sal_result res;
+ register_t is;
u_long addr;
addr = pci_sal_address(0, bus, slot, func, reg);
@@ -75,17 +77,18 @@ pci_cfgregread(int bus, int slot, int func, int reg, int len)
if (!pci_valid_access(reg, len))
return (~0);
+ is = intr_disable();
res = ia64_sal_entry(SAL_PCI_CONFIG_READ, addr, len, 0, 0, 0, 0, 0);
- if (res.sal_status < 0)
- return (~0);
+ intr_restore(is);
- return (res.sal_result[0]);
+ return ((res.sal_status < 0) ? ~0 : res.sal_result[0]);
}
void
pci_cfgregwrite(int bus, int slot, int func, int reg, uint32_t data, int len)
{
struct ia64_sal_result res;
+ register_t is;
u_long addr;
addr = pci_sal_address(0, bus, slot, func, reg);
@@ -95,5 +98,7 @@ pci_cfgregwrite(int bus, int slot, int func, int reg, uint32_t data, int len)
if (!pci_valid_access(reg, len))
return;
+ is = intr_disable();
res = ia64_sal_entry(SAL_PCI_CONFIG_WRITE, addr, len, data, 0, 0, 0, 0);
+ intr_restore(is);
}
OpenPOWER on IntegriCloud