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@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@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;