You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
59 lines
2.2 KiB
59 lines
2.2 KiB
From 210ec6353d3cab2029e1eb160671fea918c97814 Mon Sep 17 00:00:00 2001 |
|
From: "Jason S. McMullan" <jason.mcmullan@gmail.com> |
|
Date: Fri, 22 May 2015 20:30:01 +0200 |
|
Subject: [PATCH] udev/net_id: Only read the first 64 bytes of PCI config space |
|
|
|
The original code used fread(), which on some libc implementions |
|
(ie glibc 2.17) would pre-read a full 4K (PAGE_SIZE) of the |
|
PCI config space, when only 64 bytes were requested. |
|
|
|
I have recently come across PCIe hardware which responds with |
|
Completion Timeouts when accesses above 256 bytes are attempted. |
|
|
|
This can cause server systems with GHES/AEPI support to cause |
|
and immediate kernel panic due to the failed PCI transaction. |
|
|
|
This change replaces the buffered fread() with an explict |
|
unbuffered read() of 64 bytes, which corrects this issue by |
|
only reading the guaranteed first 64 bytes of PCIe config space. |
|
|
|
(cherry picked from commit 0454229c100a2113ba82df55703436d6cb2c492b) |
|
|
|
Cherry-picked from: 0454229 |
|
Resolves: #1222517 |
|
--- |
|
src/udev/udev-builtin-net_id.c | 9 +++++---- |
|
1 file changed, 5 insertions(+), 4 deletions(-) |
|
|
|
diff --git a/src/udev/udev-builtin-net_id.c b/src/udev/udev-builtin-net_id.c |
|
index 66474f772..dd2886caf 100644 |
|
--- a/src/udev/udev-builtin-net_id.c |
|
+++ b/src/udev/udev-builtin-net_id.c |
|
@@ -91,6 +91,7 @@ |
|
#include <stdlib.h> |
|
#include <stdarg.h> |
|
#include <unistd.h> |
|
+#include <fcntl.h> |
|
#include <string.h> |
|
#include <errno.h> |
|
#include <net/if.h> |
|
@@ -166,15 +167,15 @@ static int dev_pci_onboard(struct udev_device *dev, struct netnames *names) { |
|
|
|
/* read the 256 bytes PCI configuration space to check the multi-function bit */ |
|
static bool is_pci_multifunction(struct udev_device *dev) { |
|
- _cleanup_fclose_ FILE *f = NULL; |
|
+ _cleanup_close_ int fd = -1; |
|
const char *filename; |
|
uint8_t config[64]; |
|
|
|
filename = strjoina(udev_device_get_syspath(dev), "/config"); |
|
- f = fopen(filename, "re"); |
|
- if (!f) |
|
+ fd = open(filename, O_RDONLY | O_CLOEXEC); |
|
+ if (fd < 0) |
|
return false; |
|
- if (fread(&config, sizeof(config), 1, f) != 1) |
|
+ if (read(fd, &config, sizeof(config)) != sizeof(config)) |
|
return false; |
|
|
|
/* bit 0-6 header type, bit 7 multi/single function device */
|
|
|