From: Eric Anholt Date: Thu, 5 Jun 2008 18:39:06 +0000 (-0700) Subject: Catch and recover from yet another linux kernel bug in mprotect. X-Git-Tag: android-x86-6.0-r1~179 X-Git-Url: http://git.osdn.net/view?a=commitdiff_plain;h=e3adc06b8b8214478aa1d3e85fd5f83b79d039b4;p=android-x86%2Fexternal-libpciaccess.git Catch and recover from yet another linux kernel bug in mprotect. --- diff --git a/src/linux_sysfs.c b/src/linux_sysfs.c index 9e53fac..b1d196c 100644 --- a/src/linux_sysfs.c +++ b/src/linux_sysfs.c @@ -537,12 +537,11 @@ pci_device_linux_sysfs_map_range(struct pci_device *dev, map->memory = mmap(NULL, map->size, prot, MAP_SHARED, fd, offset); if (map->memory == MAP_FAILED) { - err = errno; map->memory = NULL; + close(fd); + return errno; } - close(fd); - #ifdef HAVE_MTRR if ((map->flags & PCI_DEV_MAP_FLAG_CACHABLE) != 0) { sentry.type = MTRR_TYPE_WRBACK; @@ -562,11 +561,27 @@ pci_device_linux_sysfs_map_range(struct pci_device *dev, } /* KLUDGE ALERT -- rewrite the PTEs to turn off the CD and WT bits */ mprotect (map->memory, map->size, PROT_NONE); - mprotect (map->memory, map->size, PROT_READ|PROT_WRITE); + err = mprotect (map->memory, map->size, PROT_READ|PROT_WRITE); + + if (err != 0) { + fprintf(stderr, "mprotect(PROT_READ | PROT_WRITE) failed: %s\n", + strerror(errno)); + fprintf(stderr, "remapping without mprotect performace kludge.\n"); + + munmap(map->memory, map->size); + map->memory = mmap(NULL, map->size, prot, MAP_SHARED, fd, offset); + if (map->memory == MAP_FAILED) { + map->memory = NULL; + close(fd); + return errno; + } + } } #endif - return err; + close(fd); + + return 0; } /**