On Linux, /dev/mem can be used to access PCI device resources without
first calling iopl() to obtain I/O privileges. Skipping the iopl()
call allows several flashrom programmers to work on a grsecurity kernel
with GRKERNSEC_IO=y, which blocks calls to iopl() while permitting
selective /dev/mem access.
With this patch, pcidev_init() calls rget_io_perms() automatically
on non-Linux systems. rget_io_perms() is no longer called explicitly
by programmers that use only mmapped access to PCI resources.
I have tested this patch on a Debian sid system, Linux 3.14.30 kernel
with grsecurity (GRKERNSEC_KMEM=y, GRKERNSEC_IO=y, STRICT_DEVMEM=y),
successfully programming the SPI flash on an Intel 10G NIC using the
nicintel_spi programmer. I have not tested any other programmers or
system configurations.
Signed-off-by: Ed Swierk <eswierk(a)skyportsystems.com>
---
atavia.c | 3 ---
drkaiser.c | 3 ---
gfxnvidia.c | 3 ---
it8212.c | 3 ---
nicintel.c | 6 ------
nicintel_eeprom.c | 3 ---
nicintel_spi.c | 3 ---
ogp_spi.c | 3 ---
pcidev.c | 6 ++++++
satasii.c | 3 ---
10 files changed, 6 insertions(+), 30 deletions(-)
diff --git a/atavia.c b/atavia.c
index db29eea..1bcdda5 100644
--- a/atavia.c
+++ b/atavia.c
@@ -143,9 +143,6 @@ int atavia_init(void)
}
free(arg);
- if (rget_io_perms())
- return 1;
-
dev = pcidev_init(ata_via, PCI_ROM_ADDRESS); /* Acutally no BAR setup needed at all. */
if (!dev)
return 1;
diff --git a/drkaiser.c b/drkaiser.c
index 75cc085..7ccdd07 100644
--- a/drkaiser.c
+++ b/drkaiser.c
@@ -61,9 +61,6 @@ int drkaiser_init(void)
struct pci_dev *dev = NULL;
uint32_t addr;
- if (rget_io_perms())
- return 1;
-
dev = pcidev_init(drkaiser_pcidev, PCI_BASE_ADDRESS_2);
if (!dev)
return 1;
diff --git a/gfxnvidia.c b/gfxnvidia.c
index 1e5a23a..d1635b0 100644
--- a/gfxnvidia.c
+++ b/gfxnvidia.c
@@ -82,9 +82,6 @@ int gfxnvidia_init(void)
struct pci_dev *dev = NULL;
uint32_t reg32;
- if (rget_io_perms())
- return 1;
-
dev = pcidev_init(gfx_nvidia, PCI_BASE_ADDRESS_0);
if (!dev)
return 1;
diff --git a/it8212.c b/it8212.c
index 460e820..417ffc7 100644
--- a/it8212.c
+++ b/it8212.c
@@ -51,9 +51,6 @@ static const struct par_master par_master_it8212 = {
int it8212_init(void)
{
- if (rget_io_perms())
- return 1;
-
struct pci_dev *dev = pcidev_init(devs_it8212, PCI_ROM_ADDRESS);
if (!dev)
return 1;
diff --git a/nicintel.c b/nicintel.c
index 69b40d3..ad8a0b2 100644
--- a/nicintel.c
+++ b/nicintel.c
@@ -64,12 +64,6 @@ int nicintel_init(void)
struct pci_dev *dev = NULL;
uintptr_t addr;
- /* Needed only for PCI accesses on some platforms.
- * FIXME: Refactor that into get_mem_perms/rget_io_perms/get_pci_perms?
- */
- if (rget_io_perms())
- return 1;
-
/* FIXME: BAR2 is not available if the device uses the CardBus function. */
dev = pcidev_init(nics_intel, PCI_BASE_ADDRESS_2);
if (!dev)
diff --git a/nicintel_eeprom.c b/nicintel_eeprom.c
index b5d4202..3aba21d 100644
--- a/nicintel_eeprom.c
+++ b/nicintel_eeprom.c
@@ -295,9 +295,6 @@ static int nicintel_ee_shutdown(void *eecp)
int nicintel_ee_init(void)
{
- if (rget_io_perms())
- return 1;
-
struct pci_dev *dev = pcidev_init(nics_intel_ee, PCI_BASE_ADDRESS_0);
if (!dev)
return 1;
diff --git a/nicintel_spi.c b/nicintel_spi.c
index 9195c79..fa93d08 100644
--- a/nicintel_spi.c
+++ b/nicintel_spi.c
@@ -187,9 +187,6 @@ int nicintel_spi_init(void)
struct pci_dev *dev = NULL;
uint32_t tmp;
- if (rget_io_perms())
- return 1;
-
dev = pcidev_init(nics_intel_spi, PCI_BASE_ADDRESS_0);
if (!dev)
return 1;
diff --git a/ogp_spi.c b/ogp_spi.c
index 929ecd9..73993c1 100644
--- a/ogp_spi.c
+++ b/ogp_spi.c
@@ -125,9 +125,6 @@ int ogp_spi_init(void)
}
free(type);
- if (rget_io_perms())
- return 1;
-
dev = pcidev_init(ogp_spi, PCI_BASE_ADDRESS_0);
if (!dev)
return 1;
diff --git a/pcidev.c b/pcidev.c
index 2c78063..6655987 100644
--- a/pcidev.c
+++ b/pcidev.c
@@ -165,6 +165,12 @@ static int pcidev_shutdown(void *data)
int pci_init_common(void)
{
+#if IS_LINUX
+ /* On Linux, I/O privileges are not needed for mmap access to PCI resources in /dev/mem. */
+#else
+ if (rget_io_perms())
+ return 1;
+#endif
if (pacc != NULL) {
msg_perr("%s: Tried to allocate a new PCI context, but there is still an old one!\n"
"Please report a bug at flashrom(a)flashrom.org\n", __func__);
diff --git a/satasii.c b/satasii.c
index 368d7d4..63eb788 100644
--- a/satasii.c
+++ b/satasii.c
@@ -74,9 +74,6 @@ int satasii_init(void)
uint32_t addr;
uint16_t reg_offset;
- if (rget_io_perms())
- return 1;
-
dev = pcidev_init(satas_sii, PCI_BASE_ADDRESS_0);
if (!dev)
return 1;
--
1.9.1