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 <[email protected]>
---
 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 [email protected]\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


_______________________________________________
flashrom mailing list
[email protected]
http://www.flashrom.org/mailman/listinfo/flashrom

Reply via email to